protected Completion ForInOfBodyEvaluation(IForInOfInitializer lhs, Statement stmt, IteratorRecord iteratorRecord, IterationKind iterationKind, LHSKind lhsKind, List <string> labelSet, IteratorKind?iteratorKindNullable = null) { var iteratorKind = iteratorKindNullable.GetValueOrDefault(IteratorKind.Sync); var oldEnv = Interpreter.Instance().RunningExecutionContext().LexicalEnvironment; IValue V = UndefinedValue.Instance; // TODO assuming destructuring is false bool destructuring = false; while (true) { var nextResultComp = iteratorRecord.NextMethod.Call(iteratorRecord.Iterator); if (nextResultComp.IsAbrupt()) { return(nextResultComp); } var nextResult = nextResultComp.value; if (iteratorKind == IteratorKind.Async) { throw new NotImplementedException("async"); } if (!(nextResult is Object nextResultObject)) { return(Completion.ThrowTypeError("iterator next did not return an object.")); } var doneComp = IteratorRecord.IteratorComplete(nextResultObject); if (doneComp.IsAbrupt()) { return(doneComp); } var done = (doneComp.value as BooleanValue) !.boolean; if (done) { return(Completion.NormalCompletion(V)); } var nextValueComp = IteratorRecord.IteratorValue(nextResultObject); if (nextValueComp.IsAbrupt()) { return(nextValueComp); } var nextValue = nextValueComp.value !; Completion lhsRef = Completion.NormalCompletion(); if (lhsKind == LHSKind.Assignment || lhsKind == LHSKind.VarBinding) { if (!destructuring) { lhsRef = lhs.Evaluate(Interpreter.Instance()); } } else { if (lhsKind != LHSKind.LexicalBinding) { throw new InvalidOperationException("Spec 13.7.5.13 step 6hi"); } if (!(lhs is ForDeclaration forDeclaration)) { throw new InvalidOperationException("Spec 13.7.5.13 step 6hii"); } var iterationEnv = oldEnv.NewDeclarativeEnvironment(); forDeclaration.BindingInstantiation(iterationEnv); Interpreter.Instance().RunningExecutionContext().LexicalEnvironment = iterationEnv; if (!destructuring) { lhsRef = Interpreter.Instance().ResolveBinding(forDeclaration.name, IsStrictMode); } } Completion status; if (!destructuring) { if (lhsRef.IsAbrupt()) { status = lhsRef; } else if (lhsKind == LHSKind.LexicalBinding) { status = (lhsRef.value as ReferenceValue) !.InitializeReferencedBinding(nextValue); } else { status = (lhsRef.value as ReferenceValue) !.PutValue(nextValue); } } else { throw new NotImplementedException("destructuring"); } if (status.IsAbrupt()) { Interpreter.Instance().RunningExecutionContext().LexicalEnvironment = oldEnv; if (iteratorKind == IteratorKind.Async) { throw new NotImplementedException("async"); } if (iterationKind == IterationKind.Enumerate) { return(status); } else { return(iteratorRecord.IteratorClose(status)); } } var result = stmt.Evaluate(Interpreter.Instance()); Interpreter.Instance().RunningExecutionContext().LexicalEnvironment = oldEnv; if (!LoopContinues(result, labelSet)) { if (iterationKind == IterationKind.Enumerate) { return(result.UpdateEmpty(V)); } else { status = result.UpdateEmpty(V); if (iteratorKind == IteratorKind.Async) { throw new NotImplementedException("async"); } return(iteratorRecord.IteratorClose(status)); } } if (result.value != null) { V = result.value; } } }