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; }
private static bool CheckCeqInstruction (Instruction instruction, MethodDefinition method) { bool problem = false; switch (instruction.OpCode.Code) { case Code.Conv_R_Un: case Code.Conv_R4: case Code.Conv_R8: return true; case Code.Ldc_R4: return !CheckFloatConstants ((float) instruction.Operand); case Code.Ldc_R8: return !CheckDoubleConstants ((double) instruction.Operand); case Code.Ldelem_R4: case Code.Ldelem_R8: return true; case Code.Ldloc_0: case Code.Ldloc_1: case Code.Ldloc_2: case Code.Ldloc_3: case Code.Ldloc_S: case Code.Ldloc: case Code.Ldloca: case Code.Ldloca_S: return instruction.GetVariable (method).VariableType.IsFloatingPoint (); case Code.Ldarg_0: case Code.Ldarg_1: case Code.Ldarg_2: case Code.Ldarg_3: case Code.Ldarg: case Code.Ldarg_S: case Code.Ldarga: case Code.Ldarga_S: ParameterDefinition parameter = instruction.GetParameter (method); // handle 'this' if (parameter == null) return method.DeclaringType.IsFloatingPoint (); return parameter.ParameterType.IsFloatingPoint (); case Code.Call: case Code.Callvirt: MethodReference call = instruction.Operand as MethodReference; return call.ReturnType.IsFloatingPoint (); case Code.Ldfld: case Code.Ldflda: case Code.Ldsfld: case Code.Ldsflda: FieldReference field = instruction.Operand as FieldReference; return field.FieldType.IsFloatingPoint (); } return problem; }
private void CheckArgument (MethodDefinition method, Instruction ins) { ParameterDefinition parameter = ins.GetParameter (method); if (parameter == null) return; // avoid checking parameters where a null check was already found if (has_null_check.Get (parameter.GetSequence ())) return; Instruction next = ins.Next; Code nc = next.OpCode.Code; switch (nc) { case Code.Box: // generics case Code.Ldind_Ref: // load indirect reference next = next.Next; nc = next.OpCode.Code; break; } if (null_compare.Get (nc)) { has_null_check.Set (parameter.GetSequence ()); } else { // compare with null (next or previous to current instruction) // followed by a CEQ instruction if (nc == Code.Ldnull) { if (next.Next.OpCode.Code == Code.Ceq) has_null_check.Set (parameter.GetSequence ()); } else if (nc == Code.Ceq) { if (ins.Previous.OpCode.Code == Code.Ldnull) has_null_check.Set (parameter.GetSequence ()); } } }