emnapi 1.9.1 → 1.10.0

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 (34) hide show
  1. package/dist/library_napi.js +146 -73
  2. package/include/node/emnapi.h +2 -2
  3. package/lib/wasm32/libdlmalloc-mt.a +0 -0
  4. package/lib/wasm32/libdlmalloc.a +0 -0
  5. package/lib/wasm32/libemmalloc-mt.a +0 -0
  6. package/lib/wasm32/libemmalloc.a +0 -0
  7. package/lib/wasm32/libemnapi-basic-mt.a +0 -0
  8. package/lib/wasm32/libemnapi-basic.a +0 -0
  9. package/lib/wasm32/libemnapi.a +0 -0
  10. package/lib/wasm32-emscripten/libemnapi-basic.a +0 -0
  11. package/lib/wasm32-emscripten/libemnapi-mt.a +0 -0
  12. package/lib/wasm32-emscripten/libemnapi.a +0 -0
  13. package/lib/wasm32-wasi/libemnapi-basic-mt.a +0 -0
  14. package/lib/wasm32-wasi/libemnapi-basic.a +0 -0
  15. package/lib/wasm32-wasi/libemnapi.a +0 -0
  16. package/lib/wasm32-wasi-threads/libemnapi-basic-mt.a +0 -0
  17. package/lib/wasm32-wasi-threads/libemnapi-basic-napi-rs-mt.a +0 -0
  18. package/lib/wasm32-wasi-threads/libemnapi-basic.a +0 -0
  19. package/lib/wasm32-wasi-threads/libemnapi-mt.a +0 -0
  20. package/lib/wasm32-wasi-threads/libemnapi-napi-rs-mt.a +0 -0
  21. package/lib/wasm32-wasi-threads/libemnapi.a +0 -0
  22. package/lib/wasm32-wasip1/libemnapi-basic-mt.a +0 -0
  23. package/lib/wasm32-wasip1/libemnapi-basic.a +0 -0
  24. package/lib/wasm32-wasip1/libemnapi.a +0 -0
  25. package/lib/wasm32-wasip1-threads/libemnapi-basic-mt.a +0 -0
  26. package/lib/wasm32-wasip1-threads/libemnapi-basic-napi-rs-mt.a +0 -0
  27. package/lib/wasm32-wasip1-threads/libemnapi-basic.a +0 -0
  28. package/lib/wasm32-wasip1-threads/libemnapi-mt.a +0 -0
  29. package/lib/wasm32-wasip1-threads/libemnapi-napi-rs-mt.a +0 -0
  30. package/lib/wasm32-wasip1-threads/libemnapi.a +0 -0
  31. package/lib/wasm64-emscripten/libemnapi-basic.a +0 -0
  32. package/lib/wasm64-emscripten/libemnapi-mt.a +0 -0
  33. package/lib/wasm64-emscripten/libemnapi.a +0 -0
  34. package/package.json +1 -1
