Skip to content

Commit

Permalink
Remove last unique shape (except global object)
Browse files Browse the repository at this point in the history
  • Loading branch information
HalidOdat committed May 30, 2023
1 parent 84efac2 commit 263e9e0
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 41 deletions.
47 changes: 47 additions & 0 deletions boa_builtins/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -620,6 +620,53 @@ fn main() -> io::Result<()> {
.static_method(utf16!("of"))
.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")
.static_method(utf16!("now"))
.static_method(utf16!("parse"))
Expand Down
82 changes: 45 additions & 37 deletions boa_engine/src/builtins/array/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,47 @@ impl BuiltInObject for ArrayPrototypeValues {
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.
#[derive(Debug, Clone, Copy)]
pub(crate) struct Array;
Expand All @@ -71,7 +112,7 @@ impl IntrinsicObject for Array {

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>(
realm,
Expand Down Expand Up @@ -3031,41 +3072,8 @@ impl Array {
///
/// [spec]: https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
/// [mdn]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables
pub(crate) fn unscopables_object() -> JsObject {
// 1. Let unscopableList be OrdinaryObjectCreate(null).
let unscopable_list = JsObject::with_null_proto();
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
fn unscopables_object(realm: &Realm) -> JsObject {
ArrayPrototypeUnscopables::init(realm);
realm.intrinsics().objects().array_prototype_unscopables()
}
}
14 changes: 10 additions & 4 deletions boa_engine/src/builtins/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,12 +895,17 @@ struct BuiltInBuilderStaticShape<'ctx> {
object: JsObject,
property_index: usize,
storage: Vec<JsValue>,
prototype: JsObject,
prototype: Option<JsObject>,
}

impl BuiltInBuilderStaticShape<'_> {
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
}

Expand Down Expand Up @@ -953,7 +958,8 @@ impl BuiltInBuilderStaticShape<'_> {

let mut object = self.object.borrow_mut();
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;
}
}
Expand All @@ -969,7 +975,7 @@ impl<'ctx> BuiltInBuilder {
object: I::get(realm.intrinsics()),
storage: Vec::with_capacity(shape.storage_len),
property_index: 0,
prototype: realm.intrinsics().constructors().object().prototype(),
prototype: Some(realm.intrinsics().constructors().object().prototype()),
}
}
}
Expand Down
12 changes: 12 additions & 0 deletions boa_engine/src/context/intrinsics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,9 @@ pub struct IntrinsicObjects {
/// [`%Array.prototype.values%`](https://tc39.es/ecma262/#sec-array.prototype.values)
array_prototype_values: JsFunction,

/// [`Array.prototype[ @@unscopables ]`](https://tc39.es/ecma262/#sec-array.prototype-@@unscopables)
array_prototype_unscopables: JsObject,

/// Cached iterator prototypes.
iterator_prototypes: IteratorPrototypes,

Expand Down Expand Up @@ -828,6 +831,7 @@ impl Default for IntrinsicObjects {
json: JsObject::default_with_static_shape(),
throw_type_error: JsFunction::empty_intrinsic_function(false),
array_prototype_values: JsFunction::empty_intrinsic_function_static_shape(false),
array_prototype_unscopables: JsObject::default_with_static_shape(),
iterator_prototypes: IteratorPrototypes::default(),
generator: JsObject::default_with_static_shape(),
async_generator: JsObject::default_with_static_shape(),
Expand Down Expand Up @@ -866,6 +870,14 @@ impl IntrinsicObjects {
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.
#[inline]
pub const fn iterator_prototypes(&self) -> &IteratorPrototypes {
Expand Down

0 comments on commit 263e9e0

Please sign in to comment.