Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Make native modules built with Neon work in Bun #914

Merged
merged 1 commit into from
Jul 8, 2022
Merged

Conversation

kjvalencik
Copy link
Member

@kjvalencik kjvalencik commented Jul 7, 2022

bun is a new JavaScript runtime designed to be Node.js compatible--including Node-API. However, it currently ships with an incomplete set of Node-APIs.

The following changes symbol loading to print a warning to stderr if a symbol is missing instead of panicking. This should be no change on Node because symbols are guaranteed to exist if the Node-API version number matches. On bun, this converts a panic on load to a panic when attempting to use the API.

With these changes, simple Neon modules work with bun. However, because of Neon's heavily reliance on napi_get_instance_data, many more powerful features will not work until this API is implemented in bun.

@kjvalencik kjvalencik marked this pull request as draft July 7, 2022 21:39
@kjvalencik kjvalencik marked this pull request as ready for review July 8, 2022 14:41
@kjvalencik kjvalencik force-pushed the kv/bun branch 2 times, most recently from 553de18 to b60393d Compare July 8, 2022 14:58
expected_napi_version,
actual_napi_version,
);

let print_warn = |err| eprintln!("WARN: {}", err);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sample output:

WARN: bun: undefined symbol: napi_get_value_external
WARN: bun: undefined symbol: napi_close_escapable_handle_scope
WARN: bun: undefined symbol: napi_open_escapable_handle_scope
WARN: bun: undefined symbol: napi_create_external
WARN: bun: undefined symbol: napi_escape_handle
WARN: bun: undefined symbol: napi_set_instance_data
WARN: bun: undefined symbol: napi_get_instance_data

@@ -118,7 +118,7 @@ macro_rules! generate {

#[inline(never)]
fn panic_load<T>() -> T {
panic!("Must load N-API bindings")
panic!("Node-API symbol has not been loaded")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently this panic stack looks like:

thread '<unnamed>' panicked at 'Node-API symbol has not been loaded', crates/neon/src/sys/bindings/functions.rs:307:5
stack backtrace:
   0: std::panicking::begin_panic
             at /rustc/db9d1b20bba1968c1ec1fc49616d4742c1725b4b/library/std/src/panicking.rs:525:12
   1: neon::sys::bindings::functions::napi6::panic_load
             at /work/crates/neon/src/sys/bindings/mod.rs:121:13
   2: neon::sys::bindings::functions::napi6::NAPI::get_instance_data

The panic message itself doesn't explain what symbol is missing; instead it requires the backtrace to determine. This is by design because it's never expected to happen on Node and only having a single panic method for the defaults reduces binary bloat.

Do you think it's worth the cost to binary sizes (a bunch of unique functions that should never be executed) to have more clear error messages in bun? I personally feel that the backtrace is sufficient since eventually all symbols should be implemented.

README.md Outdated Show resolved Hide resolved
Copy link
Collaborator

@dherman dherman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! I made one README suggestion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants