mirror of
https://github.com/denoland/deno.git
synced 2024-12-22 15:24:46 -05:00
53606de634
The mixed `number | bigint` representation was useful optimization for pointers. Now, pointers are represented as V8 externals. As part of the FFI stabilization effort we want to make `bigint` the only representation for `u64` and `i64`. BigInt representation performance is almost on par with mixed representation with the added benefit that its less confusing and users don't need manual checks and conversions for doing operations on the value. ``` cpu: AMD Ryzen 5 7530U with Radeon Graphics runtime: deno 1.43.6+92a8d09 (x86_64-unknown-linux-gnu) file:///home/divy/gh/ffi/main.ts benchmark time (avg) iter/s (min … max) p75 p99 p995 -------------------------------------------------------------------------- ----------------------------- nop 4.01 ns/iter 249,533,690.5 (3.97 ns … 10.8 ns) 3.97 ns 4.36 ns 9.03 ns ret bigint 7.74 ns/iter 129,127,186.8 (7.72 ns … 10.46 ns) 7.72 ns 8.11 ns 8.82 ns ret i32 7.81 ns/iter 128,087,100.5 (7.77 ns … 12.72 ns) 7.78 ns 8.57 ns 9.75 ns ret bigint (add op) 15.02 ns/iter 66,588,253.2 (14.64 ns … 24.99 ns) 14.76 ns 19.13 ns 19.44 ns ret i32 (add op) 12.02 ns/iter 83,209,131.8 (11.95 ns … 18.18 ns) 11.98 ns 13.11 ns 14.5 ns ```
91 lines
2.2 KiB
Rust
91 lines
2.2 KiB
Rust
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
|
|
|
|
use deno_core::error::AnyError;
|
|
use deno_core::OpState;
|
|
|
|
use std::mem::size_of;
|
|
use std::os::raw::c_char;
|
|
use std::os::raw::c_short;
|
|
use std::path::Path;
|
|
|
|
mod call;
|
|
mod callback;
|
|
mod dlfcn;
|
|
mod ir;
|
|
mod repr;
|
|
mod r#static;
|
|
mod symbol;
|
|
mod turbocall;
|
|
|
|
use call::op_ffi_call_nonblocking;
|
|
use call::op_ffi_call_ptr;
|
|
use call::op_ffi_call_ptr_nonblocking;
|
|
use callback::op_ffi_unsafe_callback_close;
|
|
use callback::op_ffi_unsafe_callback_create;
|
|
use callback::op_ffi_unsafe_callback_ref;
|
|
use dlfcn::op_ffi_load;
|
|
use dlfcn::ForeignFunction;
|
|
use r#static::op_ffi_get_static;
|
|
use repr::*;
|
|
use symbol::NativeType;
|
|
use symbol::Symbol;
|
|
|
|
#[cfg(not(target_pointer_width = "64"))]
|
|
compile_error!("platform not supported");
|
|
|
|
const _: () = {
|
|
assert!(size_of::<c_char>() == 1);
|
|
assert!(size_of::<c_short>() == 2);
|
|
assert!(size_of::<*const ()>() == 8);
|
|
};
|
|
|
|
pub const UNSTABLE_FEATURE_NAME: &str = "ffi";
|
|
|
|
fn check_unstable(state: &OpState, api_name: &str) {
|
|
// TODO(bartlomieju): replace with `state.feature_checker.check_or_exit`
|
|
// once we phase out `check_or_exit_with_legacy_fallback`
|
|
state
|
|
.feature_checker
|
|
.check_or_exit_with_legacy_fallback(UNSTABLE_FEATURE_NAME, api_name)
|
|
}
|
|
|
|
pub trait FfiPermissions {
|
|
fn check_partial(&mut self, path: Option<&Path>) -> Result<(), AnyError>;
|
|
}
|
|
|
|
deno_core::extension!(deno_ffi,
|
|
deps = [ deno_web ],
|
|
parameters = [P: FfiPermissions],
|
|
ops = [
|
|
op_ffi_load<P>,
|
|
op_ffi_get_static,
|
|
op_ffi_call_nonblocking,
|
|
op_ffi_call_ptr<P>,
|
|
op_ffi_call_ptr_nonblocking<P>,
|
|
op_ffi_ptr_create<P>,
|
|
op_ffi_ptr_equals<P>,
|
|
op_ffi_ptr_of<P>,
|
|
op_ffi_ptr_of_exact<P>,
|
|
op_ffi_ptr_offset<P>,
|
|
op_ffi_ptr_value<P>,
|
|
op_ffi_get_buf<P>,
|
|
op_ffi_buf_copy_into<P>,
|
|
op_ffi_cstr_read<P>,
|
|
op_ffi_read_bool<P>,
|
|
op_ffi_read_u8<P>,
|
|
op_ffi_read_i8<P>,
|
|
op_ffi_read_u16<P>,
|
|
op_ffi_read_i16<P>,
|
|
op_ffi_read_u32<P>,
|
|
op_ffi_read_i32<P>,
|
|
op_ffi_read_u64<P>,
|
|
op_ffi_read_i64<P>,
|
|
op_ffi_read_f32<P>,
|
|
op_ffi_read_f64<P>,
|
|
op_ffi_read_ptr<P>,
|
|
op_ffi_unsafe_callback_create<P>,
|
|
op_ffi_unsafe_callback_close,
|
|
op_ffi_unsafe_callback_ref,
|
|
],
|
|
esm = [ "00_ffi.js" ],
|
|
);
|