Esempio n. 1
0
            RuntimeObj BitwiseShiftRightUnsigned(RuntimeObj left, RuntimeObj right)
            {
                if (left == DoubleObj.Zero)
                {
                    return(left);
                }

                double dR = right.ToDouble();

                if (double.IsNaN(dR))
                {
                    return(left is DoubleObj ? left : DoubleObj.Create(left.ToDouble()));
                }
                int iShift = (dR < 0 ? (int)Math.Ceiling(dR) : (int)Math.Floor(dR)) % 64;

                if (iShift < 0)
                {
                    return(DoubleObj.Zero);
                }

                uint lN = (uint)JSSupport.ToInt64(left.ToDouble());

                if (lN == 0)
                {
                    return(DoubleObj.Zero);
                }

                return(DoubleObj.Create(lN >> iShift));
            }
Esempio n. 2
0
            RuntimeObj BitwiseShift(RuntimeObj val, RuntimeObj shift, bool right)
            {
                if (val == DoubleObj.Zero)
                {
                    return(val);
                }
                double dR = shift.ToDouble();
                int    iShift;

                if (double.IsNaN(dR) || (iShift = (dR < 0 ? (int)Math.Ceiling(dR) : (int)Math.Floor(dR)) % 64) == 0)
                {
                    return(val.ToValue() as DoubleObj ?? DoubleObj.Create(val.ToDouble()));
                }
                if (right && iShift < 0)
                {
                    return(DoubleObj.Zero);
                }
                int lN = JSSupport.ToInt32(val.ToDouble());

                if (lN == 0)
                {
                    return(DoubleObj.Zero);
                }
                return(DoubleObj.Create(right ? lN >> iShift : lN << iShift));
            }
Esempio n. 3
0
            protected override PExpr DoVisit()
            {
                if (IsPendingOrSignal(ref _expression, Expr.Expression))
                {
                    return(PendingOrSignal(_expression));
                }

                RuntimeObj result = _expression.Result;

                // Minus and Plus are classified as a binary operator.
                // Handle those special cases here.
                if (Expr.TokenType == JSTokenizerToken.Minus)
                {
                    result = Global.CreateNumber(-result.ToDouble());
                }
                else if (Expr.TokenType == JSTokenizerToken.Plus)
                {
                    result = Global.CreateNumber(result.ToDouble());
                }
                else
                {
                    switch ((int)Expr.TokenType & 15)
                    {
                    case (int)JSTokenizerToken.Not & 15:
                    {
                        result = Global.CreateBoolean(!result.ToBoolean());
                        break;
                    }

                    case (int)JSTokenizerToken.BitwiseNot & 15:
                    {
                        result = Global.CreateNumber(~JSSupport.ToInt64(result.ToDouble()));
                        break;
                    }

                    case (int)JSTokenizerToken.TypeOf & 15:
                    {
                        // Well known Javascript bug: typeof null === "object".
                        if (result == RuntimeObj.Null)
                        {
                            result = Global.CreateString(RuntimeObj.TypeObject);
                        }
                        else
                        {
                            result = Global.CreateString(result.Type);
                        }
                        break;
                    }

                    case (int)JSTokenizerToken.Void & 15:
                    {
                        result = RuntimeObj.Undefined;
                        break;
                    }

                    default: throw UnsupportedOperatorException();
                    }
                }
                return(SetResult(result));
            }
Esempio n. 4
0
            RuntimeObj BitwiseShiftRightUnsigned(RuntimeObj left, RuntimeObj right)
            {
                if (left == JSEvalNumber.Zero)
                {
                    return(left);
                }

                double dR = right.ToDouble();

                if (Double.IsNaN(dR))
                {
                    return(Global.CreateNumber(left));
                }
                int iShift = (dR < 0 ? (int)Math.Ceiling(dR) : (int)Math.Floor(dR)) % 64;

                if (iShift < 0)
                {
                    return(JSEvalNumber.Zero);
                }

                UInt32 lN = (UInt32)JSSupport.ToInt64(left.ToDouble());

                if (lN == 0)
                {
                    return(JSEvalNumber.Zero);
                }

                return(Global.CreateNumber(lN >> iShift));
            }
