Example #1
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.1
        /// </summary>
        /// <param name="doWhileStatement"></param>
        /// <returns></returns>
        public Completion ExecuteDoWhileStatement(DoWhileStatement doWhileStatement)
        {
            JsValue v = Undefined.Instance;
            bool    iterating;

            do
            {
                var stmt = ExecuteStatement(doWhileStatement.Body);
                if (stmt.Value != null)
                {
                    v = stmt.Value;
                }
                if (stmt.Type != Completion.Continue || stmt.Identifier != doWhileStatement.LabelSet)
                {
                    if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == doWhileStatement.LabelSet))
                    {
                        return(new Completion(Completion.Normal, v, null));
                    }

                    if (stmt.Type != Completion.Normal)
                    {
                        return(stmt);
                    }
                }
                var exprRef = _engine.EvaluateExpression(doWhileStatement.Test);
                iterating = TypeConverter.ToBoolean(_engine.GetValue(exprRef));
            } while (iterating);

            return(new Completion(Completion.Normal, v, null));
        }
Example #2
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.2
        /// </summary>
        /// <param name="whileStatement"></param>
        /// <returns></returns>
        public Completion ExecuteWhileStatement(WhileStatement whileStatement)
        {
            JsValue v = Undefined.Instance;

            while (true)
            {
                var exprRef = _engine.EvaluateExpression(whileStatement.Test);

                if (!TypeConverter.ToBoolean(_engine.GetValue(exprRef)))
                {
                    return(new Completion(Completion.Normal, v, null));
                }

                var stmt = ExecuteStatement(whileStatement.Body);

                if (stmt.Value != null)
                {
                    v = stmt.Value;
                }

                if (stmt.Type != Completion.Continue || stmt.Identifier != whileStatement.LabelSet)
                {
                    if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == whileStatement.LabelSet))
                    {
                        return(new Completion(Completion.Normal, v, null));
                    }

                    if (stmt.Type != Completion.Normal)
                    {
                        return(stmt);
                    }
                }
            }
        }
Example #3
0
        public JsValue EvaluateLogicalExpression(LogicalExpression logicalExpression)
        {
            var left = _engine.GetValue(EvaluateExpression(logicalExpression.Left));

            switch (logicalExpression.Operator)
            {
            case LogicalOperator.LogicalAnd:
                if (!TypeConverter.ToBoolean(left))
                {
                    return(left);
                }

                return(_engine.GetValue(EvaluateExpression(logicalExpression.Right)));

            case LogicalOperator.LogicalOr:
                if (TypeConverter.ToBoolean(left))
                {
                    return(left);
                }

                return(_engine.GetValue(EvaluateExpression(logicalExpression.Right)));

            default:
                throw new NotImplementedException();
            }
        }
Example #4
0
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.3
        /// </summary>
        /// <param name="forStatement"></param>
        /// <returns></returns>
        public Completion ExecuteForStatement(ForStatement forStatement)
        {
            if (forStatement.Init != null)
            {
                if (forStatement.Init.Type == SyntaxNodes.VariableDeclaration)
                {
                    ExecuteStatement(forStatement.Init.As <Statement>());
                }
                else
                {
                    _engine.GetValue(_engine.EvaluateExpression(forStatement.Init.As <Expression>()));
                }
            }

            JsValue v = Undefined.Instance;

            while (true)
            {
                if (forStatement.Test != null)
                {
                    var testExprRef = _engine.EvaluateExpression(forStatement.Test);
                    if (!TypeConverter.ToBoolean(_engine.GetValue(testExprRef)))
                    {
                        return(new Completion(Completion.Normal, v, null));
                    }
                }

                var stmt = ExecuteStatement(forStatement.Body);
                if (stmt.Value != null)
                {
                    v = stmt.Value;
                }
                if (stmt.Type == Completion.Break && (stmt.Identifier == null || stmt.Identifier == forStatement.LabelSet))
                {
                    return(new Completion(Completion.Normal, v, null));
                }
                if (stmt.Type != Completion.Continue || ((stmt.Identifier != null) && stmt.Identifier != forStatement.LabelSet))
                {
                    if (stmt.Type != Completion.Normal)
                    {
                        return(stmt);
                    }
                }
                if (forStatement.Update != null)
                {
                    var incExprRef = _engine.EvaluateExpression(forStatement.Update);
                    _engine.GetValue(incExprRef);
                }
            }
        }
