mirror of
https://github.com/denoland/deno.git
synced 2024-11-28 16:20:57 -05:00
feat(ext/ffi): Support 64 bit parameters in Fast API calls (#15140)
Co-authored-by: Divy Srivastava <dj.srivastava23@gmail.com>
This commit is contained in:
parent
77d065e034
commit
d725cb28ca
6 changed files with 51 additions and 11 deletions
|
@ -22,6 +22,10 @@ fn native_arg_to_c(ty: &NativeType) -> &'static str {
|
||||||
match ty {
|
match ty {
|
||||||
NativeType::U8 | NativeType::U16 | NativeType::U32 => "uint32_t",
|
NativeType::U8 | NativeType::U16 | NativeType::U32 => "uint32_t",
|
||||||
NativeType::I8 | NativeType::I16 | NativeType::I32 => "int32_t",
|
NativeType::I8 | NativeType::I16 | NativeType::I32 => "int32_t",
|
||||||
|
NativeType::U64
|
||||||
|
| NativeType::I64
|
||||||
|
| NativeType::USize
|
||||||
|
| NativeType::ISize => "uint64_t",
|
||||||
NativeType::Void => "void",
|
NativeType::Void => "void",
|
||||||
NativeType::F32 => "float",
|
NativeType::F32 => "float",
|
||||||
NativeType::F64 => "double",
|
NativeType::F64 => "double",
|
||||||
|
@ -40,6 +44,8 @@ fn native_to_c(ty: &NativeType) -> &'static str {
|
||||||
NativeType::Void => "void",
|
NativeType::Void => "void",
|
||||||
NativeType::F32 => "float",
|
NativeType::F32 => "float",
|
||||||
NativeType::F64 => "double",
|
NativeType::F64 => "double",
|
||||||
|
NativeType::U64 | NativeType::USize => "uint64_t",
|
||||||
|
NativeType::I64 | NativeType::ISize => "int64_t",
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -148,6 +154,14 @@ mod tests {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
codegen(vec![NativeType::I8, NativeType::U8], NativeType::I8),
|
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"
|
"#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"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -673,12 +673,11 @@ impl From<&NativeType> for fast_api::Type {
|
||||||
NativeType::F32 => fast_api::Type::Float32,
|
NativeType::F32 => fast_api::Type::Float32,
|
||||||
NativeType::F64 => fast_api::Type::Float64,
|
NativeType::F64 => fast_api::Type::Float64,
|
||||||
NativeType::Void => fast_api::Type::Void,
|
NativeType::Void => fast_api::Type::Void,
|
||||||
NativeType::Function
|
NativeType::I64
|
||||||
| NativeType::Pointer
|
|
||||||
| NativeType::I64
|
|
||||||
| NativeType::ISize
|
| NativeType::ISize
|
||||||
| NativeType::U64
|
| NativeType::U64
|
||||||
| NativeType::USize => {
|
| NativeType::USize => fast_api::Type::Uint64,
|
||||||
|
NativeType::Function | NativeType::Pointer => {
|
||||||
panic!("Cannot be fast api")
|
panic!("Cannot be fast api")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -686,7 +685,7 @@ impl From<&NativeType> for fast_api::Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
fn is_fast_api(rv: NativeType) -> bool {
|
fn is_fast_api_rv(rv: NativeType) -> bool {
|
||||||
!matches!(
|
!matches!(
|
||||||
rv,
|
rv,
|
||||||
NativeType::Function
|
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
|
// Create a JavaScript function for synchronous FFI call to
|
||||||
// the given symbol.
|
// the given symbol.
|
||||||
fn make_sync_fn<'s>(
|
fn make_sync_fn<'s>(
|
||||||
|
@ -714,8 +718,8 @@ fn make_sync_fn<'s>(
|
||||||
let mut fast_allocations: Option<*mut ()> = None;
|
let mut fast_allocations: Option<*mut ()> = None;
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
if !sym.can_callback
|
if !sym.can_callback
|
||||||
&& !sym.parameter_types.iter().any(|t| !is_fast_api(*t))
|
&& !sym.parameter_types.iter().any(|t| !is_fast_api_arg(*t))
|
||||||
&& is_fast_api(sym.result_type)
|
&& is_fast_api_rv(sym.result_type)
|
||||||
{
|
{
|
||||||
let ret = fast_api::Type::from(&sym.result_type);
|
let ret = fast_api::Type::from(&sym.result_type);
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,11 @@ pub extern "C" fn add_usize(a: usize, b: usize) -> usize {
|
||||||
a + b
|
a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub extern "C" fn add_usize_fast(a: usize, b: usize) -> u32 {
|
||||||
|
(a + b) as u32
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn add_isize(a: isize, b: isize) -> isize {
|
pub extern "C" fn add_isize(a: isize, b: isize) -> isize {
|
||||||
a + b
|
a + b
|
||||||
|
|
|
@ -272,12 +272,20 @@ Deno.bench("nop_i64()", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const { nop_usize } = dylib.symbols;
|
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);
|
nop_usize(100n);
|
||||||
});
|
});
|
||||||
|
|
||||||
const { nop_isize } = dylib.symbols;
|
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);
|
nop_isize(100n);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,8 @@ fn basic() {
|
||||||
true\n\
|
true\n\
|
||||||
579\n\
|
579\n\
|
||||||
579\n\
|
579\n\
|
||||||
|
5\n\
|
||||||
|
5\n\
|
||||||
579\n\
|
579\n\
|
||||||
8589934590n\n\
|
8589934590n\n\
|
||||||
-8589934590n\n\
|
-8589934590n\n\
|
||||||
|
|
|
@ -55,6 +55,7 @@ const dylib = Deno.dlopen(libPath, {
|
||||||
"add_u64": { parameters: ["u64", "u64"], result: "u64" },
|
"add_u64": { parameters: ["u64", "u64"], result: "u64" },
|
||||||
"add_i64": { parameters: ["i64", "i64"], result: "i64" },
|
"add_i64": { parameters: ["i64", "i64"], result: "i64" },
|
||||||
"add_usize": { parameters: ["usize", "usize"], result: "usize" },
|
"add_usize": { parameters: ["usize", "usize"], result: "usize" },
|
||||||
|
"add_usize_fast": { parameters: ["usize", "usize"], result: "u32" },
|
||||||
"add_isize": { parameters: ["isize", "isize"], result: "isize" },
|
"add_isize": { parameters: ["isize", "isize"], result: "isize" },
|
||||||
"add_f32": { parameters: ["f32", "f32"], result: "f32" },
|
"add_f32": { parameters: ["f32", "f32"], result: "f32" },
|
||||||
"add_f64": { parameters: ["f64", "f64"], result: "f64" },
|
"add_f64": { parameters: ["f64", "f64"], result: "f64" },
|
||||||
|
@ -241,7 +242,7 @@ const before = performance.now();
|
||||||
await sleepNonBlocking.call(100);
|
await sleepNonBlocking.call(100);
|
||||||
console.log(performance.now() - before >= 100);
|
console.log(performance.now() - before >= 100);
|
||||||
|
|
||||||
const { add_u32 } = symbols;
|
const { add_u32, add_usize_fast } = symbols;
|
||||||
function addU32Fast(a, b) {
|
function addU32Fast(a, b) {
|
||||||
return add_u32(a, b);
|
return add_u32(a, b);
|
||||||
};
|
};
|
||||||
|
@ -251,6 +252,12 @@ console.log(addU32Fast(123, 456));
|
||||||
%OptimizeFunctionOnNextCall(addU32Fast);
|
%OptimizeFunctionOnNextCall(addU32Fast);
|
||||||
console.log(addU32Fast(123, 456));
|
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_i32(123, 456));
|
||||||
console.log(dylib.symbols.add_u64(0xffffffffn, 0xffffffffn));
|
console.log(dylib.symbols.add_u64(0xffffffffn, 0xffffffffn));
|
||||||
console.log(dylib.symbols.add_i64(-0xffffffffn, -0xffffffffn));
|
console.log(dylib.symbols.add_i64(-0xffffffffn, -0xffffffffn));
|
||||||
|
|
Loading…
Reference in a new issue