1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-11 08:33:43 -05:00

fix(ext/ffi): allow opting out of fast ffi calls (#15131)

This commit is contained in:
Divy Srivastava 2022-07-09 18:41:07 +05:30 committed by GitHub
parent 3da182b0b8
commit 132c761e87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 21 additions and 3 deletions

View file

@ -430,6 +430,8 @@ declare namespace Deno {
result: Result;
/** When true, function calls will run on a dedicated blocking thread and will return a Promise resolving to the `result`. */
nonblocking?: NonBlocking;
/** When true, function calls can safely callback into JS or trigger a GC event. Default is `false`. */
callback?: boolean;
}
export interface ForeignStatic<Type extends NativeType = NativeType> {

View file

@ -72,6 +72,7 @@ struct Symbol {
ptr: libffi::middle::CodePtr,
parameter_types: Vec<NativeType>,
result_type: NativeType,
can_callback: bool,
}
#[allow(clippy::non_send_fields_in_send_ty)]
@ -433,6 +434,13 @@ struct ForeignFunction {
result: NativeType,
#[serde(rename = "nonblocking")]
non_blocking: Option<bool>,
#[serde(rename = "callback")]
#[serde(default = "default_callback")]
callback: bool,
}
fn default_callback() -> bool {
false
}
// ForeignStatic's name and type fields are read and used by
@ -599,6 +607,7 @@ where
ptr,
parameter_types: foreign_fn.parameters,
result_type: foreign_fn.result,
can_callback: foreign_fn.callback,
});
resource.symbols.insert(symbol_key, sym.clone());
@ -689,7 +698,8 @@ fn make_sync_fn<'s>(
) -> v8::Local<'s, v8::Function> {
let mut fast_ffi_templ = None;
if !sym.parameter_types.iter().any(|t| !is_fast_api(*t))
if !sym.can_callback
&& !sym.parameter_types.iter().any(|t| !is_fast_api(*t))
&& is_fast_api(sym.result_type)
{
let mut args = sym
@ -941,6 +951,7 @@ where
result_type,
cif,
ptr: fun_ptr,
..
} = symbol;
let mut ffi_args: Vec<NativeValue> =
Vec::with_capacity(parameter_types.len());
@ -1814,6 +1825,7 @@ fn op_ffi_call_nonblocking<'scope>(
ptr,
parameter_types,
result_type,
..
} = symbol.clone();
ffi_call(call_args, &cif, ptr, &parameter_types, result_type)
});

View file

@ -5,7 +5,7 @@
const remote = Deno.dlopen(
"dummy_lib.so",
{
method1: { parameters: ["usize", "usize"], result: "void" },
method1: { parameters: ["usize", "usize"], result: "void", callback: true },
method2: { parameters: [], result: "void" },
method3: { parameters: ["usize"], result: "void" },
method4: { parameters: ["isize"], result: "void" },

View file

@ -164,10 +164,12 @@ const dylib = Deno.dlopen(libPath, {
call_stored_function: {
parameters: [],
result: "void",
callback: true,
},
call_stored_function_2: {
parameters: ["u8"],
result: "void",
callback: true,
},
// Statics
"static_u32": {
@ -372,12 +374,14 @@ assertThrows(
"hi",
);
const { call_stored_function } = dylib.symbols;
dylib.symbols.call_fn_ptr(ptr(logCallback));
dylib.symbols.call_fn_ptr_many_parameters(ptr(logManyParametersCallback));
dylib.symbols.call_fn_ptr_return_u8(ptr(returnU8Callback));
dylib.symbols.call_fn_ptr_return_buffer(ptr(returnBufferCallback));
dylib.symbols.store_function(ptr(logCallback));
dylib.symbols.call_stored_function();
call_stored_function();
dylib.symbols.store_function_2(ptr(add10Callback));
dylib.symbols.call_stored_function_2(20);