mirror of
https://github.com/denoland/rusty_v8.git
synced 2024-12-23 15:50:11 -05:00
Implement GetPrototype and SetPrototype on objects (#321)
This commit is contained in:
parent
c9b820894e
commit
6bf57abb5c
3 changed files with 96 additions and 0 deletions
|
@ -726,6 +726,10 @@ v8::Value* v8__Object__GetIndex(v8::Object& self,
|
|||
return maybe_local_to_ptr(self.Get(context, index));
|
||||
}
|
||||
|
||||
v8::Value* v8__Object__GetPrototype(v8::Object& self) {
|
||||
return local_to_ptr(self.GetPrototype());
|
||||
}
|
||||
|
||||
MaybeBool v8__Object__Set(v8::Object& self, v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Value> key,
|
||||
v8::Local<v8::Value> value) {
|
||||
|
@ -737,6 +741,12 @@ MaybeBool v8__Object__SetIndex(v8::Object& self, v8::Local<v8::Context> context,
|
|||
return maybe_to_maybe_bool(self.Set(context, index, value));
|
||||
}
|
||||
|
||||
MaybeBool v8__Object__SetPrototype(v8::Object& self,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Value> prototype) {
|
||||
return maybe_to_maybe_bool(self.SetPrototype(context, prototype));
|
||||
}
|
||||
|
||||
MaybeBool v8__Object__CreateDataProperty(v8::Object& self,
|
||||
v8::Local<v8::Context> context,
|
||||
v8::Local<v8::Name> key,
|
||||
|
|
|
@ -37,6 +37,7 @@ extern "C" {
|
|||
context: Local<Context>,
|
||||
index: u32,
|
||||
) -> *mut Value;
|
||||
fn v8__Object__GetPrototype(object: &Object) -> *mut Value;
|
||||
fn v8__Object__Set(
|
||||
object: &Object,
|
||||
context: Local<Context>,
|
||||
|
@ -49,6 +50,11 @@ extern "C" {
|
|||
index: u32,
|
||||
value: Local<Value>,
|
||||
) -> MaybeBool;
|
||||
fn v8__Object__SetPrototype(
|
||||
object: &Object,
|
||||
context: Local<Context>,
|
||||
prototype: Local<Value>,
|
||||
) -> MaybeBool;
|
||||
fn v8__Object__CreateDataProperty(
|
||||
object: &Object,
|
||||
context: Local<Context>,
|
||||
|
@ -128,6 +134,16 @@ impl Object {
|
|||
unsafe { v8__Object__SetIndex(self, context, index, value) }.into()
|
||||
}
|
||||
|
||||
/// Set the prototype object. This does not skip objects marked to be
|
||||
/// skipped by proto and it does not consult the security handler.
|
||||
pub fn set_prototype(
|
||||
&self,
|
||||
context: Local<Context>,
|
||||
prototype: Local<Value>,
|
||||
) -> Option<bool> {
|
||||
unsafe { v8__Object__SetPrototype(self, context, prototype) }.into()
|
||||
}
|
||||
|
||||
/// Implements CreateDataProperty (ECMA-262, 7.3.4).
|
||||
///
|
||||
/// Defines a configurable, writable, enumerable property with the given value
|
||||
|
@ -185,6 +201,18 @@ impl Object {
|
|||
}
|
||||
}
|
||||
|
||||
/// Get the prototype object. This does not skip objects marked to be
|
||||
/// skipped by proto and it does not consult the security handler.
|
||||
pub fn get_prototype<'a>(
|
||||
&self,
|
||||
scope: &mut impl ToLocal<'a>,
|
||||
) -> Option<Local<'a, Value>> {
|
||||
unsafe {
|
||||
let ptr = v8__Object__GetPrototype(self);
|
||||
scope.to_local(ptr)
|
||||
}
|
||||
}
|
||||
|
||||
/// Note: SideEffectType affects the getter only, not the setter.
|
||||
pub fn set_accessor(
|
||||
&mut self,
|
||||
|
|
|
@ -2805,3 +2805,61 @@ fn take_heap_snapshot() {
|
|||
assert!(s.find(r#""Eyecatcher""#).is_some());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prototype_api() {
|
||||
let _setup_guard = setup();
|
||||
let mut params = v8::Isolate::create_params();
|
||||
params.set_array_buffer_allocator(v8::new_default_allocator());
|
||||
let mut isolate = v8::Isolate::new(params);
|
||||
{
|
||||
let mut hs = v8::HandleScope::new(&mut isolate);
|
||||
let scope = hs.enter();
|
||||
let context = v8::Context::new(scope);
|
||||
let mut cs = v8::ContextScope::new(scope, context);
|
||||
let scope = cs.enter();
|
||||
|
||||
let obj = v8::Object::new(scope);
|
||||
let proto_obj = v8::Object::new(scope);
|
||||
let key_local: v8::Local<v8::Value> =
|
||||
v8::String::new(scope, "test_proto_key").unwrap().into();
|
||||
let value_local: v8::Local<v8::Value> =
|
||||
v8::String::new(scope, "test_proto_value").unwrap().into();
|
||||
proto_obj.set(context, key_local, value_local);
|
||||
obj.set_prototype(context, proto_obj.into());
|
||||
|
||||
assert!(obj
|
||||
.get_prototype(scope)
|
||||
.unwrap()
|
||||
.same_value(proto_obj.into()));
|
||||
|
||||
let sub_gotten = obj.get(scope, context, key_local).unwrap();
|
||||
assert!(sub_gotten.is_string());
|
||||
let sub_gotten = sub_gotten.to_string(scope).unwrap();
|
||||
assert_eq!(sub_gotten.to_rust_string_lossy(scope), "test_proto_value");
|
||||
}
|
||||
{
|
||||
let mut hs = v8::HandleScope::new(&mut isolate);
|
||||
let scope = hs.enter();
|
||||
let context = v8::Context::new(scope);
|
||||
let mut cs = v8::ContextScope::new(scope, context);
|
||||
let scope = cs.enter();
|
||||
|
||||
let obj = v8::Object::new(scope);
|
||||
obj.set_prototype(context, v8::null(scope).into());
|
||||
|
||||
assert!(obj.get_prototype(scope).unwrap().is_null());
|
||||
}
|
||||
{
|
||||
let mut hs = v8::HandleScope::new(&mut isolate);
|
||||
let scope = hs.enter();
|
||||
let context = v8::Context::new(scope);
|
||||
let mut cs = v8::ContextScope::new(scope, context);
|
||||
let scope = cs.enter();
|
||||
|
||||
let val = eval(scope, context, "({ __proto__: null })").unwrap();
|
||||
let obj = val.to_object(scope).unwrap();
|
||||
|
||||
assert!(obj.get_prototype(scope).unwrap().is_null());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue