|
|
@ -1,18 +1,38 @@ |
|
|
|
use super::{PropertyDescriptor, PropertyKey}; |
|
|
|
use super::{PropertyDescriptor, PropertyKey}; |
|
|
|
use crate::{ |
|
|
|
use crate::{ |
|
|
|
gc::{Finalize, Trace}, |
|
|
|
gc::{custom_trace, Finalize, Trace}, |
|
|
|
JsString, JsSymbol, |
|
|
|
JsString, JsSymbol, |
|
|
|
}; |
|
|
|
}; |
|
|
|
use rustc_hash::FxHashMap; |
|
|
|
use indexmap::IndexMap; |
|
|
|
use std::{collections::hash_map, iter::FusedIterator}; |
|
|
|
use rustc_hash::{FxHashMap, FxHasher}; |
|
|
|
|
|
|
|
use std::{collections::hash_map, hash::BuildHasherDefault, iter::FusedIterator}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// Wrapper around indexmap::IndexMap for usage in PropertyMap
|
|
|
|
|
|
|
|
#[derive(Debug, Finalize)] |
|
|
|
|
|
|
|
struct OrderedHashMap<K: Trace>(IndexMap<K, PropertyDescriptor, BuildHasherDefault<FxHasher>>); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
impl<K: Trace> Default for OrderedHashMap<K> { |
|
|
|
|
|
|
|
fn default() -> Self { |
|
|
|
|
|
|
|
Self(IndexMap::with_hasher(BuildHasherDefault::default())) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
unsafe impl<K: Trace> Trace for OrderedHashMap<K> { |
|
|
|
|
|
|
|
custom_trace!(this, { |
|
|
|
|
|
|
|
for (k, v) in this.0.iter() { |
|
|
|
|
|
|
|
mark(k); |
|
|
|
|
|
|
|
mark(v); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[derive(Default, Debug, Trace, Finalize)] |
|
|
|
#[derive(Default, Debug, Trace, Finalize)] |
|
|
|
pub struct PropertyMap { |
|
|
|
pub struct PropertyMap { |
|
|
|
indexed_properties: FxHashMap<u32, PropertyDescriptor>, |
|
|
|
indexed_properties: FxHashMap<u32, PropertyDescriptor>, |
|
|
|
/// Properties
|
|
|
|
/// Properties
|
|
|
|
string_properties: FxHashMap<JsString, PropertyDescriptor>, |
|
|
|
string_properties: OrderedHashMap<JsString>, |
|
|
|
/// Symbol Properties
|
|
|
|
/// Symbol Properties
|
|
|
|
symbol_properties: FxHashMap<JsSymbol, PropertyDescriptor>, |
|
|
|
symbol_properties: OrderedHashMap<JsSymbol>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl PropertyMap { |
|
|
|
impl PropertyMap { |
|
|
@ -22,8 +42,8 @@ impl PropertyMap { |
|
|
|
pub fn get(&self, key: &PropertyKey) -> Option<&PropertyDescriptor> { |
|
|
|
pub fn get(&self, key: &PropertyKey) -> Option<&PropertyDescriptor> { |
|
|
|
match key { |
|
|
|
match key { |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.get(index), |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.get(index), |
|
|
|
PropertyKey::String(string) => self.string_properties.get(string), |
|
|
|
PropertyKey::String(string) => self.string_properties.0.get(string), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.get(symbol), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.0.get(symbol), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -34,16 +54,20 @@ impl PropertyMap { |
|
|
|
) -> Option<PropertyDescriptor> { |
|
|
|
) -> Option<PropertyDescriptor> { |
|
|
|
match &key { |
|
|
|
match &key { |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.insert(*index, property), |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.insert(*index, property), |
|
|
|
PropertyKey::String(string) => self.string_properties.insert(string.clone(), property), |
|
|
|
PropertyKey::String(string) => { |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.insert(symbol.clone(), property), |
|
|
|
self.string_properties.0.insert(string.clone(), property) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
PropertyKey::Symbol(symbol) => { |
|
|
|
|
|
|
|
self.symbol_properties.0.insert(symbol.clone(), property) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
pub fn remove(&mut self, key: &PropertyKey) -> Option<PropertyDescriptor> { |
|
|
|
pub fn remove(&mut self, key: &PropertyKey) -> Option<PropertyDescriptor> { |
|
|
|
match key { |
|
|
|
match key { |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.remove(index), |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.remove(index), |
|
|
|
PropertyKey::String(string) => self.string_properties.remove(string), |
|
|
|
PropertyKey::String(string) => self.string_properties.0.shift_remove(string), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.remove(symbol), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.0.shift_remove(symbol), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -54,8 +78,8 @@ impl PropertyMap { |
|
|
|
pub fn iter(&self) -> Iter<'_> { |
|
|
|
pub fn iter(&self) -> Iter<'_> { |
|
|
|
Iter { |
|
|
|
Iter { |
|
|
|
indexed_properties: self.indexed_properties.iter(), |
|
|
|
indexed_properties: self.indexed_properties.iter(), |
|
|
|
string_properties: self.string_properties.iter(), |
|
|
|
string_properties: self.string_properties.0.iter(), |
|
|
|
symbol_properties: self.symbol_properties.iter(), |
|
|
|
symbol_properties: self.symbol_properties.0.iter(), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -81,7 +105,7 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn symbol_properties(&self) -> SymbolProperties<'_> { |
|
|
|
pub fn symbol_properties(&self) -> SymbolProperties<'_> { |
|
|
|
SymbolProperties(self.symbol_properties.iter()) |
|
|
|
SymbolProperties(self.symbol_properties.0.iter()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator visiting all symbol keys in arbitrary order. The iterator element type is `&'a RcSymbol`.
|
|
|
|
/// An iterator visiting all symbol keys in arbitrary order. The iterator element type is `&'a RcSymbol`.
|
|
|
@ -89,7 +113,7 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn symbol_property_keys(&self) -> SymbolPropertyKeys<'_> { |
|
|
|
pub fn symbol_property_keys(&self) -> SymbolPropertyKeys<'_> { |
|
|
|
SymbolPropertyKeys(self.symbol_properties.keys()) |
|
|
|
SymbolPropertyKeys(self.symbol_properties.0.keys()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator visiting all symbol values in arbitrary order. The iterator element type is `&'a Property`.
|
|
|
|
/// An iterator visiting all symbol values in arbitrary order. The iterator element type is `&'a Property`.
|
|
|
@ -97,7 +121,7 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn symbol_property_values(&self) -> SymbolPropertyValues<'_> { |
|
|
|
pub fn symbol_property_values(&self) -> SymbolPropertyValues<'_> { |
|
|
|
SymbolPropertyValues(self.symbol_properties.values()) |
|
|
|
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)`.
|
|
|
|
/// An iterator visiting all indexed key-value pairs in arbitrary order. The iterator element type is `(&'a u32, &'a Property)`.
|
|
|
@ -129,7 +153,7 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn string_properties(&self) -> StringProperties<'_> { |
|
|
|
pub fn string_properties(&self) -> StringProperties<'_> { |
|
|
|
StringProperties(self.string_properties.iter()) |
|
|
|
StringProperties(self.string_properties.0.iter()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator visiting all string keys in arbitrary order. The iterator element type is `&'a RcString`.
|
|
|
|
/// An iterator visiting all string keys in arbitrary order. The iterator element type is `&'a RcString`.
|
|
|
@ -137,7 +161,7 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn string_property_keys(&self) -> StringPropertyKeys<'_> { |
|
|
|
pub fn string_property_keys(&self) -> StringPropertyKeys<'_> { |
|
|
|
StringPropertyKeys(self.string_properties.keys()) |
|
|
|
StringPropertyKeys(self.string_properties.0.keys()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator visiting all string values in arbitrary order. The iterator element type is `&'a Property`.
|
|
|
|
/// An iterator visiting all string values in arbitrary order. The iterator element type is `&'a Property`.
|
|
|
@ -145,15 +169,15 @@ impl PropertyMap { |
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
/// This iterator does not recurse down the prototype chain.
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn string_property_values(&self) -> StringPropertyValues<'_> { |
|
|
|
pub fn string_property_values(&self) -> StringPropertyValues<'_> { |
|
|
|
StringPropertyValues(self.string_properties.values()) |
|
|
|
StringPropertyValues(self.string_properties.0.values()) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#[inline] |
|
|
|
#[inline] |
|
|
|
pub fn contains_key(&self, key: &PropertyKey) -> bool { |
|
|
|
pub fn contains_key(&self, key: &PropertyKey) -> bool { |
|
|
|
match key { |
|
|
|
match key { |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.contains_key(index), |
|
|
|
PropertyKey::Index(index) => self.indexed_properties.contains_key(index), |
|
|
|
PropertyKey::String(string) => self.string_properties.contains_key(string), |
|
|
|
PropertyKey::String(string) => self.string_properties.0.contains_key(string), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.contains_key(symbol), |
|
|
|
PropertyKey::Symbol(symbol) => self.symbol_properties.0.contains_key(symbol), |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
@ -162,8 +186,8 @@ impl PropertyMap { |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct Iter<'a> { |
|
|
|
pub struct Iter<'a> { |
|
|
|
indexed_properties: hash_map::Iter<'a, u32, PropertyDescriptor>, |
|
|
|
indexed_properties: hash_map::Iter<'a, u32, PropertyDescriptor>, |
|
|
|
string_properties: hash_map::Iter<'a, JsString, PropertyDescriptor>, |
|
|
|
string_properties: indexmap::map::Iter<'a, JsString, PropertyDescriptor>, |
|
|
|
symbol_properties: hash_map::Iter<'a, JsSymbol, PropertyDescriptor>, |
|
|
|
symbol_properties: indexmap::map::Iter<'a, JsSymbol, PropertyDescriptor>, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for Iter<'a> { |
|
|
|
impl<'a> Iterator for Iter<'a> { |
|
|
@ -233,7 +257,7 @@ impl FusedIterator for Values<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the `Symbol` property entries of an `Object`
|
|
|
|
/// An iterator over the `Symbol` property entries of an `Object`
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct SymbolProperties<'a>(hash_map::Iter<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
pub struct SymbolProperties<'a>(indexmap::map::Iter<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for SymbolProperties<'a> { |
|
|
|
impl<'a> Iterator for SymbolProperties<'a> { |
|
|
|
type Item = (&'a JsSymbol, &'a PropertyDescriptor); |
|
|
|
type Item = (&'a JsSymbol, &'a PropertyDescriptor); |
|
|
@ -260,7 +284,7 @@ impl FusedIterator for SymbolProperties<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the keys (`RcSymbol`) of an `Object`.
|
|
|
|
/// An iterator over the keys (`RcSymbol`) of an `Object`.
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct SymbolPropertyKeys<'a>(hash_map::Keys<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
pub struct SymbolPropertyKeys<'a>(indexmap::map::Keys<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for SymbolPropertyKeys<'a> { |
|
|
|
impl<'a> Iterator for SymbolPropertyKeys<'a> { |
|
|
|
type Item = &'a JsSymbol; |
|
|
|
type Item = &'a JsSymbol; |
|
|
@ -287,7 +311,7 @@ impl FusedIterator for SymbolPropertyKeys<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the `Symbol` values (`Property`) of an `Object`.
|
|
|
|
/// An iterator over the `Symbol` values (`Property`) of an `Object`.
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct SymbolPropertyValues<'a>(hash_map::Values<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
pub struct SymbolPropertyValues<'a>(indexmap::map::Values<'a, JsSymbol, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for SymbolPropertyValues<'a> { |
|
|
|
impl<'a> Iterator for SymbolPropertyValues<'a> { |
|
|
|
type Item = &'a PropertyDescriptor; |
|
|
|
type Item = &'a PropertyDescriptor; |
|
|
@ -395,7 +419,7 @@ impl FusedIterator for IndexPropertyValues<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the `String` property entries of an `Object`
|
|
|
|
/// An iterator over the `String` property entries of an `Object`
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct StringProperties<'a>(hash_map::Iter<'a, JsString, PropertyDescriptor>); |
|
|
|
pub struct StringProperties<'a>(indexmap::map::Iter<'a, JsString, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for StringProperties<'a> { |
|
|
|
impl<'a> Iterator for StringProperties<'a> { |
|
|
|
type Item = (&'a JsString, &'a PropertyDescriptor); |
|
|
|
type Item = (&'a JsString, &'a PropertyDescriptor); |
|
|
@ -422,7 +446,7 @@ impl FusedIterator for StringProperties<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the string keys (`RcString`) of an `Object`.
|
|
|
|
/// An iterator over the string keys (`RcString`) of an `Object`.
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct StringPropertyKeys<'a>(hash_map::Keys<'a, JsString, PropertyDescriptor>); |
|
|
|
pub struct StringPropertyKeys<'a>(indexmap::map::Keys<'a, JsString, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for StringPropertyKeys<'a> { |
|
|
|
impl<'a> Iterator for StringPropertyKeys<'a> { |
|
|
|
type Item = &'a JsString; |
|
|
|
type Item = &'a JsString; |
|
|
@ -449,7 +473,7 @@ impl FusedIterator for StringPropertyKeys<'_> {} |
|
|
|
|
|
|
|
|
|
|
|
/// An iterator over the string values (`Property`) of an `Object`.
|
|
|
|
/// An iterator over the string values (`Property`) of an `Object`.
|
|
|
|
#[derive(Debug, Clone)] |
|
|
|
#[derive(Debug, Clone)] |
|
|
|
pub struct StringPropertyValues<'a>(hash_map::Values<'a, JsString, PropertyDescriptor>); |
|
|
|
pub struct StringPropertyValues<'a>(indexmap::map::Values<'a, JsString, PropertyDescriptor>); |
|
|
|
|
|
|
|
|
|
|
|
impl<'a> Iterator for StringPropertyValues<'a> { |
|
|
|
impl<'a> Iterator for StringPropertyValues<'a> { |
|
|
|
type Item = &'a PropertyDescriptor; |
|
|
|
type Item = &'a PropertyDescriptor; |
|
|
|