emnapi 0.31.0 → 0.33.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 +23 -2
- package/README.md +213 -94
- package/dist/library_napi.js +258 -33
- package/include/emnapi.h +1 -1
- package/include/js_native_api.h +1 -1
- package/index.js +6 -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-emscripten.txt +2 -2
- package/lib/wasm32-wasi/libemnapi-basic.a +0 -0
- package/lib/wasm32-wasi/libemnapi.a +0 -0
- package/package.json +1 -1
- package/src/async_cleanup_hook.c +126 -0
- package/src/async_context.c +53 -0
- package/src/async_work.c +236 -0
- package/src/emnapi.c +1 -1324
- package/src/emnapi_internal.h +171 -0
- package/src/js_native_api.c +106 -0
- package/src/node_api.c +73 -0
- package/src/threadsafe_function.c +617 -0
- package/src/uv/threadpool.c +36 -5
- package/src/uv/unix/async.c +1 -1
- package/src/uv/unix/thread.c +10 -1
- /package/include/{common.h → emnapi_common.h} +0 -0
package/CMakeLists.txt
CHANGED
|
@@ -26,7 +26,19 @@ set(UV_SRC
|
|
|
26
26
|
"${CMAKE_CURRENT_SOURCE_DIR}/src/uv/unix/core.c"
|
|
27
27
|
)
|
|
28
28
|
|
|
29
|
-
set(
|
|
29
|
+
set(ENAPI_BASIC_SRC
|
|
30
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/js_native_api.c"
|
|
31
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/node_api.c"
|
|
32
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/emnapi.c"
|
|
33
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_cleanup_hook.c"
|
|
34
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_context.c"
|
|
35
|
+
)
|
|
36
|
+
set(EMNAPI_THREADS_SRC
|
|
37
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/async_work.c"
|
|
38
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/threadsafe_function.c"
|
|
39
|
+
)
|
|
40
|
+
set(EMNAPI_SRC ${ENAPI_BASIC_SRC} ${EMNAPI_THREADS_SRC})
|
|
41
|
+
|
|
30
42
|
set(EMNAPI_INCLUDE "${CMAKE_CURRENT_SOURCE_DIR}/include")
|
|
31
43
|
|
|
32
44
|
set(EMNAPI_JS_LIB "${CMAKE_CURRENT_SOURCE_DIR}/dist/library_napi.js")
|
|
@@ -37,6 +49,7 @@ else()
|
|
|
37
49
|
set(EMNAPI_MT_CFLAGS "-pthread")
|
|
38
50
|
endif()
|
|
39
51
|
|
|
52
|
+
set(EMNAPI_BASIC_TARGET_NAME "emnapi-basic")
|
|
40
53
|
set(EMNAPI_TARGET_NAME "emnapi")
|
|
41
54
|
set(EMNAPI_MT_TARGET_NAME "emnapi-mt")
|
|
42
55
|
set(DLMALLOC_TARGET_NAME "dlmalloc")
|
|
@@ -82,6 +95,12 @@ if(IS_EMSCRIPTEN)
|
|
|
82
95
|
target_link_options(${EMNAPI_TARGET_NAME} INTERFACE "--js-library=${EMNAPI_JS_LIB}")
|
|
83
96
|
endif()
|
|
84
97
|
|
|
98
|
+
add_library(${EMNAPI_BASIC_TARGET_NAME} STATIC ${ENAPI_BASIC_SRC})
|
|
99
|
+
target_include_directories(${EMNAPI_BASIC_TARGET_NAME} PUBLIC ${EMNAPI_INCLUDE})
|
|
100
|
+
if(IS_EMSCRIPTEN)
|
|
101
|
+
target_link_options(${EMNAPI_BASIC_TARGET_NAME} INTERFACE "--js-library=${EMNAPI_JS_LIB}")
|
|
102
|
+
endif()
|
|
103
|
+
|
|
85
104
|
if(IS_EMSCRIPTEN OR (CMAKE_C_COMPILER_TARGET STREQUAL "wasm32-wasi-threads"))
|
|
86
105
|
set(EMNAPI_BUILD_MT ON)
|
|
87
106
|
else()
|
|
@@ -118,6 +137,7 @@ endif()
|
|
|
118
137
|
# endif()
|
|
119
138
|
if(LIB_ARCH)
|
|
120
139
|
install(TARGETS ${EMNAPI_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
140
|
+
install(TARGETS ${EMNAPI_BASIC_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
121
141
|
if(EMNAPI_BUILD_MT)
|
|
122
142
|
install(TARGETS ${EMNAPI_MT_TARGET_NAME} DESTINATION "lib/${LIB_ARCH}")
|
|
123
143
|
endif()
|
|
@@ -128,7 +148,7 @@ if(LIB_ARCH)
|
|
|
128
148
|
endif()
|
|
129
149
|
|
|
130
150
|
install(FILES
|
|
131
|
-
${CMAKE_CURRENT_SOURCE_DIR}/include/
|
|
151
|
+
${CMAKE_CURRENT_SOURCE_DIR}/include/emnapi_common.h
|
|
132
152
|
${CMAKE_CURRENT_SOURCE_DIR}/include/emnapi.h
|
|
133
153
|
${CMAKE_CURRENT_SOURCE_DIR}/include/js_native_api_types.h
|
|
134
154
|
${CMAKE_CURRENT_SOURCE_DIR}/include/js_native_api.h
|
|
@@ -150,6 +170,7 @@ install(FILES
|
|
|
150
170
|
if(EMNAPI_INSTALL_SRC)
|
|
151
171
|
install(FILES
|
|
152
172
|
${EMNAPI_SRC}
|
|
173
|
+
"${CMAKE_CURRENT_SOURCE_DIR}/src/emnapi_internal.h"
|
|
153
174
|
DESTINATION "src/${PROJECT_NAME}")
|
|
154
175
|
install(DIRECTORY
|
|
155
176
|
${CMAKE_CURRENT_SOURCE_DIR}/src/uv
|
package/README.md
CHANGED
|
@@ -6,9 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
[](https://github.com/toyobayashi/emnapi/actions/workflows/main.yml)
|
|
8
8
|
|
|
9
|
-
[Node-API](https://nodejs.org/docs/latest/api/n-api.html) implementation for [Emscripten](https://emscripten.org/index.html), [wasi-sdk](https://github.com/WebAssembly/wasi-sdk) and clang
|
|
10
|
-
|
|
11
|
-
Emscripten is the first class support target, currently thread related APIs are unavailable on `wasm32-unknown-unknown` and `wasm32-wasi` target.
|
|
9
|
+
[Node-API](https://nodejs.org/docs/latest/api/n-api.html) implementation for [Emscripten](https://emscripten.org/index.html), [wasi-sdk](https://github.com/WebAssembly/wasi-sdk) and clang with wasm support. [napi-rs support is comming soon](https://github.com/napi-rs/napi-rs/tree/emnapi).
|
|
12
10
|
|
|
13
11
|
This project aims to
|
|
14
12
|
|
|
@@ -27,6 +25,16 @@ See documentation for more details:
|
|
|
27
25
|
|
|
28
26
|
[How to build Node-API official examples](https://github.com/toyobayashi/node-addon-examples)
|
|
29
27
|
|
|
28
|
+
Emscripten is the first class support target. If your target is running addon on browser,
|
|
29
|
+
we strongly recommend you to use Emscripten instead of wasi-sdk. Async works and threadsafe
|
|
30
|
+
functions related APIs are only available on Emscripten or `wasm32-wasi-threads` target since
|
|
31
|
+
they are relying on pthread. Though today we have [WASI browser polyfill](https://github.com/toyobayashi/wasm-util),
|
|
32
|
+
`wasm32-wasi-threads` is in very early stage and WASI itself is not designed for browser.
|
|
33
|
+
There are some limitations on browser about wasi-libc's pthread implementation, for example
|
|
34
|
+
`pthread_mutex_lock` may call `__builtin_wasm_memory_atomic_wait32`(`memory.atomic.wait32`)
|
|
35
|
+
which is disallowed in browser JS main thread. While Emscripten's pthread implementation
|
|
36
|
+
has considered usage in browser.
|
|
37
|
+
|
|
30
38
|
## Prerequests
|
|
31
39
|
|
|
32
40
|
You will need to install:
|
|
@@ -332,29 +340,19 @@ For non-emscripten, you need to use `@emnapi/core`. The initialization is simila
|
|
|
332
340
|
<script src="node_modules/@emnapi/runtime/dist/emnapi.min.js"></script>
|
|
333
341
|
<script src="node_modules/@emnapi/core/dist/emnapi-core.min.js"></script>
|
|
334
342
|
<script>
|
|
335
|
-
|
|
336
|
-
context: emnapi.getDefaultContext()
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
napi: napiModule.imports.napi,
|
|
349
|
-
emnapi: napiModule.imports.emnapi
|
|
350
|
-
})
|
|
351
|
-
}).then(({ instance }) => {
|
|
352
|
-
const binding = napiModule.init(
|
|
353
|
-
instance, // WebAssembly.Instance
|
|
354
|
-
instance.exports.memory, // WebAssembly.Memory
|
|
355
|
-
instance.exports.__indirect_function_table // WebAssembly.Table
|
|
356
|
-
)
|
|
357
|
-
// binding === napiModule.exports
|
|
343
|
+
emnapiCore.instantiateNapiModule(fetch('./hello.wasm'), {
|
|
344
|
+
context: emnapi.getDefaultContext(),
|
|
345
|
+
overwriteImports (importObject) {
|
|
346
|
+
// importObject.env = {
|
|
347
|
+
// ...importObject.env,
|
|
348
|
+
// ...importObject.napi,
|
|
349
|
+
// ...importObject.emnapi,
|
|
350
|
+
// // ...
|
|
351
|
+
// }
|
|
352
|
+
}
|
|
353
|
+
}).then(({ instance, module, napiModule }) => {
|
|
354
|
+
const binding = napiModule.exports
|
|
355
|
+
// ...
|
|
358
356
|
})
|
|
359
357
|
</script>
|
|
360
358
|
```
|
|
@@ -362,35 +360,25 @@ fetch('./hello.wasm').then(res => res.arrayBuffer()).then(wasmBuffer => {
|
|
|
362
360
|
Using WASI on Node.js
|
|
363
361
|
|
|
364
362
|
```js
|
|
365
|
-
const {
|
|
363
|
+
const { instantiateNapiModule } = require('@emnapi/core')
|
|
366
364
|
const { getDefaultContext } = require('@emnapi/runtime')
|
|
367
365
|
const { WASI } = require('wasi')
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
})
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
...
|
|
379
|
-
//
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
//
|
|
384
|
-
napi: napiModule.imports.napi,
|
|
385
|
-
emnapi: napiModule.imports.emnapi
|
|
386
|
-
}).then(({ instance }) => {
|
|
387
|
-
wasi.initialize(instance)
|
|
388
|
-
const binding = napiModule.init(
|
|
389
|
-
instance,
|
|
390
|
-
instance.exports.memory,
|
|
391
|
-
instance.exports.__indirect_function_table
|
|
392
|
-
)
|
|
393
|
-
// binding === napiModule.exports
|
|
366
|
+
const fs = require('fs')
|
|
367
|
+
|
|
368
|
+
instantiateNapiModule(fs.promises.readFile('./hello.wasm'), {
|
|
369
|
+
wasi: new WASI({ /* ... */ }),
|
|
370
|
+
context: getDefaultContext(),
|
|
371
|
+
overwriteImports (importObject) {
|
|
372
|
+
// importObject.env = {
|
|
373
|
+
// ...importObject.env,
|
|
374
|
+
// ...importObject.napi,
|
|
375
|
+
// ...importObject.emnapi,
|
|
376
|
+
// // ...
|
|
377
|
+
// }
|
|
378
|
+
}
|
|
379
|
+
}).then(({ instance, module, napiModule }) => {
|
|
380
|
+
const binding = napiModule.exports
|
|
381
|
+
// ...
|
|
394
382
|
})
|
|
395
383
|
```
|
|
396
384
|
|
|
@@ -398,37 +386,26 @@ Using WASI on browser, you can use WASI polyfill in [wasm-util](https://github.c
|
|
|
398
386
|
and [memfs-browser](https://github.com/toyobayashi/memfs-browser)
|
|
399
387
|
|
|
400
388
|
```js
|
|
401
|
-
import {
|
|
389
|
+
import { instantiateNapiModule } from '@emnapi/core'
|
|
402
390
|
import { getDefaultContext } from '@emnapi/runtime'
|
|
403
391
|
import { WASI } from '@tybys/wasm-util'
|
|
404
|
-
import {
|
|
405
|
-
|
|
406
|
-
const
|
|
407
|
-
|
|
408
|
-
})
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
// clang
|
|
422
|
-
napi: napiModule.imports.napi,
|
|
423
|
-
emnapi: napiModule.imports.emnapi
|
|
424
|
-
}).then(({ instance }) => {
|
|
425
|
-
wasi.initialize(instance)
|
|
426
|
-
const binding = napiModule.init(
|
|
427
|
-
instance,
|
|
428
|
-
instance.exports.memory,
|
|
429
|
-
instance.exports.__indirect_function_table
|
|
430
|
-
)
|
|
431
|
-
// binding === napiModule.exports
|
|
392
|
+
import { Volume, createFsFromVolume } from 'memfs-browser'
|
|
393
|
+
|
|
394
|
+
const fs = createFsFromVolume(Volume.fromJSON({ /* ... */ }))
|
|
395
|
+
return instantiateNapiModule(fetch('./hello.wasm'), {
|
|
396
|
+
wasi: new WASI({ fs, /* ... */ })
|
|
397
|
+
context: getDefaultContext(),
|
|
398
|
+
overwriteImports (importObject) {
|
|
399
|
+
// importObject.env = {
|
|
400
|
+
// ...importObject.env,
|
|
401
|
+
// ...importObject.napi,
|
|
402
|
+
// ...importObject.emnapi,
|
|
403
|
+
// // ...
|
|
404
|
+
// }
|
|
405
|
+
}
|
|
406
|
+
}).then(({ instance, module, napiModule }) => {
|
|
407
|
+
const binding = napiModule.exports
|
|
408
|
+
// ...
|
|
432
409
|
})
|
|
433
410
|
```
|
|
434
411
|
|
|
@@ -492,6 +469,7 @@ clang++ -O3 \
|
|
|
492
469
|
-L./node_modules/emnapi/lib/wasm32-wasi \
|
|
493
470
|
--target=wasm32-wasi \
|
|
494
471
|
--sysroot=$WASI_SDK_PATH/share/wasi-sysroot \
|
|
472
|
+
-fno-exceptions \
|
|
495
473
|
-mexec-model=reactor \
|
|
496
474
|
-Wl,--initial-memory=16777216 \
|
|
497
475
|
-Wl,--export-dynamic \
|
|
@@ -519,6 +497,7 @@ clang++ -O3 \
|
|
|
519
497
|
-I./node_modules/emnapi/include \
|
|
520
498
|
-L./node_modules/emnapi/lib/wasm32 \
|
|
521
499
|
--target=wasm32 \
|
|
500
|
+
-fno-exceptions \
|
|
522
501
|
-nostdlib \
|
|
523
502
|
-Wl,--no-entry \
|
|
524
503
|
-Wl,--initial-memory=16777216 \
|
|
@@ -749,35 +728,168 @@ pub unsafe extern "C" fn napi_register_wasm_v1(env: napi_env, exports: napi_valu
|
|
|
749
728
|
|
|
750
729
|
</details>
|
|
751
730
|
|
|
752
|
-
### Multithread
|
|
731
|
+
### Multithread
|
|
753
732
|
|
|
754
733
|
If you want to use async work or thread safe functions,
|
|
755
734
|
there are additional C source file need to be compiled and linking.
|
|
756
735
|
Recommend use CMake directly.
|
|
757
736
|
|
|
737
|
+
**This is EXPERIMENTAL on non-emscripten.**
|
|
738
|
+
|
|
758
739
|
```cmake
|
|
759
740
|
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/node_modules/emnapi")
|
|
760
741
|
|
|
761
742
|
add_executable(hello hello.c)
|
|
762
743
|
|
|
763
744
|
target_link_libraries(hello emnapi-mt)
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
"-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
745
|
+
|
|
746
|
+
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
|
747
|
+
target_compile_options(hello PRIVATE "-sUSE_PTHREADS=1")
|
|
748
|
+
target_link_options(hello PRIVATE
|
|
749
|
+
"-sALLOW_MEMORY_GROWTH=1"
|
|
750
|
+
"-sEXPORTED_FUNCTIONS=['_malloc','_free']"
|
|
751
|
+
"-sUSE_PTHREADS=1"
|
|
752
|
+
"-sPTHREAD_POOL_SIZE=4"
|
|
753
|
+
# try to specify stack size if you experience pthread errors
|
|
754
|
+
"-sSTACK_SIZE=2MB"
|
|
755
|
+
"-sDEFAULT_PTHREAD_STACK_SIZE=2MB"
|
|
756
|
+
)
|
|
757
|
+
elseif(CMAKE_C_COMPILER_TARGET STREQUAL "wasm32-wasi-threads")
|
|
758
|
+
# Experimental
|
|
759
|
+
target_compile_options(hello PRIVATE "-fno-exceptions" "-pthread")
|
|
760
|
+
target_link_options(hello PRIVATE
|
|
761
|
+
"-pthread"
|
|
762
|
+
"-mexec-model=reactor"
|
|
763
|
+
"-Wl,--import-memory"
|
|
764
|
+
"-Wl,--max-memory=2147483648"
|
|
765
|
+
"-Wl,--export-dynamic"
|
|
766
|
+
"-Wl,--export=malloc"
|
|
767
|
+
"-Wl,--export=free"
|
|
768
|
+
"-Wl,--import-undefined"
|
|
769
|
+
"-Wl,--export-table"
|
|
770
|
+
)
|
|
771
|
+
endif()
|
|
774
772
|
```
|
|
775
773
|
|
|
776
774
|
```bash
|
|
775
|
+
# emscripten
|
|
777
776
|
emcmake cmake -DCMAKE_BUILD_TYPE=Release -DEMNAPI_WORKER_POOL_SIZE=4 -G Ninja -H. -Bbuild
|
|
777
|
+
|
|
778
|
+
# wasi-sdk with thread support (Experimental)
|
|
779
|
+
cmake -DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk-pthread.cmake \
|
|
780
|
+
-DWASI_SDK_PREFIX=$WASI_SDK_PATH \
|
|
781
|
+
-DCMAKE_BUILD_TYPE=Release \
|
|
782
|
+
-G Ninja -H. -Bbuild
|
|
783
|
+
|
|
778
784
|
cmake --build build
|
|
779
785
|
```
|
|
780
786
|
|
|
787
|
+
And additional work is required during instantiating wasm compiled with non-emscripten.
|
|
788
|
+
|
|
789
|
+
```js
|
|
790
|
+
// emnapi main thread (could be in a Worker)
|
|
791
|
+
instantiateNapiModule(input, {
|
|
792
|
+
context: getDefaultContext(),
|
|
793
|
+
wasi: new WASI(/* ... */),
|
|
794
|
+
// reuseWorker: true,
|
|
795
|
+
onCreateWorker () {
|
|
796
|
+
return new Worker('./worker.js')
|
|
797
|
+
// Node.js
|
|
798
|
+
// return new Worker(join(__dirname, './worker.js'), {
|
|
799
|
+
// env: process.env,
|
|
800
|
+
// execArgv: ['--experimental-wasi-unstable-preview1']
|
|
801
|
+
// })
|
|
802
|
+
},
|
|
803
|
+
overwriteImports (importObject) {
|
|
804
|
+
importObject.env.memory = new WebAssembly.Memory({
|
|
805
|
+
initial: 16777216 / 65536,
|
|
806
|
+
maximum: 2147483648 / 65536,
|
|
807
|
+
shared: true
|
|
808
|
+
})
|
|
809
|
+
}
|
|
810
|
+
})
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
```js
|
|
814
|
+
// worker.js
|
|
815
|
+
(function () {
|
|
816
|
+
let fs, WASI, emnapiCore
|
|
817
|
+
|
|
818
|
+
const ENVIRONMENT_IS_NODE =
|
|
819
|
+
typeof process === 'object' && process !== null &&
|
|
820
|
+
typeof process.versions === 'object' && process.versions !== null &&
|
|
821
|
+
typeof process.versions.node === 'string'
|
|
822
|
+
|
|
823
|
+
if (ENVIRONMENT_IS_NODE) {
|
|
824
|
+
const nodeWorkerThreads = require('worker_threads')
|
|
825
|
+
|
|
826
|
+
const parentPort = nodeWorkerThreads.parentPort
|
|
827
|
+
|
|
828
|
+
parentPort.on('message', (data) => {
|
|
829
|
+
globalThis.onmessage({ data })
|
|
830
|
+
})
|
|
831
|
+
|
|
832
|
+
fs = require('fs')
|
|
833
|
+
|
|
834
|
+
Object.assign(globalThis, {
|
|
835
|
+
self: globalThis,
|
|
836
|
+
require,
|
|
837
|
+
Worker: nodeWorkerThreads.Worker,
|
|
838
|
+
importScripts: function (f) {
|
|
839
|
+
(0, eval)(fs.readFileSync(f, 'utf8') + '//# sourceURL=' + f)
|
|
840
|
+
},
|
|
841
|
+
postMessage: function (msg) {
|
|
842
|
+
parentPort.postMessage(msg)
|
|
843
|
+
}
|
|
844
|
+
})
|
|
845
|
+
|
|
846
|
+
WASI = require('./wasi').WASI
|
|
847
|
+
emnapiCore = require('@emnapi/core')
|
|
848
|
+
} else {
|
|
849
|
+
importScripts('./node_modules/memfs-browser/dist/memfs.js')
|
|
850
|
+
importScripts('./node_modules/@tybys/wasm-util/dist/wasm-util.min.js')
|
|
851
|
+
importScripts('./node_modules/@emnapi/core/dist/emnapi-core.js')
|
|
852
|
+
emnapiCore = globalThis.emnapiCore
|
|
853
|
+
|
|
854
|
+
const { Volume, createFsFromVolume } = memfs
|
|
855
|
+
fs = createFsFromVolume(Volume.fromJSON({
|
|
856
|
+
'/': null
|
|
857
|
+
}))
|
|
858
|
+
|
|
859
|
+
WASI = globalThis.wasmUtil.WASI
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
const { instantiateNapiModuleSync, MessageHandler } = emnapiCore
|
|
863
|
+
|
|
864
|
+
const handler = new MessageHandler({
|
|
865
|
+
onLoad ({ wasmModule, wasmMemory }) {
|
|
866
|
+
const wasi = new WASI({
|
|
867
|
+
fs,
|
|
868
|
+
print: ENVIRONMENT_IS_NODE
|
|
869
|
+
? (...args) => {
|
|
870
|
+
const str = require('util').format(...args)
|
|
871
|
+
fs.writeSync(1, str + '\n')
|
|
872
|
+
}
|
|
873
|
+
: function () { console.log.apply(console, arguments) }
|
|
874
|
+
})
|
|
875
|
+
|
|
876
|
+
return instantiateNapiModuleSync(wasmModule, {
|
|
877
|
+
childThread: true,
|
|
878
|
+
wasi,
|
|
879
|
+
overwriteImports (importObject) {
|
|
880
|
+
importObject.env.memory = wasmMemory
|
|
881
|
+
}
|
|
882
|
+
})
|
|
883
|
+
}
|
|
884
|
+
})
|
|
885
|
+
|
|
886
|
+
globalThis.onmessage = function (e) {
|
|
887
|
+
handler.handle(e)
|
|
888
|
+
// handle other messages
|
|
889
|
+
}
|
|
890
|
+
})()
|
|
891
|
+
```
|
|
892
|
+
|
|
781
893
|
## Preprocess Macro Options
|
|
782
894
|
|
|
783
895
|
### `-DEMNAPI_WORKER_POOL_SIZE=4`
|
|
@@ -791,6 +903,13 @@ Module.preRun.push(function () {
|
|
|
791
903
|
ENV.UV_THREADPOOL_SIZE = '2';
|
|
792
904
|
}
|
|
793
905
|
});
|
|
906
|
+
|
|
907
|
+
// wasi
|
|
908
|
+
new WASI({
|
|
909
|
+
env: {
|
|
910
|
+
UV_THREADPOOL_SIZE: '2'
|
|
911
|
+
}
|
|
912
|
+
})
|
|
794
913
|
```
|
|
795
914
|
|
|
796
915
|
It represent max of `EMNAPI_WORKER_POOL_SIZE` async work (`napi_queue_async_work`) can be executed in parallel. Default is not defined, read `UV_THREADPOOL_SIZE` at runtime.
|
|
@@ -815,7 +934,7 @@ Tell emnapi how to delay async work in `uv_async_send` / `uv__async_close`.
|
|
|
815
934
|
|
|
816
935
|
### `-DEMNAPI_USE_PROXYING=1`
|
|
817
936
|
|
|
818
|
-
This option only has effect if you use `-sUSE_PTHREADS`. Default is `1` if emscripten version `>= 3.1.9`, else `0`.
|
|
937
|
+
This option only has effect if you use emscripten `-sUSE_PTHREADS`. Default is `1` if emscripten version `>= 3.1.9`, else `0`.
|
|
819
938
|
|
|
820
939
|
- `0`
|
|
821
940
|
|