1 #include <js_native_api.h>
2 #include "../common.h"
3 #include <string.h>
4
5 // these tests validate the handle scope functions in the normal
6 // flow. Forcing gc behavior to fully validate they are doing
7 // the right right thing would be quite hard so we keep it
8 // simple for now.
9
NewScope(napi_env env,napi_callback_info info)10 static napi_value NewScope(napi_env env, napi_callback_info info) {
11 napi_handle_scope scope;
12 napi_value output = NULL;
13
14 NAPI_CALL(env, napi_open_handle_scope(env, &scope));
15 NAPI_CALL(env, napi_create_object(env, &output));
16 NAPI_CALL(env, napi_close_handle_scope(env, scope));
17 return NULL;
18 }
19
NewScopeEscape(napi_env env,napi_callback_info info)20 static napi_value NewScopeEscape(napi_env env, napi_callback_info info) {
21 napi_escapable_handle_scope scope;
22 napi_value output = NULL;
23 napi_value escapee = NULL;
24
25 NAPI_CALL(env, napi_open_escapable_handle_scope(env, &scope));
26 NAPI_CALL(env, napi_create_object(env, &output));
27 NAPI_CALL(env, napi_escape_handle(env, scope, output, &escapee));
28 NAPI_CALL(env, napi_close_escapable_handle_scope(env, scope));
29 return escapee;
30 }
31
NewScopeEscapeTwice(napi_env env,napi_callback_info info)32 static napi_value NewScopeEscapeTwice(napi_env env, napi_callback_info info) {
33 napi_escapable_handle_scope scope;
34 napi_value output = NULL;
35 napi_value escapee = NULL;
36 napi_status status;
37
38 NAPI_CALL(env, napi_open_escapable_handle_scope(env, &scope));
39 NAPI_CALL(env, napi_create_object(env, &output));
40 NAPI_CALL(env, napi_escape_handle(env, scope, output, &escapee));
41 status = napi_escape_handle(env, scope, output, &escapee);
42 NAPI_ASSERT(env, status == napi_escape_called_twice, "Escaping twice fails");
43 NAPI_CALL(env, napi_close_escapable_handle_scope(env, scope));
44 return NULL;
45 }
46
NewScopeWithException(napi_env env,napi_callback_info info)47 static napi_value NewScopeWithException(napi_env env, napi_callback_info info) {
48 napi_handle_scope scope;
49 size_t argc;
50 napi_value exception_function;
51 napi_status status;
52 napi_value output = NULL;
53
54 NAPI_CALL(env, napi_open_handle_scope(env, &scope));
55 NAPI_CALL(env, napi_create_object(env, &output));
56
57 argc = 1;
58 NAPI_CALL(env, napi_get_cb_info(
59 env, info, &argc, &exception_function, NULL, NULL));
60
61 status = napi_call_function(
62 env, output, exception_function, 0, NULL, NULL);
63 NAPI_ASSERT(env, status == napi_pending_exception,
64 "Function should have thrown.");
65
66 // Closing a handle scope should still work while an exception is pending.
67 NAPI_CALL(env, napi_close_handle_scope(env, scope));
68 return NULL;
69 }
70
71 EXTERN_C_START
Init(napi_env env,napi_value exports)72 napi_value Init(napi_env env, napi_value exports) {
73 napi_property_descriptor properties[] = {
74 DECLARE_NAPI_PROPERTY("NewScope", NewScope),
75 DECLARE_NAPI_PROPERTY("NewScopeEscape", NewScopeEscape),
76 DECLARE_NAPI_PROPERTY("NewScopeEscapeTwice", NewScopeEscapeTwice),
77 DECLARE_NAPI_PROPERTY("NewScopeWithException", NewScopeWithException),
78 };
79
80 NAPI_CALL(env, napi_define_properties(
81 env, exports, sizeof(properties) / sizeof(*properties), properties));
82
83 return exports;
84 }
85 EXTERN_C_END
86