private static MethodDef LookupMethod(IMethodDefOrRef method, ModuleDefMD sourceAssembly) { TypeDef type = sourceAssembly.Types.SingleOrDefault(x => x.FullName == method.DeclaringType.FullName); return type?.FindMethod(method.Name, method.MethodSig, SigComparerOptions.PrivateScopeMethodIsComparable); }
public MethodAndOverride(MethodDef targetMethod, IMethodDefOrRef methodDeclaration) { TargetMethod = targetMethod; MethodDeclaration = methodDeclaration; }
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git) { if (git == null) return method; return Create(method, git.GenericArguments); }
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList<TypeSig> genericMethodArgs) { return Create(method, git == null ? null : git.GenericArguments, genericMethodArgs); }
public static void ApplyObjectCreationProxy(ITypeService service, ScannedItem parentItem, IList <Instruction> body, ref int index, IMethodDefOrRef operand) { if (operand.MethodSig.Params.Count > 0) { return; } //Not supporeted yet var proxyMethod = ObjectCreationFactory.Instance.GetCreationMethod(operand.MethodSig.Params.Count); if (proxyMethod == null) { return; //No factory for this parameter number (probaby disabled) } var typeSig = operand.DeclaringType.ToTypeSig(); if (parentItem != null) { typeSig = parentItem.ToGenericIfAvalible(typeSig); } body[index].OpCode = OpCodes.Call; body[index].Operand = new MethodSpecUser(proxyMethod, new GenericInstMethodSig(typeSig)); }
public MMethodDef FindMethod(IMethodDefOrRef md) { return methods.Find(md); }
public MethodInst(MMethodDef origMethodDef, IMethodDefOrRef methodRef) { this.origMethodDef = origMethodDef; this.methodRef = methodRef; }
/// <summary> /// Constructor /// </summary> /// <param name="methodBody">Method body</param> /// <param name="methodDeclaration">The method <paramref name="methodBody"/> implements</param> public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) { this.MethodBody = methodBody; this.MethodDeclaration = methodDeclaration; }
public MMethodDef FindMethod(IMethodDefOrRef md) { return(methods.Find(md)); }
void InitializeInterfaceMethods(MethodNameGroups groups) { InitializeAllInterfaces(); if (TypeDef.IsInterface) { return; } //--- Partition II 12.2 Implementing virtual methods on interfaces: //--- The VES shall use the following algorithm to determine the appropriate //--- implementation of an interface's virtual abstract methods: //--- //--- * If the base class implements the interface, start with the same virtual methods //--- that it provides; otherwise, create an interface that has empty slots for all //--- virtual functions. // Done. See initializeAllInterfaces(). var methodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.DontCompareDeclaringTypes); //--- * If this class explicitly specifies that it implements the interface (i.e., the //--- interfaces that appear in this class‘ InterfaceImpl table, §22.23) //--- * If the class defines any public virtual newslot methods whose name and //--- signature match a virtual method on the interface, then use these new virtual //--- methods to implement the corresponding interface method. if (interfaces.Count > 0) { methodsDict.Clear(); foreach (var method in methods.GetValues()) { if (!method.IsPublic() || !method.IsVirtual() || !method.IsNewSlot()) { continue; } methodsDict[method.MethodDef] = method; } foreach (var ifaceInfo in interfaces) { foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods()) { if (methodsList.Count < 1) { continue; } var methodInst = methodsList[0]; var ifaceMethod = methodInst.origMethodDef; if (!ifaceMethod.IsVirtual()) { continue; } var ifaceMethodRef = GenericArgsSubstitutor.Create(methodInst.methodRef, ifaceInfo.typeRef.TryGetGenericInstSig()); MMethodDef classMethod; if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod)) { continue; } interfaceMethodInfos.AddMethod(ifaceInfo, ifaceMethod, classMethod); } } } //--- * If there are any virtual methods in the interface that still have empty slots, //--- see if there are any public virtual methods, but not public virtual newslot //--- methods, available on this class (directly or inherited) having the same name //--- and signature, then use these to implement the corresponding methods on the //--- interface. methodsDict.Clear(); foreach (var methodInstList in virtualMethodInstances.GetMethods()) { // This class' method is at the end for (int i = methodInstList.Count - 1; i >= 0; i--) { var classMethod = methodInstList[i]; // These methods are guaranteed to be virtual. // We should allow newslot methods, despite what the official doc says. if (!classMethod.origMethodDef.IsPublic()) { continue; } methodsDict[classMethod.methodRef] = classMethod.origMethodDef; break; } } foreach (var ifaceInfo in allImplementedInterfaces.Keys) { foreach (var methodsList in ifaceInfo.typeDef.virtualMethodInstances.GetMethods()) { if (methodsList.Count < 1) { continue; } var ifaceMethod = methodsList[0].origMethodDef; if (!ifaceMethod.IsVirtual()) { continue; } var ifaceMethodRef = GenericArgsSubstitutor.Create(ifaceMethod.MethodDef, ifaceInfo.typeRef.TryGetGenericInstSig()); MMethodDef classMethod; if (!methodsDict.TryGetValue(ifaceMethodRef, out classMethod)) { continue; } interfaceMethodInfos.AddMethodIfEmpty(ifaceInfo, ifaceMethod, classMethod); } } //--- * Apply all MethodImpls that are specified for this class, thereby placing //--- explicitly specified virtual methods into the interface in preference to those //--- inherited or chosen by name matching. methodsDict.Clear(); var ifaceMethodsDict = new Dictionary <IMethodDefOrRef, MMethodDef>(MethodEqualityComparer.CompareDeclaringTypes); foreach (var ifaceInfo in allImplementedInterfaces.Keys) { var git = ifaceInfo.typeRef.TryGetGenericInstSig(); foreach (var ifaceMethod in ifaceInfo.typeDef.methods.GetValues()) { IMethodDefOrRef ifaceMethodRef = ifaceMethod.MethodDef; if (git != null) { ifaceMethodRef = SimpleClone(ifaceMethod.MethodDef, ifaceInfo.typeRef); } ifaceMethodsDict[ifaceMethodRef] = ifaceMethod; } } foreach (var classMethod in methods.GetValues()) { if (!classMethod.IsVirtual()) { continue; } foreach (var overrideMethod in classMethod.MethodDef.Overrides) { MMethodDef ifaceMethod; if (!ifaceMethodsDict.TryGetValue(overrideMethod.MethodDeclaration, out ifaceMethod)) { // We couldn't find the interface method (eg. interface not resolved) or // it overrides a base class method, and not an interface method. continue; } interfaceMethodInfos.AddMethod(overrideMethod.MethodDeclaration.DeclaringType, ifaceMethod, classMethod); } } //--- * If the current class is not abstract and there are any interface methods that //--- still have empty slots, then the program is invalid. // Check it anyway. C# requires a method, even if it's abstract. I don't think anyone // writes pure CIL assemblies. foreach (var info in interfaceMethodInfos.AllInfos) { foreach (var pair in info.IfaceMethodToClassMethod) { if (pair.Value != null) { continue; } if (!ResolvedAllInterfaces() || !ResolvedBaseClasses()) { continue; } // Ignore if COM class if (!TypeDef.IsImport && !HasAttribute("System.Runtime.InteropServices.ComImportAttribute") && !HasAttribute("System.Runtime.InteropServices.TypeLibTypeAttribute")) { Logger.w("Could not find interface method {0} ({1:X8}). Type: {2} ({3:X8})", Utils.RemoveNewlines(pair.Key.methodDef.MethodDef), pair.Key.methodDef.MethodDef.MDToken.ToInt32(), Utils.RemoveNewlines(TypeDef), TypeDef.MDToken.ToInt32()); } } } foreach (var info in interfaceMethodInfos.AllInfos) { foreach (var pair in info.IfaceMethodToClassMethod) { if (pair.Value == null) { continue; } if (pair.Key.methodDef.MethodDef.Name != pair.Value.MethodDef.Name) { continue; } groups.Same(pair.Key.methodDef, pair.Value); } } }
public bool ShouldCallInternal(IMethodDefOrRef method, FacelessValue[] args) { return(OnInternalCall?.Invoke(null, method, args) ?? true); }
public bool ShouldCallExternal(IMethodDefOrRef method, object[] args) { return(OnExternalCall?.Invoke(null, method, args) ?? true); }
/// <summary> /// Gets the advice handled interfaces. /// This is done by analyzing method body /// </summary> /// <param name="methodDefinition">The method definition.</param> /// <param name="invokedMethod">The invoked method.</param> /// <param name="genericParameterIndex">Index of the generic parameter.</param> /// <returns></returns> private static IEnumerable <Tuple <ITypeDefOrRef, MethodDef> > GetAdviceHandledInterfaces(MethodDef methodDefinition, IMethodDefOrRef invokedMethod, int genericParameterIndex) { foreach (var instruction in methodDefinition.Body.Instructions) { if (instruction.OpCode == OpCodes.Call || instruction.OpCode == OpCodes.Calli || instruction.OpCode == OpCodes.Callvirt) { var invokedMethodReference = (IMethod)instruction.Operand; if (invokedMethodReference.NumberOfGenericParameters > 0 && invokedMethodReference.SafeEquivalent(invokedMethod)) { var methodSpec = (MethodSpec)invokedMethodReference; var advisedInterface = methodSpec.GenericInstMethodSig.GenericArguments[genericParameterIndex]; //Logger.WriteDebug("Found Advice to '{0}'", advisedInterface); yield return(Tuple.Create(advisedInterface.ToTypeDefOrRef(), methodDefinition)); } } } }
/// <summary> /// Constructor /// </summary> /// <param name="method">The generic method</param> public MethodSpecUser(IMethodDefOrRef method) : this(method, null) { }
public MethodOverrideOptions(MethodOverride mo) { MethodBody = mo.MethodBody; MethodDeclaration = mo.MethodDeclaration; }
/// <summary> /// Gets the advice handled interfaces. /// This is done by analyzing calls in all methods from module /// </summary> /// <param name="moduleDefinition">The module definition.</param> /// <param name="invokedMethod">The invoked method.</param> /// <param name="genericParameterIndex">Index of the generic parameter.</param> /// <returns></returns> private static IEnumerable <Tuple <ITypeDefOrRef, MethodDef> > GetAdviceHandledInterfaces(ModuleDef moduleDefinition, IMethodDefOrRef invokedMethod, int genericParameterIndex) { return(moduleDefinition.GetTypes().SelectMany(t => t.Methods.Where(m => m.HasBody) .SelectMany(definition => GetAdviceHandledInterfaces(definition, invokedMethod, genericParameterIndex)))); }
private void StartRecurseThread(IMethodDefOrRef cleanMethod, IMethodDefOrRef obfMethod) => StartRecurseThread(cleanMethod?.ResolveMethodDef(), obfMethod?.ResolveMethodDef());
public Instructions Emit(OpCode opCode, IMethodDefOrRef value) { return(Insert(Instruction.Create(opCode, value))); }
public List<MethodInst> Lookup(IMethodDefOrRef methodRef) { List<MethodInst> list; methodInstances.TryGetValue(methodRef, out list); return list; }
public static IMethodDefOrRef Create(IMethodDefOrRef method, IList <TypeSig> genericArgs) { return(Create(method, genericArgs, null)); }
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList <TypeSig> genericMethodArgs) { return(Create(method, git == null ? null : git.GenericArguments, genericMethodArgs)); }
public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs) { return Create(method, genericArgs, null); }
/// <summary> /// Constructor /// </summary> /// <param name="method">The referenced method</param> public PdbForwardModuleInfoCustomDebugInfo(IMethodDefOrRef method) { this.method = method; }
// Creates a new method but keeps declaring type as is public static IMethodDefOrRef Create(IMethodDefOrRef method, IList<TypeSig> genericArgs, IList<TypeSig> genericMethodArgs) { if (method == null) return method; if ((genericArgs == null || genericArgs.Count == 0) && (genericMethodArgs == null || genericMethodArgs.Count == 0)) return method; var sig = method.MethodSig; if (sig == null) return method; var newSig = new GenericArgsSubstitutor(genericArgs, genericMethodArgs).Create(sig); if (newSig == sig) return method; return new MemberRefUser(method.DeclaringType.Module, method.Name, newSig, method.DeclaringType); }
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) { 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(); _mosaMethod.GenericArguments.Add(GetType(genericArg)); } _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); }
public MethodSpecOptions(MethodSpec ms) { this.Method = ms.Method; this.Instantiation = ms.Instantiation; this.CustomAttributes.AddRange(ms.CustomAttributes); }
/// <summary> /// Constructor /// </summary> /// <param name="methodBody">Method body</param> /// <param name="methodDeclaration">The method <paramref name="methodBody"/> implements</param> public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) { MethodBody = methodBody; MethodDeclaration = methodDeclaration; }
private void PopulateEverythingWithData() { // Populate types foreach (var kvp in _processedTypes) { var originalTypeDef = kvp.Value.OriginalDef; var hookTypeDef = kvp.Value.HookDef; if (originalTypeDef.BaseType != null) // original has basetype && original's basetype is already processed { hookTypeDef.BaseType = FindHookTypeDef(originalTypeDef.BaseType); } if (originalTypeDef.HasInterfaces) { foreach (var originalInterface in originalTypeDef.Interfaces) { hookTypeDef.Interfaces.Add(new InterfaceImplUser(FindHookTypeDef(originalInterface.Interface))); } hookTypeDef.BaseType = FindHookTypeDef(originalTypeDef.BaseType); } if (originalTypeDef.HasGenericParameters) { foreach (var originalParam in originalTypeDef.GenericParameters) { hookTypeDef.GenericParameters.Add(new GenericParamUser(originalParam.Number, GenericParamAttributes.NoSpecialConstraint, originalParam.Name)); } } } // Populate fields foreach (var kvp in _processedFields) { if (kvp.OriginalDef.FieldType != null) { kvp.HookDef.FieldType = FindHookTypeSig(kvp.OriginalDef.FieldType); } } // Populate methods foreach (var kvp in _processedMethods) { var originalMethodDef = kvp.OriginalDef; var hookMethodDef = kvp.HookDef; hookMethodDef.MethodSig = CreateHookMethodSig(originalMethodDef.MethodSig); if (originalMethodDef.HasParamDefs) { var originalParamDefs = originalMethodDef.ParamDefs; var hookParamDefs = hookMethodDef.ParamDefs; foreach (var originalParam in originalParamDefs) { hookParamDefs.Add(new ParamDefUser(originalParam.Name, originalParam.Sequence, originalParam.Attributes)); } } if (originalMethodDef.HasGenericParameters) { foreach (var originalParam in originalMethodDef.GenericParameters) { hookMethodDef.GenericParameters.Add(new GenericParamUser(originalParam.Number, GenericParamAttributes.NoSpecialConstraint, originalParam.Name)); } } if (originalMethodDef.Overrides.Count > 0) { var hookOverrides = new List <MethodOverride>(); foreach (var @override in originalMethodDef.Overrides) { IMethodDefOrRef newOverrideMethod = null; if (@override.MethodDeclaration.IsSystemType()) { newOverrideMethod = @override.MethodDeclaration; var overrideTypeSig = newOverrideMethod.DeclaringType.ToTypeSig(); var genSig = overrideTypeSig.ToGenericInstSig(); if (!(genSig is null)) { var genArgs = genSig.GenericArguments; var newTypeSigs = new List <TypeSig>(); foreach (var genArg in genArgs) { var newTypeDef = _processedTypes.FirstOrDefault(x => x.Value.HookDef.FullName == genArg.FullName).Value.HookDef; newTypeSigs.Add(newTypeDef.ToTypeSig()); } genArgs.Clear(); // Remove old args genArgs.AddRange(newTypeSigs); } } else { newOverrideMethod = _processedMethods.FirstOrDefault(x => x.HookDef.FullName == @override.MethodDeclaration.FullName).HookDef; } if (newOverrideMethod != null) { hookOverrides.Add(new MethodOverride(hookMethodDef, newOverrideMethod)); } } hookMethodDef.Overrides.AddRange(hookOverrides); } } }
/// <summary> /// Constructor /// </summary> /// <param name="method">The generic method</param> /// <param name="sig">The instantiated method sig</param> public MethodSpecUser(IMethodDefOrRef method, GenericInstMethodSig sig) { this.method = method; this.instantiation = sig; }
public static IMethodDefOrRef Create(IMethodDefOrRef method, GenericInstSig git, IList <TypeSig> genericMethodArgs) => Create(method, git?.GenericArguments, genericMethodArgs);