summaryrefslogtreecommitdiff
path: root/ext/ffi/callback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi/callback.rs')
-rw-r--r--ext/ffi/callback.rs60
1 files changed, 54 insertions, 6 deletions
diff --git a/ext/ffi/callback.rs b/ext/ffi/callback.rs
index b9398c790..d6ef51823 100644
--- a/ext/ffi/callback.rs
+++ b/ext/ffi/callback.rs
@@ -48,7 +48,7 @@ impl PtrSymbol {
.clone()
.into_iter()
.map(libffi::middle::Type::from),
- def.result.into(),
+ def.result.clone().into(),
);
Self { cif, ptr }
@@ -113,7 +113,7 @@ impl Future for CallbackInfo {
}
}
unsafe extern "C" fn deno_ffi_callback(
- _cif: &libffi::low::ffi_cif,
+ cif: &libffi::low::ffi_cif,
result: &mut c_void,
args: *const *const c_void,
info: &CallbackInfo,
@@ -121,15 +121,16 @@ unsafe extern "C" fn deno_ffi_callback(
LOCAL_ISOLATE_POINTER.with(|s| {
if ptr::eq(*s.borrow(), info.isolate) {
// Own isolate thread, okay to call directly
- do_ffi_callback(info, result, args);
+ do_ffi_callback(cif, info, result, args);
} else {
let async_work_sender = &info.async_work_sender;
// SAFETY: Safe as this function blocks until `do_ffi_callback` completes and a response message is received.
+ let cif: &'static libffi::low::ffi_cif = std::mem::transmute(cif);
let result: &'static mut c_void = std::mem::transmute(result);
let info: &'static CallbackInfo = std::mem::transmute(info);
let (response_sender, response_receiver) = sync_channel::<()>(0);
let fut = Box::new(move || {
- do_ffi_callback(info, result, args);
+ do_ffi_callback(cif, info, result, args);
response_sender.send(()).unwrap();
});
async_work_sender.unbounded_send(fut).unwrap();
@@ -143,6 +144,7 @@ unsafe extern "C" fn deno_ffi_callback(
}
unsafe fn do_ffi_callback(
+ cif: &libffi::low::ffi_cif,
info: &CallbackInfo,
result: &mut c_void,
args: *const *const c_void,
@@ -172,9 +174,12 @@ unsafe fn do_ffi_callback(
let result = result as *mut c_void;
let vals: &[*const c_void] =
std::slice::from_raw_parts(args, info.parameters.len());
+ let arg_types = std::slice::from_raw_parts(cif.arg_types, cif.nargs as usize);
let mut params: Vec<v8::Local<v8::Value>> = vec![];
- for (native_type, val) in info.parameters.iter().zip(vals) {
+ for ((index, native_type), val) in
+ info.parameters.iter().enumerate().zip(vals)
+ {
let value: v8::Local<v8::Value> = match native_type {
NativeType::Bool => {
let value = *((*val) as *const bool);
@@ -237,6 +242,20 @@ unsafe fn do_ffi_callback(
v8::Number::new(scope, result as f64).into()
}
}
+ NativeType::Struct(_) => {
+ let size = arg_types[index].as_ref().unwrap().size;
+ let ptr = (*val) as *const u8;
+ let slice = std::slice::from_raw_parts(ptr, size);
+ let boxed = Box::from(slice);
+ let store = v8::ArrayBuffer::new_backing_store_from_boxed_slice(boxed);
+ let ab =
+ v8::ArrayBuffer::with_backing_store(scope, &store.make_shared());
+ let local_value: v8::Local<v8::Value> =
+ v8::Uint8Array::new(scope, ab, 0, ab.byte_length())
+ .unwrap()
+ .into();
+ local_value
+ }
NativeType::Void => unreachable!(),
};
params.push(value);
@@ -440,6 +459,35 @@ unsafe fn do_ffi_callback(
as u64;
}
}
+ NativeType::Struct(_) => {
+ let size;
+ let pointer = if let Ok(value) =
+ v8::Local::<v8::ArrayBufferView>::try_from(value)
+ {
+ let byte_offset = value.byte_offset();
+ let ab = value
+ .buffer(scope)
+ .expect("Unable to deserialize result parameter.");
+ size = value.byte_length();
+ ab.data()
+ .expect("Unable to deserialize result parameter.")
+ .as_ptr()
+ .add(byte_offset)
+ } else if let Ok(value) = v8::Local::<v8::ArrayBuffer>::try_from(value) {
+ size = value.byte_length();
+ value
+ .data()
+ .expect("Unable to deserialize result parameter.")
+ .as_ptr()
+ } else {
+ panic!("Unable to deserialize result parameter.");
+ };
+ std::ptr::copy_nonoverlapping(
+ pointer as *mut u8,
+ result as *mut u8,
+ std::cmp::min(size, (*cif.rtype).size),
+ );
+ }
NativeType::Void => {
// nop
}
@@ -522,7 +570,7 @@ where
let info: *mut CallbackInfo = Box::leak(Box::new(CallbackInfo {
parameters: args.parameters.clone(),
- result: args.result,
+ result: args.result.clone(),
async_work_sender,
callback,
context,