/// <summary> /// Parse instructions and put them into an expression tree until an assignment, void call, branch target, or branch is encountered. /// Returns true if the parsed statement is last of the current basic block. This happens when the next statement is a branch /// target, or if the parsed statement could transfers control to anything but the following statement. /// </summary> private void ParseInstruction(BasicBlock currentBlock) { Statement/*?*/ statement = null; Expression/*?*/ expression = null; IOperation currentOperation = this.operationEnumerator.Current; OperationCode currentOpcode = currentOperation.OperationCode; if (this.host.PreserveILLocations) { if (this.lastLocation == null) this.lastLocation = currentOperation.Location; } else { if (this.sourceLocationProvider != null && this.lastSourceLocation == null) { foreach (var sourceLocation in this.sourceLocationProvider.GetPrimarySourceLocationsFor(currentOperation.Location)) { if (sourceLocation.StartLine != 0x00feefee) { this.lastSourceLocation = sourceLocation; break; } } } } switch (currentOpcode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.And: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Or: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Xor: expression = this.ParseBinaryOperation(currentOpcode); break; case OperationCode.Arglist: expression = new RuntimeArgumentHandleExpression(); break; case OperationCode.Array_Addr: case OperationCode.Ldelema: expression = this.ParseArrayElementAddres(currentOperation); break; case OperationCode.Array_Create: case OperationCode.Array_Create_WithLowerBound: case OperationCode.Newarr: expression = this.ParseArrayCreate(currentOperation); break; case OperationCode.Array_Get: case OperationCode.Ldelem: case OperationCode.Ldelem_I: case OperationCode.Ldelem_I1: case OperationCode.Ldelem_I2: case OperationCode.Ldelem_I4: case OperationCode.Ldelem_I8: case OperationCode.Ldelem_R4: case OperationCode.Ldelem_R8: case OperationCode.Ldelem_Ref: case OperationCode.Ldelem_U1: case OperationCode.Ldelem_U2: case OperationCode.Ldelem_U4: expression = this.ParseArrayIndexer(currentOperation); break; case OperationCode.Array_Set: statement = this.ParseArraySet(currentOperation); break; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: statement = this.ParseBinaryConditionalBranch(currentOperation); break; case OperationCode.Box: expression = this.ParseConversion(currentOperation); break; case OperationCode.Br: case OperationCode.Br_S: case OperationCode.Leave: case OperationCode.Leave_S: statement = this.ParseUnconditionalBranch(currentOperation); break; case OperationCode.Break: statement = new DebuggerBreakStatement(); break; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: statement = this.ParseUnaryConditionalBranch(currentOperation); break; case OperationCode.Call: case OperationCode.Callvirt: MethodCall call = this.ParseCall(currentOperation); if (call.MethodToCall.Type.TypeCode == PrimitiveTypeCode.Void) { call.Locations.Add(currentOperation.Location); // turning it into a statement prevents the location from being attached to the expresssion ExpressionStatement es = new ExpressionStatement(); es.Expression = call; statement = es; } else expression = call; break; case OperationCode.Calli: expression = this.ParsePointerCall(currentOperation); break; case OperationCode.Castclass: case OperationCode.Conv_I: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_R_Un: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U: case OperationCode.Conv_U1: case OperationCode.Conv_U2: case OperationCode.Conv_U4: case OperationCode.Conv_U8: case OperationCode.Unbox: case OperationCode.Unbox_Any: expression = this.ParseConversion(currentOperation); break; case OperationCode.Ckfinite: this.PopOperandStack(); Debug.Assert(false); //if code out there actually uses this, I need to know sooner rather than later. //TODO: need a code model statement for this instruction. break; case OperationCode.Constrained_: //This prefix is redundant and is not represented in the code model. break; case OperationCode.Cpblk: var copyMemory = new CopyMemoryStatement(); copyMemory.NumberOfBytesToCopy = this.PopOperandStack(); copyMemory.SourceAddress = this.PopOperandStack(); copyMemory.TargetAddress = this.PopOperandStack(); statement = copyMemory; break; case OperationCode.Cpobj: expression = this.ParseCopyObject(); break; case OperationCode.Dup: statement = this.ParseDup(); break; case OperationCode.Endfilter: statement = this.ParseEndfilter(); break; case OperationCode.Endfinally: statement = new EndFinally(); break; case OperationCode.Initblk: var fillMemory = new FillMemoryStatement(); fillMemory.NumberOfBytesToFill = this.PopOperandStack(); fillMemory.FillValue = this.PopOperandStack(); fillMemory.TargetAddress = this.PopOperandStack(); statement = fillMemory; break; case OperationCode.Initobj: statement = this.ParseInitObject(currentOperation); break; case OperationCode.Isinst: expression = this.ParseCastIfPossible(currentOperation); break; case OperationCode.Jmp: Debug.Assert(false); //if code out there actually uses this, I need to know sooner rather than later. //TODO: need a code model statement for this instruction. break; case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: case OperationCode.Ldfld: case OperationCode.Ldsfld: expression = this.ParseBoundExpression(currentOperation); break; case OperationCode.Ldarga: case OperationCode.Ldarga_S: case OperationCode.Ldflda: case OperationCode.Ldsflda: case OperationCode.Ldloca: case OperationCode.Ldloca_S: case OperationCode.Ldftn: case OperationCode.Ldvirtftn: expression = this.ParseAddressOf(currentOperation); break; case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: case OperationCode.Ldc_I8: case OperationCode.Ldc_R4: case OperationCode.Ldc_R8: case OperationCode.Ldnull: case OperationCode.Ldstr: expression = this.ParseCompileTimeConstant(currentOperation); break; case OperationCode.Ldind_I: case OperationCode.Ldind_I1: case OperationCode.Ldind_I2: case OperationCode.Ldind_I4: case OperationCode.Ldind_I8: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Ldind_U1: case OperationCode.Ldind_U2: case OperationCode.Ldind_U4: case OperationCode.Ldobj: expression = this.ParseAddressDereference(currentOperation); break; case OperationCode.Ldlen: expression = this.ParseVectorLength(); break; case OperationCode.Ldtoken: expression = ParseToken(currentOperation); break; case OperationCode.Localloc: expression = this.ParseStackArrayCreate(); break; case OperationCode.Mkrefany: expression = this.ParseMakeTypedReference(currentOperation); break; case OperationCode.Neg: expression = this.ParseUnaryOperation(new UnaryNegation()); break; case OperationCode.Not: expression = this.ParseUnaryOperation(new OnesComplement()); break; case OperationCode.Newobj: expression = this.ParseCreateObjectInstance(currentOperation); break; case OperationCode.No_: Debug.Assert(false); //if code out there actually uses this, I need to know sooner rather than later. //TODO: need object model support break; case OperationCode.Nop: statement = new EmptyStatement(); break; case OperationCode.Pop: statement = this.ParsePop(); break; case OperationCode.Readonly_: this.sawReadonly = true; break; case OperationCode.Refanytype: expression = this.ParseGetTypeOfTypedReference(); break; case OperationCode.Refanyval: expression = this.ParseGetValueOfTypedReference(currentOperation); break; case OperationCode.Ret: statement = this.ParseReturn(); break; case OperationCode.Rethrow: statement = new RethrowStatement(); break; case OperationCode.Sizeof: expression = ParseSizeOf(currentOperation); break; case OperationCode.Starg: case OperationCode.Starg_S: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: case OperationCode.Stobj: case OperationCode.Stsfld: statement = this.ParseAssignment(currentOperation); break; case OperationCode.Switch: statement = this.ParseSwitchInstruction(currentOperation); break; case OperationCode.Tail_: this.sawTailCall = true; break; case OperationCode.Throw: statement = this.ParseThrow(); break; case OperationCode.Unaligned_: this.alignment = (byte)currentOperation.Value; break; case OperationCode.Volatile_: this.sawVolatile = true; break; } if (expression != null) { if (this.host.PreserveILLocations) { expression.Locations.Add(currentOperation.Location); } this.operandStack.Push(expression); } else if (statement != null) { this.TurnOperandStackIntoPushStatements(currentBlock); currentBlock.Statements.Add(statement); if (this.host.PreserveILLocations) { if (this.lastLocation != null) { statement.Locations.Add(this.lastLocation); this.lastLocation = null; } } else if (this.lastSourceLocation != null) { statement.Locations.Add(this.lastSourceLocation); this.lastSourceLocation = null; } } }
internal EndFinally(EndFinally endFinally) : base(endFinally) { Contract.Requires(endFinally != null); }
private void ParseInstruction(Instruction instruction, List<IStatement> statements) { Contract.Requires(instruction != null); Contract.Requires(statements != null); Statement/*?*/ statement = null; Expression/*?*/ expression = null; ITypeReference/*?*/ elementType = null; IOperation currentOperation = instruction.Operation; OperationCode currentOpcode = currentOperation.OperationCode; if (this.host.PreserveILLocations) { if (this.lastLocation == null) this.lastLocation = currentOperation.Location; } else if (this.sourceLocationProvider != null) { if (this.lastSourceLocation == null) { foreach (var sourceLocation in this.sourceLocationProvider.GetPrimarySourceLocationsFor(currentOperation.Location)) { Contract.Assume(sourceLocation != null); if (sourceLocation.StartLine != 0x00feefee) { this.lastSourceLocation = sourceLocation; break; } } } } if (this.synchronizatonPointLocationFor != null) { uint currentOffset = currentOperation.Offset; var syncPointLocation = this.synchronizatonPointLocationFor[currentOffset]; if (syncPointLocation != null) { if (syncPointLocation.SynchronizationPoint.ContinuationOffset == currentOffset) this.lastContinuationLocation = new ContinuationLocation(syncPointLocation); else this.lastSynchronizationLocation = syncPointLocation; } } switch (currentOpcode) { case OperationCode.Add: case OperationCode.Add_Ovf: case OperationCode.Add_Ovf_Un: case OperationCode.And: case OperationCode.Ceq: case OperationCode.Cgt: case OperationCode.Cgt_Un: case OperationCode.Clt: case OperationCode.Clt_Un: case OperationCode.Div: case OperationCode.Div_Un: case OperationCode.Mul: case OperationCode.Mul_Ovf: case OperationCode.Mul_Ovf_Un: case OperationCode.Or: case OperationCode.Rem: case OperationCode.Rem_Un: case OperationCode.Shl: case OperationCode.Shr: case OperationCode.Shr_Un: case OperationCode.Sub: case OperationCode.Sub_Ovf: case OperationCode.Sub_Ovf_Un: case OperationCode.Xor: expression = this.ParseBinaryOperation(currentOpcode); break; case OperationCode.Arglist: expression = new RuntimeArgumentHandleExpression(); break; case OperationCode.Array_Addr: elementType = ((IArrayTypeReference)currentOperation.Value).ElementType; expression = this.ParseArrayElementAddres(currentOperation, elementType); break; case OperationCode.Ldelema: elementType = (ITypeReference)currentOperation.Value; expression = this.ParseArrayElementAddres(currentOperation, elementType, treatArrayAsSingleDimensioned: true); break; case OperationCode.Array_Create: case OperationCode.Array_Create_WithLowerBound: case OperationCode.Newarr: expression = this.ParseArrayCreate(currentOperation); break; case OperationCode.Array_Get: elementType = ((IArrayTypeReference)currentOperation.Value).ElementType; expression = this.ParseArrayIndexer(currentOperation, elementType??this.platformType.SystemObject, treatArrayAsSingleDimensioned: false); break; case OperationCode.Ldelem: elementType = (ITypeReference)currentOperation.Value; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I: elementType = this.platformType.SystemIntPtr; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I1: elementType = this.platformType.SystemInt8; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I2: elementType = this.platformType.SystemInt16; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I4: elementType = this.platformType.SystemInt32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_I8: elementType = this.platformType.SystemInt64; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_R4: elementType = this.platformType.SystemFloat32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_R8: elementType = this.platformType.SystemFloat64; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U1: elementType = this.platformType.SystemUInt8; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U2: elementType = this.platformType.SystemUInt16; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_U4: elementType = this.platformType.SystemUInt32; goto case OperationCode.Ldelem_Ref; case OperationCode.Ldelem_Ref: expression = this.ParseArrayIndexer(currentOperation, elementType??this.platformType.SystemObject, treatArrayAsSingleDimensioned: true); break; case OperationCode.Array_Set: statement = this.ParseArraySet(currentOperation); break; case OperationCode.Beq: case OperationCode.Beq_S: case OperationCode.Bge: case OperationCode.Bge_S: case OperationCode.Bge_Un: case OperationCode.Bge_Un_S: case OperationCode.Bgt: case OperationCode.Bgt_S: case OperationCode.Bgt_Un: case OperationCode.Bgt_Un_S: case OperationCode.Ble: case OperationCode.Ble_S: case OperationCode.Ble_Un: case OperationCode.Ble_Un_S: case OperationCode.Blt: case OperationCode.Blt_S: case OperationCode.Blt_Un: case OperationCode.Blt_Un_S: case OperationCode.Bne_Un: case OperationCode.Bne_Un_S: statement = this.ParseBinaryConditionalBranch(currentOperation); break; case OperationCode.Box: expression = this.ParseConversion(currentOperation); break; case OperationCode.Br: case OperationCode.Br_S: case OperationCode.Leave: case OperationCode.Leave_S: statement = this.ParseUnconditionalBranch(currentOperation); break; case OperationCode.Break: statement = new DebuggerBreakStatement(); break; case OperationCode.Brfalse: case OperationCode.Brfalse_S: case OperationCode.Brtrue: case OperationCode.Brtrue_S: statement = this.ParseUnaryConditionalBranch(currentOperation); break; case OperationCode.Call: case OperationCode.Callvirt: MethodCall call = this.ParseCall(currentOperation); if (call.MethodToCall.Type.TypeCode == PrimitiveTypeCode.Void) { call.Locations.Add(currentOperation.Location); // turning it into a statement prevents the location from being attached to the expresssion ExpressionStatement es = new ExpressionStatement(); es.Expression = call; statement = es; } else expression = call; break; case OperationCode.Calli: expression = this.ParsePointerCall(currentOperation); break; case OperationCode.Castclass: case OperationCode.Conv_I: case OperationCode.Conv_I1: case OperationCode.Conv_I2: case OperationCode.Conv_I4: case OperationCode.Conv_I8: case OperationCode.Conv_Ovf_I: case OperationCode.Conv_Ovf_I_Un: case OperationCode.Conv_Ovf_I1: case OperationCode.Conv_Ovf_I1_Un: case OperationCode.Conv_Ovf_I2: case OperationCode.Conv_Ovf_I2_Un: case OperationCode.Conv_Ovf_I4: case OperationCode.Conv_Ovf_I4_Un: case OperationCode.Conv_Ovf_I8: case OperationCode.Conv_Ovf_I8_Un: case OperationCode.Conv_Ovf_U: case OperationCode.Conv_Ovf_U_Un: case OperationCode.Conv_Ovf_U1: case OperationCode.Conv_Ovf_U1_Un: case OperationCode.Conv_Ovf_U2: case OperationCode.Conv_Ovf_U2_Un: case OperationCode.Conv_Ovf_U4: case OperationCode.Conv_Ovf_U4_Un: case OperationCode.Conv_Ovf_U8: case OperationCode.Conv_Ovf_U8_Un: case OperationCode.Conv_R_Un: case OperationCode.Conv_R4: case OperationCode.Conv_R8: case OperationCode.Conv_U: case OperationCode.Conv_U1: case OperationCode.Conv_U2: case OperationCode.Conv_U4: case OperationCode.Conv_U8: case OperationCode.Unbox: case OperationCode.Unbox_Any: expression = this.ParseConversion(currentOperation); break; case OperationCode.Ckfinite: var operand = this.PopOperandStack(); var chkfinite = new MutableCodeModel.MethodReference() { CallingConvention = Cci.CallingConvention.FastCall, ContainingType = host.PlatformType.SystemFloat64, Name = this.host.NameTable.GetNameFor("__ckfinite__"), Type = host.PlatformType.SystemFloat64, InternFactory = host.InternFactory, }; expression = new MethodCall() { Arguments = new List<IExpression>(1) { operand }, IsStaticCall = true, Type = operand.Type, MethodToCall = chkfinite }; break; case OperationCode.Constrained_: //This prefix is redundant and is not represented in the code model. break; case OperationCode.Cpblk: var copyMemory = new CopyMemoryStatement(); copyMemory.NumberOfBytesToCopy = this.PopOperandStack(); copyMemory.SourceAddress = this.PopOperandStack(); copyMemory.TargetAddress = this.PopOperandStack(); statement = copyMemory; break; case OperationCode.Cpobj: expression = this.ParseCopyObject(); break; case OperationCode.Dup: expression = this.ParseDup(instruction.Type); break; case OperationCode.Endfilter: statement = this.ParseEndfilter(); break; case OperationCode.Endfinally: statement = new EndFinally(); break; case OperationCode.Initblk: var fillMemory = new FillMemoryStatement(); fillMemory.NumberOfBytesToFill = this.PopOperandStack(); fillMemory.FillValue = this.PopOperandStack(); fillMemory.TargetAddress = this.PopOperandStack(); statement = fillMemory; break; case OperationCode.Initobj: statement = this.ParseInitObject(currentOperation); break; case OperationCode.Isinst: expression = this.ParseCastIfPossible(currentOperation); break; case OperationCode.Jmp: var methodToCall = (IMethodReference)currentOperation.Value; expression = new MethodCall() { IsJumpCall = true, MethodToCall = methodToCall, Type = methodToCall.Type }; break; case OperationCode.Ldarg: case OperationCode.Ldarg_0: case OperationCode.Ldarg_1: case OperationCode.Ldarg_2: case OperationCode.Ldarg_3: case OperationCode.Ldarg_S: case OperationCode.Ldloc: case OperationCode.Ldloc_0: case OperationCode.Ldloc_1: case OperationCode.Ldloc_2: case OperationCode.Ldloc_3: case OperationCode.Ldloc_S: case OperationCode.Ldfld: case OperationCode.Ldsfld: expression = this.ParseBoundExpression(instruction); break; case OperationCode.Ldarga: case OperationCode.Ldarga_S: case OperationCode.Ldflda: case OperationCode.Ldsflda: case OperationCode.Ldloca: case OperationCode.Ldloca_S: case OperationCode.Ldftn: case OperationCode.Ldvirtftn: expression = this.ParseAddressOf(instruction); break; case OperationCode.Ldc_I4: case OperationCode.Ldc_I4_0: case OperationCode.Ldc_I4_1: case OperationCode.Ldc_I4_2: case OperationCode.Ldc_I4_3: case OperationCode.Ldc_I4_4: case OperationCode.Ldc_I4_5: case OperationCode.Ldc_I4_6: case OperationCode.Ldc_I4_7: case OperationCode.Ldc_I4_8: case OperationCode.Ldc_I4_M1: case OperationCode.Ldc_I4_S: case OperationCode.Ldc_I8: case OperationCode.Ldc_R4: case OperationCode.Ldc_R8: case OperationCode.Ldnull: case OperationCode.Ldstr: expression = this.ParseCompileTimeConstant(currentOperation); break; case OperationCode.Ldind_I: case OperationCode.Ldind_I1: case OperationCode.Ldind_I2: case OperationCode.Ldind_I4: case OperationCode.Ldind_I8: case OperationCode.Ldind_R4: case OperationCode.Ldind_R8: case OperationCode.Ldind_Ref: case OperationCode.Ldind_U1: case OperationCode.Ldind_U2: case OperationCode.Ldind_U4: case OperationCode.Ldobj: expression = this.ParseAddressDereference(currentOperation); break; case OperationCode.Ldlen: expression = this.ParseVectorLength(); break; case OperationCode.Ldtoken: expression = ParseToken(currentOperation); break; case OperationCode.Localloc: expression = this.ParseStackArrayCreate(); break; case OperationCode.Mkrefany: expression = this.ParseMakeTypedReference(currentOperation); break; case OperationCode.Neg: expression = this.ParseUnaryOperation(new UnaryNegation()); break; case OperationCode.Not: expression = this.ParseUnaryOperation(new OnesComplement()); break; case OperationCode.Newobj: expression = this.ParseCreateObjectInstance(currentOperation); break; case OperationCode.No_: Contract.Assume(false); //if code out there actually uses this, I need to know sooner rather than later. //TODO: need object model support break; case OperationCode.Nop: statement = new EmptyStatement(); break; case OperationCode.Pop: statement = this.ParsePop(); break; case OperationCode.Readonly_: this.sawReadonly = true; break; case OperationCode.Refanytype: expression = this.ParseGetTypeOfTypedReference(); break; case OperationCode.Refanyval: expression = this.ParseGetValueOfTypedReference(currentOperation); break; case OperationCode.Ret: statement = this.ParseReturn(); break; case OperationCode.Rethrow: statement = new RethrowStatement(); break; case OperationCode.Sizeof: expression = ParseSizeOf(currentOperation); break; case OperationCode.Starg: case OperationCode.Starg_S: case OperationCode.Stelem: case OperationCode.Stelem_I: case OperationCode.Stelem_I1: case OperationCode.Stelem_I2: case OperationCode.Stelem_I4: case OperationCode.Stelem_I8: case OperationCode.Stelem_R4: case OperationCode.Stelem_R8: case OperationCode.Stelem_Ref: case OperationCode.Stfld: case OperationCode.Stind_I: case OperationCode.Stind_I1: case OperationCode.Stind_I2: case OperationCode.Stind_I4: case OperationCode.Stind_I8: case OperationCode.Stind_R4: case OperationCode.Stind_R8: case OperationCode.Stind_Ref: case OperationCode.Stloc: case OperationCode.Stloc_0: case OperationCode.Stloc_1: case OperationCode.Stloc_2: case OperationCode.Stloc_3: case OperationCode.Stloc_S: case OperationCode.Stobj: case OperationCode.Stsfld: statement = this.ParseAssignment(currentOperation); break; case OperationCode.Switch: statement = this.ParseSwitchInstruction(currentOperation); break; case OperationCode.Tail_: this.sawTailCall = true; break; case OperationCode.Throw: statement = this.ParseThrow(); break; case OperationCode.Unaligned_: Contract.Assume(currentOperation.Value is byte); var alignment = (byte)currentOperation.Value; Contract.Assume(alignment == 1 || alignment == 2 || alignment == 4); this.alignment = alignment; break; case OperationCode.Volatile_: this.sawVolatile = true; break; } if (expression != null) { if (expression.Type is Dummy) expression.Type = instruction.Type; Contract.Assume(!(expression.Type is Dummy)); if (expression.Type.TypeCode != PrimitiveTypeCode.Void) { if (this.host.PreserveILLocations) { expression.Locations.Add(currentOperation.Location); } this.operandStack.Push(expression); } } else if (statement != null) { this.TurnOperandStackIntoPushStatements(statements); statements.Add(statement); if (this.host.PreserveILLocations) { if (this.lastLocation != null) { statement.Locations.Add(this.lastLocation); this.lastLocation = null; } } else if (this.lastSourceLocation != null) { statement.Locations.Add(this.lastSourceLocation); this.lastSourceLocation = null; } if (this.lastSynchronizationLocation != null) { statement.Locations.Add(this.lastSynchronizationLocation); this.lastSynchronizationLocation = null; } else if (this.lastContinuationLocation != null) { statement.Locations.Add(this.lastContinuationLocation); this.lastContinuationLocation = null; } } }