@@ -236,8 +236,8 @@ function __emnapi_close_handle_scope(_scope) {
236
236
  /* eslint-disable @typescript-eslint/indent */
237
237
  /* eslint-disable @typescript-eslint/no-unnecessary-type-assertion */
238
238
  /* eslint-disable @typescript-eslint/explicit-function-return-type */
239
+ /* eslint-disable @typescript-eslint/indent */
239
240
  /**
240
- * @__deps emscripten_resize_heap
241
241
  * @__sig ipjp
242
242
  */
243
243
  function _napi_adjust_external_memory(env, low, high, adjusted_value) {
@@ -248,33 +248,24 @@ function _napi_adjust_external_memory(env, low, high, adjusted_value) {
248
248
  #if WASM_BIGINT
249
249
  if (!high)
250
250
  return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
251
- change_in_bytes = Number(low);
251
+ change_in_bytes = BigInt(low);
252
252
  #else
253
253
  if (!adjusted_value)
254
254
  return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
255
- change_in_bytes = (low >>> 0) + (high * Math.pow(2, 32));
255
+ change_in_bytes = BigInt(low >>> 0) + (BigInt(high) << BigInt(32));
256
256
  #endif
257
- if (change_in_bytes < 0) {
258
- return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
259
- }
260
- if (change_in_bytes > 0) {
261
- var old_size = wasmMemory.buffer.byteLength;
262
- var new_size = old_size + change_in_bytes;
263
- if (!_emscripten_resize_heap(new_size)) {
264
- return envObject.setLastError(9 /* napi_status.napi_generic_failure */);
265
- }
266
- }
257
+ var adjusted_memory = emnapiCtx.adjustAmountOfExternalAllocatedMemory(change_in_bytes);
267
258
  #if WASM_BIGINT
268
259
  {{{ from64('high') }}};
269
260
  if (emnapiCtx.feature.supportBigInt) {
270
- {{{ makeSetValue('high', 0, 'wasmMemory.buffer.byteLength', 'i64') }}};
261
+ {{{ makeSetValue('high', 0, 'adjusted_memory', 'i64') }}};
271
262
  }
272
263
  else {
273
- emnapiSetValueI64(high, wasmMemory.buffer.byteLength);
264
+ emnapiSetValueI64(high, Number(adjusted_memory));
274
265
  }
275
266
  #else
276
267
  {{{ from64('adjusted_value') }}};
277
- {{{ makeSetValue('adjusted_value', 0, 'wasmMemory.buffer.byteLength', 'i64') }}};
268
+ {{{ makeSetValue('adjusted_value', 0, 'adjusted_memory', 'i64') }}};
278
269
  #endif
279
270
  return envObject.clearLastError();
280
271
  }
@@ -557,6 +548,7 @@ function _napi_create_async_work(env, resource, resource_name, execute, complete
557
548
  var resourceName = String(emnapiCtx.handleStore.get(resource_name).value);
558
549
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
559
550
  var id = emnapiAWST.create(env, resourceObject, resourceName, execute, complete, data);
551
+ {{{ from64('result') }}};
560
552
  {{{ makeSetValue('result', 0, 'id', '*') }}};
561
553
  return envObject.clearLastError();
562
554
  }
@@ -728,7 +720,7 @@ var emnapiString = {
728
720
  ptr >>>= 0;
729
721
  var HEAPU8 = new Uint8Array(wasmMemory.buffer);
730
722
  var end = ptr;
731
- if (length === -1) {
723
+ if (length === -1 || length === 4294967295) {
732
724
  for (; HEAPU8[end];)
733
725
  ++end;
734
726
  }
@@ -821,12 +813,12 @@ var emnapiString = {
821
813
  return '';
822
814
  ptr >>>= 0;
823
815
  var end = ptr;
824
- if (length === -1) {
825
- var idx = end >> 1;
816
+ if (length === -1 || length === 4294967295) {
817
+ var idx = end >>> 1;
826
818
  var HEAPU16 = new Uint16Array(wasmMemory.buffer);
827
819
  while (HEAPU16[idx])
828
820
  ++idx;
829
- end = idx << 1;
821
+ end = (idx << 1) >>> 0;
830
822
  }
831
823
  else {
832
824
  end = ptr + (length >>> 0) * 2;
@@ -866,7 +858,7 @@ var emnapiString = {
866
858
  // @ts-expect-error
867
859
  var envObject = emnapiCtx.envStore.get(env);
868
860
  envObject.checkGCAccess();
869
- var autoLength = length === -1;
861
+ var autoLength = length === -1 || length === 4294967295;
870
862
  var sizelength = length >>> 0;
871
863
  if (length !== 0) {
872
864
  if (!str)
@@ -891,7 +883,7 @@ var emnapiString = {
891
883
  // @ts-expect-error
892
884
  var envObject = emnapiCtx.envStore.get(env);
893
885
  envObject.checkGCAccess();
894
- var autoLength = length === -1;
886
+ var autoLength = length === -1 || length === 4294967295;
895
887
  var sizelength = length >>> 0;
896
888
  if (length !== 0) {
897
889
  if (!str)
@@ -1041,6 +1033,7 @@ var emnapiExternalMemory = {
1041
1033
  var pointer = _malloc({{{ to64('arrayBuffer.byteLength') }}});
1042
1034
  if (!pointer)
1043
1035
  throw new Error('Out of memory');
1036
+ {{{ from64('pointer') }}};
1044
1037
  new Uint8Array(wasmMemory.buffer).set(new Uint8Array(arrayBuffer), pointer);
1045
1038
  info.address = pointer;
1046
1039
  info.ownership = emnapiExternalMemory.registry ? 0 /* ReferenceOwnership.kRuntime */ : 1 /* ReferenceOwnership.kUserland */;
@@ -1062,8 +1055,7 @@ var emnapiExternalMemory = {
1062
1055
  }
1063
1056
  return view;
1064
1057
  }
1065
- var maybeOldWasmMemory = emnapiExternalMemory.isDetachedArrayBuffer(view.buffer) ||
1066
- ((typeof SharedArrayBuffer === 'function') && (view.buffer instanceof SharedArrayBuffer));
1058
+ var maybeOldWasmMemory = emnapiExternalMemory.isDetachedArrayBuffer(view.buffer) || emnapiExternalMemory.isSharedArrayBuffer(view.buffer);
1067
1059
  if (maybeOldWasmMemory && emnapiExternalMemory.wasmMemoryViewTable.has(view)) {
1068
1060
  var info = emnapiExternalMemory.wasmMemoryViewTable.get(view);
1069
1061
  var Ctor = info.Ctor;
@@ -1294,13 +1286,12 @@ function _napi_get_typedarray_info(env, typedarray, type, length, data, arraybuf
1294
1286
  }
1295
1287
  {{{ makeSetValue('type', 0, 't', 'i32') }}};
1296
1288
  }
1289
+ v = emnapiExternalMemory.getOrUpdateMemoryView(v);
1297
1290
  if (length) {
1298
1291
  {{{ from64('length') }}};
1299
1292
  {{{ makeSetValue('length', 0, 'v.length', SIZE_TYPE) }}};
1300
1293
  }
1301
- var buffer;
1302
1294
  if (data || arraybuffer) {
1303
- buffer = v.buffer;
1304
1295
  if (data) {
1305
1296
  {{{ from64('data') }}};
1306
1297
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -1310,7 +1301,7 @@ function _napi_get_typedarray_info(env, typedarray, type, length, data, arraybuf
1310
1301
  if (arraybuffer) {
1311
1302
  {{{ from64('arraybuffer') }}};
1312
1303
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1313
- var ab = envObject.ensureHandleId(buffer);
1304
+ var ab = envObject.ensureHandleId(v.buffer);
1314
1305
  {{{ makeSetValue('arraybuffer', 0, 'ab', '*') }}};
1315
1306
  }
1316
1307
  }
@@ -1354,14 +1345,12 @@ function _napi_get_dataview_info(env, dataview, byte_length, data, arraybuffer,
1354
1345
  if (!handle.isDataView()) {
1355
1346
  return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
1356
1347
  }
1357
- var v = handle.value;
1348
+ var v = emnapiExternalMemory.getOrUpdateMemoryView(handle.value);
1358
1349
  if (byte_length) {
1359
1350
  {{{ from64('byte_length') }}};
1360
1351
  {{{ makeSetValue('byte_length', 0, 'v.byteLength', SIZE_TYPE) }}};
1361
1352
  }
1362
- var buffer;
1363
1353
  if (data || arraybuffer) {
1364
- buffer = v.buffer;
1365
1354
  if (data) {
1366
1355
  {{{ from64('data') }}};
1367
1356
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -1371,7 +1360,7 @@ function _napi_get_dataview_info(env, dataview, byte_length, data, arraybuffer,
1371
1360
  if (arraybuffer) {
1372
1361
  {{{ from64('arraybuffer') }}};
1373
1362
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1374
- var ab = envObject.ensureHandleId(buffer);
1363
+ var ab = envObject.ensureHandleId(v.buffer);
1375
1364
  {{{ makeSetValue('arraybuffer', 0, 'ab', '*') }}};
1376
1365
  }
1377
1366
  }
@@ -2349,7 +2338,7 @@ function _napi_define_class(env, utf8name, length, constructor, callback_data, p
2349
2338
  if (!properties)
2350
2339
  return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
2351
2340
  }
2352
- if ((length < -1) || (length > 2147483647) || (!utf8name)) {
2341
+ if (!((length >= -1 && length <= 2147483647) || length === 4294967295) || (!utf8name)) {
2353
2342
  return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
2354
2343
  }
2355
2344
  var fresult = emnapiCreateFunction(envObject, utf8name, length, constructor, callback_data);
@@ -2693,7 +2682,7 @@ function emnapiSyncMemory(js_to_wasm, arrayBufferOrView, offset, len) {
2693
2682
  var pointer = emnapiExternalMemory.getArrayBufferPointer(arrayBufferOrView, false).address;
2694
2683
  if (!pointer)
2695
2684
  throw new Error('Unknown ArrayBuffer address');
2696
- if (typeof len !== 'number' || len === -1) {
2685
+ if (typeof len !== 'number' || len === -1 || len === 4294967295) {
2697
2686
  len = arrayBufferOrView.byteLength - offset;
2698
2687
  }
2699
2688
  len = len >>> 0;
@@ -2715,7 +2704,7 @@ function emnapiSyncMemory(js_to_wasm, arrayBufferOrView, offset, len) {
2715
2704
  var pointer = viewPointerInfo.address;
2716
2705
  if (!pointer)
2717
2706
  throw new Error('Unknown ArrayBuffer address');
2718
- if (typeof len !== 'number' || len === -1) {
2707
+ if (typeof len !== 'number' || len === -1 || len === 4294967295) {
2719
2708
  len = latestView.byteLength - offset;
2720
2709
  }
2721
2710
  len = len >>> 0;
@@ -3346,6 +3335,7 @@ function _napi_create_buffer(env, size, data, result) {
3346
3335
  pointer = _malloc({{{ to64('size') }}});
3347
3336
  if (!pointer)
3348
3337
  throw new Error('Out of memory');
3338
+ {{{ from64('pointer') }}};
3349
3339
  new Uint8Array(wasmMemory.buffer).subarray(pointer, pointer + size).fill(0);
3350
3340
  var buffer_1 = Buffer.from(wasmMemory.buffer, pointer, size);
3351
3341
  var viewDescriptor = {
@@ -3549,7 +3539,7 @@ function _node_api_symbol_for(env, utf8description, length, result) {
3549
3539
  {{{ from64('length') }}};
3550
3540
  {{{ from64('utf8description') }}};
3551
3541
  {{{ from64('result') }}};
3552
- var autoLength = length === -1;
3542
+ var autoLength = length === -1 || length === 4294967295;
3553
3543
  var sizelength = length >>> 0;
3554
3544
  if (length !== 0) {
3555
3545
  if (!utf8description)
@@ -5538,6 +5528,7 @@ function _napi_run_script(env, script, result) {
5538
5528
  * ```
5539
5529
  */
5540
5530
  var emnapiTSFN = {
5531
+ _liveSet: {},
5541
5532
  offset: {
5542
5533
  __size__: 0,
5543
5534
  /* napi_ref */ resource: 0,
@@ -5546,6 +5537,9 @@ var emnapiTSFN = {
5546
5537
  /* size_t */ queue_size: 0,
5547
5538
  /* bool */ is_some: 0,
5548
5539
  /* void* */ queue: 0,
5540
+ // Reuse uv_async_t storage as JS-side wakeup state: pending event + scheduled drain.
5541
+ async_pending: 0,
5542
+ async_u_fd: 0,
5549
5543
  /* size_t */ thread_count: 0,
5550
5544
  /* int32_t */ state: 0,
5551
5545
  /* atomic_uchar */ dispatch_state: 0,
@@ -5562,6 +5556,7 @@ var emnapiTSFN = {
5562
5556
  /* int32_t */ cond: 0
5563
5557
  },
5564
5558
  init: function () {
5559
+ emnapiTSFN._liveSet = new Set();
5565
5560
  #if MEMORY64
5566
5561
  emnapiTSFN.offset.__size__ = 320 /* NapiTSFNOffset64.__size__ */;
5567
5562
  emnapiTSFN.offset.resource = 0 /* NapiTSFNOffset64.async_resource_resource */;
@@ -5570,6 +5565,8 @@ var emnapiTSFN = {
5570
5565
  emnapiTSFN.offset.queue_size = 88 /* NapiTSFNOffset64.queue_size */;
5571
5566
  emnapiTSFN.offset.is_some = 24 /* NapiTSFNOffset64.async_resource_is_some */;
5572
5567
  emnapiTSFN.offset.queue = 96 /* NapiTSFNOffset64.queue */;
5568
+ emnapiTSFN.offset.async_pending = 232 /* NapiTSFNOffset64.async_pending */;
5569
+ emnapiTSFN.offset.async_u_fd = 160 /* NapiTSFNOffset64.async_u_fd */;
5573
5570
  emnapiTSFN.offset.thread_count = 240 /* NapiTSFNOffset64.thread_count */;
5574
5571
  emnapiTSFN.offset.state = 248 /* NapiTSFNOffset64.state */;
5575
5572
  emnapiTSFN.offset.dispatch_state = 252 /* NapiTSFNOffset64.dispatch_state */;
@@ -5592,6 +5589,8 @@ var emnapiTSFN = {
5592
5589
  emnapiTSFN.offset.queue_size = 60 /* NapiTSFNOffset32.queue_size */;
5593
5590
  emnapiTSFN.offset.is_some = 24 /* NapiTSFNOffset32.async_resource_is_some */;
5594
5591
  emnapiTSFN.offset.queue = 64 /* NapiTSFNOffset32.queue */;
5592
+ emnapiTSFN.offset.async_pending = 132 /* NapiTSFNOffset32.async_pending */;
5593
+ emnapiTSFN.offset.async_u_fd = 96 /* NapiTSFNOffset32.async_u_fd */;
5595
5594
  emnapiTSFN.offset.thread_count = 136 /* NapiTSFNOffset32.thread_count */;
5596
5595
  emnapiTSFN.offset.state = 140 /* NapiTSFNOffset32.state */;
5597
5596
  emnapiTSFN.offset.dispatch_state = 144 /* NapiTSFNOffset32.dispatch_state */;
@@ -5631,7 +5630,10 @@ var emnapiTSFN = {
5631
5630
  var type = __emnapi__.type;
5632
5631
  var payload = __emnapi__.payload;
5633
5632
  if (type === 'tsfn-send') {
5634
- emnapiTSFN.dispatch(payload.tsfn);
5633
+ var pendng = payload.tsfn + emnapiTSFN.offset.async_pending;
5634
+ if (Atomics.load(new Int32Array(wasmMemory.buffer), pendng >>> 2) !== 0) {
5635
+ emnapiTSFN.enqueue(payload.tsfn);
5636
+ }
5635
5637
  }
5636
5638
  }
5637
5639
  };
@@ -5658,6 +5660,7 @@ var emnapiTSFN = {
5658
5660
  var queue = _malloc({{{ to64('size') }}});
5659
5661
  if (!queue)
5660
5662
  return false;
5663
+ {{{ from64('queue') }}};
5661
5664
  new Uint8Array(wasmMemory.buffer, queue, size).fill(0);
5662
5665
  emnapiTSFN.storeSizeTypeValue(func + emnapiTSFN.offset.queue, queue, false);
5663
5666
  return true;
@@ -5665,6 +5668,12 @@ var emnapiTSFN = {
5665
5668
  destroyQueue: function (func) {
5666
5669
  var queue = emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.queue, false);
5667
5670
  if (queue) {
5671
+ var node = emnapiTSFN.loadSizeTypeValue(queue, false);
5672
+ while (node !== 0) {
5673
+ var next = emnapiTSFN.loadSizeTypeValue(node + {{{ POINTER_SIZE }}}, false);
5674
+ _free({{{ to64('node') }}});
5675
+ node = next;
5676
+ }
5668
5677
  _free({{{ to64('queue') }}});
5669
5678
  }
5670
5679
  },
@@ -5677,6 +5686,7 @@ var emnapiTSFN = {
5677
5686
  var node = _malloc({{{ to64('size') }}});
5678
5687
  if (!node)
5679
5688
  throw new Error('OOM');
5689
+ {{{ from64('node') }}};
5680
5690
  emnapiTSFN.storeSizeTypeValue(node, data, false);
5681
5691
  emnapiTSFN.storeSizeTypeValue(node + {{{ POINTER_SIZE }}}, 0, false);
5682
5692
  if (head === 0 && tail === 0) {
@@ -5860,10 +5870,10 @@ var emnapiTSFN = {
5860
5870
  var arr, index;
5861
5871
  #if MEMORY64
5862
5872
  arr = new BigUint64Array(wasmMemory.buffer);
5863
- index = (func + offset) >> 3;
5873
+ index = (func + offset) >>> 3;
5864
5874
  #else
5865
5875
  arr = new Uint32Array(wasmMemory.buffer);
5866
- index = (func + offset) >> 2;
5876
+ index = (func + offset) >>> 2;
5867
5877
  #endif
5868
5878
  Atomics.add(arr, index, {{{ to64('1') }}});
5869
5879
  },
@@ -5872,10 +5882,10 @@ var emnapiTSFN = {
5872
5882
  var arr, index;
5873
5883
  #if MEMORY64
5874
5884
  arr = new BigUint64Array(wasmMemory.buffer);
5875
- index = (func + offset) >> 3;
5885
+ index = (func + offset) >>> 3;
5876
5886
  #else
5877
5887
  arr = new Uint32Array(wasmMemory.buffer);
5878
- index = (func + offset) >> 2;
5888
+ index = (func + offset) >>> 2;
5879
5889
  #endif
5880
5890
  Atomics.sub(arr, index, {{{ to64('1') }}});
5881
5891
  },
@@ -5887,10 +5897,10 @@ var emnapiTSFN = {
5887
5897
  var arr, index;
5888
5898
  #if MEMORY64
5889
5899
  arr = new BigUint64Array(wasmMemory.buffer);
5890
- index = (func + offset) >> 3;
5900
+ index = (func + offset) >>> 3;
5891
5901
  #else
5892
5902
  arr = new Uint32Array(wasmMemory.buffer);
5893
- index = (func + offset) >> 2;
5903
+ index = (func + offset) >>> 2;
5894
5904
  #endif
5895
5905
  Atomics.add(arr, index, {{{ to64('1') }}});
5896
5906
  },
@@ -5899,18 +5909,18 @@ var emnapiTSFN = {
5899
5909
  var arr, index;
5900
5910
  #if MEMORY64
5901
5911
  arr = new BigUint64Array(wasmMemory.buffer);
5902
- index = (func + offset) >> 3;
5912
+ index = (func + offset) >>> 3;
5903
5913
  #else
5904
5914
  arr = new Uint32Array(wasmMemory.buffer);
5905
- index = (func + offset) >> 2;
5915
+ index = (func + offset) >>> 2;
5906
5916
  #endif
5907
5917
  Atomics.sub(arr, index, {{{ to64('1') }}});
5908
5918
  },
5909
5919
  getState: function (func) {
5910
- return Atomics.load(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >> 2);
5920
+ return Atomics.load(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >>> 2);
5911
5921
  },
5912
5922
  setState: function (func, value) {
5913
- Atomics.store(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >> 2, value);
5923
+ Atomics.store(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.state) >>> 2, value);
5914
5924
  },
5915
5925
  getHandlesClosing: function (func) {
5916
5926
  return Atomics.load(new Int8Array(wasmMemory.buffer), (func + emnapiTSFN.offset.handles_closing));
@@ -5919,7 +5929,7 @@ var emnapiTSFN = {
5919
5929
  Atomics.store(new Int8Array(wasmMemory.buffer), (func + emnapiTSFN.offset.handles_closing), value);
5920
5930
  },
5921
5931
  getDispatchState: function (func) {
5922
- return Atomics.load(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >> 2);
5932
+ return Atomics.load(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >>> 2);
5923
5933
  },
5924
5934
  getContext: function (func) {
5925
5935
  return emnapiTSFN.loadSizeTypeValue(func + emnapiTSFN.offset.context, false);
@@ -5951,20 +5961,20 @@ var emnapiTSFN = {
5951
5961
  if (unsigned) {
5952
5962
  #if MEMORY64
5953
5963
  arr = new BigUint64Array(wasmMemory.buffer);
5954
- ret = Number(Atomics.load(arr, offset >> 3));
5964
+ ret = Number(Atomics.load(arr, offset >>> 3));
5955
5965
  #else
5956
5966
  arr = new Uint32Array(wasmMemory.buffer);
5957
- ret = Atomics.load(arr, offset >> 2);
5967
+ ret = Atomics.load(arr, offset >>> 2);
5958
5968
  #endif
5959
5969
  return ret;
5960
5970
  }
5961
5971
  else {
5962
5972
  #if MEMORY64
5963
5973
  arr = new BigInt64Array(wasmMemory.buffer);
5964
- ret = Number(Atomics.load(arr, offset >> 3));
5974
+ ret = Number(Atomics.load(arr, offset >>> 3));
5965
5975
  #else
5966
5976
  arr = new Int32Array(wasmMemory.buffer);
5967
- ret = Atomics.load(arr, offset >> 2);
5977
+ ret = Atomics.load(arr, offset >>> 2);
5968
5978
  #endif
5969
5979
  return ret;
5970
5980
  }
@@ -5974,20 +5984,20 @@ var emnapiTSFN = {
5974
5984
  if (unsigned) {
5975
5985
  #if MEMORY64
5976
5986
  arr = new BigUint64Array(wasmMemory.buffer);
5977
- Atomics.store(arr, offset >> 3, BigInt(value));
5987
+ Atomics.store(arr, offset >>> 3, BigInt(value));
5978
5988
  #else
5979
5989
  arr = new Uint32Array(wasmMemory.buffer);
5980
- Atomics.store(arr, offset >> 2, value);
5990
+ Atomics.store(arr, offset >>> 2, value);
5981
5991
  #endif
5982
5992
  return undefined;
5983
5993
  }
5984
5994
  else {
5985
5995
  #if MEMORY64
5986
5996
  arr = new BigInt64Array(wasmMemory.buffer);
5987
- Atomics.store(arr, offset >> 3, BigInt(value >>> 0));
5997
+ Atomics.store(arr, offset >>> 3, BigInt(value >>> 0));
5988
5998
  #else
5989
5999
  arr = new Int32Array(wasmMemory.buffer);
5990
- Atomics.store(arr, offset >> 2, value >>> 0);
6000
+ Atomics.store(arr, offset >>> 2, value >>> 0);
5991
6001
  #endif
5992
6002
  return undefined;
5993
6003
  }
@@ -6006,7 +6016,7 @@ var emnapiTSFN = {
6006
6016
  {{{ makeSetValue('func', 'emnapiTSFN.offset.is_some', '0', 'i8') }}};
6007
6017
  emnapiCtx.removeCleanupHook(envObject, emnapiTSFN.cleanup, func);
6008
6018
  envObject.unref();
6009
- var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >> 2;
6019
+ var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
6010
6020
  var arr = new Uint32Array(wasmMemory.buffer);
6011
6021
  if (Atomics.load(arr, asyncRefOffset) > 0) {
6012
6022
  Atomics.store(arr, asyncRefOffset, 0);
@@ -6022,6 +6032,7 @@ var emnapiTSFN = {
6022
6032
  }
6023
6033
  },
6024
6034
  destroy: function (func) {
6035
+ emnapiTSFN._liveSet.delete(func);
6025
6036
  emnapiTSFN.destroyQueue(func);
6026
6037
  emnapiTSFN.releaseResources(func);
6027
6038
  _free({{{ to64('func') }}});
@@ -6116,6 +6127,7 @@ var emnapiTSFN = {
6116
6127
  return;
6117
6128
  }
6118
6129
  emnapiTSFN.setHandlesClosing(func, 1);
6130
+ Atomics.store(new Int32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.async_pending) >>> 2, 1);
6119
6131
  emnapiCtx.feature.setImmediate(function () {
6120
6132
  emnapiTSFN.finalize(func);
6121
6133
  });
@@ -6207,7 +6219,7 @@ var emnapiTSFN = {
6207
6219
  var has_more = true;
6208
6220
  var iterations_left = 1000;
6209
6221
  var ui32a = new Uint32Array(wasmMemory.buffer);
6210
- var index = (func + emnapiTSFN.offset.dispatch_state) >> 2;
6222
+ var index = (func + emnapiTSFN.offset.dispatch_state) >>> 2;
6211
6223
  while (has_more && --iterations_left !== 0) {
6212
6224
  Atomics.store(ui32a, index, 1);
6213
6225
  has_more = emnapiTSFN.dispatchOne(func);
@@ -6219,25 +6231,85 @@ var emnapiTSFN = {
6219
6231
  emnapiTSFN.send(func);
6220
6232
  }
6221
6233
  },
6222
- send: function (func) {
6223
- var current_state = Atomics.or(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >> 2, 1 << 1);
6224
- if ((current_state & 1) === 1) {
6234
+ enqueue: function (func) {
6235
+ // `pending` means a worker thread has requested a wakeup that has not
6236
+ // been drained on the main thread yet.
6237
+ var pending = func + emnapiTSFN.offset.async_pending;
6238
+ // `scheduled` prevents queueing the same main-thread drain chain more than
6239
+ // once while a previous wakeup is still in flight.
6240
+ var scheduled = func + emnapiTSFN.offset.async_u_fd;
6241
+ var i32a = new Int32Array(wasmMemory.buffer);
6242
+ if (Atomics.exchange(i32a, scheduled >>> 2, 1) !== 0) {
6225
6243
  return;
6226
6244
  }
6227
- if ((typeof ENVIRONMENT_IS_PTHREAD !== 'undefined') && ENVIRONMENT_IS_PTHREAD) {
6228
- postMessage({
6229
- __emnapi__: {
6230
- type: 'tsfn-send',
6231
- payload: {
6232
- tsfn: func
6245
+ // Match uv_async_send-style coalescing in JS: the first turn represents
6246
+ // the wakeup reaching the main thread, and the second turn performs the
6247
+ // actual TSFN drain after nearby Send/Signal calls have had a chance to
6248
+ // collapse into the shared AsyncProgressWorker state.
6249
+ emnapiCtx.feature.setImmediate(function () {
6250
+ if (!emnapiTSFN._liveSet.has(func)) {
6251
+ return;
6252
+ }
6253
+ if (Atomics.load(i32a, pending >>> 2) === 0) {
6254
+ Atomics.store(i32a, scheduled >>> 2, 0);
6255
+ return;
6256
+ }
6257
+ emnapiCtx.feature.setImmediate(function () {
6258
+ try {
6259
+ // Consume the coalesced wakeup once, then let dispatch() observe any
6260
+ // queue mutations through dispatch_state like the C implementation.
6261
+ if (Atomics.exchange(i32a, pending >>> 2, 0) === 0) {
6262
+ return;
6263
+ }
6264
+ // After destroy(), the func address is freed. Skip dispatch
6265
+ // to avoid use-after-free (JS-side lifecycle check).
6266
+ if (!emnapiTSFN._liveSet.has(func)) {
6267
+ return;
6268
+ }
6269
+ emnapiTSFN.dispatch(func);
6270
+ }
6271
+ finally {
6272
+ // Allow a later wakeup to schedule a new drain chain. If another
6273
+ // worker-thread send raced with this drain, enqueue one more turn.
6274
+ if (emnapiTSFN._liveSet.has(func)) {
6275
+ Atomics.store(i32a, scheduled >>> 2, 0);
6276
+ if (Atomics.load(i32a, pending >>> 2) !== 0) {
6277
+ emnapiTSFN.enqueue(func);
6278
+ }
6233
6279
  }
6234
6280
  }
6235
6281
  });
6282
+ });
6283
+ },
6284
+ send: function (func) {
6285
+ var current_state = Atomics.or(new Uint32Array(wasmMemory.buffer), (func + emnapiTSFN.offset.dispatch_state) >>> 2, 1 << 1);
6286
+ if ((current_state & 1) === 1) {
6287
+ return;
6236
6288
  }
6237
- else {
6238
- emnapiCtx.feature.setImmediate(function () {
6239
- emnapiTSFN.dispatch(func);
6240
- });
6289
+ var pendng = func + emnapiTSFN.offset.async_pending;
6290
+ // A wakeup is already pending, so this send only needs to leave the queued
6291
+ // work in the TSFN queue and let the existing drain pick it up.
6292
+ if (Atomics.load(new Int32Array(wasmMemory.buffer), pendng >>> 2) !== 0) {
6293
+ return;
6294
+ }
6295
+ if (Atomics.exchange(new Int32Array(wasmMemory.buffer), pendng >>> 2, 1) === 0) {
6296
+ if ((typeof ENVIRONMENT_IS_PTHREAD !== 'undefined') && ENVIRONMENT_IS_PTHREAD) {
6297
+ // Worker threads only post a wakeup token. Main-thread draining is
6298
+ // serialized by enqueue() once the message is received.
6299
+ postMessage({
6300
+ __emnapi__: {
6301
+ type: 'tsfn-send',
6302
+ payload: {
6303
+ tsfn: func
6304
+ }
6305
+ }
6306
+ });
6307
+ }
6308
+ else {
6309
+ // On the main thread we can skip the cross-thread hop and schedule the
6310
+ // coalesced drain chain directly.
6311
+ emnapiTSFN.enqueue(func);
6312
+ }
6241
6313
  }
6242
6314
  }
6243
6315
  };
@@ -6324,6 +6396,7 @@ function _napi_create_threadsafe_function(env, func, async_resource, async_resou
6324
6396
  {{{ makeSetValue('tsfn', 'emnapiTSFN.offset.finalize_cb', 'thread_finalize_cb', '*') }}};
6325
6397
  {{{ makeSetValue('tsfn', 'emnapiTSFN.offset.call_js_cb', 'call_js_cb', '*') }}};
6326
6398
  emnapiCtx.addCleanupHook(envObject, emnapiTSFN.cleanup, tsfn);
6399
+ emnapiTSFN._liveSet.add(tsfn);
6327
6400
  envObject.ref();
6328
6401
  __emnapi_runtime_keepalive_push();
6329
6402
  emnapiCtx.increaseWaitingRequestCounter();
@@ -6415,7 +6488,7 @@ function _napi_unref_threadsafe_function(env, func) {
6415
6488
  return 1 /* napi_status.napi_invalid_arg */;
6416
6489
  }
6417
6490
  {{{ from64('func') }}};
6418
- var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >> 2;
6491
+ var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
6419
6492
  var arr = new Uint32Array(wasmMemory.buffer);
6420
6493
  var currentValue = Atomics.load(arr, asyncRefOffset);
6421
6494
  if (currentValue > 0) {
@@ -6434,7 +6507,7 @@ function _napi_ref_threadsafe_function(env, func) {
6434
6507
  return 1 /* napi_status.napi_invalid_arg */;
6435
6508
  }
6436
6509
  {{{ from64('func') }}};
6437
- var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >> 2;
6510
+ var asyncRefOffset = (func + emnapiTSFN.offset.async_ref) >>> 2;
6438
6511
  var arr = new Uint32Array(wasmMemory.buffer);
6439
6512
  var currentValue = Atomics.load(arr, asyncRefOffset);
6440
6513
  if (!currentValue) {
@@ -7074,7 +7147,7 @@ function _napi_get_version(env, result) {
7074
7147
  napi_add_env_cleanup_hook__deps: ["$emnapiCtx"],
7075
7148
  napi_add_env_cleanup_hook__sig: "ippp",
7076
7149
  napi_adjust_external_memory: _napi_adjust_external_memory,
7077
- napi_adjust_external_memory__deps: ["$emnapiCtx", "$emnapiSetValueI64", "emscripten_resize_heap"],
7150
+ napi_adjust_external_memory__deps: ["$emnapiCtx", "$emnapiSetValueI64"],
7078
7151
  napi_adjust_external_memory__sig: "ipjp",
7079
7152
  napi_call_function: _napi_call_function,
7080
7153
  napi_call_function__deps: ["$emnapiCtx"],
@@ -6,8 +6,8 @@
6
6
  #include "emnapi_common.h"
7
7
 
8
8
  #define EMNAPI_MAJOR_VERSION 1
9
- #define EMNAPI_MINOR_VERSION 9
10
- #define EMNAPI_PATCH_VERSION 1
9
+ #define EMNAPI_MINOR_VERSION 10
10
+ #define EMNAPI_PATCH_VERSION 0
11
11
 
12
12
  typedef enum {
13
13
  emnapi_runtime,
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emnapi",
3
- "version": "1.9.1",
3
+ "version": "1.10.0",
4
4
  "description": "Node-API implementation for Emscripten",
5
5
  "main": "index.js",
6
6
  "gypfile": false,