mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-24 15:19:31 -05:00
New const
evaluated FastFunction API (#1201)
This commit is contained in:
parent
8e6b67a38b
commit
49c77327a6
4 changed files with 104 additions and 209 deletions
|
@ -1,5 +1,3 @@
|
|||
use std::os::raw::c_void;
|
||||
|
||||
fn main() {
|
||||
// Skip running benchmarks in debug or CI.
|
||||
if cfg!(debug_assertions) || std::env::var("CI").is_ok() {
|
||||
|
@ -67,19 +65,12 @@ fn main() {
|
|||
fn fast_fn() -> i32 {
|
||||
42
|
||||
}
|
||||
pub struct FastCall;
|
||||
impl v8::fast_api::FastFunction for FastCall {
|
||||
fn args(&self) -> &'static [v8::fast_api::Type] {
|
||||
&[v8::fast_api::Type::V8Value]
|
||||
}
|
||||
fn return_type(&self) -> v8::fast_api::CType {
|
||||
v8::fast_api::CType::Int32
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_CALL: v8::fast_api::FastFunction =
|
||||
v8::fast_api::FastFunction::new(
|
||||
&[v8::fast_api::Type::V8Value],
|
||||
v8::fast_api::CType::Int32,
|
||||
fast_fn as _,
|
||||
);
|
||||
let template = v8::FunctionTemplate::builder(
|
||||
|scope: &mut v8::HandleScope,
|
||||
_: v8::FunctionCallbackArguments,
|
||||
|
@ -87,7 +78,7 @@ fn main() {
|
|||
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 value = template.get_function(scope).unwrap();
|
||||
|
||||
|
|
|
@ -249,14 +249,23 @@ impl<T: Default> FastApiTypedArray<T> {
|
|||
}
|
||||
}
|
||||
|
||||
pub trait FastFunction {
|
||||
#[inline(always)]
|
||||
fn args(&self) -> &'static [Type] {
|
||||
&[]
|
||||
}
|
||||
#[inline(always)]
|
||||
fn return_type(&self) -> CType {
|
||||
CType::Void
|
||||
}
|
||||
fn function(&self) -> *const c_void;
|
||||
pub struct FastFunction {
|
||||
pub args: &'static [Type],
|
||||
pub return_type: CType,
|
||||
pub function: *const c_void,
|
||||
}
|
||||
|
||||
impl FastFunction {
|
||||
#[inline(always)]
|
||||
pub const fn new(
|
||||
args: &'static [Type],
|
||||
return_type: CType,
|
||||
function: *const c_void,
|
||||
) -> Self {
|
||||
Self {
|
||||
args,
|
||||
return_type,
|
||||
function,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -380,18 +380,18 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
|||
pub fn build_fast(
|
||||
self,
|
||||
scope: &mut HandleScope<'s, ()>,
|
||||
overload1: &dyn FastFunction,
|
||||
overload1: &FastFunction,
|
||||
c_fn_info1: Option<*const CFunctionInfo>,
|
||||
overload2: Option<&dyn FastFunction>,
|
||||
overload2: Option<&FastFunction>,
|
||||
c_fn_info2: Option<*const CFunctionInfo>,
|
||||
) -> Local<'s, FunctionTemplate> {
|
||||
let c_fn1 = if let Some(fn_info) = c_fn_info1 {
|
||||
fn_info
|
||||
} else {
|
||||
let args = CTypeInfo::new_from_slice(overload1.args());
|
||||
let ret = CTypeInfo::new(overload1.return_type());
|
||||
let args = CTypeInfo::new_from_slice(overload1.args);
|
||||
let ret = CTypeInfo::new(overload1.return_type);
|
||||
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()
|
||||
};
|
||||
|
@ -400,14 +400,10 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
|||
if let Some(fn_info) = c_fn_info2 {
|
||||
fn_info
|
||||
} else {
|
||||
let args = CTypeInfo::new_from_slice(overload2.args());
|
||||
let ret = CTypeInfo::new(overload2.return_type());
|
||||
let args = CTypeInfo::new_from_slice(overload2.args);
|
||||
let ret = CTypeInfo::new(overload2.return_type);
|
||||
let fn_info = unsafe {
|
||||
CFunctionInfo::new(
|
||||
args.as_ptr(),
|
||||
overload2.args().len(),
|
||||
ret.as_ptr(),
|
||||
)
|
||||
CFunctionInfo::new(args.as_ptr(), overload2.args.len(), ret.as_ptr())
|
||||
};
|
||||
fn_info.as_ptr()
|
||||
}
|
||||
|
@ -425,9 +421,9 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
|||
self.length,
|
||||
ConstructorBehavior::Throw,
|
||||
self.side_effect_type,
|
||||
overload1.function(),
|
||||
overload1.function,
|
||||
c_fn1,
|
||||
overload2.map_or(null(), |f| f.function()),
|
||||
overload2.map_or(null(), |f| f.function),
|
||||
c_fn2,
|
||||
)
|
||||
})
|
||||
|
|
|
@ -15,6 +15,8 @@ use std::sync::atomic::{AtomicUsize, Ordering};
|
|||
use std::sync::Arc;
|
||||
use std::sync::Mutex;
|
||||
use v8::fast_api;
|
||||
use v8::fast_api::CType;
|
||||
use v8::fast_api::Type::*;
|
||||
use v8::inspector::ChannelBase;
|
||||
|
||||
// TODO(piscisaureus): Ideally there would be no need to import this trait.
|
||||
|
@ -8307,21 +8309,11 @@ fn test_fast_calls() {
|
|||
a + b
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
use fast_api::Type::*;
|
||||
&[V8Value, Uint32, Uint32]
|
||||
}
|
||||
|
||||
fn return_type(&self) -> fast_api::CType {
|
||||
fast_api::CType::Uint32
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, Uint32, Uint32],
|
||||
fast_api::CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8343,7 +8335,7 @@ fn test_fast_calls() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8378,25 +8370,11 @@ fn test_fast_calls_sequence() {
|
|||
a + b + array.length()
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[
|
||||
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 _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, Uint32, Uint32, Sequence(fast_api::CType::Void)],
|
||||
fast_api::CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8416,7 +8394,7 @@ fn test_fast_calls_sequence() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8451,25 +8429,11 @@ fn test_fast_calls_arraybuffer() {
|
|||
a + b + unsafe { &*data }.get(0)
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[
|
||||
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 _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, Uint32, Uint32, TypedArray(fast_api::CType::Uint32)],
|
||||
fast_api::CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8489,7 +8453,7 @@ fn test_fast_calls_arraybuffer() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8529,23 +8493,11 @@ fn test_fast_calls_typedarray() {
|
|||
sum.into()
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[
|
||||
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 _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, TypedArray(fast_api::CType::Uint8)],
|
||||
fast_api::CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8565,7 +8517,7 @@ fn test_fast_calls_typedarray() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8608,20 +8560,11 @@ fn test_fast_calls_reciever() {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[fast_api::Type::V8Value]
|
||||
}
|
||||
|
||||
fn return_type(&self) -> fast_api::CType {
|
||||
fast_api::CType::Uint32
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value],
|
||||
fast_api::CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8655,7 +8598,7 @@ fn test_fast_calls_reciever() {
|
|||
);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8700,33 +8643,17 @@ fn test_fast_calls_overload() {
|
|||
assert_eq!(data.length(), 2);
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[
|
||||
fast_api::Type::V8Value,
|
||||
fast_api::Type::TypedArray(fast_api::CType::Uint32),
|
||||
]
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, TypedArray(CType::Uint32)],
|
||||
CType::Void,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn 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 _
|
||||
}
|
||||
}
|
||||
const FAST_TEST2: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, Sequence(CType::Void)],
|
||||
CType::Void,
|
||||
fast_fn2 as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8747,9 +8674,9 @@ fn test_fast_calls_overload() {
|
|||
|
||||
let template = v8::FunctionTemplate::builder(slow_fn).build_fast(
|
||||
scope,
|
||||
&FastTest,
|
||||
&FAST_TEST,
|
||||
None,
|
||||
Some(&FastTest2),
|
||||
Some(&FAST_TEST2),
|
||||
None,
|
||||
);
|
||||
|
||||
|
@ -8796,16 +8723,11 @@ fn test_fast_calls_callback_options_fallback() {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[fast_api::Type::V8Value, fast_api::Type::CallbackOptions]
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, CallbackOptions],
|
||||
CType::Void,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8825,7 +8747,7 @@ fn test_fast_calls_callback_options_fallback() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8869,16 +8791,11 @@ fn test_fast_calls_callback_options_data() {
|
|||
*data = true;
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[fast_api::Type::V8Value, fast_api::Type::CallbackOptions]
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, CallbackOptions],
|
||||
CType::Void,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -8900,7 +8817,7 @@ fn test_fast_calls_callback_options_data() {
|
|||
|
||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
||||
.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 value = template.get_function(scope).unwrap();
|
||||
|
@ -8981,20 +8898,11 @@ fn test_fast_calls_onebytestring() {
|
|||
data.len() as u32
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[fast_api::Type::V8Value, fast_api::Type::SeqOneByteString]
|
||||
}
|
||||
|
||||
fn return_type(&self) -> fast_api::CType {
|
||||
fast_api::CType::Uint32
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, SeqOneByteString],
|
||||
CType::Uint32,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
_: &mut v8::HandleScope,
|
||||
|
@ -9013,7 +8921,7 @@ fn test_fast_calls_onebytestring() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
@ -9118,20 +9026,11 @@ fn test_fast_calls_pointer() {
|
|||
std::ptr::null_mut()
|
||||
}
|
||||
|
||||
pub struct FastTest;
|
||||
impl fast_api::FastFunction for FastTest {
|
||||
fn args(&self) -> &'static [fast_api::Type] {
|
||||
&[fast_api::Type::V8Value, fast_api::Type::Pointer]
|
||||
}
|
||||
|
||||
fn return_type(&self) -> fast_api::CType {
|
||||
fast_api::CType::Pointer
|
||||
}
|
||||
|
||||
fn function(&self) -> *const c_void {
|
||||
fast_fn as _
|
||||
}
|
||||
}
|
||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
||||
&[V8Value, Pointer],
|
||||
fast_api::CType::Pointer,
|
||||
fast_fn as _,
|
||||
);
|
||||
|
||||
fn slow_fn(
|
||||
scope: &mut v8::HandleScope,
|
||||
|
@ -9153,7 +9052,7 @@ fn test_fast_calls_pointer() {
|
|||
let global = context.global(scope);
|
||||
|
||||
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 value = template.get_function(scope).unwrap();
|
||||
|
|
Loading…
Reference in a new issue