Commit graph

298 commits

Author SHA1 Message Date
LongYinan
3deae16442
fix(napi): add tokio cleanup hook for more platforms (#1790) 2023-11-06 13:59:54 +08:00
LongYinan
65f57918fb
style(napi): as ptr => ptr::cast (#1786) 2023-11-06 11:22:30 +08:00
LongYinan
1e5c32ca60
style(napi): fix compile warning (#1785) 2023-11-06 11:21:26 +08:00
LongYinan
feabcd7f16
test(napi): add tests for napi9 features (#1784) 2023-11-06 11:03:44 +08:00
LongYinan
4e4d891ad8
feat: add experimental Env::get_module_file_name method (#1783) 2023-11-06 11:01:27 +08:00
LongYinan
2b0ddf4a21
feat(napi,sys): sync to napi9 (#1781)
- Close https://github.com/napi-rs/napi-rs/issues/1600
2023-11-06 11:00:27 +08:00
LongYinan
546b108a5b
feat(napi): support async class factory (#1779)
- Close https://github.com/napi-rs/napi-rs/issues/1777
2023-11-06 10:58:23 +08:00
LongYinan
0dc1ef738b fix(napi): asan caught memory safety issue 2023-11-04 15:26:07 +08:00
Özgür Akkurt
2c410b238d
feat(napi): impl Default for Buffer (#1734) 2023-11-02 22:32:13 +08:00
stefan-gorules
afdd4060ab
fix(napi): js promise error messages (#1672) 2023-11-02 17:32:20 +08:00
kuzeyardabulut
3a1a280d5f
fix(napi): potential double free issue (#1679)
* Update module_register.rs

* Run fmt

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-11-02 17:19:35 +08:00
LongYinan
13d0ce075e
feat: integrate with emnapi (#1669)
* Integrate with emnapi

* resolve conflict

* ignore wasm

* generate wasi file

* Add wasi test to workflow

* Fix wasi template

* emnapi new initialize api

* Finish test

* Purne tsconfig

* Generate wasi worker

* Fix electron test

* Finalize check

* Noop adjust_external_memory

* Apply cr suggestions
2023-11-02 12:57:11 +08:00
Markus
9b4beb83e9
chore(napi): make napi_register_module_v1 pub (#1747)
* feat(napi): make napi_register_module_v1 pub

* docs: add safety section

* chore: format doc comment
2023-10-09 11:18:34 +08:00
Tom Sherman
3418fd3e8f
feat(napi,sys): implement Symbol.for (#1721)
Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-09-13 15:45:14 -07:00
LongYinan
05b4be4d80
style: clippy fix (#1711) 2023-08-30 16:41:13 +08:00
plodsoft
8bf32be7d4
feat(napi): impl FromNapiValue for HashMap with custom hasher (#1682) 2023-08-11 11:05:04 +08:00
LongYinan
07d03c9435
chore: MSRV 1.63.0 2023-08-10 10:44:55 +08:00
LongYinan
a7eeb0c31c
fix(napi): promise resolve error (#1664) 2023-07-24 00:36:24 +08:00
LongYinan
6d62b3f714
chore: upgrade dependencies (#1657) 2023-07-17 14:56:02 +08:00
Markus
73a704a19e
feat(napi): keep stack traces in a deferred context (#1637)
* feat(napi): keep stack traces in deferred context

* chore: reformat code

Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>

* chore: use napi wrappers

Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>

* test(napi): add test for deferred trace

Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>

* chore: fix format

Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>

---------

Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>
2023-07-15 12:07:14 +08:00
LongYinan
53cd1bc904
fix(napi): impl send + sync for ThreadsafeFunction (#1622) 2023-06-14 15:24:01 +08:00
Alexey Orlenko
1fd469a7fc
chore: remove extra #[cfg] attribute (#1616)
This was accidentally added in 2d1e4144b3.
The second cfg attribute is essentially a no-op since the first one is
still valid and has more conditions, but we don't need it.
2023-06-07 09:30:18 +08:00
LongYinan
5a2cd93708
fix(napi): missing ValidateNapiValue for JsObject (#1606) 2023-05-27 13:33:42 +08:00
LongYinan
c6258cf633
feat(napi): support chrono::NaiveDateTime (#1601) 2023-05-26 18:28:34 +08:00
Jānis Gailis
d1fe0f0eb1
feat(napi): Bigint deserialization (#1592)
* Handle little endianness;
* Make sure get_<u/i>128 methods don't panic when words.len() < 2;
* Make sure BigInt deserialization takes into account word length and
  sign;

Signed-off-by: Janis Gailis <JanisGailis@users.noreply.github.com>
Co-authored-by: Janis Gailis <>
2023-05-19 17:27:29 +08:00
LongYinan
d184d503d5
fix(napi-derive): increase initial ref count in async fn (#1577) 2023-04-26 15:18:00 +08:00
Maël Nison
2f00e79873
chore(napi): adds support for Rc<T> / Arc<T> / Mutex<T> (#1573)
* Adds support for Rc/Arc/Mutex<T>

* Fixes codegen

* Fixes lint

* Fix clippy

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-04-25 11:14:06 +08:00
LongYinan
d9ff0b4ddf
fix(napi): do nothing in deferred if thread is destroyed (#1568) 2023-04-15 18:58:53 +08:00
LongYinan
d14fdca242
fix(napi): thread safe issue while creating class instance (#1561) 2023-04-15 15:37:01 +08:00
LongYinan
070230079d
fix(napi): noop feature 2023-04-11 11:44:10 +08:00
gaoquanzero
7fdcd7a8ae
chore(napi): add noop feature in napi crate (#1546) 2023-04-10 18:47:34 +08:00
LongYinan
66ef64bdc7
style(napi): use cast() instread as 2023-04-10 17:14:27 +08:00
LongYinan
752ffea1d9
fix(napi): revert Promise changes because of the flaky test 2023-04-10 17:14:26 +08:00
LongYinan
88773a7a8e
fix(napi): re-throw error in ThreadsafeFunction callback if we could 2023-04-10 17:02:13 +08:00
Alexey Orlenko
2d1e4144b3
fix: prevent crashing when napi_register_module_v1 is called twice (#1554)
* fix: prevent crashing when napi_register_module_v1 is called twice

Currently napi-rs addons can lead to the Node.js process aborting with
the following error when initialising the addon on Windows:

```
c:\ws\src\cleanup_queue-inl.h:32: Assertion `(insertion_info.second)
== (true)' failed.
```

This happens because `napi_add_env_cleanup_hook` must not be called
with the same arguments multiple times unless the previously scheduled
cleanup hook with the same arguments was already executed. However,
the cleanup hook added by `napi_register_module_v1` in napi-rs on
Windows was always created with `ptr::null_mut()` as an argument.

One case where this causes a problem is when using the addon from
multiple contexts (e.g. Node.js worker threads) at the same
time. However, Node.js doesn't provide any guarantees that the N-API
addon initialisation code will run only once even per thread and
context. In fact, it's totally valid to run `process.dlopen()`
multiple times from JavaScript land in Node.js, and this will lead to
the initialisation code being run multiple times as different
`exports` objects may need to be populated. This may happen in
numerous cases, e.g.:

- When it's not possible or not desirable to use `require()` and users
  must resort to using `process.dlopen()` (one use case is passing
  non-default flags to `dlopen(3)`, another is ES modules). Caching
  the results of `process.dlopen()` to avoid running it more than once
  may not always be possible reliably in all cases (for example,
  because of Jest sandbox).

- When the `require` cache is cleared.

- On Windows: `require("./addon.node")` and then
  `require(path.toNamespacedPath("./addon.node"))`.

Another issue is fixed inside `napi::tokio_runtime::drop_runtime`:
there's no need to call `napi_remove_env_cleanup_hook` (it's only
useful to cancel the hooks that haven't been executed yet). Null
pointer retrieved from `arg` was being passed as the `env` argument of
that function, so it didn't do anything and just returned
`napi_invalid_arg`.

This patch makes `napi_register_module_v1` use a counter as the
cleanup hook argument, so that the value is always different. An
alternative might have been to use a higher-level abstraction around
`sys::napi_env_cleanup_hook` that would take ownership of a boxed
closure, if there is something like this in the API already. Another
alternative could have been to heap-allocate a value so that we would
have a unique valid memory address.

The patch also contains a minor code cleanup related to
`RT_REFERENCE_COUNT` along the way: the counter is encapsulated inside
its module and `ensure_runtime` takes care of incrementing it, and
less strict memory ordering is now used as there's no need for
`SeqCst` here. If desired, it can be further optimised to
`Ordering::Release` and a separate acquire fence inside the if
statement in `drop_runtime`, as `AcqRel` for every decrement is also a
bit stricter than necessary (although simpler). These changes are not
necessary to fix the issue and can be extracted to a separate patch.

At first it was tempting to use the loaded value of
`RT_REFERENCE_COUNT` as the argument for the cleanup hook but it would
have been wrong: a simple counterexample is the following sequence:

1. init in the first context (queue: 0)
2. init in the second context (queue: 0, 1)
3. destroy the first context (queue: 1)
4. init in the third context (queue: 1, 1)

* test(napi): unload test was excluded unexpected

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-04-08 23:08:48 +08:00
Markus
71e44be73d
fix(napi): access violation in property getter/setter closure (#1552)
Signed-off-by: Markus <28785953+MarkusJx@users.noreply.github.com>
2023-04-03 11:12:07 +08:00
LongYinan
0a6b214505
fix(napi): free buffer in current thread if env is available (#1549) 2023-03-30 12:55:54 +08:00
LongYinan
a0b6e2b263
fix(napi): use ptr::copy to create TypedArray in electron fallback mode (#1548) 2023-03-29 14:03:32 +08:00
Bo
d8cfcfdfda
fix(napi): ensure that napi_call_threadsafe_function cannot be called after abort (#1533)
* refactor(napi): reduce boilerplate code for accessing `aborted` lock

* refactor: ensure that `napi_call_threadsafe_function` cannot be called after abort

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-03-28 20:54:55 +08:00
Bo
e47c13f177
fix(napi): check if the tokio runtime exists when registering the module
And recreate it if it does not exist.

In windows, electron renderer process will crash if:
1. Import some NAPI module that enable `tokio-rt` flag in renderer process.
2. Reload the page.
3. Call a function imported from that NAPI module.

Because the tokio runtime will be dropped when reloading the page, and won't create again, but currently we assume that the runtime must exist in tokio-based `within_runtime_if_available`.
This will cause some panic like this:

```
thread '<unnamed>' panicked at 'called `Option::unwrap()` on a `None` value', napi-rs\crates\napi\src\tokio_runtime.rs:72:42
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Error: Renderer process crashed: crashed, exitCode: -529697949
    at EventEmitter.<anonymous> (napi-rs\examples\napi\electron.js:33:9)
    at EventEmitter.emit (node:events:525:35)
```
2023-03-28 12:03:00 +08:00
Gabriel Francisco
3983be23f5
fix(napi): big numbers losing precision on serde_json::Value (#1538)
* fix(napi): big numbers losing precision on serde_json::Value

* fix(napi): add feature flags for bigint on number conversion

* chore(napi): change MAX_SAFE_INT to constant and convert big numbers to string when bigint is not available

* chore(napi): change how the check for safe integer range is made
2023-03-23 13:34:34 +08:00
Victor Teo
aee742f185
feat(napi): property getter and setter with closure (#1526)
* getter with closure with segment fault

* fix getter closure pointer

* add setter

* Cleanup API

* Add test for `create_function_from_closure`

* Fix compile error

* Fix flaky test title

---------

Co-authored-by: LongYinan <lynweklm@gmail.com>
2023-03-21 11:22:07 +08:00
LongYinan
550ef7c3cc
feat: export registers in wasm32 target (#1529) 2023-03-20 18:42:27 +08:00
LongYinan
5605bdf7fc
fix(napi): ThreadsafeFunctionHandle never being dropped (#1530) 2023-03-20 18:01:09 +08:00
Bo
a6e1ff471c
fix(napi): use weak arc for passing thread_finalize_data (#1525)
* fix(napi): use weak arc for passing thread_finalize_data

* fix: try to fix test of tsfn_return_promise_timeout
2023-03-20 11:56:54 +08:00
LongYinan
347e81b3cc
chore(napi): upgrade bitflags to v2 (#1518) 2023-03-16 11:23:03 +08:00
HotQ
0af728a601
fix(napi): prevent access to tsfn-raw after tsfn finalized(#1514) (#1515) 2023-03-14 21:31:52 +08:00
Alberto Pose
ffc4980d52
fix(napi): panic when Promise callbacks trigger after Promise is dropped (#1469) (#1516)
Co-authored-by: Alberto Pose <albepose@amazon.com>
2023-03-14 15:32:17 +08:00
LongYinan
96959e6425
chore(napi): remove thread_local from dependenies (#1506) 2023-03-05 19:49:52 +08:00
Hana
fc101d0d6b
fix(napi): display should be implemented on error generics (#1497) 2023-02-24 19:46:39 +08:00
Hana
853f52ed1f
fix(napi): error should be send sync conditionally (#1487) 2023-02-14 18:58:04 +08:00
LongYinan
8e3eb6204b
fix(napi): support custom status in Error (#1486) 2023-02-09 23:18:57 +08:00
Hana
90cc0a6abe
feat(napi): convert ToNapiValue tuple to variadic tsfn (#1475)
* refactor: convert ToNapiValue tuple to variadic tsfn

* chore: resolve conflicts

* fix: typo

* chore: use into instead of to

* chore: syntax compat
2023-02-08 22:30:43 +08:00
m1212e
a7dcf2a838
fix(napi): convert u64 to u32 in serialization (#1478)
https://github.com/napi-rs/napi-rs/issues/1470
serde_json::Value parses positive integers to u64 types by default. When converting serde_json::Value to a js value, those numbers are converted to BigInts, even if they are within the bounds of the number primitive. The added checks converts an u64 to an u32 if possible to prevent this behavior.

Co-authored-by: m1212e <->
2023-02-08 22:25:03 +08:00
LongYinan
c34ccc9131
fix(napi): impl Send Sync to External 2023-02-08 17:33:27 +08:00
Hana
31015652b8
fix(napi): dropping Error should not call napi-sys if feature is set to noop (#1477) 2023-02-07 15:45:56 +08:00
LongYinan
7613d669fb
chore(napi): enhance the error messages while converting types failed (#1473) 2023-02-06 00:52:59 +08:00
LongYinan
3bd2bf40b1
fix(napi): run_script return type (#1467) 2023-01-31 20:36:59 +08:00
LongYinan
e9de5681be
fix(napi): also apply electron external data fallback to lowlevel APIs (#1458)
* fix(napi): also apply electron external data fallback to lowlevel APIs

* chore: allow uninlined_format_args in tests
2023-01-28 21:31:57 +08:00
LongYinan
adb2508fdf
fix(napi): add missing NoExternalBuffersAllowed (#1457) 2023-01-28 14:53:31 +08:00
LongYinan
548f288722
fix(napi): fallback to copy arraybuffer if zero copy is not allowed (#1455) 2023-01-24 22:39:46 +08:00
LongYinan
e3adf5dac4
fix(napi): unhandled promise rejection while using EitherN<Promise<..>> (#1452) 2023-01-24 19:07:33 +08:00
LongYinan
54dd120880
fix(napi): add UnknownReturnValue to use in call_async scenario (#1451) 2023-01-24 17:41:36 +08:00
LongYinan
694f761fd9
fix(napi): throw fatal error if cast return value failed (#1450) 2023-01-24 16:32:40 +08:00
LongYinan
02daa90058
chore(napi): implement FromNapiValue for ThreadsafeFunction (#1447) 2023-01-24 12:16:24 +08:00
LongYinan
fda0aa0eec
fix(napi): fallback to copy buffer if zero copy is not allowed (#1445) 2023-01-19 17:26:59 +08:00
LongYinan
6739ddda20
fix(napi): remove useless aquire while creating ThreadsafeFunction (#1442) 2023-01-18 11:20:47 +08:00
LongYinan
46f08ee6dd
fix(napi): missing From implementation for Bigint (#1440) 2023-01-17 00:05:19 +08:00
HeYunfei
d06bd23351
fix(napi): should correctly return while dropping Buffer (#1434) 2023-01-11 20:09:39 +08:00
LongYinan
dc3a4c9f25
feat(napi): refactor ThreadsafeFunction to allow get return value of it (#1427) 2023-01-11 18:54:45 +08:00
LongYinan
5492a0b9e9
fix(napi): delete reference should be after global custom gc (#1433) 2023-01-11 17:31:03 +08:00
LongYinan
ad3ac5abc7
fix(napi): array buffer drop notify never be called in cloned buffer (#1424) 2023-01-09 16:58:26 +08:00
overlookmotel
ce2a29fca7
fix(napi): arraybuffer memory leak (#1420) 2023-01-09 14:47:36 +08:00
LongYinan
877d631d99
fix(napi): only delete reference in custom gc 2022-12-29 14:48:00 +08:00
Xiaopeng Li
ce4c28412a
fix(napi): promise leak (#1403)
Co-authored-by: Xiaopeng Li <lixiaopeng.jetspark@bytedance.com>
2022-12-29 00:15:55 +08:00
LongYinan
ef5dffca80
fix(napi): add back custom gc for Send Buffer (#1399) 2022-12-19 19:11:53 +08:00
LongYinan
328b84eb8f
style: run format 2022-12-17 00:14:05 +08:00
LongYinan
f8d1dcee5b
Merge pull request #1395 from napi-rs/tweaks-code
chore(napi): reduce Mutex usage while loading addon
2022-12-16 23:13:36 +08:00
LongYinan
e370dee545
chore(napi): remove useless de_init 2022-12-16 21:50:49 +08:00
LongYinan
6e4b16fe5d
style: clippy fix 2022-12-16 20:19:39 +08:00
LongYinan
968d9e10b1
chore(napi): fix tokio destroy logic 2022-12-16 20:07:22 +08:00
F001
d2531352aa
feat(napi): add "run_script" for "Env" (#1393)
* add "run_script" for "Env"

* Apply suggestions from code review

use `AsRef<str>` instead of `&str`

Co-authored-by: LongYinan <lynweklm@gmail.com>

* use `AsRef<str>` instead of `&str`

Co-authored-by: LongYinan <lynweklm@gmail.com>
2022-12-16 15:56:36 +08:00
LongYinan
e88fbcc404
chore(napi): remove more thread_local usage 2022-12-16 15:54:29 +08:00
LongYinan
5bd6c78b5a
chore(napi): expose tokio runtime 2022-12-16 14:35:30 +08:00
LongYinan
c01bcecb2b
chore(napi): reduce the complex about destroying tokio runtime 2022-12-16 14:32:32 +08:00
Patrick Pilch
486ce35c82
fix(napi): napi_create_async_work incorrect argument (napi-rs#1392) (#1396)
The third argument to `napi_create_async_work` (async_resource_name)
should be a `napi_value` that corresponds to a null-terminated utf-8
string.

This resolves errors running Next.js with GraalVM.

oracle/graal#5582
oracle/graal#5581
2022-12-16 13:59:15 +08:00
LongYinan
a9f9dbb232
chore(napi): reduce Mutex usage while loading addon 2022-12-16 13:41:16 +08:00
nihohit
1cf32631bf
fix(napi): typed arrays ref shouldn't use offset. (#1376)
Notice from the n-api docs that the data returned from
`napi_get_typedarray_info` is already adjusted by the byte offset.
https://nodejs.org/api/n-api.html#napi_get_typedarray_info

This means that when `as_ref`/`as_mut` apply the byte offset, the
offset is in practice applied twice.
This wasn't caught in tests because no test tried to modify a typed
array with a byte offset, and the test didn't us the typed array
structs, only `JsTypedArray`. If you want, I can modify the rest of the
functions in examples/napi-compt-mode/src/arraybuffers.rs
and the matching tests, to test all typed arrays.

IMO the `byte_offset` field can be removed entirely from the struct,
but I wanted to submit a minimal PR.
2022-11-30 20:54:13 +08:00
Simon Laux
035def0600
fix(napi): return the join handle when spawning a tokio task. (#1351)
we need this to be able to safely drop an struct,
that makes use of an async task.
the drop function needs to be able to call `.abort()`
on the join handle to avoid memory corruption and undefined bahviour.
2022-11-15 11:50:25 +08:00
Simon Laux
b0c248ad7e
chore(napi): expose tokio runtime's block_on function (#1352) 2022-11-15 11:49:46 +08:00
LongYinan
3dde26bcef
chore(napi): including type message in error message (#1350) 2022-10-24 00:16:30 +08:00
Wodann
77060adb3d
fix(napi): BigInt::get_u64 lossless check (#1348) 2022-10-22 11:16:08 +08:00
Devon Govett
5541d650a9
feat(napi): add threadsafe deferred values (#1306) 2022-10-03 13:00:48 +08:00
LongYinan
a5a04a4e54
fix(napi): make Buffer/ArrayBuffer truely Send/Sync safe 2022-10-03 11:34:46 +08:00
LongYinan
47de6301ee
fix(napi): should also delete the reference while dropping the Buffer 2022-10-02 10:14:25 +08:00
user.tax
e54c37a0b1
feat(napi): add support for Vec<(std::string::String, u16)> and some other small change (#1320) 2022-09-20 12:13:07 +08:00
user.tax
0d49b45ea9
feat(napi): add impl<T: Into<Vec<u8>>> From<T> for Uint8Array (#1317)
Co-authored-by: any <any@user.tax>
2022-09-16 23:15:29 +08:00
LongYinan
ea18170779
fix(napi): propagation error in function call (#1315) 2022-09-14 19:30:43 +08:00
Devon Govett
5ba70b0e1a
fix(napi): improve error propagation (#1303) 2022-09-14 17:03:11 +08:00
Dennis Duda
fc63ba8b52
fix(napi): some of the unsoundness in Buffer (#1294)
* fix leaked napi refcount in `Buffer` when cloning

Cloning unconditionally increased the refcount in `Buffer::clone`, but only called `napi_reference_unref` on dropping the last Buffer (the one with `strong_count == 1`). This means that the refcount will never drop back to zero after cloning, leaking the Buffer.

This commit changes it to also unconditionally unref the buffer.

* fix multiple sources of UB in `Buffer`

- `slice::from_raw_parts` may never be created with a null pointer, but `napi_get_buffer_info` was not sufficiently checked → UB when passing an empty Buffer
- `&'static mut [u8],` is invalid, as it certainly doesn't live for `'static`

Switching to `NonNull<u8>` and a `len` field fixes both of these.

- I also don't really understand how the `impl ToNapiValue for &mut Buffer` could have been sound. It creates an entirely new `Arc`, but reuses the same `Vec` allocation, leading to... a double free of the `Vec` on drop? I have replaced it with a simple call to `clone` instead.

* remove overcomplicated bool and drop impl

As far as I can tell, by just removing the bool and letting the drop code do its thing we clean up correctly in all cases. Because `napi_create_external_buffer` gets an owned `Buffer` attached to it via the Box, we can rely on `from_raw` retrieving it in the `drop_buffer` function.
2022-09-05 13:04:43 +08:00