예제 #1
0
        public static Completion min(IValue @this, IReadOnlyList <IValue> arguments)
        {
            double minValue = double.PositiveInfinity;

            foreach (var arg in arguments)
            {
                var xComp = arguments.At(0);
                if (xComp.IsAbrupt())
                {
                    return(xComp);
                }
                xComp = xComp.value !.ToNumber();
                if (xComp.IsAbrupt())
                {
                    return(xComp);
                }
                var x = (xComp.value as NumberValue) !.number;

                if (double.IsNaN(x))
                {
                    return(Completion.NormalCompletion(NumberValue.DoubleNaN));
                }

                if (x < minValue)
                {
                    minValue = x;
                }
            }

            return(Completion.NormalCompletion(new NumberValue(minValue)));
        }
예제 #2
0
 private static Completion CreatePerIterationEnvironment(IEnumerable <string> perIterationBindings)
 {
     if (perIterationBindings.Any())
     {
         var lastIterationEnv    = Interpreter.Instance().RunningExecutionContext().LexicalEnvironment;
         var lastIterationEnvRec = lastIterationEnv.EnvironmentRecord;
         var outer = lastIterationEnv.Outer;
         if (outer == null)
         {
             throw new InvalidOperationException("Spec 13.7.4.9 step 1d");
         }
         var thisIterationEnv    = outer.NewDeclarativeEnvironment();
         var thisIterationEnvRec = thisIterationEnv.EnvironmentRecord;
         foreach (var bn in perIterationBindings)
         {
             thisIterationEnvRec.CreateMutableBinding(bn, false);
             var lastValue = lastIterationEnvRec.GetBindingValue(bn, true);
             if (lastValue.IsAbrupt())
             {
                 return(lastValue);
             }
             thisIterationEnvRec.InitializeBinding(bn, lastValue.value !);
         }
         Interpreter.Instance().RunningExecutionContext().LexicalEnvironment = thisIterationEnv;
     }
     return(Completion.NormalCompletion(UndefinedValue.Instance));
 }
예제 #3
0
        public override Completion LabelledEvaluate(Interpreter interpreter, List <string> labels)
        {
            IValue V = UndefinedValue.Instance;

            while (true)
            {
                var conditionComp = whileExpression.Evaluate(interpreter);
                var condition     = conditionComp.GetValue();
                if (condition.IsAbrupt())
                {
                    return(condition);
                }
                if (!condition.value !.ToBoolean().boolean)
                {
                    return(Completion.NormalCompletion(V));
                }

                var stmtResult = doStatement.Evaluate(interpreter);
                if (!LoopContinues(stmtResult, labels))
                {
                    return(stmtResult.UpdateEmpty(V));
                }
                if (stmtResult.value != null)
                {
                    V = stmtResult.value;
                }
            }
        }
