diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-07-12 06:33:05 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-12 06:33:05 +0530 |
commit | 77d065e034db7ed21a0e110bbbfc5eb5287d009c (patch) | |
tree | 4f2ad3195f2f4d52b69432fcc5bf72496c0eaf6a /ext/ffi/lib.rs | |
parent | 5db16d122914336124620a5152655917e58f05a6 (diff) |
fix(ext/ffi): trampoline for fast calls (#15139)
Diffstat (limited to 'ext/ffi/lib.rs')
-rw-r--r-- | ext/ffi/lib.rs | 39 |
1 files changed, 32 insertions, 7 deletions
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index a5a156727..feb879aba 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -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); + } + } }), ); |