Esempio n. 5
0
            RuntimeObj BitwiseShift(RuntimeObj val, RuntimeObj shift, bool right)
            {
                if (val == JSEvalNumber.Zero)
                {
                    return(val);
                }
                double dR = shift.ToDouble();
                int    iShift;

                if (Double.IsNaN(dR) || (iShift = (dR < 0 ? (int)Math.Ceiling(dR) : (int)Math.Floor(dR)) % 64) == 0)
                {
                    return(Global.CreateNumber(val));
                }
                if (right && iShift < 0)
                {
                    return(JSEvalNumber.Zero);
                }
                Int32 lN = JSSupport.ToInt32(val.ToDouble());

                if (lN == 0)
                {
                    return(JSEvalNumber.Zero);
                }
                return(Global.CreateNumber(right ? lN >> iShift : lN << iShift));
            }
        public bool Compare(GlobalContext c, out int result)
        {
            result = 0;
            if (Y == RuntimeObj.Undefined)
            {
                return(X == RuntimeObj.Undefined);
            }

            Debug.Assert(typeof(IComparable).IsAssignableFrom(typeof(StringObj)), "StringObj is Comparable.");

            IComparable cmp;

            if (X.GetType() == Y.GetType() && (cmp = X as IComparable) != null)
            {
                result = cmp.CompareTo(Y);
            }
            else if (X.Type == RuntimeObj.TypeNumber || Y.Type == RuntimeObj.TypeNumber)
            {
                Double xD = X.ToDouble();
                Double yD = Y.ToDouble();
                if (Double.IsNaN(xD) || Double.IsNaN(yD))
                {
                    return(false);
                }
                if (xD < yD)
                {
                    result = -1;
                }
                else if (xD > yD)
                {
                    result = 1;
                }
            }
            else
            {
                return(false);
            }
            if (Swapped)
            {
                result = -result;
            }
            return(true);
        }
 public bool AreEqual(GlobalContext c)
 {
     if (ReferenceEquals(X, Y))
     {
         return(X != JSEvalNumber.NaN);
     }
     if (ReferenceEquals(X.Type, Y.Type))
     {
         Debug.Assert(X != RuntimeObj.Undefined && X != RuntimeObj.Null, "This has been handled by the normalization and the above reference test.");
         if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber))
         {
             Debug.Assert(!(((JSEvalNumber)X).IsNaN && ((JSEvalNumber)Y).IsNaN));
             return(X.ToDouble() == Y.ToDouble());
         }
         else if (ReferenceEquals(X.Type, RuntimeObj.TypeString))
         {
             return(X.ToString() == Y.ToString());
         }
         else if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean))
         {
             return(X.ToBoolean() == Y.ToBoolean());
         }
         else
         {
             IComparable cmp;
             if (X.GetType() == Y.GetType() && (cmp = X as IComparable) != null)
             {
                 Debug.Assert((cmp.CompareTo(Y) == 0) == X.Equals(Y), "When IComparable is implemented, it must match Equals behavior.");
                 return(cmp.Equals(Y));
             }
         }
         return(false);
     }
     if (ReferenceEquals(X.Type, RuntimeObj.TypeNumber) && ReferenceEquals(Y.Type, RuntimeObj.TypeString))
     {
         return(X.ToDouble() == Y.ToDouble());
     }
     if (ReferenceEquals(X.Type, RuntimeObj.TypeBoolean) || ReferenceEquals(Y.Type, RuntimeObj.TypeBoolean))
     {
         return(X.ToBoolean() == Y.ToBoolean());
     }
     return(false);
 }