예제 #4
0
        private Completion EvaluateTypeof(Interpreter interpreter)
        {
            var valComp = unaryExpression.Evaluate(interpreter);

            if (valComp.value is ReferenceValue reference)
            {
                if (reference.IsUnresolvableReference())
                {
                    return(Completion.NormalCompletion(new StringValue("undefined")));
                }
            }
            var val = valComp.GetValue();

            if (val.IsAbrupt())
            {
                return(val);
            }
            return(Completion.NormalCompletion(new StringValue(val.value switch
            {
                UndefinedValue _ => "undefined",
                NullValue _ => "object",
                BooleanValue _ => "boolean",
                NumberValue _ => "number",
                StringValue _ => "string",
                FunctionObject _ => "function",
                Object _ => "object",
                _ => throw new InvalidOperationException("OperatorUnaryExpression.EvaluateTypeof: unknown type"),
            })));
예제 #5
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var @ref     = memberExpression.Evaluate(interpreter);
            var funcComp = @ref.GetValue();

            if (funcComp.IsAbrupt())
            {
                return(funcComp);
            }
            var func = funcComp.value !;

            if (func == UndefinedValue.Instance && @ref.value is ReferenceValue r)
            {
                return(Completion.ThrowReferenceError($"Cannot call undefined method {r.referencedName } on a {r.baseValue.GetType().Name}"));
            }

            if (@ref.value is ReferenceValue referenceValue && !referenceValue.baseValue.IsPrimitive() && referenceValue.referencedName == "eval")
            {
                if (func == interpreter.CurrentRealm().Intrinsics.Eval)
                {
                    var argList = arguments.ArgumentListEvaluation();
                    if (argList.IsAbrupt())
                    {
                        return(argList);
                    }
                    if (!argList.Other.Any())
                    {
                        return(Completion.NormalCompletion(UndefinedValue.Instance));
                    }
                    var evalText  = argList.Other ![0];
예제 #6
0
 public override Completion Evaluate(Interpreter interpreter)
 {
     if (System.Diagnostics.Debugger.IsAttached)
     {
         System.Diagnostics.Debugger.Break();
     }
     return(Completion.NormalCompletion());
 }
예제 #7
0
 public override Completion Evaluate(Interpreter interpreter)
 {
     if (!scriptBody.Any())
     {
         return(Completion.NormalCompletion(UndefinedValue.Instance));
     }
     throw new InvalidOperationException("Evaluate is not defined for scripts with bodies. Use ScriptEvaluate instead.");
 }
예제 #8
0
 public Completion Evaluate(Interpreter interpreter)
 {
     if (statementList == null)
     {
         return(Completion.NormalCompletion());
     }
     return(statementList.Evaluate(interpreter));
 }
예제 #9
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var comp = variableDeclarations.Evaluate(interpreter);

            if (comp.IsAbrupt())
            {
                return(comp);
            }
            return(Completion.NormalCompletion());
        }
예제 #10
0
        public override Completion LabelledEvaluate(Interpreter interpreter, List <string> labelSet)
        {
            labelSet.Add(identifier.name);
            var stmtResult = labelledItem.LabelledEvaluate(interpreter, labelSet);

            if (stmtResult.completionType == CompletionType.Break && identifier.name == stmtResult.target)
            {
                stmtResult = Completion.NormalCompletion(stmtResult.value);
            }
            return(stmtResult);
        }
예제 #11
0
 public override Completion Evaluate(Interpreter interpreter)
 {
     foreach (var i in lexicalDeclarationItems)
     {
         var completion = i.Evaluate(interpreter);
         if (completion.IsAbrupt())
         {
             return(completion);
         }
     }
     return(Completion.NormalCompletion());
 }
예제 #12
0
        public override Completion LabelledEvaluate(Interpreter interpreter, List <string> labels)
        {
            var stmtResult = Evaluate(interpreter);

            if (stmtResult.completionType == CompletionType.Break && stmtResult.target == null)
            {
                if (stmtResult.value == null)
                {
                    return(Completion.NormalCompletion(UndefinedValue.Instance));
                }
                stmtResult = Completion.NormalCompletion(stmtResult.value);
            }
            return(stmtResult);
        }
예제 #13
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var lhs = unaryExpression.Evaluate(interpreter);

            if (lhs.IsAbrupt())
            {
                return(lhs);
            }

            var lhsValue = lhs.GetValue();

            if (lhsValue.IsAbrupt())
            {
                return(lhsValue);
            }

            var oldValueComp = lhsValue.value !.ToNumber();

            if (oldValueComp.IsAbrupt())
            {
                return(oldValueComp);
            }
            var oldValue = oldValueComp.value as NumberValue;

            if (!(lhs.value is ReferenceValue reference))
            {
                throw new InvalidOperationException("PrefixUpdateExpression.Evaluate: unaryExpression did not return a reference");
            }

            NumberValue newValue;

            if (updateOperation == UpdateOperator.Decrement)
            {
                newValue = new NumberValue(oldValue !.number - 1);
            }
            else
            {
                newValue = new NumberValue(oldValue !.number + 1);
            }

            var putComp = reference.PutValue(newValue);

            if (putComp.IsAbrupt())
            {
                return(putComp);
            }

            return(Completion.NormalCompletion(newValue));
        }
예제 #14
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            IValue lastValue = UndefinedValue.Instance;

            foreach (var expression in assignmentExpressions)
            {
                var comp = expression.Evaluate(interpreter).GetValue();
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
                lastValue = comp.value !;
            }
            return(Completion.NormalCompletion(lastValue));
        }
