• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // we define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED here to
2 // validate that it can be used as a form of test itself. It is
3 // not related to any of the other tests
4 // defined in the file
5 #define NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <stdint.h>
9 #include <js_native_api.h>
10 #include "../common.h"
11 
testStrictEquals(napi_env env,napi_callback_info info)12 static napi_value testStrictEquals(napi_env env, napi_callback_info info) {
13   size_t argc = 2;
14   napi_value args[2];
15   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
16 
17   bool bool_result;
18   napi_value result;
19   NAPI_CALL(env, napi_strict_equals(env, args[0], args[1], &bool_result));
20   NAPI_CALL(env, napi_get_boolean(env, bool_result, &result));
21 
22   return result;
23 }
24 
testGetPrototype(napi_env env,napi_callback_info info)25 static napi_value testGetPrototype(napi_env env, napi_callback_info info) {
26   size_t argc = 1;
27   napi_value args[1];
28   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
29 
30   napi_value result;
31   NAPI_CALL(env, napi_get_prototype(env, args[0], &result));
32 
33   return result;
34 }
35 
testGetVersion(napi_env env,napi_callback_info info)36 static napi_value testGetVersion(napi_env env, napi_callback_info info) {
37   uint32_t version;
38   napi_value result;
39   NAPI_CALL(env, napi_get_version(env, &version));
40   NAPI_CALL(env, napi_create_uint32(env, version, &result));
41   return result;
42 }
43 
doInstanceOf(napi_env env,napi_callback_info info)44 static napi_value doInstanceOf(napi_env env, napi_callback_info info) {
45   size_t argc = 2;
46   napi_value args[2];
47   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
48 
49   bool instanceof;
50   NAPI_CALL(env, napi_instanceof(env, args[0], args[1], &instanceof));
51 
52   napi_value result;
53   NAPI_CALL(env, napi_get_boolean(env, instanceof, &result));
54 
55   return result;
56 }
57 
getNull(napi_env env,napi_callback_info info)58 static napi_value getNull(napi_env env, napi_callback_info info) {
59   napi_value result;
60   NAPI_CALL(env, napi_get_null(env, &result));
61   return result;
62 }
63 
getUndefined(napi_env env,napi_callback_info info)64 static napi_value getUndefined(napi_env env, napi_callback_info info) {
65   napi_value result;
66   NAPI_CALL(env, napi_get_undefined(env, &result));
67   return result;
68 }
69 
createNapiError(napi_env env,napi_callback_info info)70 static napi_value createNapiError(napi_env env, napi_callback_info info) {
71   napi_value value;
72   NAPI_CALL(env, napi_create_string_utf8(env, "xyz", 3, &value));
73 
74   double double_value;
75   napi_status status = napi_get_value_double(env, value, &double_value);
76 
77   NAPI_ASSERT(env, status != napi_ok, "Failed to produce error condition");
78 
79   const napi_extended_error_info *error_info = 0;
80   NAPI_CALL(env, napi_get_last_error_info(env, &error_info));
81 
82   NAPI_ASSERT(env, error_info->error_code == status,
83       "Last error info code should match last status");
84   NAPI_ASSERT(env, error_info->error_message,
85       "Last error info message should not be null");
86 
87   return NULL;
88 }
89 
testNapiErrorCleanup(napi_env env,napi_callback_info info)90 static napi_value testNapiErrorCleanup(napi_env env, napi_callback_info info) {
91   const napi_extended_error_info *error_info = 0;
92   NAPI_CALL(env, napi_get_last_error_info(env, &error_info));
93 
94   napi_value result;
95   bool is_ok = error_info->error_code == napi_ok;
96   NAPI_CALL(env, napi_get_boolean(env, is_ok, &result));
97 
98   return result;
99 }
100 
testNapiTypeof(napi_env env,napi_callback_info info)101 static napi_value testNapiTypeof(napi_env env, napi_callback_info info) {
102   size_t argc = 1;
103   napi_value args[1];
104   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, NULL, NULL));
105 
106   napi_valuetype argument_type;
107   NAPI_CALL(env, napi_typeof(env, args[0], &argument_type));
108 
109   napi_value result = NULL;
110   if (argument_type == napi_number) {
111     NAPI_CALL(env, napi_create_string_utf8(
112         env, "number", NAPI_AUTO_LENGTH, &result));
113   } else if (argument_type == napi_string) {
114     NAPI_CALL(env, napi_create_string_utf8(
115         env, "string", NAPI_AUTO_LENGTH, &result));
116   } else if (argument_type == napi_function) {
117     NAPI_CALL(env, napi_create_string_utf8(
118         env, "function", NAPI_AUTO_LENGTH, &result));
119   } else if (argument_type == napi_object) {
120     NAPI_CALL(env, napi_create_string_utf8(
121         env, "object", NAPI_AUTO_LENGTH, &result));
122   } else if (argument_type == napi_boolean) {
123     NAPI_CALL(env, napi_create_string_utf8(
124         env, "boolean", NAPI_AUTO_LENGTH, &result));
125   } else if (argument_type == napi_undefined) {
126     NAPI_CALL(env, napi_create_string_utf8(
127         env, "undefined", NAPI_AUTO_LENGTH, &result));
128   } else if (argument_type == napi_symbol) {
129     NAPI_CALL(env, napi_create_string_utf8(
130         env, "symbol", NAPI_AUTO_LENGTH, &result));
131   } else if (argument_type == napi_null) {
132     NAPI_CALL(env, napi_create_string_utf8(
133         env, "null", NAPI_AUTO_LENGTH, &result));
134   }
135   return result;
136 }
137 
138 static bool deref_item_called = false;
deref_item(napi_env env,void * data,void * hint)139 static void deref_item(napi_env env, void* data, void* hint) {
140   (void) hint;
141 
142   NAPI_ASSERT_RETURN_VOID(env, data == &deref_item_called,
143     "Finalize callback was called with the correct pointer");
144 
145   deref_item_called = true;
146 }
147 
deref_item_was_called(napi_env env,napi_callback_info info)148 static napi_value deref_item_was_called(napi_env env, napi_callback_info info) {
149   napi_value it_was_called;
150 
151   NAPI_CALL(env, napi_get_boolean(env, deref_item_called, &it_was_called));
152 
153   return it_was_called;
154 }
155 
wrap_first_arg(napi_env env,napi_callback_info info,napi_finalize finalizer,void * data)156 static napi_value wrap_first_arg(napi_env env,
157                                  napi_callback_info info,
158                                  napi_finalize finalizer,
159                                  void* data) {
160   size_t argc = 1;
161   napi_value to_wrap;
162 
163   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &to_wrap, NULL, NULL));
164   NAPI_CALL(env, napi_wrap(env, to_wrap, data, finalizer, NULL, NULL));
165 
166   return to_wrap;
167 }
168 
wrap(napi_env env,napi_callback_info info)169 static napi_value wrap(napi_env env, napi_callback_info info) {
170   deref_item_called = false;
171   return wrap_first_arg(env, info, deref_item, &deref_item_called);
172 }
173 
unwrap(napi_env env,napi_callback_info info)174 static napi_value unwrap(napi_env env, napi_callback_info info) {
175   size_t argc = 1;
176   napi_value wrapped;
177   void* data;
178 
179   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &wrapped, NULL, NULL));
180   NAPI_CALL(env, napi_unwrap(env, wrapped, &data));
181 
182   return NULL;
183 }
184 
remove_wrap(napi_env env,napi_callback_info info)185 static napi_value remove_wrap(napi_env env, napi_callback_info info) {
186   size_t argc = 1;
187   napi_value wrapped;
188   void* data;
189 
190   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &wrapped, NULL, NULL));
191   NAPI_CALL(env, napi_remove_wrap(env, wrapped, &data));
192 
193   return NULL;
194 }
195 
196 static bool finalize_called = false;
test_finalize(napi_env env,void * data,void * hint)197 static void test_finalize(napi_env env, void* data, void* hint) {
198   finalize_called = true;
199 }
200 
test_finalize_wrap(napi_env env,napi_callback_info info)201 static napi_value test_finalize_wrap(napi_env env, napi_callback_info info) {
202   return wrap_first_arg(env, info, test_finalize, NULL);
203 }
204 
finalize_was_called(napi_env env,napi_callback_info info)205 static napi_value finalize_was_called(napi_env env, napi_callback_info info) {
206   napi_value it_was_called;
207 
208   NAPI_CALL(env, napi_get_boolean(env, finalize_called, &it_was_called));
209 
210   return it_was_called;
211 }
212 
testAdjustExternalMemory(napi_env env,napi_callback_info info)213 static napi_value testAdjustExternalMemory(napi_env env, napi_callback_info info) {
214   napi_value result;
215   int64_t adjustedValue;
216 
217   NAPI_CALL(env, napi_adjust_external_memory(env, 1, &adjustedValue));
218   NAPI_CALL(env, napi_create_double(env, (double)adjustedValue, &result));
219 
220   return result;
221 }
222 
testNapiRun(napi_env env,napi_callback_info info)223 static napi_value testNapiRun(napi_env env, napi_callback_info info) {
224   napi_value script, result;
225   size_t argc = 1;
226 
227   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, &script, NULL, NULL));
228 
229   NAPI_CALL(env, napi_run_script(env, script, &result));
230 
231   return result;
232 }
233 
finalizer_only_callback(napi_env env,void * data,void * hint)234 static void finalizer_only_callback(napi_env env, void* data, void* hint) {
235   napi_ref js_cb_ref = data;
236   napi_value js_cb, undefined;
237   NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, js_cb_ref, &js_cb));
238   NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
239   NAPI_CALL_RETURN_VOID(env,
240       napi_call_function(env, undefined, js_cb, 0, NULL, NULL));
241   NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, js_cb_ref));
242 }
243 
add_finalizer_only(napi_env env,napi_callback_info info)244 static napi_value add_finalizer_only(napi_env env, napi_callback_info info) {
245   size_t argc = 2;
246   napi_value argv[2];
247   napi_ref js_cb_ref;
248 
249   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
250   NAPI_CALL(env, napi_create_reference(env, argv[1], 1, &js_cb_ref));
251   NAPI_CALL(env,
252       napi_add_finalizer(env,
253                          argv[0],
254                          js_cb_ref,
255                          finalizer_only_callback,
256                          NULL,
257                          NULL));
258   return NULL;
259 }
260 
261 static const char* env_cleanup_finalizer_messages[] = {
262   "simple wrap",
263   "wrap, removeWrap",
264   "first wrap",
265   "second wrap"
266 };
267 
cleanup_env_finalizer(napi_env env,void * data,void * hint)268 static void cleanup_env_finalizer(napi_env env, void* data, void* hint) {
269   (void) env;
270   (void) hint;
271 
272   printf("finalize at env cleanup for %s\n",
273       env_cleanup_finalizer_messages[(uintptr_t)data]);
274 }
275 
env_cleanup_wrap(napi_env env,napi_callback_info info)276 static napi_value env_cleanup_wrap(napi_env env, napi_callback_info info) {
277   size_t argc = 2;
278   napi_value argv[2];
279   uint32_t value;
280   uintptr_t ptr_value;
281   NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, NULL, NULL));
282 
283   NAPI_CALL(env, napi_get_value_uint32(env, argv[1], &value));
284 
285   ptr_value = value;
286   return wrap_first_arg(env, info, cleanup_env_finalizer, (void*)ptr_value);
287 }
288 
289 EXTERN_C_START
Init(napi_env env,napi_value exports)290 napi_value Init(napi_env env, napi_value exports) {
291   napi_property_descriptor descriptors[] = {
292     DECLARE_NAPI_PROPERTY("testStrictEquals", testStrictEquals),
293     DECLARE_NAPI_PROPERTY("testGetPrototype", testGetPrototype),
294     DECLARE_NAPI_PROPERTY("testGetVersion", testGetVersion),
295     DECLARE_NAPI_PROPERTY("testNapiRun", testNapiRun),
296     DECLARE_NAPI_PROPERTY("doInstanceOf", doInstanceOf),
297     DECLARE_NAPI_PROPERTY("getUndefined", getUndefined),
298     DECLARE_NAPI_PROPERTY("getNull", getNull),
299     DECLARE_NAPI_PROPERTY("createNapiError", createNapiError),
300     DECLARE_NAPI_PROPERTY("testNapiErrorCleanup", testNapiErrorCleanup),
301     DECLARE_NAPI_PROPERTY("testNapiTypeof", testNapiTypeof),
302     DECLARE_NAPI_PROPERTY("wrap", wrap),
303     DECLARE_NAPI_PROPERTY("envCleanupWrap", env_cleanup_wrap),
304     DECLARE_NAPI_PROPERTY("unwrap", unwrap),
305     DECLARE_NAPI_PROPERTY("removeWrap", remove_wrap),
306     DECLARE_NAPI_PROPERTY("addFinalizerOnly", add_finalizer_only),
307     DECLARE_NAPI_PROPERTY("testFinalizeWrap", test_finalize_wrap),
308     DECLARE_NAPI_PROPERTY("finalizeWasCalled", finalize_was_called),
309     DECLARE_NAPI_PROPERTY("derefItemWasCalled", deref_item_was_called),
310     DECLARE_NAPI_PROPERTY("testAdjustExternalMemory", testAdjustExternalMemory)
311   };
312 
313   NAPI_CALL(env, napi_define_properties(
314       env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
315 
316   return exports;
317 }
318 EXTERN_C_END
319