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

Add some Array methods (#283)

This commit is contained in:
Ben Noordhuis 2020-02-14 15:42:54 +01:00 committed by GitHub
parent 554f06f6bc
commit 5d0b9fd760
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 101 additions and 6 deletions

View file

@ -681,12 +681,23 @@ v8::Value* v8__Object__Get(v8::Object& self, v8::Local<v8::Context> context,
return maybe_local_to_ptr(self.Get(context, key));
}
v8::Value* v8__Object__GetIndex(v8::Object& self,
v8::Local<v8::Context> context,
uint32_t index) {
return maybe_local_to_ptr(self.Get(context, index));
}
MaybeBool v8__Object__Set(v8::Object& self, v8::Local<v8::Context> context,
v8::Local<v8::Value> key,
v8::Local<v8::Value> value) {
return maybe_to_maybe_bool(self.Set(context, key, value));
}
MaybeBool v8__Object__SetIndex(v8::Object& self, v8::Local<v8::Context> context,
uint32_t index, v8::Local<v8::Value> value) {
return maybe_to_maybe_bool(self.Set(context, index, value));
}
MaybeBool v8__Object__CreateDataProperty(v8::Object& self,
v8::Local<v8::Context> context,
v8::Local<v8::Name> key,
@ -725,6 +736,16 @@ v8::Array* v8__Array__New(v8::Isolate* isolate, int length) {
return local_to_ptr(v8::Array::New(isolate, length));
}
v8::Array* v8__Array__New_with_elements(v8::Isolate* isolate,
v8::Local<v8::Value>* elements,
size_t length) {
return local_to_ptr(v8::Array::New(isolate, elements, length));
}
uint32_t v8__Array__Length(const v8::Array& self) {
return self.Length();
}
v8::Number* v8__Number__New(v8::Isolate* isolate, double value) {
return *v8::Number::New(isolate, value);
}

View file

@ -32,12 +32,23 @@ extern "C" {
context: Local<Context>,
key: Local<Value>,
) -> *mut Value;
fn v8__Object__GetIndex(
object: &Object,
context: Local<Context>,
index: u32,
) -> *mut Value;
fn v8__Object__Set(
object: &Object,
context: Local<Context>,
key: Local<Value>,
value: Local<Value>,
) -> MaybeBool;
fn v8__Object__SetIndex(
object: &Object,
context: Local<Context>,
index: u32,
value: Local<Value>,
) -> MaybeBool;
fn v8__Object__CreateDataProperty(
object: &Object,
context: Local<Context>,
@ -55,6 +66,12 @@ extern "C" {
fn v8__Object__CreationContext(object: &Object) -> *mut Context;
fn v8__Array__New(isolate: *mut Isolate, length: int) -> *mut Array;
fn v8__Array__New_with_elements(
isolate: *mut Isolate,
elements: *const Local<Value>,
length: usize,
) -> *mut Array;
fn v8__Array__Length(array: &Array) -> u32;
}
impl Object {
@ -100,6 +117,17 @@ impl Object {
unsafe { v8__Object__Set(self, context, key, value) }.into()
}
/// Set only return Just(true) or Empty(), so if it should never fail, use
/// result.Check().
pub fn set_index(
&self,
context: Local<Context>,
index: u32,
value: Local<Value>,
) -> Option<bool> {
unsafe { v8__Object__SetIndex(self, context, index, value) }.into()
}
/// Implements CreateDataProperty (ECMA-262, 7.3.4).
///
/// Defines a configurable, writable, enumerable property with the given value
@ -145,6 +173,18 @@ impl Object {
}
}
pub fn get_index<'a>(
&self,
scope: &mut impl ToLocal<'a>,
context: Local<Context>,
index: u32,
) -> Option<Local<'a, Value>> {
unsafe {
let ptr = v8__Object__GetIndex(self, context, index);
scope.to_local(ptr)
}
}
/// Note: SideEffectType affects the getter only, not the setter.
pub fn set_accessor(
&mut self,
@ -187,4 +227,26 @@ impl Array {
let ptr = unsafe { v8__Array__New(scope.isolate(), length) };
unsafe { scope.to_local(ptr) }.unwrap()
}
/// Creates a JavaScript array out of a Local<Value> array with a known length.
pub fn new_with_elements<'sc>(
scope: &mut impl ToLocal<'sc>,
elements: &[Local<Value>],
) -> Local<'sc, Array> {
if elements.is_empty() {
return Self::new(scope, 0);
}
let ptr = unsafe {
v8__Array__New_with_elements(
scope.isolate(),
&elements[0],
elements.len(),
)
};
unsafe { scope.to_local(ptr) }.unwrap()
}
pub fn length(&self) -> u32 {
unsafe { v8__Array__Length(self) }
}
}

View file

@ -1086,20 +1086,32 @@ fn array() {
let mut cs = v8::ContextScope::new(scope, context);
let scope = cs.enter();
let s1 = v8::String::new(scope, "a").unwrap();
let index1 = v8::Integer::new(scope, 0);
let s2 = v8::String::new(scope, "b").unwrap();
let index2 = v8::Integer::new(scope, 1);
let array = v8::Array::new(scope, 2);
assert_eq!(array.length(), 2);
let lhs = array.creation_context(scope).global(scope);
let rhs = context.global(scope);
assert!(lhs.strict_equals(rhs.into()));
array.set(context, index1.into(), s1.into());
array.set(context, index2.into(), s2.into());
array.set_index(context, 0, s1.into());
array.set_index(context, 1, s2.into());
let maybe_v1 = array.get(scope, context, index1.into());
let maybe_v1 = array.get_index(scope, context, 0);
assert!(maybe_v1.is_some());
assert!(maybe_v1.unwrap().same_value(s1.into()));
let maybe_v2 = array.get(scope, context, index2.into());
let maybe_v2 = array.get_index(scope, context, 1);
assert!(maybe_v2.is_some());
assert!(maybe_v2.unwrap().same_value(s2.into()));
let array = v8::Array::new_with_elements(scope, &[]);
assert_eq!(array.length(), 0);
let array = v8::Array::new_with_elements(scope, &[s1.into(), s2.into()]);
assert_eq!(array.length(), 2);
let maybe_v1 = array.get_index(scope, context, 0);
assert!(maybe_v1.is_some());
assert!(maybe_v1.unwrap().same_value(s1.into()));
let maybe_v2 = array.get_index(scope, context, 1);
assert!(maybe_v2.is_some());
assert!(maybe_v2.unwrap().same_value(s2.into()));
}