public static Method IsMethodCall (Statement s) { if (s == null) return null; var expressionStatement = s as ExpressionStatement; if (expressionStatement == null) return null; var methodCall = expressionStatement.Expression as MethodCall; if (methodCall == null) return null; var binding = methodCall.Callee as MemberBinding; if (binding == null) return null; return binding.BoundMember as Method; }
private int ParseStatement (Collection<Instruction> instructions, int index, List<Statement> result, out bool isNewBlock) { Expression expression = null; Statement statement = null; isNewBlock = false; bool needToRepeat = true; while (index < instructions.Count) { Instruction inst = instructions [index++]; Code opcode = inst.OpCode.Code; bool isStatement = false; switch (opcode) { case Code.Nop: statement = new Statement (NodeType.Nop); needToRepeat = false; break; case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: expression = GetParameterExpression (opcode - Code.Ldarg_0); break; case Code.Ldarg_S: expression = GetParameterExpression ((int) inst.Operand); break; case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: expression = GetLocalExpression (opcode - Code.Ldloc_0); break; case Code.Ldloc_S: expression = GetLocalExpression ((int) (inst.Operand)); break; case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: statement = new AssignmentStatement (PopOperand (), GetLocalExpression ((opcode - Code.Stloc_0))); needToRepeat = false; break; case Code.Stloc_S: statement = new AssignmentStatement (PopOperand (), GetLocalExpression ((VariableDefinition) (inst.Operand))); needToRepeat = false; break; case Code.Starg_S: statement = new AssignmentStatement (PopOperand (), GetParameterExpression ((int) (inst.Operand))); needToRepeat = false; break; case Code.Ldarga_S: throw new NotImplementedException (); case Code.Ldloca_S: throw new NotImplementedException (); case Code.Ldnull: expression = Literal.Null; break; case Code.Ldc_I4_M1: case Code.Ldc_I4_0: case Code.Ldc_I4_1: case Code.Ldc_I4_2: case Code.Ldc_I4_3: case Code.Ldc_I4_4: case Code.Ldc_I4_5: case Code.Ldc_I4_6: case Code.Ldc_I4_7: case Code.Ldc_I4_8: expression = GetLiteral ((opcode - Code.Ldc_I4_0), CoreSystemTypes.Instance.TypeInt32); break; case Code.Ldc_I8: expression = GetLiteral ((Int64) inst.Operand, CoreSystemTypes.Instance.TypeInt64); break; case Code.Ldc_I4_S: expression = GetLiteral ((int) (sbyte) inst.Operand, CoreSystemTypes.Instance.TypeInt32); break; case Code.Ldc_I4: expression = GetLiteral ((int) inst.Operand, CoreSystemTypes.Instance.TypeInt32); break; case Code.Ldc_R4: expression = GetLiteral ((float) inst.Operand, CoreSystemTypes.Instance.TypeSingle); break; case Code.Ldc_R8: expression = GetLiteral ((double) inst.Operand, CoreSystemTypes.Instance.TypeDouble); break; case Code.Ret: statement = new Return (TypeIsVoid (this.method.ReturnType) ? null : PopOperand ()); isNewBlock = true; needToRepeat = false; break; case Code.Br_S: statement = ParseBranch (inst, NodeType.Nop, 0, true, false); isNewBlock = true; needToRepeat = false; break; case Code.Brfalse_S: statement = ParseBranch (inst, NodeType.LogicalNot, 1, true, false); isNewBlock = true; needToRepeat = false; break; case Code.Brtrue_S: statement = ParseBranch (inst, NodeType.Nop, 1, true, false); isNewBlock = true; needToRepeat = false; break; case Code.Bne_Un_S: statement = ParseBranch (inst, NodeType.Ne, 2, true, true); isNewBlock = true; needToRepeat = false; break; case Code.Bge_Un_S: statement = ParseBranch (inst, NodeType.Ge, 2, true, true); isNewBlock = true; needToRepeat = false; break; case Code.Bgt_Un_S: statement = ParseBranch (inst, NodeType.Gt, 2, true, true); isNewBlock = true; needToRepeat = false; break; case Code.Ble_S: statement = ParseBranch (inst, NodeType.Le, 2, true, false); isNewBlock = true; needToRepeat = false; break; case Code.Blt_Un_S: statement = ParseBranch (inst, NodeType.Lt, 2, true, true); isNewBlock = true; needToRepeat = false; break; case Code.Br: statement = ParseBranch (inst, NodeType.Nop, 0, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Brfalse: statement = ParseBranch (inst, NodeType.LogicalNot, 0, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Brtrue: statement = ParseBranch (inst, NodeType.Nop, 1, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Beq: statement = ParseBranch (inst, NodeType.Eq, 2, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Bge: statement = ParseBranch (inst, NodeType.Ge, 2, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Bgt: statement = ParseBranch (inst, NodeType.Gt, 2, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Ble: statement = ParseBranch (inst, NodeType.Le, 2, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Blt: statement = ParseBranch (inst, NodeType.Lt, 2, false, false); isNewBlock = true; needToRepeat = false; break; case Code.Bne_Un: statement = ParseBranch (inst, NodeType.LogicalNot, 2, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Bge_Un: statement = ParseBranch (inst, NodeType.Ge, 2, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Bgt_Un: statement = ParseBranch (inst, NodeType.Gt, 2, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Ble_Un: statement = ParseBranch (inst, NodeType.Le, 2, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Blt_Un: statement = ParseBranch (inst, NodeType.Lt, 2, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Leave: statement = ParseBranch (inst, NodeType.Nop, 0, false, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Leave_S: statement = ParseBranch (inst, NodeType.Nop, 0, true, false, true); isNewBlock = true; needToRepeat = false; break; case Code.Endfinally: statement = new EndFinally (); isNewBlock = true; needToRepeat = false; break; case Code.Switch: break; case Code.Ldind_I1: break; case Code.Ldind_U1: break; case Code.Ldind_I2: break; case Code.Ldind_U2: break; case Code.Ldind_I4: break; case Code.Ldind_U4: break; case Code.Ldind_I8: break; case Code.Ldind_I: break; case Code.Ldind_R4: break; case Code.Ldind_R8: break; case Code.Ldind_Ref: break; case Code.Stind_Ref: break; case Code.Stind_I1: break; case Code.Stind_I2: break; case Code.Stind_I4: break; case Code.Stind_I8: break; case Code.Stind_R4: break; case Code.Stind_R8: break; case Code.Add: expression = ParseBinaryOperation (NodeType.Add); break; case Code.Sub: expression = ParseBinaryOperation (NodeType.Sub); break; case Code.Mul: expression = ParseBinaryOperation (NodeType.Mul); break; case Code.Div: expression = ParseBinaryOperation (NodeType.Div); break; case Code.Div_Un: expression = ParseBinaryOperation (NodeType.Div_Un); break; case Code.Rem: expression = ParseBinaryOperation (NodeType.Rem); break; case Code.Rem_Un: expression = ParseBinaryOperation (NodeType.Rem_Un); break; case Code.And: expression = ParseBinaryOperation (NodeType.And); break; case Code.Or: expression = ParseBinaryOperation (NodeType.Or); break; case Code.Xor: expression = ParseBinaryOperation (NodeType.Xor); break; case Code.Shl: expression = ParseBinaryOperation (NodeType.Shl); break; case Code.Shr: expression = ParseBinaryOperation (NodeType.Shr); break; case Code.Shr_Un: expression = ParseBinaryOperation (NodeType.Shr_Un); break; case Code.Neg: expression = ParseUnaryOperation (NodeType.Neg); break; case Code.Not: expression = ParseUnaryOperation (NodeType.Not); break; case Code.Conv_I1: expression = new UnaryExpression (NodeType.Conv_I1, PopOperand (), CoreSystemTypes.Instance.TypeSByte); break; case Code.Conv_I2: expression = new UnaryExpression (NodeType.Conv_I2, PopOperand (), CoreSystemTypes.Instance.TypeInt16); break; case Code.Conv_I4: expression = new UnaryExpression (NodeType.Conv_I4, PopOperand (), CoreSystemTypes.Instance.TypeInt32); break; case Code.Conv_I8: expression = new UnaryExpression (NodeType.Conv_I8, PopOperand (), CoreSystemTypes.Instance.TypeInt64); break; case Code.Conv_R4: expression = new UnaryExpression (NodeType.Conv_R4, PopOperand (), CoreSystemTypes.Instance.TypeSingle); break; case Code.Conv_R8: expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeDouble); break; case Code.Conv_U4: expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeUInt32); break; case Code.Conv_U8: expression = new UnaryExpression (NodeType.Conv_R8, PopOperand (), CoreSystemTypes.Instance.TypeUInt64); break; case Code.Call: expression = ParseCall (inst, NodeType.Call, out isStatement); if (isStatement) needToRepeat = false; break; case Code.Callvirt: expression = ParseCall (inst, NodeType.CallVirt, out isStatement); if (isStatement) needToRepeat = false; break; case Code.Cpobj: break; case Code.Ldobj: break; case Code.Ldstr: expression = GetLiteral (inst.Operand, CoreSystemTypes.Instance.TypeString); break; case Code.Newobj: expression = ParseNewObjectCreation (inst); break; case Code.Castclass: break; case Code.Isinst: break; case Code.Conv_R_Un: break; case Code.Unbox: break; case Code.Throw: isNewBlock = true; break; case Code.Ldfld: break; case Code.Ldflda: break; case Code.Stfld: break; case Code.Ldsfld: break; case Code.Ldsflda: break; case Code.Stsfld: break; case Code.Stobj: break; case Code.Conv_Ovf_I1_Un: break; case Code.Conv_Ovf_I2_Un: break; case Code.Conv_Ovf_I4_Un: break; case Code.Conv_Ovf_I8_Un: break; case Code.Conv_Ovf_U1_Un: break; case Code.Conv_Ovf_U2_Un: break; case Code.Conv_Ovf_U4_Un: break; case Code.Conv_Ovf_U8_Un: break; case Code.Conv_Ovf_I_Un: break; case Code.Conv_Ovf_U_Un: break; case Code.Box: break; case Code.Newarr: break; case Code.Ldlen: break; case Code.Ldelema: break; case Code.Ldelem_I1: break; case Code.Ldelem_U1: break; case Code.Ldelem_I2: break; case Code.Ldelem_U2: break; case Code.Ldelem_I4: break; case Code.Ldelem_U4: break; case Code.Ldelem_I8: break; case Code.Ldelem_I: break; case Code.Ldelem_R4: break; case Code.Ldelem_R8: break; case Code.Ldelem_Ref: break; case Code.Stelem_I: break; case Code.Stelem_I1: break; case Code.Stelem_I2: break; case Code.Stelem_I4: break; case Code.Stelem_I8: break; case Code.Stelem_R4: break; case Code.Stelem_R8: break; case Code.Stelem_Ref: break; case Code.Ldelem_Any: break; case Code.Stelem_Any: break; case Code.Unbox_Any: break; case Code.Conv_Ovf_I1: break; case Code.Conv_Ovf_U1: break; case Code.Conv_Ovf_I2: break; case Code.Conv_Ovf_U2: break; case Code.Conv_Ovf_I4: break; case Code.Conv_Ovf_U4: break; case Code.Conv_Ovf_I8: break; case Code.Conv_Ovf_U8: break; case Code.Refanyval: break; case Code.Ckfinite: break; case Code.Mkrefany: break; case Code.Ldtoken: break; case Code.Conv_U2: break; case Code.Conv_U1: break; case Code.Conv_I: break; case Code.Conv_Ovf_I: break; case Code.Conv_Ovf_U: break; case Code.Add_Ovf: break; case Code.Add_Ovf_Un: break; case Code.Mul_Ovf: break; case Code.Mul_Ovf_Un: break; case Code.Sub_Ovf: break; case Code.Sub_Ovf_Un: break; case Code.Stind_I: break; case Code.Conv_U: break; case Code.Arglist: break; case Code.Ceq: expression = ParseBinaryComparison (NodeType.Ceq); break; case Code.Cgt: expression = ParseBinaryComparison (NodeType.Cgt); break; case Code.Cgt_Un: break; case Code.Clt: expression = ParseBinaryComparison (NodeType.Clt); break; case Code.Clt_Un: break; case Code.Ldftn: break; case Code.Ldvirtftn: break; case Code.Ldarg: break; case Code.Ldarga: break; case Code.Starg: break; case Code.Ldloc: break; case Code.Ldloca: break; case Code.Stloc: break; case Code.Localloc: break; case Code.Endfilter: isNewBlock = true; break; case Code.Unaligned: break; case Code.Volatile: break; case Code.Tail: break; case Code.Initobj: break; case Code.Constrained: break; case Code.Cpblk: break; case Code.Initblk: break; case Code.No: break; case Code.Rethrow: isNewBlock = true; break; case Code.Sizeof: break; case Code.Refanytype: break; case Code.Readonly: break; default: needToRepeat = false; break; } if (!needToRepeat) break; int offset = inst.Next == null ? inst.Offset + 1 : inst.Next.Offset; if (!this.block_map.ContainsKey (offset)) this.evaluation_stack.Push (expression); else { isNewBlock = true; break; } } while (this.evaluation_stack.Count > 0) { Statement stmt = new ExpressionStatement (this.evaluation_stack.Pop ()); result.Add (stmt); } if (statement == null) statement = new ExpressionStatement (expression); result.Add (statement); if (!isNewBlock) isNewBlock = this.block_map.ContainsKey (instructions [index].Offset); return index; }
public Method IsContractCall (Statement s) { Method m = HelperMethods.IsMethodCall (s); if (IsContractMethod (m)) return m; return null; }