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;
							}
						}
					}
				}
			}
		}
Example #2
0
		// 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;
							}
						}
					}
				}
			}
		}
Example #3
0
		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);				
				}
			}
		}
Example #4
0
        // 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;
					}
				}
			}
		}
Example #5
0
		// 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); 
					}
				}
			}
		}
Example #6
0
        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);
        }