/// <summary>
            /// Updates the status based on the current <see cref="PExpr"/>.
            /// </summary>
            /// <param name="r">The current <see cref="PExpr"/>.</param>
            internal protected virtual void UpdateStatus(PExpr r)
            {
                _error  = (_result = r.Result) as RuntimeError;
                _status = ScriptEngineStatus.None;
                if (r.AsErrorResult != null)
                {
                    _status |= ScriptEngineStatus.IsError;
                }
                if (r.IsPending)
                {
                    Debug.Assert(r.DeferredStatus != PExpr.DeferredKind.None);
                    switch (r.DeferredStatus)
                    {
                    case PExpr.DeferredKind.Timeout: _status |= ScriptEngineStatus.Timeout; break;

                    case PExpr.DeferredKind.Breakpoint: _status |= ScriptEngineStatus.Breakpoint; break;

                    case PExpr.DeferredKind.AsyncCall: _status |= ScriptEngineStatus.AsyncCall; break;

                    case PExpr.DeferredKind.FirstChanceError: _status |= ScriptEngineStatus.FirstChanceError; break;

                    default: Debug.Fail("UpdateStatus"); break;
                    }
                }
                else
                {
                    _status |= ScriptEngineStatus.IsFinished;
                }
            }
Exemple #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));
            }
Exemple #3
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));
            }
Exemple #4
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));
            }
Exemple #5
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));
            }
Exemple #6
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));
            }
 public RuntimeObjComparer(RuntimeObj x, RuntimeObj y)
 {
     if (x == RuntimeObj.Null)
     {
         x = RuntimeObj.Undefined;
     }
     else
     {
         x = x.ToValue();
     }
     if (y == RuntimeObj.Null)
     {
         y = RuntimeObj.Undefined;
     }
     else
     {
         y = y.ToValue();
     }
     if ((Swapped = string.CompareOrdinal(x.Type, y.Type) > 0))
     {
         X = y;
         Y = x;
     }
     else
     {
         X = x;
         Y = y;
     }
 }
 /// <summary>
 /// Initializes a new runtime error.
 /// </summary>
 /// <param name="culprit">The expression. Can not be null.</param>
 /// <param name="thrownValue">The error value. Can not be null.</param>
 public RuntimeError( Expr culprit, RuntimeObj thrownValue )
     : base(culprit)
 {
     if( thrownValue == null ) throw new ArgumentNullException();
     if( thrownValue is RefRuntimeObj ) throw new ArgumentException();
     Message = "Runtime error.";
     ThrownValue = thrownValue;
 }
 public WithObjectScope(GlobalContext ctx, RuntimeObj o)
 {
     Debug.Assert(ctx != null && o != null);
     Object = o;
     Parent = ctx.InternalWithObjectScope;
     ctx.InternalWithObjectScope = this;
     _ctx = ctx;
 }
            public override PExpr SetResult(RuntimeObj result)
            {
                IAccessorFrame p = PrevAccessor;

                if (p != null && !p.IsResolved)
                {
                    p.SetResult(result);
                }
                return(base.SetResult(result));
            }
Exemple #11
0
 protected PExpr ReentrantSetResult(RuntimeObj result)
 {
     Debug.Assert(result != null);
     if (Result != null)
     {
         Debug.Assert(Result == result);
         return(new PExpr(result));
     }
     return(SetResult(result));
 }
Exemple #12
0
            public override PExpr SetResult(RuntimeObj result)
            {
                // NextFrame is actually the PreviousAccessor
                IAccessorFrame p = NextFrame as IAccessorFrame;

                if (p != null && !p.IsResolved)
                {
                    p.SetResult(result);
                }
                return(base.SetResult(result));
            }
 /// <summary>
 /// Resets the current execution. This frees the <see cref="ScriptEngine"/>: new calls to its <see cref="G:ScriptEngine.Execute"/> can be made.
 /// </summary>
 public void Dispose()
 {
     if (_visitor != null)
     {
         _engine.StopExecution();
         _error   = null;
         _result  = null;
         _status  = ScriptEngineStatus.None;
         _visitor = null;
     }
 }
 public RuntimeObj CreateString(RuntimeObj o)
 {
     if (o == null)
     {
         return(RuntimeObj.Null);
     }
     if (o is JSEvalString)
     {
         return(o);
     }
     return(CreateString(o.ToString()));
 }
 public RuntimeObj CreateBoolean(RuntimeObj o)
 {
     if (o == null)
     {
         return(JSEvalBoolean.False);
     }
     if (o is JSEvalBoolean)
     {
         return(o);
     }
     return(CreateBoolean(o.ToBoolean()));
 }
 public RuntimeObj CreateNumber(RuntimeObj o)
 {
     if (o == null)
     {
         return(JSEvalNumber.Zero);
     }
     if (o is JSEvalNumber)
     {
         return(o);
     }
     return(CreateNumber(o.ToDouble()));
 }
