0
0
Fork 0
mirror of https://github.com/denoland/rusty_v8.git synced 2024-12-25 00:29:14 -05:00

Refactor v8::Object bindings (#243)

* Rename `Object::new2()` to `Object::with_prototype_and_properties()`.
* Make `Object::with_prototype_and_properties()` take a slice of keys
  and a slice of values as arguments, instead of using
  `Vec<v8::Local<v8::Name>>` and `Vec<v8::Local<v8::Value>>>`.
* Remove type `MaybeBool` from the public interface. These methods now
  return `Option<bool>` instead.
* Fix parameter type mismatches between Rust and C++ APIs.
This commit is contained in:
Bert Belder 2020-01-22 22:58:31 +01:00
parent dcb94533f8
commit 8617f77fd3
No known key found for this signature in database
GPG key ID: 7A77887B2E2ED461
5 changed files with 62 additions and 84 deletions

View file

@ -658,10 +658,9 @@ v8::Object* v8__Object__New(v8::Isolate* isolate) {
return local_to_ptr(v8::Object::New(isolate)); return local_to_ptr(v8::Object::New(isolate));
} }
v8::Object* v8__Object__New2(v8::Isolate* isolate, v8::Object* v8__Object__New__with_prototype_and_properties(
v8::Local<v8::Value> prototype_or_null, v8::Isolate* isolate, v8::Local<v8::Value> prototype_or_null,
v8::Local<v8::Name>* names, v8::Local<v8::Name>* names, v8::Local<v8::Value>* values, size_t length) {
v8::Local<v8::Value>* values, size_t length) {
return local_to_ptr( return local_to_ptr(
v8::Object::New(isolate, prototype_or_null, names, values, length)); v8::Object::New(isolate, prototype_or_null, names, values, length));
} }

View file

@ -162,7 +162,6 @@ pub use snapshot::OwnedStartupData;
pub use snapshot::SnapshotCreator; pub use snapshot::SnapshotCreator;
pub use snapshot::StartupData; pub use snapshot::StartupData;
pub use string::NewStringType; pub use string::NewStringType;
pub use support::MaybeBool;
pub use support::SharedRef; pub use support::SharedRef;
pub use support::UniquePtr; pub use support::UniquePtr;
pub use support::UniqueRef; pub use support::UniqueRef;

View file

