1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-24 08:09:08 -05:00

fix(napi): handle return value from initializer (#17502)

Fixes https://github.com/denoland/deno/issues/17349
This commit is contained in:
Divy Srivastava 2023-01-23 05:29:46 -08:00 committed by GitHub
parent b96bbc32c8
commit c3e0b12c72
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 41 additions and 13 deletions

View file

@ -678,7 +678,7 @@ where
let nm = unsafe { &*nm }; let nm = unsafe { &*nm };
assert_eq!(nm.nm_version, 1); assert_eq!(nm.nm_version, 1);
// SAFETY: we are going blind, calling the register function on the other side. // SAFETY: we are going blind, calling the register function on the other side.
let exports = unsafe { let maybe_exports = unsafe {
(nm.nm_register_func)( (nm.nm_register_func)(
env_ptr, env_ptr,
std::mem::transmute::<v8::Local<v8::Value>, napi_value>( std::mem::transmute::<v8::Local<v8::Value>, napi_value>(
@ -687,11 +687,20 @@ where
) )
}; };
// SAFETY: v8::Local is a pointer to a value and napi_value is also a pointer let exports = maybe_exports
// to a value, they have the same layout .as_ref()
let exports = unsafe { .map(|_| unsafe {
std::mem::transmute::<napi_value, v8::Local<v8::Value>>(exports) // 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 }) Ok(serde_v8::Value { v8_value: exports })
} }
None => { None => {
@ -704,17 +713,29 @@ where
exports: napi_value, exports: napi_value,
) -> napi_value>(b"napi_register_module_v1") ) -> napi_value>(b"napi_register_module_v1")
.expect("napi_register_module_v1 not found"); .expect("napi_register_module_v1 not found");
init( let maybe_exports = init(
env_ptr, env_ptr,
std::mem::transmute::<v8::Local<v8::Value>, napi_value>( std::mem::transmute::<v8::Local<v8::Value>, napi_value>(
exports.into(), exports.into(),
), ),
) );
};
Ok(serde_v8::Value { let exports = maybe_exports
v8_value: exports.into(), .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 // NAPI addons can't be unloaded, so we're going to "forget" the library

View file

@ -123,13 +123,20 @@ pub fn init_cleanup_hook(env: napi_env, exports: napi_value) {
#[no_mangle] #[no_mangle]
unsafe extern "C" fn napi_register_module_v1( unsafe extern "C" fn napi_register_module_v1(
env: napi_env, env: napi_env,
exports: napi_value, _: napi_value,
) -> napi_value { ) -> napi_value {
#[cfg(windows)] #[cfg(windows)]
{ {
napi_sys::setup(); 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); strings::init(env, exports);
numbers::init(env, exports); numbers::init(env, exports);
typedarray::init(env, exports); typedarray::init(env, exports);