Exemple #17
0
            public virtual PExpr SetResult(RuntimeObj result)
            {
                Debug.Assert(_result == null);
                RuntimeError e = result as RuntimeError;

                if (e != null && !(e.Expr is SyntaxErrorExpr) && Visitor.EnableFirstChanceError)
                {
                    Visitor.FirstChanceError = e;
                    return(new PExpr(this, PExprKind.FirstChanceError));
                }
                return(new PExpr((_result = result)));
            }
Exemple #18
0
 /// <summary>
 /// Sets the referenced value.
 /// </summary>
 /// <param name="e">The expression that sets the value.</param>
 /// <param name="value">New value to set.</param>
 /// <returns>The value or an error.</returns>
 public virtual RuntimeObj SetValue(Expr e, RuntimeObj value)
 {
     if (value == null)
     {
         _value = RuntimeObj.Null;
     }
     else
     {
         var r = value as RefRuntimeObj;
         _value = r != null ? r.Value : value;
     }
     return(_value);
 }
 /// <summary>
 /// Initializes a new runtime error.
 /// </summary>
 /// <param name="culprit">The expression. Can not be null.</param>
 /// <param name="thrownValue">The error value. Can not be null.</param>
 public RuntimeError(Expr culprit, RuntimeObj thrownValue)
     : base(culprit)
 {
     if (thrownValue == null)
     {
         throw new ArgumentNullException();
     }
     if (thrownValue is RefRuntimeObj)
     {
         throw new ArgumentException();
     }
     Message     = "Runtime error.";
     ThrownValue = thrownValue;
 }
Exemple #20
0
 public override RuntimeObj SetValue(Expr e, RuntimeObj value)
 {
     Debug.Assert(_handler.PropertySetter != null);
     try
     {
         object v = Convert.ChangeType(value.ToNative(_eo._context), _handler.PropertyOrFieldType);
         _handler.PropertySetter(_eo._o, null, v);
     }
     catch (Exception ex)
     {
         return(new RuntimeError(e, ex.Message));
     }
     return(base.SetValue(e, value));
 }
Exemple #21
0
 internal PExpr Read(IAccessorFrame frame)
 {
     try
     {
         object[]   index = null;
         object     val   = _handler.PropertyGetter(_eo._o, index);
         RuntimeObj obj   = val == _eo ? _eo : frame.Global.Create(val);
         if (_handler.PropertySetter != null)
         {
             base.SetValue(frame.Expr, obj);
             return(frame.SetResult(this));
         }
         return(frame.SetResult(obj));
     }
     catch (Exception ex)
     {
         return(frame.SetError(ex.Message));
     }
 }
 public RefRuntimeObj()
 {
     _value = Undefined;
 }
Exemple #23
0
 public PExpr(RuntimeObj resultOrSignal)
     : this(null, resultOrSignal, DeferredKind.None)
 {
 }
Exemple #24
0
 AccessorMemberFrameLookup(EvalVisitor visitor, RuntimeObj o, AccessorMemberFrame f)
     : base(visitor, f.Expr)
 {
     _o = o;
     _f = f;
 }
Exemple #25
0
 PExpr IAccessorFrame.SetResult(RuntimeObj result)
 {
     return(Frame.SetResult(result));
 }
 /// <summary>
 /// Resets the current execution. This frees the <see cref="ScriptEngine"/>: new calls to its <see cref="G:ScriptEngine.Execute"/> can be made. 
 /// </summary>
 public void Dispose()
 {
     if( _visitor != null )
     {
         _engine.StopExecution();
         _error = null;
         _result = null;
         _status = ScriptEngineStatus.None;
         _visitor = null;
     }
 }
 public RuntimeFlowBreaking( FlowBreakingExpr e, RuntimeObj value = null )
     : base(e)
 {
     Value = value;
 }
