emnapi 1.11.0 → 2.0.0-alpha.2

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.
Files changed (79) hide show
  1. package/CMakeLists.txt +127 -57
  2. package/README.md +164 -776
  3. package/cmake/wasm32.cmake +0 -3
  4. package/common.gypi +16 -14
  5. package/dist/library_async_work.js +390 -0
  6. package/dist/library_napi.js +1476 -2802
  7. package/dist/library_threadsafe_function.js +1178 -0
  8. package/dist/library_v8.js +1594 -0
  9. package/emnapi.gyp +37 -0
  10. package/include/node/emnapi.h +13 -2
  11. package/include/node/js_native_api_types.h +22 -0
  12. package/include/node/node.h +198 -0
  13. package/include/node/node_api.h +0 -10
  14. package/include/node/node_buffer.h +92 -0
  15. package/include/node/node_object_wrap.h +132 -0
  16. package/include/node/node_version.h +110 -0
  17. package/include/node/uv/unix.h +1 -0
  18. package/include/node/uv/version.h +43 -0
  19. package/include/node/uv.h +6 -0
  20. package/index.js +15 -7
  21. package/lib/wasm32-emscripten/libemnapi-mt.a +0 -0
  22. package/lib/wasm32-emscripten/libemnapi.a +0 -0
  23. package/lib/wasm32-wasip1-threads/libemnapi-mt.a +0 -0
  24. package/lib/wasm32-wasip1-threads/libemnapi-napi-rs-mt.a +0 -0
  25. package/lib/wasm32-wasip1-threads/libemnapi.a +0 -0
  26. package/lib/wasm64-emscripten/libemnapi-mt.a +0 -0
  27. package/lib/wasm64-emscripten/libemnapi.a +0 -0
  28. package/package.json +1 -1
  29. package/src/async_cleanup_hook.c +6 -6
  30. package/src/emnapi_internal.h +5 -10
  31. package/src/js_native_api.c +37 -21
  32. package/src/js_native_api_internal.h +66 -0
  33. package/src/node_api.c +1 -1
  34. package/src/threadsafe_function.c +2 -2
  35. package/src/uv/unix/thread.c +21 -0
  36. package/src/v8/array.cc +19 -0
  37. package/src/v8/boolean.cc +26 -0
  38. package/src/v8/date.cc +15 -0
  39. package/src/v8/exception.cc +48 -0
  40. package/src/v8/external.cc +23 -0
  41. package/src/v8/function.cc +35 -0
  42. package/src/v8/handle_scope.cc +46 -0
  43. package/src/v8/internal.cc +126 -0
  44. package/src/v8/internal.h +41 -0
  45. package/src/v8/isolate.cc +35 -0
  46. package/src/v8/json.cc +25 -0
  47. package/src/v8/node.cc +24 -0
  48. package/src/v8/number.cc +62 -0
  49. package/src/v8/object.cc +106 -0
  50. package/src/v8/script.cc +75 -0
  51. package/src/v8/string.cc +104 -0
  52. package/src/v8/template.cc +234 -0
  53. package/src/v8/try_catch.cc +50 -0
  54. package/src/v8/v8_impl.h +42 -0
  55. package/src/v8/value.cc +138 -0
  56. package/lib/wasm32/libdlmalloc-mt.a +0 -0
  57. package/lib/wasm32/libdlmalloc.a +0 -0
  58. package/lib/wasm32/libemmalloc-mt.a +0 -0
  59. package/lib/wasm32/libemmalloc.a +0 -0
  60. package/lib/wasm32/libemnapi-basic-mt.a +0 -0
  61. package/lib/wasm32/libemnapi-basic.a +0 -0
  62. package/lib/wasm32/libemnapi.a +0 -0
  63. package/lib/wasm32-emscripten/libemnapi-basic.a +0 -0
  64. package/lib/wasm32-wasi/libemnapi-basic-mt.a +0 -0
  65. package/lib/wasm32-wasi/libemnapi-basic.a +0 -0
  66. package/lib/wasm32-wasi/libemnapi.a +0 -0
  67. package/lib/wasm32-wasi-threads/libemnapi-basic-mt.a +0 -0
  68. package/lib/wasm32-wasi-threads/libemnapi-basic-napi-rs-mt.a +0 -0
  69. package/lib/wasm32-wasi-threads/libemnapi-basic.a +0 -0
  70. package/lib/wasm32-wasi-threads/libemnapi-mt.a +0 -0
  71. package/lib/wasm32-wasi-threads/libemnapi-napi-rs-mt.a +0 -0
  72. package/lib/wasm32-wasi-threads/libemnapi.a +0 -0
  73. package/lib/wasm32-wasip1/libemnapi-basic-mt.a +0 -0
  74. package/lib/wasm32-wasip1/libemnapi-basic.a +0 -0
  75. package/lib/wasm32-wasip1/libemnapi.a +0 -0
  76. package/lib/wasm32-wasip1-threads/libemnapi-basic-mt.a +0 -0
  77. package/lib/wasm32-wasip1-threads/libemnapi-basic-napi-rs-mt.a +0 -0
  78. package/lib/wasm32-wasip1-threads/libemnapi-basic.a +0 -0
  79. 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
+ Object.values(PThread.pthreads).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
+ });