emnapi 0.35.0 → 0.36.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/README.md +65 -42
- package/cmake/wasm32.cmake +2 -0
- package/dist/library_napi.js +38 -11
- 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/package.json +1 -1
- package/src/uv/unix/async.c +17 -1
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ emcc -O3 \
|
|
|
164
164
|
-I./node_modules/emnapi/include \
|
|
165
165
|
-L./node_modules/emnapi/lib/wasm32-emscripten \
|
|
166
166
|
--js-library=./node_modules/emnapi/dist/library_napi.js \
|
|
167
|
-
-sEXPORTED_FUNCTIONS="['_malloc','_free']" \
|
|
167
|
+
-sEXPORTED_FUNCTIONS="['_napi_register_wasm_v1','_malloc','_free']" \
|
|
168
168
|
-o hello.js \
|
|
169
169
|
hello.c \
|
|
170
170
|
-lemnapi
|
|
@@ -385,7 +385,7 @@ import { WASI } from '@tybys/wasm-util'
|
|
|
385
385
|
import { Volume, createFsFromVolume } from 'memfs-browser'
|
|
386
386
|
|
|
387
387
|
const fs = createFsFromVolume(Volume.fromJSON({ /* ... */ }))
|
|
388
|
-
|
|
388
|
+
instantiateNapiModule(fetch('./hello.wasm'), {
|
|
389
389
|
wasi: new WASI({ fs, /* ... */ })
|
|
390
390
|
context: getDefaultContext(),
|
|
391
391
|
overwriteImports (importObject) {
|
|
@@ -443,7 +443,7 @@ em++ -O3 \
|
|
|
443
443
|
-I./node_modules/emnapi/include \
|
|
444
444
|
-L./node_modules/emnapi/lib/wasm32-emscripten \
|
|
445
445
|
--js-library=./node_modules/emnapi/dist/library_napi.js \
|
|
446
|
-
-sEXPORTED_FUNCTIONS="['_malloc','_free']" \
|
|
446
|
+
-sEXPORTED_FUNCTIONS="['_napi_register_wasm_v1','_malloc','_free']" \
|
|
447
447
|
-o hello.js \
|
|
448
448
|
hello.cpp \
|
|
449
449
|
-lemnapi
|
|
@@ -541,7 +541,7 @@ add_executable(hello hello.c)
|
|
|
541
541
|
target_link_libraries(hello emnapi)
|
|
542
542
|
if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
|
543
543
|
target_link_options(hello PRIVATE
|
|
544
|
-
"-sEXPORTED_FUNCTIONS=['_malloc','_free']"
|
|
544
|
+
"-sEXPORTED_FUNCTIONS=['_napi_register_wasm_v1','_malloc','_free']"
|
|
545
545
|
)
|
|
546
546
|
elseif(CMAKE_SYSTEM_NAME STREQUAL "WASI")
|
|
547
547
|
set_target_properties(hello PROPERTIES SUFFIX ".wasm")
|
|
@@ -616,9 +616,9 @@ path = "src/main.rs"
|
|
|
616
616
|
# crate-type = ["cdylib"]
|
|
617
617
|
|
|
618
618
|
[dependencies]
|
|
619
|
-
napi = { version = "2.
|
|
619
|
+
napi = { version = "2.12.1", default-features = false, features = ["napi8"] }
|
|
620
620
|
napi-sys = { version = "2.2.3", features = ["napi8"] }
|
|
621
|
-
napi-derive = "2.
|
|
621
|
+
napi-derive = "2.12.2"
|
|
622
622
|
|
|
623
623
|
[build-dependencies]
|
|
624
624
|
napi-build = "2.0.1"
|
|
@@ -678,47 +678,61 @@ rustflags = [
|
|
|
678
678
|
```rust
|
|
679
679
|
#![no_main]
|
|
680
680
|
|
|
681
|
-
use napi
|
|
681
|
+
use napi_derive::napi;
|
|
682
682
|
|
|
683
|
-
#[
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
extern crate napi_derive;
|
|
690
|
-
|
|
691
|
-
fn sum(a: i32, b: i32) -> i32 {
|
|
692
|
-
a + b
|
|
683
|
+
#[napi]
|
|
684
|
+
fn fibonacci(n: u32) -> u32 {
|
|
685
|
+
match n {
|
|
686
|
+
1 | 2 => 1,
|
|
687
|
+
_ => fibonacci(n - 1) + fibonacci(n - 2),
|
|
688
|
+
}
|
|
693
689
|
}
|
|
690
|
+
```
|
|
694
691
|
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
let ret = sum(arg0, arg1);
|
|
700
|
-
ctx.env.create_int32(ret)
|
|
701
|
-
}
|
|
692
|
+
</details>
|
|
693
|
+
|
|
694
|
+
<details>
|
|
695
|
+
<summary>index.js</summary><br />
|
|
702
696
|
|
|
703
|
-
|
|
704
|
-
|
|
697
|
+
```js
|
|
698
|
+
const fs = require('fs')
|
|
699
|
+
const path = require('path')
|
|
700
|
+
const useWASI = false
|
|
705
701
|
|
|
706
|
-
|
|
702
|
+
let wasi
|
|
703
|
+
if (useWASI) {
|
|
704
|
+
const { WASI } = require('wasi')
|
|
705
|
+
wasi = new WASI({ /* ... */ })
|
|
707
706
|
}
|
|
708
707
|
|
|
709
|
-
|
|
710
|
-
#[module_exports]
|
|
711
|
-
fn init(exports: napi::JsObject, env: napi::Env) -> napi::Result<()> {
|
|
712
|
-
module_register(env, exports)
|
|
713
|
-
}
|
|
708
|
+
const { instantiateNapiModule } = require('@emnapi/core')
|
|
714
709
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
710
|
+
const wasmBuffer = useWASI
|
|
711
|
+
? fs.readFileSync(path.join(__dirname, './target/wasm32-wasi/release/binding.wasm'))
|
|
712
|
+
: fs.readFileSync(path.join(__dirname, './target/wasm32-unknown-unknown/release/binding.wasm'))
|
|
713
|
+
|
|
714
|
+
instantiateNapiModule(wasmBuffer, {
|
|
715
|
+
context: require('@emnapi/runtime').getDefaultContext(),
|
|
716
|
+
wasi,
|
|
717
|
+
beforeInit ({ instance }) {
|
|
718
|
+
for (const sym in instance.exports) {
|
|
719
|
+
if (sym.startsWith('__napi_register__')) {
|
|
720
|
+
instance.exports[sym]()
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
},
|
|
724
|
+
overwriteImports (importObject) {
|
|
725
|
+
importObject.env = {
|
|
726
|
+
...importObject.env,
|
|
727
|
+
...importObject.napi,
|
|
728
|
+
...importObject.emnapi
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
}).then(({ instance, napiModule }) => {
|
|
732
|
+
const binding = napiModule.exports
|
|
733
|
+
// output: 5
|
|
734
|
+
console.log(binding.fibonacci(5))
|
|
735
|
+
})
|
|
722
736
|
```
|
|
723
737
|
|
|
724
738
|
</details>
|
|
@@ -747,7 +761,7 @@ Now emnapi has 3 implementations of async work and 2 implementations of TSFN:
|
|
|
747
761
|
| B | libemnapi-basic(-mt).a | ✅ | ✅ | ✅ | ✅ |
|
|
748
762
|
| C | libemnapi-basic-mt.a | ❌ | ✅ | ❌ | ✅ |
|
|
749
763
|
| D | libemnapi-mt.a | ✅ | ❌ | ❌ | ✅ |
|
|
750
|
-
| E | libemnapi-basic-mt.a
|
|
764
|
+
| E | libemnapi-basic(-mt).a | ✅ | ✅ | ✅ | ✅ |
|
|
751
765
|
|
|
752
766
|
There are some limitations on browser about wasi-libc's pthread implementation, for example
|
|
753
767
|
`pthread_mutex_lock` may call `__builtin_wasm_memory_atomic_wait32`(`memory.atomic.wait32`)
|
|
@@ -755,6 +769,15 @@ which is disallowed in browser JS main thread. While Emscripten's pthread implem
|
|
|
755
769
|
has considered usage in browser. If you need to run your addon with multithreaded features on browser,
|
|
756
770
|
we recommend you use Emscripten A & D, or bare wasm32 C & E.
|
|
757
771
|
|
|
772
|
+
Note: For browsers, all the multithreaded features relying on Web Workers (Emscripten pthread also relying on Web Workers)
|
|
773
|
+
require cross-origin isolation to enable `SharedArrayBuffer`. You can make a page cross-origin isolated
|
|
774
|
+
by serving the page with these headers:
|
|
775
|
+
|
|
776
|
+
```
|
|
777
|
+
Cross-Origin-Embedder-Policy: require-corp
|
|
778
|
+
Cross-Origin-Opener-Policy: same-origin
|
|
779
|
+
```
|
|
780
|
+
|
|
758
781
|
#### About Prebuilt Libraries
|
|
759
782
|
|
|
760
783
|
Prebuilt libraries can be found in the `lib` directory in `emnapi` npm package.
|
|
@@ -782,7 +805,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
|
|
|
782
805
|
target_compile_options(hello PRIVATE "-pthread")
|
|
783
806
|
target_link_options(hello PRIVATE
|
|
784
807
|
"-sALLOW_MEMORY_GROWTH=1"
|
|
785
|
-
"-sEXPORTED_FUNCTIONS=['_malloc','_free']"
|
|
808
|
+
"-sEXPORTED_FUNCTIONS=['_napi_register_wasm_v1','_malloc','_free']"
|
|
786
809
|
"-pthread"
|
|
787
810
|
"-sPTHREAD_POOL_SIZE=4"
|
|
788
811
|
# try to specify stack size if you experience pthread errors
|
|
@@ -832,7 +855,7 @@ cmake -DCMAKE_TOOLCHAIN_FILE=$WASI_SDK_PATH/share/cmake/wasi-sdk-pthread.cmake \
|
|
|
832
855
|
-G Ninja -H. -Bbuild
|
|
833
856
|
|
|
834
857
|
cmake -DCMAKE_TOOLCHAIN_FILE=node_modules/emnapi/cmake/wasm32.cmake \
|
|
835
|
-
-
|
|
858
|
+
-DLLVM_PREFIX=$WASI_SDK_PATH \
|
|
836
859
|
-DCMAKE_BUILD_TYPE=Release \
|
|
837
860
|
-G Ninja -H. -Bbuild
|
|
838
861
|
|
package/cmake/wasm32.cmake
CHANGED
|
@@ -16,10 +16,12 @@ endif()
|
|
|
16
16
|
|
|
17
17
|
set(CMAKE_C_COMPILER ${LLVM_PREFIX}/bin/clang${WASM_HOST_EXE_SUFFIX})
|
|
18
18
|
set(CMAKE_CXX_COMPILER ${LLVM_PREFIX}/bin/clang++${WASM_HOST_EXE_SUFFIX})
|
|
19
|
+
set(CMAKE_ASM_COMPILER ${LLVM_PREFIX}/bin/clang${WASI_HOST_EXE_SUFFIX})
|
|
19
20
|
set(CMAKE_AR ${LLVM_PREFIX}/bin/llvm-ar${WASM_HOST_EXE_SUFFIX})
|
|
20
21
|
set(CMAKE_RANLIB ${LLVM_PREFIX}/bin/llvm-ranlib${WASM_HOST_EXE_SUFFIX})
|
|
21
22
|
set(CMAKE_C_COMPILER_TARGET ${triple})
|
|
22
23
|
set(CMAKE_CXX_COMPILER_TARGET ${triple})
|
|
24
|
+
set(CMAKE_ASM_COMPILER_TARGET ${triple})
|
|
23
25
|
|
|
24
26
|
# Don't look in the sysroot for executables to run during the build
|
|
25
27
|
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
|
package/dist/library_napi.js
CHANGED
|
@@ -1221,8 +1221,8 @@ function napi_create_reference(env, value, initial_refcount, result) {
|
|
|
1221
1221
|
if (result == 0)
|
|
1222
1222
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
1223
1223
|
var handle = emnapiCtx.handleStore.get(value);
|
|
1224
|
-
if (!(handle.isObject() || handle.isFunction())) {
|
|
1225
|
-
return envObject.setLastError(
|
|
1224
|
+
if (!(handle.isObject() || handle.isFunction() || handle.isSymbol())) {
|
|
1225
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
1226
1226
|
}
|
|
1227
1227
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1228
1228
|
var ref = emnapiCtx.createReference(envObject, handle.id, initial_refcount >>> 0, 1 /* Ownership.kUserland */);
|
|
@@ -4680,17 +4680,22 @@ function napi_create_string_latin1(env, str, length, result) {
|
|
|
4680
4680
|
if (env == 0)
|
|
4681
4681
|
return 1 /* napi_status.napi_invalid_arg */;
|
|
4682
4682
|
var envObject = emnapiCtx.envStore.get(env);
|
|
4683
|
+
{{{ from64('length') }}};
|
|
4684
|
+
var autoLength = length === -1;
|
|
4685
|
+
length = length >>> 0;
|
|
4686
|
+
if (length !== 0) {
|
|
4687
|
+
if (str == 0)
|
|
4688
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4689
|
+
}
|
|
4683
4690
|
if (result == 0)
|
|
4684
4691
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4685
4692
|
{{{ from64('str') }}};
|
|
4686
|
-
|
|
4687
|
-
length = length >>> 0;
|
|
4688
|
-
if (!((length === 0xffffffff) || (length <= 2147483647)) || (!str)) {
|
|
4693
|
+
if (!(autoLength || (length <= 2147483647))) {
|
|
4689
4694
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4690
4695
|
}
|
|
4691
4696
|
var latin1String = '';
|
|
4692
4697
|
var len = 0;
|
|
4693
|
-
if (
|
|
4698
|
+
if (autoLength) {
|
|
4694
4699
|
while (true) {
|
|
4695
4700
|
var ch = {{{ makeGetValue('str', 0, 'u8') }}};
|
|
4696
4701
|
if (!ch)
|
|
@@ -4719,11 +4724,17 @@ function napi_create_string_utf16(env, str, length, result) {
|
|
|
4719
4724
|
if (env == 0)
|
|
4720
4725
|
return 1 /* napi_status.napi_invalid_arg */;
|
|
4721
4726
|
var envObject = emnapiCtx.envStore.get(env);
|
|
4727
|
+
{{{ from64('length') }}};
|
|
4728
|
+
var autoLength = length === -1;
|
|
4729
|
+
var sizelength = length >>> 0;
|
|
4730
|
+
if (length !== 0) {
|
|
4731
|
+
if (str == 0)
|
|
4732
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4733
|
+
}
|
|
4722
4734
|
if (result == 0)
|
|
4723
4735
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4724
4736
|
{{{ from64('str') }}};
|
|
4725
|
-
|
|
4726
|
-
if (((length < -1) || (length > 2147483647)) || (!str)) {
|
|
4737
|
+
if (!(autoLength || (sizelength <= 2147483647))) {
|
|
4727
4738
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4728
4739
|
}
|
|
4729
4740
|
var utf16String = emnapiUtf16ToString(str, length);
|
|
@@ -4737,11 +4748,17 @@ function napi_create_string_utf8(env, str, length, result) {
|
|
|
4737
4748
|
if (env == 0)
|
|
4738
4749
|
return 1 /* napi_status.napi_invalid_arg */;
|
|
4739
4750
|
var envObject = emnapiCtx.envStore.get(env);
|
|
4751
|
+
{{{ from64('length') }}};
|
|
4752
|
+
var autoLength = length === -1;
|
|
4753
|
+
var sizelength = length >>> 0;
|
|
4754
|
+
if (length !== 0) {
|
|
4755
|
+
if (str == 0)
|
|
4756
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4757
|
+
}
|
|
4740
4758
|
if (result == 0)
|
|
4741
4759
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4742
4760
|
{{{ from64('str') }}};
|
|
4743
|
-
|
|
4744
|
-
if (((length < -1) || (length > 2147483647)) || (!str)) {
|
|
4761
|
+
if (!(autoLength || (sizelength <= 2147483647))) {
|
|
4745
4762
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
4746
4763
|
}
|
|
4747
4764
|
var utf8String = emnapiUtf8ToString(str, length);
|
|
@@ -5336,7 +5353,13 @@ function node_api_symbol_for(env, utf8description, length, result) {
|
|
|
5336
5353
|
{{{ from64('length') }}};
|
|
5337
5354
|
{{{ from64('utf8description') }}};
|
|
5338
5355
|
{{{ from64('result') }}};
|
|
5339
|
-
|
|
5356
|
+
var autoLength = length === -1;
|
|
5357
|
+
var sizelength = length >>> 0;
|
|
5358
|
+
if (length !== 0) {
|
|
5359
|
+
if (utf8description == 0)
|
|
5360
|
+
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
5361
|
+
}
|
|
5362
|
+
if (!(autoLength || (sizelength <= 2147483647))) {
|
|
5340
5363
|
return envObject.setLastError(1 /* napi_status.napi_invalid_arg */);
|
|
5341
5364
|
}
|
|
5342
5365
|
var descriptionString = emnapiUtf8ToString(utf8description, length);
|
|
@@ -5763,6 +5786,8 @@ mergeInto(LibraryManager.library, {
|
|
|
5763
5786
|
return UTF8ToString(ptr);
|
|
5764
5787
|
}
|
|
5765
5788
|
length = length >>> 0;
|
|
5789
|
+
if (!length)
|
|
5790
|
+
return '';
|
|
5766
5791
|
return emnapiUtf8Decoder.decode({{{ getUnsharedTextDecoderView('HEAPU8', 'ptr', 'ptr + length') }}});
|
|
5767
5792
|
},
|
|
5768
5793
|
$emnapiUtf16leDecoder__postset: 'emnapiUtf16leDecoder();',
|
|
@@ -5806,6 +5831,8 @@ mergeInto(LibraryManager.library, {
|
|
|
5806
5831
|
return UTF16ToString(ptr);
|
|
5807
5832
|
}
|
|
5808
5833
|
length = length >>> 0;
|
|
5834
|
+
if (!length)
|
|
5835
|
+
return '';
|
|
5809
5836
|
return emnapiUtf16leDecoder.decode({{{ getUnsharedTextDecoderView('HEAPU8', 'ptr', 'ptr + length * 2') }}});
|
|
5810
5837
|
}
|
|
5811
5838
|
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.
|
|
2
|
-
clang version 17.0.0 (https://github.com/llvm/llvm-project
|
|
1
|
+
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.34 (57b21b8fdcbe3ebb523178b79465254668eab408)
|
|
2
|
+
clang version 17.0.0 (https://github.com/llvm/llvm-project a031f72187ce495b9faa4ccf99b1e901a3872f4b)
|
|
3
3
|
Target: wasm32-unknown-emscripten
|
|
4
4
|
Thread model: posix
|
|
5
5
|
InstalledDir: /home/runner/work/emnapi/emnapi/emsdk-cache/emsdk-main/upstream/bin
|
package/package.json
CHANGED
package/src/uv/unix/async.c
CHANGED
|
@@ -151,9 +151,25 @@ static void uv__async_io(uv_loop_t* loop) {
|
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
153
|
|
|
154
|
+
#if EMNAPI_USE_PROXYING
|
|
155
|
+
|
|
156
|
+
#undef emscripten_main_browser_thread_id
|
|
157
|
+
|
|
158
|
+
__attribute__((weak))
|
|
159
|
+
pthread_t emscripten_main_browser_thread_id(void) {
|
|
160
|
+
return NULL;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
__attribute__((weak))
|
|
164
|
+
pthread_t emscripten_main_runtime_thread_id(void) {
|
|
165
|
+
return emscripten_main_browser_thread_id();
|
|
166
|
+
}
|
|
167
|
+
#endif
|
|
168
|
+
|
|
154
169
|
static void uv__async_send(uv_loop_t* loop) {
|
|
155
170
|
#if EMNAPI_USE_PROXYING
|
|
156
|
-
pthread_t main_thread =
|
|
171
|
+
pthread_t main_thread = emscripten_main_runtime_thread_id();
|
|
172
|
+
assert(main_thread != NULL);
|
|
157
173
|
if (pthread_equal(main_thread, pthread_self())) {
|
|
158
174
|
NEXT_TICK((void (*)(void *))uv__async_io, loop);
|
|
159
175
|
} else {
|