Browse Source

Remove IIterator interface (#1000)

Marko Lahma 3 years ago
parent
commit
6f4ad5052f

+ 1 - 1
Jint/Native/Array/ArrayConstructor.cs

@@ -175,7 +175,7 @@ namespace Jint.Native.Array
                 Engine engine,
                 Engine engine,
                 JsValue thisArg,
                 JsValue thisArg,
                 ObjectInstance instance,
                 ObjectInstance instance,
-                IIterator iterator,
+                IteratorInstance iterator,
                 ICallable callable) : base(engine, iterator, 2)
                 ICallable callable) : base(engine, iterator, 2)
             {
             {
                 _thisArg = thisArg;
                 _thisArg = thisArg;

+ 9 - 0
Jint/Native/Generator/GeneratorKind.cs

@@ -0,0 +1,9 @@
+namespace Jint.Native.Generator
+{
+    internal enum GeneratorKind
+    {
+        NonGenerator,
+        Sync,
+        Async
+    }
+}

+ 0 - 11
Jint/Native/Iterator/IIterator.cs

@@ -1,11 +0,0 @@
-using Jint.Native.Object;
-using Jint.Runtime;
-
-namespace Jint.Native.Iterator
-{
-    internal interface IIterator
-    {
-        bool TryIteratorStep(out ObjectInstance nextItem);
-        void Close(CompletionType completion);
-    }
-}

+ 6 - 6
Jint/Native/Iterator/IteratorInstance.cs

@@ -8,7 +8,7 @@ using Jint.Runtime.Descriptors;
 
 
 namespace Jint.Native.Iterator
 namespace Jint.Native.Iterator
 {
 {
-    internal class IteratorInstance : ObjectInstance, IIterator
+    internal class IteratorInstance : ObjectInstance
     {
     {
         private readonly IEnumerator<JsValue> _enumerable;
         private readonly IEnumerator<JsValue> _enumerable;
 
 
@@ -47,7 +47,7 @@ namespace Jint.Native.Iterator
             return false;
             return false;
         }
         }
 
 
-        public void Close(CompletionType completion)
+        public virtual void Close(CompletionType completion)
         {
         {
         }
         }
 
 
@@ -119,12 +119,12 @@ namespace Jint.Native.Iterator
             }
             }
         }
         }
 
 
-        internal sealed class ObjectIterator : IIterator
+        internal sealed class ObjectIterator : IteratorInstance
         {
         {
             private readonly ObjectInstance _target;
             private readonly ObjectInstance _target;
             private readonly ICallable _nextMethod;
             private readonly ICallable _nextMethod;
 
 
-            public ObjectIterator(ObjectInstance target)
+            public ObjectIterator(ObjectInstance target) : base(target.Engine)
             {
             {
                 _target = target;
                 _target = target;
                 _nextMethod = target.Get(CommonProperties.Next, target) as ICallable;
                 _nextMethod = target.Get(CommonProperties.Next, target) as ICallable;
@@ -134,7 +134,7 @@ namespace Jint.Native.Iterator
                 }
                 }
             }
             }
 
 
-            public bool TryIteratorStep(out ObjectInstance result)
+            public override bool TryIteratorStep(out ObjectInstance result)
             {
             {
                 result = IteratorNext();
                 result = IteratorNext();
 
 
@@ -159,7 +159,7 @@ namespace Jint.Native.Iterator
                 return instance;
                 return instance;
             }
             }
 
 