예제 #15
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var obj = Utils.ObjectCreate(interpreter.CurrentRealm().Intrinsics.ObjectPrototype);

            foreach (var property in propertyDefinitions)
            {
                var comp = property.PropertyDefinitionEvaluation(obj, true);
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
            }

            return(Completion.NormalCompletion(obj));
        }
예제 #16
0
        protected static Completion ForBodyEvaluation(AbstractExpression?test, AbstractExpression?increment, Statement stmt, IEnumerable <string> perIterationBindings, List <string> labelSet)
        {
            IValue V    = UndefinedValue.Instance;
            var    comp = CreatePerIterationEnvironment(perIterationBindings);

            if (comp.IsAbrupt())
            {
                return(comp);
            }
            while (true)
            {
                if (test != null)
                {
                    var testComp      = test.Evaluate(Interpreter.Instance());
                    var testValueComp = testComp.GetValue();
                    if (testValueComp.IsAbrupt())
                    {
                        return(testValueComp);
                    }
                    if (!testValueComp.value !.ToBoolean().boolean)
                    {
                        return(Completion.NormalCompletion(V));
                    }
                }
                var result = stmt.Evaluate(Interpreter.Instance());
                if (!LoopContinues(result, labelSet))
                {
                    return(result.UpdateEmpty(V));
                }
                if (result.value != null)
                {
                    V = result.value;
                }
                comp = CreatePerIterationEnvironment(perIterationBindings);
                if (comp.IsAbrupt())
                {
                    return(comp);
                }
                if (increment != null)
                {
                    var inc = increment.Evaluate(Interpreter.Instance()).GetValue();
                    if (inc.IsAbrupt())
                    {
                        return(inc);
                    }
                }
            }
        }
예제 #17
0
        public Completion PropertyDefinitionEvaluation(Object @object, bool enumerable)
        {
            var valueComp = Evaluate(Interpreter.Instance()).GetValue();

            if (valueComp.IsAbrupt())
            {
                return(valueComp);
            }
            var value = valueComp.value !;

            if (Utils.CreateDataPropertyOrThrow(@object, identifier.name, value).IsAbrupt())
            {
                throw new InvalidOperationException("Spec ! 12.2.6.8 IdentifierReference, step 6");
            }
            return(Completion.NormalCompletion());
        }
예제 #18
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            if (!statementList.Any())
            {
                return(Completion.NormalCompletion());
            }
            var oldEnv   = interpreter.RunningExecutionContext().LexicalEnvironment;
            var blockEnv = oldEnv.NewDeclarativeEnvironment();

            BlockDeclarationInstantiation(statementList, blockEnv);
            interpreter.RunningExecutionContext().LexicalEnvironment = blockEnv;
            Completion blockValue = statementList.Evaluate(interpreter);

            interpreter.RunningExecutionContext().LexicalEnvironment = oldEnv;
            return(blockValue);
        }
예제 #19
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var left = logicalOrExpression.Evaluate(interpreter).GetValue();

            if (left.IsAbrupt())
            {
                return(left);
            }
            var leftValue = left.value !;

            if (leftValue.ToBoolean().boolean)
            {
                return(Completion.NormalCompletion(leftValue));
            }
            return(logicalAndExpression.Evaluate(interpreter).GetValue());
        }