@ -14,42 +14,41 @@ use crate::Value;
extern "C" { extern "C" {
fn v8__Object__New(isolate: *mut Isolate) -> *mut Object; fn v8__Object__New(isolate: *mut Isolate) -> *mut Object;
fn v8__Object__New2( fn v8__Object__New__with_prototype_and_properties(
isolate: *mut Isolate, isolate: *mut Isolate,
prototype_or_null: *mut Value, prototype_or_null: Local<Value>,
names: *mut *mut Name, names: *mut Local<Name>,
values: *mut *mut Value, values: *mut Local<Value>,
length: usize, length: usize,
) -> *mut Object; ) -> *mut Object;
fn v8__Object__SetAccessor( fn v8__Object__SetAccessor(
self_: &Object, self_: &Object,
context: *const Context, context: Local<Context>,
name: *const Name, name: Local<Name>,
getter: AccessorNameGetterCallback, getter: AccessorNameGetterCallback,
) -> MaybeBool; ) -> MaybeBool;
fn v8__Object__Get( fn v8__Object__Get(
object: &Object, object: &Object,
context: *const Context, context: Local<Context>,
key: *const Value, key: Local<Value>,
) -> *mut Value; ) -> *mut Value;
fn v8__Object__Set( fn v8__Object__Set(
object: &Object, object: &Object,
context: *const Context, context: Local<Context>,
key: *const Value, key: Local<Value>,
value: *const Value, value: Local<Value>,
) -> MaybeBool; ) -> MaybeBool;
fn v8__Object__CreateDataProperty( fn v8__Object__CreateDataProperty(
object: &Object, object: &Object,
context: *const Context, context: Local<Context>,
key: *const Name, key: Local<Name>,
value: *const Value, value: Local<Value>,
) -> MaybeBool; ) -> MaybeBool;
fn v8__Object__DefineOwnProperty( fn v8__Object__DefineOwnProperty(
object: &Object, object: &Object,
context: *const Context, context: Local<Context>,
key: *const Name, key: Local<Name>,
value: *const Value, value: Local<Value>,
attr: PropertyAttribute, attr: PropertyAttribute,
) -> MaybeBool; ) -> MaybeBool;
fn v8__Object__GetIdentityHash(object: &Object) -> int; fn v8__Object__GetIdentityHash(object: &Object) -> int;
@ -70,35 +69,23 @@ impl Object {
/// a prototype at all). This is similar to Object.create(). /// a prototype at all). This is similar to Object.create().
/// All properties will be created as enumerable, configurable /// All properties will be created as enumerable, configurable
/// and writable properties. /// and writable properties.
pub fn new2<'sc>( pub fn with_prototype_and_properties<'sc>(
scope: &mut impl ToLocal<'sc>, scope: &mut impl ToLocal<'sc>,
mut prototype_or_null: Local<'sc, Value>, prototype_or_null: Local<'sc, Value>,
names: Vec<Local<'sc, Name>>, names: &[Local<Name>],
values: Vec<Local<'sc, Value>>, values: &[Local<Value>],
) -> Local<'sc, Object> { ) -> Local<'sc, Object> {
let length = names.len(); assert_eq!(names.len(), values.len());
assert_eq!(length, values.len()); unsafe {
let mut names_: Vec<*mut Name> = vec![]; let object = v8__Object__New__with_prototype_and_properties(
for mut name in names {
let n = &mut *name;
names_.push(n);
}
let mut values_: Vec<*mut Value> = vec![];
for mut value in values {
let n = &mut *value;
values_.push(n);
}
let ptr = unsafe {
v8__Object__New2(
scope.isolate(), scope.isolate(),
&mut *prototype_or_null, prototype_or_null,
names_.as_mut_ptr(), names.as_ptr() as *mut Local<Name>,
values_.as_mut_ptr(), values.as_ptr() as *mut Local<Value>,
length, names.len(),
) );
}; scope.to_local(object).unwrap()
unsafe { scope.to_local(ptr) }.unwrap() }
} }
/// Set only return Just(true) or Empty(), so if it should never fail, use /// Set only return Just(true) or Empty(), so if it should never fail, use
@ -108,8 +95,8 @@ impl Object {
context: Local<Context>, context: Local<Context>,
key: Local<Value>, key: Local<Value>,
value: Local<Value>, value: Local<Value>,
) -> MaybeBool { ) -> Option<bool> {
unsafe { v8__Object__Set(self, &*context, &*key, &*value) } unsafe { v8__Object__Set(self, context, key, value) }.into()
} }
/// Implements CreateDataProperty (ECMA-262, 7.3.4). /// Implements CreateDataProperty (ECMA-262, 7.3.4).
@ -124,8 +111,8 @@ impl Object {
context: Local<Context>, context: Local<Context>,
key: Local<Name>, key: Local<Name>,
value: Local<Value>, value: Local<Value>,
) -> MaybeBool { ) -> Option<bool> {
unsafe { v8__Object__CreateDataProperty(self, &*context, &*key, &*value) } unsafe { v8__Object__CreateDataProperty(self, context, key, value) }.into()
} }
/// Implements DefineOwnProperty. /// Implements DefineOwnProperty.
@ -140,10 +127,9 @@ impl Object {
key: Local<Name>, key: Local<Name>,
value: Local<Value>, value: Local<Value>,
attr: PropertyAttribute, attr: PropertyAttribute,
) -> MaybeBool { ) -> Option<bool> {
unsafe { unsafe { v8__Object__DefineOwnProperty(self, context, key, value, attr) }
v8__Object__DefineOwnProperty(self, &*context, &*key, &*value, attr) .into()
}
} }
pub fn get<'a>( pub fn get<'a>(
@ -153,7 +139,7 @@ impl Object {
key: Local<Value>, key: Local<Value>,
) -> Option<Local<'a, Value>> { ) -> Option<Local<'a, Value>> {
unsafe { unsafe {
let ptr = v8__Object__Get(self, &*context, &*key); let ptr = v8__Object__Get(self, context, key);
scope.to_local(ptr) scope.to_local(ptr)
} }
} }
@ -164,10 +150,9 @@ impl Object {
context: Local<Context>, context: Local<Context>,
name: Local<Name>, name: Local<Name>,
getter: impl for<'s> MapFnTo<AccessorNameGetterCallback<'s>>, getter: impl for<'s> MapFnTo<AccessorNameGetterCallback<'s>>,
) -> MaybeBool { ) -> Option<bool> {
unsafe { unsafe { v8__Object__SetAccessor(self, context, name, getter.map_fn_to()) }
v8__Object__SetAccessor(self, &*context, &*name, getter.map_fn_to()) .into()
}
} }
/// Returns the identity hash for this object. The current implementation /// Returns the identity hash for this object. The current implementation

