summaryrefslogtreecommitdiff
path: root/ext/ffi/jit_trampoline.rs
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ffi/jit_trampoline.rs')
-rw-r--r--ext/ffi/jit_trampoline.rs263
1 files changed, 0 insertions, 263 deletions
diff --git a/ext/ffi/jit_trampoline.rs b/ext/ffi/jit_trampoline.rs
deleted file mode 100644
index 6cb8ec74c..000000000
--- a/ext/ffi/jit_trampoline.rs
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright 2018-2022 the Deno authors. All rights reserved. MIT license.
-
-use crate::NativeType;
-use crate::{tcc::Compiler, Symbol};
-use std::ffi::c_void;
-use std::ffi::CString;
-use std::fmt::Write as _;
-use std::mem::size_of;
-
-const _: () = assert!(size_of::<fn()>() == size_of::<usize>());
-
-pub(crate) struct Allocation {
- pub addr: *mut c_void,
- _ctx: Compiler,
- _sym: Box<Symbol>,
-}
-
-macro_rules! cstr {
- ($st:expr) => {
- &CString::new($st).unwrap()
- };
-}
-
-fn native_arg_to_c(ty: &NativeType) -> &'static str {
- match ty {
- NativeType::Bool => "bool",
- NativeType::U8 | NativeType::U16 | NativeType::U32 => "uint32_t",
- NativeType::I8 | NativeType::I16 | NativeType::I32 => "int32_t",
- NativeType::Void => "void",
- NativeType::F32 => "float",
- NativeType::F64 => "double",
- NativeType::U64 => "uint64_t",
- NativeType::I64 => "int64_t",
- NativeType::ISize => "intptr_t",
- NativeType::USize => "uintptr_t",
- NativeType::Buffer => "struct FastApiTypedArray*",
- NativeType::Function | NativeType::Pointer => "void*",
- }
-}
-
-fn native_to_c(ty: &NativeType) -> &'static str {
- match ty {
- NativeType::Bool => "bool",
- NativeType::U8 => "uint8_t",
- NativeType::U16 => "uint16_t",
- NativeType::U32 => "uint32_t",
- NativeType::I8 => "int8_t",
- NativeType::I16 => "uint16_t",
- NativeType::I32 => "int32_t",
- NativeType::Void => "void",
- NativeType::F32 => "float",
- NativeType::F64 => "double",
- NativeType::U64 => "uint64_t",
- NativeType::I64 => "int64_t",
- NativeType::ISize => "intptr_t",
- NativeType::USize => "uintptr_t",
- NativeType::Pointer | NativeType::Buffer | NativeType::Function => "void*",
- }
-}
-
-pub(crate) fn codegen(sym: &crate::Symbol) -> String {
- let mut c = String::from(include_str!("prelude.h"));
- let needs_unwrap = crate::needs_unwrap(sym.result_type);
-
- // Return type of the FFI call.
- let ffi_ret = native_to_c(&sym.result_type);
- // Return type of the trampoline.
- let ret = if needs_unwrap { "void" } else { ffi_ret };
-
- // extern <return_type> func(
- let _ = write!(c, "\nextern {ffi_ret} func(");
- // <param_type> p0, <param_type> p1, ...);
- for (i, ty) in sym.parameter_types.iter().enumerate() {
- if i > 0 {
- c += ", ";
- }
- c += native_to_c(ty);
- let _ = write!(c, " p{i}");
- }
- c += ");\n\n";
-
- // void* recv, <param_type> p0, <param_type> p1, ...);
- c += ret;
- c += " func_trampoline(";
- c += "void* recv";
- for (i, ty) in sym.parameter_types.iter().enumerate() {
- c += ", ";
- c += native_arg_to_c(ty);
- let _ = write!(c, " p{i}");
- }
- if needs_unwrap {
- let _ = write!(c, ", struct FastApiTypedArray* const p_ret");
- }
- c += ") {\n";
- // func(p0, p1, ...);
- let mut call_s = String::from("func(");
- {
- for (i, ty) in sym.parameter_types.iter().enumerate() {
- if i > 0 {
- call_s += ", ";
- }
- if matches!(ty, NativeType::Buffer) {
- let _ = write!(call_s, "p{i}->data");
- } else {
- let _ = write!(call_s, "p{i}");
- }
- }
- call_s += ");\n";
- }
- if needs_unwrap {
- // <return_type> r = func(p0, p1, ...);
- // ((<return_type>*)p_ret->data)[0] = r;
- let _ = write!(c, " {ffi_ret} r = {call_s}");
- let _ = writeln!(c, " (({ffi_ret}*)p_ret->data)[0] = r;");
- } else {
- // return func(p0, p1, ...);
- let _ = write!(c, " return {call_s}");
- }
- c += "}\n\n";
- c
-}
-
-pub(crate) fn gen_trampoline(
- sym: Box<crate::Symbol>,
-) -> Result<Box<Allocation>, ()> {
- let mut ctx = Compiler::new()?;
- ctx.set_options(cstr!("-nostdlib"));
- // SAFETY: symbol satisfies ABI requirement.
- unsafe { ctx.add_symbol(cstr!("func"), sym.ptr.0 as *const c_void) };
- let c = codegen(&sym);
- ctx.compile_string(cstr!(c))?;
- let alloc = Allocation {
- addr: ctx.relocate_and_get_symbol(cstr!("func_trampoline"))?,
- _ctx: ctx,
- _sym: sym,
- };
- Ok(Box::new(alloc))
-}
-
-#[cfg(test)]
-mod tests {
- use super::*;
- use libffi::middle::Type;
- use std::ptr::null_mut;
-
- fn codegen(parameters: Vec<NativeType>, ret: NativeType) -> String {
- let sym = Box::new(crate::Symbol {
- cif: libffi::middle::Cif::new(vec![], Type::void()),
- ptr: libffi::middle::CodePtr(null_mut()),
- parameter_types: parameters,
- result_type: ret,
- can_callback: false,
- });
- super::codegen(&sym)
- }
-
- const PRELUDE: &str = include_str!("prelude.h");
- fn assert_codegen(expected: String, actual: &str) {
- assert_eq!(expected, format!("{PRELUDE}\n{}", actual))
- }
-
- #[test]
- fn test_gen_trampoline() {
- assert_codegen(
- codegen(vec![], NativeType::Void),
- "extern void func();\n\n\
- void func_trampoline(void* recv) {\
- \n return func();\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::U32, NativeType::U32], NativeType::U32),
- "extern uint32_t func(uint32_t p0, uint32_t p1);\n\n\
- uint32_t func_trampoline(void* recv, uint32_t p0, uint32_t p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::I32, NativeType::I32], NativeType::I32),
- "extern int32_t func(int32_t p0, int32_t p1);\n\n\
- int32_t func_trampoline(void* recv, int32_t p0, int32_t p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::F32, NativeType::F32], NativeType::F32),
- "extern float func(float p0, float p1);\n\n\
- float func_trampoline(void* recv, float p0, float p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::F64, NativeType::F64], NativeType::F64),
- "extern double func(double p0, double p1);\n\n\
- double func_trampoline(void* recv, double p0, double p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::Buffer, NativeType::U32], NativeType::U32),
- "extern uint32_t func(void* p0, uint32_t p1);\n\n\
- uint32_t func_trampoline(void* recv, struct FastApiTypedArray* p0, uint32_t p1) {\
- \n return func(p0->data, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::Buffer, NativeType::Buffer], NativeType::U32),
- "extern uint32_t func(void* p0, void* p1);\n\n\
- uint32_t func_trampoline(void* recv, struct FastApiTypedArray* p0, struct FastApiTypedArray* p1) {\
- \n return func(p0->data, p1->data);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![], NativeType::U64),
- "extern uint64_t func();\n\n\
- void func_trampoline(void* recv, struct FastApiTypedArray* const p_ret) {\
- \n uint64_t r = func();\
- \n ((uint64_t*)p_ret->data)[0] = r;\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::Buffer, NativeType::Buffer], NativeType::U64),
- "extern uint64_t func(void* p0, void* p1);\n\n\
- void func_trampoline(void* recv, struct FastApiTypedArray* p0, struct FastApiTypedArray* p1, struct FastApiTypedArray* const p_ret) {\
- \n uint64_t r = func(p0->data, p1->data);\
- \n ((uint64_t*)p_ret->data)[0] = r;\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::Pointer, NativeType::Pointer], NativeType::U64),
- "extern uint64_t func(void* p0, void* p1);\n\n\
- void func_trampoline(void* recv, void* p0, void* p1, struct FastApiTypedArray* const p_ret) {\
- \n uint64_t r = func(p0, p1);\
- \n ((uint64_t*)p_ret->data)[0] = r;\n\
- }\n\n",
- );
- }
-
- #[test]
- fn test_gen_trampoline_implicit_cast() {
- assert_codegen(
- codegen(vec![NativeType::I8, NativeType::U8], NativeType::I8),
- "extern int8_t func(int8_t p0, uint8_t p1);\n\n\
- int8_t func_trampoline(void* recv, int32_t p0, uint32_t p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::ISize, NativeType::U64], NativeType::Void),
- "extern void func(intptr_t p0, uint64_t p1);\n\n\
- void func_trampoline(void* recv, intptr_t p0, uint64_t p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- assert_codegen(
- codegen(vec![NativeType::USize, NativeType::USize], NativeType::U32),
- "extern uint32_t func(uintptr_t p0, uintptr_t p1);\n\n\
- uint32_t func_trampoline(void* recv, uintptr_t p0, uintptr_t p1) {\
- \n return func(p0, p1);\n\
- }\n\n",
- );
- }
-}