mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-11-27 16:11:06 -05:00
update fast calls api (#1564)
This commit is contained in:
parent
0d57670bac
commit
70e18db2ff
8 changed files with 359 additions and 475 deletions
|
@ -65,12 +65,14 @@ fn main() {
|
||||||
fn fast_fn() -> i32 {
|
fn fast_fn() -> i32 {
|
||||||
42
|
42
|
||||||
}
|
}
|
||||||
const FAST_CALL: v8::fast_api::FastFunction =
|
const FAST_CALL: v8::fast_api::CFunction = v8::fast_api::CFunction::new(
|
||||||
v8::fast_api::FastFunction::new(
|
fast_fn as _,
|
||||||
&[v8::fast_api::Type::V8Value],
|
&v8::fast_api::CFunctionInfo::new(
|
||||||
v8::fast_api::CType::Int32,
|
v8::fast_api::Type::Int32.scalar(),
|
||||||
fast_fn as _,
|
&[v8::fast_api::Type::V8Value.scalar()],
|
||||||
);
|
v8::fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
|
);
|
||||||
let template = v8::FunctionTemplate::builder(
|
let template = v8::FunctionTemplate::builder(
|
||||||
|scope: &mut v8::HandleScope,
|
|scope: &mut v8::HandleScope,
|
||||||
_: v8::FunctionCallbackArguments,
|
_: v8::FunctionCallbackArguments,
|
||||||
|
@ -78,7 +80,7 @@ fn main() {
|
||||||
rv.set(v8::Integer::new(scope, 42).into());
|
rv.set(v8::Integer::new(scope, 42).into());
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.build_fast(scope, &FAST_CALL, None, None, None);
|
.build_fast(scope, &[FAST_CALL]);
|
||||||
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();
|
||||||
|
|
||||||
|
|
|
@ -2247,70 +2247,17 @@ const v8::Signature* v8__Signature__New(v8::Isolate* isolate,
|
||||||
return local_to_ptr(v8::Signature::New(isolate, ptr_to_local(templ)));
|
return local_to_ptr(v8::Signature::New(isolate, ptr_to_local(templ)));
|
||||||
}
|
}
|
||||||
|
|
||||||
v8::CTypeInfo* v8__CTypeInfo__New(v8::CTypeInfo::Type ty) {
|
|
||||||
std::unique_ptr<v8::CTypeInfo> u =
|
|
||||||
std::make_unique<v8::CTypeInfo>(v8::CTypeInfo(ty));
|
|
||||||
return u.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void v8__CTypeInfo__DELETE(v8::CTypeInfo* self) { delete self; }
|
|
||||||
|
|
||||||
struct CTypeSequenceType {
|
|
||||||
v8::CTypeInfo::Type c_type;
|
|
||||||
v8::CTypeInfo::SequenceType sequence_type;
|
|
||||||
};
|
|
||||||
|
|
||||||
v8::CTypeInfo* v8__CTypeInfo__New__From__Slice(unsigned int len,
|
|
||||||
CTypeSequenceType* ty) {
|
|
||||||
v8::CTypeInfo* v = (v8::CTypeInfo*)malloc(sizeof(v8::CTypeInfo) * len);
|
|
||||||
for (size_t i = 0; i < len; i += 1) {
|
|
||||||
v[i] = v8::CTypeInfo(ty[i].c_type, ty[i].sequence_type);
|
|
||||||
}
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
v8::CFunctionInfo* v8__CFunctionInfo__New(
|
|
||||||
const v8::CTypeInfo& return_info, unsigned int args_len,
|
|
||||||
v8::CTypeInfo* args_info, v8::CFunctionInfo::Int64Representation repr) {
|
|
||||||
std::unique_ptr<v8::CFunctionInfo> info = std::make_unique<v8::CFunctionInfo>(
|
|
||||||
v8::CFunctionInfo(return_info, args_len, args_info, repr));
|
|
||||||
return info.release();
|
|
||||||
}
|
|
||||||
|
|
||||||
void v8__CFunctionInfo__DELETE(v8::CFunctionInfo* self) { delete self; }
|
|
||||||
|
|
||||||
const v8::FunctionTemplate* v8__FunctionTemplate__New(
|
const v8::FunctionTemplate* v8__FunctionTemplate__New(
|
||||||
v8::Isolate* isolate, v8::FunctionCallback callback,
|
v8::Isolate* isolate, v8::FunctionCallback callback,
|
||||||
const v8::Value* data_or_null, const v8::Signature* signature_or_null,
|
const v8::Value* data_or_null, const v8::Signature* signature_or_null,
|
||||||
int length, v8::ConstructorBehavior constructor_behavior,
|
int length, v8::ConstructorBehavior constructor_behavior,
|
||||||
v8::SideEffectType side_effect_type, void* func_ptr1,
|
v8::SideEffectType side_effect_type, const v8::CFunction* c_functions,
|
||||||
const v8::CFunctionInfo* c_function_info1, void* func_ptr2,
|
size_t c_functions_len) {
|
||||||
const v8::CFunctionInfo* c_function_info2) {
|
v8::MemorySpan<const v8::CFunction> overloads{c_functions, c_functions_len};
|
||||||
// Support upto 2 overloads. V8 requires TypedArray to have a
|
|
||||||
// v8::Array overload.
|
|
||||||
if (func_ptr1) {
|
|
||||||
if (func_ptr2 == nullptr) {
|
|
||||||
const v8::CFunction o[] = {v8::CFunction(func_ptr1, c_function_info1)};
|
|
||||||
auto overload = v8::MemorySpan<const v8::CFunction>{o, 1};
|
|
||||||
return local_to_ptr(v8::FunctionTemplate::NewWithCFunctionOverloads(
|
|
||||||
isolate, callback, ptr_to_local(data_or_null),
|
|
||||||
ptr_to_local(signature_or_null), length, constructor_behavior,
|
|
||||||
side_effect_type, overload));
|
|
||||||
} else {
|
|
||||||
const v8::CFunction o[] = {v8::CFunction(func_ptr1, c_function_info1),
|
|
||||||
v8::CFunction(func_ptr2, c_function_info2)};
|
|
||||||
auto overload = v8::MemorySpan<const v8::CFunction>{o, 2};
|
|
||||||
return local_to_ptr(v8::FunctionTemplate::NewWithCFunctionOverloads(
|
|
||||||
isolate, callback, ptr_to_local(data_or_null),
|
|
||||||
ptr_to_local(signature_or_null), length, constructor_behavior,
|
|
||||||
side_effect_type, overload));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
auto overload = v8::MemorySpan<const v8::CFunction>{};
|
|
||||||
return local_to_ptr(v8::FunctionTemplate::NewWithCFunctionOverloads(
|
return local_to_ptr(v8::FunctionTemplate::NewWithCFunctionOverloads(
|
||||||
isolate, callback, ptr_to_local(data_or_null),
|
isolate, callback, ptr_to_local(data_or_null),
|
||||||
ptr_to_local(signature_or_null), length, constructor_behavior,
|
ptr_to_local(signature_or_null), length, constructor_behavior,
|
||||||
side_effect_type, overload));
|
side_effect_type, overloads));
|
||||||
}
|
}
|
||||||
|
|
||||||
const v8::Function* v8__FunctionTemplate__GetFunction(
|
const v8::Function* v8__FunctionTemplate__GetFunction(
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include <v8-cppgc.h>
|
#include <v8-cppgc.h>
|
||||||
|
#include <v8-fast-api-calls.h>
|
||||||
#include <v8-message.h>
|
#include <v8-message.h>
|
||||||
#include <v8-typed-array.h>
|
#include <v8-typed-array.h>
|
||||||
|
|
||||||
|
@ -28,3 +29,6 @@ static size_t v8__TypedArray__kMaxByteLength = v8::TypedArray::kMaxByteLength;
|
||||||
static size_t v8__##name##__kMaxLength = v8::name::kMaxLength;
|
static size_t v8__##name##__kMaxLength = v8::name::kMaxLength;
|
||||||
EACH_TYPED_ARRAY(TYPED_ARRAY_MAX_LENGTH)
|
EACH_TYPED_ARRAY(TYPED_ARRAY_MAX_LENGTH)
|
||||||
#undef TYPED_ARRAY_MAX_LENGTH
|
#undef TYPED_ARRAY_MAX_LENGTH
|
||||||
|
|
||||||
|
using v8__CFunction = v8::CFunction;
|
||||||
|
using v8__CFunctionInfo = v8::CFunctionInfo;
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#![allow(unused)]
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright 2019-2021 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2019-2021 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use crate::fast_api::CFunctionInfo;
|
||||||
use crate::support::intptr_t;
|
use crate::support::intptr_t;
|
||||||
use crate::FunctionCallback;
|
use crate::FunctionCallback;
|
||||||
use crate::IndexedDefinerCallback;
|
use crate::IndexedDefinerCallback;
|
||||||
|
@ -33,6 +34,7 @@ pub union ExternalReference<'s> {
|
||||||
pub enumerator: PropertyEnumeratorCallback<'s>,
|
pub enumerator: PropertyEnumeratorCallback<'s>,
|
||||||
pub message: MessageCallback,
|
pub message: MessageCallback,
|
||||||
pub pointer: *mut c_void,
|
pub pointer: *mut c_void,
|
||||||
|
pub type_info: *const CFunctionInfo,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s> Debug for ExternalReference<'s> {
|
impl<'s> Debug for ExternalReference<'s> {
|
||||||
|
|
404
src/fast_api.rs
404
src/fast_api.rs
|
@ -1,205 +1,138 @@
|
||||||
use crate::support::Opaque;
|
use std::ffi::c_void;
|
||||||
|
|
||||||
|
use crate::binding::*;
|
||||||
use crate::Isolate;
|
use crate::Isolate;
|
||||||
use crate::Local;
|
use crate::Local;
|
||||||
use crate::Value;
|
use crate::Value;
|
||||||
use std::{
|
|
||||||
ffi::c_void,
|
|
||||||
mem::align_of,
|
|
||||||
ptr::{self, NonNull},
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" {
|
#[derive(Clone, Copy)]
|
||||||
fn v8__CTypeInfo__New(ty: CType) -> *mut CTypeInfo;
|
#[repr(transparent)]
|
||||||
fn v8__CTypeInfo__New__From__Slice(
|
pub struct CFunction(v8__CFunction);
|
||||||
len: usize,
|
|
||||||
tys: *const CTypeSequenceInfo,
|
impl CFunction {
|
||||||
) -> *mut CTypeInfo;
|
pub const fn new(address: *const c_void, type_info: &CFunctionInfo) -> Self {
|
||||||
fn v8__CTypeInfo__DELETE(this: *mut CTypeInfo);
|
Self(v8__CFunction {
|
||||||
fn v8__CFunctionInfo__New(
|
address_: address,
|
||||||
return_info: *const CTypeInfo,
|
type_info_: &type_info.0,
|
||||||
args_len: usize,
|
})
|
||||||
args_info: *const CTypeInfo,
|
}
|
||||||
repr: Int64Representation,
|
|
||||||
) -> *mut CFunctionInfo;
|
pub const fn address(&self) -> *const c_void {
|
||||||
fn v8__CFunctionInfo__DELETE(this: *mut CFunctionInfo);
|
self.0.address_
|
||||||
|
}
|
||||||
|
|
||||||
|
pub const fn type_info(&self) -> &CFunctionInfo {
|
||||||
|
// SAFETY: We initialize this field with a reference. and
|
||||||
|
// the layout of CFunctionInfo is identical to v8_CFunctionInfo.
|
||||||
|
unsafe { &*(self.0.type_info_ as *const CFunctionInfo) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(transparent)]
|
||||||
#[derive(Default)]
|
pub struct CFunctionInfo(v8__CFunctionInfo);
|
||||||
pub struct CFunctionInfo(Opaque);
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
#[derive(Default)]
|
|
||||||
pub struct CFunction(Opaque);
|
|
||||||
|
|
||||||
impl CFunctionInfo {
|
impl CFunctionInfo {
|
||||||
#[inline(always)]
|
/// Construct a struct to hold a CFunction's type information.
|
||||||
pub unsafe fn new(
|
/// |return_info| describes the function's return type.
|
||||||
args: *const CTypeInfo,
|
/// |arg_info| is an array of |arg_count| CTypeInfos describing the
|
||||||
args_len: usize,
|
/// arguments. Only the last argument may be of the special type
|
||||||
return_type: *const CTypeInfo,
|
/// CTypeInfo::kCallbackOptionsType.
|
||||||
|
pub const fn new(
|
||||||
|
return_info: CTypeInfo,
|
||||||
|
arg_info: &[CTypeInfo],
|
||||||
repr: Int64Representation,
|
repr: Int64Representation,
|
||||||
) -> NonNull<CFunctionInfo> {
|
) -> Self {
|
||||||
NonNull::new_unchecked(v8__CFunctionInfo__New(
|
Self(v8__CFunctionInfo {
|
||||||
return_type,
|
arg_count_: arg_info.len() as _,
|
||||||
args_len,
|
arg_info_: arg_info.as_ptr() as _,
|
||||||
args,
|
repr_: repr as _,
|
||||||
repr,
|
return_info_: return_info.0,
|
||||||
))
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for CFunctionInfo {
|
#[derive(Clone, Copy)]
|
||||||
fn drop(&mut self) {
|
#[repr(u8)]
|
||||||
unsafe { v8__CFunctionInfo__DELETE(self) };
|
pub enum Int64Representation {
|
||||||
}
|
/// Use numbers to represent 64 bit integers.
|
||||||
|
Number = v8_CFunctionInfo_Int64Representation_kNumber,
|
||||||
|
/// Use BigInts to represent 64 bit integers.
|
||||||
|
BigInt = v8_CFunctionInfo_Int64Representation_kBigInt,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[derive(Clone, Copy)]
|
||||||
#[derive(Debug)]
|
#[repr(transparent)]
|
||||||
pub struct CTypeInfo(Opaque);
|
pub struct CTypeInfo(v8_CTypeInfo);
|
||||||
|
|
||||||
impl CTypeInfo {
|
impl CTypeInfo {
|
||||||
#[inline(always)]
|
pub const fn new(
|
||||||
pub fn new(ty: CType) -> NonNull<CTypeInfo> {
|
r#type: Type,
|
||||||
unsafe { NonNull::new_unchecked(v8__CTypeInfo__New(ty)) }
|
sequence_type: SequenceType,
|
||||||
}
|
flags: Flags,
|
||||||
|
) -> Self {
|
||||||
pub fn new_from_slice(types: &[Type]) -> NonNull<CTypeInfo> {
|
Self(v8_CTypeInfo {
|
||||||
let mut structs = vec![];
|
flags_: flags.bits(),
|
||||||
|
sequence_type_: sequence_type as _,
|
||||||
for type_ in types.iter() {
|
type_: r#type as _,
|
||||||
structs.push(type_.into())
|
})
|
||||||
}
|
|
||||||
|
|
||||||
unsafe {
|
|
||||||
NonNull::new_unchecked(v8__CTypeInfo__New__From__Slice(
|
|
||||||
structs.len(),
|
|
||||||
structs.as_ptr(),
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Drop for CTypeInfo {
|
#[derive(Clone, Copy)]
|
||||||
fn drop(&mut self) {
|
|
||||||
unsafe { v8__CTypeInfo__DELETE(self) };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum SequenceType {
|
pub enum Type {
|
||||||
Scalar,
|
Void = v8_CTypeInfo_Type_kVoid,
|
||||||
/// sequence<T>
|
Bool = v8_CTypeInfo_Type_kBool,
|
||||||
IsSequence,
|
Uint8 = v8_CTypeInfo_Type_kUint8,
|
||||||
/// TypedArray of T or any ArrayBufferView if T is void
|
Int32 = v8_CTypeInfo_Type_kInt32,
|
||||||
IsTypedArray,
|
Uint32 = v8_CTypeInfo_Type_kUint32,
|
||||||
/// ArrayBuffer
|
Int64 = v8_CTypeInfo_Type_kInt64,
|
||||||
IsArrayBuffer,
|
Uint64 = v8_CTypeInfo_Type_kUint64,
|
||||||
}
|
Float32 = v8_CTypeInfo_Type_kFloat32,
|
||||||
|
Float64 = v8_CTypeInfo_Type_kFloat64,
|
||||||
#[derive(Clone, Copy, Debug)]
|
Pointer = v8_CTypeInfo_Type_kPointer,
|
||||||
#[repr(u8)]
|
V8Value = v8_CTypeInfo_Type_kV8Value,
|
||||||
#[non_exhaustive]
|
SeqOneByteString = v8_CTypeInfo_Type_kSeqOneByteString,
|
||||||
pub enum CType {
|
ApiObject = v8_CTypeInfo_Type_kApiObject,
|
||||||
Void = 0,
|
Any = v8_CTypeInfo_Type_kAny,
|
||||||
Bool,
|
|
||||||
Uint8,
|
|
||||||
Int32,
|
|
||||||
Uint32,
|
|
||||||
Int64,
|
|
||||||
Uint64,
|
|
||||||
Float32,
|
|
||||||
Float64,
|
|
||||||
Pointer,
|
|
||||||
V8Value,
|
|
||||||
SeqOneByteString,
|
|
||||||
// https://github.com/v8/v8/blob/492a32943bc34a527f42df2ae15a77154b16cc84/include/v8-fast-api-calls.h#L264-L267
|
|
||||||
// kCallbackOptionsType is not part of the Type enum
|
|
||||||
// because it is only used internally. Use value 255 that is larger
|
|
||||||
// than any valid Type enum.
|
|
||||||
CallbackOptions = 255,
|
CallbackOptions = 255,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
impl Type {
|
||||||
#[non_exhaustive]
|
pub const fn scalar(self) -> CTypeInfo {
|
||||||
pub enum Type {
|
CTypeInfo::new(self, SequenceType::Scalar, Flags::empty())
|
||||||
Void,
|
}
|
||||||
Bool,
|
|
||||||
Uint8,
|
|
||||||
Int32,
|
|
||||||
Uint32,
|
|
||||||
Int64,
|
|
||||||
Uint64,
|
|
||||||
Float32,
|
|
||||||
Float64,
|
|
||||||
Pointer,
|
|
||||||
V8Value,
|
|
||||||
SeqOneByteString,
|
|
||||||
CallbackOptions,
|
|
||||||
Sequence(CType),
|
|
||||||
TypedArray(CType),
|
|
||||||
ArrayBuffer(CType),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<&Type> for CType {
|
pub const fn typed_array(self) -> CTypeInfo {
|
||||||
fn from(ty: &Type) -> CType {
|
CTypeInfo::new(self, SequenceType::IsTypedArray, Flags::empty())
|
||||||
match ty {
|
|
||||||
Type::Void => CType::Void,
|
|
||||||
Type::Bool => CType::Bool,
|
|
||||||
Type::Uint8 => CType::Uint8,
|
|
||||||
Type::Int32 => CType::Int32,
|
|
||||||
Type::Uint32 => CType::Uint32,
|
|
||||||
Type::Int64 => CType::Int64,
|
|
||||||
Type::Uint64 => CType::Uint64,
|
|
||||||
Type::Float32 => CType::Float32,
|
|
||||||
Type::Float64 => CType::Float64,
|
|
||||||
Type::Pointer => CType::Pointer,
|
|
||||||
Type::V8Value => CType::V8Value,
|
|
||||||
Type::SeqOneByteString => CType::SeqOneByteString,
|
|
||||||
Type::CallbackOptions => CType::CallbackOptions,
|
|
||||||
Type::Sequence(ty) => *ty,
|
|
||||||
Type::TypedArray(ty) => *ty,
|
|
||||||
Type::ArrayBuffer(ty) => *ty,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Type> for SequenceType {
|
#[derive(Clone, Copy)]
|
||||||
fn from(ty: &Type) -> SequenceType {
|
#[repr(u8)]
|
||||||
match ty {
|
pub enum SequenceType {
|
||||||
Type::Sequence(_) => SequenceType::IsSequence,
|
Scalar = v8_CTypeInfo_SequenceType_kScalar,
|
||||||
Type::TypedArray(_) => SequenceType::IsTypedArray,
|
/// sequence<T>
|
||||||
Type::ArrayBuffer(_) => SequenceType::IsArrayBuffer,
|
IsSequence = v8_CTypeInfo_SequenceType_kIsSequence,
|
||||||
_ => SequenceType::Scalar,
|
/// TypedArray of T or any ArrayBufferView if T is void
|
||||||
}
|
IsTypedArray = v8_CTypeInfo_SequenceType_kIsTypedArray,
|
||||||
|
/// ArrayBuffer
|
||||||
|
IsArrayBuffer = v8_CTypeInfo_SequenceType_kIsArrayBuffer,
|
||||||
|
}
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
pub struct Flags: u8 {
|
||||||
|
/// Must be an ArrayBuffer or TypedArray
|
||||||
|
const AllowShared = v8_CTypeInfo_Flags_kAllowSharedBit;
|
||||||
|
/// T must be integral
|
||||||
|
const EnforceRange = v8_CTypeInfo_Flags_kEnforceRangeBit;
|
||||||
|
/// T must be integral
|
||||||
|
const Clamp = v8_CTypeInfo_Flags_kClampBit;
|
||||||
|
/// T must be float or double
|
||||||
|
const IsRestricted = v8_CTypeInfo_Flags_kIsRestrictedBit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Type> for CTypeSequenceInfo {
|
|
||||||
fn from(ty: &Type) -> CTypeSequenceInfo {
|
|
||||||
CTypeSequenceInfo {
|
|
||||||
c_type: ty.into(),
|
|
||||||
sequence_type: ty.into(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
struct CTypeSequenceInfo {
|
|
||||||
c_type: CType,
|
|
||||||
sequence_type: SequenceType,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[repr(C)]
|
|
||||||
pub union FastApiCallbackData<'a> {
|
|
||||||
/// `data_ptr` allows for default constructing FastApiCallbackOptions.
|
|
||||||
pub data_ptr: *mut c_void,
|
|
||||||
/// The `data` passed to the FunctionTemplate constructor, or `undefined`.
|
|
||||||
pub data: Local<'a, Value>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A struct which may be passed to a fast call callback, like so
|
/// A struct which may be passed to a fast call callback, like so
|
||||||
/// ```c
|
/// ```c
|
||||||
/// void FastMethodWithOptions(int param, FastApiCallbackOptions& options);
|
/// void FastMethodWithOptions(int param, FastApiCallbackOptions& options);
|
||||||
|
@ -217,7 +150,8 @@ pub struct FastApiCallbackOptions<'a> {
|
||||||
/// fallback conditions are checked, because otherwise executing the slow
|
/// fallback conditions are checked, because otherwise executing the slow
|
||||||
/// callback might produce visible side-effects twice.
|
/// callback might produce visible side-effects twice.
|
||||||
pub fallback: bool,
|
pub fallback: bool,
|
||||||
pub data: FastApiCallbackData<'a>,
|
/// The `data` passed to the FunctionTemplate constructor, or `undefined`.
|
||||||
|
pub data: Local<'a, Value>,
|
||||||
/// When called from WebAssembly, a view of the calling module's memory.
|
/// When called from WebAssembly, a view of the calling module's memory.
|
||||||
pub wasm_memory: *const FastApiTypedArray<u8>,
|
pub wasm_memory: *const FastApiTypedArray<u8>,
|
||||||
}
|
}
|
||||||
|
@ -235,8 +169,45 @@ pub struct FastApiTypedArray<T: Default> {
|
||||||
data: *mut T,
|
data: *mut T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Default> FastApiTypedArray<T> {
|
||||||
|
/// Performs an unaligned-safe read of T from the underlying data.
|
||||||
|
#[inline(always)]
|
||||||
|
pub const fn get(&self, index: usize) -> T {
|
||||||
|
debug_assert!(index < self.length);
|
||||||
|
// SAFETY: src is valid for reads, and is a valid value for T
|
||||||
|
unsafe { std::ptr::read_unaligned(self.data.add(index)) }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a slice pointing to the underlying data if safe to do so.
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> {
|
||||||
|
// V8 may provide an invalid or null pointer when length is zero, so we just
|
||||||
|
// ignore that value completely and create an empty slice in this case.
|
||||||
|
if self.length == 0 {
|
||||||
|
return Some(&mut []);
|
||||||
|
}
|
||||||
|
// Ensure that we never return an unaligned or null buffer
|
||||||
|
if self.data.is_null() || (self.data as usize) % align_of::<T>() != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
Some(unsafe { std::slice::from_raw_parts_mut(self.data, self.length) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Any TypedArray. It uses kTypedArrayBit with base type void
|
||||||
|
/// Overloaded args of ArrayBufferView and TypedArray are not supported
|
||||||
|
/// (for now) because the generic “any” ArrayBufferView doesn’t have its
|
||||||
|
/// own instance type. It could be supported if we specify that
|
||||||
|
/// TypedArray<T> always has precedence over the generic ArrayBufferView,
|
||||||
|
/// but this complicates overload resolution.
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct FastApiArrayBufferView {
|
||||||
|
pub data: *mut c_void,
|
||||||
|
pub byte_length: usize,
|
||||||
|
}
|
||||||
|
|
||||||
// FastApiOneByteString is an alias for SeqOneByteString and the type is widely used in deno_core.
|
// FastApiOneByteString is an alias for SeqOneByteString and the type is widely used in deno_core.
|
||||||
#[allow(dead_code)]
|
#[allow(unused)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct FastApiOneByteString {
|
pub struct FastApiOneByteString {
|
||||||
data: *const u8,
|
data: *const u8,
|
||||||
|
@ -256,88 +227,3 @@ impl FastApiOneByteString {
|
||||||
unsafe { std::slice::from_raw_parts(self.data, self.length as usize) }
|
unsafe { std::slice::from_raw_parts(self.data, self.length as usize) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> FastApiTypedArray<T> {
|
|
||||||
/// Performs an unaligned-safe read of T from the underlying data.
|
|
||||||
#[inline(always)]
|
|
||||||
pub const fn get(&self, index: usize) -> T {
|
|
||||||
debug_assert!(index < self.length);
|
|
||||||
// SAFETY: src is valid for reads, and is a valid value for T
|
|
||||||
unsafe { ptr::read_unaligned(self.data.add(index)) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Given a pointer to a `FastApiTypedArray`, returns a slice pointing to the
|
|
||||||
/// data if safe to do so.
|
|
||||||
///
|
|
||||||
/// # Safety
|
|
||||||
///
|
|
||||||
/// The pointer must not be null and the caller must choose a lifetime that is
|
|
||||||
/// safe.
|
|
||||||
#[inline(always)]
|
|
||||||
pub unsafe fn get_storage_from_pointer_if_aligned<'a>(
|
|
||||||
ptr: *mut Self,
|
|
||||||
) -> Option<&'a mut [T]> {
|
|
||||||
debug_assert!(!ptr.is_null());
|
|
||||||
let self_ref = ptr.as_mut().unwrap_unchecked();
|
|
||||||
self_ref.get_storage_if_aligned()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a slice pointing to the underlying data if safe to do so.
|
|
||||||
#[inline(always)]
|
|
||||||
pub fn get_storage_if_aligned(&self) -> Option<&mut [T]> {
|
|
||||||
// V8 may provide an invalid or null pointer when length is zero, so we just
|
|
||||||
// ignore that value completely and create an empty slice in this case.
|
|
||||||
if self.length == 0 {
|
|
||||||
return Some(&mut []);
|
|
||||||
}
|
|
||||||
// Ensure that we never return an unaligned or null buffer
|
|
||||||
if self.data.is_null() || (self.data as usize) % align_of::<T>() != 0 {
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
Some(unsafe { std::slice::from_raw_parts_mut(self.data, self.length) })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone)]
|
|
||||||
pub struct FastFunction {
|
|
||||||
pub args: &'static [Type],
|
|
||||||
pub function: *const c_void,
|
|
||||||
pub repr: Int64Representation,
|
|
||||||
pub return_type: CType,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FastFunction {
|
|
||||||
#[inline(always)]
|
|
||||||
pub const fn new(
|
|
||||||
args: &'static [Type],
|
|
||||||
return_type: CType,
|
|
||||||
function: *const c_void,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
args,
|
|
||||||
function,
|
|
||||||
repr: Int64Representation::Number,
|
|
||||||
return_type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const fn new_with_bigint(
|
|
||||||
args: &'static [Type],
|
|
||||||
return_type: CType,
|
|
||||||
function: *const c_void,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
args,
|
|
||||||
function,
|
|
||||||
repr: Int64Representation::BigInt,
|
|
||||||
return_type,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
|
||||||
#[repr(u8)]
|
|
||||||
pub enum Int64Representation {
|
|
||||||
Number = 0,
|
|
||||||
BigInt = 1,
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,9 +3,7 @@ use crate::data::FunctionTemplate;
|
||||||
use crate::data::Name;
|
use crate::data::Name;
|
||||||
use crate::data::ObjectTemplate;
|
use crate::data::ObjectTemplate;
|
||||||
use crate::data::Template;
|
use crate::data::Template;
|
||||||
use crate::fast_api::CFunctionInfo;
|
use crate::fast_api::CFunction;
|
||||||
use crate::fast_api::CTypeInfo;
|
|
||||||
use crate::fast_api::FastFunction;
|
|
||||||
use crate::isolate::Isolate;
|
use crate::isolate::Isolate;
|
||||||
use crate::support::int;
|
use crate::support::int;
|
||||||
use crate::support::MapFnTo;
|
use crate::support::MapFnTo;
|
||||||
|
@ -37,7 +35,6 @@ use crate::Signature;
|
||||||
use crate::String;
|
use crate::String;
|
||||||
use crate::Value;
|
use crate::Value;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::ffi::c_void;
|
|
||||||
use std::ptr::null;
|
use std::ptr::null;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -66,10 +63,8 @@ extern "C" {
|
||||||
length: i32,
|
length: i32,
|
||||||
constructor_behavior: ConstructorBehavior,
|
constructor_behavior: ConstructorBehavior,
|
||||||
side_effect_type: SideEffectType,
|
side_effect_type: SideEffectType,
|
||||||
func_ptr1: *const c_void,
|
c_functions: *const CFunction,
|
||||||
c_function1: *const CFunctionInfo,
|
c_functions_len: usize,
|
||||||
func_ptr2: *const c_void,
|
|
||||||
c_function2: *const CFunctionInfo,
|
|
||||||
) -> *const FunctionTemplate;
|
) -> *const FunctionTemplate;
|
||||||
fn v8__FunctionTemplate__GetFunction(
|
fn v8__FunctionTemplate__GetFunction(
|
||||||
this: *const FunctionTemplate,
|
this: *const FunctionTemplate,
|
||||||
|
@ -700,9 +695,7 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
||||||
self.constructor_behavior,
|
self.constructor_behavior,
|
||||||
self.side_effect_type,
|
self.side_effect_type,
|
||||||
null(),
|
null(),
|
||||||
null(),
|
0,
|
||||||
null(),
|
|
||||||
null(),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -717,47 +710,8 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
||||||
pub fn build_fast(
|
pub fn build_fast(
|
||||||
self,
|
self,
|
||||||
scope: &mut HandleScope<'s, ()>,
|
scope: &mut HandleScope<'s, ()>,
|
||||||
overload1: &FastFunction,
|
overloads: &[CFunction],
|
||||||
c_fn_info1: Option<*const CFunctionInfo>,
|
|
||||||
overload2: Option<&FastFunction>,
|
|
||||||
c_fn_info2: Option<*const CFunctionInfo>,
|
|
||||||
) -> Local<'s, FunctionTemplate> {
|
) -> 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 fn_info = unsafe {
|
|
||||||
CFunctionInfo::new(
|
|
||||||
args.as_ptr(),
|
|
||||||
overload1.args.len(),
|
|
||||||
ret.as_ptr(),
|
|
||||||
overload1.repr,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
fn_info.as_ptr()
|
|
||||||
};
|
|
||||||
|
|
||||||
let c_fn2 = if let Some(overload2) = overload2 {
|
|
||||||
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 fn_info = unsafe {
|
|
||||||
CFunctionInfo::new(
|
|
||||||
args.as_ptr(),
|
|
||||||
overload2.args.len(),
|
|
||||||
ret.as_ptr(),
|
|
||||||
overload2.repr,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
fn_info.as_ptr()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
null()
|
|
||||||
};
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
scope.cast_local(|sd| {
|
scope.cast_local(|sd| {
|
||||||
v8__FunctionTemplate__New(
|
v8__FunctionTemplate__New(
|
||||||
|
@ -768,10 +722,8 @@ impl<'s> FunctionBuilder<'s, FunctionTemplate> {
|
||||||
self.length,
|
self.length,
|
||||||
ConstructorBehavior::Throw,
|
ConstructorBehavior::Throw,
|
||||||
self.side_effect_type,
|
self.side_effect_type,
|
||||||
overload1.function,
|
overloads.as_ptr(),
|
||||||
c_fn1,
|
overloads.len(),
|
||||||
overload2.map_or(null(), |f| f.function),
|
|
||||||
c_fn2,
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,10 +15,9 @@ use std::ptr::{addr_of, addr_of_mut, NonNull};
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
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::Type::*;
|
use v8::fast_api;
|
||||||
use v8::fast_api::{CType, FastApiTypedArray};
|
|
||||||
use v8::inspector::ChannelBase;
|
use v8::inspector::ChannelBase;
|
||||||
use v8::{fast_api, AccessorConfiguration};
|
use v8::AccessorConfiguration;
|
||||||
|
|
||||||
// TODO(piscisaureus): Ideally there would be no need to import this trait.
|
// TODO(piscisaureus): Ideally there would be no need to import this trait.
|
||||||
use v8::MapFnTo;
|
use v8::MapFnTo;
|
||||||
|
@ -10456,10 +10455,17 @@ fn test_fast_calls() {
|
||||||
a + b
|
a + b
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Uint32, Uint32],
|
|
||||||
fast_api::CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10481,8 +10487,8 @@ fn test_fast_calls() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10508,16 +10514,11 @@ fn test_fast_calls_empty_buffer() {
|
||||||
static mut WHO: &str = "none";
|
static mut WHO: &str = "none";
|
||||||
unsafe fn fast_fn(
|
unsafe fn fast_fn(
|
||||||
_recv: v8::Local<v8::Object>,
|
_recv: v8::Local<v8::Object>,
|
||||||
buffer: *mut FastApiTypedArray<u8>,
|
buffer: *mut fast_api::FastApiTypedArray<u8>,
|
||||||
) {
|
) {
|
||||||
assert_eq!(WHO, "slow");
|
assert_eq!(WHO, "slow");
|
||||||
WHO = "fast";
|
WHO = "fast";
|
||||||
assert_eq!(
|
assert_eq!(0, (*buffer).get_storage_if_aligned().unwrap().len());
|
||||||
0,
|
|
||||||
FastApiTypedArray::get_storage_from_pointer_if_aligned(buffer)
|
|
||||||
.unwrap()
|
|
||||||
.len()
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10530,10 +10531,20 @@ fn test_fast_calls_empty_buffer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, TypedArray(CType::Uint8)],
|
|
||||||
fast_api::CType::Void,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Void.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Uint8,
|
||||||
|
fast_api::SequenceType::IsTypedArray,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let _setup_guard = setup::parallel_test();
|
let _setup_guard = setup::parallel_test();
|
||||||
|
@ -10544,8 +10555,8 @@ fn test_fast_calls_empty_buffer() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10575,10 +10586,22 @@ fn test_fast_calls_sequence() {
|
||||||
a + b + array.length()
|
a + b + array.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Uint32, Uint32, Sequence(fast_api::CType::Void)],
|
|
||||||
fast_api::CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Void,
|
||||||
|
fast_api::SequenceType::IsSequence,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10598,8 +10621,8 @@ fn test_fast_calls_sequence() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10634,10 +10657,22 @@ fn test_fast_calls_arraybuffer() {
|
||||||
a + b + unsafe { &*data }.get(0)
|
a + b + unsafe { &*data }.get(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Uint32, Uint32, TypedArray(fast_api::CType::Uint32)],
|
|
||||||
fast_api::CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Uint32,
|
||||||
|
fast_api::SequenceType::IsTypedArray,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10657,8 +10692,8 @@ fn test_fast_calls_arraybuffer() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10698,10 +10733,20 @@ fn test_fast_calls_typedarray() {
|
||||||
sum.into()
|
sum.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, TypedArray(fast_api::CType::Uint8)],
|
|
||||||
fast_api::CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Uint8,
|
||||||
|
fast_api::SequenceType::IsTypedArray,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10721,8 +10766,8 @@ fn test_fast_calls_typedarray() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10765,10 +10810,13 @@ fn test_fast_calls_reciever() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value],
|
|
||||||
fast_api::CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[fast_api::Type::V8Value.scalar()],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10802,8 +10850,8 @@ fn test_fast_calls_reciever() {
|
||||||
embedder_obj as _,
|
embedder_obj as _,
|
||||||
);
|
);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10848,16 +10896,36 @@ fn test_fast_calls_overload() {
|
||||||
assert_eq!(data.length(), 2);
|
assert_eq!(data.length(), 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, TypedArray(CType::Uint32)],
|
|
||||||
CType::Void,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Void.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Uint32,
|
||||||
|
fast_api::SequenceType::IsTypedArray,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const FAST_TEST2: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST2: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Sequence(CType::Void)],
|
|
||||||
CType::Void,
|
|
||||||
fast_fn2 as _,
|
fast_fn2 as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Void.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::CTypeInfo::new(
|
||||||
|
fast_api::Type::Void,
|
||||||
|
fast_api::SequenceType::IsSequence,
|
||||||
|
fast_api::Flags::empty(),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10877,13 +10945,8 @@ fn test_fast_calls_overload() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn).build_fast(
|
let template = v8::FunctionTemplate::builder(slow_fn)
|
||||||
scope,
|
.build_fast(scope, &[FAST_TEST, FAST_TEST2]);
|
||||||
&FAST_TEST,
|
|
||||||
None,
|
|
||||||
Some(&FAST_TEST2),
|
|
||||||
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();
|
||||||
|
@ -10928,10 +10991,16 @@ fn test_fast_calls_callback_options_fallback() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, CallbackOptions],
|
|
||||||
CType::Void,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Void.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::CallbackOptions.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -10951,8 +11020,8 @@ 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 =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -10986,20 +11055,26 @@ fn test_fast_calls_callback_options_data() {
|
||||||
options: *mut fast_api::FastApiCallbackOptions,
|
options: *mut fast_api::FastApiCallbackOptions,
|
||||||
) {
|
) {
|
||||||
let options = &mut *options;
|
let options = &mut *options;
|
||||||
if !options.data.data.is_external() {
|
if !options.data.is_external() {
|
||||||
options.fallback = true;
|
options.fallback = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let data = v8::Local::<v8::External>::cast_unchecked(options.data.data);
|
let data = v8::Local::<v8::External>::cast_unchecked(options.data);
|
||||||
let data = &mut *(data.value() as *mut bool);
|
let data = &mut *(data.value() as *mut bool);
|
||||||
*data = true;
|
*data = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, CallbackOptions],
|
|
||||||
CType::Void,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Void.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::CallbackOptions.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -11022,7 +11097,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, &FAST_TEST, None, None, None);
|
.build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -11103,10 +11178,16 @@ fn test_fast_calls_onebytestring() {
|
||||||
data.len() as u32
|
data.len() as u32
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, SeqOneByteString],
|
|
||||||
CType::Uint32,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint32.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::SeqOneByteString.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -11125,8 +11206,8 @@ fn test_fast_calls_onebytestring() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
@ -11162,18 +11243,31 @@ fn test_fast_calls_i64representation() {
|
||||||
a * b
|
a * b
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST_NUMBER: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST_NUMBER: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Uint64, Uint64],
|
|
||||||
CType::Uint64,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Uint64.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Uint64.scalar(),
|
||||||
|
fast_api::Type::Uint64.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
const FAST_TEST_BIGINT: fast_api::FastFunction =
|
const FAST_TEST_BIGINT: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
fast_api::FastFunction::new_with_bigint(
|
fast_fn as _,
|
||||||
&[V8Value, Uint64, Uint64],
|
&fast_api::CFunctionInfo::new(
|
||||||
CType::Uint64,
|
fast_api::Type::Uint64.scalar(),
|
||||||
fast_fn as _,
|
&[
|
||||||
);
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Uint64.scalar(),
|
||||||
|
fast_api::Type::Uint64.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::BigInt,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
_: &mut v8::HandleScope,
|
_: &mut v8::HandleScope,
|
||||||
|
@ -11191,20 +11285,10 @@ fn test_fast_calls_i64representation() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template_number = v8::FunctionTemplate::builder(slow_fn).build_fast(
|
let template_number = v8::FunctionTemplate::builder(slow_fn)
|
||||||
scope,
|
.build_fast(scope, &[FAST_TEST_NUMBER]);
|
||||||
&FAST_TEST_NUMBER,
|
let template_bigint = v8::FunctionTemplate::builder(slow_fn)
|
||||||
None,
|
.build_fast(scope, &[FAST_TEST_BIGINT]);
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
let template_bigint = v8::FunctionTemplate::builder(slow_fn).build_fast(
|
|
||||||
scope,
|
|
||||||
&FAST_TEST_BIGINT,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
|
|
||||||
let name_number = v8::String::new(scope, "func_number").unwrap();
|
let name_number = v8::String::new(scope, "func_number").unwrap();
|
||||||
let name_bigint = v8::String::new(scope, "func_bigint").unwrap();
|
let name_bigint = v8::String::new(scope, "func_bigint").unwrap();
|
||||||
|
@ -11338,10 +11422,16 @@ fn test_fast_calls_pointer() {
|
||||||
std::ptr::null_mut()
|
std::ptr::null_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
const FAST_TEST: fast_api::FastFunction = fast_api::FastFunction::new(
|
const FAST_TEST: fast_api::CFunction = fast_api::CFunction::new(
|
||||||
&[V8Value, Pointer],
|
|
||||||
fast_api::CType::Pointer,
|
|
||||||
fast_fn as _,
|
fast_fn as _,
|
||||||
|
&fast_api::CFunctionInfo::new(
|
||||||
|
fast_api::Type::Pointer.scalar(),
|
||||||
|
&[
|
||||||
|
fast_api::Type::V8Value.scalar(),
|
||||||
|
fast_api::Type::Pointer.scalar(),
|
||||||
|
],
|
||||||
|
fast_api::Int64Representation::Number,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
fn slow_fn(
|
fn slow_fn(
|
||||||
|
@ -11363,8 +11453,8 @@ fn test_fast_calls_pointer() {
|
||||||
|
|
||||||
let global = context.global(scope);
|
let global = context.global(scope);
|
||||||
|
|
||||||
let template = v8::FunctionTemplate::builder(slow_fn)
|
let template =
|
||||||
.build_fast(scope, &FAST_TEST, None, None, None);
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, &[FAST_TEST]);
|
||||||
|
|
||||||
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();
|
||||||
|
|
Loading…
Reference in a new issue