0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-11-30 16:41:03 -05:00

New const evaluated FastFunction API (#1201)

This commit is contained in:
Divy Srivastava 2023-03-22 20:37:48 +05:30 committed by GitHub
parent 8e6b67a38b
commit 49c77327a6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 104 additions and 209 deletions

View file

@ -1,5 +1,3 @@
use std::os::raw::c_void;
fn main() { fn main() {
// Skip running benchmarks in debug or CI. // Skip running benchmarks in debug or CI.
if cfg!(debug_assertions) || std::env::var("CI").is_ok() { if cfg!(debug_assertions) || std::env::var("CI").is_ok() {
@ -67,19 +65,12 @@ fn main() {
fn fast_fn() -> i32 { fn fast_fn() -> i32 {
42 42
} }
pub struct FastCall; const FAST_CALL: v8::fast_api::FastFunction =
impl v8::fast_api::FastFunction for FastCall { v8::fast_api::FastFunction::new(
fn args(&self) -> &'static [v8::fast_api::Type] { &[v8::fast_api::Type::V8Value],
&[v8::fast_api::Type::V8Value] v8::fast_api::CType::Int32,
} fast_fn as _,
fn return_type(&self) -> v8::fast_api::CType { );
v8::fast_api::CType::Int32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
let template = v8::FunctionTemplate::builder( let template = v8::FunctionTemplate::builder(
|scope: &mut v8::HandleScope, |scope: &mut v8::HandleScope,
_: v8::FunctionCallbackArguments, _: v8::FunctionCallbackArguments,
@ -87,7 +78,7 @@ fn main() {
rv.set(v8::Integer::new(scope, 42).into()); rv.set(v8::Integer::new(scope, 42).into());
}, },
) )
.build_fast(scope, &FastCall, None, None, None); .build_fast(scope, &FAST_CALL, None, None, None);
let name = v8::String::new(scope, "new_fast").unwrap(); let name = v8::String::new(scope, "new_fast").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();

View file

@ -249,14 +249,23 @@ impl<T: Default> FastApiTypedArray<T> {
} }
} }
pub trait FastFunction { pub struct FastFunction {
pub args: &'static [Type],
pub return_type: CType,
pub function: *const c_void,
}
impl FastFunction {
#[inline(always)] #[inline(always)]
fn args(&self) -> &'static [Type] { pub const fn new(
&[] args: &'static [Type],
return_type: CType,
function: *const c_void,
) -> Self {
Self {
args,
return_type,
function,
} }
#[inline(always)]
fn return_type(&self) -> CType {
CType::Void
} }
fn function(&self) -> *const c_void;
} }

View file

@ -380,18 +380,18 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
pub fn build_fast( pub fn build_fast(
self, self,
scope: &mut HandleScope<'s, ()>, scope: &mut HandleScope<'s, ()>,
overload1: &dyn FastFunction, overload1: &FastFunction,
c_fn_info1: Option<*const CFunctionInfo>, c_fn_info1: Option<*const CFunctionInfo>,
overload2: Option<&dyn FastFunction>, overload2: Option<&FastFunction>,
c_fn_info2: Option<*const CFunctionInfo>, c_fn_info2: Option<*const CFunctionInfo>,
) -> Local<'s, FunctionTemplate> { ) -> Local<'s, FunctionTemplate> {
let c_fn1 = if let Some(fn_info) = c_fn_info1 { let c_fn1 = if let Some(fn_info) = c_fn_info1 {
fn_info fn_info
} else { } else {
let args = CTypeInfo::new_from_slice(overload1.args()); let args = CTypeInfo::new_from_slice(overload1.args);
let ret = CTypeInfo::new(overload1.return_type()); let ret = CTypeInfo::new(overload1.return_type);
let fn_info = unsafe { let fn_info = unsafe {
CFunctionInfo::new(args.as_ptr(), overload1.args().len(), ret.as_ptr()) CFunctionInfo::new(args.as_ptr(), overload1.args.len(), ret.as_ptr())
}; };
fn_info.as_ptr() fn_info.as_ptr()
}; };
@ -400,14 +400,10 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
if let Some(fn_info) = c_fn_info2 { if let Some(fn_info) = c_fn_info2 {
fn_info fn_info
} else { } else {
let args = CTypeInfo::new_from_slice(overload2.args()); let args = CTypeInfo::new_from_slice(overload2.args);
let ret = CTypeInfo::new(overload2.return_type()); let ret = CTypeInfo::new(overload2.return_type);
let fn_info = unsafe { let fn_info = unsafe {
CFunctionInfo::new( CFunctionInfo::new(args.as_ptr(), overload2.args.len(), ret.as_ptr())
args.as_ptr(),
overload2.args().len(),
ret.as_ptr(),
)
}; };
fn_info.as_ptr() fn_info.as_ptr()
} }
@ -425,9 +421,9 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
self.length, self.length,
ConstructorBehavior::Throw, ConstructorBehavior::Throw,
self.side_effect_type, self.side_effect_type,
overload1.function(), overload1.function,
c_fn1, c_fn1,
overload2.map_or(null(), |f| f.function()), overload2.map_or(null(), |f| f.function),
c_fn2, c_fn2,
) )
}) })

