emnapi 1.4.5 → 1.6.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.
- package/CMakeLists.txt +34 -0
- package/README.md +4 -2
- package/common.gypi +11 -0
- package/dist/library_napi.js +128 -12
- package/emnapi.gyp +18 -0
- package/include/node/emnapi.h +2 -2
- package/include/node/js_native_api.h +9 -1
- 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-emscripten/libemnapi-mt.a +0 -0
- package/lib/wasm32-emscripten/libemnapi.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/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-basic.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/emnapi_internal.h +7 -0
- package/src/threadsafe_function.c +4 -4
- package/src/wasi_wait.c +106 -0
package/CMakeLists.txt
CHANGED
|
@@ -44,6 +44,7 @@ set(ENAPI_BASIC_SRC
|
|
|
44
44
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/node_api.c"
|
|
45
45
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_cleanup_hook.c"
|
|
46
46
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_context.c"
|
|
47
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/wasi_wait.c"
|
|
47
48
|
)
|
|
48
49
|
set(EMNAPI_THREADS_SRC
|
|
49
50
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_work.c"
|
|
@@ -70,6 +71,10 @@ set(EMNAPI_BASIC_TARGET_NAME "emnapi-basic")
|
|
|
70
71
|
set(EMNAPI_BASIC_MT_TARGET_NAME "emnapi-basic-mt")
|
|
71
72
|
set(EMNAPI_TARGET_NAME "emnapi")
|
|
72
73
|
set(EMNAPI_MT_TARGET_NAME "emnapi-mt")
|
|
74
|
+
|
|
75
|
+
set(EMNAPI_BASIC_NAPI_RS_MT_TARGET_NAME "emnapi-basic-napi-rs-mt")
|
|
76
|
+
set(EMNAPI_NAPI_RS_MT_TARGET_NAME "emnapi-napi-rs-mt")
|
|
77
|
+
|
|
73
78
|
set(DLMALLOC_TARGET_NAME "dlmalloc")
|
|
74
79
|
set(DLMALLOC_MT_TARGET_NAME "dlmalloc-mt")
|
|
75
80
|
set(EMMALLOC_TARGET_NAME "emmalloc")
|
|
@@ -155,6 +160,31 @@ else()
|
|
|
155
160
|
set(EMNAPI_BUILD_BASIC_MT OFF)
|
|
156
161
|
endif()
|
|
157
162
|
|
|
163
|
+
if(IS_WASM32_WASIP1_THREADS)
|
|
164
|
+
set(EMNAPI_BUILD_FOR_NAPI_RS ON)
|
|
165
|
+
else()
|
|
166
|
+
set(EMNAPI_BUILD_FOR_NAPI_RS OFF)
|
|
167
|
+
endif()
|
|
168
|
+
|
|
169
|
+
if(EMNAPI_BUILD_FOR_NAPI_RS)
|
|
170
|
+
add_library(${EMNAPI_NAPI_RS_MT_TARGET_NAME} STATIC ${EMNAPI_SRC} ${UV_SRC})
|
|
171
|
+
target_include_directories(${EMNAPI_NAPI_RS_MT_TARGET_NAME} PUBLIC ${EMNAPI_INCLUDE})
|
|
172
|
+
target_compile_definitions(${EMNAPI_NAPI_RS_MT_TARGET_NAME}
|
|
173
|
+
PUBLIC ${EMNAPI_DEFINES} "NAPI_EXTERN=__attribute__((__import_module__(\"env\")))"
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
add_library(${EMNAPI_BASIC_NAPI_RS_MT_TARGET_NAME} STATIC
|
|
177
|
+
${ENAPI_BASIC_SRC}
|
|
178
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/thread/async_worker_create.c"
|
|
179
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/thread/async_worker_init.S"
|
|
180
|
+
)
|
|
181
|
+
target_include_directories(${EMNAPI_BASIC_NAPI_RS_MT_TARGET_NAME} PUBLIC ${EMNAPI_INCLUDE})
|
|
182
|
+
target_compile_definitions(${EMNAPI_BASIC_NAPI_RS_MT_TARGET_NAME}
|
|
183
|
+
PUBLIC ${EMNAPI_DEFINES} "NAPI_EXTERN=__attribute__((__import_module__(\"env\")))"
|
|
184
|
+
PRIVATE "EMNAPI_DISABLE_UV"
|
|
185
|
+
)
|
|
186
|
+
endif()
|
|
187
|
+
|
|
158
188
|
if(EMNAPI_BUILD_BASIC_MT)
|
|
159
189
|
add_library(${EMNAPI_BASIC_MT_TARGET_NAME} STATIC
|
|
160
190
|
${ENAPI_BASIC_SRC}
|
|
@@ -222,6 +252,10 @@ if(LIB_ARCH)
|
|
|
222
252
|
if(EMNAPI_BUILD_BASIC_MT)
|
|
223
253
|
install(TARGETS ${EMNAPI_BASIC_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
224
254
|
endif()
|
|
255
|
+
if(EMNAPI_BUILD_FOR_NAPI_RS)
|
|
256
|
+
install(TARGETS ${EMNAPI_NAPI_RS_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
257
|
+
install(TARGETS ${EMNAPI_BASIC_NAPI_RS_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
258
|
+
endif()
|
|
225
259
|
if(IS_WASM32)
|
|
226
260
|
install(TARGETS ${DLMALLOC_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
227
261
|
install(TARGETS ${DLMALLOC_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
package/README.md
CHANGED
|
@@ -816,8 +816,9 @@ Now emnapi has 3 implementations of async work and 2 implementations of TSFN:
|
|
|
816
816
|
There are some limitations on browser about wasi-libc's pthread implementation, for example
|
|
817
817
|
`pthread_mutex_lock` may call `__builtin_wasm_memory_atomic_wait32`(`memory.atomic.wait32`)
|
|
818
818
|
which is disallowed in browser JS main thread. While Emscripten's pthread implementation
|
|
819
|
-
has considered usage in browser.
|
|
820
|
-
|
|
819
|
+
has considered usage in browser. This issue can be solved by upgrading `wasi-sdk` to v26+
|
|
820
|
+
and emnapi v1.5.0+ then pass `--export=emnapi_thread_crashed` to the linker. If you need to
|
|
821
|
+
run your addon with multithreaded features, we recommend you use A & D or C & E.
|
|
821
822
|
|
|
822
823
|
Note: For browsers, all the multithreaded features relying on Web Workers (Emscripten pthread also relying on Web Workers)
|
|
823
824
|
require cross-origin isolation to enable `SharedArrayBuffer`. You can make a page cross-origin isolated
|
|
@@ -879,6 +880,7 @@ elseif(CMAKE_C_COMPILER_TARGET STREQUAL "wasm32-wasi-threads")
|
|
|
879
880
|
"-Wl,--export-if-defined=node_api_module_get_api_version_v1"
|
|
880
881
|
"-Wl,--export=malloc"
|
|
881
882
|
"-Wl,--export=free"
|
|
883
|
+
"-Wl,--export=emnapi_thread_crashed"
|
|
882
884
|
"-Wl,--import-undefined"
|
|
883
885
|
"-Wl,--export-table"
|
|
884
886
|
)
|
package/common.gypi
CHANGED
|
@@ -308,6 +308,7 @@
|
|
|
308
308
|
'src/async_cleanup_hook.c',
|
|
309
309
|
'src/async_context.c',
|
|
310
310
|
'src/async_work.c',
|
|
311
|
+
'src/wasi_wait.c',
|
|
311
312
|
'src/threadsafe_function.c',
|
|
312
313
|
'src/uv/uv-common.c',
|
|
313
314
|
'src/uv/threadpool.c',
|
|
@@ -370,6 +371,16 @@
|
|
|
370
371
|
]
|
|
371
372
|
},
|
|
372
373
|
}],
|
|
374
|
+
['OS == "wasi"', {
|
|
375
|
+
'ldflags': [
|
|
376
|
+
'-Wl,--export=emnapi_thread_crashed',
|
|
377
|
+
],
|
|
378
|
+
'xcode_settings': {
|
|
379
|
+
'OTHER_LDFLAGS': [
|
|
380
|
+
'-Wl,--export=emnapi_thread_crashed',
|
|
381
|
+
],
|
|
382
|
+
},
|
|
383
|
+
}],
|
|
373
384
|
['OS != "wasi"', {
|
|
374
385
|
'defines': [
|
|
375
386
|
'PAGESIZE=65536'
|
package/dist/library_napi.js
CHANGED
|
@@ -61,10 +61,13 @@ function emnapiInit(options) {
|
|
|
61
61
|
});
|
|
62
62
|
}
|
|
63
63
|
catch (err) {
|
|
64
|
+
if (err !== 'unwind') {
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
finally {
|
|
64
69
|
emnapiCtx.closeScope(envObject, scope);
|
|
65
|
-
throw err;
|
|
66
70
|
}
|
|
67
|
-
emnapiCtx.closeScope(envObject, scope);
|
|
68
71
|
emnapiModule.loaded = true;
|
|
69
72
|
delete emnapiModule.envObject;
|
|
70
73
|
return emnapiModule.exports;
|
|
@@ -75,7 +78,6 @@ function emnapiInit(options) {
|
|
|
75
78
|
function __emnapi_async_work_pool_size() {
|
|
76
79
|
return Math.abs(emnapiAsyncWorkPoolSize);
|
|
77
80
|
}
|
|
78
|
-
/* eslint-disable @typescript-eslint/indent */
|
|
79
81
|
/**
|
|
80
82
|
* @__sig ipiip
|
|
81
83
|
*/
|
|
@@ -180,6 +182,31 @@ function __emnapi_ctx_increase_waiting_request_counter() {
|
|
|
180
182
|
function __emnapi_ctx_decrease_waiting_request_counter() {
|
|
181
183
|
emnapiCtx.decreaseWaitingRequestCounter();
|
|
182
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* @__sig i
|
|
187
|
+
*/
|
|
188
|
+
function __emnapi_is_main_runtime_thread() {
|
|
189
|
+
return ENVIRONMENT_IS_PTHREAD ? 0 : 1;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* @__sig i
|
|
193
|
+
*/
|
|
194
|
+
function __emnapi_is_main_browser_thread() {
|
|
195
|
+
return (typeof window !== 'undefined' && typeof document !== 'undefined' && !ENVIRONMENT_IS_NODE) ? 1 : 0;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* @__sig v
|
|
199
|
+
*/
|
|
200
|
+
function __emnapi_unwind() {
|
|
201
|
+
// eslint-disable-next-line @typescript-eslint/no-throw-literal
|
|
202
|
+
throw 'unwind';
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* @__sig d
|
|
206
|
+
*/
|
|
207
|
+
function __emnapi_get_now() {
|
|
208
|
+
return performance.timeOrigin + performance.now();
|
|
209
|
+
}
|
|
183
210
|
function emnapiSetValueI64(result, numberValue) {
|
|
184
211
|
var tempDouble;
|
|
185
212
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -190,6 +217,20 @@ function emnapiSetValueI64(result, numberValue) {
|
|
|
190
217
|
{{{ makeSetValue('result', 0, 'tempI64[0]', 'i32') }}};
|
|
191
218
|
{{{ makeSetValue('result', 4, 'tempI64[1]', 'i32') }}};
|
|
192
219
|
}
|
|
220
|
+
/**
|
|
221
|
+
* @__deps $emnapiCtx
|
|
222
|
+
* @__sig p
|
|
223
|
+
*/
|
|
224
|
+
function __emnapi_open_handle_scope() {
|
|
225
|
+
return emnapiCtx.openScope().id;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* @__deps $emnapiCtx
|
|
229
|
+
* @__sig vp
|
|
230
|
+
*/
|
|
231
|
+
function __emnapi_close_handle_scope(_scope) {
|
|
232
|
+
return emnapiCtx.closeScope();
|
|
233
|
+
}
|
|
193
234
|
/* eslint-disable eqeqeq */
|
|
194
235
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
195
236
|
/* eslint-disable @typescript-eslint/indent */
|
|
@@ -942,6 +983,10 @@ var emnapiExternalMemory = {
|
|
|
942
983
|
emnapiExternalMemory.table = new WeakMap();
|
|
943
984
|
emnapiExternalMemory.wasmMemoryViewTable = new WeakMap();
|
|
944
985
|
},
|
|
986
|
+
isSharedArrayBuffer: function (value) {
|
|
987
|
+
return ((typeof SharedArrayBuffer === 'function' && value instanceof SharedArrayBuffer) ||
|
|
988
|
+
(Object.prototype.toString.call(value) === '[object SharedArrayBuffer]'));
|
|
989
|
+
},
|
|
945
990
|
isDetachedArrayBuffer: function (arrayBuffer) {
|
|
946
991
|
if (arrayBuffer.byteLength === 0) {
|
|
947
992
|
try {
|
|
@@ -1083,7 +1128,7 @@ function _napi_get_arraybuffer_info(env, arraybuffer, data, byte_length) {
|
|
|
1083
1128
|
if (!arraybuffer)
|
|
1084
1129
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
1085
1130
|
var handle = emnapiCtx.handleStore.get(arraybuffer);
|
|
1086
|
-
if (!handle.isArrayBuffer()) {
|
|
1131
|
+
if (!handle.isArrayBuffer() && !emnapiExternalMemory.isSharedArrayBuffer(handle.value)) {
|
|
1087
1132
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
1088
1133
|
}
|
|
1089
1134
|
if (data) {
|
|
@@ -2586,7 +2631,7 @@ function emnapiSyncMemory(js_to_wasm, arrayBufferOrView, offset, len) {
|
|
|
2586
2631
|
offset = offset !== null && offset !== void 0 ? offset : 0;
|
|
2587
2632
|
offset = offset >>> 0;
|
|
2588
2633
|
var view;
|
|
2589
|
-
if (arrayBufferOrView instanceof ArrayBuffer) {
|
|
2634
|
+
if (arrayBufferOrView instanceof ArrayBuffer || emnapiExternalMemory.isSharedArrayBuffer(arrayBufferOrView)) {
|
|
2590
2635
|
var pointer = emnapiExternalMemory.getArrayBufferPointer(arrayBufferOrView, false).address;
|
|
2591
2636
|
if (!pointer)
|
|
2592
2637
|
throw new Error('Unknown ArrayBuffer address');
|
|
@@ -2654,7 +2699,7 @@ function _emnapi_sync_memory(env, js_to_wasm, arraybuffer_or_view, offset, len)
|
|
|
2654
2699
|
{{{ from64('len') }}};
|
|
2655
2700
|
var handleId = {{{ makeGetValue('arraybuffer_or_view', 0, '*') }}};
|
|
2656
2701
|
var handle = envObject.ctx.handleStore.get(handleId);
|
|
2657
|
-
if (!handle.isArrayBuffer() && !handle.isTypedArray() && !handle.isDataView()) {
|
|
2702
|
+
if (!handle.isArrayBuffer() && !handle.isTypedArray() && !handle.isDataView() && !emnapiExternalMemory.isSharedArrayBuffer(handle.value)) {
|
|
2658
2703
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
2659
2704
|
}
|
|
2660
2705
|
var ret = emnapiSyncMemory(Boolean(js_to_wasm), handle.value, offset, len);
|
|
@@ -2674,7 +2719,7 @@ function emnapiGetMemoryAddress(arrayBufferOrView) {
|
|
|
2674
2719
|
var isArrayBuffer = arrayBufferOrView instanceof ArrayBuffer;
|
|
2675
2720
|
var isDataView = arrayBufferOrView instanceof DataView;
|
|
2676
2721
|
var isTypedArray = ArrayBuffer.isView(arrayBufferOrView) && !isDataView;
|
|
2677
|
-
if (!isArrayBuffer && !isTypedArray && !isDataView) {
|
|
2722
|
+
if (!isArrayBuffer && !isTypedArray && !isDataView && !emnapiExternalMemory.isSharedArrayBuffer(arrayBufferOrView)) {
|
|
2678
2723
|
throw new TypeError('emnapiGetMemoryAddress expect ArrayBuffer or ArrayBufferView as first parameter');
|
|
2679
2724
|
}
|
|
2680
2725
|
var info;
|
|
@@ -2800,10 +2845,10 @@ function _napi_create_array_with_length(env, length, result) {
|
|
|
2800
2845
|
{{{ makeSetValue('result', 0, 'value', '*') }}};
|
|
2801
2846
|
return envObject.clearLastError();
|
|
2802
2847
|
}
|
|
2803
|
-
function emnapiCreateArrayBuffer(byte_length, data) {
|
|
2848
|
+
function emnapiCreateArrayBuffer(byte_length, data, shared) {
|
|
2804
2849
|
{{{ from64('byte_length') }}};
|
|
2805
2850
|
byte_length = byte_length >>> 0;
|
|
2806
|
-
var arrayBuffer = new ArrayBuffer(byte_length);
|
|
2851
|
+
var arrayBuffer = shared ? new SharedArrayBuffer(byte_length) : new ArrayBuffer(byte_length);
|
|
2807
2852
|
if (data) {
|
|
2808
2853
|
{{{ from64('data') }}};
|
|
2809
2854
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
@@ -2832,7 +2877,37 @@ function _napi_create_arraybuffer(env, byte_length, data, result) {
|
|
|
2832
2877
|
if (!result)
|
|
2833
2878
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
2834
2879
|
{{{ from64('result') }}};
|
|
2835
|
-
var arrayBuffer = emnapiCreateArrayBuffer(byte_length, data);
|
|
2880
|
+
var arrayBuffer = emnapiCreateArrayBuffer(byte_length, data, false);
|
|
2881
|
+
value = emnapiCtx.addToCurrentScope(arrayBuffer).id;
|
|
2882
|
+
{{{ makeSetValue('result', 0, 'value', '*') }}};
|
|
2883
|
+
return envObject.getReturnStatus();
|
|
2884
|
+
}
|
|
2885
|
+
catch (err) {
|
|
2886
|
+
envObject.tryCatch.setError(err);
|
|
2887
|
+
return envObject.setLastError(10 /* napi_status.napi_pending_exception */);
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
/**
|
|
2891
|
+
* @__sig ipppp
|
|
2892
|
+
*/
|
|
2893
|
+
function _node_api_create_sharedarraybuffer(env, byte_length, data, result) {
|
|
2894
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2895
|
+
var value;
|
|
2896
|
+
if (!env)
|
|
2897
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
2898
|
+
// @ts-expect-error
|
|
2899
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
2900
|
+
envObject.checkGCAccess();
|
|
2901
|
+
if (!envObject.tryCatch.isEmpty())
|
|
2902
|
+
return envObject.setLastError(10 /* napi_status.napi_pending_exception */);
|
|
2903
|
+
if (!envObject.canCallIntoJs())
|
|
2904
|
+
return envObject.setLastError(envObject.moduleApiVersion >= 10 ? 23 /* napi_status.napi_cannot_run_js */ : 10 /* napi_status.napi_pending_exception */);
|
|
2905
|
+
envObject.clearLastError();
|
|
2906
|
+
try {
|
|
2907
|
+
if (!result)
|
|
2908
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
2909
|
+
{{{ from64('result') }}};
|
|
2910
|
+
var arrayBuffer = emnapiCreateArrayBuffer(byte_length, data, true);
|
|
2836
2911
|
value = emnapiCtx.addToCurrentScope(arrayBuffer).id;
|
|
2837
2912
|
{{{ makeSetValue('result', 0, 'value', '*') }}};
|
|
2838
2913
|
return envObject.getReturnStatus();
|
|
@@ -3205,7 +3280,7 @@ function _napi_create_buffer_copy(env, length, data, result_data, result) {
|
|
|
3205
3280
|
if (!Buffer) {
|
|
3206
3281
|
throw emnapiCtx.createNotSupportBufferError('napi_create_buffer_copy', '');
|
|
3207
3282
|
}
|
|
3208
|
-
var arrayBuffer = emnapiCreateArrayBuffer(length, result_data);
|
|
3283
|
+
var arrayBuffer = emnapiCreateArrayBuffer(length, result_data, false);
|
|
3209
3284
|
var buffer = Buffer.from(arrayBuffer);
|
|
3210
3285
|
{{{ from64('data') }}};
|
|
3211
3286
|
{{{ from64('length') }}};
|
|
@@ -6417,6 +6492,27 @@ function _napi_is_arraybuffer(env, value, result) {
|
|
|
6417
6492
|
return envObject.clearLastError();
|
|
6418
6493
|
}
|
|
6419
6494
|
/** @__sig ippp */
|
|
6495
|
+
function _node_api_is_sharedarraybuffer(env, value, result) {
|
|
6496
|
+
if (!env)
|
|
6497
|
+
return 1 /* napi_status.napi_invalid_arg */;
|
|
6498
|
+
// @ts-expect-error
|
|
6499
|
+
var envObject = emnapiCtx.envStore.get(env);
|
|
6500
|
+
envObject.checkGCAccess();
|
|
6501
|
+
if (!value)
|
|
6502
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
6503
|
+
if (!result)
|
|
6504
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
6505
|
+
var h = emnapiCtx.handleStore.get(value);
|
|
6506
|
+
{{{ from64('result') }}};
|
|
6507
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
6508
|
+
var r = ((typeof SharedArrayBuffer === 'function' && h.value instanceof SharedArrayBuffer) ||
|
|
6509
|
+
(Object.prototype.toString.call(h.value) === '[object SharedArrayBuffer]'))
|
|
6510
|
+
? 1
|
|
6511
|
+
: 0;
|
|
6512
|
+
{{{ makeSetValue('result', 0, 'r', 'i8') }}};
|
|
6513
|
+
return envObject.clearLastError();
|
|
6514
|
+
}
|
|
6515
|
+
/** @__sig ippp */
|
|
6420
6516
|
function _napi_is_date(env, value, result) {
|
|
6421
6517
|
if (!env)
|
|
6422
6518
|
return 1 /* napi_status.napi_invalid_arg */;
|
|
@@ -6655,6 +6751,9 @@ function _napi_get_version(env, result) {
|
|
|
6655
6751
|
_emnapi_callback_into_module: __emnapi_callback_into_module,
|
|
6656
6752
|
_emnapi_callback_into_module__deps: ["$emnapiCtx"],
|
|
6657
6753
|
_emnapi_callback_into_module__sig: "vipppi",
|
|
6754
|
+
_emnapi_close_handle_scope: __emnapi_close_handle_scope,
|
|
6755
|
+
_emnapi_close_handle_scope__deps: ["$emnapiCtx", "$emnapiCtx"],
|
|
6756
|
+
_emnapi_close_handle_scope__sig: "vp",
|
|
6658
6757
|
_emnapi_ctx_decrease_waiting_request_counter: __emnapi_ctx_decrease_waiting_request_counter,
|
|
6659
6758
|
_emnapi_ctx_decrease_waiting_request_counter__deps: ["$emnapiCtx"],
|
|
6660
6759
|
_emnapi_ctx_decrease_waiting_request_counter__sig: "v",
|
|
@@ -6681,6 +6780,12 @@ function _napi_get_version(env, result) {
|
|
|
6681
6780
|
_emnapi_get_last_error_info__sig: "vpppp",
|
|
6682
6781
|
_emnapi_get_node_version: __emnapi_get_node_version,
|
|
6683
6782
|
_emnapi_get_node_version__sig: "vppp",
|
|
6783
|
+
_emnapi_get_now: __emnapi_get_now,
|
|
6784
|
+
_emnapi_get_now__sig: "d",
|
|
6785
|
+
_emnapi_is_main_browser_thread: __emnapi_is_main_browser_thread,
|
|
6786
|
+
_emnapi_is_main_browser_thread__sig: "i",
|
|
6787
|
+
_emnapi_is_main_runtime_thread: __emnapi_is_main_runtime_thread,
|
|
6788
|
+
_emnapi_is_main_runtime_thread__sig: "i",
|
|
6684
6789
|
_emnapi_node_emit_async_destroy: __emnapi_node_emit_async_destroy,
|
|
6685
6790
|
_emnapi_node_emit_async_destroy__deps: ["$emnapiNodeBinding"],
|
|
6686
6791
|
_emnapi_node_emit_async_destroy__sig: "vdd",
|
|
@@ -6690,12 +6795,17 @@ function _napi_get_version(env, result) {
|
|
|
6690
6795
|
_emnapi_node_make_callback: __emnapi_node_make_callback,
|
|
6691
6796
|
_emnapi_node_make_callback__deps: ["$emnapiNodeBinding", "$emnapiCtx"],
|
|
6692
6797
|
_emnapi_node_make_callback__sig: "ipppppddp",
|
|
6798
|
+
_emnapi_open_handle_scope: __emnapi_open_handle_scope,
|
|
6799
|
+
_emnapi_open_handle_scope__deps: ["$emnapiCtx", "$emnapiCtx"],
|
|
6800
|
+
_emnapi_open_handle_scope__sig: "p",
|
|
6693
6801
|
_emnapi_runtime_keepalive_pop: __emnapi_runtime_keepalive_pop,
|
|
6694
6802
|
_emnapi_runtime_keepalive_pop__deps: ["$runtimeKeepalivePop"],
|
|
6695
6803
|
_emnapi_runtime_keepalive_pop__sig: "v",
|
|
6696
6804
|
_emnapi_runtime_keepalive_push: __emnapi_runtime_keepalive_push,
|
|
6697
6805
|
_emnapi_runtime_keepalive_push__deps: ["$runtimeKeepalivePush"],
|
|
6698
6806
|
_emnapi_runtime_keepalive_push__sig: "v",
|
|
6807
|
+
_emnapi_unwind: __emnapi_unwind,
|
|
6808
|
+
_emnapi_unwind__sig: "v",
|
|
6699
6809
|
_emnapi_worker_unref: __emnapi_worker_unref,
|
|
6700
6810
|
_emnapi_worker_unref__deps: ["$PThread"],
|
|
6701
6811
|
_emnapi_worker_unref__sig: "vp",
|
|
@@ -6729,7 +6839,7 @@ function _napi_get_version(env, result) {
|
|
|
6729
6839
|
emnapi_is_support_weakref__deps: ["$emnapiCtx"],
|
|
6730
6840
|
emnapi_is_support_weakref__sig: "i",
|
|
6731
6841
|
emnapi_sync_memory: _emnapi_sync_memory,
|
|
6732
|
-
emnapi_sync_memory__deps: ["$emnapiCtx", "$emnapiSyncMemory"],
|
|
6842
|
+
emnapi_sync_memory__deps: ["$emnapiCtx", "$emnapiExternalMemory", "$emnapiSyncMemory"],
|
|
6733
6843
|
emnapi_sync_memory__sig: "ipippp",
|
|
6734
6844
|
$emnapiTSFN: emnapiTSFN,
|
|
6735
6845
|
$emnapiTSFN__deps: ["$emnapiCtx", "_emnapi_runtime_keepalive_pop", "$emnapiNodeBinding", "_emnapi_node_emit_async_destroy", "malloc", "free"],
|
|
@@ -7177,9 +7287,15 @@ function _napi_get_version(env, result) {
|
|
|
7177
7287
|
node_api_create_property_key_utf8: _node_api_create_property_key_utf8,
|
|
7178
7288
|
node_api_create_property_key_utf8__deps: ["napi_create_string_utf8"],
|
|
7179
7289
|
node_api_create_property_key_utf8__sig: "ipppp",
|
|
7290
|
+
node_api_create_sharedarraybuffer: _node_api_create_sharedarraybuffer,
|
|
7291
|
+
node_api_create_sharedarraybuffer__deps: ["$emnapiCtx", "$emnapiCreateArrayBuffer"],
|
|
7292
|
+
node_api_create_sharedarraybuffer__sig: "ipppp",
|
|
7180
7293
|
node_api_create_syntax_error: _node_api_create_syntax_error,
|
|
7181
7294
|
node_api_create_syntax_error__deps: ["$emnapiCtx"],
|
|
7182
7295
|
node_api_create_syntax_error__sig: "ipppp",
|
|
7296
|
+
node_api_is_sharedarraybuffer: _node_api_is_sharedarraybuffer,
|
|
7297
|
+
node_api_is_sharedarraybuffer__deps: ["$emnapiCtx"],
|
|
7298
|
+
node_api_is_sharedarraybuffer__sig: "ippp",
|
|
7183
7299
|
node_api_post_finalizer: _node_api_post_finalizer,
|
|
7184
7300
|
node_api_post_finalizer__deps: ["$emnapiCtx"],
|
|
7185
7301
|
node_api_post_finalizer__sig: "ipppp",
|
package/emnapi.gyp
CHANGED
|
@@ -55,6 +55,7 @@
|
|
|
55
55
|
'src/node_api.c',
|
|
56
56
|
'src/async_cleanup_hook.c',
|
|
57
57
|
'src/async_context.c',
|
|
58
|
+
'src/wasi_wait.c',
|
|
58
59
|
],
|
|
59
60
|
'link_settings': {
|
|
60
61
|
'target_conditions': [
|
|
@@ -88,6 +89,22 @@
|
|
|
88
89
|
]
|
|
89
90
|
},
|
|
90
91
|
}],
|
|
92
|
+
['OS == "wasi"', {
|
|
93
|
+
'link_settings': {
|
|
94
|
+
'target_conditions': [
|
|
95
|
+
['_type == "executable"', {
|
|
96
|
+
'ldflags': [
|
|
97
|
+
'-Wl,--export=emnapi_thread_crashed',
|
|
98
|
+
],
|
|
99
|
+
'xcode_settings': {
|
|
100
|
+
'OTHER_LDFLAGS': [
|
|
101
|
+
'-Wl,--export=emnapi_thread_crashed',
|
|
102
|
+
],
|
|
103
|
+
},
|
|
104
|
+
}],
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
}],
|
|
91
108
|
]
|
|
92
109
|
},
|
|
93
110
|
{
|
|
@@ -98,6 +115,7 @@
|
|
|
98
115
|
'src/node_api.c',
|
|
99
116
|
'src/async_cleanup_hook.c',
|
|
100
117
|
'src/async_context.c',
|
|
118
|
+
'src/wasi_wait.c',
|
|
101
119
|
|
|
102
120
|
'src/uv/uv-common.c',
|
|
103
121
|
'src/uv/threadpool.c',
|
package/include/node/emnapi.h
CHANGED
|
@@ -358,7 +358,7 @@ napi_create_reference(napi_env env,
|
|
|
358
358
|
|
|
359
359
|
// Deletes a reference. The referenced value is released, and may
|
|
360
360
|
// be GC'd unless there are other references to it.
|
|
361
|
-
NAPI_EXTERN napi_status NAPI_CDECL napi_delete_reference(
|
|
361
|
+
NAPI_EXTERN napi_status NAPI_CDECL napi_delete_reference(node_api_basic_env env,
|
|
362
362
|
napi_ref ref);
|
|
363
363
|
|
|
364
364
|
// Increments the reference count, optionally returning the resulting count.
|
|
@@ -480,6 +480,14 @@ napi_get_dataview_info(napi_env env,
|
|
|
480
480
|
napi_value* arraybuffer,
|
|
481
481
|
size_t* byte_offset);
|
|
482
482
|
|
|
483
|
+
#ifdef NAPI_EXPERIMENTAL
|
|
484
|
+
#define NODE_API_EXPERIMENTAL_HAS_SHAREDARRAYBUFFER
|
|
485
|
+
NAPI_EXTERN napi_status NAPI_CDECL
|
|
486
|
+
node_api_is_sharedarraybuffer(napi_env env, napi_value value, bool* result);
|
|
487
|
+
NAPI_EXTERN napi_status NAPI_CDECL node_api_create_sharedarraybuffer(
|
|
488
|
+
napi_env env, size_t byte_length, void** data, napi_value* result);
|
|
489
|
+
#endif // NAPI_EXPERIMENTAL
|
|
490
|
+
|
|
483
491
|
// version management
|
|
484
492
|
NAPI_EXTERN napi_status NAPI_CDECL napi_get_version(node_api_basic_env env,
|
|
485
493
|
uint32_t* result);
|
|
Binary file
|
package/lib/wasm32/libdlmalloc.a
CHANGED
|
Binary file
|
|
Binary file
|
package/lib/wasm32/libemmalloc.a
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/lib/wasm32/libemnapi.a
CHANGED
|
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
|
|
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
package/src/emnapi_internal.h
CHANGED
|
@@ -98,11 +98,18 @@ EMNAPI_INTERNAL_EXTERN void _emnapi_runtime_keepalive_pop();
|
|
|
98
98
|
#define EMNAPI_KEEPALIVE_POP _emnapi_runtime_keepalive_pop
|
|
99
99
|
#endif
|
|
100
100
|
|
|
101
|
+
EMNAPI_INTERNAL_EXTERN napi_handle_scope _emnapi_open_handle_scope();
|
|
102
|
+
EMNAPI_INTERNAL_EXTERN void _emnapi_close_handle_scope(napi_handle_scope scope);
|
|
101
103
|
EMNAPI_INTERNAL_EXTERN void _emnapi_env_ref(napi_env env);
|
|
102
104
|
EMNAPI_INTERNAL_EXTERN void _emnapi_env_unref(napi_env env);
|
|
103
105
|
EMNAPI_INTERNAL_EXTERN void _emnapi_ctx_increase_waiting_request_counter();
|
|
104
106
|
EMNAPI_INTERNAL_EXTERN void _emnapi_ctx_decrease_waiting_request_counter();
|
|
105
107
|
|
|
108
|
+
EMNAPI_INTERNAL_EXTERN int _emnapi_is_main_browser_thread();
|
|
109
|
+
EMNAPI_INTERNAL_EXTERN int _emnapi_is_main_runtime_thread();
|
|
110
|
+
EMNAPI_INTERNAL_EXTERN double _emnapi_get_now();
|
|
111
|
+
EMNAPI_INTERNAL_EXTERN void _emnapi_unwind();
|
|
112
|
+
|
|
106
113
|
#if defined(__EMSCRIPTEN_PTHREADS__) || defined(_REENTRANT)
|
|
107
114
|
#define EMNAPI_HAVE_THREADS 1
|
|
108
115
|
#else
|
|
@@ -136,6 +136,8 @@ static void _emnapi_tsfn_destroy(napi_threadsafe_function func) {
|
|
|
136
136
|
EMNAPI_ASSERT_CALL(napi_delete_reference(func->env, func->ref));
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
EMNAPI_ASYNC_RESOURCE_DTOR(func->env, (emnapi_async_resource*) func);
|
|
140
|
+
|
|
139
141
|
EMNAPI_ASSERT_CALL(napi_remove_env_cleanup_hook(func->env, _emnapi_tsfn_cleanup, func));
|
|
140
142
|
_emnapi_env_unref(func->env);
|
|
141
143
|
if (func->async_ref) {
|
|
@@ -144,7 +146,6 @@ static void _emnapi_tsfn_destroy(napi_threadsafe_function func) {
|
|
|
144
146
|
func->async_ref = false;
|
|
145
147
|
}
|
|
146
148
|
|
|
147
|
-
EMNAPI_ASYNC_RESOURCE_DTOR(func->env, (emnapi_async_resource*) func);
|
|
148
149
|
free(func);
|
|
149
150
|
}
|
|
150
151
|
|
|
@@ -209,8 +210,7 @@ static napi_value _emnapi_tsfn_finalize_in_callback_scope(napi_env env, napi_cal
|
|
|
209
210
|
}
|
|
210
211
|
|
|
211
212
|
static void _emnapi_tsfn_finalize(napi_threadsafe_function func) {
|
|
212
|
-
napi_handle_scope scope;
|
|
213
|
-
EMNAPI_ASSERT_CALL(napi_open_handle_scope(func->env, &scope));
|
|
213
|
+
napi_handle_scope scope = _emnapi_open_handle_scope();
|
|
214
214
|
if (func->finalize_cb) {
|
|
215
215
|
if (emnapi_is_node_binding_available()) {
|
|
216
216
|
napi_value resource, cb;
|
|
@@ -229,7 +229,7 @@ static void _emnapi_tsfn_finalize(napi_threadsafe_function func) {
|
|
|
229
229
|
}
|
|
230
230
|
}
|
|
231
231
|
_emnapi_tsfn_empty_queue_and_delete(func);
|
|
232
|
-
|
|
232
|
+
_emnapi_close_handle_scope(scope);
|
|
233
233
|
}
|
|
234
234
|
|
|
235
235
|
static void _emnapi_tsfn_do_finalize(uv_handle_t* data) {
|
package/src/wasi_wait.c
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
#if defined(__wasi__)
|
|
2
|
+
|
|
3
|
+
#include <time.h>
|
|
4
|
+
#include <errno.h>
|
|
5
|
+
#include <pthread.h>
|
|
6
|
+
#include <stdio.h>
|
|
7
|
+
#include "emnapi_internal.h"
|
|
8
|
+
|
|
9
|
+
struct __pthread {
|
|
10
|
+
unsigned char _[32];
|
|
11
|
+
volatile int cancel;
|
|
12
|
+
volatile unsigned char canceldisable, cancelasync;
|
|
13
|
+
unsigned char tsd_used:1;
|
|
14
|
+
unsigned char dlerror_flag:1;
|
|
15
|
+
unsigned char __[68];
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
#define INFINITY __builtin_inff()
|
|
19
|
+
|
|
20
|
+
int __wasilibc_futex_wait_atomic_wait(volatile void *addr, int op, int val, int64_t max_wait_ns);
|
|
21
|
+
|
|
22
|
+
static _Atomic pthread_t crashed_thread_id = NULL;
|
|
23
|
+
|
|
24
|
+
__attribute__((visibility("default")))
|
|
25
|
+
void emnapi_thread_crashed() {
|
|
26
|
+
crashed_thread_id = pthread_self();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
void _emnapi_yield() {
|
|
30
|
+
if (crashed_thread_id) {
|
|
31
|
+
_emnapi_runtime_keepalive_push();
|
|
32
|
+
_emnapi_unwind();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static int _emnapi_wait_main_browser_thread(int is_runtime_thread, volatile void *addr, int op, int val, double max_wait_ms) {
|
|
37
|
+
double now = _emnapi_get_now();
|
|
38
|
+
double end = now + max_wait_ms;
|
|
39
|
+
|
|
40
|
+
while (1) {
|
|
41
|
+
now = _emnapi_get_now();
|
|
42
|
+
if (now >= end) {
|
|
43
|
+
return -ETIMEDOUT;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (is_runtime_thread) {
|
|
47
|
+
_emnapi_yield();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (__c11_atomic_load((_Atomic int *)addr, __ATOMIC_SEQ_CST) != val) {
|
|
51
|
+
break;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
return 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
int _emnapi_wait(int is_runtime_thread, volatile void *addr, int op, int val, double max_wait_ms) {
|
|
59
|
+
if (is_runtime_thread) {
|
|
60
|
+
_emnapi_yield();
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// https://github.com/WebAssembly/wasi-libc/blob/3f7eb4c7d6ede4dde3c4bffa6ed14e8d656fe93f/libc-top-half/musl/src/thread/wasm32/__wasilibc_busywait.c#L42
|
|
64
|
+
if (!_emnapi_is_main_browser_thread()) {
|
|
65
|
+
int64_t max_wait_ns = -1;
|
|
66
|
+
if (max_wait_ms != INFINITY) {
|
|
67
|
+
max_wait_ns = (int64_t)(max_wait_ms*1000*1000);
|
|
68
|
+
}
|
|
69
|
+
return __wasilibc_futex_wait_atomic_wait(addr, op, val, max_wait_ns);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
return _emnapi_wait_main_browser_thread(is_runtime_thread, addr, op, val, max_wait_ms);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
int __wasilibc_futex_wait_maybe_busy(volatile void *addr, int op, int val, int64_t max_wait_ns) {
|
|
76
|
+
// https://github.com/emscripten-core/emscripten/blob/89ce854a99238d04116a3d9b5afe241eec90c6c3/system/lib/libc/musl/src/thread/__timedwait.c#L60
|
|
77
|
+
int r = 0;
|
|
78
|
+
double msecsToSleep = max_wait_ns >= 0 ? (max_wait_ns / 1000000.0) : INFINITY;
|
|
79
|
+
int is_runtime_thread = _emnapi_is_main_runtime_thread();
|
|
80
|
+
double max_ms_slice_to_sleep = is_runtime_thread ? 1 : 100;
|
|
81
|
+
|
|
82
|
+
if (is_runtime_thread ||
|
|
83
|
+
pthread_self()->canceldisable != PTHREAD_CANCEL_DISABLE ||
|
|
84
|
+
pthread_self()->cancelasync) {
|
|
85
|
+
double sleepUntilTime = _emnapi_get_now() + msecsToSleep;
|
|
86
|
+
do {
|
|
87
|
+
if (pthread_self()->cancel) {
|
|
88
|
+
pthread_testcancel();
|
|
89
|
+
return ECANCELED;
|
|
90
|
+
}
|
|
91
|
+
msecsToSleep = sleepUntilTime - _emnapi_get_now();
|
|
92
|
+
if (msecsToSleep <= 0) {
|
|
93
|
+
r = ETIMEDOUT;
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
if (msecsToSleep > max_ms_slice_to_sleep)
|
|
97
|
+
msecsToSleep = max_ms_slice_to_sleep;
|
|
98
|
+
r = -_emnapi_wait(is_runtime_thread, (void*)addr, op, val, msecsToSleep);
|
|
99
|
+
} while (r == ETIMEDOUT);
|
|
100
|
+
} else {
|
|
101
|
+
r = -_emnapi_wait(is_runtime_thread, (void*)addr, op, val, msecsToSleep);
|
|
102
|
+
}
|
|
103
|
+
return r;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
#endif
|