mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-01-21 21:50:20 -05:00
Add v8::Object [Get/Set]AlignedPointer[From/In]InternalField
(#1026)
This commit is contained in:
parent
2193d827b9
commit
08e1a1c361
3 changed files with 135 additions and 0 deletions
|
@ -1165,6 +1165,16 @@ const v8::Value* v8__Object__GetIndex(const v8::Object& self,
|
||||||
ptr_to_local(&self)->Get(ptr_to_local(&context), index));
|
ptr_to_local(&self)->Get(ptr_to_local(&context), index));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* v8__Object__GetAlignedPointerFromInternalField(const v8::Object& self,
|
||||||
|
int index) {
|
||||||
|
return ptr_to_local(&self)->GetAlignedPointerFromInternalField(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void v8__Object__SetAlignedPointerInInternalField(const v8::Object& self,
|
||||||
|
int index, void* value) {
|
||||||
|
ptr_to_local(&self)->SetAlignedPointerInInternalField(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
const v8::Value* v8__Object__GetPrototype(const v8::Object& self) {
|
const v8::Value* v8__Object__GetPrototype(const v8::Object& self) {
|
||||||
return local_to_ptr(ptr_to_local(&self)->GetPrototype());
|
return local_to_ptr(ptr_to_local(&self)->GetPrototype());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
use libc::c_void;
|
||||||
|
|
||||||
use crate::isolate::Isolate;
|
use crate::isolate::Isolate;
|
||||||
use crate::support::int;
|
use crate::support::int;
|
||||||
use crate::support::MapFnTo;
|
use crate::support::MapFnTo;
|
||||||
|
@ -120,6 +122,15 @@ extern "C" {
|
||||||
this: *const Object,
|
this: *const Object,
|
||||||
index: int,
|
index: int,
|
||||||
) -> *const Value;
|
) -> *const Value;
|
||||||
|
fn v8__Object__GetAlignedPointerFromInternalField(
|
||||||
|
this: *const Object,
|
||||||
|
index: int,
|
||||||
|
) -> *const c_void;
|
||||||
|
fn v8__Object__SetAlignedPointerInInternalField(
|
||||||
|
this: *const Object,
|
||||||
|
index: int,
|
||||||
|
value: *const c_void,
|
||||||
|
);
|
||||||
fn v8__Object__SetIntegrityLevel(
|
fn v8__Object__SetIntegrityLevel(
|
||||||
this: *const Object,
|
this: *const Object,
|
||||||
context: *const Context,
|
context: *const Context,
|
||||||
|
@ -512,6 +523,28 @@ impl Object {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Gets a 2-byte-aligned native pointer from an internal field.
|
||||||
|
///
|
||||||
|
/// # Safety
|
||||||
|
/// This field must have been set by SetAlignedPointerInInternalField, everything else leads to undefined behavior.
|
||||||
|
pub unsafe fn get_aligned_pointer_from_internal_field(
|
||||||
|
&self,
|
||||||
|
index: i32,
|
||||||
|
) -> *const c_void {
|
||||||
|
v8__Object__GetAlignedPointerFromInternalField(self, index)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets a 2-byte-aligned native pointer in an internal field.
|
||||||
|
/// To retrieve such a field, GetAlignedPointerFromInternalField must be used.
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
|
pub fn set_aligned_pointer_in_internal_field(
|
||||||
|
&self,
|
||||||
|
index: i32,
|
||||||
|
value: *const c_void,
|
||||||
|
) {
|
||||||
|
unsafe { v8__Object__SetAlignedPointerInInternalField(self, index, value) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Sets the integrity level of the object.
|
/// Sets the integrity level of the object.
|
||||||
pub fn set_integrity_level(
|
pub fn set_integrity_level(
|
||||||
&self,
|
&self,
|
||||||
|
|
|
@ -7247,3 +7247,95 @@ fn test_fast_calls_arraybuffer() {
|
||||||
eval(scope, source).unwrap();
|
eval(scope, source).unwrap();
|
||||||
assert_eq!("fast", unsafe { WHO });
|
assert_eq!("fast", unsafe { WHO });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_fast_calls_reciever() {
|
||||||
|
const V8_WRAPPER_TYPE_INDEX: i32 = 0;
|
||||||
|
const V8_WRAPPER_OBJECT_INDEX: i32 = 1;
|
||||||
|
|
||||||
|
static mut WHO: &str = "none";
|
||||||
|
fn fast_fn(recv: v8::Local<v8::Object>) -> u32 {
|
||||||
|
unsafe {
|
||||||
|
WHO = "fast";
|
||||||
|
let embedder_obj =
|
||||||
|
recv.get_aligned_pointer_from_internal_field(V8_WRAPPER_OBJECT_INDEX);
|
||||||
|
|
||||||
|
let i = *(embedder_obj as *const u32);
|
||||||
|
assert_eq!(i, 69);
|
||||||
|
i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
type Signature = fn(receiver: v8::Local<v8::Object>) -> u32;
|
||||||
|
fn function(&self) -> Self::Signature {
|
||||||
|
fast_fn
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn slow_fn(
|
||||||
|
scope: &mut v8::HandleScope,
|
||||||
|
_: v8::FunctionCallbackArguments,
|
||||||
|
mut rv: v8::ReturnValue,
|
||||||
|
) {
|
||||||
|
unsafe { WHO = "slow" };
|
||||||
|
rv.set(v8::Boolean::new(scope, false).into());
|
||||||
|
}
|
||||||
|
|
||||||
|
let _setup_guard = setup();
|
||||||
|
let isolate = &mut v8::Isolate::new(
|
||||||
|
v8::CreateParams::default().embedder_wrapper_type_info_offsets(
|
||||||
|
V8_WRAPPER_TYPE_INDEX,
|
||||||
|
V8_WRAPPER_OBJECT_INDEX,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
let scope = &mut v8::HandleScope::new(isolate);
|
||||||
|
let context = v8::Context::new(scope);
|
||||||
|
let scope = &mut v8::ContextScope::new(scope, context);
|
||||||
|
|
||||||
|
let object_template = v8::ObjectTemplate::new(scope);
|
||||||
|
assert!(object_template
|
||||||
|
.set_internal_field_count((V8_WRAPPER_OBJECT_INDEX + 1) as usize));
|
||||||
|
|
||||||
|
let obj = object_template.new_instance(scope).unwrap();
|
||||||
|
let embedder_obj = Box::into_raw(Box::new(69u32));
|
||||||
|
obj.set_aligned_pointer_in_internal_field(
|
||||||
|
V8_WRAPPER_OBJECT_INDEX,
|
||||||
|
embedder_obj as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
let template =
|
||||||
|
v8::FunctionTemplate::builder(slow_fn).build_fast(scope, FastTest);
|
||||||
|
|
||||||
|
let name = v8::String::new(scope, "method").unwrap();
|
||||||
|
let value = template.get_function(scope).unwrap();
|
||||||
|
obj.set(scope, name.into(), value.into()).unwrap();
|
||||||
|
|
||||||
|
let obj_str = v8::String::new(scope, "obj").unwrap();
|
||||||
|
let global = context.global(scope);
|
||||||
|
global.set(scope, obj_str.into(), obj.into()).unwrap();
|
||||||
|
|
||||||
|
let source = r#"
|
||||||
|
function f() { return obj.method(); }
|
||||||
|
%PrepareFunctionForOptimization(f);
|
||||||
|
f();
|
||||||
|
"#;
|
||||||
|
eval(scope, source).unwrap();
|
||||||
|
assert_eq!("slow", unsafe { WHO });
|
||||||
|
|
||||||
|
let source = r#"
|
||||||
|
%OptimizeFunctionOnNextCall(f);
|
||||||
|
f();
|
||||||
|
"#;
|
||||||
|
eval(scope, source).unwrap();
|
||||||
|
assert_eq!("fast", unsafe { WHO });
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue