diff options
author | Aapo Alasuutari <aapo.alasuutari@gmail.com> | 2022-07-12 05:50:20 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-12 08:20:20 +0530 |
commit | d725cb28ca353b55a575856a76b11630be575ec1 (patch) | |
tree | e4bb20981bdf5c77f258053930b42b0babc0650c | |
parent | 77d065e034db7ed21a0e110bbbfc5eb5287d009c (diff) |
feat(ext/ffi): Support 64 bit parameters in Fast API calls (#15140)
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
-rw-r--r-- | ext/ffi/jit_trampoline.rs | 16 | ||||
-rw-r--r-- | ext/ffi/lib.rs | 18 | ||||
-rw-r--r-- | test_ffi/src/lib.rs | 5 | ||||
-rw-r--r-- | test_ffi/tests/bench.js | 12 | ||||
-rw-r--r-- | test_ffi/tests/integration_tests.rs | 2 | ||||
-rw-r--r-- | test_ffi/tests/test.js | 9 |
6 files changed, 51 insertions, 11 deletions
diff --git a/ext/ffi/jit_trampoline.rs b/ext/ffi/jit_trampoline.rs index 40c14dfb0..2c3c519c0 100644 --- a/ext/ffi/jit_trampoline.rs +++ b/ext/ffi/jit_trampoline.rs @@ -22,6 +22,10 @@ fn native_arg_to_c(ty: &NativeType) -> &'static str { match ty { NativeType::U8 | NativeType::U16 | NativeType::U32 => "uint32_t", NativeType::I8 | NativeType::I16 | NativeType::I32 => "int32_t", + NativeType::U64 + | NativeType::I64 + | NativeType::USize + | NativeType::ISize => "uint64_t", NativeType::Void => "void", NativeType::F32 => "float", NativeType::F64 => "double", @@ -40,6 +44,8 @@ fn native_to_c(ty: &NativeType) -> &'static str { NativeType::Void => "void", NativeType::F32 => "float", NativeType::F64 => "double", + NativeType::U64 | NativeType::USize => "uint64_t", + NativeType::I64 | NativeType::ISize => "int64_t", _ => unimplemented!(), } } @@ -148,6 +154,14 @@ mod tests { assert_eq!( codegen(vec![NativeType::I8, NativeType::U8], NativeType::I8), "#include <stdint.h>\n\nextern int8_t func(int8_t p0, uint8_t p1);\n\nint8_t func_trampoline(void* recv, int32_t p0, uint32_t p1) {\n return func(p0, p1);\n}\n\n" - ) + ); + assert_eq!( + codegen(vec![NativeType::ISize, NativeType::U64], NativeType::Void), + "#include <stdint.h>\n\nextern void func(int64_t p0, uint64_t p1);\n\nvoid func_trampoline(void* recv, uint64_t p0, uint64_t p1) {\n return func(p0, p1);\n}\n\n" + ); + assert_eq!( + codegen(vec![NativeType::USize, NativeType::USize], NativeType::U32), + "#include <stdint.h>\n\nextern uint32_t func(uint64_t p0, uint64_t p1);\n\nuint32_t func_trampoline(void* recv, uint64_t p0, uint64_t p1) {\n return func(p0, p1);\n}\n\n" + ); } } diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index feb879aba..eddfed039 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -673,12 +673,11 @@ impl From<&NativeType> for fast_api::Type { NativeType::F32 => fast_api::Type::Float32, NativeType::F64 => fast_api::Type::Float64, NativeType::Void => fast_api::Type::Void, - NativeType::Function - | NativeType::Pointer - | NativeType::I64 + NativeType::I64 | NativeType::ISize | NativeType::U64 - | NativeType::USize => { + | NativeType::USize => fast_api::Type::Uint64, + NativeType::Function | NativeType::Pointer => { panic!("Cannot be fast api") } } @@ -686,7 +685,7 @@ impl From<&NativeType> for fast_api::Type { } #[cfg(not(target_os = "windows"))] -fn is_fast_api(rv: NativeType) -> bool { +fn is_fast_api_rv(rv: NativeType) -> bool { !matches!( rv, NativeType::Function @@ -698,6 +697,11 @@ fn is_fast_api(rv: NativeType) -> bool { ) } +#[cfg(not(target_os = "windows"))] +fn is_fast_api_arg(rv: NativeType) -> bool { + !matches!(rv, NativeType::Function | NativeType::Pointer) +} + // Create a JavaScript function for synchronous FFI call to // the given symbol. fn make_sync_fn<'s>( @@ -714,8 +718,8 @@ fn make_sync_fn<'s>( 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) + && !sym.parameter_types.iter().any(|t| !is_fast_api_arg(*t)) + && is_fast_api_rv(sym.result_type) { let ret = fast_api::Type::from(&sym.result_type); diff --git a/test_ffi/src/lib.rs b/test_ffi/src/lib.rs index 257a47368..cde914c22 100644 --- a/test_ffi/src/lib.rs +++ b/test_ffi/src/lib.rs @@ -75,6 +75,11 @@ pub extern "C" fn add_usize(a: usize, b: usize) -> usize { } #[no_mangle] +pub extern "C" fn add_usize_fast(a: usize, b: usize) -> u32 { + (a + b) as u32 +} + +#[no_mangle] pub extern "C" fn add_isize(a: isize, b: isize) -> isize { a + b } diff --git a/test_ffi/tests/bench.js b/test_ffi/tests/bench.js index e611d9f3c..54a9e0acc 100644 --- a/test_ffi/tests/bench.js +++ b/test_ffi/tests/bench.js @@ -272,12 +272,20 @@ Deno.bench("nop_i64()", () => { }); const { nop_usize } = dylib.symbols; -Deno.bench("nop_usize()", () => { +Deno.bench("nop_usize() number", () => { + nop_usize(100); +}); + +Deno.bench("nop_usize() bigint", () => { nop_usize(100n); }); const { nop_isize } = dylib.symbols; -Deno.bench("nop_isize()", () => { +Deno.bench("nop_isize() number", () => { + nop_isize(100); +}); + +Deno.bench("nop_isize() bigint", () => { nop_isize(100n); }); diff --git a/test_ffi/tests/integration_tests.rs b/test_ffi/tests/integration_tests.rs index 4982ffad5..26de8ce0d 100644 --- a/test_ffi/tests/integration_tests.rs +++ b/test_ffi/tests/integration_tests.rs @@ -63,6 +63,8 @@ fn basic() { true\n\ 579\n\ 579\n\ + 5\n\ + 5\n\ 579\n\ 8589934590n\n\ -8589934590n\n\ diff --git a/test_ffi/tests/test.js b/test_ffi/tests/test.js index 4e05be3ed..ff81f302e 100644 --- a/test_ffi/tests/test.js +++ b/test_ffi/tests/test.js @@ -55,6 +55,7 @@ const dylib = Deno.dlopen(libPath, { "add_u64": { parameters: ["u64", "u64"], result: "u64" }, "add_i64": { parameters: ["i64", "i64"], result: "i64" }, "add_usize": { parameters: ["usize", "usize"], result: "usize" }, + "add_usize_fast": { parameters: ["usize", "usize"], result: "u32" }, "add_isize": { parameters: ["isize", "isize"], result: "isize" }, "add_f32": { parameters: ["f32", "f32"], result: "f32" }, "add_f64": { parameters: ["f64", "f64"], result: "f64" }, @@ -241,7 +242,7 @@ const before = performance.now(); await sleepNonBlocking.call(100); console.log(performance.now() - before >= 100); -const { add_u32 } = symbols; +const { add_u32, add_usize_fast } = symbols; function addU32Fast(a, b) { return add_u32(a, b); }; @@ -251,6 +252,12 @@ console.log(addU32Fast(123, 456)); %OptimizeFunctionOnNextCall(addU32Fast); console.log(addU32Fast(123, 456)); +function addU64Fast(a, b) { return add_usize_fast(a, b); }; +%PrepareFunctionForOptimization(addU64Fast); +console.log(addU64Fast(2, 3)); +%OptimizeFunctionOnNextCall(addU64Fast); +console.log(addU64Fast(2, 3)); + console.log(dylib.symbols.add_i32(123, 456)); console.log(dylib.symbols.add_u64(0xffffffffn, 0xffffffffn)); console.log(dylib.symbols.add_i64(-0xffffffffn, -0xffffffffn)); |