Selaa lähdekoodia

Harmonize iterator prototype intrinsics to follow spec (#933)

Marko Lahma 4 vuotta sitten
vanhempi
commit
af31a9dce6

+ 113 - 0
Jint/Native/Array/ArrayIteratorPrototype.cs

@@ -0,0 +1,113 @@
+using System;
+using Jint.Native.Iterator;
+using Jint.Native.Object;
+using Jint.Native.TypedArray;
+using Jint.Runtime;
+
+namespace Jint.Native.Array
+{
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%arrayiteratorprototype%-object
+    /// </summary>
+    internal sealed class ArrayIteratorPrototype : IteratorPrototype
+    {
+        internal ArrayIteratorPrototype(
+            Engine engine,
+            Realm realm,
+            ObjectPrototype objectPrototype) : base(engine, realm, "Array Iterator", objectPrototype)
+        {
+        }
+
+        internal IteratorInstance Construct(ObjectInstance array, Func<Intrinsics, Prototype> prototypeSelector)
+        {
+            var instance = new ArrayLikeIterator(Engine, array, ArrayIteratorType.KeyAndValue)
+            {
+                _prototype = prototypeSelector(_realm.Intrinsics)
+            };
+
+            return instance;
+        }
+
+        internal IteratorInstance Construct(ObjectInstance array, ArrayIteratorType kind)
+        {
+            var instance = new ArrayLikeIterator(Engine, array, kind)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        private sealed class ArrayLikeIterator : IteratorInstance
+        {
+            private readonly ArrayIteratorType _kind;
+            private readonly TypedArrayInstance _typedArray;
+            private readonly ArrayOperations _operations;
+            private uint _position;
+            private bool _closed;
+
+            public ArrayLikeIterator(Engine engine, ObjectInstance objectInstance, ArrayIteratorType kind) : base(engine)
+            {
+                _kind = kind;
+                _typedArray = objectInstance as TypedArrayInstance;
+                if (_typedArray is null)
+                {
+                    _operations = ArrayOperations.For(objectInstance);
+                }
+
+                _position = 0;
+            }
+
+            public override bool TryIteratorStep(out ObjectInstance nextItem)
+            {
+                uint len;
+                if (_typedArray is not null)
+                {
+                    _typedArray._viewedArrayBuffer.AssertNotDetached();
+                    len = _typedArray.Length;
+                }
+                else
+                {
+                    len = _operations.GetLength();
+                }
+
+                if (!_closed && _position < len)
+                {
+                    JsValue value;
+                    if (_typedArray is not null)
+                    {
+                        nextItem = _kind switch
+                        {
+                            ArrayIteratorType.Key => new ValueIteratorPosition(_engine, _position),
+                            ArrayIteratorType.Value => new ValueIteratorPosition(_engine, _typedArray[(int) _position]),
+                            _ => new KeyValueIteratorPosition(_engine, _position, _typedArray[(int) _position])
+                        };
+                    }
+                    else
+                    {
+                        _operations.TryGetValue(_position, out value);
+                        if (_kind == ArrayIteratorType.Key)
+                        {
+                            nextItem = new ValueIteratorPosition(_engine, _position);
+                        }
+                        else if (_kind == ArrayIteratorType.Value)
+                        {
+                            nextItem = new ValueIteratorPosition(_engine, value);
+                        }
+                        else
+                        {
+                            nextItem = new KeyValueIteratorPosition(_engine, _position, value);
+                        }
+                    }
+
+                    _position++;
+                    return true;
+                }
+
+                _closed = true;
+                nextItem = KeyValueIteratorPosition.Done;
+                return false;
+            }
+        }
+    }
+}

+ 3 - 3
Jint/Native/Array/ArrayPrototype.cs

@@ -106,7 +106,7 @@ namespace Jint.Native.Array
         {
             if (thisObj is ObjectInstance oi && oi.IsArrayLike)
             {
-                return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.Key);
+                return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.Key);
             }
 
             ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");
@@ -117,7 +117,7 @@ namespace Jint.Native.Array
         {
             if (thisObj is ObjectInstance oi && oi.IsArrayLike)
             {
-                return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.Value);
+                return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.Value);
             }
 
             ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");
