mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-23 15:50:11 -05:00
Add ObjectTemplate::set_accessor{_with_setter}
(#687)
This commit is contained in:
parent
fbd6528e63
commit
6d25d19b4c
4 changed files with 129 additions and 2 deletions
|
@ -971,6 +971,19 @@ void v8__ObjectTemplate__SetInternalFieldCount(const v8::ObjectTemplate& self,
|
|||
ptr_to_local(&self)->SetInternalFieldCount(value);
|
||||
}
|
||||
|
||||
void v8__ObjectTemplate__SetAccessor(const v8::ObjectTemplate& self,
|
||||
const v8::Name& key,
|
||||
v8::AccessorNameGetterCallback getter) {
|
||||
ptr_to_local(&self)->SetAccessor(ptr_to_local(&key), getter);
|
||||
}
|
||||
|
||||
void v8__ObjectTemplate__SetAccessorWithSetter(
|
||||
const v8::ObjectTemplate& self, const v8::Name& key,
|
||||
v8::AccessorNameGetterCallback getter,
|
||||
v8::AccessorNameSetterCallback setter) {
|
||||
ptr_to_local(&self)->SetAccessor(ptr_to_local(&key), getter, setter);
|
||||
}
|
||||
|
||||
const v8::Object* v8__Object__New(v8::Isolate* isolate) {
|
||||
return local_to_ptr(v8::Object::New(isolate));
|
||||
}
|
||||
|
|
|
@ -213,7 +213,9 @@ pub struct PropertyCallbackArguments<'s> {
|
|||
}
|
||||
|
||||
impl<'s> PropertyCallbackArguments<'s> {
|
||||
fn from_property_callback_info(info: *const PropertyCallbackInfo) -> Self {
|
||||
pub(crate) fn from_property_callback_info(
|
||||
info: *const PropertyCallbackInfo,
|
||||
) -> Self {
|
||||
Self {
|
||||
info,
|
||||
phantom: PhantomData,
|
||||
|
|
|
@ -6,6 +6,8 @@ use crate::data::Template;
|
|||
use crate::isolate::Isolate;
|
||||
use crate::support::int;
|
||||
use crate::support::MapFnTo;
|
||||
use crate::AccessorNameGetterCallback;
|
||||
use crate::AccessorNameSetterCallback;
|
||||
use crate::CFunction;
|
||||
use crate::ConstructorBehavior;
|
||||
use crate::Context;
|
||||
|
@ -68,6 +70,17 @@ extern "C" {
|
|||
this: *const ObjectTemplate,
|
||||
value: int,
|
||||
);
|
||||
fn v8__ObjectTemplate__SetAccessor(
|
||||
this: *const ObjectTemplate,
|
||||
key: *const Name,
|
||||
getter: AccessorNameGetterCallback,
|
||||
);
|
||||
fn v8__ObjectTemplate__SetAccessorWithSetter(
|
||||
this: *const ObjectTemplate,
|
||||
key: *const Name,
|
||||
getter: AccessorNameGetterCallback,
|
||||
setter: AccessorNameSetterCallback,
|
||||
);
|
||||
}
|
||||
|
||||
impl Template {
|
||||
|
@ -228,4 +241,28 @@ impl ObjectTemplate {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_accessor(
|
||||
&self,
|
||||
key: Local<Name>,
|
||||
getter: impl for<'s> MapFnTo<AccessorNameGetterCallback<'s>>,
|
||||
) {
|
||||
unsafe { v8__ObjectTemplate__SetAccessor(self, &*key, getter.map_fn_to()) }
|
||||
}
|
||||
|
||||
pub fn set_accessor_with_setter(
|
||||
&self,
|
||||
key: Local<Name>,
|
||||
getter: impl for<'s> MapFnTo<AccessorNameGetterCallback<'s>>,
|
||||
setter: impl for<'s> MapFnTo<AccessorNameSetterCallback<'s>>,
|
||||
) {
|
||||
unsafe {
|
||||
v8__ObjectTemplate__SetAccessorWithSetter(
|
||||
self,
|
||||
&*key,
|
||||
getter.map_fn_to(),
|
||||
setter.map_fn_to(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1314,6 +1314,81 @@ fn function_template_signature() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object_template_set_accessor() {
|
||||
let _setup_guard = setup();
|
||||
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 getter = |scope: &mut v8::HandleScope,
|
||||
key: v8::Local<v8::Name>,
|
||||
args: v8::PropertyCallbackArguments,
|
||||
mut rv: v8::ReturnValue| {
|
||||
let this = args.this();
|
||||
|
||||
let expected_key = v8::String::new(scope, "key").unwrap();
|
||||
assert!(key.strict_equals(expected_key.into()));
|
||||
|
||||
rv.set(this.get_internal_field(scope, 0).unwrap());
|
||||
};
|
||||
|
||||
let setter = |scope: &mut v8::HandleScope,
|
||||
key: v8::Local<v8::Name>,
|
||||
value: v8::Local<v8::Value>,
|
||||
args: v8::PropertyCallbackArguments| {
|
||||
let this = args.this();
|
||||
|
||||
let expected_key = v8::String::new(scope, "key").unwrap();
|
||||
assert!(key.strict_equals(expected_key.into()));
|
||||
|
||||
assert!(value.is_int32());
|
||||
assert!(this.set_internal_field(0, value));
|
||||
};
|
||||
|
||||
let key = v8::String::new(scope, "key").unwrap();
|
||||
let name = v8::String::new(scope, "obj").unwrap();
|
||||
|
||||
// Lone getter
|
||||
let templ = v8::ObjectTemplate::new(scope);
|
||||
templ.set_internal_field_count(1);
|
||||
templ.set_accessor(key.into(), getter);
|
||||
|
||||
let obj = templ.new_instance(scope).unwrap();
|
||||
let int = v8::Integer::new(scope, 42);
|
||||
obj.set_internal_field(0, int.into());
|
||||
scope.get_current_context().global(scope).set(
|
||||
scope,
|
||||
name.into(),
|
||||
obj.into(),
|
||||
);
|
||||
assert!(eval(scope, "obj.key").unwrap().strict_equals(int.into()));
|
||||
|
||||
// Getter + setter
|
||||
let templ = v8::ObjectTemplate::new(scope);
|
||||
templ.set_internal_field_count(1);
|
||||
templ.set_accessor_with_setter(key.into(), getter, setter);
|
||||
|
||||
let obj = templ.new_instance(scope).unwrap();
|
||||
obj.set_internal_field(0, int.into());
|
||||
scope.get_current_context().global(scope).set(
|
||||
scope,
|
||||
name.into(),
|
||||
obj.into(),
|
||||
);
|
||||
let new_int = v8::Integer::new(scope, 9);
|
||||
eval(scope, "obj.key = 9");
|
||||
assert!(obj
|
||||
.get_internal_field(scope, 0)
|
||||
.unwrap()
|
||||
.strict_equals(new_int.into()));
|
||||
// Falls back on standard setter
|
||||
assert!(eval(scope, "obj.key2 = null; obj.key2").unwrap().is_null());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn object() {
|
||||
let _setup_guard = setup();
|
||||
|
@ -4352,7 +4427,7 @@ fn value_serializer_and_deserializer_js_objects() {
|
|||
} else {
|
||||
equal = equal && (item == objects[index]);
|
||||
}
|
||||
});
|
||||
});
|
||||
equal.toString()
|
||||
}
|
||||
"#,
|
||||
|
|
Loading…
Reference in a new issue