Example #5
0
        public JsValue EvaluateConditionalExpression(ConditionalExpression conditionalExpression)
        {
            var lref = _engine.EvaluateExpression(conditionalExpression.Test);

            if (TypeConverter.ToBoolean(_engine.GetValue(lref)))
            {
                var trueRef = _engine.EvaluateExpression(conditionalExpression.Consequent);
                return(_engine.GetValue(trueRef));
            }
            else
            {
                var falseRef = _engine.EvaluateExpression(conditionalExpression.Alternate);
                return(_engine.GetValue(falseRef));
            }
        }
Example #6
0
        public static bool SameValue(JsValue x, JsValue y)
        {
            var typea = TypeConverter.GetPrimitiveType(x);
            var typeb = TypeConverter.GetPrimitiveType(y);

            if (typea != typeb)
            {
                return(false);
            }

            if (typea == Types.None)
            {
                return(true);
            }
            if (typea == Types.Number)
            {
                var nx = TypeConverter.ToNumber(x);
                var ny = TypeConverter.ToNumber(y);

                if (double.IsNaN(nx) && double.IsNaN(ny))
                {
                    return(true);
                }

                if (nx.Equals(ny))
                {
                    if (nx.Equals(0))
                    {
                        // +0 !== -0
                        return(NumberInstance.IsNegativeZero(nx) == NumberInstance.IsNegativeZero(ny));
                    }

                    return(true);
                }

                return(false);
            }
            if (typea == Types.String)
            {
                return(TypeConverter.ToString(x) == TypeConverter.ToString(y));
            }
            if (typea == Types.Boolean)
            {
                return(TypeConverter.ToBoolean(x) == TypeConverter.ToBoolean(y));
            }
            return(x == y);
        }
Example #7
0
        public Completion ExecuteIfStatement(IfStatement ifStatement)
        {
            var        exprRef = _engine.EvaluateExpression(ifStatement.Test);
            Completion result;

            if (TypeConverter.ToBoolean(_engine.GetValue(exprRef)))
            {
                result = ExecuteStatement(ifStatement.Consequent);
            }
            else if (ifStatement.Alternate != null)
            {
                result = ExecuteStatement(ifStatement.Alternate);
            }
            else
            {
                return(new Completion(Completion.Normal, null, null));
            }

            return(result);
        }
Example #8
0
        public JsValue EvaluateUnaryExpression(UnaryExpression unaryExpression)
        {
            var       value = _engine.EvaluateExpression(unaryExpression.Argument);
            Reference r;

            switch (unaryExpression.Operator)
            {
            case UnaryOperator.Plus:
                return(TypeConverter.ToNumber(_engine.GetValue(value)));

            case UnaryOperator.Minus:
                var n = TypeConverter.ToNumber(_engine.GetValue(value));
                return(double.IsNaN(n) ? double.NaN : n *-1);

            case UnaryOperator.BitwiseNot:
                return(~TypeConverter.ToInt32(_engine.GetValue(value)));

            case UnaryOperator.LogicalNot:
                return(!TypeConverter.ToBoolean(_engine.GetValue(value)));

            case UnaryOperator.Delete:
                r = value as Reference;
                if (r == null)
                {
                    return(true);
                }
                if (r.IsUnresolvableReference())
                {
                    if (r.IsStrict())
                    {
                        throw new JavaScriptException(_engine.SyntaxError);
                    }

                    return(true);
                }
                if (r.IsPropertyReference())
                {
                    var o = TypeConverter.ToObject(_engine, r.GetBase());
                    return(o.Delete(r.GetReferencedName(), r.IsStrict()));
                }
                if (r.IsStrict())
                {
                    throw new JavaScriptException(_engine.SyntaxError);
                }
                var bindings = r.GetBase().TryCast <EnvironmentRecord>();
                return(bindings.DeleteBinding(r.GetReferencedName()));

            case UnaryOperator.Void:
                _engine.GetValue(value);
                return(Undefined.Instance);

            case UnaryOperator.TypeOf:
                r = value as Reference;
                if (r != null)
                {
                    if (r.IsUnresolvableReference())
                    {
                        return("undefined");
                    }
                }
                var v = _engine.GetValue(value);
                if (v == Undefined.Instance)
                {
                    return("undefined");
                }
                if (v == Null.Instance)
                {
                    return("object");
                }
                switch (v.Type)
                {
                case Types.Boolean: return("boolean");

                case Types.Number: return("number");

                case Types.String: return("string");
                }
                if (v.TryCast <ICallable>() != null)
                {
                    return("function");
                }
                return("object");

            default:
                throw new ArgumentException();
            }
        }