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:
parent
3da182b0b8
commit
132c761e87
4 changed files with 21 additions and 3 deletions
2
cli/dts/lib.deno.unstable.d.ts
vendored
2
cli/dts/lib.deno.unstable.d.ts
vendored
|
@ -430,6 +430,8 @@ declare namespace Deno {
|
||||||
result: Result;
|
result: Result;
|
||||||
/** When true, function calls will run on a dedicated blocking thread and will return a Promise resolving to the `result`. */
|
/** When true, function calls will run on a dedicated blocking thread and will return a Promise resolving to the `result`. */
|
||||||
nonblocking?: NonBlocking;
|
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> {
|
export interface ForeignStatic<Type extends NativeType = NativeType> {
|
||||||
|
|
|
@ -72,6 +72,7 @@ struct Symbol {
|
||||||
ptr: libffi::middle::CodePtr,
|
ptr: libffi::middle::CodePtr,
|
||||||
parameter_types: Vec<NativeType>,
|
parameter_types: Vec<NativeType>,
|
||||||
result_type: NativeType,
|
result_type: NativeType,
|
||||||
|
can_callback: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::non_send_fields_in_send_ty)]
|
#[allow(clippy::non_send_fields_in_send_ty)]
|
||||||
|
@ -433,6 +434,13 @@ struct ForeignFunction {
|
||||||
result: NativeType,
|
result: NativeType,
|
||||||
#[serde(rename = "nonblocking")]
|
#[serde(rename = "nonblocking")]
|
||||||
non_blocking: Option<bool>,
|
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
|
// ForeignStatic's name and type fields are read and used by
|
||||||
|
@ -599,6 +607,7 @@ where
|
||||||
ptr,
|
ptr,
|
||||||
parameter_types: foreign_fn.parameters,
|
parameter_types: foreign_fn.parameters,
|
||||||
result_type: foreign_fn.result,
|
result_type: foreign_fn.result,
|
||||||
|
can_callback: foreign_fn.callback,
|
||||||
});
|
});
|
||||||
|
|
||||||
resource.symbols.insert(symbol_key, sym.clone());
|
resource.symbols.insert(symbol_key, sym.clone());
|
||||||
|
@ -689,7 +698,8 @@ fn make_sync_fn<'s>(
|
||||||
) -> v8::Local<'s, v8::Function> {
|
) -> v8::Local<'s, v8::Function> {
|
||||||
let mut fast_ffi_templ = None;
|
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)
|
&& is_fast_api(sym.result_type)
|
||||||
{
|
{
|
||||||
let mut args = sym
|
let mut args = sym
|
||||||
|
@ -941,6 +951,7 @@ where
|
||||||
result_type,
|
result_type,
|
||||||
cif,
|
cif,
|
||||||
ptr: fun_ptr,
|
ptr: fun_ptr,
|
||||||
|
..
|
||||||
} = symbol;
|
} = symbol;
|
||||||
let mut ffi_args: Vec<NativeValue> =
|
let mut ffi_args: Vec<NativeValue> =
|
||||||
Vec::with_capacity(parameter_types.len());
|
Vec::with_capacity(parameter_types.len());
|
||||||
|
@ -1814,6 +1825,7 @@ fn op_ffi_call_nonblocking<'scope>(
|
||||||
ptr,
|
ptr,
|
||||||
parameter_types,
|
parameter_types,
|
||||||
result_type,
|
result_type,
|
||||||
|
..
|
||||||
} = symbol.clone();
|
} = symbol.clone();
|
||||||
ffi_call(call_args, &cif, ptr, ¶meter_types, result_type)
|
ffi_call(call_args, &cif, ptr, ¶meter_types, result_type)
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
const remote = Deno.dlopen(
|
const remote = Deno.dlopen(
|
||||||
"dummy_lib.so",
|
"dummy_lib.so",
|
||||||
{
|
{
|
||||||
method1: { parameters: ["usize", "usize"], result: "void" },
|
method1: { parameters: ["usize", "usize"], result: "void", callback: true },
|
||||||
method2: { parameters: [], result: "void" },
|
method2: { parameters: [], result: "void" },
|
||||||
method3: { parameters: ["usize"], result: "void" },
|
method3: { parameters: ["usize"], result: "void" },
|
||||||
method4: { parameters: ["isize"], result: "void" },
|
method4: { parameters: ["isize"], result: "void" },
|
||||||
|
|
|
@ -164,10 +164,12 @@ const dylib = Deno.dlopen(libPath, {
|
||||||
call_stored_function: {
|
call_stored_function: {
|
||||||
parameters: [],
|
parameters: [],
|
||||||
result: "void",
|
result: "void",
|
||||||
|
callback: true,
|
||||||
},
|
},
|
||||||
call_stored_function_2: {
|
call_stored_function_2: {
|
||||||
parameters: ["u8"],
|
parameters: ["u8"],
|
||||||
result: "void",
|
result: "void",
|
||||||
|
callback: true,
|
||||||
},
|
},
|
||||||
// Statics
|
// Statics
|
||||||
"static_u32": {
|
"static_u32": {
|
||||||
|
@ -372,12 +374,14 @@ assertThrows(
|
||||||
"hi",
|
"hi",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const { call_stored_function } = dylib.symbols;
|
||||||
|
|
||||||
dylib.symbols.call_fn_ptr(ptr(logCallback));
|
dylib.symbols.call_fn_ptr(ptr(logCallback));
|
||||||
dylib.symbols.call_fn_ptr_many_parameters(ptr(logManyParametersCallback));
|
dylib.symbols.call_fn_ptr_many_parameters(ptr(logManyParametersCallback));
|
||||||
dylib.symbols.call_fn_ptr_return_u8(ptr(returnU8Callback));
|
dylib.symbols.call_fn_ptr_return_u8(ptr(returnU8Callback));
|
||||||
dylib.symbols.call_fn_ptr_return_buffer(ptr(returnBufferCallback));
|
dylib.symbols.call_fn_ptr_return_buffer(ptr(returnBufferCallback));
|
||||||
dylib.symbols.store_function(ptr(logCallback));
|
dylib.symbols.store_function(ptr(logCallback));
|
||||||
dylib.symbols.call_stored_function();
|
call_stored_function();
|
||||||
dylib.symbols.store_function_2(ptr(add10Callback));
|
dylib.symbols.store_function_2(ptr(add10Callback));
|
||||||
dylib.symbols.call_stored_function_2(20);
|
dylib.symbols.call_stored_function_2(20);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue