Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Temporary fix for object iter
Browse files Browse the repository at this point in the history
HalidOdat committed Mar 24, 2023
1 parent b986321 commit 335906c
Showing 10 changed files with 98 additions and 176 deletions.
25 changes: 5 additions & 20 deletions boa_engine/src/object/internal_methods/global.rs
Original file line number Diff line number Diff line change
@@ -254,30 +254,15 @@ pub(crate) fn global_own_property_keys(
};

// 2. For each own property key P of O such that P is an array index, in ascending numeric index order, do
// a. Add P as the last element of keys.
// a. Add P as the last element of keys.
keys.extend(ordered_indexes.into_iter().map(Into::into));

// 3. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
context
.realm
.global_property_map
.string_property_keys()
.cloned()
.map(Into::into),
);

// a. Add P as the last element of keys.
//
// 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
context
.realm
.global_property_map
.symbol_property_keys()
.cloned()
.map(Into::into),
);
// a. Add P as the last element of keys.
keys.extend(context.realm.global_property_map.shape.keys());

// 5. Return keys.
Ok(keys)
23 changes: 6 additions & 17 deletions boa_engine/src/object/internal_methods/integer_indexed.rs
Original file line number Diff line number Diff line change
@@ -222,30 +222,19 @@ pub(crate) fn integer_indexed_exotic_own_property_keys(
vec![]
} else {
// 2. If IsDetachedBuffer(O.[[ViewedArrayBuffer]]) is false, then
// a. For each integer i starting with 0 such that i < O.[[ArrayLength]], in ascending order, do
// i. Add ! ToString(𝔽(i)) as the last element of keys.
// a. For each integer i starting with 0 such that i < O.[[ArrayLength]], in ascending order, do
// i. Add ! ToString(𝔽(i)) as the last element of keys.
(0..inner.array_length())
.map(|index| PropertyKey::Index(index as u32))
.collect()
};

// 3. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.properties
.string_property_keys()
.cloned()
.map(Into::into),
);

// a. Add P as the last element of keys.
//
// 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.properties
.symbol_property_keys()
.cloned()
.map(Into::into),
);
// a. Add P as the last element of keys.
keys.extend(obj.properties.shape.keys());

// 5. Return keys.
Ok(keys)
21 changes: 4 additions & 17 deletions boa_engine/src/object/internal_methods/mod.rs
Original file line number Diff line number Diff line change
@@ -714,24 +714,11 @@ pub(crate) fn ordinary_own_property_keys(
keys.extend(ordered_indexes.into_iter().map(Into::into));

// 3. For each own property key P of O such that Type(P) is String and P is not an array index, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.borrow()
.properties
.string_property_keys()
.cloned()
.map(Into::into),
);

// a. Add P as the last element of keys.
//
// 4. For each own property key P of O such that Type(P) is Symbol, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.borrow()
.properties
.symbol_property_keys()
.cloned()
.map(Into::into),
);
// a. Add P as the last element of keys.
keys.extend(obj.borrow().properties.shape.keys());

// 5. Return keys.
Ok(keys)
21 changes: 5 additions & 16 deletions boa_engine/src/object/internal_methods/string.rs
Original file line number Diff line number Diff line change
@@ -101,12 +101,12 @@ pub(crate) fn string_exotic_own_property_keys(
let mut keys = Vec::with_capacity(len);

// 5. For each integer i starting with 0 such that i < len, in ascending order, do
// a. Add ! ToString(𝔽(i)) as the last element of keys.
// a. Add ! ToString(𝔽(i)) as the last element of keys.
keys.extend((0..len).map(Into::into));

// 6. For each own property key P of O such that P is an array index
// and ! ToIntegerOrInfinity(P) ≥ len, in ascending numeric index order, do
// a. Add P as the last element of keys.
// a. Add P as the last element of keys.
let mut remaining_indices: Vec<_> = obj
.properties
.index_property_keys()
@@ -117,23 +117,12 @@ pub(crate) fn string_exotic_own_property_keys(

// 7. For each own property key P of O such that Type(P) is String and P is not
// an array index, in ascending chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.properties
.string_property_keys()
.cloned()
.map(Into::into),
);
// a. Add P as the last element of keys.

// 8. For each own property key P of O such that Type(P) is Symbol, in ascending
// chronological order of property creation, do
// a. Add P as the last element of keys.
keys.extend(
obj.properties
.symbol_property_keys()
.cloned()
.map(Into::into),
);
// a. Add P as the last element of keys.
keys.extend(obj.properties.shape.keys());

// 9. Return keys.
Ok(keys)
94 changes: 7 additions & 87 deletions boa_engine/src/object/property_map.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use super::{
shape::{Shape, TransitionKey},
shape::{Shape, Slot, TransitionKey},
PropertyDescriptor, PropertyKey,
};
use crate::{property::PropertyDescriptorBuilder, JsString, JsSymbol, JsValue};
@@ -263,6 +263,12 @@ impl PropertyMap {
None
}

/// Get the property with the given key from the [`PropertyMap`].
#[must_use]
pub fn get_storage(&self, slot: Slot) -> PropertyDescriptor {
self.storage[slot.index as usize].clone()
}

/// Insert the given property descriptor with the given key [`PropertyMap`].
pub fn insert(
&mut self,
@@ -323,65 +329,6 @@ impl PropertyMap {
}
}

/// An iterator visiting all key-value pairs in arbitrary order. The iterator element type is `(PropertyKey, &'a Property)`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn iter(&self) -> Iter<'_> {
Iter {
indexed_properties: self.indexed_properties.iter(),
string_properties: self.string_properties.0.iter(),
symbol_properties: self.symbol_properties.0.iter(),
}
}

/// An iterator visiting all keys in arbitrary order. The iterator element type is `PropertyKey`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn keys(&self) -> Keys<'_> {
Keys(self.iter())
}

/// An iterator visiting all values in arbitrary order. The iterator element type is `&'a Property`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn values(&self) -> Values<'_> {
Values(self.iter())
}

/// An iterator visiting all symbol key-value pairs in arbitrary order. The iterator element type is `(&'a RcSymbol, &'a Property)`.
///
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn symbol_properties(&self) -> SymbolProperties<'_> {
SymbolProperties(self.symbol_properties.0.iter())
}

/// An iterator visiting all symbol keys in arbitrary order. The iterator element type is `&'a RcSymbol`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn symbol_property_keys(&self) -> SymbolPropertyKeys<'_> {
SymbolPropertyKeys(self.symbol_properties.0.keys())
}

/// An iterator visiting all symbol values in arbitrary order. The iterator element type is `&'a Property`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn symbol_property_values(&self) -> SymbolPropertyValues<'_> {
SymbolPropertyValues(self.symbol_properties.0.values())
}

/// An iterator visiting all indexed key-value pairs in arbitrary order. The iterator element type is `(&'a u32, &'a Property)`.
///
/// This iterator does not recurse down the prototype chain.
@@ -409,33 +356,6 @@ impl PropertyMap {
self.indexed_properties.values()
}

/// An iterator visiting all string key-value pairs in arbitrary order. The iterator element type is `(&'a RcString, &'a Property)`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn string_properties(&self) -> StringProperties<'_> {
StringProperties(self.string_properties.0.iter())
}

/// An iterator visiting all string keys in arbitrary order. The iterator element type is `&'a RcString`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn string_property_keys(&self) -> StringPropertyKeys<'_> {
StringPropertyKeys(self.string_properties.0.keys())
}

/// An iterator visiting all string values in arbitrary order. The iterator element type is `&'a Property`.
///
/// This iterator does not recurse down the prototype chain.
#[inline]
#[must_use]
pub fn string_property_values(&self) -> StringPropertyValues<'_> {
StringPropertyValues(self.string_properties.0.values())
}

/// Returns `true` if the given key is contained in the [`PropertyMap`].
#[inline]
#[must_use]
7 changes: 7 additions & 0 deletions boa_engine/src/object/shape/mod.rs
Original file line number Diff line number Diff line change
@@ -122,4 +122,11 @@ impl Shape {
Inner::Unique(shape) => shape.lookup(key),
}
}

pub(crate) fn keys(&self) -> Vec<PropertyKey> {
match &self.inner {
Inner::Shared(shape) => shape.keys(),
Inner::Unique(shape) => shape.keys(),
}
}
}
25 changes: 25 additions & 0 deletions boa_engine/src/object/shape/shared_shape.rs
Original file line number Diff line number Diff line change
@@ -285,4 +285,29 @@ impl SharedShape {

result
}

// TODO: implement DescriptorArray to optimize this :)
pub(crate) fn keys(&self) -> Vec<PropertyKey> {
let mut keys_string = Vec::new();
let mut keys_symbol = Vec::new();

let mut p = Some(self);
while let Some(shape) = p {
// Root has no properties
if shape.is_root() {
break;
}
if shape.transition_type() == TransitionType::Insert {
if matches!(shape.property_key(), PropertyKey::String(_)) {
keys_string.push(shape.property_key().clone());
} else {
keys_symbol.push(shape.property_key().clone());
}
}
p = shape.previous();
}
keys_string.reverse();
keys_string.extend(keys_symbol.into_iter().rev());
keys_string
}
}
21 changes: 21 additions & 0 deletions boa_engine/src/object/shape/unique_shape.rs
Original file line number Diff line number Diff line change
@@ -86,4 +86,25 @@ impl UniqueShape {

None
}

/// Gets all keys first strings then symbols.
pub(crate) fn keys(&self) -> Vec<PropertyKey> {
let mut property_table = self.inner.property_table.borrow();

let mut keys = Vec::with_capacity(property_table.len());
for key in property_table
.iter()
.filter(|x| matches!(x, PropertyKey::String(_)))
{
keys.push(key.clone());
}
for key in property_table
.iter()
.filter(|x| matches!(x, PropertyKey::Symbol(_)))
{
keys.push(key.clone());
}

keys
}
}
26 changes: 10 additions & 16 deletions boa_engine/src/value/display.rs
Original file line number Diff line number Diff line change
@@ -67,36 +67,30 @@ macro_rules! print_obj_value {
}
};
(props of $obj:expr, $display_fn:ident, $indent:expr, $encounters:expr, $print_internals:expr) => {
print_obj_value!(impl $obj, |(key, val)| {
{let mut keys: Vec<_> = $obj.borrow().properties().index_property_keys().map(crate::property::PropertyKey::Index).collect();
keys.extend($obj.borrow().properties().shape.keys());
let mut result = Vec::default();
for key in keys {
let val = $obj.borrow().properties().get(&key).expect("There should be a value");
if val.is_data_descriptor() {
let v = &val.expect_value();
format!(
result.push(format!(
"{:>width$}: {}",
key,
$display_fn(v, $encounters, $indent.wrapping_add(4), $print_internals),
width = $indent,
)
));
} else {
let display = match (val.set().is_some(), val.get().is_some()) {
(true, true) => "Getter & Setter",
(true, false) => "Setter",
(false, true) => "Getter",
_ => "No Getter/Setter"
};
format!("{:>width$}: {}", key, display, width = $indent)
result.push(format!("{:>width$}: {}", key, display, width = $indent));
}
})
};

// A private overload of the macro
// DO NOT use directly
(impl $v:expr, $f:expr) => {
$v
.borrow()
.properties()
.iter()
.map($f)
.collect::<Vec<String>>()
}
result}
};
}

Loading

0 comments on commit 335906c

Please sign in to comment.