public void VisitInstruction(TypedInstruction instruction) { if (m_offset < 0) { m_offset = NullCheck.Check<NullDerefRule>(instruction, m_info.Tracker, out m_details); } }
private int DoGetStackCount(TypedInstruction instruction, StackBehaviour behavior) { int count = 0; switch (behavior) { case StackBehaviour.Pop0: case StackBehaviour.Push0: break; case StackBehaviour.Pop1: case StackBehaviour.Popi: case StackBehaviour.Popref: case StackBehaviour.Push1: case StackBehaviour.Pushi: case StackBehaviour.Pushi8: case StackBehaviour.Pushr4: case StackBehaviour.Pushr8: case StackBehaviour.Pushref: count = 1; break; case StackBehaviour.Pop1_pop1: case StackBehaviour.Popi_pop1: case StackBehaviour.Popi_popi: case StackBehaviour.Popi_popi8: case StackBehaviour.Popi_popr4: case StackBehaviour.Popi_popr8: case StackBehaviour.Popref_pop1: case StackBehaviour.Popref_popi: case StackBehaviour.Push1_push1: count = 2; break; case StackBehaviour.Popi_popi_popi: case StackBehaviour.Popref_popi_popi: case StackBehaviour.Popref_popi_popi8: case StackBehaviour.Popref_popi_popr4: case StackBehaviour.Popref_popi_popr8: case StackBehaviour.Popref_popi_popref: count = 3; break; case StackBehaviour.PopAll: // leave count = int.MaxValue; break; case StackBehaviour.Varpop: // call, newobj, ret Call call = instruction as Call; if (call != null) { count = call.Target.Parameters.Count + (call.Target.HasThis ? 1 : 0); } else if (instruction.Untyped.OpCode.Code == Code.Ret) { count = int.MaxValue; } else { NewObj no = instruction as NewObj; DBC.Assert(no != null, "Varpop opcode should be call, ret, or newobj"); count = no.Ctor.Parameters.Count; } break; case StackBehaviour.Varpush: // call Call call2 = instruction as Call; DBC.Assert(call2 != null, "Varpush opcode should be call"); if (call2.Target.ReturnType.ReturnType.FullName != "System.Void") count = 1; break; default: DBC.Fail("Bad stack behavior: {0}", behavior); break; } return count; }
private int DoGetStackDelta(TypedInstruction instruction) { int delta = 0; delta += DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPush); delta -= DoGetStackCount(instruction, instruction.Untyped.OpCode.StackBehaviourPop); // Log.DebugLine(this, "{0} (delta = {1})", instruction, delta); return delta; }
private void DoCheck(TypedInstruction binary) { if (binary.Index >= 2) { int rhsEnd = binary.Index - 1; int rhsStart = rhsEnd - DoGetPushRange(m_info, rhsEnd); int lhsEnd = rhsStart - 1; int lhsStart = lhsEnd - DoGetPushRange(m_info, lhsEnd); Log.DebugLine(this, "{0} at {1:X}", binary.Untyped.OpCode.Code, binary.Untyped.Offset); Log.DebugLine(this, " lhs range: [{0:X}, {1:X}]", m_info.Instructions[lhsStart].Untyped.Offset, m_info.Instructions[lhsEnd].Untyped.Offset); Log.DebugLine(this, " rhs range: [{0:X}, {1:X}]", m_info.Instructions[rhsStart].Untyped.Offset, m_info.Instructions[rhsEnd].Untyped.Offset); bool matches = (rhsEnd - rhsStart) == (lhsEnd - lhsStart); for (int i = 0; i <= (rhsEnd - rhsStart) && matches; ++i) { TypedInstruction lhs = m_info.Instructions[lhsStart + i]; TypedInstruction rhs = m_info.Instructions[rhsStart + i]; matches = lhs.Untyped.Matches(rhs.Untyped); } if (matches) { m_offset = binary.Untyped.Offset; } } }
private void DoCheckLoad(TypedInstruction instruction) { LoadConstantInt load = m_info.Instructions[instruction.Index - 1] as LoadConstantInt; if (load != null) { if (load.Value < 0 || load.Value > 255) { m_offset = instruction.Untyped.Offset; Log.DebugLine(this, "bad exit at {0:X2}", m_offset); } } LoadLocal local = m_info.Instructions[instruction.Index - 1] as LoadLocal; if (local != null) { Log.DebugLine(this, "{0} at {1:X2}", instruction.Untyped.OpCode, instruction.Untyped.Offset); if (m_candidateLoads.IndexOf(local.Variable) < 0) { m_candidateLoads.Add(local.Variable); } } }
private void DoCheck(TypedInstruction call, MethodReference target, int nth) { int index = m_info.Tracker.GetStackIndex(call.Index, nth); if (index >= 0) { LoadString load = m_info.Instructions[index] as LoadString; if (load != null) { m_offset = call.Untyped.Offset; m_bad = target.ToString(); Log.DebugLine(this, "bad call at {0:X2}", m_offset); } } }
public void VisitInstruction(TypedInstruction instruction) { if (m_needsCheck && !m_foundEarlyReturn && m_offset < 0) { m_offset = NullCheck.Check<EqualsRequiresNullCheckRule>(instruction, m_tracker, out m_details); } }
private bool DoMatch(TypedInstruction lhs, TypedInstruction rhs) { if (lhs.Untyped.OpCode.Code != rhs.Untyped.OpCode.Code) return false; if (lhs.Untyped.Operand != null || rhs.Untyped.Operand != null) { if (lhs.Untyped.Operand != null && rhs.Untyped.Operand != null) { if (!DoMatchOperand(lhs.Untyped.Operand, rhs.Untyped.Operand)) return false; } else return false; } return true; }