internal static bool AreEquivalent(Instruction source, Instruction target) { if (source.OpCode.Code != target.OpCode.Code) return false; if (source.OpCode.Code == Code.Ldstr) return true; //Check the types in ldarg stuff. Sometimes this scheme //could lead us to false positives. We need an analysis //which depends on the context. if (source.IsLoadArgument ()) { // case where 'ldarg this' is used (p.GetSequence () would be 0) if (!Current.HasParameters && !Target.HasParameters) return true; return AreEquivalent (source.GetParameter (Current), target.GetParameter (Target)); } // The same for ldloc / stloc if (source.IsLoadLocal () || source.IsStoreLocal ()) return AreEquivalent (source.GetVariable (Current), target.GetVariable (Target)); //WARNING: Dirty Evil Hack: this should be in the //Pattern class if (source.OpCode.Code == Code.Ret && source.Previous != null && (source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Pushi || source.Previous.OpCode.Code == Code.Ldnull || source.Previous.OpCode.StackBehaviourPush == StackBehaviour.Push1)) return false; //if (source.Operand != target.Operand) if (source.Operand != null && target.Operand != null) { // we're sure that target.Operand is of the same type as source.Operand (same OpCode is used) Instruction si = (source.Operand as Instruction); if (si != null) return (si.Offset == ((Instruction) target.Operand).Offset); IMetadataTokenProvider sm = (source.Operand as IMetadataTokenProvider); if (sm != null) return sm.Equals (target.Operand as IMetadataTokenProvider); if (source.Operand == target.Operand) return true; // last chance: we do call ToString if (source.Operand.ToString () != target.Operand.ToString ()) return false; } return true; }
static bool OriginsMatch (MethodDefinition method, Instruction lhs, Instruction rhs) { bool match = false; object operand1 = lhs.GetOperand (method); object operand2 = rhs.GetOperand (method); if (lhs.OpCode.Code == rhs.OpCode.Code) { if (lhs.IsLoadArgument ()) match = operand1.Equals (operand2); else if (lhs.IsLoadElement ()) match = LoadElementMatch (method, lhs, rhs); else if (lhs.IsLoadIndirect ()) match = LoadIndirectMatch (method, lhs, rhs); else if (lhs.IsLoadLocal ()) match = LocalsMatch (operand1, operand2); } else if (lhs.IsStoreLocal () && rhs.IsLoadLocal ()) match = LocalsMatch (operand1, operand2); else if (lhs.IsLoadLocal () && rhs.IsStoreLocal ()) match = LocalsMatch (operand1, operand2); return match; }