Exemple #28
0
 PExpr(EvalVisitor.Frame pending, RuntimeObj resultOrSignal, DeferredKind status)
 {
     Frame          = pending;
     Result         = resultOrSignal;
     DeferredStatus = status;
 }
 public RuntimeObj CreateBoolean( RuntimeObj o )
 {
     if( o == null ) return JSEvalBoolean.False;
     if( o is JSEvalBoolean ) return o;
     return CreateBoolean( o.ToBoolean() );
 }
 public RuntimeObj CreateString( RuntimeObj o )
 {
     if( o == null ) return RuntimeObj.Null;
     if( o is JSEvalString ) return o;
     return CreateString( o.ToString() );
 }
 public virtual PExpr SetResult( RuntimeObj result )
 {
     Debug.Assert( _result == null );
     RuntimeError e = result as RuntimeError;
     if( e != null && !(e.Expr is SyntaxErrorExpr) && _visitor.EnableFirstChanceError )
     {
         _visitor.FirstChanceError = e;
         return new PExpr( this, PExpr.DeferredKind.FirstChanceError );
     }
     return new PExpr( (_result = result) );
 }
 public override PExpr SetResult(RuntimeObj result)
 {
     Debug.Assert(PrevFrame is IAccessorFrame);
     PrevFrame.SetResult(result);
     return(base.SetResult(result));
 }
 /// <summary>
 /// Opens a scope on a object.
 /// </summary>
 /// <param name="o">The scope object.</param>
 /// <returns></returns>
 public IWithObjectScope OpenWithScope(RuntimeObj o)
 {
     return(new WithObjectScope(this, o));
 }
Exemple #34
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));
            }
 /// <summary>
 /// Updates the status based on the current <see cref="PExpr"/>.
 /// </summary>
 /// <param name="r">The current <see cref="PExpr"/>.</param>
 protected internal virtual void UpdateStatus( PExpr r )
 {
     _error = (_result = r.Result) as RuntimeError;
     _status = ScriptEngineStatus.None;
     if( r.AsErrorResult != null ) _status |= ScriptEngineStatus.IsError;
     if( r.IsPending )
     {
         Debug.Assert( r.DeferredStatus != PExpr.DeferredKind.None );
         switch( r.DeferredStatus )
         {
             case PExpr.DeferredKind.Timeout: _status |= ScriptEngineStatus.Timeout; break;
             case PExpr.DeferredKind.Breakpoint: _status |= ScriptEngineStatus.Breakpoint; break;
             case PExpr.DeferredKind.AsyncCall: _status |= ScriptEngineStatus.AsyncCall; break;
             case PExpr.DeferredKind.FirstChanceError: _status |= ScriptEngineStatus.FirstChanceError; break;
             default: Debug.Fail( "UpdateStatus" ); break;
         }
     }
     else _status |= ScriptEngineStatus.IsFinished;
 }
Exemple #36
0
 PExpr( EvalVisitor.Frame pending, RuntimeObj resultOrSignal, DeferredKind status )
 {
     Frame = pending;
     Result = resultOrSignal;
     DeferredStatus = status;
 }
 public RuntimeObj CreateNumber( RuntimeObj o )
 {
     if( o == null ) return JSEvalNumber.Zero;
     if( o is JSEvalNumber ) return o;
     return CreateNumber( o.ToDouble() );
 }
Exemple #38
0
 public PExpr( RuntimeObj resultOrSignal )
     : this(null, resultOrSignal, DeferredKind.None)
 {
 }
Exemple #39
0
 PExpr(EvalVisitor.Frame pending, RuntimeObj resultOrSignal, PExprKind status)
 {
     Frame         = pending;
     Result        = resultOrSignal;
     PendingStatus = status;
 }
Exemple #40
0
 public RuntimeFlowBreaking(FlowBreakingExpr e, RuntimeObj value = null)
     : base(e)
 {
     Value = value;
 }
Exemple #41
0
 public RefRuntimeObj()
 {
     _value = Undefined;
 }