diff --git a/boa_builtins/build.rs b/boa_builtins/build.rs index 83fc2c6d01..30aa655f60 100644 --- a/boa_builtins/build.rs +++ b/boa_builtins/build.rs @@ -1038,6 +1038,11 @@ fn main() -> io::Result<()> { .property(WellKnown::ToStringTag, Attribute::CONFIGURABLE) .build(file)?; + BuiltInBuilder::new(&context, "ARRAY_ITERATOR_PROTOTYPE") + .method(utf16!("next")) + .property(WellKnown::ToStringTag, Attribute::CONFIGURABLE) + .build(file)?; + context.build(file)?; Ok(()) diff --git a/boa_engine/src/builtins/array/array_iterator.rs b/boa_engine/src/builtins/array/array_iterator.rs index 417efb815a..cfecff5e8c 100644 --- a/boa_engine/src/builtins/array/array_iterator.rs +++ b/boa_engine/src/builtins/array/array_iterator.rs @@ -12,9 +12,8 @@ use crate::{ context::intrinsics::Intrinsics, error::JsNativeError, object::{JsObject, ObjectData}, - property::{Attribute, PropertyNameKind}, + property::PropertyNameKind, realm::Realm, - symbol::JsSymbol, Context, JsResult, }; use boa_gc::{Finalize, Trace}; @@ -39,21 +38,20 @@ impl IntrinsicObject for ArrayIterator { fn init(realm: &Realm) { let _timer = Profiler::global().start_event("ArrayIterator", "init"); - BuiltInBuilder::with_intrinsic::(realm) - .prototype( - realm - .intrinsics() - .objects() - .iterator_prototypes() - .iterator(), - ) - .static_method(Self::next, "next", 0) - .static_property( - JsSymbol::to_string_tag(), - "Array Iterator", - Attribute::CONFIGURABLE, - ) - .build(); + BuiltInBuilder::with_intrinsic_static_shape::( + realm, + &boa_builtins::ARRAY_ITERATOR_PROTOTYPE_STATIC_SHAPE, + ) + .prototype( + realm + .intrinsics() + .objects() + .iterator_prototypes() + .iterator(), + ) + .static_method(Self::next, 0) + .static_property("Array Iterator") + .build(); } fn get(intrinsics: &Intrinsics) -> JsObject { diff --git a/boa_engine/src/builtins/iterable/mod.rs b/boa_engine/src/builtins/iterable/mod.rs index e6dddab4da..12a86bb6c4 100644 --- a/boa_engine/src/builtins/iterable/mod.rs +++ b/boa_engine/src/builtins/iterable/mod.rs @@ -40,7 +40,7 @@ macro_rules! if_abrupt_close_iterator { pub(crate) use if_abrupt_close_iterator; /// The built-in iterator prototypes. -#[derive(Debug, Default, Trace, Finalize)] +#[derive(Debug, Trace, Finalize)] pub struct IteratorPrototypes { /// The `IteratorPrototype` object. iterator: JsObject, @@ -74,6 +74,24 @@ pub struct IteratorPrototypes { segment: JsObject, } +impl Default for IteratorPrototypes { + fn default() -> Self { + Self { + array: JsObject::default_with_static_shape(), + iterator: JsObject::default(), + async_iterator: JsObject::default(), + async_from_sync_iterator: JsObject::default(), + set: JsObject::default(), + string: JsObject::default(), + regexp_string: JsObject::default(), + map: JsObject::default(), + for_in: JsObject::default(), + #[cfg(feature = "intl")] + segment: JsObject::default(), + } + } +} + impl IteratorPrototypes { /// Returns the `ArrayIteratorPrototype` object. #[inline] diff --git a/boa_engine/src/builtins/mod.rs b/boa_engine/src/builtins/mod.rs index f8d3496d33..85ff7f77d6 100644 --- a/boa_engine/src/builtins/mod.rs +++ b/boa_engine/src/builtins/mod.rs @@ -855,9 +855,15 @@ struct BuiltInBuilderStaticShape<'ctx> { object: JsObject, property_index: usize, storage: Vec, + prototype: JsObject, } impl BuiltInBuilderStaticShape<'_> { + fn prototype(mut self, prototype: JsObject) -> Self { + self.prototype = prototype; + self + } + /// Adds a new static method to the builtin object. fn static_method(mut self, function: NativeFunctionPointer, length: usize) -> Self { let name = self.shape.get_string_key_expect(self.property_index); @@ -890,14 +896,7 @@ impl BuiltInBuilderStaticShape<'_> { let mut object = self.object.borrow_mut(); object.properties_mut().shape = StaticShape::new(self.shape).into(); - self.storage.push( - self.realm - .intrinsics() - .constructors() - .object() - .prototype() - .into(), - ); + self.storage.push(self.prototype.into()); object.properties_mut().storage = self.storage; } } @@ -924,6 +923,7 @@ impl<'ctx> BuiltInBuilder<'ctx, OrdinaryObject> { object: I::get(realm.intrinsics()), storage: Vec::with_capacity(shape.storage_len), property_index: 0, + prototype: realm.intrinsics().constructors().object().prototype(), } } }