mirror of
https://github.com/denoland/rusty_v8.git
synced 2025-03-09 05:27:08 -04:00
feat: Add v8::Object::DefineProperty (#1172)
This commit is contained in:
parent
bc5660b4b2
commit
55e8a2d60d
5 changed files with 172 additions and 0 deletions
|
@ -1254,6 +1254,14 @@ MaybeBool v8__Object__DefineOwnProperty(const v8::Object& self,
|
|||
ptr_to_local(&context), ptr_to_local(&key), ptr_to_local(&value), attr));
|
||||
}
|
||||
|
||||
MaybeBool v8__Object__DefineProperty(const v8::Object& self,
|
||||
const v8::Context& context,
|
||||
const v8::Name& key,
|
||||
v8::PropertyDescriptor& desc) {
|
||||
return maybe_to_maybe_bool(ptr_to_local(&self)->DefineProperty(
|
||||
ptr_to_local(&context), ptr_to_local(&key), desc));
|
||||
}
|
||||
|
||||
MaybeBool v8__Object__SetAccessor(const v8::Object& self,
|
||||
const v8::Context& context,
|
||||
const v8::Name& key,
|
||||
|
@ -3228,3 +3236,36 @@ void icu_set_default_locale(const char* locale) {
|
|||
}
|
||||
|
||||
} // extern "C"
|
||||
|
||||
// v8::PropertyDescriptor
|
||||
|
||||
extern "C" {
|
||||
|
||||
static_assert(sizeof(v8::PropertyDescriptor) == sizeof(size_t),
|
||||
"v8::PropertyDescriptor size mismatch");
|
||||
|
||||
void v8__PropertyDescriptor__CONSTRUCT(uninit_t<v8::PropertyDescriptor>* buf) {
|
||||
construct_in_place<v8::PropertyDescriptor>(buf);
|
||||
}
|
||||
|
||||
void v8__PropertyDescriptor__CONSTRUCT__Get_Set(
|
||||
uninit_t<v8::PropertyDescriptor>* buf, v8::Local<v8::Value> get,
|
||||
v8::Local<v8::Value> set) {
|
||||
construct_in_place<v8::PropertyDescriptor>(buf, get, set);
|
||||
}
|
||||
|
||||
void v8__PropertyDescriptor__DESTRUCT(v8::PropertyDescriptor* self) {
|
||||
self->~PropertyDescriptor();
|
||||
}
|
||||
|
||||
void v8__PropertyDescriptor__set_enumerable(v8::PropertyDescriptor* self,
|
||||
bool enumurable) {
|
||||
self->set_enumerable(enumurable);
|
||||
}
|
||||
|
||||
void v8__PropertyDescriptor__set_configurable(v8::PropertyDescriptor* self,
|
||||
bool configurable) {
|
||||
self->set_configurable(configurable);
|
||||
}
|
||||
|
||||
} // extern "C"
|
||||
|
|
|
@ -57,6 +57,7 @@ mod primitives;
|
|||
mod private;
|
||||
mod promise;
|
||||
mod property_attribute;
|
||||
mod property_descriptor;
|
||||
mod property_filter;
|
||||
mod proxy;
|
||||
mod scope;
|
||||
|
@ -125,6 +126,7 @@ pub use primitives::*;
|
|||
pub use private::*;
|
||||
pub use promise::{PromiseRejectEvent, PromiseRejectMessage, PromiseState};
|
||||
pub use property_attribute::*;
|
||||
pub use property_descriptor::*;
|
||||
pub use property_filter::*;
|
||||
pub use proxy::*;
|
||||
pub use scope::CallbackScope;
|
||||
|
|
|
@ -17,6 +17,7 @@ use crate::Name;
|
|||
use crate::Object;
|
||||
use crate::Private;
|
||||
use crate::PropertyAttribute;
|
||||
use crate::PropertyDescriptor;
|
||||
use crate::PropertyFilter;
|
||||
use crate::Value;
|
||||
use std::convert::TryFrom;
|
||||
|
@ -86,6 +87,12 @@ extern "C" {
|
|||
value: *const Value,
|
||||
attr: PropertyAttribute,
|
||||
) -> MaybeBool;
|
||||
fn v8__Object__DefineProperty(
|
||||
this: *const Object,
|
||||
context: *const Context,
|
||||
key: *const Name,
|
||||
desc: *const PropertyDescriptor,
|
||||
) -> MaybeBool;
|
||||
fn v8__Object__GetIdentityHash(this: *const Object) -> int;
|
||||
fn v8__Object__GetCreationContext(this: *const Object) -> *const Context;
|
||||
fn v8__Object__GetOwnPropertyNames(
|
||||
|
@ -339,6 +346,24 @@ impl Object {
|
|||
.into()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn define_property(
|
||||
&self,
|
||||
scope: &mut HandleScope,
|
||||
key: Local<Name>,
|
||||
descriptor: &PropertyDescriptor,
|
||||
) -> Option<bool> {
|
||||
unsafe {
|
||||
v8__Object__DefineProperty(
|
||||
self,
|
||||
&*scope.get_current_context(),
|
||||
&*key,
|
||||
descriptor,
|
||||
)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn get<'s>(
|
||||
&self,
|
||||
|
|
75
src/property_descriptor.rs
Normal file
75
src/property_descriptor.rs
Normal file
|
@ -0,0 +1,75 @@
|
|||
use std::mem::size_of;
|
||||
use std::mem::MaybeUninit;
|
||||
|
||||
use crate::Local;
|
||||
use crate::Value;
|
||||
|
||||
extern "C" {
|
||||
fn v8__PropertyDescriptor__CONSTRUCT(out: *mut PropertyDescriptor);
|
||||
fn v8__PropertyDescriptor__CONSTRUCT__Get_Set(
|
||||
this: *const PropertyDescriptor,
|
||||
get: *const Value,
|
||||
set: *const Value,
|
||||
);
|
||||
fn v8__PropertyDescriptor__DESTRUCT(this: *mut PropertyDescriptor);
|
||||
fn v8__PropertyDescriptor__set_enumerable(
|
||||
this: *mut PropertyDescriptor,
|
||||
enumerable: bool,
|
||||
);
|
||||
fn v8__PropertyDescriptor__set_configurable(
|
||||
this: *mut PropertyDescriptor,
|
||||
configurable: bool,
|
||||
);
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct PropertyDescriptor([usize; 1]);
|
||||
|
||||
const _: () = {
|
||||
assert!(
|
||||
size_of::<PropertyDescriptor>() == size_of::<usize>(),
|
||||
"PropertyDescriptor size is not 1 usize"
|
||||
);
|
||||
};
|
||||
|
||||
impl Default for PropertyDescriptor {
|
||||
fn default() -> Self {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl PropertyDescriptor {
|
||||
pub fn new() -> Self {
|
||||
let mut this = MaybeUninit::<Self>::uninit();
|
||||
unsafe {
|
||||
v8__PropertyDescriptor__CONSTRUCT(this.as_mut_ptr());
|
||||
this.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new_from_get_set(get: Local<Value>, set: Local<Value>) -> Self {
|
||||
let mut this = MaybeUninit::<Self>::uninit();
|
||||
unsafe {
|
||||
v8__PropertyDescriptor__CONSTRUCT__Get_Set(
|
||||
this.as_mut_ptr(),
|
||||
&*get,
|
||||
&*set,
|
||||
);
|
||||
this.assume_init()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_enumerable(&mut self, enumerable: bool) {
|
||||
unsafe { v8__PropertyDescriptor__set_enumerable(self, enumerable) }
|
||||
}
|
||||
|
||||
pub fn set_configurable(&mut self, configurable: bool) {
|
||||
unsafe { v8__PropertyDescriptor__set_configurable(self, configurable) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for PropertyDescriptor {
|
||||
fn drop(&mut self) {
|
||||
unsafe { v8__PropertyDescriptor__DESTRUCT(self) }
|
||||
}
|
||||
}
|
|
@ -8966,3 +8966,32 @@ fn test_fast_calls_pointer() {
|
|||
eval(scope, source).unwrap();
|
||||
assert_eq!("fast", unsafe { WHO });
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_define_property() {
|
||||
let _setup_guard = setup::parallel_test();
|
||||
let isolate = &mut v8::Isolate::new(Default::default());
|
||||
{
|
||||
let scope = &mut v8::HandleScope::new(isolate);
|
||||
let context = v8::Context::new(scope);
|
||||
let scope = &mut v8::ContextScope::new(scope, context);
|
||||
|
||||
let mut desc = v8::PropertyDescriptor::new();
|
||||
desc.set_configurable(true);
|
||||
desc.set_enumerable(false);
|
||||
|
||||
let name = v8::String::new(scope, "g").unwrap();
|
||||
context
|
||||
.global(scope)
|
||||
.define_property(scope, name.into(), &desc);
|
||||
let source = r#"
|
||||
{
|
||||
const d = Object.getOwnPropertyDescriptor(globalThis, "g");
|
||||
[d.configurable, d.enumerable, d.writable].toString()
|
||||
}
|
||||
"#;
|
||||
let actual = eval(scope, source).unwrap();
|
||||
let expected = v8::String::new(scope, "true,false,false").unwrap();
|
||||
assert!(expected.strict_equals(actual));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue