public IEnumerable<object> Run(IApp app, CancellationToken token) { if (typeDef == null) { yield return new AnalysisError("Failed to resolve '" + type.FullName + "'."); yield break; } var comparer = new SigComparer(); if (typeDef.IsInterface) { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (!type.HasInterfaces) continue; foreach (var iface in type.Interfaces) { if (comparer.Equals(iface.Interface, typeDef)) yield return type; } } } else { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (comparer.Equals(type.BaseType, typeDef)) yield return type; } } }
public override bool Equals(object obj) { var other = obj as FuncSig; if (other == null || other.Flags != Flags) { return(false); } if (other.ParamSigs.Length != ParamSigs.Length) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < ParamSigs.Length; i++) { if (!comparer.Equals(ParamSigs[i], other.ParamSigs[i])) { return(false); } } if (!comparer.Equals(RetType, other.RetType)) { return(false); } return(true); }
/// <summary> /// Find all references to a TypeDef and replace them with another TypeDef. /// Note that field and method references from the source TypeDef will also need to be replaced serparately. /// </summary> public static void ReplaceAllTypeDefReferences(TypeDef sourceTypeDef, TypeDef destinationTypeDef, ModuleDefMD moduleDefMd) { var types = moduleDefMd.GetTypes(); var sourceTypeSig = sourceTypeDef.ToTypeSig(); var destinationTypeSig = destinationTypeDef.ToTypeSig(); var sigComparer = new SigComparer(); foreach (var type in types) { // Fields foreach (var field in type.Fields) { if (sigComparer.Equals(field.FieldType, sourceTypeSig)) { field.FieldType = destinationTypeSig; } } // Methods foreach (var method in type.Methods) { if (method.Body == null) { continue; } foreach (var instruction in method.Body.Instructions) { if (instruction.Operand != null) { if (instruction.Operand is MethodSpec methodSpec && methodSpec.GenericInstMethodSig != null) { // Replace generic parameter types for (var i = methodSpec.GenericInstMethodSig.GenericArguments.Count - 1; i >= 0; i--) { var genericArgument = methodSpec.GenericInstMethodSig.GenericArguments[i]; var genericArgumentTypeSpec = genericArgument as TypeSig; if (sigComparer.Equals(genericArgumentTypeSpec, sourceTypeSig)) { methodSpec.GenericInstMethodSig.GenericArguments.RemoveAt(i); methodSpec.GenericInstMethodSig.GenericArguments.Insert(i, destinationTypeSig); } } // Todo: Parameters // Todo: Return types. } } } } } }
T[] ConvertArray <T>(TypeSig elemType, IList <CAArgument> oldList) { var list = new T[oldList.Count]; bool tIsValueType = typeof(T).IsValueType; bool tIsSystemObject = typeof(T) == typeof(object); var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken); for (int i = 0; i < list.Length; i++) { var arg = oldList[i]; if (!tIsSystemObject && !sigComparer.Equals(elemType, arg.Type)) { return(Array.Empty <T>()); } var res = ConvertFromModel(arg.Type, arg.Value); if (res is T) { list[i] = (T)res; } else if (!tIsValueType && (res == null || res == Null <T> .Instance)) { object n = null; list[i] = (T)n; } else { return(Array.Empty <T>()); } } return(list); }
public static bool SigListEquals(IList <TypeSig> x, IList <TypeSig> y) { if (x == null && y == null) { return(true); } if (x == null || y == null) { return(false); } if (x.Count != y.Count) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < x.Count; ++i) { if (!comparer.Equals(x[i], y[i])) { return(false); } } return(true); }
protected MethodSignature SubstituteArguments(ModuleDef module, MethodSignature signature) { bool changed = false; List <Func <ModuleDef, TypeSig> > newParams = new List <Func <ModuleDef, TypeSig> >(); SigComparer comparer = new SigComparer(ComparerOptions); foreach (ParameterSignature param in signature.Parameters) { TypeSig typeSub = Substitute(param.ParameterType(module)); if (!comparer.Equals(typeSub, param.ParameterType(module))) { changed = true; } newParams.Add(Safe(typeSub)); } return(changed ? signature.DeclaringType.Method(signature.Name, signature.CallConvention, newParams) : signature); Func <ModuleDef, TypeSig> Safe(TypeSig sig) => m => { if (module != m) { throw new ArgumentException("incompatible module"); } return(sig); }; }
IEnumerable <MethodDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); foreach (var method in type.Methods) { if (!method.HasBody) { continue; } foreach (var instr in method.Body.Instructions) { switch (instr.OpCode.Code) { case Code.Stfld: case Code.Stsfld: case Code.Ldflda: // Taking address of field -> potentially assign indirectly case Code.Ldsflda: break; default: continue; } if (instr.Operand is IField && comparer.Equals((IField)instr.Operand, Item)) { yield return(method); break; } } } }
/// <summary> /// Replaces all method references with the specified reference within the specified context. /// </summary> /// <param name="context">The current <see cref="DNContext"/>.</param> /// <param name="targetRef">The <see cref="MethodReference"/> to replace.</param> /// <param name="newRef">The <see cref="MethodReference"/> to replace targetRef with.</param> /// <param name="exitRecursion">Excludes recursive method calls from the replacement operation (may have undesired consequences with recursive methods).</param> public static void ReplaceAllMethodRefs(this IMethod targetRef, IMethod newRef, DNContext context, bool exitRecursion = true) { foreach (var tDef in context.PrimaryAssembly.ManifestModule.Types) { foreach (var mDef in tDef.Methods) { if (!mDef.HasBody) // abstract, runtime & external, etc { continue; } if (exitRecursion && mDef == newRef) // may have undesired consequences with recursive methods { continue; } foreach (var i in mDef.Body.Instructions) { if (i.Operand is IMethod && comp.Equals(targetRef, (IMethod)i.Operand)) { i.Operand = newRef; } } } } }
/// <summary> /// Checks if there's a constructor matching the specified signature /// in the source type or among the to-be-injected members /// </summary> /// <param name="sig">constructor signature</param> /// <returns>true if the matching constructor is found, false otherwise</returns> public bool HasInstanceCtor(MethodSig sig) { var sc = new SigComparer(); return(TypeMapping.Source.FindInstanceConstructors() .Concat(Injected.OfType <MethodDef>().Where(m => m.IsInstanceConstructor)) .Any(c => sc.Equals(c.MethodSig, sig))); }
public IEnumerable <object> Run(IApp app, CancellationToken token) { if (typeDef == null) { yield return(new AnalysisError("Failed to resolve '" + type.FullName + "'.")); yield break; } var comparer = new SigComparer(); if (typeDef.IsInterface) { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (!type.HasInterfaces) { continue; } foreach (var iface in type.Interfaces) { if (comparer.Equals(iface.Interface, typeDef)) { yield return(type); } } } } else { foreach (var type in app.Modules.GetModules().SelectMany(module => module.GetTypes())) { token.ThrowIfCancellationRequested(); if (comparer.Equals(type.BaseType, typeDef)) { yield return(type); } } } }
private static bool IsMatchingOverride(MethodOverride methodOverride, IMethodDefOrRef targetMethod) { SigComparer comparer = default; var targetDeclTypeDef = targetMethod.DeclaringType.ResolveTypeDef(); var overrideDeclTypeDef = methodOverride.MethodDeclaration.DeclaringType.ResolveTypeDef(); if (!comparer.Equals(targetDeclTypeDef, overrideDeclTypeDef)) { return(false); } var targetMethodSig = targetMethod.MethodSig; var overrideMethodSig = methodOverride.MethodDeclaration.MethodSig; targetMethodSig = ResolveGenericSignature(targetMethod, targetMethodSig); overrideMethodSig = ResolveGenericSignature(methodOverride.MethodDeclaration, overrideMethodSig); return(comparer.Equals(targetMethodSig, overrideMethodSig)); }
static bool Impl(MethodDef method, MethodDef ifaceMethod) { if (method.HasOverrides) { var comparer = new SigComparer(SigComparerOptions.CompareDeclaringTypes | SigComparerOptions.PrivateScopeIsComparable); if (method.Overrides.Any(m => comparer.Equals(m.MethodDeclaration, ifaceMethod))) return true; } if (method.Name != ifaceMethod.Name) return false; return TypesHierarchyHelpers.MatchInterfaceMethod(method, ifaceMethod, ifaceMethod.DeclaringType); }
IEnumerable <IMemberDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); if (comparer.Equals(type.BaseType, Item)) { yield return(type); } else if (type.Interfaces.Any(iface => comparer.Equals(iface.Interface, Item))) { yield return(type); } foreach (var method in type.Methods) { if (method.Parameters.Any(param => comparer.Equals(param.Type, Item))) { yield return(method); continue; } if (comparer.Equals(method.ReturnType, Item)) { yield return(method); continue; } if (!method.HasBody) { continue; } if (method.Body.Variables.Any(var => comparer.Equals(var.Type, Item))) { yield return(method); continue; } foreach (var instr in method.Body.Instructions) { if (instr.Operand is ITypeDefOrRef && comparer.Equals((ITypeDefOrRef)instr.Operand, Item)) { yield return(method); break; } else if (instr.Operand is IMemberRef && comparer.Equals(((IMemberRef)instr.Operand).DeclaringType, Item)) { yield return(method); break; } } } }
/// <summary> /// Finds all custom attributes of a certain type /// </summary> /// <param name="attrType">Custom attribute type</param> /// <param name="options">Attribute type comparison flags</param> /// <returns>All <see cref="CustomAttribute"/>s of the requested type</returns> public IEnumerable <CustomAttribute> FindAll(IType attrType, SigComparerOptions options) { var comparer = new SigComparer(options); foreach (var ca in this.GetSafeEnumerable()) { if (comparer.Equals(ca.AttributeType, attrType)) { yield return(ca); } } }
public static MethodDef[] GetMethods(this TypeDef type, string name, MethodFlags flags = MethodFlags.All, params ITypeDefOrRef[] arguments) { bool argsSpec = arguments != null && arguments.Length > 0; return(type.Methods.Where(md => { if (md.Name != name) { return false; } if (md.IsPublic && (flags & MethodFlags.Public) == 0) { return false; } if (!md.IsPublic && (flags & MethodFlags.NonPublic) == 0) { return false; } if (md.IsStatic && (flags & MethodFlags.Static) == 0) { return false; } if (!md.IsStatic && (flags & MethodFlags.Instance) == 0) { return false; } if (!argsSpec) { return true; } var start = md.IsStatic ? 0 : 1; if (arguments.Length + start != md.Parameters.Count) { return false; } for (int i = 0; i < arguments.Length; i++) { if (!comp.Equals(arguments[i], md.Parameters[i + start].Type)) { return false; } } return true; }).ToArray()); }
public override bool Equals(object obj) { if (!(obj is FuncSig other) || other.Flags != this.Flags) { return(false); } if (other.ParamSigs.Length != this.ParamSigs.Length) { return(false); } var comparer = new SigComparer(); for (int i = 0; i < this.ParamSigs.Length; i++) { if (!comparer.Equals(this.ParamSigs[i], other.ParamSigs[i])) { return(false); } } return(!comparer.Equals(this.RetType, other.RetType) ? false : true); }
private static bool IsMatchingOverride(MethodOverride methodOverride, IMethodDefOrRef targetMethod) { SigComparer comparer = default; var targetDeclTypeDef = targetMethod.DeclaringType.ResolveTypeDef(); var overrideDeclTypeDef = methodOverride.MethodDeclaration.DeclaringType.ResolveTypeDef(); if (!comparer.Equals(targetDeclTypeDef, overrideDeclTypeDef)) { return(false); } var targetMethodSig = targetMethod.MethodSig; var overrideMethodSig = methodOverride.MethodDeclaration.MethodSig; if (methodOverride.MethodDeclaration.DeclaringType is TypeSpec spec && spec.TypeSig is GenericInstSig genericInstSig) { overrideMethodSig = GenericArgumentResolver.Resolve(overrideMethodSig, genericInstSig.GenericArguments); } return(comparer.Equals(targetMethodSig, overrideMethodSig)); }
/// <summary> /// Finds a custom attribute /// </summary> /// <param name="attrType">Custom attribute type</param> /// <param name="options">Attribute type comparison flags</param> /// <returns>The first <see cref="CustomAttribute"/> found or <c>null</c> if none found</returns> public CustomAttribute Find(IType attrType, SigComparerOptions options) { var comparer = new SigComparer(options); foreach (var ca in this.GetSafeEnumerable()) { if (comparer.Equals(ca.AttributeType, attrType)) { return(ca); } } return(null); }
TypeDef FindSlow(TypeRef typeRef) { InitializeTypeEnumerator(); var comparer = new SigComparer(TypeComparerOptions); while (true) { var type = GetNextTypeDef(); if (type == null || comparer.Equals(type, typeRef)) { return(type); } } }
public bool IsAttachedTo(XamlType type) { if (type == null || ResolvedMember == null || type.ResolvedType == null) return true; var declType = ResolvedMember.DeclaringType; var t = type.ResolvedType; var comparer = new SigComparer(); do { if (comparer.Equals(t, declType)) return false; t = t.GetBaseType(); } while (t != null); return true; }
static bool Impl(MethodDef method, MethodDef ifaceMethod) { if (method.HasOverrides) { var comparer = new SigComparer(SigComparerOptions.CompareDeclaringTypes | SigComparerOptions.PrivateScopeIsComparable); if (method.Overrides.Any(m => comparer.Equals(m.MethodDeclaration, ifaceMethod))) { return(true); } } if (method.Name != ifaceMethod.Name) { return(false); } return(TypesHierarchyHelpers.MatchInterfaceMethod(method, ifaceMethod, ifaceMethod.DeclaringType)); }
/// <summary> /// Get the real decrypter method from a found helper method. /// </summary> /// <remarks>5.0</remarks> static MethodDef GetRealDecrypterMethod(MethodDef helper) { var methods = helper.DeclaringType.Methods; var sigComparer = new SigComparer(); foreach (var method in methods) { if (method.MDToken != helper.MDToken && method.IsAssembly && sigComparer.Equals(method.MethodSig, helper.MethodSig)) { return(method); } } return(null); }
public bool IsAttachedTo(XamlType type) { if (type is null || ResolvedMember is null || type.ResolvedType is null) { return(true); } var declType = ResolvedMember.DeclaringType; var t = type.ResolvedType; var comparer = new SigComparer(); do { if (comparer.Equals(t, declType)) { return(false); } t = t.GetBaseType(); } while (!(t is null)); return(true); }
TypeDef FindCache(TypeRef typeRef) { TypeDef cachedType; if (typeRefCache.TryGetValue(typeRef, out cachedType)) { return(cachedType); } // Build the cache lazily var comparer = new SigComparer(TypeComparerOptions); while (true) { cachedType = GetNextTypeDefCache(); if (cachedType == null || comparer.Equals(cachedType, typeRef)) { return(cachedType); } } }
object ConvertEnum <T>(TypeSig elemType, IList <CAArgument> oldList) { var ary = ConvertArray <EnumInfo>(elemType, oldList); var list = new T[ary.Length]; var sigComparer = new SigComparer(SigComparerOptions.CompareAssemblyPublicKeyToken); for (int i = 0; i < list.Length; i++) { if (ary[i].Value is T && sigComparer.Equals(elemType, ary[i].EnumType)) { list[i] = (T)ary[i].Value; } } return(new EnumInfo { EnumType = elemType.ToTypeDefOrRef(), Value = list, IsArray = true, }); }
IEnumerable <MethodDef> AnalyzeType(TypeDef type) { var comparer = new SigComparer(SigComparerOptions.CompareMethodFieldDeclaringType); foreach (var method in type.Methods) { if (!method.HasBody) { continue; } foreach (var instr in method.Body.Instructions) { if (instr.Operand is IMethod && comparer.Equals((IMethod)instr.Operand, Item)) { yield return(method); break; } } } }
public bool Equals(Instruction x, Instruction y) { var sigComparer = new SigComparer(); if (x != null && y != null && x.OpCode == y.OpCode) { if (x.Operand == null && y.Operand == null) { return(true); } if (x.Operand is FieldDef xFieldDef && y.Operand is FieldDef yFieldDef) { return(sigComparer.Equals(xFieldDef, yFieldDef)); } if (x.Operand is MemberRef xMemberRef && y.Operand is MemberRef yMemberRef) { return(sigComparer.Equals(xMemberRef, yMemberRef)); } if (x.Operand is IField xIField && y.Operand is IField yIField) { return(sigComparer.Equals(xIField, yIField)); } if (x.Operand is MethodSpec xMethodSpec && y.Operand is MethodSpec yMethodSpec) { return(sigComparer.Equals(xMethodSpec, yMethodSpec)); } if (x.Operand is MethodDef xMethodDef && y.Operand is MethodDef yMethodDef) { return(sigComparer.Equals(xMethodDef, yMethodDef)); } if (x.Operand is IMethod xIMethod && y.Operand is IMethod yIMethod) { return(sigComparer.Equals(xIMethod, yIMethod)); } if (x.Operand is TypeSpec xTypeSpec && y.Operand is TypeSpec yTypeSpec) { return(sigComparer.Equals(xTypeSpec, yTypeSpec)); } if (x.Operand is TypeSig xTypeSig && y.Operand is TypeSig yTypeSig) { return(sigComparer.Equals(xTypeSig, yTypeSig)); } if (x.Operand is MethodSig xMethodSig && y.Operand is MethodSig yMethodSig) { return(sigComparer.Equals(xMethodSig, yMethodSig)); } if (x.Operand is TypeRef xTypeRef && y.Operand is TypeRef yTypeRef) { return(sigComparer.Equals(xTypeRef, yTypeRef)); } if (x.Operand is TypeDef xTypeDef && y.Operand is TypeDef yTypeDef) { return(sigComparer.Equals(xTypeDef, yTypeDef)); } if (x.Operand is FieldSig xFieldSig && y.Operand is FieldSig yFieldSig) { return(sigComparer.Equals(xFieldSig, yFieldSig)); } if (x.Operand is ITypeDefOrRef xITypeDefOrRef && y.Operand is ITypeDefOrRef yITypeDefOrRef) { return(sigComparer.Equals(xITypeDefOrRef, yITypeDefOrRef)); } if (x.Operand is GenericInstMethodSig xGenericInstMethodSig && y.Operand is GenericInstMethodSig yGenericInstMethodSig) { return(sigComparer.Equals(xGenericInstMethodSig, yGenericInstMethodSig)); } if (x.Operand is IMemberRef xIMemberRef && y.Operand is IMemberRef yIMemberRef) { return(sigComparer.Equals(xIMemberRef, yIMemberRef)); } if (x.Operand is IType xIType && y.Operand is IType yIType) { return(sigComparer.Equals(xIType, yIType)); } if (x.Operand is EventDef xEventDef && y.Operand is EventDef yEventDef) { return(sigComparer.Equals(xEventDef, yEventDef)); } if (x.Operand is PropertyDef xPropertyDef && y.Operand is PropertyDef yPropertyDef) { return(sigComparer.Equals(xPropertyDef, yPropertyDef)); } if (x.Operand is ExportedType xExportedType && y.Operand is ExportedType yExportedType) { return(sigComparer.Equals(xExportedType, yExportedType)); } if (x.Operand is LocalSig xLocalSig && y.Operand is LocalSig yLocalSig) { return(sigComparer.Equals(xLocalSig, yLocalSig)); } if (x.Operand is IList <TypeSig> xIList && y.Operand is IList <TypeSig> yIList) { return(sigComparer.Equals(xIList, yIList)); } if (x.Operand is MethodBaseSig xMethodBaseSig && y.Operand is MethodBaseSig yMethodBaseSig) { return(sigComparer.Equals(xMethodBaseSig, yMethodBaseSig)); } if (x.Operand is CallingConventionSig xCallingConventionSig && y.Operand is CallingConventionSig yCallingConventionSig) { return(sigComparer.Equals(xCallingConventionSig, yCallingConventionSig)); } return(x.Operand == y.Operand); } return(false); }
MethodDef CreateFlagCtor(FlagDef flag, Func <MethodSig, bool> validator) { MethodSig sig; var cats = new List <Tuple <FieldDef, TypeSig> >(); var it = flag.Type; var sm = it.TypeMapping.Source.Module; do { var qarg = Rng.NextInt32(1, 5); cats.Add(Tuple.Create(flag.Field, flag.Field.FieldType)); var fq = new Queue <FieldDef>( it.TypeMapping.Source.Fields.Where(f => !f.IsStatic & !f.IsLiteral & !f.HasFieldRVA)); while (cats.Count < qarg) { if (fq.Count > 0) { var f = fq.Dequeue(); cats.Add(Tuple.Create(f, f.FieldType)); } else { cats.Add(Tuple.Create <FieldDef, TypeSig>(null, sm.CorLibTypes.Int32)); } } cats.Shuffle(Rng); var args = cats.Select(c => c.Item2).ToArray(); sig = MethodSig.CreateInstance(sm.CorLibTypes.Void, args); } while (!validator(sig)); var ctor = new MethodDefUser(".ctor", sig, MethodImplAttributes.IL | MethodImplAttributes.Managed, MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName | MethodAttributes.Public) { Body = new CilBody { MaxStack = 8 } }; var i = 0; foreach (var t in cats) { ctor.ParamDefs.Add(new ParamDefUser("a" + (i++), (ushort)i)); } var sc = new SigComparer(); IMethod baseCtor; var bc = it.Base?.Ctors.RandomElementOrDefault(Rng); var emitter = DnextFactory.NewILEmitter(sm); emitter.Emit(OpCodes.Ldarg_0); if (bc != null) { foreach (var pd in bc.Parameters) { if (pd.IsNormalMethodParameter) { var f = ctor.Parameters.FirstOrDefault(p => p.IsNormalMethodParameter && sc.Equals(p.Type, pd.Type)); if (f != null && Rng.NextBoolean()) { emitter.Ldarg(f); } else { Utils.RandomConst(emitter, pd.Type, Rng); } } } baseCtor = bc; } else { baseCtor = new MemberRefUser(sm, ".ctor", MethodSig.CreateInstance(sm.CorLibTypes.Void), sm.CorLibTypes.Object.TypeRef); } emitter.Call(baseCtor); Parameter flagpar = null; foreach (var p in ctor.Parameters) { if (p.IsNormalMethodParameter) { var t = cats[p.Index - 1]; if (t.Item1 != null) { emitter.Emit(OpCodes.Ldarg_0); emitter.Ldarg(p); emitter.Emit(Instruction.Create(OpCodes.Stfld, t.Item1)); if (t.Item1 == flag.Field) { flagpar = p; } } } } emitter.Emit(OpCodes.Ret); emitter.Replace(ctor.Body); flag.SetCtor(ctor, flagpar); return(ctor); }
TypeRef TryResolveType(TypeRef sourceRef, AssemblyRef scope, bool followForward) { if (scope == null) { return(null); } var typeRef = Import2(sourceRef, scope); var scopeDef = TargetModule.Context.AssemblyResolver.Resolve(typeRef.DefinitionAssembly, TargetModule); if (scopeDef != null) { if (scopeDef.TypeExists(typeRef)) { return(typeRef); } var sigComparer = new SigComparer(SigComparerOptions.DontCompareTypeScope); var exportType = scopeDef.Modules.SelectMany(m => m.ExportedTypes).Where(et => sigComparer.Equals(et, typeRef)).FirstOrDefault(); if (exportType != null) { if (followForward && (corelibRef == null || exportType.Implementation.Name != corelibRef.Name)) { return(exportType.ToTypeRef()); } else { return(typeRef); } } } return(null); }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { var declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } var genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); // Need to make sure we pop otherwise it will cause bugs resolver.PopMethodGenericArguments(); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition != desc.Definition || !comparer.Equals(mDesc.Signature, newSig)) { continue; } if (newSig.ContainsGenericParameter || newSig.GenParamCount > 0) { continue; } if (m.GenericArguments.Count != genericArgs.Count) { continue; } if (m.GenericArguments.Count > 0) { var failedGenericArgumentMatch = false; for (var i = 0; i < m.GenericArguments.Count; i++) { if (comparer.Equals(genericArguments[i], m.GenericArguments[i].GetTypeSig())) { continue; } failedGenericArgumentMatch = true; break; } if (failedGenericArgumentMatch) { continue; } } return(m); } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArgs) { hasOpening |= genericArg.HasOpenGenericParameter(); var t = GetType(genericArg); if (!_mosaMethod.GenericArguments.Contains(t)) { _mosaMethod.GenericArguments.Add(t); } } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }
TypeDef FindSlow(TypeRef typeRef) { InitializeTypeEnumerator(); var comparer = new SigComparer { Options = TypeComparerOptions }; while (true) { var type = GetNextTypeDef(); if (type == null || comparer.Equals(type, typeRef)) return type; } }
TypeDef FindCache(TypeRef typeRef) { TypeDef cachedType; if (typeRefCache.TryGetValue(typeRef, out cachedType)) return cachedType; // Build the cache lazily var comparer = new SigComparer { Options = TypeComparerOptions }; while (true) { cachedType = GetNextTypeDefCache(); if (cachedType == null || comparer.Equals(cachedType, typeRef)) return cachedType; } }
/// <summary> /// Get the real decrypter method from a found helper method. /// </summary> /// <remarks>5.0</remarks> static MethodDef GetRealDecrypterMethod(MethodDef helper) { var methods = helper.DeclaringType.Methods; var sigComparer = new SigComparer(); foreach (var method in methods) { if (method.MDToken != helper.MDToken && method.IsAssembly && sigComparer.Equals(method.MethodSig, helper.MethodSig)) return method; } return null; }
public MosaMethod LoadGenericMethodInstance(IMethodDefOrRef method, IList <TypeSig> genericArguments, GenericArgumentResolver resolver) { MosaType declType = GetType(resolver.Resolve(method.DeclaringType.ToTypeSig())); MDToken token; if (method is MethodDef) { token = ((MethodDef)method).MDToken; } else { token = ((MemberRef)method).ResolveMethodThrow().MDToken; } MosaMethod mosaMethod = null; UnitDesc <MethodDef, MethodSig> desc = null; foreach (var m in declType.Methods) { desc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (desc.Token.Token == token) { mosaMethod = m; break; } } if (mosaMethod == null) { throw new AssemblyLoadException(); } List <TypeSig> genericArgs = new List <TypeSig>(); foreach (var genericArg in genericArguments) { genericArgs.Add(resolver.Resolve(genericArg)); } resolver.PushMethodGenericArguments(genericArgs); // Check for existing generic method instance var newSig = resolver.Resolve(method.MethodSig); var comparer = new SigComparer(); foreach (var m in declType.Methods) { var mDesc = m.GetUnderlyingObject <UnitDesc <MethodDef, MethodSig> >(); if (mDesc.Definition == desc.Definition && comparer.Equals(mDesc.Signature, newSig)) { return(m); } } mosaMethod = metadata.Controller.CreateMethod(mosaMethod); using (var _mosaMethod = metadata.Controller.MutateMethod(mosaMethod)) { bool hasOpening = mosaMethod.DeclaringType.HasOpenGenericParams; foreach (var genericArg in genericArguments) { var newGenericArg = resolver.Resolve(genericArg); hasOpening |= newGenericArg.HasOpenGenericParameter(); _mosaMethod.GenericArguments.Add(GetType(newGenericArg)); } _mosaMethod.UnderlyingObject = desc.Clone(newSig); _mosaMethod.DeclaringType = declType; _mosaMethod.HasOpenGenericParams = hasOpening; } resolver.PopMethodGenericArguments(); using (var decl = metadata.Controller.MutateType(declType)) decl.Methods.Add(mosaMethod); metadata.Resolver.EnqueueForResolve(mosaMethod); return(mosaMethod); }
static TypeSig ICast/* needs a better name */ (TypeSig a, TypeSig b, ICorLibTypes ts) { if (comp.Equals(a, b)) { return(a); } if (comp.Equals(a, ts.String)) { return(a); } if (comp.Equals(b, ts.String)) { return(b); } if (comp.Equals(a, ts.IntPtr) || comp.Equals(a, ts.UIntPtr)) { return(a); } if (comp.Equals(b, ts.IntPtr) || comp.Equals(b, ts.UIntPtr)) { return(b); } if (comp.Equals(a, ts.Double)) { return(a); } if (comp.Equals(b, ts.Double)) { return(b); } if (comp.Equals(a, ts.Single)) { return(a); } if (comp.Equals(b, ts.Single)) { return(b); } if (comp.Equals(a, ts.Int64) || comp.Equals(a, ts.UInt64)) { return(a); } if (comp.Equals(b, ts.Int64) || comp.Equals(b, ts.UInt64)) { return(b); } if (!a.IsByRef || !b.IsByRef) { return(ts.Object); } var ad = a.ToTypeDefOrRef().ResolveTypeDefThrow(); var bd = b.ToTypeDefOrRef().ResolveTypeDefThrow(); if ((!ad.IsSequentialLayout || !ad.IsExplicitLayout) && (!bd.IsSequentialLayout || !bd.IsExplicitLayout)) { return(ts.IntPtr); } // close enough return(ad.PackingSize > bd.PackingSize ? a : b); }