View file

@ -236,7 +236,7 @@ where
#[repr(C)] #[repr(C)]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub enum MaybeBool { pub(crate) enum MaybeBool {
JustFalse = 0, JustFalse = 0,
JustTrue = 1, JustTrue = 1,
Nothing = 2, Nothing = 2,

View file

@ -1013,15 +1013,16 @@ fn object() {
let mut cs = v8::ContextScope::new(scope, context); let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter(); let scope = cs.enter();
let null: v8::Local<v8::Value> = v8::null(scope).into(); let null: v8::Local<v8::Value> = v8::null(scope).into();
let s1 = v8::String::new(scope, "a").unwrap(); let n1: v8::Local<v8::Name> = v8::String::new(scope, "a").unwrap().into();
let s2 = v8::String::new(scope, "b").unwrap(); let n2: v8::Local<v8::Name> = v8::String::new(scope, "b").unwrap().into();
let name1 = s1.into();
let name2 = s2.into();
let names = vec![name1, name2];
let v1: v8::Local<v8::Value> = v8::Number::new(scope, 1.0).into(); let v1: v8::Local<v8::Value> = v8::Number::new(scope, 1.0).into();
let v2: v8::Local<v8::Value> = v8::Number::new(scope, 2.0).into(); let v2: v8::Local<v8::Value> = v8::Number::new(scope, 2.0).into();
let values = vec![v1, v2]; let object = v8::Object::with_prototype_and_properties(
let object = v8::Object::new2(scope, null, names, values); scope,
null,
&[n1, n2],
&[v1, v2],
);
assert!(!object.is_null_or_undefined()); assert!(!object.is_null_or_undefined());
let object_ = v8::Object::new(scope); let object_ = v8::Object::new(scope);
@ -1088,18 +1089,14 @@ fn create_data_property() {
let obj = obj.to_object(scope).unwrap(); let obj = obj.to_object(scope).unwrap();
let key = v8_str(scope, "foo"); let key = v8_str(scope, "foo");
let value = v8_str(scope, "bar"); let value = v8_str(scope, "bar");
assert_eq!( assert!(obj
obj.create_data_property(context, key.into(), value.into()), .create_data_property(context, key.into(), value.into())
v8::MaybeBool::JustTrue .unwrap());
);
let actual = obj.get(scope, context, key.into()).unwrap(); let actual = obj.get(scope, context, key.into()).unwrap();
assert!(value.strict_equals(actual)); assert!(value.strict_equals(actual));
let key2 = v8_str(scope, "foo2"); let key2 = v8_str(scope, "foo2");
assert_eq!( assert!(obj.set(context, key2.into(), value.into()).unwrap());
obj.set(context, key2.into(), value.into()),
v8::MaybeBool::JustTrue
);
let actual = obj.get(scope, context, key2.into()).unwrap(); let actual = obj.get(scope, context, key2.into()).unwrap();
assert!(value.strict_equals(actual)); assert!(value.strict_equals(actual));
} }
@ -1893,12 +1890,10 @@ fn shared_array_buffer() {
} }
let global = context.global(scope); let global = context.global(scope);
let r = global.create_data_property( let r = global
context, .create_data_property(context, v8_str(scope, "shared").into(), sab.into())
v8_str(scope, "shared").into(), .unwrap();
sab.into(), assert!(r);
);
assert_eq!(r, v8::MaybeBool::JustTrue);
let source = v8::String::new( let source = v8::String::new(
scope, scope,
r"sharedBytes = new Uint8Array(shared); r"sharedBytes = new Uint8Array(shared);