@@ -128,7 +128,7 @@ namespace Jint.Native.Array
         {
             if (thisObj is ObjectInstance oi && oi.IsArrayLike)
             {
-                return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(oi, ArrayIteratorType.KeyAndValue);
+                return _realm.Intrinsics.ArrayIteratorPrototype.Construct(oi, ArrayIteratorType.KeyAndValue);
             }
 
             ExceptionHelper.ThrowTypeError(_realm, "cannot construct iterator");

+ 0 - 157
Jint/Native/Iterator/IteratorConstructor.cs

@@ -1,157 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using Jint.Native.Function;
-using Jint.Native.Map;
-using Jint.Native.Object;
-using Jint.Native.Set;
-using Jint.Runtime;
-
-namespace Jint.Native.Iterator
-{
-    public sealed class IteratorConstructor : FunctionInstance, IConstructor
-    {
-        private static readonly JsString _functionName = new JsString("iterator");
-
-        internal IteratorConstructor(
-            Engine engine,
-            Realm realm,
-            ObjectPrototype objectPrototype)
-            : base(engine, realm, _functionName)
-        {
-            ArrayIteratorPrototypeObject = new IteratorPrototype(engine, realm, "Array Iterator", objectPrototype);
-            GenericIteratorPrototypeObject = new IteratorPrototype(engine, realm, null, objectPrototype);
-            MapIteratorPrototypeObject = new IteratorPrototype(engine, realm, "Map Iterator", objectPrototype);
-            RegExpStringIteratorPrototypeObject = new IteratorPrototype(engine, realm, "RegExp String Iterator", objectPrototype);
-            SetIteratorPrototypeObject = new IteratorPrototype(engine, realm, "Set Iterator", objectPrototype);
-            StringIteratorPrototypeObject = new IteratorPrototype(engine, realm, "String Iterator", objectPrototype);
-        }
-
-        internal IteratorPrototype ArrayIteratorPrototypeObject { get; }
-        internal IteratorPrototype GenericIteratorPrototypeObject { get; }
-        private IteratorPrototype MapIteratorPrototypeObject { get; }
-        private IteratorPrototype RegExpStringIteratorPrototypeObject { get; }
-        private IteratorPrototype SetIteratorPrototypeObject { get; }
-        private IteratorPrototype StringIteratorPrototypeObject { get; }
-
-        public override JsValue Call(JsValue thisObject, JsValue[] arguments)
-        {
-            return Construct(arguments);
-        }
-
-        public ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
-        {
-            return Construct(Enumerable.Empty<JsValue>());
-        }
-
-        internal IteratorInstance Construct(IEnumerable<JsValue> enumerable)
-        {
-            var instance = new IteratorInstance(Engine, enumerable)
-            {
-                _prototype = GenericIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance Construct(List<JsValue> enumerable)
-        {
-            var instance = new IteratorInstance.ListIterator(Engine, enumerable)
-            {
-                _prototype = GenericIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance Construct(ObjectInstance array, Func<Intrinsics, Prototype> prototypeSelector)
-        {
-            var instance = new IteratorInstance.ArrayLikeIterator(Engine, array, ArrayIteratorType.KeyAndValue)
-            {
-                _prototype = prototypeSelector(_realm.Intrinsics)
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance ConstructEntryIterator(MapInstance map)
-        {
-            var instance = new IteratorInstance.MapIterator(Engine, map)
-            {
-                _prototype = MapIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance ConstructKeyIterator(MapInstance map)
-        {
-            var instance = new IteratorInstance(Engine, map._map.Keys)
-            {
-                _prototype = MapIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance ConstructValueIterator(MapInstance map)
-        {
-            var instance = new IteratorInstance(Engine, map._map.Values)
-            {
-                _prototype = MapIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance ConstructEntryIterator(SetInstance set)
-        {
-            var instance = new IteratorInstance.SetEntryIterator(Engine, set)
-            {
-                _prototype = SetIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance ConstructValueIterator(SetInstance set)
-        {
-            var instance = new IteratorInstance.ListIterator(Engine, set._set._list)
-            {
-                _prototype = SetIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance CreateArrayLikeIterator(ObjectInstance array, ArrayIteratorType kind)
-        {
-            var instance = new IteratorInstance.ArrayLikeIterator(Engine, array, kind)
-            {
-                _prototype = ArrayIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        internal IteratorInstance CreateRegExpStringIterator(ObjectInstance iteratingRegExp, string iteratedString, bool global, bool unicode)
-        {
-            var instance = new IteratorInstance.RegExpStringIterator(Engine, iteratingRegExp, iteratedString, global, unicode)
-            {
-                _prototype = RegExpStringIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-
-        public ObjectInstance Construct(string str)
-        {
-            var instance = new IteratorInstance.StringIterator(Engine, str)
-            {
-                _prototype = StringIteratorPrototypeObject
-            };
-
-            return instance;
-        }
-    }
-}

+ 2 - 133
Jint/Native/Iterator/IteratorInstance.cs

@@ -1,13 +1,8 @@
 using System.Collections.Generic;
 using System.Globalization;
 using System.Linq;
-
-using Jint.Native.Array;
-using Jint.Native.Map;
 using Jint.Native.Object;
 using Jint.Native.RegExp;
-using Jint.Native.Set;
-using Jint.Native.TypedArray;
 using Jint.Runtime;
 using Jint.Runtime.Descriptors;
 
@@ -63,7 +58,7 @@ namespace Jint.Native.Iterator
             return obj;
         }
 
-        private sealed class KeyValueIteratorPosition : ObjectInstance
+        internal sealed class KeyValueIteratorPosition : ObjectInstance
         {
             internal static readonly ObjectInstance Done = new KeyValueIteratorPosition(null, null, null);
 
@@ -81,7 +76,7 @@ namespace Jint.Native.Iterator
             }
         }
 
-        private sealed class ValueIteratorPosition : ObjectInstance
+        internal sealed class ValueIteratorPosition : ObjectInstance
         {
             internal static readonly ObjectInstance Done = new KeyValueIteratorPosition(null, null, null);
 
@@ -96,61 +91,6 @@ namespace Jint.Native.Iterator
             }
         }
 
-        public sealed class MapIterator : IteratorInstance
-        {
-            private readonly MapInstance _map;
-
-            private int _position;
-
-            public MapIterator(Engine engine, MapInstance map) : base(engine)
-            {
-                _map = map;
-                _position = 0;
-            }
-
-            public override bool TryIteratorStep(out ObjectInstance nextItem)
-            {
-                if (_position < _map.GetSize())
-                {
-                    var key = _map._map.GetKey(_position);
-                    var value = _map._map[key];
-
-                    _position++;
-                    nextItem = new KeyValueIteratorPosition(_engine, key, value);
-                    return true;
-                }
-
-                nextItem = KeyValueIteratorPosition.Done;
-                return false;
-            }
-        }
-
-        public sealed class SetEntryIterator : IteratorInstance
-        {
-            private readonly SetInstance _set;
-            private int _position;
-
-            public SetEntryIterator(Engine engine, SetInstance set) : base(engine)
-            {
-                _set = set;
-                _position = 0;
-            }
-
-            public override bool TryIteratorStep(out ObjectInstance nextItem)
-            {
-                if (_position < _set._set._list.Count)
-                {
-                    var value = _set._set[_position];
-                    _position++;
-                    nextItem = new KeyValueIteratorPosition(_engine, value, value);
-                    return true;
-                }
-
-                nextItem = KeyValueIteratorPosition.Done;
-                return false;
-            }
-        }
-
         public sealed class ListIterator : IteratorInstance
         {
             private readonly List<JsValue> _values;
@@ -179,77 +119,6 @@ namespace Jint.Native.Iterator
             }
         }
 
-        internal sealed class ArrayLikeIterator : IteratorInstance
-        {
-            private readonly ArrayIteratorType _kind;
-            private readonly TypedArrayInstance _typedArray;
-            private readonly ArrayOperations _operations;
-            private uint _position;
-            private bool _closed;
-
-            public ArrayLikeIterator(Engine engine, ObjectInstance objectInstance, ArrayIteratorType kind) : base(engine)
-            {
-                _kind = kind;
-                _typedArray = objectInstance as TypedArrayInstance;
-                if (_typedArray is null)
-                {
-                    _operations = ArrayOperations.For(objectInstance);
-                }
-                _position = 0;
-            }
-
-            public override bool TryIteratorStep(out ObjectInstance nextItem)
-            {
-                uint len;
-                if (_typedArray is not null)
-                {
-                    _typedArray._viewedArrayBuffer.AssertNotDetached();
-                    len = _typedArray.Length;
-                }
-                else
-                {
-                    len = _operations.GetLength();
-                }
-
-                if (!_closed && _position < len)
-                {
-                    JsValue value;
-                    if (_typedArray is not null)
-                    {
-                        nextItem = _kind switch
-                        {
-                            ArrayIteratorType.Key => new ValueIteratorPosition(_engine, _position),
-                            ArrayIteratorType.Value => new ValueIteratorPosition(_engine, _typedArray[(int) _position]),
-                            _ => new KeyValueIteratorPosition(_engine, _position, _typedArray[(int) _position])
-                        };
-                    }
-                    else
-                    {
-                        _operations.TryGetValue(_position, out value);
-                        if (_kind == ArrayIteratorType.Key)
-                        {
-                            nextItem = new ValueIteratorPosition(_engine, _position);
-                        }
-                        else if (_kind == ArrayIteratorType.Value)
-                        {
-                            nextItem = new ValueIteratorPosition(_engine, value);
-                        }
-                        else
-                        {
-                            nextItem = new KeyValueIteratorPosition(_engine, _position, value);
-                        }
-                    }
-
-                    _position++;
-                    return true;
-                }
-
-                _closed = true;
-                nextItem = KeyValueIteratorPosition.Done;
-                return false;
-            }
-        }
-
         internal sealed class ObjectIterator : IIterator
         {
             private readonly ObjectInstance _target;

+ 27 - 3
Jint/Native/Iterator/IteratorPrototype.cs

@@ -1,4 +1,5 @@
-using Jint.Collections;
+using System.Collections.Generic;
+using Jint.Collections;
 using Jint.Native.Object;
 using Jint.Native.Symbol;
 using Jint.Runtime;
@@ -7,7 +8,10 @@ using Jint.Runtime.Interop;
 
 namespace Jint.Native.Iterator
 {
-    internal sealed class IteratorPrototype : Prototype
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%iteratorprototype%-object
+    /// </summary>
+    internal class IteratorPrototype : Prototype
     {
         private readonly string _name;
 
@@ -42,7 +46,27 @@ namespace Jint.Native.Iterator
             SetSymbols(symbols);
         }
 
-        private JsValue ToIterator(JsValue thisObj, JsValue[] arguments)
+        internal IteratorInstance Construct(IEnumerable<JsValue> enumerable)
+        {
+            var instance = new IteratorInstance(Engine, enumerable)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        internal IteratorInstance Construct(List<JsValue> enumerable)
+        {
+            var instance = new IteratorInstance.ListIterator(Engine, enumerable)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        private static JsValue ToIterator(JsValue thisObj, JsValue[] arguments)
         {
             return thisObj;
         }

+ 3 - 3
Jint/Native/Map/MapInstance.cs

@@ -85,17 +85,17 @@ namespace Jint.Native.Map
 
         internal ObjectInstance Iterator()
         {
-            return _realm.Intrinsics.Iterator.ConstructEntryIterator(this);
+            return _realm.Intrinsics.MapIteratorPrototype.ConstructEntryIterator(this);
         }
 
         internal ObjectInstance Keys()
         {
-            return _realm.Intrinsics.Iterator.ConstructKeyIterator(this);
+            return _realm.Intrinsics.MapIteratorPrototype.ConstructKeyIterator(this);
         }
 
         internal ObjectInstance Values()
         {
-            return _realm.Intrinsics.Iterator.ConstructValueIterator(this);
+            return _realm.Intrinsics.MapIteratorPrototype.ConstructValueIterator(this);
         }
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]

+ 79 - 0
Jint/Native/Map/MapIteratorPrototype.cs

@@ -0,0 +1,79 @@
+using Jint.Native.Iterator;
+using Jint.Native.Object;
+using Jint.Runtime;
+
+namespace Jint.Native.Map
+{
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%mapiteratorprototype%-object
+    /// </summary>
+    internal sealed class MapIteratorPrototype : IteratorPrototype
+    {
+        internal MapIteratorPrototype(
+            Engine engine,
+            Realm realm,
+            ObjectPrototype objectPrototype) : base(engine, realm, "Map Iterator", objectPrototype)
+        {
+        }
+
+        internal IteratorInstance ConstructEntryIterator(MapInstance map)
+        {
+            var instance = new MapIterator(Engine, map)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        internal IteratorInstance ConstructKeyIterator(MapInstance map)
+        {
+            var instance = new IteratorInstance(Engine, map._map.Keys)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        internal IteratorInstance ConstructValueIterator(MapInstance map)
+        {
+            var instance = new IteratorInstance(Engine, map._map.Values)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        private sealed class MapIterator : IteratorInstance
+        {
+            private readonly MapInstance _map;
+
+            private int _position;
+
+            public MapIterator(Engine engine, MapInstance map) : base(engine)
+            {
+                _map = map;
+                _position = 0;
+            }
+
+            public override bool TryIteratorStep(out ObjectInstance nextItem)
+            {
+                if (_position < _map.GetSize())
+                {
+                    var key = _map._map.GetKey(_position);
+                    var value = _map._map[key];
+
+                    _position++;
+                    nextItem = new KeyValueIteratorPosition(_engine, key, value);
+                    return true;
+                }
+
+                nextItem = KeyValueIteratorPosition.Done;
+                return false;
+            }
+        }
+
+    }
+}

+ 1 - 1
Jint/Native/RegExp/RegExpPrototype.cs

@@ -736,7 +736,7 @@ namespace Jint.Native.RegExp
             var global = flags.IndexOf('g') != -1;
             var fullUnicode = flags.IndexOf('u') != -1;
 
-            return _realm.Intrinsics.Iterator.CreateRegExpStringIterator(matcher, s, global, fullUnicode);
+            return _realm.Intrinsics.RegExpStringIteratorPrototype.Construct(matcher, s, global, fullUnicode);
         }
 
         private static int AdvanceStringIndex(string s, int index, bool unicode)

+ 29 - 0
Jint/Native/RegExp/RegExpStringIteratorPrototype.cs

@@ -0,0 +1,29 @@
+using Jint.Native.Iterator;
+using Jint.Native.Object;
+using Jint.Runtime;
+
+namespace Jint.Native.RegExp
+{
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%regexpstringiteratorprototype%-object
+    /// </summary>
+    internal sealed class RegExpStringIteratorPrototype : IteratorPrototype
+    {
+        internal RegExpStringIteratorPrototype(
+            Engine engine,
+            Realm realm,
+            ObjectPrototype objectPrototype) : base(engine, realm, "RegExp String Iterator", objectPrototype)
+        {
+        }
+
+        internal IteratorInstance Construct(ObjectInstance iteratingRegExp, string iteratedString, bool global, bool unicode)
+        {
+            var instance = new IteratorInstance.RegExpStringIterator(Engine, iteratingRegExp, iteratedString, global, unicode)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+    }
+}

+ 2 - 2
Jint/Native/Set/SetInstance.cs

@@ -73,12 +73,12 @@ namespace Jint.Native.Set
 
         internal ObjectInstance Entries()
         {
-            return _engine.Realm.Intrinsics.Iterator.ConstructEntryIterator(this);
+            return _engine.Realm.Intrinsics.SetIteratorPrototype.ConstructEntryIterator(this);
         }
 
         internal ObjectInstance Values()
         {
-            return _engine.Realm.Intrinsics.Iterator.ConstructValueIterator(this);
+            return _engine.Realm.Intrinsics.SetIteratorPrototype.ConstructValueIterator(this);
         }
     }
 }

+ 66 - 0
Jint/Native/Set/SetIteratorPrototype.cs

@@ -0,0 +1,66 @@
+using Jint.Native.Iterator;
+using Jint.Native.Object;
+using Jint.Runtime;
+
+namespace Jint.Native.Set
+{
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%setiteratorprototype%-object
+    /// </summary>
+    internal sealed class SetIteratorPrototype : IteratorPrototype
+    {
+        internal SetIteratorPrototype(
+            Engine engine,
+            Realm realm,
+            ObjectPrototype objectPrototype) : base(engine, realm, "Set Iterator", objectPrototype)
+        {
+        }
+
+        internal IteratorInstance ConstructEntryIterator(SetInstance set)
+        {
+            var instance = new SetEntryIterator(Engine, set)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        internal IteratorInstance ConstructValueIterator(SetInstance set)
+        {
+            var instance = new IteratorInstance.ListIterator(Engine, set._set._list)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+
+        private sealed class SetEntryIterator : IteratorInstance
+        {
+            private readonly SetInstance _set;
+            private int _position;
+
+            public SetEntryIterator(Engine engine, SetInstance set) : base(engine)
+            {
+                _set = set;
+                _position = 0;
+            }
+
+            public override bool TryIteratorStep(out ObjectInstance nextItem)
+            {
+                if (_position < _set._set._list.Count)
+                {
+                    var value = _set._set[_position];
+                    _position++;
+                    nextItem = new KeyValueIteratorPosition(_engine, value, value);
+                    return true;
+                }
+
+                nextItem = KeyValueIteratorPosition.Done;
+                return false;
+            }
+        }
+
+    }
+}

+ 29 - 0
Jint/Native/String/StringIteratorPrototype.cs

@@ -0,0 +1,29 @@
+using Jint.Native.Iterator;
+using Jint.Native.Object;
+using Jint.Runtime;
+
+namespace Jint.Native.String
+{
+    /// <summary>
+    /// https://tc39.es/ecma262/#sec-%stringiteratorprototype%-object
+    /// </summary>
+    internal sealed class StringIteratorPrototype : IteratorPrototype
+    {
+        internal StringIteratorPrototype(
+            Engine engine,
+            Realm realm,
+            ObjectPrototype objectPrototype) : base(engine, realm, "String Iterator", objectPrototype)
+        {
+        }
+
+        public ObjectInstance Construct(string str)
+        {
+            var instance = new IteratorInstance.StringIterator(Engine, str)
+            {
+                _prototype = this
+            };
+
+            return instance;
+        }
+    }
+}

+ 1 - 1
Jint/Native/String/StringPrototype.cs

@@ -92,7 +92,7 @@ namespace Jint.Native.String
         {
             TypeConverter.CheckObjectCoercible(_engine, thisObj);
             var str = TypeConverter.ToString(thisObj);
-            return _realm.Intrinsics.Iterator.Construct(str);
+            return _realm.Intrinsics.StringIteratorPrototype.Construct(str);
         }
 
         private JsValue ToStringString(JsValue thisObj, JsValue[] arguments)

+ 3 - 3
Jint/Native/TypedArray/IntrinsicTypedArrayPrototype.cs

@@ -266,7 +266,7 @@ namespace Jint.Native.TypedArray
         private JsValue Entries(JsValue thisObj, JsValue[] arguments)
         {
             var o = thisObj.ValidateTypedArray(_realm);
-            return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(o, ArrayIteratorType.KeyAndValue);
+            return _realm.Intrinsics.ArrayIteratorPrototype.Construct(o, ArrayIteratorType.KeyAndValue);
         }
 
         /// <summary>
@@ -622,7 +622,7 @@ namespace Jint.Native.TypedArray
         private JsValue Keys(JsValue thisObj, JsValue[] arguments)
         {
             var o = thisObj.ValidateTypedArray(_realm);
-            return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(o, ArrayIteratorType.Key);
+            return _realm.Intrinsics.ArrayIteratorPrototype.Construct(o, ArrayIteratorType.Key);
         }
 
         /// <summary>
@@ -1266,7 +1266,7 @@ namespace Jint.Native.TypedArray
         private JsValue Values(JsValue thisObj, JsValue[] arguments)
         {
             var o = thisObj.ValidateTypedArray(_realm);
-            return _realm.Intrinsics.Iterator.CreateArrayLikeIterator(o, ArrayIteratorType.Value);
+            return _realm.Intrinsics.ArrayIteratorPrototype.Construct(o, ArrayIteratorType.Value);
         }
 
         /// <summary>

+ 1 - 1
Jint/Runtime/Interop/ObjectWrapper.cs

@@ -219,7 +219,7 @@ namespace Jint.Runtime.Interop
             {
                 var iteratorFunction = new ClrFunctionInstance(
                     Engine, "iterator",
-                    (thisObject, arguments) => _engine.Realm.Intrinsics.Iterator.Construct(this, intrinsics => intrinsics.Iterator.GenericIteratorPrototypeObject),
+                    (thisObject, arguments) => _engine.Realm.Intrinsics.ArrayIteratorPrototype.Construct(this, intrinsics => intrinsics.IteratorPrototype),
                     1,
                     PropertyFlag.Configurable);
                 var iteratorProperty = new PropertyDescriptor(iteratorFunction, PropertyFlag.Configurable | PropertyFlag.Writable);

+ 23 - 3
Jint/Runtime/Intrinsics.cs

@@ -53,16 +53,21 @@ namespace Jint.Runtime
         private ReflectInstance _reflect;
         private EvalFunctionInstance _eval;
         private DateConstructor _date;
-        private IteratorConstructor _iterator;
+        private IteratorPrototype _iteratorPrototype;
         private MathInstance _math;
         private JsonInstance _json;
         private SymbolConstructor _symbol;
         private RegExpConstructor _regExp;
+        private RegExpStringIteratorPrototype _regExpStringIteratorPrototype;
         private NumberConstructor _number;
         private StringConstructor _string;
+        private StringIteratorPrototype _stringIteratorPrototype;
         private MapConstructor _map;
+        private MapIteratorPrototype _mapIteratorPrototype;
         private SetConstructor _set;
+        private SetIteratorPrototype _setIteratorPrototype;
         private ArrayConstructor _array;
+        private ArrayIteratorPrototype _arrayIteratorPrototype;
         private BooleanConstructor _boolean;
         private ArrayBufferConstructor _arrayBufferConstructor;
         private DataViewConstructor _dataView;
@@ -102,6 +107,9 @@ namespace Jint.Runtime
         public ArrayConstructor Array =>
             _array ??= new ArrayConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        internal ArrayIteratorPrototype ArrayIteratorPrototype =>
+            _arrayIteratorPrototype ??= new ArrayIteratorPrototype(_engine, _realm, Object.PrototypeObject);
+
         public DataViewConstructor DataView =>
             _dataView ??= new DataViewConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
@@ -147,9 +155,15 @@ namespace Jint.Runtime
         public MapConstructor Map =>
             _map ??= new MapConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        internal MapIteratorPrototype MapIteratorPrototype =>
+            _mapIteratorPrototype ??= new MapIteratorPrototype(_engine, _realm, Object.PrototypeObject);
+
         public SetConstructor Set =>
             _set ??= new SetConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        internal SetIteratorPrototype SetIteratorPrototype =>
+            _setIteratorPrototype ??= new SetIteratorPrototype(_engine, _realm, Object.PrototypeObject);
+
         public WeakMapConstructor WeakMap =>
             _weakMap ??= new WeakMapConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
@@ -159,15 +173,21 @@ namespace Jint.Runtime
         public PromiseConstructor Promise =>
             _promise ??= new PromiseConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
-        public IteratorConstructor Iterator =>
-            _iterator ??= new IteratorConstructor(_engine, _realm, Object.PrototypeObject);
+        internal IteratorPrototype IteratorPrototype =>
+            _iteratorPrototype ??= new IteratorPrototype(_engine, _realm, null, Object.PrototypeObject);
 
         public StringConstructor String =>
             _string ??= new StringConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        internal StringIteratorPrototype StringIteratorPrototype =>
+            _stringIteratorPrototype ??= new StringIteratorPrototype(_engine, _realm, Object.PrototypeObject);
+
         public RegExpConstructor RegExp =>
             _regExp ??= new RegExpConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);
 
+        internal RegExpStringIteratorPrototype RegExpStringIteratorPrototype =>
+            _regExpStringIteratorPrototype ??= new RegExpStringIteratorPrototype(_engine, _realm, Object.PrototypeObject);
+
         public BooleanConstructor Boolean =>
             _boolean ??= new BooleanConstructor(_engine, _realm, Function.PrototypeObject, Object.PrototypeObject);