feat: v8::Object::PreviewEntries (#1276)

This commit is contained in:
Leo Kettmeir 2023-07-10 19:30:11 +02:00 committed by GitHub
parent 70239dc4ce
commit c6fe9e70d0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 119 additions and 7 deletions

View File

@ -463,8 +463,8 @@ uint32_t v8__ScriptCompiler__CachedDataVersionTag() {
return v8::ScriptCompiler::CachedDataVersionTag();
}
size_t v8__TypedArray__Length(const v8::TypedArray* self) {
return ptr_to_local(self)->Length();
size_t v8__TypedArray__Length(const v8::TypedArray* self) {
return ptr_to_local(self)->Length();
}
size_t v8__TypedArray__kMaxLength() { return v8::TypedArray::kMaxLength; }
@ -1134,7 +1134,7 @@ void v8__ObjectTemplate__SetAccessor(
const v8::ObjectTemplate& self, const v8::Name& key,
v8::AccessorNameGetterCallback getter,
v8::AccessorNameSetterCallback setter,
const v8::Value* data_or_null,
const v8::Value* data_or_null,
v8::PropertyAttribute attr) {
ptr_to_local(&self)->SetAccessor(
ptr_to_local(&key), getter, setter, ptr_to_local(data_or_null), v8::AccessControl::DEFAULT,
@ -1279,9 +1279,9 @@ MaybeBool v8__Object__DefineProperty(const v8::Object& self,
MaybeBool v8__Object__SetAccessor(const v8::Object& self,
const v8::Context& context,
const v8::Name& key,
v8::AccessorNameGetterCallback getter,
v8::AccessorNameGetterCallback getter,
v8::AccessorNameSetterCallback setter,
const v8::Value* data_or_null,
const v8::Value* data_or_null,
v8::PropertyAttribute attr) {
return maybe_to_maybe_bool(ptr_to_local(&self)->SetAccessor(
ptr_to_local(&context), ptr_to_local(&key), getter, setter,
@ -1444,6 +1444,12 @@ const v8::Value* v8__Object__GetOwnPropertyDescriptor(
ptr_to_local(&context), ptr_to_local(&key)));
}
const v8::Array* v8__Object__PreviewEntries(
const v8::Object& self,
bool* is_key_value) {
return maybe_local_to_ptr(ptr_to_local(&self)->PreviewEntries(is_key_value));
}
const v8::Array* v8__Array__New(v8::Isolate* isolate, int length) {
return local_to_ptr(v8::Array::New(isolate, length));
@ -1778,7 +1784,7 @@ void v8__Context__SetPromiseHooks(v8::Context& self,
const v8::Value* v8__Context__GetSecurityToken(const v8::Context& self) {
auto value = ptr_to_local(&self)->GetSecurityToken();
return local_to_ptr(value);
return local_to_ptr(value);
}
void v8__Context__SetSecurityToken(v8::Context& self,
@ -1792,7 +1798,7 @@ void v8__Context__UseDefaultSecurityToken(v8::Context& self) {
}
void v8__Context__AllowCodeGenerationFromStrings(v8::Context& self, bool allow) {
ptr_to_local(&self)->AllowCodeGenerationFromStrings(allow);
ptr_to_local(&self)->AllowCodeGenerationFromStrings(allow);
}
bool v8__Context_IsCodeGenerationFromStringsAllowed(v8::Context& self) {

View File

@ -26,6 +26,7 @@ use crate::String;
use crate::Value;
use std::convert::TryFrom;
use std::ffi::c_void;
use std::mem::MaybeUninit;
use std::num::NonZeroI32;
use std::ptr::null;
@ -192,6 +193,10 @@ extern "C" {
context: *const Context,
key: *const Name,
) -> *const Value;
fn v8__Object__PreviewEntries(
this: *const Object,
is_key_value: *mut bool,
) -> *const Array;
fn v8__Array__New(isolate: *mut Isolate, length: int) -> *const Array;
fn v8__Array__New_with_elements(
@ -807,6 +812,28 @@ impl Object {
})
}
}
/// If this object is a Set, Map, WeakSet or WeakMap, this returns a
/// representation of the elements of this object as an array.
/// If this object is a SetIterator or MapIterator, this returns all elements
/// of the underlying collection, starting at the iterator's current position.
///
/// Also returns a boolean, indicating whether the returned array contains
/// key & values (for example when the value is Set.entries()).
pub fn preview_entries<'s>(
&self,
scope: &mut HandleScope<'s>,
) -> (Option<Local<'s, Array>>, bool) {
let mut is_key_value = MaybeUninit::uninit();
unsafe {
let val = scope.cast_local(|_| {
v8__Object__PreviewEntries(self, is_key_value.as_mut_ptr())
});
let is_key_value = is_key_value.assume_init();
(val, is_key_value)
}
}
}
/// Object integrity levels can be used to restrict what can be done to an

View File

@ -6741,6 +6741,85 @@ fn get_own_property_descriptor() {
assert!(desc.is_undefined());
}
#[test]
fn preview_entries() {
let _setup_guard = setup::parallel_test();
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 obj = eval(
scope,
"var set = new Set([1,2,3]); set.delete(1); set.keys()",
)
.unwrap();
let obj = obj.to_object(scope).unwrap();
let (preview, is_key_value) = obj.preview_entries(scope);
let preview = preview.unwrap();
assert!(!is_key_value);
assert_eq!(preview.length(), 2);
assert_eq!(
preview
.get_index(scope, 0)
.unwrap()
.number_value(scope)
.unwrap(),
2.0
);
assert_eq!(
preview
.get_index(scope, 1)
.unwrap()
.number_value(scope)
.unwrap(),
3.0
);
}
{
let obj = eval(
scope,
"var set = new Set([1,2,3]); set.delete(2); set.entries()",
)
.unwrap();
let obj = obj.to_object(scope).unwrap();
let (preview, is_key_value) = obj.preview_entries(scope);
let preview = preview.unwrap();
assert!(is_key_value);
assert_eq!(preview.length(), 4);
let first = preview
.get_index(scope, 0)
.unwrap()
.number_value(scope)
.unwrap();
let second = preview
.get_index(scope, 2)
.unwrap()
.number_value(scope)
.unwrap();
assert_eq!(first, 1.0);
assert_eq!(second, 3.0);
assert_eq!(
first,
preview
.get_index(scope, 1)
.unwrap()
.number_value(scope)
.unwrap(),
);
assert_eq!(
second,
preview
.get_index(scope, 3)
.unwrap()
.number_value(scope)
.unwrap(),
);
}
}
#[test]
fn test_prototype_api() {
let _setup_guard = setup::parallel_test();