public void VisitBranch(ConditionalBranch branch) { if (m_needsCheck && !m_foundSingle && branch.Index >= 2 && m_numLocks == 1) { // Look for the if within the lock: // call System.Void System.Threading.Monitor::Enter(System.Object) // ldsfld field // brtrue 2A if (branch.Untyped.OpCode.Code == Code.Brtrue || branch.Untyped.OpCode.Code == Code.Brtrue_S) { LoadStaticField load = m_info.Instructions[branch.Index - 1] as LoadStaticField; Call call = m_info.Instructions[branch.Index - 2] as Call; if (load != null && call != null && call.Target.ToString() == "System.Void System.Threading.Monitor::Enter(System.Object)") { m_field = load.Field; Log.DebugLine(this, "found candidate lock at {0:X2}", branch.Untyped.Offset); // If we found the inner if then we need to look for a new // and a store within the if, if (DoFindNew(branch.Index + 1, branch.Target.Index - branch.Index - 1)) { m_foundSingle = true; // and a second guard before the lock. if (DoFindGuard(call.Index - 1)) { m_foundGuard = true; } } } } } }
// 10: brfalse 14 // 11: ldstr "pos" // 12: call System.Void System.Console::WriteLine(System.String) // 13: br 16 // // 14: ldstr "pos" // 15: call System.Void System.Console::WriteLine(System.String) // 16: ret public void VisitBranch(ConditionalBranch conditional) { if (m_offset < 0) { // If it's a forward conditional branch, if (conditional.Target.Index > conditional.Index) { // and the not-taken case ends with a forward unconditional branch, UnconditionalBranch unconditional = m_info.Instructions[conditional.Target.Index - 1] as UnconditionalBranch; if (unconditional != null && unconditional.Target.Index > unconditional.Index) { // then we have a contruct that resembles an if statement so we'll // compare the code in the two branches. int num1 = unconditional.Index - conditional.Index - 1; int num2 = unconditional.Target.Index - conditional.Target.Index; Log.DebugLine(this, "not taken at {0:X2} has {1} instructions, taken has {2} instructions", conditional.Untyped.Offset, num1, num2); if (num1 == num2 && conditional.Target.Index + num2 <= m_info.Instructions.Length) { if (DoMatches(conditional.Index + 1, conditional.Target.Index, num1)) { Log.DebugLine(this, "matches"); m_offset = conditional.Untyped.Offset; } } } } } }
public void VisitBranch(ConditionalBranch branch) { if (m_offset < 0) { if (DoMatch1(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch1 matched at {0:X2}", m_offset); } else if (DoMatch2(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch2 matched at {0:X2}", m_offset); } else if (DoMatch3(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch3 matched at {0:X2}", m_offset); } else if (DoMatch5(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch5 matched at {0:X2}", m_offset); } else if (DoMatch1b(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch1b matched at {0:X2}", m_offset); } else if (DoMatch2b(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch2b matched at {0:X2}", m_offset); } else if (DoMatch3b(branch.Index)) { m_offset = branch.Untyped.Offset; Log.DebugLine(this, "DoMatch3b matched at {0:X2}", m_offset); } } }
// ldfld bool Smokey.Tests.DisposeableTest/NoNullCheck2::m_disposed // brtrue IL_001d public void VisitConditional(ConditionalBranch branch) { if (m_disposable) { if (m_isNullaryDispose || m_isUnaryDispose) { if (branch.Index > 0) { LoadField load = m_minfo.Instructions[branch.Index - 1] as LoadField; if (load == null || load.Field.Name.IndexOf("m_disposed") < 0) // testing m_disposed does not count as a branch for null checking m_hasNoBranches = false; } } } }
// ldarg.1 list // brtrue 11 public void VisitBranch(ConditionalBranch branch) { if (m_needsCheck && m_offset < 0) { if (branch.Untyped.OpCode.Code == Code.Brtrue || branch.Untyped.OpCode.Code == Code.Brtrue_S || branch.Untyped.OpCode.Code == Code.Brfalse || branch.Untyped.OpCode.Code == Code.Brfalse_S) { LoadArg load = m_info.Instructions[branch.Index - 1] as LoadArg; if (load != null) { m_table[load.Name] = true; Log.DebugLine(this, "found a compare at {0:X2}", branch.Untyped.Offset); } } } }
private TypedInstruction DoGetTyped(MethodDefinition method, Instruction untyped, int index) { TypedInstruction instruction = null; switch (untyped.OpCode.Code) { case Code.Add: case Code.Add_Ovf: case Code.Add_Ovf_Un: case Code.And: case Code.Div: case Code.Div_Un: case Code.Mul: case Code.Mul_Ovf: case Code.Mul_Ovf_Un: case Code.Or: case Code.Rem: case Code.Rem_Un: case Code.Shl: case Code.Shr: case Code.Shr_Un: case Code.Sub: case Code.Sub_Ovf: case Code.Sub_Ovf_Un: case Code.Xor: instruction = new BinaryOp(untyped, index); break; case Code.Beq: case Code.Beq_S: case Code.Bge: case Code.Bge_S: case Code.Bge_Un: case Code.Bge_Un_S: case Code.Bgt: case Code.Bgt_S: case Code.Bgt_Un: case Code.Bgt_Un_S: case Code.Ble: case Code.Ble_S: case Code.Ble_Un: case Code.Ble_Un_S: case Code.Blt: case Code.Blt_S: case Code.Blt_Un: case Code.Blt_Un_S: case Code.Bne_Un: case Code.Bne_Un_S: case Code.Brfalse: case Code.Brfalse_S: case Code.Brtrue: case Code.Brtrue_S: instruction = new ConditionalBranch(untyped, index); break; case Code.Box: instruction = new Box(untyped, index); break; case Code.Br: case Code.Br_S: case Code.Leave: case Code.Leave_S: instruction = new UnconditionalBranch(untyped, index); break; case Code.Call: case Code.Callvirt: instruction = new Call(untyped, index); break; case Code.Castclass: case Code.Isinst: instruction = new CastClass(untyped, index); break; case Code.Ceq: instruction = new Ceq(untyped, index); break; case Code.Cgt: case Code.Cgt_Un: case Code.Clt: case Code.Clt_Un: instruction = new Compare(untyped, index); break; case Code.Conv_I1: case Code.Conv_I2: case Code.Conv_I4: case Code.Conv_I8: case Code.Conv_R4: case Code.Conv_R8: case Code.Conv_U4: case Code.Conv_U8: case Code.Conv_R_Un: case Code.Conv_Ovf_I1_Un: case Code.Conv_Ovf_I2_Un: case Code.Conv_Ovf_I4_Un: case Code.Conv_Ovf_I8_Un: case Code.Conv_Ovf_U1_Un: case Code.Conv_Ovf_U2_Un: case Code.Conv_Ovf_U4_Un: case Code.Conv_Ovf_U8_Un: case Code.Conv_Ovf_I_Un: case Code.Conv_Ovf_U_Un: case Code.Conv_Ovf_I1: case Code.Conv_Ovf_U1: case Code.Conv_Ovf_I2: case Code.Conv_Ovf_U2: case Code.Conv_Ovf_I4: case Code.Conv_Ovf_U4: case Code.Conv_Ovf_I8: case Code.Conv_Ovf_U8: case Code.Conv_U2: case Code.Conv_U1: case Code.Conv_I: case Code.Conv_Ovf_I: case Code.Conv_Ovf_U: case Code.Conv_U: instruction = new Conv(untyped, index); break; case Code.Endfilter: case Code.Endfinally: case Code.Ret: case Code.Rethrow: instruction = new End(untyped, index); break; case Code.Initobj: instruction = new InitObj(untyped, index); break; case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarg: case Code.Ldarg_S: instruction = new LoadArg(method, untyped, index); break; case Code.Ldarga: case Code.Ldarga_S: instruction = new LoadArgAddress(method, untyped, index); 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: case Code.Ldc_I4_S: case Code.Ldc_I4: case Code.Ldc_I8: instruction = new LoadConstantInt(untyped, index); break; case Code.Ldc_R4: case Code.Ldc_R8: instruction = new LoadConstantFloat(untyped, index); break; case Code.Ldelema: case Code.Ldtoken: instruction = new LoadPointer(untyped, index); break; case Code.Ldelem_I1: case Code.Ldelem_U1: case Code.Ldelem_I2: case Code.Ldelem_U2: case Code.Ldelem_I4: case Code.Ldelem_U4: case Code.Ldelem_I8: case Code.Ldelem_I: case Code.Ldelem_R4: case Code.Ldelem_R8: case Code.Ldelem_Ref: case Code.Ldelem_Any: case Code.Ldind_I1: case Code.Ldind_U1: case Code.Ldind_I2: case Code.Ldind_U2: case Code.Ldind_I4: case Code.Ldind_U4: case Code.Ldind_I8: case Code.Ldind_I: case Code.Ldind_R4: case Code.Ldind_R8: case Code.Ldind_Ref: case Code.Ldlen: instruction = new Load(untyped, index); break; case Code.Ldfld: instruction = new LoadField(untyped, index); break; case Code.Ldflda: instruction = new LoadFieldAddress(untyped, index); break; case Code.Ldftn: case Code.Ldvirtftn: instruction = new LoadFunctionAddress(untyped, index); break; case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldloc: case Code.Ldloc_S: instruction = new LoadLocal(m_symbols, method, untyped, index); break; case Code.Ldloca: case Code.Ldloca_S: instruction = new LoadLocalAddress(m_symbols, method, untyped, index); break; case Code.Ldnull: instruction = new LoadNull(untyped, index); break; case Code.Ldsfld: instruction = new LoadStaticField(untyped, index); break; case Code.Ldsflda: instruction = new LoadStaticFieldAddress(untyped, index); break; case Code.Ldstr: instruction = new LoadString(untyped, index); break; case Code.Newarr: instruction = new NewArr(untyped, index); break; case Code.Newobj: instruction = new NewObj(untyped, index); break; case Code.Starg: case Code.Starg_S: instruction = new StoreArg(method, untyped, index); break; case Code.Stelem_I: case Code.Stelem_I1: case Code.Stelem_I2: case Code.Stelem_I4: case Code.Stelem_I8: case Code.Stelem_R4: case Code.Stelem_R8: case Code.Stelem_Ref: case Code.Stelem_Any: case Code.Stind_I: case Code.Stind_I1: case Code.Stind_I2: case Code.Stind_I4: case Code.Stind_I8: case Code.Stind_R4: case Code.Stind_R8: case Code.Stobj: instruction = new Store(untyped, index); break; case Code.Stfld: instruction = new StoreField(untyped, index); break; case Code.Stloc_0: case Code.Stloc_1: case Code.Stloc_2: case Code.Stloc_3: case Code.Stloc: case Code.Stloc_S: instruction = new StoreLocal(m_symbols, method, untyped, index); break; case Code.Stsfld: instruction = new StoreStaticField(untyped, index); break; case Code.Switch: instruction = new Switch(untyped, index); break; case Code.Throw: instruction = new Throw(untyped, index); break; case Code.Unbox: case Code.Unbox_Any: instruction = new Unbox(untyped, index); break; default: instruction = new CatchAll(untyped, index); break; } return(instruction); }