From decde80d81650801e5bc69798ab2942b42a00996 Mon Sep 17 00:00:00 2001 From: Jeremy Pritts <49847914+ds5678@users.noreply.github.com> Date: Sun, 17 Nov 2024 11:15:52 -0800 Subject: [PATCH] Add ContextToMethodDescriptor extension class (#376) --- .../AsmResolver/ContextToMethodDescriptor.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 Cpp2IL.Core/Utils/AsmResolver/ContextToMethodDescriptor.cs diff --git a/Cpp2IL.Core/Utils/AsmResolver/ContextToMethodDescriptor.cs b/Cpp2IL.Core/Utils/AsmResolver/ContextToMethodDescriptor.cs new file mode 100644 index 00000000..096b5e57 --- /dev/null +++ b/Cpp2IL.Core/Utils/AsmResolver/ContextToMethodDescriptor.cs @@ -0,0 +1,52 @@ +using System.Linq; +using AsmResolver.DotNet; +using AsmResolver.DotNet.Signatures; +using Cpp2IL.Core.Model.Contexts; + +namespace Cpp2IL.Core.Utils.AsmResolver; + +public static class ContextToMethodDescriptor +{ + private static MethodDefinition GetMethodDefinition(this MethodAnalysisContext context) + { + return context.GetExtraData("AsmResolverMethod") ?? throw new($"AsmResolver method not found in method analysis context for {context}"); + } + + private static MethodSignature ToMethodSignature(this MethodAnalysisContext context, ModuleDefinition parentModule) + { + var returnType = context.ReturnTypeContext.ToTypeSignature(parentModule); + var parameters = context.Parameters.Select(p => p.ToTypeSignature(parentModule)); + + var genericParameterCount = context.Definition?.GenericContainer?.genericParameterCount ?? 0; + + return context.IsStatic + ? MethodSignature.CreateStatic(returnType, genericParameterCount, parameters) + : MethodSignature.CreateInstance(returnType, genericParameterCount, parameters); + } + + public static IMethodDescriptor ToMethodDescriptor(this MethodAnalysisContext context, ModuleDefinition parentModule) + { + if (context is ConcreteGenericMethodAnalysisContext concreteMethod) + { + var memberReference = new MemberReference( + concreteMethod.DeclaringType?.ToTypeSignature(parentModule).ToTypeDefOrRef(), + concreteMethod.Name, + concreteMethod.BaseMethodContext.ToMethodSignature(parentModule)); + + var methodGenericParameters = concreteMethod.ResolveMethodGenericParameters(); + if (methodGenericParameters.Length == 0) + { + return parentModule.DefaultImporter.ImportMethod(memberReference); + } + else + { + var typeSignatures = methodGenericParameters.Select(p => p.ToTypeSignature(parentModule)).ToArray(); + return parentModule.DefaultImporter.ImportMethod(memberReference.MakeGenericInstanceMethod(typeSignatures)); + } + } + else + { + return parentModule.DefaultImporter.ImportMethod(context.GetMethodDefinition()); + } + } +}