예제 #20
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            var baseValueComp = dotMemberExpression.Evaluate(interpreter).GetValue();

            if (baseValueComp.IsAbrupt())
            {
                return(baseValueComp);
            }
            var baseValue = baseValueComp.value !;
            var coercible = baseValue.RequireObjectCoercible();

            if (coercible.IsAbrupt())
            {
                return(coercible);
            }
            return(Completion.NormalCompletion(new ReferenceValue(baseValue, dotIdentifierName, IsStrictMode)));
        }
예제 #21
0
        public static Completion log(IValue @this, IReadOnlyList <IValue> arguments)
        {
            var xComp = arguments.At(0);

            if (xComp.IsAbrupt())
            {
                return(xComp);
            }
            xComp = xComp.value !.ToNumber();
            if (xComp.IsAbrupt())
            {
                return(xComp);
            }
            var x = (xComp.value as NumberValue) !.number;

            return(Completion.NormalCompletion(new NumberValue(System.Math.Log(x))));
        }
예제 #22
0
        public Completion BindingInitialization(IValue value, LexicalEnvironment environment)
        {
            if (environment != null)
            {
                environment.EnvironmentRecord.InitializeBinding(name, value);
                return(Completion.NormalCompletion(UndefinedValue.Instance));
            }
            var lhsComp = Interpreter.Instance().ResolveBinding(name, IsStrictMode);

            if (lhsComp.IsAbrupt())
            {
                return(lhsComp);
            }
            var lhs = lhsComp.value as ReferenceValue;

            return(lhs !.PutValue(value));
        }
예제 #23
0
        public override Completion Evaluate(Interpreter interpreter)
        {
            Completion lastValue = Completion.NormalCompletion();

            foreach (var statement in statements)
            {
                var val = statement.Evaluate(interpreter);
                if (val.IsAbrupt())
                {
                    return(val);
                }
                if (val.value != null)
                {
                    lastValue = val;
                }
            }
            return(lastValue);
        }
예제 #24
0
 public override Completion Evaluate(Interpreter interpreter)
 {
     if (arrayLiteralItems.Count == 1 && arrayLiteralItems[0] is Elision e)
     {
         var array = ArrayObject.ArrayCreate(0);
         array.Set("length", new NumberValue(e.width), false);
         return(Completion.NormalCompletion(array));
     }
     else
     {
         var array = ArrayObject.ArrayCreate(0);
         var len   = ArrayAccumulate(array, 0);
         if (len.IsAbrupt())
         {
             return(len);
         }
         array.Set("length", len.value !, false);
         return(Completion.NormalCompletion(array));
     }
 }
예제 #25
0
        public static Completion Calculate(IValue leftValue, IValue rightValue)
        {
            var baseComp = leftValue.ToNumber();

            if (baseComp.IsAbrupt())
            {
                return(baseComp);
            }
            var exponentComp = rightValue.ToNumber();

            if (exponentComp.IsAbrupt())
            {
                return(exponentComp);
            }


            double @base    = (baseComp.value as NumberValue) !.number;
            double exponent = (exponentComp.value as NumberValue) !.number;

            return(Completion.NormalCompletion(new NumberValue(Math.Pow(@base, exponent))));
        }
예제 #26
0
        public Completion PropertyDefinitionEvaluation(Object @object, bool enumerable)
        {
            var valueComp = assignmentExpression.Evaluate(Interpreter.Instance());

            if (valueComp.IsAbrupt())
            {
                return(valueComp);
            }
            var value = valueComp.value;

            if (!(value is Object source))
            {
                throw new InvalidOperationException($"ObjectLiteral: tried to initialize an object using a spread on a non-object");
            }
            valueComp = Utils.CopyDataProperties(@object, source, excludedItems: Utils.EmptyList <string>());
            if (valueComp.IsAbrupt())
            {
                return(valueComp);
            }
            return(Completion.NormalCompletion());
        }
