Browse Source

Remove last unique shape (except global object)

optimization/static-shapes
Haled Odat 1 year ago
parent
commit
263e9e02e2
  1. 47
      boa_builtins/build.rs
  2. 82
      boa_engine/src/builtins/array/mod.rs
  3. 14
      boa_engine/src/builtins/mod.rs
  4. 12
      boa_engine/src/context/intrinsics.rs

47
boa_builtins/build.rs

@ -620,6 +620,53 @@ fn main() -> io::Result<()> {
.static_method(utf16!("of")) .static_method(utf16!("of"))
.build(file)?; .build(file)?;
BuiltInBuilder::new(&context, "ARRAY_UNSCOPABLES_OBJECT")
.property(
utf16!("at"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("copyWithin"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("entries"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("fill"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("find"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("findIndex"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("flat"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("flatMap"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("includes"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("keys"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.property(
utf16!("values"),
Attribute::WRITABLE | Attribute::ENUMERABLE | Attribute::CONFIGURABLE,
)
.build(file)?;
BuiltInBuilderConstructor::new(&context, "DATE") BuiltInBuilderConstructor::new(&context, "DATE")
.static_method(utf16!("now")) .static_method(utf16!("now"))
.static_method(utf16!("parse")) .static_method(utf16!("parse"))

82
boa_engine/src/builtins/array/mod.rs

@ -55,6 +55,47 @@ impl BuiltInObject for ArrayPrototypeValues {
const NAME: &'static str = "values"; const NAME: &'static str = "values";
} }
pub(crate) struct ArrayPrototypeUnscopables;
impl IntrinsicObject for ArrayPrototypeUnscopables {
fn init(realm: &Realm) {
BuiltInBuilder::with_intrinsic::<Self>(
realm,
&boa_builtins::ARRAY_UNSCOPABLES_OBJECT_STATIC_SHAPE,
)
// 1. Let unscopableList be OrdinaryObjectCreate(null).
.no_prototype()
// 2. Perform ! CreateDataPropertyOrThrow(unscopableList, "at", true).
.static_property(true)
// 3. Perform ! CreateDataPropertyOrThrow(unscopableList, "copyWithin", true).
.static_property(true)
// 4. Perform ! CreateDataPropertyOrThrow(unscopableList, "entries", true).
.static_property(true)
// 5. Perform ! CreateDataPropertyOrThrow(unscopableList, "fill", true).
.static_property(true)
// 6. Perform ! CreateDataPropertyOrThrow(unscopableList, "find", true).
.static_property(true)
// 7. Perform ! CreateDataPropertyOrThrow(unscopableList, "findIndex", true).
.static_property(true)
// 8. Perform ! CreateDataPropertyOrThrow(unscopableList, "flat", true).
.static_property(true)
// 9. Perform ! CreateDataPropertyOrThrow(unscopableList, "flatMap", true).
.static_property(true)
// 10. Perform ! CreateDataPropertyOrThrow(unscopableList, "includes", true).
.static_property(true)
// 11. Perform ! CreateDataPropertyOrThrow(unscopableList, "keys", true).
.static_property(true)
// 12. Perform ! CreateDataPropertyOrThrow(unscopableList, "values", true).
.static_property(true)
// 13. Return unscopableList.
.build();
}
fn get(intrinsics: &Intrinsics) -> JsObject {
intrinsics.objects().array_prototype_unscopables()
}
}
/// JavaScript `Array` built-in implementation. /// JavaScript `Array` built-in implementation.
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub(crate) struct Array; pub(crate) struct Array;
@ -71,7 +112,7 @@ impl IntrinsicObject for Array {
let values_function = realm.intrinsics().objects().array_prototype_values(); let values_function = realm.intrinsics().objects().array_prototype_values();
let unscopables_object = Self::unscopables_object(); let unscopables_object = Self::unscopables_object(realm);
BuiltInBuilder::from_standard_constructor_static_shape::<Self>( BuiltInBuilder::from_standard_constructor_static_shape::<Self>(
realm, realm,
@ -3031,41 +3072,8 @@ impl Array {
/// ///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables /// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables /// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables
pub(crate) fn unscopables_object() -> JsObject { fn unscopables_object(realm: &Realm) -> JsObject {
// 1. Let unscopableList be OrdinaryObjectCreate(null). ArrayPrototypeUnscopables::init(realm);
let unscopable_list = JsObject::with_null_proto(); realm.intrinsics().objects().array_prototype_unscopables()
let true_prop = PropertyDescriptor::builder()
.value(true)
.writable(true)
.enumerable(true)
.configurable(true);
{
let mut obj = unscopable_list.borrow_mut();
// 2. Perform ! CreateDataPropertyOrThrow(unscopableList, "at", true).
obj.insert(utf16!("at"), true_prop.clone());
// 3. Perform ! CreateDataPropertyOrThrow(unscopableList, "copyWithin", true).
obj.insert(utf16!("copyWithin"), true_prop.clone());
// 4. Perform ! CreateDataPropertyOrThrow(unscopableList, "entries", true).
obj.insert(utf16!("entries"), true_prop.clone());
// 5. Perform ! CreateDataPropertyOrThrow(unscopableList, "fill", true).
obj.insert(utf16!("fill"), true_prop.clone());
// 6. Perform ! CreateDataPropertyOrThrow(unscopableList, "find", true).
obj.insert(utf16!("find"), true_prop.clone());
// 7. Perform ! CreateDataPropertyOrThrow(unscopableList, "findIndex", true).
obj.insert(utf16!("findIndex"), true_prop.clone());
// 8. Perform ! CreateDataPropertyOrThrow(unscopableList, "flat", true).
obj.insert(utf16!("flat"), true_prop.clone());
// 9. Perform ! CreateDataPropertyOrThrow(unscopableList, "flatMap", true).
obj.insert(utf16!("flatMap"), true_prop.clone());
// 10. Perform ! CreateDataPropertyOrThrow(unscopableList, "includes", true).
obj.insert(utf16!("includes"), true_prop.clone());
// 11. Perform ! CreateDataPropertyOrThrow(unscopableList, "keys", true).
obj.insert(utf16!("keys"), true_prop.clone());
// 12. Perform ! CreateDataPropertyOrThrow(unscopableList, "values", true).
obj.insert(utf16!("values"), true_prop);
}
// 13. Return unscopableList.
unscopable_list
} }
} }

14
boa_engine/src/builtins/mod.rs

@ -895,12 +895,17 @@ struct BuiltInBuilderStaticShape<'ctx> {
object: JsObject, object: JsObject,
property_index: usize, property_index: usize,
storage: Vec<JsValue>, storage: Vec<JsValue>,
prototype: JsObject, prototype: Option<JsObject>,
} }
impl BuiltInBuilderStaticShape<'_> { impl BuiltInBuilderStaticShape<'_> {
fn prototype(mut self, prototype: JsObject) -> Self { fn prototype(mut self, prototype: JsObject) -> Self {
self.prototype = prototype; self.prototype = Some(prototype);
self
}
fn no_prototype(mut self) -> Self {
self.prototype = None;
self self
} }
@ -953,7 +958,8 @@ impl BuiltInBuilderStaticShape<'_> {
let mut object = self.object.borrow_mut(); let mut object = self.object.borrow_mut();
object.properties_mut().shape = StaticShape::new(self.shape).into(); object.properties_mut().shape = StaticShape::new(self.shape).into();
self.storage.push(self.prototype.into()); self.storage
.push(self.prototype.map_or(JsValue::undefined(), Into::into));
object.properties_mut().storage = self.storage; object.properties_mut().storage = self.storage;
} }
} }
@ -969,7 +975,7 @@ impl<'ctx> BuiltInBuilder {
object: I::get(realm.intrinsics()), object: I::get(realm.intrinsics()),
storage: Vec::with_capacity(shape.storage_len), storage: Vec::with_capacity(shape.storage_len),
property_index: 0, property_index: 0,
prototype: realm.intrinsics().constructors().object().prototype(), prototype: Some(realm.intrinsics().constructors().object().prototype()),
} }
} }
} }

12
boa_engine/src/context/intrinsics.rs

@ -776,6 +776,9 @@ pub struct IntrinsicObjects {
/// [`%Array.prototype.values%`](https://tc39.es/ecma262/#sec-array.prototype.values) /// [`%Array.prototype.values%`](https://tc39.es/ecma262/#sec-array.prototype.values)
array_prototype_values: JsFunction, array_prototype_values: JsFunction,
/// [`Array.prototype[ @@unscopables ]`](https://tc39.es/ecma262/#sec-array.prototype-@@unscopables)
array_prototype_unscopables: JsObject,
/// Cached iterator prototypes. /// Cached iterator prototypes.
iterator_prototypes: IteratorPrototypes, iterator_prototypes: IteratorPrototypes,
@ -828,6 +831,7 @@ impl Default for IntrinsicObjects {
json: JsObject::default_with_static_shape(), json: JsObject::default_with_static_shape(),
throw_type_error: JsFunction::empty_intrinsic_function(false), throw_type_error: JsFunction::empty_intrinsic_function(false),
array_prototype_values: JsFunction::empty_intrinsic_function_static_shape(false), array_prototype_values: JsFunction::empty_intrinsic_function_static_shape(false),
array_prototype_unscopables: JsObject::default_with_static_shape(),
iterator_prototypes: IteratorPrototypes::default(), iterator_prototypes: IteratorPrototypes::default(),
generator: JsObject::default_with_static_shape(), generator: JsObject::default_with_static_shape(),
async_generator: JsObject::default_with_static_shape(), async_generator: JsObject::default_with_static_shape(),
@ -866,6 +870,14 @@ impl IntrinsicObjects {
self.array_prototype_values.clone() self.array_prototype_values.clone()
} }
/// Gets the [`Array.prototype[ @@unscopables ]`][spec] object.
///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
#[inline]
pub(crate) fn array_prototype_unscopables(&self) -> JsObject {
self.array_prototype_unscopables.clone()
}
/// Gets the cached iterator prototypes. /// Gets the cached iterator prototypes.
#[inline] #[inline]
pub const fn iterator_prototypes(&self) -> &IteratorPrototypes { pub const fn iterator_prototypes(&self) -> &IteratorPrototypes {

Loading…
Cancel
Save