summaryrefslogtreecommitdiff
path: root/ext/ffi/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi/lib.rs')
-rw-r--r--ext/ffi/lib.rs70
1 files changed, 69 insertions, 1 deletions
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs
index 2a6799b5f..8f06854d6 100644
--- a/ext/ffi/lib.rs
+++ b/ext/ffi/lib.rs
@@ -130,6 +130,11 @@ pub fn init<P: FfiPermissions + 'static>(unstable: bool) -> Extension {
("op_ffi_load", op_sync(op_ffi_load::<P>)),
("op_ffi_call", op_sync(op_ffi_call)),
("op_ffi_call_nonblocking", op_async(op_ffi_call_nonblocking)),
+ ("op_ffi_call_ptr", op_sync(op_ffi_call_ptr)),
+ (
+ "op_ffi_call_ptr_nonblocking",
+ op_async(op_ffi_call_ptr_nonblocking),
+ ),
("op_ffi_ptr_of", op_sync(op_ffi_ptr_of::<P>)),
("op_ffi_buf_copy_into", op_sync(op_ffi_buf_copy_into::<P>)),
("op_ffi_cstr_read", op_sync(op_ffi_cstr_read::<P>)),
@@ -323,7 +328,7 @@ fn value_as_f64(value: Value) -> Result<f64, AnyError> {
}
}
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
struct U32x2(u32, u32);
impl From<u64> for U32x2 {
@@ -469,6 +474,49 @@ struct FfiCallArgs {
buffers: Vec<Option<ZeroCopyBuf>>,
}
+#[derive(Deserialize)]
+#[serde(rename_all = "camelCase")]
+struct FfiCallPtrArgs {
+ pointer: U32x2,
+ def: ForeignFunction,
+ parameters: Vec<Value>,
+ buffers: Vec<Option<ZeroCopyBuf>>,
+}
+
+impl From<FfiCallPtrArgs> for FfiCallArgs {
+ fn from(args: FfiCallPtrArgs) -> Self {
+ FfiCallArgs {
+ rid: 0,
+ symbol: String::new(),
+ parameters: args.parameters,
+ buffers: args.buffers,
+ }
+ }
+}
+
+impl FfiCallPtrArgs {
+ fn get_symbol(&self) -> Symbol {
+ let fn_ptr: u64 = self.pointer.into();
+ let ptr = libffi::middle::CodePtr::from_ptr(fn_ptr as _);
+ let cif = libffi::middle::Cif::new(
+ self
+ .def
+ .parameters
+ .clone()
+ .into_iter()
+ .map(libffi::middle::Type::from),
+ self.def.result.into(),
+ );
+
+ Symbol {
+ cif,
+ ptr,
+ parameter_types: self.def.parameters.clone(),
+ result_type: self.def.result,
+ }
+ }
+}
+
fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
let buffers: Vec<Option<&[u8]>> = args
.buffers
@@ -563,6 +611,26 @@ fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
})
}
+fn op_ffi_call_ptr(
+ _state: &mut deno_core::OpState,
+ args: FfiCallPtrArgs,
+ _: (),
+) -> Result<Value, AnyError> {
+ let symbol = args.get_symbol();
+ ffi_call(args.into(), &symbol)
+}
+
+async fn op_ffi_call_ptr_nonblocking(
+ _state: Rc<RefCell<deno_core::OpState>>,
+ args: FfiCallPtrArgs,
+ _: (),
+) -> Result<Value, AnyError> {
+ let symbol = args.get_symbol();
+ tokio::task::spawn_blocking(move || ffi_call(args.into(), &symbol))
+ .await
+ .unwrap()
+}
+
fn op_ffi_call(
state: &mut deno_core::OpState,
args: FfiCallArgs,