View file

@ -15,6 +15,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::sync::Mutex; use std::sync::Mutex;
use v8::fast_api; use v8::fast_api;
use v8::fast_api::CType;
use v8::fast_api::Type::*;
use v8::inspector::ChannelBase; use v8::inspector::ChannelBase;
// TODO(piscisaureus): Ideally there would be no need to import this trait. // TODO(piscisaureus): Ideally there would be no need to import this trait.
@ -8307,21 +8309,11 @@ fn test_fast_calls() {
a + b a + b
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, Uint32, Uint32],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Uint32,
use fast_api::Type::*; fast_fn as _,
&[V8Value, Uint32, Uint32] );
}
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8343,7 +8335,7 @@ fn test_fast_calls() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8378,25 +8370,11 @@ fn test_fast_calls_sequence() {
a + b + array.length() a + b + array.length()
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, Uint32, Uint32, Sequence(fast_api::CType::Void)],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Uint32,
&[ fast_fn as _,
fast_api::Type::V8Value, );
fast_api::Type::Uint32,
fast_api::Type::Uint32,
fast_api::Type::Sequence(fast_api::CType::Void),
]
}
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8416,7 +8394,7 @@ fn test_fast_calls_sequence() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8451,25 +8429,11 @@ fn test_fast_calls_arraybuffer() {
a + b + unsafe { &*data }.get(0) a + b + unsafe { &*data }.get(0)
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, Uint32, Uint32, TypedArray(fast_api::CType::Uint32)],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Uint32,
&[ fast_fn as _,
fast_api::Type::V8Value, );
fast_api::Type::Uint32,
fast_api::Type::Uint32,
fast_api::Type::TypedArray(fast_api::CType::Uint32),
]
}
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8489,7 +8453,7 @@ fn test_fast_calls_arraybuffer() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8529,23 +8493,11 @@ fn test_fast_calls_typedarray() {
sum.into() sum.into()
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, TypedArray(fast_api::CType::Uint8)],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Uint32,
&[ fast_fn as _,
fast_api::Type::V8Value, );
fast_api::Type::TypedArray(fast_api::CType::Uint8),
]
}
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8565,7 +8517,7 @@ fn test_fast_calls_typedarray() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8608,20 +8560,11 @@ fn test_fast_calls_reciever() {
} }
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Uint32,
&[fast_api::Type::V8Value] fast_fn as _,
} );
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8655,7 +8598,7 @@ fn test_fast_calls_reciever() {
); );
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "method").unwrap(); let name = v8::String::new(scope, "method").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8700,33 +8643,17 @@ fn test_fast_calls_overload() {
assert_eq!(data.length(), 2); assert_eq!(data.length(), 2);
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, TypedArray(CType::Uint32)],
fn args(&self) -> &'static [fast_api::Type] { CType::Void,
&[ fast_fn as _,
fast_api::Type::V8Value, );
fast_api::Type::TypedArray(fast_api::CType::Uint32),
]
}
fn function(&self) -> *const c_void { const FAST_TEST2: fast_api::FastFunction = fast_api::FastFunction::new(
fast_fn as _ &[V8Value, Sequence(CType::Void)],
} CType::Void,
} fast_fn2 as _,
);
pub struct FastTest2;
impl fast_api::FastFunction for FastTest2 {
fn args(&self) -> &'static [fast_api::Type] {
&[
fast_api::Type::V8Value,
fast_api::Type::Sequence(fast_api::CType::Void),
]
}
fn function(&self) -> *const c_void {
fast_fn2 as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8747,9 +8674,9 @@ fn test_fast_calls_overload() {
let template = v8::FunctionTemplate::builder(slow_fn).build_fast( let template = v8::FunctionTemplate::builder(slow_fn).build_fast(
scope, scope,
&FastTest, &FAST_TEST,
None, None,
Some(&FastTest2), Some(&FAST_TEST2),
None, None,
); );
@ -8796,16 +8723,11 @@ fn test_fast_calls_callback_options_fallback() {
} }
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, CallbackOptions],
fn args(&self) -> &'static [fast_api::Type] { CType::Void,
&[fast_api::Type::V8Value, fast_api::Type::CallbackOptions] fast_fn as _,
} );
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8825,7 +8747,7 @@ fn test_fast_calls_callback_options_fallback() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8869,16 +8791,11 @@ fn test_fast_calls_callback_options_data() {
*data = true; *data = true;
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, CallbackOptions],
fn args(&self) -> &'static [fast_api::Type] { CType::Void,
&[fast_api::Type::V8Value, fast_api::Type::CallbackOptions] fast_fn as _,
} );
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -8900,7 +8817,7 @@ fn test_fast_calls_callback_options_data() {
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.data(external.into()) .data(external.into())
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -8981,20 +8898,11 @@ fn test_fast_calls_onebytestring() {
data.len() as u32 data.len() as u32
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, SeqOneByteString],
fn args(&self) -> &'static [fast_api::Type] { CType::Uint32,
&[fast_api::Type::V8Value, fast_api::Type::SeqOneByteString] fast_fn as _,
} );
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Uint32
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
_: &mut v8::HandleScope, _: &mut v8::HandleScope,
@ -9013,7 +8921,7 @@ fn test_fast_calls_onebytestring() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();
@ -9118,20 +9026,11 @@ fn test_fast_calls_pointer() {
std::ptr::null_mut() std::ptr::null_mut()
} }
pub struct FastTest; const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
impl fast_api::FastFunction for FastTest { &[V8Value, Pointer],
fn args(&self) -> &'static [fast_api::Type] { fast_api::CType::Pointer,
&[fast_api::Type::V8Value, fast_api::Type::Pointer] fast_fn as _,
} );
fn return_type(&self) -> fast_api::CType {
fast_api::CType::Pointer
}
fn function(&self) -> *const c_void {
fast_fn as _
}
}
fn slow_fn( fn slow_fn(
scope: &mut v8::HandleScope, scope: &mut v8::HandleScope,
@ -9153,7 +9052,7 @@ fn test_fast_calls_pointer() {
let global = context.global(scope); let global = context.global(scope);
let template = v8::FunctionTemplate::builder(slow_fn) let template = v8::FunctionTemplate::builder(slow_fn)
.build_fast(scope, &FastTest, None, None, None); .build_fast(scope, &FAST_TEST, None, None, None);
let name = v8::String::new(scope, "func").unwrap(); let name = v8::String::new(scope, "func").unwrap();
let value = template.get_function(scope).unwrap(); let value = template.get_function(scope).unwrap();