/
binding.cc
123 lines (93 loc) Β· 3.92 KB
/
binding.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
#include "node_api.h"
#include "uv.h"
#include "../../js-native-api/common.h"
namespace {
napi_value RunInCallbackScope(napi_env env, napi_callback_info info) {
size_t argc;
napi_value args[3];
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, nullptr, nullptr, nullptr));
NAPI_ASSERT(env, argc == 3 , "Wrong number of arguments");
NAPI_CALL(env, napi_get_cb_info(env, info, &argc, args, nullptr, nullptr));
napi_valuetype valuetype;
NAPI_CALL(env, napi_typeof(env, args[0], &valuetype));
NAPI_ASSERT(env, valuetype == napi_object,
"Wrong type of arguments. Expects an object as first argument.");
NAPI_CALL(env, napi_typeof(env, args[1], &valuetype));
NAPI_ASSERT(env, valuetype == napi_string,
"Wrong type of arguments. Expects a string as second argument.");
NAPI_CALL(env, napi_typeof(env, args[2], &valuetype));
NAPI_ASSERT(env, valuetype == napi_function,
"Wrong type of arguments. Expects a function as third argument.");
napi_async_context context;
NAPI_CALL(env, napi_async_init(env, args[0], args[1], &context));
napi_callback_scope scope = nullptr;
NAPI_CALL(
env,
napi_open_callback_scope(env,
args[0],
context,
&scope));
// if the function has an exception pending after the call that is ok
// so we don't use NAPI_CALL as we must close the callback scope regardless
napi_value result = nullptr;
napi_status function_call_result =
napi_call_function(env, args[0], args[2], 0, nullptr, &result);
if (function_call_result != napi_ok) {
GET_AND_THROW_LAST_ERROR((env));
}
NAPI_CALL(env, napi_close_callback_scope(env, scope));
return result;
}
static napi_env shared_env = nullptr;
static napi_deferred deferred = nullptr;
static void Callback(uv_work_t* req, int ignored) {
napi_env env = shared_env;
napi_handle_scope handle_scope = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_open_handle_scope(env, &handle_scope));
napi_value resource_name;
NAPI_CALL_RETURN_VOID(env, napi_create_string_utf8(
env, "test", NAPI_AUTO_LENGTH, &resource_name));
napi_async_context context;
NAPI_CALL_RETURN_VOID(env,
napi_async_init(env, nullptr, resource_name, &context));
napi_value resource_object;
NAPI_CALL_RETURN_VOID(env, napi_create_object(env, &resource_object));
napi_value undefined_value;
NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined_value));
napi_callback_scope scope = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_open_callback_scope(env,
resource_object,
context,
&scope));
NAPI_CALL_RETURN_VOID(env,
napi_resolve_deferred(env, deferred, undefined_value));
NAPI_CALL_RETURN_VOID(env, napi_close_callback_scope(env, scope));
NAPI_CALL_RETURN_VOID(env, napi_close_handle_scope(env, handle_scope));
delete req;
}
napi_value TestResolveAsync(napi_env env, napi_callback_info info) {
napi_value promise = nullptr;
if (deferred == nullptr) {
shared_env = env;
NAPI_CALL(env, napi_create_promise(env, &deferred, &promise));
uv_loop_t* loop = nullptr;
NAPI_CALL(env, napi_get_uv_event_loop(env, &loop));
uv_work_t* req = new uv_work_t();
uv_queue_work(loop,
req,
[](uv_work_t*) {},
Callback);
}
return promise;
}
napi_value Init(napi_env env, napi_value exports) {
napi_property_descriptor descriptors[] = {
DECLARE_NAPI_PROPERTY("runInCallbackScope", RunInCallbackScope),
DECLARE_NAPI_PROPERTY("testResolveAsync", TestResolveAsync)
};
NAPI_CALL(env, napi_define_properties(
env, exports, sizeof(descriptors) / sizeof(*descriptors), descriptors));
return exports;
}
} // anonymous namespace
NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)