Ejemplo n.º 1
0
        internal IteratorInstance ConstructValueIterator(MapInstance map)
        {
            var instance = new IteratorInstance(Engine, map._map.Values)
            {
                _prototype = this
            };

            return(instance);
        }
Ejemplo n.º 2
0
 public ArraySpreadProtocol(
     Engine engine,
     ArrayInstance instance,
     IteratorInstance iterator,
     long startIndex) : base(engine, iterator, 0)
 {
     _instance = instance;
     _index    = startIndex - 1;
 }
Ejemplo n.º 3
0
 public ArrayProtocol(
     Engine engine,
     JsValue thisArg,
     ObjectInstance instance,
     IteratorInstance iterator,
     ICallable callable) : base(engine, iterator, 2)
 {
     _thisArg  = thisArg;
     _instance = ArrayOperations.For(instance);
     _callable = callable;
 }
Ejemplo n.º 4
0
        internal bool TryGetIterator(Realm realm, out IteratorInstance iterator, GeneratorKind hint = GeneratorKind.Sync, ICallable method = null)
        {
            var obj = TypeConverter.ToObject(realm, this);

            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;
                return(false);
            }

            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");
            }

            if (iteratorResult is IteratorInstance i)
            {
                iterator = i;
            }
            else
            {
                iterator = new IteratorInstance.ObjectIterator(iteratorResult);
            }

            return(true);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofheadevaluation-tdznames-expr-iterationkind
        /// </summary>
        private bool HeadEvaluation(EvaluationContext context, out IteratorInstance result)
        {
            var engine = context.Engine;
            var oldEnv = engine.ExecutionContext.LexicalEnvironment;
            var tdz    = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv);

            if (_tdzNames != null)
            {
                var TDZEnvRec = tdz;
                foreach (var name in _tdzNames)
                {
                    TDZEnvRec.CreateMutableBinding(name);
                }
            }

            engine.UpdateLexicalEnvironment(tdz);
            var exprValue = _right.GetValue(context).Value;

            engine.UpdateLexicalEnvironment(oldEnv);

            if (_iterationKind == IterationKind.Enumerate)
            {
                if (exprValue.IsNullOrUndefined())
                {
                    result = null;
                    return(false);
                }

                var obj = TypeConverter.ToObject(engine.Realm, exprValue);
                result = new ObjectKeyVisitor(engine, obj);
            }
            else
            {
                result = exprValue as IteratorInstance ?? exprValue.GetIterator(engine.Realm);
            }

            return(true);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset
        /// </summary>
        private Completion BodyEvaluation(
            EvaluationContext context,
            JintExpression lhs,
            JintStatement stmt,
            IteratorInstance iteratorRecord,
            IterationKind iterationKind,
            LhsKind lhsKind,
            IteratorKind iteratorKind = IteratorKind.Sync)
        {
            var    engine        = context.Engine;
            var    oldEnv        = engine.ExecutionContext.LexicalEnvironment;
            var    v             = Undefined.Instance;
            var    destructuring = _destructuring;
            string lhsName       = null;

            var completionType = CompletionType.Normal;
            var close          = false;

            try
            {
                while (true)
                {
                    EnvironmentRecord iterationEnv = null;
                    if (!iteratorRecord.TryIteratorStep(out var nextResult))
                    {
                        close = true;
                        return(new Completion(CompletionType.Normal, v, null, Location));
                    }

                    if (iteratorKind == IteratorKind.Async)
                    {
                        // nextResult = await nextResult;
                        ExceptionHelper.ThrowNotImplementedException("await");
                    }

                    var nextValue = nextResult.Get(CommonProperties.Value);
                    close = true;

                    var lhsRef = new ExpressionResult();
                    if (lhsKind != LhsKind.LexicalBinding)
                    {
                        if (!destructuring)
                        {
                            lhsRef = lhs.Evaluate(context);
                        }
                    }
                    else
                    {
                        iterationEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv);
                        if (_tdzNames != null)
                        {
                            BindingInstantiation(iterationEnv);
                        }
                        engine.UpdateLexicalEnvironment(iterationEnv);

                        if (!destructuring)
                        {
                            var identifier = (Identifier)((VariableDeclaration)_leftNode).Declarations[0].Id;
                            lhsName ??= identifier.Name;
                            lhsRef = new ExpressionResult(ExpressionCompletionType.Normal, engine.ResolveBinding(lhsName), identifier.Location);
                        }
                    }

                    if (context.DebugMode)
                    {
                        context.Engine.DebugHandler.OnStep(_leftNode);
                    }

                    var status = new Completion();
                    if (!destructuring)
                    {
                        if (lhsRef.IsAbrupt())
                        {
                            close  = true;
                            status = new Completion(lhsRef);
                        }
                        else if (lhsKind == LhsKind.LexicalBinding)
                        {
                            ((Reference)lhsRef.Value).InitializeReferencedBinding(nextValue);
                        }
                        else
                        {
                            engine.PutValue((Reference)lhsRef.Value, nextValue);
                        }
                    }
                    else
                    {
                        status = BindingPatternAssignmentExpression.ProcessPatterns(
                            context,
                            _assignmentPattern,
                            nextValue,
                            iterationEnv,
                            checkObjectPatternPropertyReference: _lhsKind != LhsKind.VarBinding);

                        if (lhsKind == LhsKind.Assignment)
                        {
                            // DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument.
                        }
                        else if (lhsKind == LhsKind.VarBinding)
                        {
                            // BindingInitialization for lhs passing nextValue and undefined as the arguments.
                        }
                        else
                        {
                            // BindingInitialization for lhs passing nextValue and iterationEnv as arguments
                        }
                    }

                    if (status.IsAbrupt())
                    {
                        engine.UpdateLexicalEnvironment(oldEnv);
                        if (_iterationKind == IterationKind.AsyncIterate)
                        {
                            iteratorRecord.Close(status.Type);
                            return(status);
                        }

                        if (iterationKind == IterationKind.Enumerate)
                        {
                            return(status);
                        }

                        iteratorRecord.Close(status.Type);
                        return(status);
                    }

                    var result = stmt.Execute(context);
                    engine.UpdateLexicalEnvironment(oldEnv);

                    if (!ReferenceEquals(result.Value, null))
                    {
                        v = result.Value;
                    }

                    if (result.Type == CompletionType.Break && (result.Target == null || result.Target == _statement?.LabelSet?.Name))
                    {
                        completionType = CompletionType.Normal;
                        return(new Completion(CompletionType.Normal, v, null, Location));
                    }

                    if (result.Type != CompletionType.Continue || (result.Target != null && result.Target != _statement?.LabelSet?.Name))
                    {
                        completionType = result.Type;
                        if (result.IsAbrupt())
                        {
                            close = true;
                            return(result);
                        }
                    }
                }
            }
            catch
            {
                completionType = CompletionType.Throw;
                throw;
            }
            finally
            {
                if (close)
                {
                    try
                    {
                        iteratorRecord.Close(completionType);
                    }
                    catch
                    {
                        // if we already have and exception, use it
                        if (completionType != CompletionType.Throw)
                        {
                            throw;
                        }
                    }
                }
                engine.UpdateLexicalEnvironment(oldEnv);
            }
        }
Ejemplo n.º 7
0
 internal void GetValueAndCheckIterator(EvaluationContext context, out JsValue instance, out IteratorInstance iterator)
 {
     instance = _argument.GetValue(context).Value;
     if (instance is null || !instance.TryGetIterator(context.Engine.Realm, out iterator))
     {
         iterator = null;
         ExceptionHelper.ThrowTypeError(context.Engine.Realm, _argumentName + " is not iterable");
     }
 }