public static Instruction Create(Type type) { // Boxed enums can be unboxed as their underlying types: switch ((type.IsEnum() ? Enum.GetUnderlyingType(type) : type).GetTypeCode()) { case TypeCode.Boolean: return _Boolean ?? (_Boolean = new NotEqualBoolean()); case TypeCode.SByte: return _SByte ?? (_SByte = new NotEqualSByte()); case TypeCode.Byte: return _Byte ?? (_Byte = new NotEqualByte()); case TypeCode.Char: return _Char ?? (_Char = new NotEqualChar()); case TypeCode.Int16: return _Int16 ?? (_Int16 = new NotEqualInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new NotEqualInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new NotEqualInt64()); case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new NotEqualInt16()); case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new NotEqualInt32()); case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new NotEqualInt64()); case TypeCode.Single: return _Single ?? (_Single = new NotEqualSingle()); case TypeCode.Double: return _Double ?? (_Double = new NotEqualDouble()); case TypeCode.Object: if (!type.IsValueType()) { return _Reference ?? (_Reference = new NotEqualReference()); } // TODO: Nullable<T> throw new NotImplementedException(); default: throw new NotImplementedException(); } }
internal InstructionArray(int maxStackDepth, int maxContinuationDepth, Instruction[] instructions, object[] objects, RuntimeLabel[] labels, List<KeyValuePair<int, object>> debugCookies) { MaxStackDepth = maxStackDepth; MaxContinuationDepth = maxContinuationDepth; Instructions = instructions; DebugCookies = debugCookies; Objects = objects; Labels = labels; }
public static Instruction Create(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.Int16: return _Int16 ?? (_Int16 = new DivInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new DivInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new DivInt64()); case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new DivUInt16()); case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new DivUInt32()); case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new DivUInt64()); case TypeCode.Single: return _Single ?? (_Single = new DivSingle()); case TypeCode.Double: return _Double ?? (_Double = new DivDouble()); default: throw Assert.Unreachable; } }
public static Instruction Create(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.SByte: return _SByte ?? (_SByte = new LessThanSByte()); case TypeCode.Byte: return _Byte ?? (_Byte = new LessThanByte()); case TypeCode.Char: return _Char ?? (_Char = new LessThanChar()); case TypeCode.Int16: return _Int16 ?? (_Int16 = new LessThanInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new LessThanInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new LessThanInt64()); case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new LessThanUInt16()); case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new LessThanUInt32()); case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new LessThanUInt64()); case TypeCode.Single: return _Single ?? (_Single = new LessThanSingle()); case TypeCode.Double: return _Double ?? (_Double = new LessThanDouble()); default: throw Assert.Unreachable; } }
internal Interpreter(LambdaExpression lambda, bool[] localIsBoxed, int maxStackDepth, Instruction[] instructions, ExceptionHandler[] handlers) { this._lambda = lambda; this._numberOfLocals = localIsBoxed.Length; if (AnyBoxedLocals(localIsBoxed)) { _localIsBoxed = localIsBoxed; } else { _localIsBoxed = null; } this._maxStackDepth = maxStackDepth; this._instructions = instructions; this._handlers = handlers; _onlyFaultHandlers = true; foreach (var handler in handlers) { if (!handler.IsFault) { _onlyFaultHandlers = false; break; } } }
internal Interpreter(LambdaExpression lambda, bool[] localIsBoxed, int maxStackDepth, Instruction[] instructions, ExceptionHandler[] handlers, DebugInfo[] debugInfos) { _lambda = lambda; _numberOfLocals = localIsBoxed.Length; if (Array.IndexOf(localIsBoxed, true) != -1) { _localIsBoxed = localIsBoxed; } else { _localIsBoxed = null; } _maxStackDepth = maxStackDepth; _instructions = instructions; _handlers = handlers; _debugInfos = debugInfos; _onlyFaultHandlers = true; foreach (var handler in handlers) { if (!handler.IsFinallyOrFault) { _onlyFaultHandlers = false; break; } } }
public static Instruction CreateLifted(Type type) { // Boxed enums can be unboxed as their underlying types: switch ((type.IsEnum() ? Enum.GetUnderlyingType(type) : type).GetTypeCode()) { case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new EqualBoolean() { LiftedToNull = true }); case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new EqualSByte() { LiftedToNull = true }); case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new EqualByte() { LiftedToNull = true }); case TypeCode.Char: return _CharLifted ?? (_CharLifted = new EqualChar() { LiftedToNull = true }); case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new EqualInt16() { LiftedToNull = true }); case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new EqualInt32() { LiftedToNull = true }); case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new EqualInt64() { LiftedToNull = true }); case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new EqualInt16() { LiftedToNull = true }); case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new EqualInt32() { LiftedToNull = true }); case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new EqualInt64() { LiftedToNull = true }); case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new EqualSingle() { LiftedToNull = true }); case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new EqualDouble() { LiftedToNull = true }); default: throw Assert.Unreachable; } }
internal InstructionArray(Instruction[] instructions, object[] objects, List<KeyValuePair<int, object>> debugCookies) { Instructions = instructions; DebugCookies = debugCookies; Objects = objects; }
public void AddInstruction(Instruction instruction) { //Debug.Assert(_currentStackDepth >= 0); // checks that the stack is valid if (_currentStackDepth == -1) { return; // this code is unreachable } _instructions.Add(instruction); _currentStackDepth -= instruction.ConsumedStack; Debug.Assert(_currentStackDepth >= 0); // checks that there's enough room to pop _currentStackDepth += instruction.ProducedStack; if (_currentStackDepth > _maxStackDepth) _maxStackDepth = _currentStackDepth; }
private void UpdateStackDepth(Instruction instruction) { Debug.Assert(instruction.ConsumedStack >= 0 && instruction.ProducedStack >= 0 && instruction.ConsumedContinuations >= 0 && instruction.ProducedContinuations >= 0); _currentStackDepth -= instruction.ConsumedStack; Debug.Assert(_currentStackDepth >= 0); _currentStackDepth += instruction.ProducedStack; if (_currentStackDepth > _maxStackDepth) { _maxStackDepth = _currentStackDepth; } _currentContinuationsDepth -= instruction.ConsumedContinuations; Debug.Assert(_currentContinuationsDepth >= 0); _currentContinuationsDepth += instruction.ProducedContinuations; if (_currentContinuationsDepth > _maxContinuationDepth) { _maxContinuationDepth = _currentContinuationsDepth; } }
public void Emit(Instruction instruction) { _instructions.Add(instruction); UpdateStackDepth(instruction); }
public InstructionView(Instruction instruction, string name, int index, int stackDepth, int continuationsDepth) { _instruction = instruction; _name = name; _index = index; _stackDepth = stackDepth; _continuationsDepth = continuationsDepth; }
public static Instruction CreateLifted(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new AndInt16Lifted()); case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new AndInt32Lifted()); case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new AndInt64Lifted()); case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new AndUInt16Lifted()); case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new AndUInt32Lifted()); case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new AndUInt64Lifted()); case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new AndBooleanLifted()); default: throw Assert.Unreachable; } }
public static Instruction Create(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.Int16: return _Int16 ?? (_Int16 = new AndInt16()); case TypeCode.Int32: return _Int32 ?? (_Int32 = new AndInt32()); case TypeCode.Int64: return _Int64 ?? (_Int64 = new AndInt64()); case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new AndUInt16()); case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new AndUInt32()); case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new AndUInt64()); case TypeCode.Boolean: return _Boolean ?? (_Boolean = new AndBoolean()); default: throw Assert.Unreachable; } }
public static Instruction CreateLifted(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NegateOvfInt16Lifted()); case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NegateOvfInt32Lifted()); case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NegateOvfInt64Lifted()); case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NegateOvfUInt16Lifted()); case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NegateOvfUInt32Lifted()); case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new NegateOvfSingleLifted()); case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new NegateOvfDoubleLifted()); default: throw Assert.Unreachable; } }
public void EmitLoad(bool value) { if ((bool)value) { Emit(_true ?? (_true = new LoadObjectInstruction(value))); } else { Emit(_false ?? (_false = new LoadObjectInstruction(value))); } }
private static void RunInstructions(Instruction[] instructions, StackFrame frame) { int index = frame.InstructionIndex; while (index < instructions.Length) { index += instructions[index].Run(frame); frame.InstructionIndex = index; } }
public void EmitLoad(object value, Type type) { if (value == null) { Emit(_null ?? (_null = new LoadObjectInstruction(null))); return; } if (type == null || type.IsValueType) { if (value is bool) { EmitLoad((bool)value); return; } if (value is int) { int i = (int)value; if (i >= PushIntMinCachedValue && i <= PushIntMaxCachedValue) { if (_ints == null) { _ints = new Instruction[PushIntMaxCachedValue - PushIntMinCachedValue + 1]; } i -= PushIntMinCachedValue; Emit(_ints[i] ?? (_ints[i] = new LoadObjectInstruction(value))); return; } } } if (_objects == null) { _objects = new List<object>(); if (_loadObjectCached == null) { _loadObjectCached = new Instruction[CachedObjectCount]; } } if (_objects.Count < _loadObjectCached.Length) { uint index = (uint)_objects.Count; _objects.Add(value); Emit(_loadObjectCached[index] ?? (_loadObjectCached[index] = new LoadCachedObjectInstruction(index))); } else { Emit(new LoadObjectInstruction(value)); } }
public static Instruction CreateLifted(Type type) { Debug.Assert(!type.IsEnum()); switch (type.GetTypeCode()) { case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new LessThanSByte() { LiftedToNull = true }); case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new LessThanByte() { LiftedToNull = true }); case TypeCode.Char: return _CharLifted ?? (_CharLifted = new LessThanChar() { LiftedToNull = true }); case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new LessThanInt16() { LiftedToNull = true }); case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new LessThanInt32() { LiftedToNull = true }); case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new LessThanInt64() { LiftedToNull = true }); case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new LessThanUInt16() { LiftedToNull = true }); case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new LessThanUInt32() { LiftedToNull = true }); case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new LessThanUInt64() { LiftedToNull = true }); case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new LessThanSingle() { LiftedToNull = true }); case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new LessThanDouble() { LiftedToNull = true }); default: throw Assert.Unreachable; } }
public void Emit(Instruction instruction) { _instructions.Add(instruction); UpdateStackDepth(instruction.ConsumedStack, instruction.ProducedStack); }