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));
        }
Exemple #2
0
        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));
        }
Exemple #3
0
        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;
                }
            }
        }
Exemple #5
0
        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());
        }