mirror of
https://github.com/denoland/deno.git
synced 2025-10-02 15:14:33 +00:00
fix(ext/ffi): trampoline for fast calls (#15139)
This commit is contained in:
parent
5db16d1229
commit
77d065e034
11 changed files with 435 additions and 11 deletions
|
@ -39,6 +39,11 @@ use std::path::PathBuf;
|
|||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
mod jit_trampoline;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
mod tcc;
|
||||
|
||||
thread_local! {
|
||||
static LOCAL_ISOLATE_POINTER: RefCell<*const v8::Isolate> = RefCell::new(ptr::null());
|
||||
}
|
||||
|
@ -72,6 +77,8 @@ struct Symbol {
|
|||
ptr: libffi::middle::CodePtr,
|
||||
parameter_types: Vec<NativeType>,
|
||||
result_type: NativeType,
|
||||
// This is dead code only on Windows
|
||||
#[allow(dead_code)]
|
||||
can_callback: bool,
|
||||
}
|
||||
|
||||
|
@ -678,6 +685,7 @@ impl From<&NativeType> for fast_api::Type {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
fn is_fast_api(rv: NativeType) -> bool {
|
||||
!matches!(
|
||||
rv,
|
||||
|
@ -696,25 +704,36 @@ fn make_sync_fn<'s>(
|
|||
scope: &mut v8::HandleScope<'s>,
|
||||
sym: Box<Symbol>,
|
||||
) -> v8::Local<'s, v8::Function> {
|
||||
let mut fast_ffi_templ = None;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let mut fast_ffi_templ: Option<FfiFastCallTemplate> = None;
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
let fast_ffi_templ: Option<FfiFastCallTemplate> = None;
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let mut fast_allocations: Option<*mut ()> = None;
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
if !sym.can_callback
|
||||
&& !sym.parameter_types.iter().any(|t| !is_fast_api(*t))
|
||||
&& is_fast_api(sym.result_type)
|
||||
{
|
||||
let ret = fast_api::Type::from(&sym.result_type);
|
||||
|
||||
let mut args = sym
|
||||
.parameter_types
|
||||
.iter()
|
||||
.map(|t| t.into())
|
||||
.collect::<Vec<_>>();
|
||||
if args.is_empty() {
|
||||
args.push(fast_api::Type::V8Value);
|
||||
}
|
||||
// recv
|
||||
args.insert(0, fast_api::Type::V8Value);
|
||||
let symbol_trampoline =
|
||||
jit_trampoline::gen_trampoline(sym.clone()).expect("gen_trampoline");
|
||||
fast_ffi_templ = Some(FfiFastCallTemplate {
|
||||
args: args.into_boxed_slice(),
|
||||
ret: (&fast_api::Type::from(&sym.result_type)).into(),
|
||||
symbol_ptr: sym.ptr.as_ptr() as *const c_void,
|
||||
ret: (&ret).into(),
|
||||
symbol_ptr: symbol_trampoline.addr,
|
||||
});
|
||||
fast_allocations = Some(Box::into_raw(symbol_trampoline) as *mut ());
|
||||
}
|
||||
|
||||
let sym = Box::leak(sym);
|
||||
|
@ -754,7 +773,13 @@ fn make_sync_fn<'s>(
|
|||
Box::new(move |_| {
|
||||
// SAFETY: This is never called twice. pointer obtained
|
||||
// from Box::into_raw, hence, satisfies memory layout requirements.
|
||||
unsafe { Box::from_raw(sym) };
|
||||
unsafe {
|
||||
Box::from_raw(sym);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
if let Some(fast_allocations) = fast_allocations {
|
||||
Box::from_raw(fast_allocations as *mut jit_trampoline::Allocation);
|
||||
}
|
||||
}
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue