diff options
author | Dj <43033058+DjDeveloperr@users.noreply.github.com> | 2023-04-04 00:02:21 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-03 21:32:21 +0300 |
commit | 62c566469710ba610df764df0ee6560295532e4b (patch) | |
tree | 5abd4547b40fa9b2fa89afe4a057a9c556759005 /ext/ffi/dlfcn.rs | |
parent | 51d3fb78ad2453e649d01bcc833ecfec1a05d685 (diff) |
feat(ext/ffi): support marking symbols as optional (#18529)
Diffstat (limited to 'ext/ffi/dlfcn.rs')
-rw-r--r-- | ext/ffi/dlfcn.rs | 23 |
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 |