Esempio n. 8
0
 public RuntimeObj CreateNumber(RuntimeObj o)
 {
     if (o == null)
     {
         return(JSEvalNumber.Zero);
     }
     if (o is JSEvalNumber)
     {
         return(o);
     }
     return(CreateNumber(o.ToDouble()));
 }
Esempio n. 9
0
            protected override PExpr DoVisit()
            {
                if (IsPendingOrSignal(ref _left, Expr.Left))
                {
                    return(PendingOrSignal(_left));
                }

                // Do not evaluate right expression if it is useless: short-circuit boolean evaluation.
                if ((Expr.BinaryOperatorToken == JSTokenizerToken.And && !_left.Result.ToBoolean()) ||
                    (Expr.BinaryOperatorToken == JSTokenizerToken.Or && _left.Result.ToBoolean()))
                {
                    return(SetResult(_left.Result));
                }

                if (IsPendingOrSignal(ref _right, Expr.Right))
                {
                    return(PendingOrSignal(_right));
                }

                RuntimeObj left  = _left.Result;
                RuntimeObj right = _right.Result;

                // Right value is the result for And and Or.
                RuntimeObj result = right;

                if (Expr.BinaryOperatorToken != JSTokenizerToken.And && Expr.BinaryOperatorToken != JSTokenizerToken.Or)
                {
                    if ((Expr.BinaryOperatorToken & JSTokenizerToken.IsCompareOperator) != 0)
                    {
                        #region ==, <, >, <=, >=, !=, === and !==
                        int compareValue;
                        switch ((int)Expr.BinaryOperatorToken & 15)
                        {
                        case (int)JSTokenizerToken.StrictEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).AreEqualStrict(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.StrictDifferent & 15:
                        {
                            result = Global.CreateBoolean(!new RuntimeObjComparer(left, right).AreEqualStrict(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.Greater & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue > 0);
                            break;
                        }

                        case (int)JSTokenizerToken.GreaterOrEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue >= 0);
                            break;
                        }

                        case (int)JSTokenizerToken.Less & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue < 0);
                            break;
                        }

                        case (int)JSTokenizerToken.LessOrEqual & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).Compare(Global, out compareValue) && compareValue <= 0);
                            break;
                        }

                        case (int)JSTokenizerToken.Equal & 15:
                        {
                            result = Global.CreateBoolean(new RuntimeObjComparer(left, right).AreEqual(Global));
                            break;
                        }

                        case (int)JSTokenizerToken.Different & 15:
                        {
                            result = Global.CreateBoolean(!new RuntimeObjComparer(left, right).AreEqual(Global));
                            break;
                        }

                        default: throw UnsupportedOperatorException();
                        }
                        #endregion
                    }
                    else if ((Expr.BinaryOperatorToken & JSTokenizerToken.IsBinaryOperator) != 0)
                    {
                        #region |, ^, &, >>, <<, >>>, +, -, /, * and %.
                        switch ((int)Expr.BinaryOperatorToken & 15)
                        {
                        case (int)JSTokenizerToken.Plus & 15:
                        {
                            if (ReferenceEquals(left.Type, RuntimeObj.TypeNumber) && ReferenceEquals(right.Type, RuntimeObj.TypeNumber))
                            {
                                result = Global.CreateNumber(left.ToDouble() + right.ToDouble());
                            }
                            else
                            {
                                result = Global.CreateString(String.Concat(left.ToString(), right.ToString()));
                            }
                            break;
                        }

                        case (int)JSTokenizerToken.Minus & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() - right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Mult & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() * right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Divide & 15:
                        {
                            result = Global.CreateNumber(left.ToDouble() / right.ToDouble());
                            break;
                        }

                        case (int)JSTokenizerToken.Modulo & 15:
                        {
                            if (right == JSEvalNumber.Zero || left == JSEvalNumber.NegativeInfinity || left == JSEvalNumber.Infinity)
                            {
                                result = JSEvalNumber.NaN;
                            }
                            else if (left == JSEvalNumber.NegativeInfinity || left == JSEvalNumber.Infinity)
                            {
                                result = right;
                            }
                            else
                            {
                                result = Global.CreateNumber(left.ToDouble() % right.ToDouble());
                            }
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseAnd & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l & rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseOr & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l | rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseXOr & 15:
                        {
                            Int64 l  = JSSupport.ToInt64(left.ToDouble());
                            Int64 rO = JSSupport.ToInt64(right.ToDouble());
                            result = Global.CreateNumber(l ^ rO);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftLeft & 15:
                        {
                            result = BitwiseShift(left, right, false);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftRight & 15:
                        {
                            result = BitwiseShift(left, right, true);
                            break;
                        }

                        case (int)JSTokenizerToken.BitwiseShiftRightNoSignBit & 15:
                        {
                            result = BitwiseShiftRightUnsigned(left, right);
                            break;
                        }

                        default: throw UnsupportedOperatorException();
                        }
                        #endregion
                    }
                    else
                    {
                        throw UnsupportedOperatorException();
                    }
                }
                return(SetResult(result));
            }
Esempio n. 10
0
 public RuntimeObj CreateNumber( RuntimeObj o )
 {
     if( o == null ) return JSEvalNumber.Zero;
     if( o is JSEvalNumber ) return o;
     return CreateNumber( o.ToDouble() );
 }
Esempio n. 11
0
 public override double ToDouble() => _value.ToDouble();
Esempio n. 12
0
 public override double ToDouble()
 {
     return(_value.ToDouble());
 }
Esempio n. 13
0
            protected override PExpr DoVisit()
            {
                if (IsPendingOrSignal(ref _expression, Expr.Expression))
                {
                    RuntimeError e = _expression.AsErrorResult;
                    if (e != null &&
                        e.IsReferenceError &&
                        ((int)Expr.TokenType & 15) == ((int)TokenizerToken.TypeOf & 15))
                    {
                        return(SetResult(StringObj.Create(RuntimeObj.TypeUndefined)));
                    }
                    return(PendingOrSignal(_expression));
                }
                RuntimeObj result = _expression.Result;

                // Minus and Plus are classified as a binary operator.
                // Handle those special cases here.
                if (Expr.TokenType == TokenizerToken.Minus)
                {
                    result = DoubleObj.Create(-result.ToDouble());
                }
                else if (Expr.TokenType == TokenizerToken.Plus)
                {
                    result = DoubleObj.Create(result.ToDouble());
                }
                else
                {
                    switch ((int)Expr.TokenType & 15)
                    {
                    case (int)TokenizerToken.Not & 15:
                    {
                        result = result.ToBoolean() ? BooleanObj.False : BooleanObj.True;
                        break;
                    }

                    case (int)TokenizerToken.BitwiseNot & 15:
                    {
                        result = DoubleObj.Create(~JSSupport.ToInt64(result.ToDouble()));
                        break;
                    }

                    case (int)TokenizerToken.TypeOf & 15:
                    {
                        // Well known Javascript bug: typeof null === "object".
                        if (result == RuntimeObj.Null)
                        {
                            result = StringObj.Create(RuntimeObj.TypeObject);
                        }
                        else
                        {
                            result = StringObj.Create(result.Type);
                        }
                        break;
                    }

                    case (int)TokenizerToken.IndexOf & 15:
                    {
                        RefRuntimeIndexedObj iO = result as RefRuntimeIndexedObj;
                        if (iO == null)
                        {
                            result = new RuntimeError(Expr, "No associated index. indexof must be used on a foreach variable.");
                        }
                        else
                        {
                            result = iO.Index;
                        }
                        break;
                    }

                    case (int)TokenizerToken.Void & 15:
                    {
                        result = RuntimeObj.Undefined;
                        break;
                    }

                    default: throw UnsupportedOperatorException();
                    }
                }
                return(SetResult(result));
            }