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.rs28
1 files changed, 26 insertions, 2 deletions
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs
index e1acd097a..ebf5572a7 100644
--- a/ext/ffi/lib.rs
+++ b/ext/ffi/lib.rs
@@ -11,6 +11,7 @@ use deno_core::Extension;
use deno_core::OpState;
use deno_core::Resource;
use deno_core::ResourceId;
+use deno_core::ZeroCopyBuf;
use dlopen::raw::Library;
use libffi::middle::Arg;
use serde::Deserialize;
@@ -131,6 +132,7 @@ enum NativeType {
ISize,
F32,
F64,
+ Buffer,
}
impl From<NativeType> for libffi::middle::Type {
@@ -149,6 +151,7 @@ impl From<NativeType> for libffi::middle::Type {
NativeType::ISize => libffi::middle::Type::isize(),
NativeType::F32 => libffi::middle::Type::f32(),
NativeType::F64 => libffi::middle::Type::f64(),
+ NativeType::Buffer => libffi::middle::Type::pointer(),
}
}
}
@@ -168,6 +171,7 @@ union NativeValue {
isize_value: isize,
f32_value: f32,
f64_value: f64,
+ buffer: *const u8,
}
impl NativeValue {
@@ -210,9 +214,14 @@ impl NativeValue {
NativeType::F64 => Self {
f64_value: value_as_f64(value),
},
+ NativeType::Buffer => unreachable!(),
}
}
+ fn buffer(ptr: *const u8) -> Self {
+ Self { buffer: ptr }
+ }
+
unsafe fn as_arg(&self, native_type: NativeType) -> Arg {
match native_type {
NativeType::Void => Arg::new(&self.void_value),
@@ -228,6 +237,7 @@ impl NativeValue {
NativeType::ISize => Arg::new(&self.isize_value),
NativeType::F32 => Arg::new(&self.f32_value),
NativeType::F64 => Arg::new(&self.f64_value),
+ NativeType::Buffer => Arg::new(&self.buffer),
}
}
}
@@ -257,6 +267,7 @@ fn value_as_f64(value: Value) -> f64 {
}
#[derive(Deserialize, Debug)]
+#[serde(rename_all = "camelCase")]
struct ForeignFunction {
parameters: Vec<NativeType>,
result: NativeType,
@@ -293,20 +304,32 @@ where
Ok(state.resource_table.add(resource))
}
-#[derive(Deserialize, Debug)]
+#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
struct FfiCallArgs {
rid: ResourceId,
symbol: String,
parameters: Vec<Value>,
+ buffers: Vec<ZeroCopyBuf>,
}
fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
+ let buffers: Vec<&[u8]> =
+ args.buffers.iter().map(|buffer| &buffer[..]).collect();
+
let native_values = symbol
.parameter_types
.iter()
.zip(args.parameters.into_iter())
- .map(|(&native_type, value)| NativeValue::new(native_type, value))
+ .map(|(&native_type, value)| {
+ if let NativeType::Buffer = native_type {
+ let idx: usize = value_as_uint(value);
+ let ptr = buffers[idx].as_ptr();
+ NativeValue::buffer(ptr)
+ } else {
+ NativeValue::new(native_type, value)
+ }
+ })
.collect::<Vec<_>>();
let call_args = symbol
@@ -358,6 +381,7 @@ fn ffi_call(args: FfiCallArgs, symbol: &Symbol) -> Result<Value, AnyError> {
NativeType::F64 => {
json!(unsafe { symbol.cif.call::<f64>(symbol.ptr, &call_args) })
}
+ NativeType::Buffer => unreachable!(),
})
}