Skip to content

Commit

Permalink
fix(napi): handle return value from initializer (denoland#17502)
Browse files Browse the repository at this point in the history
  • Loading branch information
littledivy committed Jan 23, 2023
1 parent b96bbc3 commit c3e0b12
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
47 changes: 34 additions & 13 deletions ext/napi/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -678,7 +678,7 @@ where
let nm = unsafe { &*nm };
assert_eq!(nm.nm_version, 1);
// SAFETY: we are going blind, calling the register function on the other side.
let exports = unsafe {
let maybe_exports = unsafe {
(nm.nm_register_func)(
env_ptr,
std::mem::transmute::<v8::Local<v8::Value>, napi_value>(
Expand All @@ -687,11 +687,20 @@ where
)
};

// SAFETY: v8::Local is a pointer to a value and napi_value is also a pointer
// to a value, they have the same layout
let exports = unsafe {
std::mem::transmute::<napi_value, v8::Local<v8::Value>>(exports)
};
let exports = maybe_exports
.as_ref()
.map(|_| unsafe {
// SAFETY: v8::Local is a pointer to a value and napi_value is also a pointer
// to a value, they have the same layout
std::mem::transmute::<napi_value, v8::Local<v8::Value>>(
maybe_exports,
)
})
.unwrap_or_else(|| {
// If the module didn't return anything, we use the exports object.
exports.into()
});

Ok(serde_v8::Value { v8_value: exports })
}
None => {
Expand All @@ -704,17 +713,29 @@ where
exports: napi_value,
) -> napi_value>(b"napi_register_module_v1")
.expect("napi_register_module_v1 not found");
init(
let maybe_exports = init(
env_ptr,
std::mem::transmute::<v8::Local<v8::Value>, napi_value>(
exports.into(),
),
)
};

Ok(serde_v8::Value {
v8_value: exports.into(),
})
);

let exports = maybe_exports
.as_ref()
.map(|_| {
// SAFETY: v8::Local is a pointer to a value and napi_value is also a pointer
// to a value, they have the same layout
std::mem::transmute::<napi_value, v8::Local<v8::Value>>(
maybe_exports,
)
})
.unwrap_or_else(|| {
// If the module didn't return anything, we use the exports object.
exports.into()
});

Ok(serde_v8::Value { v8_value: exports })
}
}
};
// NAPI addons can't be unloaded, so we're going to "forget" the library
Expand Down
9 changes: 8 additions & 1 deletion test_napi/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,20 @@ pub fn init_cleanup_hook(env: napi_env, exports: napi_value) {
#[no_mangle]
unsafe extern "C" fn napi_register_module_v1(
env: napi_env,
exports: napi_value,
_: napi_value,
) -> napi_value {
#[cfg(windows)]
{
napi_sys::setup();
}

// We create a fresh exports object and leave the passed
// exports object empty.
//
// https://github.com/denoland/deno/issues/17349
let mut exports = std::ptr::null_mut();
assert_napi_ok!(napi_create_object(env, &mut exports));

strings::init(env, exports);
numbers::init(env, exports);
typedarray::init(env, exports);
Expand Down

0 comments on commit c3e0b12

Please sign in to comment.