emnapi 1.9.2 → 2.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +127 -57
- package/README.md +164 -776
- package/cmake/wasm32.cmake +0 -3
- package/common.gypi +16 -14
- package/dist/library_async_work.js +390 -0
- package/dist/library_napi.js +1743 -2759
- package/dist/library_threadsafe_function.js +1178 -0
- package/dist/library_v8.js +1594 -0
- package/emnapi.gyp +37 -0
- package/include/node/emnapi.h +39 -3
- package/include/node/js_native_api.h +10 -0
- package/include/node/js_native_api_types.h +26 -0
- package/include/node/node.h +198 -0
- package/include/node/node_api.h +0 -10
- package/include/node/node_buffer.h +92 -0
- package/include/node/node_object_wrap.h +132 -0
- package/include/node/node_version.h +110 -0
- package/include/node/uv/unix.h +1 -0
- package/include/node/uv/version.h +43 -0
- package/include/node/uv.h +6 -0
- package/index.js +15 -7
- package/lib/wasm32-emscripten/libemnapi-mt.a +0 -0
- package/lib/wasm32-emscripten/libemnapi.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi-mt.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi-napi-rs-mt.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi.a +0 -0
- package/lib/wasm64-emscripten/libemnapi-mt.a +0 -0
- package/lib/wasm64-emscripten/libemnapi.a +0 -0
- package/package.json +1 -1
- package/src/async_cleanup_hook.c +6 -6
- package/src/emnapi_internal.h +5 -10
- package/src/js_native_api.c +37 -21
- package/src/js_native_api_internal.h +66 -0
- package/src/node_api.c +1 -1
- package/src/threadsafe_function.c +2 -2
- package/src/uv/unix/thread.c +21 -0
- package/src/v8/array.cc +19 -0
- package/src/v8/boolean.cc +26 -0
- package/src/v8/date.cc +15 -0
- package/src/v8/exception.cc +48 -0
- package/src/v8/external.cc +23 -0
- package/src/v8/function.cc +35 -0
- package/src/v8/handle_scope.cc +46 -0
- package/src/v8/internal.cc +126 -0
- package/src/v8/internal.h +41 -0
- package/src/v8/isolate.cc +35 -0
- package/src/v8/json.cc +25 -0
- package/src/v8/node.cc +24 -0
- package/src/v8/number.cc +62 -0
- package/src/v8/object.cc +106 -0
- package/src/v8/script.cc +75 -0
- package/src/v8/string.cc +104 -0
- package/src/v8/template.cc +234 -0
- package/src/v8/try_catch.cc +50 -0
- package/src/v8/v8_impl.h +42 -0
- package/src/v8/value.cc +138 -0
- package/lib/wasm32/libdlmalloc-mt.a +0 -0
- package/lib/wasm32/libdlmalloc.a +0 -0
- package/lib/wasm32/libemmalloc-mt.a +0 -0
- package/lib/wasm32/libemmalloc.a +0 -0
- package/lib/wasm32/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32/libemnapi-basic.a +0 -0
- package/lib/wasm32/libemnapi.a +0 -0
- package/lib/wasm32-emscripten/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasi/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32-wasi/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasi/libemnapi.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi-basic-napi-rs-mt.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi-mt.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi-napi-rs-mt.a +0 -0
- package/lib/wasm32-wasi-threads/libemnapi.a +0 -0
- package/lib/wasm32-wasip1/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32-wasip1/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasip1/libemnapi.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi-basic-mt.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi-basic-napi-rs-mt.a +0 -0
- package/lib/wasm32-wasip1-threads/libemnapi-basic.a +0 -0
- package/lib/wasm64-emscripten/libemnapi-basic.a +0 -0
|
@@ -0,0 +1,1178 @@
|
|
|
1
|
+
//#region src/emscripten/init.ts
|
|
2
|
+
/* eslint-disable @stylistic/indent */
|
|
3
|
+
var emnapiCtx$1 = undefined;
|
|
4
|
+
var emnapiEnv = undefined;
|
|
5
|
+
// export var emnapiRuntimeModuleExports: any = undefined!
|
|
6
|
+
var emnapiNodeBinding$1 = undefined;
|
|
7
|
+
var emnapiAsyncWorkPoolSize = 0;
|
|
8
|
+
const emnapiModule = {
|
|
9
|
+
exports: {},
|
|
10
|
+
loaded: false,
|
|
11
|
+
filename: ''
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* @__deps emnapi_create_env
|
|
15
|
+
* @__deps emnapi_delete_env
|
|
16
|
+
*/
|
|
17
|
+
function emnapiInit(options) {
|
|
18
|
+
if (emnapiModule.loaded)
|
|
19
|
+
return emnapiModule.exports;
|
|
20
|
+
if (typeof options !== 'object' || options === null) {
|
|
21
|
+
throw new TypeError('Invalid emnapi init option');
|
|
22
|
+
}
|
|
23
|
+
const context = options.context;
|
|
24
|
+
if (typeof context !== 'object' || context === null) {
|
|
25
|
+
throw new TypeError("Invalid `options.context`. Use `import { getDefaultContext } from '@emnapi/runtime'`");
|
|
26
|
+
}
|
|
27
|
+
emnapiCtx$1 = context;
|
|
28
|
+
const filename = typeof options.filename === 'string' ? options.filename : '';
|
|
29
|
+
emnapiModule.filename = filename;
|
|
30
|
+
if ('nodeBinding' in options) {
|
|
31
|
+
const nodeBinding = options.nodeBinding;
|
|
32
|
+
if (typeof nodeBinding !== 'object' || nodeBinding === null) {
|
|
33
|
+
throw new TypeError('Invalid `options.nodeBinding`. Use @emnapi/node-binding package');
|
|
34
|
+
}
|
|
35
|
+
emnapiNodeBinding$1 = nodeBinding;
|
|
36
|
+
}
|
|
37
|
+
if ('asyncWorkPoolSize' in options) {
|
|
38
|
+
if (typeof options.asyncWorkPoolSize !== 'number') {
|
|
39
|
+
throw new TypeError('options.asyncWorkPoolSize must be a integer');
|
|
40
|
+
}
|
|
41
|
+
emnapiAsyncWorkPoolSize = options.asyncWorkPoolSize >> 0;
|
|
42
|
+
if (emnapiAsyncWorkPoolSize > 1024) {
|
|
43
|
+
emnapiAsyncWorkPoolSize = 1024;
|
|
44
|
+
}
|
|
45
|
+
else if (emnapiAsyncWorkPoolSize < -1024) {
|
|
46
|
+
emnapiAsyncWorkPoolSize = -1024;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const NODE_MODULE_VERSION = 127 /* Version.NODE_MODULE_VERSION */;
|
|
50
|
+
const nodeRegisterModuleSymbol = `node_register_module_v${NODE_MODULE_VERSION}`;
|
|
51
|
+
const emscriptenExportedSymbol = `_${nodeRegisterModuleSymbol}`;
|
|
52
|
+
if (typeof Module[emscriptenExportedSymbol] === 'function') {
|
|
53
|
+
const scope = emnapiCtx$1.isolate.openScope();
|
|
54
|
+
try {
|
|
55
|
+
const exports = emnapiModule.exports;
|
|
56
|
+
const exportsHandle = scope.add(exports);
|
|
57
|
+
const moduleHandle = scope.add(emnapiModule);
|
|
58
|
+
Module[emscriptenExportedSymbol]({{{ to64('exportsHandle') }}}, {{{ to64('moduleHandle') }}}, {{{ to64('5') }}});
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
if (err !== 'unwind') {
|
|
62
|
+
throw err;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
emnapiCtx$1.isolate.closeScope(scope);
|
|
67
|
+
}
|
|
68
|
+
emnapiModule.loaded = true;
|
|
69
|
+
delete emnapiModule.envObject;
|
|
70
|
+
return emnapiModule.exports;
|
|
71
|
+
}
|
|
72
|
+
const find = Object.keys(Module).filter(k => k.startsWith('_node_register_module_v'));
|
|
73
|
+
if (find.length > 0) {
|
|
74
|
+
throw new Error(`The module${emnapiModule.filename ? ` '${emnapiModule.filename}'` : ''}
|
|
75
|
+
was compiled against a different Node.js version using
|
|
76
|
+
NODE_MODULE_VERSION ${find[0].slice(23)}. This version of Node.js requires
|
|
77
|
+
NODE_MODULE_VERSION ${NODE_MODULE_VERSION}.`);
|
|
78
|
+
}
|
|
79
|
+
const moduleApiVersion = Module._node_api_module_get_api_version_v1();
|
|
80
|
+
const envObject = emnapiModule.envObject || (() => {
|
|
81
|
+
let address = _emnapi_create_env();
|
|
82
|
+
{{{ from64('address') }}};
|
|
83
|
+
address += 8;
|
|
84
|
+
const envObject = emnapiModule.envObject = emnapiEnv = emnapiCtx$1.createEnv(filename, moduleApiVersion, {
|
|
85
|
+
address,
|
|
86
|
+
deleteEnv: (ptr) => {
|
|
87
|
+
_emnapi_delete_env({{{ to64('ptr') }}} - {{{ to64('8') }}});
|
|
88
|
+
},
|
|
89
|
+
setLastError(env, error_code, engine_error_code, engine_reserved) {
|
|
90
|
+
{{{ from64('env') }}};
|
|
91
|
+
env -= 8;
|
|
92
|
+
{{{ from64('engine_reserved') }}};
|
|
93
|
+
#if MEMORY64
|
|
94
|
+
{{{ makeSetValue('env', 60 /* NapiEnvOffset64.last_error_error_code */, 'error_code', 'i32') }}};
|
|
95
|
+
{{{ makeSetValue('env', 56 /* NapiEnvOffset64.last_error_engine_error_code */, 'engine_error_code', 'u32') }}};
|
|
96
|
+
{{{ makeSetValue('env', 48 /* NapiEnvOffset64.last_error_engine_reserved */, 'engine_reserved', '*') }}};
|
|
97
|
+
#else
|
|
98
|
+
{{{ makeSetValue('env', 40 /* NapiEnvOffset32.last_error_error_code */, 'error_code', 'i32') }}};
|
|
99
|
+
{{{ makeSetValue('env', 36 /* NapiEnvOffset32.last_error_engine_error_code */, 'engine_error_code', 'u32') }}};
|
|
100
|
+
{{{ makeSetValue('env', 32 /* NapiEnvOffset32.last_error_engine_reserved */, 'engine_reserved', '*') }}};
|
|
101
|
+
#endif
|
|
102
|
+
return error_code;
|
|
103
|
+
},
|
|
104
|
+
makeDynCall_vppp: (cb) => {{{ makeDynCall('vppp', 'cb') }}},
|
|
105
|
+
makeDynCall_vp: (cb) => {{{ makeDynCall('vp', 'cb') }}},
|
|
106
|
+
abort
|
|
107
|
+
}, emnapiNodeBinding$1);
|
|
108
|
+
#if MEMORY64
|
|
109
|
+
{{{ makeSetValue('address - 8', 32 /* NapiEnvOffset64.id */, 'envObject.id', 'u32') }}};
|
|
110
|
+
#else
|
|
111
|
+
{{{ makeSetValue('address - 8', 24 /* NapiEnvOffset32.id */, 'envObject.id', 'u32') }}};
|
|
112
|
+
#endif
|
|
113
|
+
return envObject;
|
|
114
|
+
})();
|
|
115
|
+
const scope = emnapiCtx$1.openScope(envObject);
|
|
116
|
+
try {
|
|
117
|
+
envObject.callIntoModule((envObject) => {
|
|
118
|
+
const exports = emnapiModule.exports;
|
|
119
|
+
const env = envObject.bridge.address;
|
|
120
|
+
const exportsHandle = scope.add(exports);
|
|
121
|
+
const napiValue = Module._napi_register_wasm_v1({{{ to64('env') }}}, {{{ to64('exportsHandle') }}});
|
|
122
|
+
emnapiModule.exports = (!napiValue) ? exports : emnapiCtx$1.jsValueFromNapiValue(napiValue);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
if (err !== 'unwind') {
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
emnapiCtx$1.closeScope(envObject, scope);
|
|
132
|
+
}
|
|
133
|
+
emnapiModule.loaded = true;
|
|
134
|
+
delete emnapiModule.envObject;
|
|
135
|
+
return emnapiModule.exports;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* @__sig i
|
|
139
|
+
*/
|
|
140
|
+
function _emnapi_async_work_pool_size() {
|
|
141
|
+
return Math.abs(emnapiAsyncWorkPoolSize);
|
|
142
|
+
}
|
|
143
|
+
//#endregion src/emscripten/init.ts
|
|
144
|
+
//#region src/macro.ts
|
|
145
|
+
//#endregion src/macro.ts
|
|
146
|
+
//#region src/threadsafe-function.ts
|
|
147
|
+
/* eslint-disable @stylistic/indent */
|
|
148
|
+
/**
|
|
149
|
+
* @__deps malloc
|
|
150
|
+
* @__deps free
|
|
151
|
+
* @__deps $emnapiCtx
|
|
152
|
+
* @__deps $emnapiEnv
|
|
153
|
+
* @__deps $emnapiNodeBinding
|
|
154
|
+
* @__deps _emnapi_node_emit_async_destroy
|
|
155
|
+
* @__deps _emnapi_runtime_keepalive_pop
|
|
156
|
+
* @__postset
|
|
157
|
+
* ```
|
|
158
|
+
* emnapiTSFN.init();
|
|
159
|
+
* ```
|
|
160
|
+
*/
|
|
161
|
+
const emnapiTSFN = {
|
|
162
|
+
_liveSet: {},
|
|
163
|
+
offset: {
|
|
164
|
+
__size__: 0,
|
|
165
|
+
/* napi_ref */ resource: 0,
|
|
166
|
+
/* double */ async_id: 0,
|
|
167
|
+
/* double */ trigger_async_id: 0,
|
|
168
|
+
/* size_t */ queue_size: 0,
|
|
169
|
+
/* bool */ is_some: 0,
|
|
170
|
+
/* void* */ queue: 0,
|
|
171
|
+
// Reuse uv_async_t storage as JS-side wakeup state: pending event + scheduled drain.
|
|
172
|
+
async_pending: 0,
|
|
173
|
+
async_u_fd: 0,
|
|
174
|
+
/* size_t */ thread_count: 0,
|
|
175
|
+
/* int32_t */ state: 0,
|
|
176
|
+
/* atomic_uchar */ dispatch_state: 0,
|
|
177
|
+
/* void* */ context: 0,
|
|
178
|
+
/* size_t */ max_queue_size: 0,
|
|
179
|
+
/* napi_ref */ ref: 0,
|
|
180
|
+
/* napi_env */ env: 0,
|
|
181
|
+
/* void* */ finalize_data: 0,
|
|
182
|
+
/* napi_finalize */ finalize_cb: 0,
|
|
183
|
+
/* napi_threadsafe_function_call_js */ call_js_cb: 0,
|
|
184
|
+
/* bool */ handles_closing: 0,
|
|
185
|
+
/* bool */ async_ref: 0,
|
|
186
|
+
/* int32_t */ mutex: 0,
|
|
187
|
+
/* int32_t */ cond: 0,
|
|
188
|
+
},
|
|
189
|
+
init() {
|
|
190
|
+
emnapiTSFN._liveSet = new Set();
|
|
191
|
+
#if MEMORY64
|
|
192
|
+
emnapiTSFN.offset.__size__ = 320 /* NapiTSFNOffset64.__size__ */;
|
|
193
|
+
emnapiTSFN.offset.resource = 0 /* NapiTSFNOffset64.async_resource_resource */;
|
|
194
|
+
emnapiTSFN.offset.async_id = 8 /* NapiTSFNOffset64.async_resource_async_context_async_id */;
|
|
195
|
+
emnapiTSFN.offset.trigger_async_id = 16 /* NapiTSFNOffset64.async_resource_async_context_trigger_async_id */;
|
|
196
|
+
emnapiTSFN.offset.queue_size = 88 /* NapiTSFNOffset64.queue_size */;
|
|
197
|
+
emnapiTSFN.offset.is_some = 24 /* NapiTSFNOffset64.async_resource_is_some */;
|
|
198
|
+
emnapiTSFN.offset.queue = 96 /* NapiTSFNOffset64.queue */;
|
|
199
|
+
emnapiTSFN.offset.async_pending = 232 /* NapiTSFNOffset64.async_pending */;
|
|
200
|
+
emnapiTSFN.offset.async_u_fd = 160 /* NapiTSFNOffset64.async_u_fd */;
|
|
201
|
+
emnapiTSFN.offset.thread_count = 240 /* NapiTSFNOffset64.thread_count */;
|
|
202
|
+
emnapiTSFN.offset.state = 248 /* NapiTSFNOffset64.state */;
|
|
203
|
+
emnapiTSFN.offset.dispatch_state = 252 /* NapiTSFNOffset64.dispatch_state */;
|
|
204
|
+
emnapiTSFN.offset.context = 256 /* NapiTSFNOffset64.context */;
|
|
205
|
+
emnapiTSFN.offset.max_queue_size = 264 /* NapiTSFNOffset64.max_queue_size */;
|
|
206
|
+
emnapiTSFN.offset.ref = 272 /* NapiTSFNOffset64.ref */;
|
|
207
|
+
emnapiTSFN.offset.env = 280 /* NapiTSFNOffset64.env */;
|
|
208
|
+
emnapiTSFN.offset.finalize_data = 288 /* NapiTSFNOffset64.finalize_data */;
|
|
209
|
+
emnapiTSFN.offset.finalize_cb = 296 /* NapiTSFNOffset64.finalize_cb */;
|
|
210
|
+
emnapiTSFN.offset.call_js_cb = 304 /* NapiTSFNOffset64.call_js_cb */;
|
|
211
|
+
emnapiTSFN.offset.handles_closing = 312 /* NapiTSFNOffset64.handles_closing */;
|
|
212
|
+
emnapiTSFN.offset.async_ref = 316 /* NapiTSFNOffset64.async_ref */;
|
|
213
|
+
emnapiTSFN.offset.mutex = 32 /* NapiTSFNOffset64.mutex */;
|
|
214
|
+
emnapiTSFN.offset.cond = 80 /* NapiTSFNOffset64.cond */;
|
|
215
|
+
#else
|
|
216
|
+
emnapiTSFN.offset.__size__ = 184 /* NapiTSFNOffset32.__size__ */;
|
|
217
|
+
emnapiTSFN.offset.resource = 0 /* NapiTSFNOffset32.async_resource_resource */;
|
|
218
|
+
emnapiTSFN.offset.async_id = 8 /* NapiTSFNOffset32.async_resource_async_context_async_id */;
|
|
219
|
+
emnapiTSFN.offset.trigger_async_id = 16 /* NapiTSFNOffset32.async_resource_async_context_trigger_async_id */;
|
|
220
|
+
emnapiTSFN.offset.queue_size = 60 /* NapiTSFNOffset32.queue_size */;
|
|
221
|
+
emnapiTSFN.offset.is_some = 24 /* NapiTSFNOffset32.async_resource_is_some */;
|
|
222
|
+
emnapiTSFN.offset.queue = 64 /* NapiTSFNOffset32.queue */;
|
|
223
|
+
emnapiTSFN.offset.async_pending = 132 /* NapiTSFNOffset32.async_pending */;
|
|
224
|
+
emnapiTSFN.offset.async_u_fd = 96 /* NapiTSFNOffset32.async_u_fd */;
|
|
225
|
+
emnapiTSFN.offset.thread_count = 136 /* NapiTSFNOffset32.thread_count */;
|
|
226
|
+
emnapiTSFN.offset.state = 140 /* NapiTSFNOffset32.state */;
|
|
227
|
+
emnapiTSFN.offset.dispatch_state = 144 /* NapiTSFNOffset32.dispatch_state */;
|
|
228
|
+
emnapiTSFN.offset.context = 148 /* NapiTSFNOffset32.context */;
|
|
229
|
+
emnapiTSFN.offset.max_queue_size = 152 /* NapiTSFNOffset32.max_queue_size */;
|
|
230
|
+
emnapiTSFN.offset.ref = 156 /* NapiTSFNOffset32.ref */;
|
|
231
|
+
emnapiTSFN.offset.env = 160 /* NapiTSFNOffset32.env */;
|
|
232
|
+
emnapiTSFN.offset.finalize_data = 164 /* NapiTSFNOffset32.finalize_data */;
|
|
233
|
+
emnapiTSFN.offset.finalize_cb = 168 /* NapiTSFNOffset32.finalize_cb */;
|
|
234
|
+
emnapiTSFN.offset.call_js_cb = 172 /* NapiTSFNOffset32.call_js_cb */;
|
|
235
|
+
emnapiTSFN.offset.handles_closing = 176 /* NapiTSFNOffset32.handles_closing */;
|
|
236
|
+
emnapiTSFN.offset.async_ref = 180 /* NapiTSFNOffset32.async_ref */;
|
|
237
|
+
emnapiTSFN.offset.mutex = 32 /* NapiTSFNOffset32.mutex */;
|
|
238
|
+
emnapiTSFN.offset.cond = 56 /* NapiTSFNOffset32.cond */;
|
|
239
|
+
#endif
|
|
240
|
+
emnapiTSFN.offset.mutex = emnapiTSFN.offset.mutex + 4;
|
|
241
|
+
if (typeof PThread !== 'undefined') {
|
|
242
|
+
PThread.unusedWorkers.forEach(emnapiTSFN.addListener);
|
|
243
|
+
PThread.runningWorkers.forEach(emnapiTSFN.addListener);
|
|
244
|
+
const __original_getNewWorker = PThread.getNewWorker;
|
|
245
|
+
PThread.getNewWorker = function () {
|
|
246
|
+
const r = __original_getNewWorker.apply(this, arguments);
|
|
247
|
+
emnapiTSFN.addListener(r);
|
|
248
|
+
return r;
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
},
|
|
252
|
+
addListener(worker) {
|
|
253
|
+
if (!worker)
|
|
254
|
+
return false;
|
|
255
|
+
if (worker._emnapiTSFNListener)
|
|
256
|
+
return true;
|
|
257
|
+
const handler = function (e) {
|
|
258
|
+
const data = ENVIRONMENT_IS_NODE ? e : e.data;
|
|
259
|
+
const __emnapi__ = data.__emnapi__;
|
|
260
|
+
if (__emnapi__) {
|
|
261
|
+
const type = __emnapi__.type;
|
|
262
|
+
const payload = __emnapi__.payload;
|
|
263
|
+
if (type === 'tsfn-send') {
|
|
264
|
+
const pendng = payload.tsfn + emnapiTSFN.offset.async_pending;
|
|
265
|
+
if (Atomics.load(new Int32Array(wasmMemory.buffer), pendng >>> 2) !== 0) {
|
|
266
|
+
emnapiTSFN.enqueue(payload.tsfn);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
};
|
|
271
|
+
const dispose = function () {
|
|
272
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
273
|
+
worker.off('message', handler);
|
|
274
|
+
}
|
|
275
|
+
else {
|
|
276
|
+
worker.removeEventListener('message', handler, false);
|
|
277
|
+
}
|
|
278
|
+
delete worker._emnapiTSFNListener;
|
|
279
|
+
};
|
|
280
|
+
worker._emnapiTSFNListener = { handler, dispose };
|
|
281
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
282
|
+
worker.on('message', handler);
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
worker.addEventListener('message', handler, false);
|
|
286
|
+
}
|
|
287
|
+
return true;
|
|
288
|
+
},
|
|
289
|
+
initQueue(func) {
|
|
290
|
+
const size = 2 * {{{ POINTER_SIZE }}};
|
|
291
|
+
let queue = _malloc({{{ to64('size') }}});
|
|
292
|
+
if (!queue)
|
|
293
|
+
return false;
|
|
294
|
+
{{{ from64('queue') }}};
|
|
295
|
+
new Uint8Array(wasmMemory.buffer, queue, size).fill(0);
|
|
296
|
+
emnapiTSFN.storeSizeTypeValue(func + emnapiTSFN.offset.queue, queue, false);
|
|
297
|
+
return true;
|
|
298
|
+
},
|
|
299
|
+
destroyQueue(func) {
|
|
300
|
+
const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
|
|
301
|
+
if (queue) {
|
|
302
|
+
let node = emnapiTSFN.loadSizeTypeValue(queue, false);
|
|
303
|
+
while (node !== 0) {
|
|
304
|
+
const next = emnapiTSFN.loadSizeTypeValue(node + {{{ POINTER_SIZE }}}, false);
|
|
305
|
+
_free({{{ to64('node') }}});
|
|
306
|
+
node = next;
|
|
307
|
+
}
|
|
308
|
+
_free({{{ to64('queue') }}});
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
pushQueue(func, data) {
|
|
312
|
+
const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
|
|
313
|
+
const head = emnapiTSFN.loadSizeTypeValue(queue, false);
|
|
314
|
+
const tail = emnapiTSFN.loadSizeTypeValue(queue + {{{ POINTER_SIZE }}}, false);
|
|
315
|
+
const size = 2 * {{{ POINTER_SIZE }}};
|
|
316
|
+
let node = _malloc({{{ to64('size') }}});
|
|
317
|
+
if (!node)
|
|
318
|
+
throw new Error('OOM');
|
|
319
|
+
{{{ from64('node') }}};
|
|
320
|
+
emnapiTSFN.storeSizeTypeValue(node, data, false);
|
|
321
|
+
emnapiTSFN.storeSizeTypeValue(node + {{{ POINTER_SIZE }}}, 0, false);
|
|
322
|
+
if (head === 0 && tail === 0) {
|
|
323
|
+
emnapiTSFN.storeSizeTypeValue(queue, node, false);
|
|
324
|
+
emnapiTSFN.storeSizeTypeValue(queue + {{{ POINTER_SIZE }}}, node, false);
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
emnapiTSFN.storeSizeTypeValue(tail + {{{ POINTER_SIZE }}}, node, false);
|
|
328
|
+
emnapiTSFN.storeSizeTypeValue(queue + {{{ POINTER_SIZE }}}, node, false);
|
|
329
|
+
}
|
|
330
|
+
emnapiTSFN.addQueueSize(func);
|
|
331
|
+
},
|
|
332
|
+
shiftQueue(func) {
|
|
333
|
+
const queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
|
|
334
|
+
const head = emnapiTSFN.loadSizeTypeValue(queue, false);
|
|
335
|
+
if (head === 0)
|
|
336
|
+
return 0;
|
|
337
|
+
const node = head;
|
|
338
|
+
const next = emnapiTSFN.loadSizeTypeValue(head + {{{ POINTER_SIZE }}}, false);
|
|
339
|
+
emnapiTSFN.storeSizeTypeValue(queue, next, false);
|
|
340
|
+
if (next === 0) {
|
|
341
|
+
emnapiTSFN.storeSizeTypeValue(queue + {{{ POINTER_SIZE }}}, 0, false);
|
|
342
|
+
}
|
|
343
|
+
emnapiTSFN.storeSizeTypeValue(node + {{{ POINTER_SIZE }}}, 0, false);
|
|
344
|
+
const value = emnapiTSFN.loadSizeTypeValue(node, false);
|
|
345
|
+
_free({{{ to64('node') }}});
|
|
346
|
+
emnapiTSFN.subQueueSize(func);
|
|
347
|
+
return value;
|
|
348
|
+
},
|
|
349
|
+
push(func, data, mode) {
|
|
350
|
+
const mutex = emnapiTSFN.getMutex(func);
|
|
351
|
+
const cond = emnapiTSFN.getCond(func);
|
|
352
|
+
const waitCondition = () => {
|
|
353
|
+
const queueSize = emnapiTSFN.getQueueSize(func);
|
|
354
|
+
const maxSize = emnapiTSFN.getMaxQueueSize(func);
|
|
355
|
+
return queueSize >= maxSize && maxSize > 0 && emnapiTSFN.getState(func) === 0 /* State.kOpen */;
|
|
356
|
+
};
|
|
357
|
+
const isBrowserMain = typeof window !== 'undefined' && typeof document !== 'undefined' && !ENVIRONMENT_IS_NODE;
|
|
358
|
+
let shouldDelete = false;
|
|
359
|
+
const ret = mutex.execute(() => {
|
|
360
|
+
while (waitCondition()) {
|
|
361
|
+
if (mode === 0 /* napi_threadsafe_function_call_mode.napi_tsfn_nonblocking */) {
|
|
362
|
+
return 15 /* napi_status.napi_queue_full */;
|
|
363
|
+
}
|
|
364
|
+
/**
|
|
365
|
+
* Browser JS main thread can not use `Atomics.wait`
|
|
366
|
+
*
|
|
367
|
+
* Related:
|
|
368
|
+
* https://github.com/nodejs/node/pull/32689
|
|
369
|
+
* https://github.com/nodejs/node/pull/33453
|
|
370
|
+
*/
|
|
371
|
+
if (isBrowserMain) {
|
|
372
|
+
return 21 /* napi_status.napi_would_deadlock */;
|
|
373
|
+
}
|
|
374
|
+
cond.wait();
|
|
375
|
+
}
|
|
376
|
+
if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
|
|
377
|
+
emnapiTSFN.pushQueue(func, data);
|
|
378
|
+
emnapiTSFN.send(func);
|
|
379
|
+
return 0 /* napi_status.napi_ok */;
|
|
380
|
+
}
|
|
381
|
+
if (emnapiTSFN.getThreadCount(func) === 0) {
|
|
382
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
383
|
+
}
|
|
384
|
+
emnapiTSFN.subThreadCount(func);
|
|
385
|
+
if (!(emnapiTSFN.getState(func) === 2 /* State.kClosed */ && emnapiTSFN.getThreadCount(func) === 0)) {
|
|
386
|
+
return 16 /* napi_status.napi_closing */;
|
|
387
|
+
}
|
|
388
|
+
shouldDelete = true;
|
|
389
|
+
return 16 /* napi_status.napi_closing */;
|
|
390
|
+
});
|
|
391
|
+
if (shouldDelete) {
|
|
392
|
+
emnapiTSFN.destroy(func);
|
|
393
|
+
}
|
|
394
|
+
return ret;
|
|
395
|
+
},
|
|
396
|
+
getMutex(func) {
|
|
397
|
+
const index = func + emnapiTSFN.offset.mutex;
|
|
398
|
+
const mutex = {
|
|
399
|
+
lock() {
|
|
400
|
+
const isBrowserMain = typeof window !== 'undefined' && typeof document !== 'undefined' && !ENVIRONMENT_IS_NODE;
|
|
401
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1);
|
|
402
|
+
if (isBrowserMain) {
|
|
403
|
+
while (true) {
|
|
404
|
+
const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
|
|
405
|
+
if (oldValue === 0) {
|
|
406
|
+
return;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
while (true) {
|
|
412
|
+
const oldValue = Atomics.compareExchange(i32a, 0, 0, 10);
|
|
413
|
+
if (oldValue === 0) {
|
|
414
|
+
return;
|
|
415
|
+
}
|
|
416
|
+
Atomics.wait(i32a, 0, 10);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
},
|
|
420
|
+
/* lockAsync () {
|
|
421
|
+
return new Promise<void>(resolve => {
|
|
422
|
+
const again = (): void => { fn() }
|
|
423
|
+
const fn = (): void => {
|
|
424
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1)
|
|
425
|
+
const oldValue = Atomics.compareExchange(i32a, 0, 0, 10)
|
|
426
|
+
if (oldValue === 0) {
|
|
427
|
+
resolve()
|
|
428
|
+
return
|
|
429
|
+
}
|
|
430
|
+
(Atomics as any).waitAsync(i32a, 0, 10).value.then(again)
|
|
431
|
+
}
|
|
432
|
+
fn()
|
|
433
|
+
})
|
|
434
|
+
}, */
|
|
435
|
+
unlock() {
|
|
436
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1);
|
|
437
|
+
const oldValue = Atomics.compareExchange(i32a, 0, 10, 0);
|
|
438
|
+
if (oldValue !== 10) {
|
|
439
|
+
throw new Error('Tried to unlock while not holding the mutex');
|
|
440
|
+
}
|
|
441
|
+
Atomics.notify(i32a, 0, 1);
|
|
442
|
+
},
|
|
443
|
+
execute(fn) {
|
|
444
|
+
mutex.lock();
|
|
445
|
+
try {
|
|
446
|
+
return fn();
|
|
447
|
+
}
|
|
448
|
+
finally {
|
|
449
|
+
mutex.unlock();
|
|
450
|
+
}
|
|
451
|
+
} /* ,
|
|
452
|
+
executeAsync<T> (fn: () => Promise<T>): Promise<T> {
|
|
453
|
+
return mutex.lockAsync().then(() => {
|
|
454
|
+
const r = fn()
|
|
455
|
+
mutex.unlock()
|
|
456
|
+
return r
|
|
457
|
+
}, (err) => {
|
|
458
|
+
mutex.unlock()
|
|
459
|
+
throw err
|
|
460
|
+
})
|
|
461
|
+
} */
|
|
462
|
+
};
|
|
463
|
+
return mutex;
|
|
464
|
+
},
|
|
465
|
+
getCond(func) {
|
|
466
|
+
const index = func + emnapiTSFN.offset.cond;
|
|
467
|
+
const mutex = emnapiTSFN.getMutex(func);
|
|
468
|
+
const cond = {
|
|
469
|
+
wait() {
|
|
470
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1);
|
|
471
|
+
const value = Atomics.load(i32a, 0);
|
|
472
|
+
mutex.unlock();
|
|
473
|
+
Atomics.wait(i32a, 0, value);
|
|
474
|
+
mutex.lock();
|
|
475
|
+
},
|
|
476
|
+
/* waitAsync () {
|
|
477
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1)
|
|
478
|
+
const value = Atomics.load(i32a, 0)
|
|
479
|
+
mutex.unlock()
|
|
480
|
+
const lock = (): Promise<void> => mutex.lockAsync()
|
|
481
|
+
try {
|
|
482
|
+
return (Atomics as any).waitAsync(i32a, 0, value).value.then(lock, lock)
|
|
483
|
+
} catch (err) {
|
|
484
|
+
return lock()
|
|
485
|
+
}
|
|
486
|
+
}, */
|
|
487
|
+
signal() {
|
|
488
|
+
const i32a = new Int32Array(wasmMemory.buffer, index, 1);
|
|
489
|
+
Atomics.add(i32a, 0, 1);
|
|
490
|
+
Atomics.notify(i32a, 0, 1);
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
return cond;
|
|
494
|
+
},
|
|
495
|
+
getQueueSize(func) {
|
|
496
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue_size, true);
|
|
497
|
+
},
|
|
498
|
+
addQueueSize(func) {
|
|
499
|
+
const offset = emnapiTSFN.offset.queue_size;
|
|
500
|
+
let arr, index;
|
|
501
|
+
#if MEMORY64
|
|
502
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
503
|
+
index = (func + offset) >>> 3;
|
|
504
|
+
#else
|
|
505
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
506
|
+
index = (func + offset) >>> 2;
|
|
507
|
+
#endif
|
|
508
|
+
Atomics.add(arr, index, {{{ to64('1') }}});
|
|
509
|
+
},
|
|
510
|
+
subQueueSize(func) {
|
|
511
|
+
const offset = emnapiTSFN.offset.queue_size;
|
|
512
|
+
let arr, index;
|
|
513
|
+
#if MEMORY64
|
|
514
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
515
|
+
index = (func + offset) >>> 3;
|
|
516
|
+
#else
|
|
517
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
518
|
+
index = (func + offset) >>> 2;
|
|
519
|
+
#endif
|
|
520
|
+
Atomics.sub(arr, index, {{{ to64('1') }}});
|
|
521
|
+
},
|
|
522
|
+
getThreadCount(func) {
|
|
523
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.thread_count, true);
|
|
524
|
+
},
|
|
525
|
+
addThreadCount(func) {
|
|
526
|
+
const offset = emnapiTSFN.offset.thread_count;
|
|
527
|
+
let arr, index;
|
|
528
|
+
#if MEMORY64
|
|
529
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
530
|
+
index = (func + offset) >>> 3;
|
|
531
|
+
#else
|
|
532
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
533
|
+
index = (func + offset) >>> 2;
|
|
534
|
+
#endif
|
|
535
|
+
Atomics.add(arr, index, {{{ to64('1') }}});
|
|
536
|
+
},
|
|
537
|
+
subThreadCount(func) {
|
|
538
|
+
const offset = emnapiTSFN.offset.thread_count;
|
|
539
|
+
let arr, index;
|
|
540
|
+
#if MEMORY64
|
|
541
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
542
|
+
index = (func + offset) >>> 3;
|
|
543
|
+
#else
|
|
544
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
545
|
+
index = (func + offset) >>> 2;
|
|
546
|
+
#endif
|
|
547
|
+
Atomics.sub(arr, index, {{{ to64('1') }}});
|
|
548
|
+
},
|
|
549
|
+
getState(func) {
|
|
550
|
+
return Atomics.load(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >>> 2);
|
|
551
|
+
},
|
|
552
|
+
setState(func, value) {
|
|
553
|
+
Atomics.store(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >>> 2, value);
|
|
554
|
+
},
|
|
555
|
+
getHandlesClosing(func) {
|
|
556
|
+
return Atomics.load(new Int8Array(wasmMemory.buffer), (func + emnapiTSFN.offset.handles_closing));
|
|
557
|
+
},
|
|
558
|
+
setHandlesClosing(func, value) {
|
|
559
|
+
Atomics.store(new Int8Array(wasmMemory.buffer), (func + emnapiTSFN.offset.handles_closing), value);
|
|
560
|
+
},
|
|
561
|
+
getDispatchState(func) {
|
|
562
|
+
return Atomics.load(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >>> 2);
|
|
563
|
+
},
|
|
564
|
+
getContext(func) {
|
|
565
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.context, false);
|
|
566
|
+
},
|
|
567
|
+
getMaxQueueSize(func) {
|
|
568
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.max_queue_size, true);
|
|
569
|
+
},
|
|
570
|
+
getEnv(func) {
|
|
571
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.env, false);
|
|
572
|
+
},
|
|
573
|
+
getCallJSCb(func) {
|
|
574
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.call_js_cb, false);
|
|
575
|
+
},
|
|
576
|
+
getRef(func) {
|
|
577
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.ref, false);
|
|
578
|
+
},
|
|
579
|
+
getResource(func) {
|
|
580
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.resource, false);
|
|
581
|
+
},
|
|
582
|
+
getFinalizeCb(func) {
|
|
583
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.finalize_cb, false);
|
|
584
|
+
},
|
|
585
|
+
getFinalizeData(func) {
|
|
586
|
+
return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.finalize_data, false);
|
|
587
|
+
},
|
|
588
|
+
loadSizeTypeValue(offset, unsigned) {
|
|
589
|
+
let ret;
|
|
590
|
+
let arr;
|
|
591
|
+
if (unsigned) {
|
|
592
|
+
#if MEMORY64
|
|
593
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
594
|
+
ret = Number(Atomics.load(arr, offset >>> 3));
|
|
595
|
+
#else
|
|
596
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
597
|
+
ret = Atomics.load(arr, offset >>> 2);
|
|
598
|
+
#endif
|
|
599
|
+
return ret;
|
|
600
|
+
}
|
|
601
|
+
else {
|
|
602
|
+
#if MEMORY64
|
|
603
|
+
arr = new BigInt64Array(wasmMemory.buffer);
|
|
604
|
+
ret = Number(Atomics.load(arr, offset >>> 3));
|
|
605
|
+
#else
|
|
606
|
+
arr = new Int32Array(wasmMemory.buffer);
|
|
607
|
+
ret = Atomics.load(arr, offset >>> 2);
|
|
608
|
+
#endif
|
|
609
|
+
return ret;
|
|
610
|
+
}
|
|
611
|
+
},
|
|
612
|
+
storeSizeTypeValue(offset, value, unsigned) {
|
|
613
|
+
let arr;
|
|
614
|
+
if (unsigned) {
|
|
615
|
+
#if MEMORY64
|
|
616
|
+
arr = new BigUint64Array(wasmMemory.buffer);
|
|
617
|
+
Atomics.store(arr, offset >>> 3, BigInt(value));
|
|
618
|
+
#else
|
|
619
|
+
arr = new Uint32Array(wasmMemory.buffer);
|
|
620
|
+
Atomics.store(arr, offset >>> 2, value);
|
|
621
|
+
#endif
|
|
622
|
+
return undefined;
|
|
623
|
+
}
|
|
624
|
+
else {
|
|
625
|
+
#if MEMORY64
|
|
626
|
+
arr = new BigInt64Array(wasmMemory.buffer);
|
|
627
|
+
Atomics.store(arr, offset >>> 3, BigInt(value >>> 0));
|
|
628
|
+
#else
|
|
629
|
+
arr = new Int32Array(wasmMemory.buffer);
|
|
630
|
+
Atomics.store(arr, offset >>> 2, value >>> 0);
|
|
631
|
+
#endif
|
|
632
|
+
return undefined;
|
|
633
|
+
}
|
|
634
|
+
},
|
|
635
|
+
releaseResources(func) {
|
|
636
|
+
if (emnapiTSFN.getState(func) !== 2 /* State.kClosed */) {
|
|
637
|
+
emnapiTSFN.setState(func, 2 /* State.kClosed */);
|
|
638
|
+
const env = emnapiTSFN.getEnv(func);
|
|
639
|
+
const envObject = emnapiEnv;
|
|
640
|
+
const ref = emnapiTSFN.getRef(func);
|
|
641
|
+
if (ref) {
|
|
642
|
+
emnapiCtx.getRef(ref).dispose();
|
|
643
|
+
}
|
|
644
|
+
const resource = emnapiTSFN.getResource(func);
|
|
645
|
+
emnapiCtx.getRef(resource).dispose();
|
|
646
|
+
{{{ makeSetValue('func', 'emnapiTSFN.offset.is_some', '0', 'i8') }}};
|
|
647
|
+
emnapiCtx.removeCleanupHook(envObject, emnapiTSFN.cleanup, func);
|
|
648
|
+
envObject.unref();
|
|
649
|
+
const asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
|
|
650
|
+
const arr = new Uint32Array(wasmMemory.buffer);
|
|
651
|
+
if (Atomics.load(arr, asyncRefOffset) > 0) {
|
|
652
|
+
Atomics.store(arr, asyncRefOffset, 0);
|
|
653
|
+
__emnapi_runtime_keepalive_pop();
|
|
654
|
+
emnapiCtx.decreaseWaitingRequestCounter();
|
|
655
|
+
}
|
|
656
|
+
if (emnapiNodeBinding) {
|
|
657
|
+
const view = new DataView(wasmMemory.buffer);
|
|
658
|
+
const asyncId = view.getFloat64(func + emnapiTSFN.offset.async_id, true);
|
|
659
|
+
const triggerAsyncId = view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true);
|
|
660
|
+
__emnapi_node_emit_async_destroy(asyncId, triggerAsyncId);
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
},
|
|
664
|
+
destroy(func) {
|
|
665
|
+
emnapiTSFN._liveSet.delete(func);
|
|
666
|
+
emnapiTSFN.destroyQueue(func);
|
|
667
|
+
emnapiTSFN.releaseResources(func);
|
|
668
|
+
_free({{{ to64('func') }}});
|
|
669
|
+
},
|
|
670
|
+
emptyQueue(func) {
|
|
671
|
+
const drainQueue = [];
|
|
672
|
+
emnapiTSFN.getMutex(func).execute(() => {
|
|
673
|
+
while (emnapiTSFN.getQueueSize(func) > 0) {
|
|
674
|
+
drainQueue.push(emnapiTSFN.shiftQueue(func));
|
|
675
|
+
}
|
|
676
|
+
});
|
|
677
|
+
const callJsCb = emnapiTSFN.getCallJSCb(func);
|
|
678
|
+
const context = emnapiTSFN.getContext(func);
|
|
679
|
+
let data;
|
|
680
|
+
for (let i = 0; i < drainQueue.length; i++) {
|
|
681
|
+
data = drainQueue[i];
|
|
682
|
+
if (callJsCb) {
|
|
683
|
+
{{{ makeDynCall('vpppp', 'callJsCb') }}}({{{ to64('0') }}}, {{{ to64('0') }}}, {{{ to64('context') }}}, {{{ to64('data') }}});
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
},
|
|
687
|
+
maybeDelete(func) {
|
|
688
|
+
let shouldDelete = false;
|
|
689
|
+
emnapiTSFN.getMutex(func).execute(() => {
|
|
690
|
+
if (emnapiTSFN.getThreadCount(func) > 0) {
|
|
691
|
+
emnapiTSFN.releaseResources(func);
|
|
692
|
+
}
|
|
693
|
+
else {
|
|
694
|
+
shouldDelete = true;
|
|
695
|
+
}
|
|
696
|
+
});
|
|
697
|
+
if (shouldDelete) {
|
|
698
|
+
emnapiTSFN.destroy(func);
|
|
699
|
+
}
|
|
700
|
+
},
|
|
701
|
+
finalize(func) {
|
|
702
|
+
const env = emnapiTSFN.getEnv(func);
|
|
703
|
+
const envObject = emnapiEnv;
|
|
704
|
+
emnapiCtx.openScope(envObject);
|
|
705
|
+
const finalize = emnapiTSFN.getFinalizeCb(func);
|
|
706
|
+
const data = emnapiTSFN.getFinalizeData(func);
|
|
707
|
+
const context = emnapiTSFN.getContext(func);
|
|
708
|
+
const f = () => {
|
|
709
|
+
envObject.callFinalizerInternal(0, {{{ to64('finalize') }}}, {{{ to64('data') }}}, {{{ to64('context') }}});
|
|
710
|
+
};
|
|
711
|
+
try {
|
|
712
|
+
emnapiTSFN.emptyQueue(func);
|
|
713
|
+
if (finalize) {
|
|
714
|
+
if (emnapiNodeBinding) {
|
|
715
|
+
const resource = emnapiTSFN.getResource(func);
|
|
716
|
+
const resource_value = emnapiCtx.getRef(resource).get();
|
|
717
|
+
const resourceObject = emnapiCtx.jsValueFromNapiValue(resource_value);
|
|
718
|
+
const view = new DataView(wasmMemory.buffer);
|
|
719
|
+
const asyncId = view.getFloat64(func + emnapiTSFN.offset.async_id, true);
|
|
720
|
+
const triggerAsyncId = view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true);
|
|
721
|
+
emnapiNodeBinding.node.makeCallback(resourceObject, f, [], {
|
|
722
|
+
asyncId,
|
|
723
|
+
triggerAsyncId
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
else {
|
|
727
|
+
f();
|
|
728
|
+
}
|
|
729
|
+
}
|
|
730
|
+
emnapiTSFN.maybeDelete(func);
|
|
731
|
+
}
|
|
732
|
+
finally {
|
|
733
|
+
emnapiCtx.closeScope(envObject);
|
|
734
|
+
}
|
|
735
|
+
},
|
|
736
|
+
cleanup(func) {
|
|
737
|
+
emnapiTSFN.closeHandlesAndMaybeDelete(func, 1);
|
|
738
|
+
},
|
|
739
|
+
closeHandlesAndMaybeDelete(func, set_closing) {
|
|
740
|
+
const env = emnapiTSFN.getEnv(func);
|
|
741
|
+
const envObject = emnapiEnv;
|
|
742
|
+
emnapiCtx.openScope(envObject);
|
|
743
|
+
try {
|
|
744
|
+
if (set_closing) {
|
|
745
|
+
emnapiTSFN.getMutex(func).execute(() => {
|
|
746
|
+
emnapiTSFN.setState(func, 1 /* State.kClosing */);
|
|
747
|
+
if (emnapiTSFN.getMaxQueueSize(func) > 0) {
|
|
748
|
+
emnapiTSFN.getCond(func).signal();
|
|
749
|
+
}
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
if (emnapiTSFN.getHandlesClosing(func)) {
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
emnapiTSFN.setHandlesClosing(func, 1);
|
|
756
|
+
Atomics.store(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.async_pending) >>> 2, 1);
|
|
757
|
+
emnapiCtx.features.setImmediate(() => {
|
|
758
|
+
emnapiTSFN.finalize(func);
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
finally {
|
|
762
|
+
emnapiCtx.closeScope(envObject);
|
|
763
|
+
}
|
|
764
|
+
},
|
|
765
|
+
dispatchOne(func) {
|
|
766
|
+
let data = 0;
|
|
767
|
+
let popped_value = false;
|
|
768
|
+
let has_more = false;
|
|
769
|
+
const mutex = emnapiTSFN.getMutex(func);
|
|
770
|
+
const cond = emnapiTSFN.getCond(func);
|
|
771
|
+
mutex.execute(() => {
|
|
772
|
+
if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
|
|
773
|
+
let size = emnapiTSFN.getQueueSize(func);
|
|
774
|
+
if (size > 0) {
|
|
775
|
+
data = emnapiTSFN.shiftQueue(func);
|
|
776
|
+
popped_value = true;
|
|
777
|
+
const maxQueueSize = emnapiTSFN.getMaxQueueSize(func);
|
|
778
|
+
if (size === maxQueueSize && maxQueueSize > 0) {
|
|
779
|
+
cond.signal();
|
|
780
|
+
}
|
|
781
|
+
size--;
|
|
782
|
+
}
|
|
783
|
+
if (size === 0) {
|
|
784
|
+
if (emnapiTSFN.getThreadCount(func) === 0) {
|
|
785
|
+
emnapiTSFN.setState(func, 1 /* State.kClosing */);
|
|
786
|
+
if (emnapiTSFN.getMaxQueueSize(func) > 0) {
|
|
787
|
+
cond.signal();
|
|
788
|
+
}
|
|
789
|
+
emnapiTSFN.closeHandlesAndMaybeDelete(func, 0);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
else {
|
|
793
|
+
has_more = true;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
emnapiTSFN.closeHandlesAndMaybeDelete(func, 0);
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
if (popped_value) {
|
|
801
|
+
const env = emnapiTSFN.getEnv(func);
|
|
802
|
+
const envObject = emnapiEnv;
|
|
803
|
+
emnapiCtx.openScope(envObject);
|
|
804
|
+
const f = () => {
|
|
805
|
+
envObject.callbackIntoModule(false, () => {
|
|
806
|
+
const callJsCb = emnapiTSFN.getCallJSCb(func);
|
|
807
|
+
const ref = emnapiTSFN.getRef(func);
|
|
808
|
+
const js_callback = ref ? emnapiCtx.getRef(ref).get() : 0;
|
|
809
|
+
if (callJsCb) {
|
|
810
|
+
const context = emnapiTSFN.getContext(func);
|
|
811
|
+
{{{ makeDynCall('vpppp', 'callJsCb') }}}({{{ to64('env') }}}, {{{ to64('js_callback') }}}, {{{ to64('context') }}}, {{{ to64('data') }}});
|
|
812
|
+
}
|
|
813
|
+
else {
|
|
814
|
+
const jsCallback = js_callback ? emnapiCtx.jsValueFromNapiValue(js_callback) : null;
|
|
815
|
+
if (typeof jsCallback === 'function') {
|
|
816
|
+
jsCallback();
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
});
|
|
820
|
+
};
|
|
821
|
+
try {
|
|
822
|
+
if (emnapiNodeBinding) {
|
|
823
|
+
const resource = emnapiTSFN.getResource(func);
|
|
824
|
+
const resource_value = emnapiCtx.getRef(resource).get();
|
|
825
|
+
const resourceObject = emnapiCtx.jsValueFromNapiValue(resource_value);
|
|
826
|
+
const view = new DataView(wasmMemory.buffer);
|
|
827
|
+
emnapiNodeBinding.node.makeCallback(resourceObject, f, [], {
|
|
828
|
+
asyncId: view.getFloat64(func + emnapiTSFN.offset.async_id, true),
|
|
829
|
+
triggerAsyncId: view.getFloat64(func + emnapiTSFN.offset.trigger_async_id, true)
|
|
830
|
+
});
|
|
831
|
+
}
|
|
832
|
+
else {
|
|
833
|
+
f();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
finally {
|
|
837
|
+
emnapiCtx.closeScope(envObject);
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
return has_more;
|
|
841
|
+
},
|
|
842
|
+
dispatch(func) {
|
|
843
|
+
let has_more = true;
|
|
844
|
+
let iterations_left = 1000;
|
|
845
|
+
const ui32a = new Uint32Array(wasmMemory.buffer);
|
|
846
|
+
const index = (func + emnapiTSFN.offset.dispatch_state) >>> 2;
|
|
847
|
+
while (has_more && --iterations_left !== 0) {
|
|
848
|
+
Atomics.store(ui32a, index, 1);
|
|
849
|
+
has_more = emnapiTSFN.dispatchOne(func);
|
|
850
|
+
if (Atomics.exchange(ui32a, index, 0) !== 1) {
|
|
851
|
+
has_more = true;
|
|
852
|
+
}
|
|
853
|
+
}
|
|
854
|
+
if (has_more) {
|
|
855
|
+
emnapiTSFN.send(func);
|
|
856
|
+
}
|
|
857
|
+
},
|
|
858
|
+
enqueue(func) {
|
|
859
|
+
// `pending` means a worker thread has requested a wakeup that has not
|
|
860
|
+
// been drained on the main thread yet.
|
|
861
|
+
const pending = func + emnapiTSFN.offset.async_pending;
|
|
862
|
+
// `scheduled` prevents queueing the same main-thread drain chain more than
|
|
863
|
+
// once while a previous wakeup is still in flight.
|
|
864
|
+
const scheduled = func + emnapiTSFN.offset.async_u_fd;
|
|
865
|
+
const i32a = new Int32Array(wasmMemory.buffer);
|
|
866
|
+
if (Atomics.exchange(i32a, scheduled >>> 2, 1) !== 0) {
|
|
867
|
+
return;
|
|
868
|
+
}
|
|
869
|
+
// Match uv_async_send-style coalescing in JS: the first turn represents
|
|
870
|
+
// the wakeup reaching the main thread, and the second turn performs the
|
|
871
|
+
// actual TSFN drain after nearby Send/Signal calls have had a chance to
|
|
872
|
+
// collapse into the shared AsyncProgressWorker state.
|
|
873
|
+
emnapiCtx.features.setImmediate(() => {
|
|
874
|
+
if (!emnapiTSFN._liveSet.has(func)) {
|
|
875
|
+
return;
|
|
876
|
+
}
|
|
877
|
+
if (Atomics.load(i32a, pending >>> 2) === 0) {
|
|
878
|
+
Atomics.store(i32a, scheduled >>> 2, 0);
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
881
|
+
emnapiCtx.features.setImmediate(() => {
|
|
882
|
+
try {
|
|
883
|
+
// Consume the coalesced wakeup once, then let dispatch() observe any
|
|
884
|
+
// queue mutations through dispatch_state like the C implementation.
|
|
885
|
+
if (Atomics.exchange(i32a, pending >>> 2, 0) === 0) {
|
|
886
|
+
return;
|
|
887
|
+
}
|
|
888
|
+
// After destroy(), the func address is freed. Skip dispatch
|
|
889
|
+
// to avoid use-after-free (JS-side lifecycle check).
|
|
890
|
+
if (!emnapiTSFN._liveSet.has(func)) {
|
|
891
|
+
return;
|
|
892
|
+
}
|
|
893
|
+
emnapiTSFN.dispatch(func);
|
|
894
|
+
}
|
|
895
|
+
finally {
|
|
896
|
+
// Allow a later wakeup to schedule a new drain chain. If another
|
|
897
|
+
// worker-thread send raced with this drain, enqueue one more turn.
|
|
898
|
+
if (emnapiTSFN._liveSet.has(func)) {
|
|
899
|
+
Atomics.store(i32a, scheduled >>> 2, 0);
|
|
900
|
+
if (Atomics.load(i32a, pending >>> 2) !== 0) {
|
|
901
|
+
emnapiTSFN.enqueue(func);
|
|
902
|
+
}
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
});
|
|
907
|
+
},
|
|
908
|
+
send(func) {
|
|
909
|
+
const current_state = Atomics.or(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >>> 2, 1 << 1);
|
|
910
|
+
if ((current_state & 1) === 1) {
|
|
911
|
+
return;
|
|
912
|
+
}
|
|
913
|
+
const pendng = func + emnapiTSFN.offset.async_pending;
|
|
914
|
+
// A wakeup is already pending, so this send only needs to leave the queued
|
|
915
|
+
// work in the TSFN queue and let the existing drain pick it up.
|
|
916
|
+
if (Atomics.load(new Int32Array(wasmMemory.buffer), pendng >>> 2) !== 0) {
|
|
917
|
+
return;
|
|
918
|
+
}
|
|
919
|
+
if (Atomics.exchange(new Int32Array(wasmMemory.buffer), pendng >>> 2, 1) === 0) {
|
|
920
|
+
if ((typeof ENVIRONMENT_IS_PTHREAD !== 'undefined') && ENVIRONMENT_IS_PTHREAD) {
|
|
921
|
+
// Worker threads only post a wakeup token. Main-thread draining is
|
|
922
|
+
// serialized by enqueue() once the message is received.
|
|
923
|
+
postMessage({
|
|
924
|
+
__emnapi__: {
|
|
925
|
+
type: 'tsfn-send',
|
|
926
|
+
payload: {
|
|
927
|
+
tsfn: func
|
|
928
|
+
}
|
|
929
|
+
}
|
|
930
|
+
});
|
|
931
|
+
}
|
|
932
|
+
else {
|
|
933
|
+
// On the main thread we can skip the cross-thread hop and schedule the
|
|
934
|
+
// coalesced drain chain directly.
|
|
935
|
+
emnapiTSFN.enqueue(func);
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
}
|
|
939
|
+
};
|
|
940
|
+
emnapiTSFN.init();
|
|
941
|
+
emnapiPluginCtx.emnapiTSFN = emnapiTSFN;
|
|
942
|
+
/**
|
|
943
|
+
* @__deps _emnapi_node_emit_async_init
|
|
944
|
+
* @__deps _emnapi_runtime_keepalive_push
|
|
945
|
+
* @__sig ippppppppppp
|
|
946
|
+
*/
|
|
947
|
+
function _napi_create_threadsafe_function(env, func, async_resource, async_resource_name, max_queue_size, initial_thread_count, thread_finalize_data, thread_finalize_cb, context, call_js_cb, result) {
|
|
948
|
+
if (!env)
|
|
949
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
950
|
+
// @ts-expect-error
|
|
951
|
+
const envObject = emnapiEnv;
|
|
952
|
+
envObject.checkGCAccess();
|
|
953
|
+
if (!async_resource_name)
|
|
954
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
955
|
+
{{{ from64('max_queue_size') }}};
|
|
956
|
+
{{{ from64('initial_thread_count') }}};
|
|
957
|
+
{{{ from64('env') }}};
|
|
958
|
+
{{{ from64('thread_finalize_data') }}};
|
|
959
|
+
{{{ from64('thread_finalize_cb') }}};
|
|
960
|
+
{{{ from64('context') }}};
|
|
961
|
+
{{{ from64('call_js_cb') }}};
|
|
962
|
+
max_queue_size = max_queue_size >>> 0;
|
|
963
|
+
initial_thread_count = initial_thread_count >>> 0;
|
|
964
|
+
if (initial_thread_count === 0) {
|
|
965
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
966
|
+
}
|
|
967
|
+
if (!result)
|
|
968
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
969
|
+
let ref = 0;
|
|
970
|
+
{{{ from64('func') }}};
|
|
971
|
+
if (!func) {
|
|
972
|
+
if (!call_js_cb)
|
|
973
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
974
|
+
}
|
|
975
|
+
else {
|
|
976
|
+
const funcValue = emnapiCtx.jsValueFromNapiValue(func);
|
|
977
|
+
if (typeof funcValue !== 'function') {
|
|
978
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
979
|
+
}
|
|
980
|
+
ref = emnapiCtx.createReference(envObject, func, 1, 1 /* ReferenceOwnership.kUserland */).id;
|
|
981
|
+
}
|
|
982
|
+
let asyncResourceObject;
|
|
983
|
+
if (async_resource) {
|
|
984
|
+
asyncResourceObject = emnapiCtx.jsValueFromNapiValue(async_resource);
|
|
985
|
+
if (asyncResourceObject == null) {
|
|
986
|
+
return envObject.setLastError(2 /* napi_status.napi_object_expected */);
|
|
987
|
+
}
|
|
988
|
+
asyncResourceObject = Object(asyncResourceObject);
|
|
989
|
+
}
|
|
990
|
+
else {
|
|
991
|
+
asyncResourceObject = {};
|
|
992
|
+
}
|
|
993
|
+
const resource = emnapiCtx.napiValueFromJsValue(asyncResourceObject);
|
|
994
|
+
let asyncResourceName = emnapiCtx.jsValueFromNapiValue(async_resource_name);
|
|
995
|
+
if (typeof asyncResourceName === 'symbol') {
|
|
996
|
+
return envObject.setLastError(3 /* napi_status.napi_string_expected */);
|
|
997
|
+
}
|
|
998
|
+
asyncResourceName = String(asyncResourceName);
|
|
999
|
+
const resource_name = emnapiCtx.napiValueFromJsValue(asyncResourceName);
|
|
1000
|
+
// tsfn create
|
|
1001
|
+
const sizeofTSFN = emnapiTSFN.offset.__size__;
|
|
1002
|
+
let tsfn = _malloc({{{ to64('sizeofTSFN') }}});
|
|
1003
|
+
if (!tsfn)
|
|
1004
|
+
return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
|
|
1005
|
+
{{{ from64('tsfn') }}};
|
|
1006
|
+
new Uint8Array(wasmMemory.buffer).subarray(tsfn, tsfn + sizeofTSFN).fill(0);
|
|
1007
|
+
const resourceRef = emnapiCtx.createReference(envObject, resource, 1, 1 /* ReferenceOwnership.kUserland */);
|
|
1008
|
+
const resource_ = resourceRef.id;
|
|
1009
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.resource', 'resource_', '*') }}};
|
|
1010
|
+
if (!emnapiTSFN.initQueue(tsfn)) {
|
|
1011
|
+
_free({{{ to64('tsfn') }}});
|
|
1012
|
+
resourceRef.dispose();
|
|
1013
|
+
return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
|
|
1014
|
+
}
|
|
1015
|
+
__emnapi_node_emit_async_init(resource, resource_name, -1, tsfn + emnapiTSFN.offset.async_id);
|
|
1016
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.is_some', '1', 'i8') }}};
|
|
1017
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.thread_count', 'initial_thread_count', SIZE_TYPE) }}};
|
|
1018
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.context', 'context', '*') }}};
|
|
1019
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.max_queue_size', 'max_queue_size', SIZE_TYPE) }}};
|
|
1020
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.ref', 'ref', '*') }}};
|
|
1021
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.env', 'env', '*') }}};
|
|
1022
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.finalize_data', 'thread_finalize_data', '*') }}};
|
|
1023
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.finalize_cb', 'thread_finalize_cb', '*') }}};
|
|
1024
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.call_js_cb', 'call_js_cb', '*') }}};
|
|
1025
|
+
emnapiCtx.addCleanupHook(envObject, emnapiTSFN.cleanup, tsfn);
|
|
1026
|
+
emnapiTSFN._liveSet.add(tsfn);
|
|
1027
|
+
envObject.ref();
|
|
1028
|
+
__emnapi_runtime_keepalive_push();
|
|
1029
|
+
emnapiCtx.increaseWaitingRequestCounter();
|
|
1030
|
+
{{{ makeSetValue('tsfn', 'emnapiTSFN.offset.async_ref', '1', 'u32') }}};
|
|
1031
|
+
{{{ from64('result') }}};
|
|
1032
|
+
{{{ makeSetValue('result', 0, 'tsfn', '*') }}};
|
|
1033
|
+
return envObject.clearLastError();
|
|
1034
|
+
}
|
|
1035
|
+
/** @__sig ipp */
|
|
1036
|
+
function _napi_get_threadsafe_function_context(func, result) {
|
|
1037
|
+
if (!func || !result) {
|
|
1038
|
+
abort();
|
|
1039
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1040
|
+
}
|
|
1041
|
+
{{{ from64('func') }}};
|
|
1042
|
+
{{{ from64('result') }}};
|
|
1043
|
+
const context = emnapiTSFN.getContext(func);
|
|
1044
|
+
{{{ makeSetValue('result', 0, 'context', '*') }}};
|
|
1045
|
+
return 0 /* napi_status.napi_ok */;
|
|
1046
|
+
}
|
|
1047
|
+
/** @__sig ippi */
|
|
1048
|
+
function _napi_call_threadsafe_function(func, data, mode) {
|
|
1049
|
+
if (!func) {
|
|
1050
|
+
abort();
|
|
1051
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1052
|
+
}
|
|
1053
|
+
{{{ from64('func') }}};
|
|
1054
|
+
{{{ from64('data') }}};
|
|
1055
|
+
return emnapiTSFN.push(func, data, mode);
|
|
1056
|
+
}
|
|
1057
|
+
/** @__sig ip */
|
|
1058
|
+
function _napi_acquire_threadsafe_function(func) {
|
|
1059
|
+
if (!func) {
|
|
1060
|
+
abort();
|
|
1061
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1062
|
+
}
|
|
1063
|
+
{{{ from64('func') }}};
|
|
1064
|
+
const mutex = emnapiTSFN.getMutex(func);
|
|
1065
|
+
return mutex.execute(() => {
|
|
1066
|
+
if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
|
|
1067
|
+
emnapiTSFN.addThreadCount(func);
|
|
1068
|
+
return 0 /* napi_status.napi_ok */;
|
|
1069
|
+
}
|
|
1070
|
+
return 16 /* napi_status.napi_closing */;
|
|
1071
|
+
});
|
|
1072
|
+
}
|
|
1073
|
+
/** @__sig ipi */
|
|
1074
|
+
function _napi_release_threadsafe_function(func, mode) {
|
|
1075
|
+
if (!func) {
|
|
1076
|
+
abort();
|
|
1077
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1078
|
+
}
|
|
1079
|
+
{{{ from64('func') }}};
|
|
1080
|
+
const mutex = emnapiTSFN.getMutex(func);
|
|
1081
|
+
const cond = emnapiTSFN.getCond(func);
|
|
1082
|
+
let shouldDelete = false;
|
|
1083
|
+
const ret = mutex.execute(() => {
|
|
1084
|
+
if (emnapiTSFN.getThreadCount(func) === 0) {
|
|
1085
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1086
|
+
}
|
|
1087
|
+
emnapiTSFN.subThreadCount(func);
|
|
1088
|
+
if (emnapiTSFN.getThreadCount(func) === 0 || mode === 1 /* napi_threadsafe_function_release_mode.napi_tsfn_abort */) {
|
|
1089
|
+
if (emnapiTSFN.getState(func) === 0 /* State.kOpen */) {
|
|
1090
|
+
if (mode === 1 /* napi_threadsafe_function_release_mode.napi_tsfn_abort */) {
|
|
1091
|
+
emnapiTSFN.setState(func, 1 /* State.kClosing */);
|
|
1092
|
+
}
|
|
1093
|
+
if (emnapiTSFN.getState(func) === 1 /* State.kClosing */ && emnapiTSFN.getMaxQueueSize(func) > 0) {
|
|
1094
|
+
cond.signal();
|
|
1095
|
+
}
|
|
1096
|
+
emnapiTSFN.send(func);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
if (!(emnapiTSFN.getState(func) === 2 /* State.kClosed */ && emnapiTSFN.getThreadCount(func) === 0)) {
|
|
1100
|
+
return 0 /* napi_status.napi_ok */;
|
|
1101
|
+
}
|
|
1102
|
+
shouldDelete = true;
|
|
1103
|
+
return 0 /* napi_status.napi_ok */;
|
|
1104
|
+
});
|
|
1105
|
+
if (shouldDelete) {
|
|
1106
|
+
emnapiTSFN.destroy(func);
|
|
1107
|
+
}
|
|
1108
|
+
return ret;
|
|
1109
|
+
}
|
|
1110
|
+
/**
|
|
1111
|
+
* @__deps _emnapi_runtime_keepalive_pop
|
|
1112
|
+
* @__sig ipp
|
|
1113
|
+
*/
|
|
1114
|
+
function _napi_unref_threadsafe_function(env, func) {
|
|
1115
|
+
if (!func) {
|
|
1116
|
+
abort();
|
|
1117
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1118
|
+
}
|
|
1119
|
+
{{{ from64('func') }}};
|
|
1120
|
+
const asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
|
|
1121
|
+
const arr = new Uint32Array(wasmMemory.buffer);
|
|
1122
|
+
const currentValue = Atomics.load(arr, asyncRefOffset);
|
|
1123
|
+
if (currentValue > 0) {
|
|
1124
|
+
Atomics.store(arr, asyncRefOffset, currentValue - 1);
|
|
1125
|
+
if (currentValue === 1) {
|
|
1126
|
+
__emnapi_runtime_keepalive_pop();
|
|
1127
|
+
emnapiCtx.decreaseWaitingRequestCounter();
|
|
1128
|
+
}
|
|
1129
|
+
}
|
|
1130
|
+
return 0 /* napi_status.napi_ok */;
|
|
1131
|
+
}
|
|
1132
|
+
/**
|
|
1133
|
+
* @__deps _emnapi_runtime_keepalive_push
|
|
1134
|
+
* @__sig ipp
|
|
1135
|
+
*/
|
|
1136
|
+
function _napi_ref_threadsafe_function(env, func) {
|
|
1137
|
+
if (!func) {
|
|
1138
|
+
abort();
|
|
1139
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
1140
|
+
}
|
|
1141
|
+
{{{ from64('func') }}};
|
|
1142
|
+
const asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
|
|
1143
|
+
const arr = new Uint32Array(wasmMemory.buffer);
|
|
1144
|
+
const currentValue = Atomics.load(arr, asyncRefOffset);
|
|
1145
|
+
if (!currentValue) {
|
|
1146
|
+
__emnapi_runtime_keepalive_push();
|
|
1147
|
+
emnapiCtx.increaseWaitingRequestCounter();
|
|
1148
|
+
}
|
|
1149
|
+
Atomics.store(arr, asyncRefOffset, currentValue + 1);
|
|
1150
|
+
return 0 /* napi_status.napi_ok */;
|
|
1151
|
+
}
|
|
1152
|
+
(typeof addToLibrary === "function" ? addToLibrary : (...args) => mergeInto(LibraryManager.library, ...args))({
|
|
1153
|
+
$emnapiEnv: "undefined",
|
|
1154
|
+
$emnapiTSFN: emnapiTSFN,
|
|
1155
|
+
$emnapiTSFN__deps: ["$emnapiEnv", "malloc", "free", "$emnapiCtx", "$emnapiEnv", "$emnapiNodeBinding", "_emnapi_node_emit_async_destroy", "_emnapi_runtime_keepalive_pop"],
|
|
1156
|
+
$emnapiTSFN__postset: "emnapiTSFN.init();",
|
|
1157
|
+
napi_acquire_threadsafe_function: _napi_acquire_threadsafe_function,
|
|
1158
|
+
napi_acquire_threadsafe_function__deps: ["$emnapiTSFN"],
|
|
1159
|
+
napi_acquire_threadsafe_function__sig: "ip",
|
|
1160
|
+
napi_call_threadsafe_function: _napi_call_threadsafe_function,
|
|
1161
|
+
napi_call_threadsafe_function__deps: ["$emnapiTSFN"],
|
|
1162
|
+
napi_call_threadsafe_function__sig: "ippi",
|
|
1163
|
+
napi_create_threadsafe_function: _napi_create_threadsafe_function,
|
|
1164
|
+
napi_create_threadsafe_function__deps: ["$emnapiEnv", "$emnapiTSFN", "_emnapi_node_emit_async_init", "_emnapi_runtime_keepalive_push"],
|
|
1165
|
+
napi_create_threadsafe_function__sig: "ippppppppppp",
|
|
1166
|
+
napi_get_threadsafe_function_context: _napi_get_threadsafe_function_context,
|
|
1167
|
+
napi_get_threadsafe_function_context__deps: ["$emnapiTSFN"],
|
|
1168
|
+
napi_get_threadsafe_function_context__sig: "ipp",
|
|
1169
|
+
napi_ref_threadsafe_function: _napi_ref_threadsafe_function,
|
|
1170
|
+
napi_ref_threadsafe_function__deps: ["$emnapiTSFN", "_emnapi_runtime_keepalive_push"],
|
|
1171
|
+
napi_ref_threadsafe_function__sig: "ipp",
|
|
1172
|
+
napi_release_threadsafe_function: _napi_release_threadsafe_function,
|
|
1173
|
+
napi_release_threadsafe_function__deps: ["$emnapiTSFN"],
|
|
1174
|
+
napi_release_threadsafe_function__sig: "ipi",
|
|
1175
|
+
napi_unref_threadsafe_function: _napi_unref_threadsafe_function,
|
|
1176
|
+
napi_unref_threadsafe_function__deps: ["$emnapiTSFN", "_emnapi_runtime_keepalive_pop"],
|
|
1177
|
+
napi_unref_threadsafe_function__sig: "ipp"
|
|
1178
|
+
});
|