예제 #27
0
 public override Completion Evaluate(Interpreter interpreter)
 {
     if (hasElse)
     {
         var conditionComp = conditionExpression.Evaluate(interpreter).GetValue();
         if (conditionComp.IsAbrupt())
         {
             return(conditionComp);
         }
         var        condition = conditionComp.value !.ToBoolean();
         Completion stmtCompletion;
         if (condition.boolean)
         {
             stmtCompletion = trueStatement.Evaluate(interpreter);
         }
         else
         {
             stmtCompletion = falseStatement !.Evaluate(interpreter);
         }
         return(stmtCompletion.UpdateEmpty(UndefinedValue.Instance));
     }
     else
     {
         var conditionComp = conditionExpression.Evaluate(interpreter).GetValue();
         if (conditionComp.IsAbrupt())
         {
             return(conditionComp);
         }
         var condition = conditionComp.value !.ToBoolean();
         if (!condition.boolean)
         {
             return(Completion.NormalCompletion(UndefinedValue.Instance));
         }
         else
         {
             var stmtCompletion = trueStatement.Evaluate(interpreter);
             return(stmtCompletion.UpdateEmpty(UndefinedValue.Instance));
         }
     }
 }
예제 #28
0
        private Completion AbstractRelationalComparison(IValue x, IValue y, bool leftFirst = true)
        {
            IValue px, py;

            if (leftFirst)
            {
                var xComp = x.ToPrimitive();
                if (xComp.IsAbrupt())
                {
                    return(xComp);
                }
                px = xComp.value !;
                var yComp = y.ToPrimitive();
                if (yComp.IsAbrupt())
                {
                    return(yComp);
                }
                py = yComp.value !;
            }
            else
            {
                var yComp = y.ToPrimitive();
                if (yComp.IsAbrupt())
                {
                    return(yComp);
                }
                py = yComp.value !;
                var xComp = x.ToPrimitive();
                if (xComp.IsAbrupt())
                {
                    return(xComp);
                }
                px = xComp.value !;
            }
            if (px is StringValue sx && py is StringValue sy)
            {
                return(Completion.NormalCompletion((string.Compare(sx.@string, sy.@string, StringComparison.InvariantCulture) < 0) ? BooleanValue.True : BooleanValue.False));
            }
예제 #29
0
        public Completion Evaluate(Interpreter interpreter)
        {
            if (assignmentExpression == null)
            {
                return(Completion.NormalCompletion());
            }
            var lhsComp = interpreter.ResolveBinding(name, IsStrictMode);

            if (lhsComp.IsAbrupt())
            {
                return(lhsComp);
            }
            if (!(lhsComp.value is ReferenceValue referenceValue))
            {
                throw new InvalidOperationException("ResolveBinding didn't return a reference");
            }

            Completion value;

            if (assignmentExpression is FunctionExpression functionExpression && functionExpression.isAnonymous)
            {
                value = functionExpression.NamedEvaluate(interpreter, name);
            }
예제 #30
0
        public static Completion MakeSuperPropertyReference(IValue actualThis, string propertyKey, bool strict)
        {
            var env = Interpreter.Instance().GetThisEnvironment();

            if (!env.HasSuperBinding())
            {
                throw new InvalidOperationException("SuperHelper.MakeSuperPropertyReference: Interpreter.GetThisEnvironment has no super binding");
            }
            var baseValueComp = ((FunctionEnvironmentRecord)env).GetSuperBase();

            if (baseValueComp.IsAbrupt())
            {
                return(baseValueComp);
            }
            var baseValue = baseValueComp.value !;
            var coercible = baseValue.RequireObjectCoercible();

            if (coercible.IsAbrupt())
            {
                return(coercible);
            }
            return(Completion.NormalCompletion(new SuperReferenceValue(baseValue, propertyKey, strict, actualThis)));
        }