perf: optimize FunctionCallbackInfo and PropertyCallbackInfo methods (#1104)

This commit is contained in:
Bert Belder 2022-10-19 21:41:22 +02:00 committed by GitHub
parent c89ae9453b
commit d85f78527f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 368 additions and 183 deletions

View File

@ -31,9 +31,9 @@ fn main() {
}
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let scope = unsafe { &mut v8::CallbackScope::new(&*info) };
let mut rv =
unsafe { v8::ReturnValue::from_function_callback_info(info) };
let info = unsafe { &*info };
let scope = unsafe { &mut v8::CallbackScope::new(info) };
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set(v8::Integer::new(scope, 42).into());
}
let func = v8::Function::new_raw(scope, callback).unwrap();
@ -42,8 +42,8 @@ fn main() {
}
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let mut rv =
unsafe { v8::ReturnValue::from_function_callback_info(info) };
let info = unsafe { &*info };
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set_uint32(42);
}
let func = v8::Function::new_raw(scope, callback).unwrap();
@ -96,9 +96,9 @@ fn main() {
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let scope = unsafe { &mut v8::CallbackScope::new(&*info) };
let mut rv =
unsafe { v8::ReturnValue::from_function_callback_info(info) };
let info = unsafe { &*info };
let scope = unsafe { &mut v8::CallbackScope::new(info) };
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set(v8::undefined(scope).into());
}
let func = v8::Function::new_raw(scope, callback).unwrap();
@ -108,12 +108,11 @@ fn main() {
{
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let mut rv =
unsafe { v8::ReturnValue::from_function_callback_info(info) };
let mut info = unsafe {
v8::FunctionCallbackArguments::from_function_callback_info(info)
};
rv.set(v8::undefined(unsafe { info.get_isolate() }).into());
let info = unsafe { &*info };
let mut rv = v8::ReturnValue::from_function_callback_info(info);
let mut args =
v8::FunctionCallbackArguments::from_function_callback_info(info);
rv.set(v8::undefined(unsafe { args.get_isolate() }).into());
}
let func = v8::Function::new_raw(scope, callback).unwrap();
let name = v8::String::new(scope, "undefined_from_isolate").unwrap();

View File

@ -100,7 +100,7 @@ static_assert(offsetof(v8::ScriptCompiler::CachedData, buffer_policy) == 12,
#endif
extern "C" {
const extern size_t v8__internal__Internals__kIsolateEmbedderDataOffset =
const extern int v8__internal__Internals__kIsolateEmbedderDataOffset =
v8::internal::Internals::kIsolateEmbedderDataOffset;
void v8__V8__SetFlagsFromCommandLine(int* argc, char** argv,
@ -1908,39 +1908,15 @@ const v8::ObjectTemplate* v8__FunctionTemplate__InstanceTemplate(
return local_to_ptr(ptr_to_local(&self)->InstanceTemplate());
}
v8::Isolate* v8__FunctionCallbackInfo__GetIsolate(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return self.GetIsolate();
}
const extern int v8__FunctionCallbackInfo__kArgsLength =
v8::FunctionCallbackInfo<v8::Value>::kArgsLength;
v8::Value* v8__FunctionCallbackInfo__GetReturnValue(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return make_pod<v8::Value*>(self.GetReturnValue());
}
const extern int v8__PropertyCallbackInfo__kArgsLength =
v8::PropertyCallbackInfo<v8::Value>::kArgsLength;
const v8::Object* v8__FunctionCallbackInfo__This(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return local_to_ptr(self.This());
}
int v8__FunctionCallbackInfo__Length(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return self.Length();
}
const v8::Value* v8__FunctionCallbackInfo__GetArgument(
const v8::FunctionCallbackInfo<v8::Value>& self, int i) {
return local_to_ptr(self[i]);
}
const v8::Value* v8__FunctionCallbackInfo__Data(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return local_to_ptr(self.Data());
}
const v8::Value* v8__FunctionCallbackInfo__NewTarget(
const v8::FunctionCallbackInfo<v8::Value>& self) {
return local_to_ptr(self.NewTarget());
bool v8__PropertyCallbackInfo__ShouldThrowOnError(
const v8::PropertyCallbackInfo<v8::Value>& self) {
return self.ShouldThrowOnError();
}
void v8__ReturnValue__Set(v8::ReturnValue<v8::Value>* self,
@ -2290,21 +2266,6 @@ const v8::Value* v8__PromiseRejectMessage__GetValue(
return local_to_ptr(self.GetValue());
}
v8::Isolate* v8__PropertyCallbackInfo__GetIsolate(
const v8::PropertyCallbackInfo<v8::Value>& self) {
return self.GetIsolate();
}
v8::Value* v8__PropertyCallbackInfo__GetReturnValue(
const v8::PropertyCallbackInfo<v8::Value>& self) {
return make_pod<v8::Value*>(self.GetReturnValue());
}
const v8::Object* v8__PropertyCallbackInfo__This(
const v8::PropertyCallbackInfo<v8::Value>& self) {
return local_to_ptr(self.This());
}
const v8::Proxy* v8__Proxy__New(const v8::Context& context,
const v8::Object& target,
const v8::Object& handler) {

View File

@ -1,6 +1,7 @@
use std::convert::TryFrom;
use std::marker::PhantomData;
use std::ptr::null;
use std::ptr::NonNull;
use crate::scope::CallbackScope;
use crate::script_compiler::CachedData;
@ -9,6 +10,7 @@ use crate::support::MapFnTo;
use crate::support::ToCFn;
use crate::support::UnitType;
use crate::support::{int, Opaque};
use crate::undefined;
use crate::Context;
use crate::Function;
use crate::HandleScope;
@ -52,34 +54,13 @@ extern "C" {
script: *const Function,
) -> *mut CachedData<'static>;
fn v8__FunctionCallbackInfo__GetReturnValue(
info: *const FunctionCallbackInfo,
) -> *mut Value;
fn v8__FunctionCallbackInfo__This(
this: *const FunctionCallbackInfo,
) -> *const Object;
fn v8__FunctionCallbackInfo__Length(this: *const FunctionCallbackInfo)
-> int;
fn v8__FunctionCallbackInfo__GetArgument(
this: *const FunctionCallbackInfo,
i: int,
) -> *const Value;
fn v8__FunctionCallbackInfo__Data(
this: *const FunctionCallbackInfo,
) -> *const Value;
fn v8__FunctionCallbackInfo__NewTarget(
this: *const FunctionCallbackInfo,
) -> *const Value;
fn v8__FunctionCallbackInfo__GetIsolate(
this: *const FunctionCallbackInfo,
) -> *mut Isolate;
static v8__FunctionCallbackInfo__kArgsLength: int;
fn v8__PropertyCallbackInfo__GetReturnValue(
static v8__PropertyCallbackInfo__kArgsLength: int;
fn v8__PropertyCallbackInfo__ShouldThrowOnError(
this: *const PropertyCallbackInfo,
) -> *mut Value;
fn v8__PropertyCallbackInfo__This(
this: *const PropertyCallbackInfo,
) -> *const Object;
) -> bool;
fn v8__ReturnValue__Set(this: *mut ReturnValue, value: *const Value);
fn v8__ReturnValue__Set__Bool(this: *mut ReturnValue, value: bool);
@ -126,7 +107,7 @@ pub enum SideEffectType {
// is derived.
#[repr(C)]
#[derive(Debug)]
pub struct ReturnValue<'cb>(*mut Value, PhantomData<&'cb ()>);
pub struct ReturnValue<'cb>(NonNull<Value>, PhantomData<&'cb ()>);
/// In V8 ReturnValue<> has a type parameter, but
/// it turns out that in most of the APIs it's ReturnValue<Value>
@ -134,17 +115,15 @@ pub struct ReturnValue<'cb>(*mut Value, PhantomData<&'cb ()>);
/// other types. So for now it's a simplified version.
impl<'cb> ReturnValue<'cb> {
#[inline(always)]
pub unsafe fn from_function_callback_info(
info: *const FunctionCallbackInfo,
) -> Self {
let slot = v8__FunctionCallbackInfo__GetReturnValue(info);
Self(slot, PhantomData)
pub fn from_function_callback_info(info: &'cb FunctionCallbackInfo) -> Self {
let nn = info.get_return_value_non_null();
Self(nn, PhantomData)
}
#[inline(always)]
fn from_property_callback_info(info: *const PropertyCallbackInfo) -> Self {
let slot = unsafe { v8__PropertyCallbackInfo__GetReturnValue(info) };
Self(slot, PhantomData)
fn from_property_callback_info(info: &'cb PropertyCallbackInfo) -> Self {
let nn = info.get_return_value_non_null();
Self(nn, PhantomData)
}
#[inline(always)]
@ -205,11 +184,109 @@ impl<'cb> ReturnValue<'cb> {
pub struct FunctionCallbackInfo {
// The layout of this struct must match that of `class FunctionCallbackInfo`
// as defined in v8.h.
implicit_args: *mut Opaque,
values: *const Value,
implicit_args: *mut *const Opaque,
values: *mut *const Opaque,
length: int,
}
// These constants must match those defined on `class FunctionCallbackInfo` in
// v8-function-callback.h.
#[allow(dead_code, non_upper_case_globals)]
impl FunctionCallbackInfo {
const kHolderIndex: i32 = 0;
const kIsolateIndex: i32 = 1;
const kReturnValueDefaultValueIndex: i32 = 2;
const kReturnValueIndex: i32 = 3;
const kDataIndex: i32 = 4;
const kNewTargetIndex: i32 = 5;
const kArgsLength: i32 = 6;
}
impl FunctionCallbackInfo {
#[inline(always)]
pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
let arg_nn =
self.get_implicit_arg_non_null::<*mut Isolate>(Self::kIsolateIndex);
*unsafe { arg_nn.as_ref() }
}
#[inline(always)]
pub(crate) fn get_return_value_non_null(&self) -> NonNull<Value> {
self.get_implicit_arg_non_null::<Value>(Self::kReturnValueIndex)
}
#[inline(always)]
pub(crate) fn holder(&self) -> Local<Object> {
unsafe { self.get_implicit_arg_local(Self::kHolderIndex) }
}
#[inline(always)]
pub(crate) fn new_target(&self) -> Local<Value> {
unsafe { self.get_implicit_arg_local(Self::kNewTargetIndex) }
}
#[inline(always)]
pub(crate) fn this(&self) -> Local<Object> {
unsafe { self.get_arg_local(-1) }
}
#[inline(always)]
pub(crate) fn data(&self) -> Local<Value> {
unsafe { self.get_implicit_arg_local(Self::kDataIndex) }
}
#[inline(always)]
pub(crate) fn length(&self) -> i32 {
self.length
}
#[inline(always)]
pub(crate) fn get(&self, index: int) -> Local<Value> {
if index >= 0 && index < self.length {
unsafe { self.get_arg_local(index) }
} else {
let isolate = unsafe { &mut *self.get_isolate_ptr() };
undefined(isolate).into()
}
}
#[inline(always)]
fn get_implicit_arg_non_null<T>(&self, index: i32) -> NonNull<T> {
// In debug builds, check that `FunctionCallbackInfo::kArgsLength` matches
// the C++ definition. Unfortunately we can't check the other constants
// because they are declared protected in the C++ header.
debug_assert_eq!(
unsafe { v8__FunctionCallbackInfo__kArgsLength },
Self::kArgsLength
);
// Assert that `index` is in bounds.
assert!(index >= 0);
assert!(index < Self::kArgsLength);
// Compute the address of the implicit argument and cast to `NonNull<T>`.
let ptr = unsafe { self.implicit_args.offset(index as isize) as *mut T };
debug_assert!(!ptr.is_null());
unsafe { NonNull::new_unchecked(ptr) }
}
// SAFETY: caller must guarantee that the implicit argument at `index`
// contains a valid V8 handle.
#[inline(always)]
unsafe fn get_implicit_arg_local<T>(&self, index: i32) -> Local<T> {
let nn = self.get_implicit_arg_non_null::<T>(index);
Local::from_non_null(nn)
}
// SAFETY: caller must guarantee that the `index` value lies between -1 and
// self.length.
#[inline(always)]
unsafe fn get_arg_local<T>(&self, index: i32) -> Local<T> {
let ptr = self.values.offset(index as _) as *mut T;
debug_assert!(!ptr.is_null());
let nn = NonNull::new_unchecked(ptr);
Local::from_non_null(nn)
}
}
/// The information passed to a property callback about the context
/// of the property access.
#[repr(C)]
@ -217,89 +294,166 @@ pub struct FunctionCallbackInfo {
pub struct PropertyCallbackInfo {
// The layout of this struct must match that of `class PropertyCallbackInfo`
// as defined in v8.h.
args: *mut Opaque,
args: *mut *const Opaque,
}
#[derive(Debug)]
pub struct FunctionCallbackArguments<'s> {
info: *const FunctionCallbackInfo,
phantom: PhantomData<&'s ()>,
// These constants must match those defined on `class PropertyCallbackInfo` in
// v8-function-callback.h.
#[allow(dead_code, non_upper_case_globals)]
impl PropertyCallbackInfo {
const kShouldThrowOnErrorIndex: i32 = 0;
const kHolderIndex: i32 = 1;
const kIsolateIndex: i32 = 2;
const kReturnValueDefaultValueIndex: i32 = 3;
const kReturnValueIndex: i32 = 4;
const kDataIndex: i32 = 5;
const kThisIndex: i32 = 6;
const kArgsLength: i32 = 7;
}
impl<'s> FunctionCallbackArguments<'s> {
impl PropertyCallbackInfo {
#[inline(always)]
pub unsafe fn from_function_callback_info(
info: *const FunctionCallbackInfo,
) -> Self {
Self {
info,
phantom: PhantomData,
}
pub(crate) fn get_isolate_ptr(&self) -> *mut Isolate {
let arg_nn = self.get_arg_non_null::<*mut Isolate>(Self::kIsolateIndex);
*unsafe { arg_nn.as_ref() }
}
#[inline(always)]
pub(crate) fn get_return_value_non_null(&self) -> NonNull<Value> {
self.get_arg_non_null::<Value>(Self::kReturnValueIndex)
}
#[inline(always)]
pub(crate) fn holder(&self) -> Local<Object> {
unsafe { self.get_arg_local(Self::kHolderIndex) }
}
#[inline(always)]
pub(crate) fn this(&self) -> Local<Object> {
unsafe { self.get_arg_local(Self::kThisIndex) }
}
#[inline(always)]
pub(crate) fn data(&self) -> Local<Value> {
unsafe { self.get_arg_local(Self::kDataIndex) }
}
#[inline(always)]
pub(crate) fn should_throw_on_error(&self) -> bool {
unsafe { v8__PropertyCallbackInfo__ShouldThrowOnError(self) }
}
#[inline(always)]
fn get_arg_non_null<T>(&self, index: i32) -> NonNull<T> {
// In debug builds, verify that `PropertyCallbackInfo::kArgsLength` matches
// the C++ definition. Unfortunately we can't check the other constants
// because they are declared protected in the C++ header.
debug_assert_eq!(
unsafe { v8__PropertyCallbackInfo__kArgsLength },
Self::kArgsLength
);
// Assert that `index` is in bounds.
assert!(index >= 0);
assert!(index < Self::kArgsLength);
// Compute the address of the implicit argument and cast to `NonNull<T>`.
let ptr = unsafe { self.args.offset(index as isize) as *mut T };
debug_assert!(!ptr.is_null());
unsafe { NonNull::new_unchecked(ptr) }
}
// SAFETY: caller must guarantee that the implicit argument at `index`
// contains a valid V8 handle.
#[inline(always)]
unsafe fn get_arg_local<T>(&self, index: i32) -> Local<T> {
let nn = self.get_arg_non_null::<T>(index);
Local::from_non_null(nn)
}
}
#[derive(Debug)]
pub struct FunctionCallbackArguments<'s>(&'s FunctionCallbackInfo);
impl<'s> FunctionCallbackArguments<'s> {
#[inline(always)]
pub fn from_function_callback_info(info: &'s FunctionCallbackInfo) -> Self {
Self(info)
}
/// SAFETY: caller must guarantee that no other references to the isolate are
/// accessible. Specifically, if an open CallbackScope or HandleScope exists
/// in the current function, `FunctionCallbackArguments::get_isolate()` should
/// not be called.
#[inline(always)]
pub unsafe fn get_isolate(&mut self) -> &mut Isolate {
&mut *v8__FunctionCallbackInfo__GetIsolate(self.info)
&mut *self.0.get_isolate_ptr()
}
/// If the callback was created without a Signature, this is the same value as
/// `this()`. If there is a signature, and the signature didn't match `this()`
/// but one of its hidden prototypes, this will be the respective hidden
/// prototype.
///
/// Note that this is not the prototype of `this()` on which the accessor
/// referencing this callback was found (which in V8 internally is often
/// referred to as holder [sic]).
#[inline(always)]
pub fn holder(&self) -> Local<'s, Object> {
self.0.holder()
}
/// For construct calls, this returns the "new.target" value.
#[inline(always)]
pub fn new_target(&self) -> Local<'s, Value> {
self.0.new_target()
}
/// Returns the receiver. This corresponds to the "this" value.
#[inline(always)]
pub fn this(&self) -> Local<'s, Object> {
unsafe {
Local::from_raw(v8__FunctionCallbackInfo__This(self.info)).unwrap()
}
self.0.this()
}
/// Returns the data argument specified when creating the callback.
#[inline(always)]
pub fn data(&self) -> Option<Local<'s, Value>> {
unsafe { Local::from_raw(v8__FunctionCallbackInfo__Data(self.info)) }
pub fn data(&self) -> Local<'s, Value> {
self.0.data()
}
/// The number of available arguments.
#[inline(always)]
pub fn length(&self) -> int {
unsafe {
let length = (*self.info).length;
debug_assert_eq!(length, v8__FunctionCallbackInfo__Length(self.info));
length
}
self.0.length()
}
/// Accessor for the available arguments. Returns `undefined` if the index is
/// out of bounds.
#[inline(always)]
pub fn get(&self, i: int) -> Local<'s, Value> {
unsafe {
Local::from_raw(v8__FunctionCallbackInfo__GetArgument(self.info, i))
.unwrap()
}
}
/// For construct calls, this returns the "new.target" value.
#[inline(always)]
pub fn new_target(&self) -> Local<'s, Value> {
unsafe {
Local::from_raw(v8__FunctionCallbackInfo__NewTarget(self.info)).unwrap()
}
self.0.get(i)
}
}
#[derive(Debug)]
pub struct PropertyCallbackArguments<'s> {
info: *const PropertyCallbackInfo,
phantom: PhantomData<&'s ()>,
}
pub struct PropertyCallbackArguments<'s>(&'s PropertyCallbackInfo);
impl<'s> PropertyCallbackArguments<'s> {
#[inline(always)]
pub(crate) fn from_property_callback_info(
info: *const PropertyCallbackInfo,
info: &'s PropertyCallbackInfo,
) -> Self {
Self {
info,
phantom: PhantomData,
}
Self(info)
}
/// Returns he object in the prototype chain of the receiver that has the
/// interceptor. Suppose you have `x` and its prototype is `y`, and `y` has an
/// interceptor. Then `info.this()` is `x` and `info.holder()` is `y`. The
/// `holder()` could be a hidden object (the global object, rather than the
/// global proxy).
///
/// For security reasons, do not pass the object back into the runtime.
#[inline(always)]
pub fn holder(&self) -> Local<'s, Object> {
self.0.holder()
}
/// Returns the receiver. In many cases, this is the object on which the
@ -343,9 +497,25 @@ impl<'s> PropertyCallbackArguments<'s> {
/// ```
#[inline(always)]
pub fn this(&self) -> Local<'s, Object> {
unsafe {
Local::from_raw(v8__PropertyCallbackInfo__This(self.info)).unwrap()
}
self.0.this()
}
/// Returns the data set in the configuration, i.e., in
/// `NamedPropertyHandlerConfiguration` or
/// `IndexedPropertyHandlerConfiguration.`
#[inline(always)]
pub fn data(&self) -> Local<'s, Value> {
self.0.data()
}
/// Returns `true` if the intercepted function should throw if an error
/// occurs. Usually, `true` corresponds to `'use strict'`.
///
/// Always `false` when intercepting `Reflect.set()` independent of the
/// language mode.
#[inline(always)]
pub fn should_throw_on_error(&self) -> bool {
self.0.should_throw_on_error()
}
}
@ -358,10 +528,10 @@ where
{
fn mapping() -> Self {
let f = |info: *const FunctionCallbackInfo| {
let scope = &mut unsafe { CallbackScope::new(&*info) };
let args =
unsafe { FunctionCallbackArguments::from_function_callback_info(info) };
let rv = unsafe { ReturnValue::from_function_callback_info(info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = FunctionCallbackArguments::from_function_callback_info(info);
let rv = ReturnValue::from_function_callback_info(info);
(F::get())(scope, args, rv);
};
f.to_c_fn()
@ -380,7 +550,8 @@ where
{
fn mapping() -> Self {
let f = |key: Local<Name>, info: *const PropertyCallbackInfo| {
let scope = &mut unsafe { CallbackScope::new(&*info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, key, args, rv);
@ -401,7 +572,8 @@ where
let f = |key: Local<Name>,
value: Local<Value>,
info: *const PropertyCallbackInfo| {
let scope = &mut unsafe { CallbackScope::new(&*info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
(F::get())(scope, key, value, args);
};
@ -419,8 +591,8 @@ where
{
fn mapping() -> Self {
let f = |info: *const PropertyCallbackInfo| {
let info = info as *const PropertyCallbackInfo;
let scope = &mut unsafe { CallbackScope::new(&*info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, args, rv);
@ -441,7 +613,8 @@ where
{
fn mapping() -> Self {
let f = |index: u32, info: *const PropertyCallbackInfo| {
let scope = &mut unsafe { CallbackScope::new(&*info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
let rv = ReturnValue::from_property_callback_info(info);
(F::get())(scope, index, args, rv);
@ -461,7 +634,8 @@ where
fn mapping() -> Self {
let f =
|index: u32, value: Local<Value>, info: *const PropertyCallbackInfo| {
let scope = &mut unsafe { CallbackScope::new(&*info) };
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = PropertyCallbackArguments::from_property_callback_info(info);
(F::get())(scope, index, value, args);
};

View File

@ -7,6 +7,7 @@ use crate::isolate_create_params::CreateParams;
use crate::promise::PromiseRejectMessage;
use crate::scope::data::ScopeData;
use crate::snapshot::SnapshotCreator;
use crate::support::int;
use crate::support::Allocated;
use crate::support::MapFnFrom;
use crate::support::MapFnTo;
@ -340,7 +341,7 @@ pub type PrepareStackTraceCallback<'s> =
) -> PrepareStackTraceCallbackRet;
extern "C" {
static v8__internal__Internals__kIsolateEmbedderDataOffset: usize;
static v8__internal__Internals__kIsolateEmbedderDataOffset: int;
fn v8__Isolate__New(params: *const raw::CreateParams) -> *mut Isolate;
fn v8__Isolate__Dispose(this: *mut Isolate);
@ -510,7 +511,7 @@ impl Isolate {
Self::EMBEDDER_DATA_SLOT_COUNT
);
assert_eq!(
unsafe { v8__internal__Internals__kIsolateEmbedderDataOffset },
unsafe { v8__internal__Internals__kIsolateEmbedderDataOffset } as usize,
Self::EMBEDDER_DATA_OFFSET
);
}

View File

@ -903,13 +903,13 @@ mod getter {
impl<'s> GetIsolate<'s> for &'s FunctionCallbackInfo {
unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
&mut *raw::v8__FunctionCallbackInfo__GetIsolate(self)
&mut *self.get_isolate_ptr()
}
}
impl<'s> GetIsolate<'s> for &'s PropertyCallbackInfo {
unsafe fn get_isolate_mut(self) -> &'s mut Isolate {
&mut *raw::v8__PropertyCallbackInfo__GetIsolate(self)
&mut *self.get_isolate_ptr()
}
}
@ -1733,12 +1733,6 @@ mod raw {
pub(super) fn v8__Message__GetIsolate(this: *const Message)
-> *mut Isolate;
pub(super) fn v8__Object__GetIsolate(this: *const Object) -> *mut Isolate;
pub(super) fn v8__FunctionCallbackInfo__GetIsolate(
this: *const FunctionCallbackInfo,
) -> *mut Isolate;
pub(super) fn v8__PropertyCallbackInfo__GetIsolate(
this: *const PropertyCallbackInfo,
) -> *mut Isolate;
}
}

View File

@ -181,15 +181,14 @@ where
where
F: UnitType + Fn(&mut HandleScope, Local<Value>, WasmStreaming),
{
let scope = &mut unsafe { CallbackScope::new(&*info) };
let args =
unsafe { FunctionCallbackArguments::from_function_callback_info(info) };
let data = args.data().unwrap(); // Always present.
let data = &*data as *const Value;
let info = unsafe { &*info };
let scope = &mut unsafe { CallbackScope::new(info) };
let args = FunctionCallbackArguments::from_function_callback_info(info);
let data = args.data();
let zero = null_mut();
let mut that = WasmStreamingSharedPtr([zero, zero]);
unsafe {
v8__WasmStreaming__Unpack(scope.get_isolate_ptr(), data, &mut that)
v8__WasmStreaming__Unpack(scope.get_isolate_ptr(), &*data, &mut that)
};
let source = args.get(0);
(F::get())(scope, source, WasmStreaming(that));

View File

@ -1634,6 +1634,10 @@ fn instance_template_with_internal_field() {
mut retval: v8::ReturnValue,
) {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(this.set_internal_field(0, v8::Integer::new(scope, 42).into()));
retval.set(this.into())
}
@ -1671,6 +1675,10 @@ fn object_template_set_accessor() {
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -1683,6 +1691,10 @@ fn object_template_set_accessor() {
args: v8::PropertyCallbackArguments| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -1737,6 +1749,10 @@ fn object_template_set_accessor() {
_: v8::ReturnValue,
) {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
let ret = v8::Integer::new(scope, 69);
assert!(this.set_internal_field(0, ret.into()));
}
@ -1794,6 +1810,10 @@ fn object_template_set_named_property_handler() {
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -1806,6 +1826,10 @@ fn object_template_set_named_property_handler() {
args: v8::PropertyCallbackArguments| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -1819,6 +1843,10 @@ fn object_template_set_named_property_handler() {
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "key").unwrap();
assert!(key.strict_equals(expected_key.into()));
//PropertyAttribute::READ_ONLY
@ -1843,7 +1871,12 @@ fn object_template_set_named_property_handler() {
args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue| {
let this = args.this();
//Validate is the current object
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
// Validate is the current object.
let expected_value = v8::Integer::new(scope, 42);
assert!(this
.get_internal_field(scope, 0)
@ -1962,6 +1995,11 @@ fn object_template_set_indexed_property_handler() {
args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_index = 37;
assert!(index.eq(&expected_index));
rv.set(this.get_internal_field(scope, 0).unwrap());
@ -1973,6 +2011,10 @@ fn object_template_set_indexed_property_handler() {
args: v8::PropertyCallbackArguments| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
assert_eq!(index, 37);
assert!(value.is_int32());
@ -1992,7 +2034,12 @@ fn object_template_set_indexed_property_handler() {
args: v8::PropertyCallbackArguments,
mut rv: v8::ReturnValue| {
let this = args.this();
//Validate is the current object
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
// Validate is the current object.
let expected_value = v8::Integer::new(scope, 42);
assert!(this
.get_internal_field(scope, 0)
@ -2295,6 +2342,10 @@ fn object_set_accessor() {
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "getter_key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -2349,6 +2400,10 @@ fn object_set_accessor_with_setter() {
mut rv: v8::ReturnValue| {
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "getter_setter_key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -2369,8 +2424,13 @@ fn object_set_accessor_with_setter() {
value: v8::Local<v8::Value>,
args: v8::PropertyCallbackArguments| {
println!("setter called");
let this = args.this();
assert_eq!(args.holder(), this);
assert!(args.data().is_undefined());
assert!(!args.should_throw_on_error());
let expected_key = v8::String::new(scope, "getter_setter_key").unwrap();
assert!(key.strict_equals(expected_key.into()));
@ -2507,7 +2567,7 @@ fn fn_callback_external(
mut rv: v8::ReturnValue,
) {
assert_eq!(args.length(), 0);
let data = args.data().unwrap();
let data = args.data();
let external = v8::Local::<v8::External>::try_from(data).unwrap();
let data =
unsafe { std::slice::from_raw_parts(external.value() as *mut u8, 5) };
@ -2578,8 +2638,6 @@ fn data_is_true_callback(
_rv: v8::ReturnValue,
) {
let data = args.data();
assert!(data.is_some());
let data = data.unwrap();
assert!(data.is_true());
}
@ -2610,15 +2668,14 @@ fn function_builder_raw() {
let recv: v8::Local<v8::Value> = global.into();
extern "C" fn callback(info: *const v8::FunctionCallbackInfo) {
let scope = unsafe { &mut v8::CallbackScope::new(&*info) };
let args = unsafe {
v8::FunctionCallbackArguments::from_function_callback_info(info)
};
let info = unsafe { &*info };
let scope = unsafe { &mut v8::CallbackScope::new(info) };
let args =
v8::FunctionCallbackArguments::from_function_callback_info(info);
assert!(args.length() == 1);
assert!(args.get(0).is_string());
let mut rv =
unsafe { v8::ReturnValue::from_function_callback_info(info) };
let mut rv = v8::ReturnValue::from_function_callback_info(info);
rv.set(
v8::String::new(scope, "Hello from function!")
.unwrap()