private void ExtractInstructions(IEnumerable <Cecil.Cil.Instruction> operations, IList <AnalysisNet.IInstruction> instructions) { foreach (Cecil.Cil.Instruction op in operations) { AnalysisNet.IInstruction instruction = ExtractInstruction(op); instructions.Add(instruction); } }
private AnalysisNet.IInstruction ExtractInstruction(Cecil.Cil.Instruction operation) { AnalysisNet.IInstruction instruction = null; // cecil does not have an enum we require it for the switch statement Cecil.Cil.Code code = operation.OpCode.Code; switch (code) { case Mono.Cecil.Cil.Code.Add: case Mono.Cecil.Cil.Code.Add_Ovf: case Mono.Cecil.Cil.Code.Add_Ovf_Un: case Mono.Cecil.Cil.Code.And: case Mono.Cecil.Cil.Code.Ceq: case Mono.Cecil.Cil.Code.Cgt: case Mono.Cecil.Cil.Code.Cgt_Un: case Mono.Cecil.Cil.Code.Clt: case Mono.Cecil.Cil.Code.Clt_Un: case Mono.Cecil.Cil.Code.Div: case Mono.Cecil.Cil.Code.Div_Un: case Mono.Cecil.Cil.Code.Mul: case Mono.Cecil.Cil.Code.Mul_Ovf: case Mono.Cecil.Cil.Code.Mul_Ovf_Un: case Mono.Cecil.Cil.Code.Or: case Mono.Cecil.Cil.Code.Rem: case Mono.Cecil.Cil.Code.Rem_Un: case Mono.Cecil.Cil.Code.Shl: case Mono.Cecil.Cil.Code.Shr: case Mono.Cecil.Cil.Code.Shr_Un: case Mono.Cecil.Cil.Code.Sub: case Mono.Cecil.Cil.Code.Sub_Ovf: case Mono.Cecil.Cil.Code.Sub_Ovf_Un: case Mono.Cecil.Cil.Code.Xor: instruction = ProcessBasic(operation); break; //case Mono.Cecil.Cil.Code.Arglist: // //expression = new RuntimeArgumentHandleExpression(); // break; //case Mono.Cecil.Cil.Code.Array_Create_WithLowerBound: //case Mono.Cecil.Cil.Code.Array_Create: case Mono.Cecil.Cil.Code.Newarr: instruction = ProcessCreateArray(operation); break; //case Mono.Cecil.Cil.Code.Array_Get: // instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Content); // break; //case Mono.Cecil.Cil.Code.Array_Addr: // instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Address); // break; //case Mono.Cecil.Cil.Code.Ldelem: case Mono.Cecil.Cil.Code.Ldelem_Any: case Mono.Cecil.Cil.Code.Ldelem_I: case Mono.Cecil.Cil.Code.Ldelem_I1: case Mono.Cecil.Cil.Code.Ldelem_I2: case Mono.Cecil.Cil.Code.Ldelem_I4: case Mono.Cecil.Cil.Code.Ldelem_I8: case Mono.Cecil.Cil.Code.Ldelem_R4: case Mono.Cecil.Cil.Code.Ldelem_R8: case Mono.Cecil.Cil.Code.Ldelem_U1: case Mono.Cecil.Cil.Code.Ldelem_U2: case Mono.Cecil.Cil.Code.Ldelem_U4: case Mono.Cecil.Cil.Code.Ldelem_Ref: instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Content); break; case Mono.Cecil.Cil.Code.Ldelema: instruction = ProcessLoadArrayElement(operation, AnalysisNetBytecode.LoadArrayElementOperation.Address); break; case Mono.Cecil.Cil.Code.Beq: case Mono.Cecil.Cil.Code.Beq_S: case Mono.Cecil.Cil.Code.Bne_Un: case Mono.Cecil.Cil.Code.Bne_Un_S: case Mono.Cecil.Cil.Code.Bge: case Mono.Cecil.Cil.Code.Bge_S: case Mono.Cecil.Cil.Code.Bge_Un: case Mono.Cecil.Cil.Code.Bge_Un_S: case Mono.Cecil.Cil.Code.Bgt: case Mono.Cecil.Cil.Code.Bgt_S: case Mono.Cecil.Cil.Code.Bgt_Un: case Mono.Cecil.Cil.Code.Bgt_Un_S: case Mono.Cecil.Cil.Code.Ble: case Mono.Cecil.Cil.Code.Ble_S: case Mono.Cecil.Cil.Code.Ble_Un: case Mono.Cecil.Cil.Code.Ble_Un_S: case Mono.Cecil.Cil.Code.Blt: case Mono.Cecil.Cil.Code.Blt_S: case Mono.Cecil.Cil.Code.Blt_Un: case Mono.Cecil.Cil.Code.Blt_Un_S: instruction = ProcessBinaryConditionalBranch(operation); break; case Mono.Cecil.Cil.Code.Br: case Mono.Cecil.Cil.Code.Br_S: instruction = ProcessUnconditionalBranch(operation); break; case Mono.Cecil.Cil.Code.Leave: case Mono.Cecil.Cil.Code.Leave_S: instruction = ProcessLeave(operation); break; case Mono.Cecil.Cil.Code.Break: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Nop: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Brfalse: case Mono.Cecil.Cil.Code.Brfalse_S: case Mono.Cecil.Cil.Code.Brtrue: case Mono.Cecil.Cil.Code.Brtrue_S: instruction = ProcessUnaryConditionalBranch(operation); break; case Mono.Cecil.Cil.Code.Call: case Mono.Cecil.Cil.Code.Callvirt: case Mono.Cecil.Cil.Code.Jmp: instruction = ProcessMethodCall(operation); break; case Mono.Cecil.Cil.Code.Calli: instruction = ProcessMethodCallIndirect(operation); break; case Mono.Cecil.Cil.Code.Castclass: case Mono.Cecil.Cil.Code.Isinst: case Mono.Cecil.Cil.Code.Box: case Mono.Cecil.Cil.Code.Unbox: case Mono.Cecil.Cil.Code.Unbox_Any: case Mono.Cecil.Cil.Code.Conv_I: case Mono.Cecil.Cil.Code.Conv_Ovf_I: case Mono.Cecil.Cil.Code.Conv_Ovf_I_Un: case Mono.Cecil.Cil.Code.Conv_I1: case Mono.Cecil.Cil.Code.Conv_Ovf_I1: case Mono.Cecil.Cil.Code.Conv_Ovf_I1_Un: case Mono.Cecil.Cil.Code.Conv_I2: case Mono.Cecil.Cil.Code.Conv_Ovf_I2: case Mono.Cecil.Cil.Code.Conv_Ovf_I2_Un: case Mono.Cecil.Cil.Code.Conv_I4: case Mono.Cecil.Cil.Code.Conv_Ovf_I4: case Mono.Cecil.Cil.Code.Conv_Ovf_I4_Un: case Mono.Cecil.Cil.Code.Conv_I8: case Mono.Cecil.Cil.Code.Conv_Ovf_I8: case Mono.Cecil.Cil.Code.Conv_Ovf_I8_Un: case Mono.Cecil.Cil.Code.Conv_U: case Mono.Cecil.Cil.Code.Conv_Ovf_U: case Mono.Cecil.Cil.Code.Conv_Ovf_U_Un: case Mono.Cecil.Cil.Code.Conv_U1: case Mono.Cecil.Cil.Code.Conv_Ovf_U1: case Mono.Cecil.Cil.Code.Conv_Ovf_U1_Un: case Mono.Cecil.Cil.Code.Conv_U2: case Mono.Cecil.Cil.Code.Conv_Ovf_U2: case Mono.Cecil.Cil.Code.Conv_Ovf_U2_Un: case Mono.Cecil.Cil.Code.Conv_U4: case Mono.Cecil.Cil.Code.Conv_Ovf_U4: case Mono.Cecil.Cil.Code.Conv_Ovf_U4_Un: case Mono.Cecil.Cil.Code.Conv_U8: case Mono.Cecil.Cil.Code.Conv_Ovf_U8: case Mono.Cecil.Cil.Code.Conv_Ovf_U8_Un: case Mono.Cecil.Cil.Code.Conv_R4: case Mono.Cecil.Cil.Code.Conv_R8: case Mono.Cecil.Cil.Code.Conv_R_Un: instruction = ProcessConversion(operation); break; //case Mono.Cecil.Cil.Code.Ckfinite: // var operand = result = PopOperandStack(); // var chkfinite = new MutableCodeModel.MethodReference() // { // CallingConvention = Cci.CallingConvention.FastCall, // ContainingType = host.PlatformType.SystemFloat64, // Name = result = 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 Mono.Cecil.Cil.Code.Constrained: instruction = ProcessConstrained(operation); break; case Mono.Cecil.Cil.Code.Cpblk: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Cpobj: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Dup: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Endfilter: case Mono.Cecil.Cil.Code.Endfinally: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Initblk: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Initobj: instruction = ProcessInitObj(operation); break; case Mono.Cecil.Cil.Code.Ldarg: case Mono.Cecil.Cil.Code.Ldarg_0: case Mono.Cecil.Cil.Code.Ldarg_1: case Mono.Cecil.Cil.Code.Ldarg_2: case Mono.Cecil.Cil.Code.Ldarg_3: case Mono.Cecil.Cil.Code.Ldarg_S: case Mono.Cecil.Cil.Code.Ldarga: case Mono.Cecil.Cil.Code.Ldarga_S: instruction = ProcessLoadArgument(operation); break; case Mono.Cecil.Cil.Code.Ldloc: case Mono.Cecil.Cil.Code.Ldloc_0: case Mono.Cecil.Cil.Code.Ldloc_1: case Mono.Cecil.Cil.Code.Ldloc_2: case Mono.Cecil.Cil.Code.Ldloc_3: case Mono.Cecil.Cil.Code.Ldloc_S: case Mono.Cecil.Cil.Code.Ldloca: case Mono.Cecil.Cil.Code.Ldloca_S: instruction = ProcessLoadLocal(operation); break; case Mono.Cecil.Cil.Code.Ldfld: case Mono.Cecil.Cil.Code.Ldsfld: case Mono.Cecil.Cil.Code.Ldflda: case Mono.Cecil.Cil.Code.Ldsflda: instruction = ProcessLoadField(operation); break; case Mono.Cecil.Cil.Code.Ldftn: case Mono.Cecil.Cil.Code.Ldvirtftn: instruction = ProcessLoadMethodAddress(operation); break; case Mono.Cecil.Cil.Code.Ldc_I4: case Mono.Cecil.Cil.Code.Ldc_I4_0: case Mono.Cecil.Cil.Code.Ldc_I4_1: case Mono.Cecil.Cil.Code.Ldc_I4_2: case Mono.Cecil.Cil.Code.Ldc_I4_3: case Mono.Cecil.Cil.Code.Ldc_I4_4: case Mono.Cecil.Cil.Code.Ldc_I4_5: case Mono.Cecil.Cil.Code.Ldc_I4_6: case Mono.Cecil.Cil.Code.Ldc_I4_7: case Mono.Cecil.Cil.Code.Ldc_I4_8: case Mono.Cecil.Cil.Code.Ldc_I4_M1: case Mono.Cecil.Cil.Code.Ldc_I4_S: case Mono.Cecil.Cil.Code.Ldc_I8: case Mono.Cecil.Cil.Code.Ldc_R4: case Mono.Cecil.Cil.Code.Ldc_R8: case Mono.Cecil.Cil.Code.Ldnull: case Mono.Cecil.Cil.Code.Ldstr: instruction = ProcessLoadConstant(operation); break; case Mono.Cecil.Cil.Code.Ldind_I: case Mono.Cecil.Cil.Code.Ldind_I1: case Mono.Cecil.Cil.Code.Ldind_I2: case Mono.Cecil.Cil.Code.Ldind_I4: case Mono.Cecil.Cil.Code.Ldind_I8: case Mono.Cecil.Cil.Code.Ldind_R4: case Mono.Cecil.Cil.Code.Ldind_R8: case Mono.Cecil.Cil.Code.Ldind_Ref: case Mono.Cecil.Cil.Code.Ldind_U1: case Mono.Cecil.Cil.Code.Ldind_U2: case Mono.Cecil.Cil.Code.Ldind_U4: case Mono.Cecil.Cil.Code.Ldobj: instruction = ProcessLoadIndirect(operation); break; case Mono.Cecil.Cil.Code.Ldlen: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Ldtoken: instruction = ProcessLoadToken(operation); break; case Mono.Cecil.Cil.Code.Localloc: instruction = ProcessBasic(operation); break; //case Mono.Cecil.Cil.Code.Mkrefany: // expression = result = ParseMakeTypedReference(currentOperation); // break; case Mono.Cecil.Cil.Code.Neg: case Mono.Cecil.Cil.Code.Not: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Newobj: instruction = ProcessCreateObject(operation); break; //case Mono.Cecil.Cil.Code.No_: // // If code out there actually uses this, I need to know sooner rather than later. // // TODO: need object model support // throw new NotImplementedException("Invalid opcode: No."); case Mono.Cecil.Cil.Code.Pop: instruction = ProcessBasic(operation); break; //case Mono.Cecil.Cil.Code.Readonly_: // result = sawReadonly = true; // break; //case Mono.Cecil.Cil.Code.Refanytype: // expression = result = ParseGetTypeOfTypedReference(); // break; //case Mono.Cecil.Cil.Code.Refanyval: // expression = result = ParseGetValueOfTypedReference(currentOperation); // break; case Mono.Cecil.Cil.Code.Ret: instruction = ProcessBasic(operation); break; case Mono.Cecil.Cil.Code.Sizeof: instruction = ProcessSizeof(operation); break; case Mono.Cecil.Cil.Code.Starg: case Mono.Cecil.Cil.Code.Starg_S: instruction = ProcessStoreArgument(operation); break; //case Mono.Cecil.Cil.Code.Array_Set: //case Mono.Cecil.Cil.Code.Stelem: case Mono.Cecil.Cil.Code.Stelem_Any: case Mono.Cecil.Cil.Code.Stelem_I: case Mono.Cecil.Cil.Code.Stelem_I1: case Mono.Cecil.Cil.Code.Stelem_I2: case Mono.Cecil.Cil.Code.Stelem_I4: case Mono.Cecil.Cil.Code.Stelem_I8: case Mono.Cecil.Cil.Code.Stelem_R4: case Mono.Cecil.Cil.Code.Stelem_R8: case Mono.Cecil.Cil.Code.Stelem_Ref: instruction = ProcessStoreArrayElement(operation); break; case Mono.Cecil.Cil.Code.Stfld: case Mono.Cecil.Cil.Code.Stsfld: instruction = ProcessStoreField(operation); break; case Mono.Cecil.Cil.Code.Stind_I: case Mono.Cecil.Cil.Code.Stind_I1: case Mono.Cecil.Cil.Code.Stind_I2: case Mono.Cecil.Cil.Code.Stind_I4: case Mono.Cecil.Cil.Code.Stind_I8: case Mono.Cecil.Cil.Code.Stind_R4: case Mono.Cecil.Cil.Code.Stind_R8: case Mono.Cecil.Cil.Code.Stind_Ref: case Mono.Cecil.Cil.Code.Stobj: instruction = ProcessStoreIndirect(operation); break; case Mono.Cecil.Cil.Code.Stloc: case Mono.Cecil.Cil.Code.Stloc_0: case Mono.Cecil.Cil.Code.Stloc_1: case Mono.Cecil.Cil.Code.Stloc_2: case Mono.Cecil.Cil.Code.Stloc_3: case Mono.Cecil.Cil.Code.Stloc_S: instruction = ProcessStoreLocal(operation); break; case Mono.Cecil.Cil.Code.Switch: instruction = ProcessSwitch(operation); break; //case Mono.Cecil.Cil.Code.Tail_: // result = sawTailCall = true; // break; case Mono.Cecil.Cil.Code.Throw: case Mono.Cecil.Cil.Code.Rethrow: instruction = ProcessBasic(operation); break; //case Mono.Cecil.Cil.Code.Unaligned_: // Contract.Assume(currentOperation.Value is byte); // var alignment = (byte)currentOperation.Value; // Contract.Assume(alignment == 1 || alignment == 2 || alignment == 4); // result = alignment = alignment; // break; //case Mono.Cecil.Cil.Code.Volatile_: // result = sawVolatile = true; // break; default: //Console.WriteLine("Unknown bytecode: {0}", operation.OperationCode); //throw new UnknownBytecodeException(operation); //continue; // Quick fix to preserve the offset in case it is a target location of some jump // Otherwise it will break the control-flow analysis later. instruction = new AnalysisNetBytecode.BasicInstruction((uint)operation.Offset, AnalysisNetBytecode.BasicOperation.Nop); break; } return(instruction); }