• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #define NAPI_EXPERIMENTAL
2 #include <js_native_api.h>
3 #include "../common.h"
4 #include <string.h>
5 #include "test_null.h"
6 
7 static int test_value = 3;
8 
Get(napi_env env,napi_callback_info info)9 static napi_value Get(napi_env env, napi_callback_info info) {
10   size_t argc = 2;
11   napi_value args[2];
12   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
13 
14   NAPI_ASSERT(env, argc >= 2, "Wrong number of arguments");
15 
16   napi_valuetype valuetype0;
17   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
18 
19   NAPI_ASSERT(env, valuetype0 == napi_object,
20       "Wrong type of arguments. Expects an object as first argument.");
21 
22   napi_valuetype valuetype1;
23   NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
24 
25   NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
26       "Wrong type of arguments. Expects a string or symbol as second.");
27 
28   napi_value object = args[0];
29   napi_value output;
30   NAPI_CALL(env, napi_get_property(env, object, args[1], &output));
31 
32   return output;
33 }
34 
GetNamed(napi_env env,napi_callback_info info)35 static napi_value GetNamed(napi_env env, napi_callback_info info) {
36   size_t argc = 2;
37   napi_value args[2];
38   char key[256] = "";
39   size_t key_length;
40   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
41 
42   NAPI_ASSERT(env, argc >= 2, "Wrong number of arguments");
43 
44   napi_valuetype value_type0;
45   NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
46 
47   NAPI_ASSERT(env, value_type0 == napi_object,
48       "Wrong type of arguments. Expects an object as first argument.");
49 
50   napi_valuetype value_type1;
51   NAPI_CALL(env, napi_typeof(env, args[1], &value_type1));
52 
53   NAPI_ASSERT(env, value_type1 == napi_string,
54       "Wrong type of arguments. Expects a string as second.");
55 
56   napi_value object = args[0];
57   NAPI_CALL(env,
58       napi_get_value_string_utf8(env, args[1], key, 255, &key_length));
59   key[255] = 0;
60   NAPI_ASSERT(env, key_length <= 255,
61       "Cannot accommodate keys longer than 255 bytes");
62   napi_value output;
63   NAPI_CALL(env, napi_get_named_property(env, object, key, &output));
64 
65   return output;
66 }
67 
GetPropertyNames(napi_env env,napi_callback_info info)68 static napi_value GetPropertyNames(napi_env env, napi_callback_info info) {
69   size_t argc = 1;
70   napi_value args[1];
71   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
72 
73   NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
74 
75   napi_valuetype value_type0;
76   NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
77 
78   NAPI_ASSERT(env, value_type0 == napi_object,
79       "Wrong type of arguments. Expects an object as first argument.");
80 
81   napi_value output;
82   NAPI_CALL(env, napi_get_property_names(env, args[0], &output));
83 
84   return output;
85 }
86 
GetSymbolNames(napi_env env,napi_callback_info info)87 static napi_value GetSymbolNames(napi_env env, napi_callback_info info) {
88   size_t argc = 1;
89   napi_value args[1];
90   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
91 
92   NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
93 
94   napi_valuetype value_type0;
95   NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
96 
97   NAPI_ASSERT(env,
98               value_type0 == napi_object,
99               "Wrong type of arguments. Expects an object as first argument.");
100 
101   napi_value output;
102   NAPI_CALL(env,
103             napi_get_all_property_names(
104                 env,
105                 args[0],
106                 napi_key_include_prototypes,
107                 napi_key_skip_strings,
108                 napi_key_numbers_to_strings,
109                 &output));
110 
111   return output;
112 }
113 
Set(napi_env env,napi_callback_info info)114 static napi_value Set(napi_env env, napi_callback_info info) {
115   size_t argc = 3;
116   napi_value args[3];
117   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
118 
119   NAPI_ASSERT(env, argc >= 3, "Wrong number of arguments");
120 
121   napi_valuetype valuetype0;
122   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
123 
124   NAPI_ASSERT(env, valuetype0 == napi_object,
125       "Wrong type of arguments. Expects an object as first argument.");
126 
127   napi_valuetype valuetype1;
128   NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
129 
130   NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
131       "Wrong type of arguments. Expects a string or symbol as second.");
132 
133   NAPI_CALL(env, napi_set_property(env, args[0], args[1], args[2]));
134 
135   napi_value valuetrue;
136   NAPI_CALL(env, napi_get_boolean(env, true, &valuetrue));
137 
138   return valuetrue;
139 }
140 
SetNamed(napi_env env,napi_callback_info info)141 static napi_value SetNamed(napi_env env, napi_callback_info info) {
142   size_t argc = 3;
143   napi_value args[3];
144   char key[256] = "";
145   size_t key_length;
146   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
147 
148   NAPI_ASSERT(env, argc >= 3, "Wrong number of arguments");
149 
150   napi_valuetype value_type0;
151   NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
152 
153   NAPI_ASSERT(env, value_type0 == napi_object,
154       "Wrong type of arguments. Expects an object as first argument.");
155 
156   napi_valuetype value_type1;
157   NAPI_CALL(env, napi_typeof(env, args[1], &value_type1));
158 
159   NAPI_ASSERT(env, value_type1 == napi_string,
160       "Wrong type of arguments. Expects a string as second.");
161 
162   NAPI_CALL(env,
163       napi_get_value_string_utf8(env, args[1], key, 255, &key_length));
164   key[255] = 0;
165   NAPI_ASSERT(env, key_length <= 255,
166       "Cannot accommodate keys longer than 255 bytes");
167 
168   NAPI_CALL(env, napi_set_named_property(env, args[0], key, args[2]));
169 
170   napi_value value_true;
171   NAPI_CALL(env, napi_get_boolean(env, true, &value_true));
172 
173   return value_true;
174 }
175 
Has(napi_env env,napi_callback_info info)176 static napi_value Has(napi_env env, napi_callback_info info) {
177   size_t argc = 2;
178   napi_value args[2];
179   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
180 
181   NAPI_ASSERT(env, argc >= 2, "Wrong number of arguments");
182 
183   napi_valuetype valuetype0;
184   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
185 
186   NAPI_ASSERT(env, valuetype0 == napi_object,
187       "Wrong type of arguments. Expects an object as first argument.");
188 
189   napi_valuetype valuetype1;
190   NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
191 
192   NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
193       "Wrong type of arguments. Expects a string or symbol as second.");
194 
195   bool has_property;
196   NAPI_CALL(env, napi_has_property(env, args[0], args[1], &has_property));
197 
198   napi_value ret;
199   NAPI_CALL(env, napi_get_boolean(env, has_property, &ret));
200 
201   return ret;
202 }
203 
HasNamed(napi_env env,napi_callback_info info)204 static napi_value HasNamed(napi_env env, napi_callback_info info) {
205   size_t argc = 2;
206   napi_value args[2];
207   char key[256] = "";
208   size_t key_length;
209   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
210 
211   NAPI_ASSERT(env, argc >= 2, "Wrong number of arguments");
212 
213   napi_valuetype value_type0;
214   NAPI_CALL(env, napi_typeof(env, args[0], &value_type0));
215 
216   NAPI_ASSERT(env, value_type0 == napi_object,
217       "Wrong type of arguments. Expects an object as first argument.");
218 
219   napi_valuetype value_type1;
220   NAPI_CALL(env, napi_typeof(env, args[1], &value_type1));
221 
222   NAPI_ASSERT(env, value_type1 == napi_string || value_type1 == napi_symbol,
223       "Wrong type of arguments. Expects a string as second.");
224 
225   NAPI_CALL(env,
226       napi_get_value_string_utf8(env, args[1], key, 255, &key_length));
227   key[255] = 0;
228   NAPI_ASSERT(env, key_length <= 255,
229       "Cannot accommodate keys longer than 255 bytes");
230 
231   bool has_property;
232   NAPI_CALL(env, napi_has_named_property(env, args[0], key, &has_property));
233 
234   napi_value ret;
235   NAPI_CALL(env, napi_get_boolean(env, has_property, &ret));
236 
237   return ret;
238 }
239 
HasOwn(napi_env env,napi_callback_info info)240 static napi_value HasOwn(napi_env env, napi_callback_info info) {
241   size_t argc = 2;
242   napi_value args[2];
243   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
244 
245   NAPI_ASSERT(env, argc == 2, "Wrong number of arguments");
246 
247   napi_valuetype valuetype0;
248   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
249 
250   NAPI_ASSERT(env, valuetype0 == napi_object,
251       "Wrong type of arguments. Expects an object as first argument.");
252 
253   // napi_valuetype valuetype1;
254   // NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
255   //
256   // NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
257   //   "Wrong type of arguments. Expects a string or symbol as second.");
258 
259   bool has_property;
260   NAPI_CALL(env, napi_has_own_property(env, args[0], args[1], &has_property));
261 
262   napi_value ret;
263   NAPI_CALL(env, napi_get_boolean(env, has_property, &ret));
264 
265   return ret;
266 }
267 
Delete(napi_env env,napi_callback_info info)268 static napi_value Delete(napi_env env, napi_callback_info info) {
269   size_t argc = 2;
270   napi_value args[2];
271 
272   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
273   NAPI_ASSERT(env, argc == 2, "Wrong number of arguments");
274 
275   napi_valuetype valuetype0;
276   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
277   NAPI_ASSERT(env, valuetype0 == napi_object,
278       "Wrong type of arguments. Expects an object as first argument.");
279 
280   napi_valuetype valuetype1;
281   NAPI_CALL(env, napi_typeof(env, args[1], &valuetype1));
282   NAPI_ASSERT(env, valuetype1 == napi_string || valuetype1 == napi_symbol,
283       "Wrong type of arguments. Expects a string or symbol as second.");
284 
285   bool result;
286   napi_value ret;
287   NAPI_CALL(env, napi_delete_property(env, args[0], args[1], &result));
288   NAPI_CALL(env, napi_get_boolean(env, result, &ret));
289 
290   return ret;
291 }
292 
New(napi_env env,napi_callback_info info)293 static napi_value New(napi_env env, napi_callback_info info) {
294   napi_value ret;
295   NAPI_CALL(env, napi_create_object(env, &ret));
296 
297   napi_value num;
298   NAPI_CALL(env, napi_create_int32(env, 987654321, &num));
299 
300   NAPI_CALL(env, napi_set_named_property(env, ret, "test_number", num));
301 
302   napi_value str;
303   const char* str_val = "test string";
304   size_t str_len = strlen(str_val);
305   NAPI_CALL(env, napi_create_string_utf8(env, str_val, str_len, &str));
306 
307   NAPI_CALL(env, napi_set_named_property(env, ret, "test_string", str));
308 
309   return ret;
310 }
311 
Inflate(napi_env env,napi_callback_info info)312 static napi_value Inflate(napi_env env, napi_callback_info info) {
313   size_t argc = 1;
314   napi_value args[1];
315   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
316 
317   NAPI_ASSERT(env, argc >= 1, "Wrong number of arguments");
318 
319   napi_valuetype valuetype0;
320   NAPI_CALL(env, napi_typeof(env, args[0], &valuetype0));
321 
322   NAPI_ASSERT(env, valuetype0 == napi_object,
323       "Wrong type of arguments. Expects an object as first argument.");
324 
325   napi_value obj = args[0];
326   napi_value propertynames;
327   NAPI_CALL(env, napi_get_property_names(env, obj, &propertynames));
328 
329   uint32_t i, length;
330   NAPI_CALL(env, napi_get_array_length(env, propertynames, &length));
331 
332   for (i = 0; i < length; i++) {
333     napi_value property_str;
334     NAPI_CALL(env, napi_get_element(env, propertynames, i, &property_str));
335 
336     napi_value value;
337     NAPI_CALL(env, napi_get_property(env, obj, property_str, &value));
338 
339     double double_val;
340     NAPI_CALL(env, napi_get_value_double(env, value, &double_val));
341     NAPI_CALL(env, napi_create_double(env, double_val + 1, &value));
342     NAPI_CALL(env, napi_set_property(env, obj, property_str, value));
343   }
344 
345   return obj;
346 }
347 
Wrap(napi_env env,napi_callback_info info)348 static napi_value Wrap(napi_env env, napi_callback_info info) {
349   size_t argc = 1;
350   napi_value arg;
351   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &arg, NULL, NULL));
352 
353   NAPI_CALL(env, napi_wrap(env, arg, &test_value, NULL, NULL, NULL));
354   return NULL;
355 }
356 
Unwrap(napi_env env,napi_callback_info info)357 static napi_value Unwrap(napi_env env, napi_callback_info info) {
358   size_t argc = 1;
359   napi_value arg;
360   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &arg, NULL, NULL));
361 
362   void* data;
363   NAPI_CALL(env, napi_unwrap(env, arg, &data));
364 
365   bool is_expected = (data != NULL && *(int*)data == 3);
366   napi_value result;
367   NAPI_CALL(env, napi_get_boolean(env, is_expected, &result));
368   return result;
369 }
370 
TestSetProperty(napi_env env,napi_callback_info info)371 static napi_value TestSetProperty(napi_env env,
372                                   napi_callback_info info) {
373   napi_status status;
374   napi_value object, key, value;
375 
376   NAPI_CALL(env, napi_create_object(env, &object));
377 
378   NAPI_CALL(env, napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &key));
379 
380   NAPI_CALL(env, napi_create_object(env, &value));
381 
382   status = napi_set_property(NULL, object, key, value);
383 
384   add_returned_status(env,
385                       "envIsNull",
386                       object,
387                       "Invalid argument",
388                       napi_invalid_arg,
389                       status);
390 
391   napi_set_property(env, NULL, key, value);
392 
393   add_last_status(env, "objectIsNull", object);
394 
395   napi_set_property(env, object, NULL, value);
396 
397   add_last_status(env, "keyIsNull", object);
398 
399   napi_set_property(env, object, key, NULL);
400 
401   add_last_status(env, "valueIsNull", object);
402 
403   return object;
404 }
405 
TestHasProperty(napi_env env,napi_callback_info info)406 static napi_value TestHasProperty(napi_env env,
407                                   napi_callback_info info) {
408   napi_status status;
409   napi_value object, key;
410   bool result;
411 
412   NAPI_CALL(env, napi_create_object(env, &object));
413 
414   NAPI_CALL(env, napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &key));
415 
416   status = napi_has_property(NULL, object, key, &result);
417 
418   add_returned_status(env,
419                       "envIsNull",
420                       object,
421                       "Invalid argument",
422                       napi_invalid_arg,
423                       status);
424 
425   napi_has_property(env, NULL, key, &result);
426 
427   add_last_status(env, "objectIsNull", object);
428 
429   napi_has_property(env, object, NULL, &result);
430 
431   add_last_status(env, "keyIsNull", object);
432 
433   napi_has_property(env, object, key, NULL);
434 
435   add_last_status(env, "resultIsNull", object);
436 
437   return object;
438 }
439 
TestGetProperty(napi_env env,napi_callback_info info)440 static napi_value TestGetProperty(napi_env env,
441                                   napi_callback_info info) {
442   napi_status status;
443   napi_value object, key, result;
444 
445   NAPI_CALL(env, napi_create_object(env, &object));
446 
447   NAPI_CALL(env, napi_create_string_utf8(env, "", NAPI_AUTO_LENGTH, &key));
448 
449   NAPI_CALL(env, napi_create_object(env, &result));
450 
451   status = napi_get_property(NULL, object, key, &result);
452 
453   add_returned_status(env,
454                       "envIsNull",
455                       object,
456                       "Invalid argument",
457                       napi_invalid_arg,
458                       status);
459 
460   napi_get_property(env, NULL, key, &result);
461 
462   add_last_status(env, "objectIsNull", object);
463 
464   napi_get_property(env, object, NULL, &result);
465 
466   add_last_status(env, "keyIsNull", object);
467 
468   napi_get_property(env, object, key, NULL);
469 
470   add_last_status(env, "resultIsNull", object);
471 
472   return object;
473 }
474 
TestFreeze(napi_env env,napi_callback_info info)475 static napi_value TestFreeze(napi_env env,
476                              napi_callback_info info) {
477   size_t argc = 1;
478   napi_value args[1];
479   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
480 
481   napi_value object = args[0];
482   NAPI_CALL(env, napi_object_freeze(env, object));
483 
484   return object;
485 }
486 
TestSeal(napi_env env,napi_callback_info info)487 static napi_value TestSeal(napi_env env,
488                            napi_callback_info info) {
489   size_t argc = 1;
490   napi_value args[1];
491   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
492 
493   napi_value object = args[0];
494   NAPI_CALL(env, napi_object_seal(env, object));
495 
496   return object;
497 }
498 
499 // We create two type tags. They are basically 128-bit UUIDs.
500 static const napi_type_tag type_tags[2] = {
501   { 0xdaf987b3cc62481a, 0xb745b0497f299531 },
502   { 0xbb7936c374084d9b, 0xa9548d0762eeedb9 }
503 };
504 
505 static napi_value
TypeTaggedInstance(napi_env env,napi_callback_info info)506 TypeTaggedInstance(napi_env env, napi_callback_info info) {
507   size_t argc = 1;
508   uint32_t type_index;
509   napi_value instance, which_type;
510 
511   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &which_type, NULL, NULL));
512   NAPI_CALL(env, napi_get_value_uint32(env, which_type, &type_index));
513   NAPI_CALL(env, napi_create_object(env, &instance));
514   NAPI_CALL(env, napi_type_tag_object(env, instance, &type_tags[type_index]));
515 
516   return instance;
517 }
518 
519 static napi_value
CheckTypeTag(napi_env env,napi_callback_info info)520 CheckTypeTag(napi_env env, napi_callback_info info) {
521   size_t argc = 2;
522   bool result;
523   napi_value argv[2], js_result;
524   uint32_t type_index;
525 
526   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
527   NAPI_CALL(env, napi_get_value_uint32(env, argv[0], &type_index));
528   NAPI_CALL(env, napi_check_object_type_tag(env,
529                                             argv[1],
530                                             &type_tags[type_index],
531                                             &result));
532   NAPI_CALL(env, napi_get_boolean(env, result, &js_result));
533 
534   return js_result;
535 }
536 
537 EXTERN_C_START
Init(napi_env env,napi_value exports)538 napi_value Init(napi_env env, napi_value exports) {
539   napi_property_descriptor descriptors[] = {
540     DECLARE_NAPI_PROPERTY("Get", Get),
541     DECLARE_NAPI_PROPERTY("GetNamed", GetNamed),
542     DECLARE_NAPI_PROPERTY("GetPropertyNames", GetPropertyNames),
543     DECLARE_NAPI_PROPERTY("GetSymbolNames", GetSymbolNames),
544     DECLARE_NAPI_PROPERTY("Set", Set),
545     DECLARE_NAPI_PROPERTY("SetNamed", SetNamed),
546     DECLARE_NAPI_PROPERTY("Has", Has),
547     DECLARE_NAPI_PROPERTY("HasNamed", HasNamed),
548     DECLARE_NAPI_PROPERTY("HasOwn", HasOwn),
549     DECLARE_NAPI_PROPERTY("Delete", Delete),
550     DECLARE_NAPI_PROPERTY("New", New),
551     DECLARE_NAPI_PROPERTY("Inflate", Inflate),
552     DECLARE_NAPI_PROPERTY("Wrap", Wrap),
553     DECLARE_NAPI_PROPERTY("Unwrap", Unwrap),
554     DECLARE_NAPI_PROPERTY("TestSetProperty", TestSetProperty),
555     DECLARE_NAPI_PROPERTY("TestHasProperty", TestHasProperty),
556     DECLARE_NAPI_PROPERTY("TypeTaggedInstance", TypeTaggedInstance),
557     DECLARE_NAPI_PROPERTY("CheckTypeTag", CheckTypeTag),
558     DECLARE_NAPI_PROPERTY("TestGetProperty", TestGetProperty),
559     DECLARE_NAPI_PROPERTY("TestFreeze", TestFreeze),
560     DECLARE_NAPI_PROPERTY("TestSeal", TestSeal),
561   };
562 
563   init_test_null(env, exports);
564 
565   NAPI_CALL(env, napi_define_properties(
566       env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
567 
568   return exports;
569 }
570 EXTERN_C_END
571