-            public void Close(CompletionType completion)
+            public override void Close(CompletionType completion)
             {
             {
                 if (!_target.TryGetValue(CommonProperties.Return, out var func)
                 if (!_target.TryGetValue(CommonProperties.Return, out var func)
                     || func.IsNullOrUndefined())
                     || func.IsNullOrUndefined())

+ 3 - 3
Jint/Native/Iterator/IteratorProtocol.cs

@@ -9,12 +9,12 @@ namespace Jint.Native.Iterator
     internal abstract class IteratorProtocol
     internal abstract class IteratorProtocol
     {
     {
         private readonly Engine _engine;
         private readonly Engine _engine;
-        private readonly IIterator _iterator;
+        private readonly IteratorInstance _iterator;
         private readonly int _argCount;
         private readonly int _argCount;
 
 
         protected IteratorProtocol(
         protected IteratorProtocol(
             Engine engine,
             Engine engine,
-            IIterator iterator,
+            IteratorInstance iterator,
             int argCount)
             int argCount)
         {
         {
             _engine = engine;
             _engine = engine;
@@ -68,7 +68,7 @@ namespace Jint.Native.Iterator
 
 
         protected abstract void ProcessItem(JsValue[] args, JsValue currentValue);
         protected abstract void ProcessItem(JsValue[] args, JsValue currentValue);
 
 
-        internal static void AddEntriesFromIterable(ObjectInstance target, IIterator iterable, object adder)
+        internal static void AddEntriesFromIterable(ObjectInstance target, IteratorInstance iterable, object adder)
         {
         {
             var callable = adder as ICallable;
             var callable = adder as ICallable;
             if (callable is null)
             if (callable is null)

+ 29 - 10
Jint/Native/JsValue.cs

@@ -2,6 +2,7 @@
 using System.Diagnostics;
 using System.Diagnostics;
 using System.Diagnostics.Contracts;
 using System.Diagnostics.Contracts;
 using System.Runtime.CompilerServices;
 using System.Runtime.CompilerServices;
+using Jint.Native.Generator;
 using Jint.Native.Iterator;
 using Jint.Native.Iterator;
 using Jint.Native.Number;
 using Jint.Native.Number;
 using Jint.Native.Object;
 using Jint.Native.Object;
@@ -36,9 +37,9 @@ namespace Jint.Native
 
 
         [Pure]
         [Pure]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        internal IIterator GetIterator(Realm realm)
+        internal IteratorInstance GetIterator(Realm realm, GeneratorKind hint = GeneratorKind.Sync, ICallable method = null)
         {
         {
-            if (!TryGetIterator(realm, out var iterator))
+            if (!TryGetIterator(realm, out var iterator, hint, method))
             {
             {
                 ExceptionHelper.ThrowTypeError(realm, "The value is not iterable");
                 ExceptionHelper.ThrowTypeError(realm, "The value is not iterable");
             }
             }
@@ -48,30 +49,48 @@ namespace Jint.Native
 
 
         [Pure]
         [Pure]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        internal bool TryGetIterator(Realm realm, out IIterator iterator)
+        internal bool TryGetIterator(Realm realm, out IteratorInstance iterator, GeneratorKind hint = GeneratorKind.Sync, ICallable method = null)
         {
         {
-            var objectInstance = TypeConverter.ToObject(realm, this);
+            var obj = TypeConverter.ToObject(realm, this);
 
 
-            if (!objectInstance.TryGetValue(GlobalSymbolRegistry.Iterator, out var value)
-                || value is not ICallable callable)
+            if (method is null)
+            {
+                if (hint == GeneratorKind.Async)
+                {
+                    method = obj.GetMethod(GlobalSymbolRegistry.AsyncIterator);
+                    if (method is null)
+                    {
+                        var syncMethod = obj.GetMethod(GlobalSymbolRegistry.Iterator);
+                        var syncIteratorRecord = obj.GetIterator(realm, GeneratorKind.Sync, syncMethod);
+                        // TODO async CreateAsyncFromSyncIterator(syncIteratorRecord);
+                        ExceptionHelper.ThrowNotImplementedException("async");
+                    }
+                }
+                else
+                {
+                    method = obj.GetMethod(GlobalSymbolRegistry.Iterator);
+                }
+            }
+
+            if (method is null)
             {
             {
                 iterator = null;
                 iterator = null;
                 return false;
                 return false;
             }
             }
 
 
-            var obj = callable.Call(this, Arguments.Empty) as ObjectInstance;
-            if (obj is null)
+            var iteratorResult = method.Call(obj, Arguments.Empty) as ObjectInstance;
+            if (iteratorResult is null)
             {
             {
                 ExceptionHelper.ThrowTypeError(realm, "Result of the Symbol.iterator method is not an object");
                 ExceptionHelper.ThrowTypeError(realm, "Result of the Symbol.iterator method is not an object");
             }
             }
 
 
-            if (obj is IIterator i)
+            if (iteratorResult is IteratorInstance i)
             {
             {
                 iterator = i;
                 iterator = i;
             }
             }
             else
             else
             {
             {
-                iterator = new IteratorInstance.ObjectIterator(obj);
+                iterator = new IteratorInstance.ObjectIterator(iteratorResult);
             }
             }
 
 
             return true;
             return true;

+ 2 - 2
Jint/Native/Promise/PromiseConstructor.cs

@@ -194,7 +194,7 @@ namespace Jint.Native.Promise
             }
             }
 
 
 
 
-            IIterator iterator;
+            IteratorInstance iterator;
             // 5. Let iteratorRecord be GetIterator(iterable).
             // 5. Let iteratorRecord be GetIterator(iterable).
             // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
             // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
 
 
@@ -336,7 +336,7 @@ namespace Jint.Native.Promise
             }
             }
 
 
 
 
-            IIterator iterator;
+            IteratorInstance iterator;
             // 5. Let iteratorRecord be GetIterator(iterable).
             // 5. Let iteratorRecord be GetIterator(iterable).
             // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
             // 6. IfAbruptRejectPromise(iteratorRecord, promiseCapability).
 
 

+ 1 - 1
Jint/Runtime/Environments/FunctionEnvironmentRecord.cs

@@ -408,7 +408,7 @@ namespace Jint.Runtime.Environments
             public ArrayPatternProtocol(
             public ArrayPatternProtocol(
                 Engine engine,
                 Engine engine,
                 ArrayInstance instance,
                 ArrayInstance instance,
-                IIterator iterator,
+                IteratorInstance iterator,
                 int max) : base(engine, iterator, 0)
                 int max) : base(engine, iterator, 0)
             {
             {
                 _instance = instance;
                 _instance = instance;

+ 2 - 2
Jint/Runtime/Interpreter/Expressions/BindingPatternAssignmentExpression.cs

@@ -64,7 +64,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             return default;
             return default;
         }
         }
 
 
-        private static bool ConsumeFromIterator(IIterator it, out JsValue value, out bool done)
+        private static bool ConsumeFromIterator(IteratorInstance it, out JsValue value, out bool done)
         {
         {
             value = JsValue.Undefined;
             value = JsValue.Undefined;
             done = false;
             done = false;
@@ -89,7 +89,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             var realm = engine.Realm;
             var realm = engine.Realm;
             var obj = TypeConverter.ToObject(realm, argument);
             var obj = TypeConverter.ToObject(realm, argument);
             ArrayOperations arrayOperations = null;
             ArrayOperations arrayOperations = null;
-            IIterator iterator = null;
+            IteratorInstance iterator = null;
 
 
             // optimize for array unless someone has touched the iterator
             // optimize for array unless someone has touched the iterator
             if (obj.IsArrayLike && obj.HasOriginalIterator)
             if (obj.IsArrayLike && obj.HasOriginalIterator)

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintArrayExpression.cs

@@ -93,7 +93,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             public ArraySpreadProtocol(
             public ArraySpreadProtocol(
                 Engine engine,
                 Engine engine,
                 ArrayInstance instance,
                 ArrayInstance instance,
-                IIterator iterator,
+                IteratorInstance iterator,
                 long startIndex) : base(engine, iterator, 0)
                 long startIndex) : base(engine, iterator, 0)
             {
             {
                 _instance = instance;
                 _instance = instance;

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintExpression.cs

@@ -479,7 +479,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             public ArraySpreadProtocol(
             public ArraySpreadProtocol(
                 Engine engine,
                 Engine engine,
                 System.Collections.Generic.List<JsValue> instance,
                 System.Collections.Generic.List<JsValue> instance,
-                IIterator iterator) : base(engine, iterator, 0)
+                IteratorInstance iterator) : base(engine, iterator, 0)
             {
             {
                 _instance = instance;
                 _instance = instance;
             }
             }

+ 1 - 1
Jint/Runtime/Interpreter/Expressions/JintSpreadExpression.cs

@@ -30,7 +30,7 @@ namespace Jint.Runtime.Interpreter.Expressions
             return Completion.Normal(objectInstance, _expression.Location);
             return Completion.Normal(objectInstance, _expression.Location);
         }
         }
 
 
-        internal void GetValueAndCheckIterator(EvaluationContext context, out JsValue instance, out IIterator iterator)
+        internal void GetValueAndCheckIterator(EvaluationContext context, out JsValue instance, out IteratorInstance iterator)
         {
         {
             instance = _argument.GetValue(context).Value;
             instance = _argument.GetValue(context).Value;
             if (instance is null || !instance.TryGetIterator(context.Engine.Realm, out iterator))
             if (instance is null || !instance.TryGetIterator(context.Engine.Realm, out iterator))

+ 3 - 3
Jint/Runtime/Interpreter/Statements/JintForInForOfStatement.cs

@@ -104,7 +104,7 @@ namespace Jint.Runtime.Interpreter.Statements
         /// <summary>
         /// <summary>
         /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofheadevaluation-tdznames-expr-iterationkind
         /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofheadevaluation-tdznames-expr-iterationkind
         /// </summary>
         /// </summary>
-        private bool HeadEvaluation(EvaluationContext context, out IIterator result)
+        private bool HeadEvaluation(EvaluationContext context, out IteratorInstance result)
         {
         {
             var engine = context.Engine;
             var engine = context.Engine;
             var oldEnv = engine.ExecutionContext.LexicalEnvironment;
             var oldEnv = engine.ExecutionContext.LexicalEnvironment;
@@ -135,7 +135,7 @@ namespace Jint.Runtime.Interpreter.Statements
             }
             }
             else
             else
             {
             {
-                result = exprValue as IIterator ?? exprValue.GetIterator(engine.Realm);
+                result = exprValue as IteratorInstance ?? exprValue.GetIterator(engine.Realm);
             }
             }
 
 
             return true;
             return true;
@@ -148,7 +148,7 @@ namespace Jint.Runtime.Interpreter.Statements
             EvaluationContext context,
             EvaluationContext context,
             JintExpression lhs,
             JintExpression lhs,
             JintStatement stmt,
             JintStatement stmt,
-            IIterator iteratorRecord,
+            IteratorInstance iteratorRecord,
             IterationKind iterationKind,
             IterationKind iterationKind,
             LhsKind lhsKind,
             LhsKind lhsKind,
             IteratorKind iteratorKind = IteratorKind.Sync)
             IteratorKind iteratorKind = IteratorKind.Sync)