0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-24 08:09:16 -05:00

Implement GetPrototype and SetPrototype on objects (#321)

This commit is contained in:
Max Bruce 2020-03-23 08:39:43 -07:00 committed by GitHub
parent c9b820894e
commit 6bf57abb5c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 0 deletions

View file

@ -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,

View file

@ -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,

View file

@ -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());
}
}