summaryrefslogtreecommitdiff
path: root/ext/ffi/dlfcn.rs
diff options
context:
space:
mode:
authorDj <43033058+DjDeveloperr@users.noreply.github.com>2023-04-04 00:02:21 +0530
committerGitHub <noreply@github.com>2023-04-03 21:32:21 +0300
commit62c566469710ba610df764df0ee6560295532e4b (patch)
tree5abd4547b40fa9b2fa89afe4a057a9c556759005 /ext/ffi/dlfcn.rs
parent51d3fb78ad2453e649d01bcc833ecfec1a05d685 (diff)
feat(ext/ffi): support marking symbols as optional (#18529)
Diffstat (limited to 'ext/ffi/dlfcn.rs')
-rw-r--r--ext/ffi/dlfcn.rs23
1 files changed, 19 insertions, 4 deletions
diff --git a/ext/ffi/dlfcn.rs b/ext/ffi/dlfcn.rs
index 4f58248e6..3af9177bf 100644
--- a/ext/ffi/dlfcn.rs
+++ b/ext/ffi/dlfcn.rs
@@ -76,12 +76,19 @@ pub struct ForeignFunction {
#[serde(rename = "callback")]
#[serde(default = "default_callback")]
callback: bool,
+ #[serde(rename = "optional")]
+ #[serde(default = "default_optional")]
+ optional: bool,
}
fn default_callback() -> bool {
false
}
+fn default_optional() -> bool {
+ false
+}
+
// ForeignStatic's name and type fields are read and used by
// serde_v8 to determine which variant a ForeignSymbol is.
// They are not used beyond that and are thus marked with underscores.
@@ -156,7 +163,7 @@ where
ForeignSymbol::ForeignStatic(_) => {
// No-op: Statics will be handled separately and are not part of the Rust-side resource.
}
- ForeignSymbol::ForeignFunction(foreign_fn) => {
+ ForeignSymbol::ForeignFunction(foreign_fn) => 'register_symbol: {
let symbol = match &foreign_fn.name {
Some(symbol) => symbol,
None => &symbol_key,
@@ -168,10 +175,18 @@ where
// SAFETY: The obtained T symbol is the size of a pointer.
match unsafe { resource.lib.symbol::<*const c_void>(symbol) } {
Ok(value) => Ok(value),
- Err(err) => Err(generic_error(format!(
- "Failed to register symbol {symbol}: {err}"
- ))),
+ Err(err) => if foreign_fn.optional {
+ let null: v8::Local<v8::Value> = v8::null(scope).into();
+ let func_key = v8::String::new(scope, &symbol_key).unwrap();
+ obj.set(scope, func_key.into(), null);
+ break 'register_symbol;
+ } else {
+ Err(generic_error(format!(
+ "Failed to register symbol {symbol}: {err}"
+ )))
+ },
}?;
+
let ptr = libffi::middle::CodePtr::from_ptr(fn_ptr as _);
let cif = libffi::middle::Cif::new(
foreign_fn