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