summaryrefslogtreecommitdiff
path: root/ext/ffi/dlfcn.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi/dlfcn.rs')
-rw-r--r--ext/ffi/dlfcn.rs31
1 files changed, 23 insertions, 8 deletions
diff --git a/ext/ffi/dlfcn.rs b/ext/ffi/dlfcn.rs
index 5caf95ef2..eeff2c8a7 100644
--- a/ext/ffi/dlfcn.rs
+++ b/ext/ffi/dlfcn.rs
@@ -1,6 +1,7 @@
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
use crate::check_unstable;
+use crate::ir::out_buffer_as_ptr;
use crate::symbol::NativeType;
use crate::symbol::Symbol;
use crate::turbocall;
@@ -52,7 +53,7 @@ impl DynamicLibraryResource {
}
}
-pub fn needs_unwrap(rv: NativeType) -> bool {
+pub fn needs_unwrap(rv: &NativeType) -> bool {
matches!(
rv,
NativeType::Function
@@ -65,7 +66,7 @@ pub fn needs_unwrap(rv: NativeType) -> bool {
)
}
-fn is_i64(rv: NativeType) -> bool {
+fn is_i64(rv: &NativeType) -> bool {
matches!(rv, NativeType::I64 | NativeType::ISize)
}
@@ -166,7 +167,7 @@ where
.clone()
.into_iter()
.map(libffi::middle::Type::from),
- foreign_fn.result.into(),
+ foreign_fn.result.clone().into(),
);
let func_key = v8::String::new(scope, &symbol_key).unwrap();
@@ -216,11 +217,24 @@ fn make_sync_fn<'s>(
// SAFETY: The pointer will not be deallocated until the function is
// garbage collected.
let symbol = unsafe { &*(external.value() as *const Symbol) };
- let needs_unwrap = match needs_unwrap(symbol.result_type) {
+ let needs_unwrap = match needs_unwrap(&symbol.result_type) {
true => Some(args.get(symbol.parameter_types.len() as i32)),
false => None,
};
- match crate::call::ffi_call_sync(scope, args, symbol) {
+ let out_buffer = match symbol.result_type {
+ NativeType::Struct(_) => {
+ let argc = args.length();
+ out_buffer_as_ptr(
+ scope,
+ Some(
+ v8::Local::<v8::TypedArray>::try_from(args.get(argc - 1))
+ .unwrap(),
+ ),
+ )
+ }
+ _ => None,
+ };
+ match crate::call::ffi_call_sync(scope, args, symbol, out_buffer) {
Ok(result) => {
match needs_unwrap {
Some(v) => {
@@ -228,7 +242,7 @@ fn make_sync_fn<'s>(
let backing_store =
view.buffer(scope).unwrap().get_backing_store();
- if is_i64(symbol.result_type) {
+ if is_i64(&symbol.result_type) {
// SAFETY: v8::SharedRef<v8::BackingStore> is similar to Arc<[u8]>,
// it points to a fixed continuous slice of bytes on the heap.
let bs = unsafe {
@@ -251,8 +265,9 @@ fn make_sync_fn<'s>(
}
}
None => {
- // SAFETY: Same return type declared to libffi; trust user to have it right beyond that.
- let result = unsafe { result.to_v8(scope, symbol.result_type) };
+ let result =
+ // SAFETY: Same return type declared to libffi; trust user to have it right beyond that.
+ unsafe { result.to_v8(scope, symbol.result_type.clone()) };
rv.set(result.v8_value);
}
}