/// <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; } }
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)); }
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)); }
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)); }
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)); }
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)); }
protected PExpr ReentrantSetResult(RuntimeObj result) { Debug.Assert(result != null); if (Result != null) { Debug.Assert(Result == result); return(new PExpr(result)); } return(SetResult(result)); }
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())); }
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))); }
/// <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; }
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)); }
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; }
public PExpr(RuntimeObj resultOrSignal) : this(null, resultOrSignal, DeferredKind.None) { }
AccessorMemberFrameLookup(EvalVisitor visitor, RuntimeObj o, AccessorMemberFrame f) : base(visitor, f.Expr) { _o = o; _f = f; }
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; }
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)); }
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; }
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() ); }
public PExpr( RuntimeObj resultOrSignal ) : this(null, resultOrSignal, DeferredKind.None) { }
PExpr(EvalVisitor.Frame pending, RuntimeObj resultOrSignal, PExprKind status) { Frame = pending; Result = resultOrSignal; PendingStatus = status; }
public RuntimeFlowBreaking(FlowBreakingExpr e, RuntimeObj value = null) : base(e) { Value = value; }