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