private BooleanCompletion EvaluateDelete(Interpreter interpreter) { var refComp = unaryExpression.Evaluate(interpreter); if (refComp.IsAbrupt()) { return(refComp.WithEmptyBool()); } var @ref = refComp.value; if (!(@ref is ReferenceValue reference)) { return(true); } if (reference.IsUnresolvableReference()) { if (reference.strict) { throw new InvalidOperationException("OperatorUnaryExpression.EvaluateDelete: cannot delete an unresolved member in strict mode"); } return(true); } if (reference.IsPropertyReference()) { if (reference is SuperReferenceValue) { return(Completion.ThrowReferenceError("OperatorUnaryExpression.EvaluateDelete: cannot delete from super").WithEmptyBool()); } var baseObj = ((IValue)reference.baseValue).ToObject().value as Object; var deleteStatus = baseObj !.InternalDelete(reference.referencedName); if (deleteStatus.IsAbrupt()) { return(deleteStatus); } var success = deleteStatus.Other; if (success == false && reference.strict) { return(Completion.ThrowTypeError("OperatorUnaryExpression.EvaluateDelete: delete failed in strict mode").WithEmptyBool()); } return(success); } if (!(reference.baseValue is EnvironmentRecord envRec)) { throw new InvalidOperationException("OperatorUnaryExpression.EvaluateDelete: unrecognized IReferenceable"); } return(envRec.DeleteBinding(reference.referencedName)); }
public Completion EvaluateNew(Interpreter interpreter, Arguments arguments) { var constructorComp = Evaluate(interpreter).GetValue(); if (constructorComp.IsAbrupt()) { return(constructorComp); } var constructor = constructorComp.value; var argumentValues = arguments.ArgumentListEvaluation(); if (argumentValues.IsAbrupt()) { return(argumentValues); } if (!(constructor is Constructor @object)) { return(Completion.ThrowTypeError("EvaluateNew: the expression is not a constructor.")); } return(@object.Construct(argumentValues.Other)); }
public override Completion Evaluate(Interpreter interpreter) { var leftValueComp = relationalExpression.Evaluate(interpreter).GetValue(); if (leftValueComp.IsAbrupt()) { return(leftValueComp); } var leftValue = leftValueComp.value !; var rightValueComp = shiftExpression.Evaluate(interpreter).GetValue(); if (rightValueComp.IsAbrupt()) { return(rightValueComp); } var rightValue = rightValueComp.value !; Completion r; switch (relationalOperator) { case RelationalOperator.LessThan: r = AbstractRelationalComparison(leftValue, rightValue); if (r.IsAbrupt()) { return(r); } if (r.value == UndefinedValue.Instance) { return(Completion.NormalCompletion(BooleanValue.False)); } return(r); case RelationalOperator.GreaterThan: r = AbstractRelationalComparison(rightValue, leftValue, false); if (r.IsAbrupt()) { return(r); } if (r.value == UndefinedValue.Instance) { return(Completion.NormalCompletion(BooleanValue.False)); } return(r); case RelationalOperator.LessThanOrEqual: r = AbstractRelationalComparison(rightValue, leftValue, false); if (r.IsAbrupt()) { return(r); } if (r.value == UndefinedValue.Instance || r.value == BooleanValue.True) { return(Completion.NormalCompletion(BooleanValue.False)); } return(Completion.NormalCompletion(BooleanValue.True)); case RelationalOperator.GreaterThanOrEqual: r = AbstractRelationalComparison(leftValue, rightValue); if (r.IsAbrupt()) { return(r); } if (r.value == UndefinedValue.Instance || r.value == BooleanValue.True) { return(Completion.NormalCompletion(BooleanValue.False)); } return(Completion.NormalCompletion(BooleanValue.True)); case RelationalOperator.Instanceof: return(InstanceOf(leftValue, rightValue)); case RelationalOperator.In: if (!(rightValue is Object o)) { return(Completion.ThrowTypeError("in operator applied to non-object")); } var propertyKey = leftValue.ToPropertyKey(); if (propertyKey.IsAbrupt()) { return(propertyKey); } return(o.HasProperty(propertyKey.Other !)); default: throw new InvalidOperationException($"RelationalExpression.Evaluate: unknown RelationalOperator enum value {(int)relationalOperator}"); } }
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; } } }
private Completion GlobalDeclarationInstantiation(LexicalEnvironment env) { var envRecAbstract = env.EnvironmentRecord; if (!(envRecAbstract is GlobalEnvironmentRecord envRec)) { throw new InvalidOperationException("Spec 15.1.11 step 2"); } var lexNames = scriptBody.LexicallyDeclaredNames(); var varNames = scriptBody.VarDeclaredNames(); foreach (var name in lexNames) { if (envRec.HasVarDeclaration(name)) { return(Completion.ThrowSyntaxError($"variable {name} is already declared")); } if (envRec.HasLexicalDeclaration(name)) { return(Completion.ThrowSyntaxError($"variable {name} is already declared")); } var hasRestrictedGlobal = envRec.HasRestrictedGlobalProperty(name); if (hasRestrictedGlobal.IsAbrupt()) { return(hasRestrictedGlobal); } if (hasRestrictedGlobal.Other == true) { return(Completion.ThrowSyntaxError($"variable {name} is already a restricted global")); } } foreach (var name in varNames) { if (envRec.HasLexicalDeclaration(name)) { return(Completion.ThrowSyntaxError($"variable {name} is already declared")); } } var varDeclarations = scriptBody.VarScopedDeclarations(); var functionsToInitialize = new List <FunctionDeclaration>(); var declaredFunctionNames = new List <string>(); foreach (var d in varDeclarations.Reverse()) { if (d is FunctionDeclaration f) { var fn = f.BoundNames()[0]; if (!declaredFunctionNames.Contains(fn)) { var fnDefinable = envRec.CanDeclareGlobalFunction(fn); if (fnDefinable.IsAbrupt()) { return(fnDefinable); } if (!fnDefinable.Other) { return(Completion.ThrowTypeError($"function {fn} cannot be declared.")); } declaredFunctionNames.Add(fn); functionsToInitialize.Insert(0, f); } } } var declaredVarNames = new List <string>(); foreach (var d in varDeclarations) { string vn; if (d is VariableDeclaration v) { vn = v.name; } else if (d is ForBinding f) { vn = f.name; } else { continue; } if (!declaredVarNames.Contains(vn)) { var vnDefinable = envRec.CanDeclareGlobalVar(vn); if (vnDefinable.IsAbrupt()) { return(vnDefinable); } if (!vnDefinable.Other) { return(Completion.ThrowTypeError($"variable {vn} cannot be declared.")); } declaredVarNames.Add(vn); } } //TODO Annex B.3.3.2 var lexDeclarations = scriptBody.LexicallyScopedDeclarations(); foreach (var d in lexDeclarations) { foreach (var dn in d.BoundNames()) { Completion comp; if (d.IsConstantDeclaration()) { comp = envRec.CreateImmutableBinding(dn, true); } else { comp = envRec.CreateMutableBinding(dn, false); } if (comp.IsAbrupt()) { return(comp); } } } foreach (var f in functionsToInitialize) { var fn = f.BoundNames()[0]; var fo = f.InstantiateFunctionObject(env); var comp = envRec.CreateGlobalFunctionBinding(fn, fo, false); if (comp.IsAbrupt()) { return(comp); } } foreach (var vn in declaredVarNames) { var comp = envRec.CreateGlobalVarBinding(vn, false); if (comp.IsAbrupt()) { return(comp); } } return(Completion.NormalCompletion()); }