[new] AOTGenericReferences打印出详细的泛型类型及函数签名

main
walon 2022-09-23 15:16:43 +08:00
parent aed13e464b
commit c76e68411f
6 changed files with 93 additions and 4 deletions

View File

@ -37,6 +37,8 @@ namespace HybridCLR.Editor.AOT
private readonly HashSet<string> _hotUpdateAssemblyFiles;
public ConstraintContext ConstraintContext { get; } = new ConstraintContext();
public List<GenericClass> AotGenericTypes { get; } = new List<GenericClass>();
public List<GenericMethod> AotGenericMethods { get; } = new List<GenericMethod>();
@ -195,7 +197,7 @@ namespace HybridCLR.Editor.AOT
private void FilterAOTGenericTypeAndMethods()
{
var cc = new ConstraintContext();
ConstraintContext cc = this.ConstraintContext;
AotGenericTypes.AddRange(_genericTypes.Where(type => IsAotType(type.Type)).Select(gc => cc.ApplyConstraints(gc)));
AotGenericMethods.AddRange(_genericMethods.Where(method => IsAotGenericMethod(method.Method)).Select(gm => cc.ApplyConstraints(gm)));
}

View File

@ -1,4 +1,5 @@
using HybridCLR.Editor.Meta;
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using System;
using System.Collections.Generic;
using System.Linq;
@ -7,8 +8,58 @@ using System.Threading.Tasks;
namespace HybridCLR.Editor.AOT
{
public class ConstraintContext
{
public class ImplType
{
public TypeSig BaseType { get; }
public List<TypeSig> Interfaces { get; }
public bool ValueType { get; }
private readonly int _hash;
public ImplType(TypeSig baseType, List<TypeSig> interfaces, bool valueType)
{
BaseType = baseType;
Interfaces = interfaces;
ValueType = valueType;
_hash = ComputHash();
}
public override bool Equals(object obj)
{
ImplType o = (ImplType)obj;
return EqualityUtil.EqualsTypeSig(this.BaseType, o.BaseType)
&& EqualityUtil.EqualsTypeSigArray(this.Interfaces, o.Interfaces)
&& this.ValueType == o.ValueType;
}
public override int GetHashCode()
{
return _hash;
}
private int ComputHash()
{
int hash = 0;
if (BaseType != null)
{
hash = HashUtil.CombineHash(hash, TypeEqualityComparer.Instance.GetHashCode(BaseType));
}
if (Interfaces.Count > 0)
{
hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(Interfaces));
}
return hash;
}
}
public HashSet<ImplType> ImplTypes { get; } = new HashSet<ImplType>();
public GenericClass ApplyConstraints(GenericClass gc)
{
return gc;

View File

@ -20,18 +20,28 @@ namespace HybridCLR.Editor.AOT
codes.Add("public class AOTGenericReferences : UnityEngine.MonoBehaviour");
codes.Add("{");
codes.Add("");
codes.Add("\t// {{ constraint implement type");
codes.Add("\t// }} ");
codes.Add("");
codes.Add("\t// {{ AOT generic type");
foreach(var type in types)
{
codes.Add($"\t//{type.Type}");
codes.Add($"\t//{type.ToTypeSig()}");
}
codes.Add("\t// }}");
codes.Add("");
codes.Add("\tpublic void RefMethods()");
codes.Add("\t{");
foreach(var method in methods)
{
codes.Add($"\t\t// {method.Method}");
codes.Add($"\t\t// {method.ToMethodSpec()}");
}
codes.Add("\t}");

View File

@ -9,6 +9,19 @@ namespace HybridCLR.Editor
{
public static class EqualityUtil
{
public static bool EqualsTypeSig(TypeSig a, TypeSig b)
{
if (a == b)
{
return true;
}
if (a != null && b != null)
{
return TypeEqualityComparer.Instance.Equals(a, b);
}
return false;
}
public static bool EqualsTypeSigArray(List<TypeSig> a, List<TypeSig> b)
{
if (a == b)

View File

@ -48,6 +48,11 @@ namespace HybridCLR.Editor.Meta
return hash;
}
public TypeSig ToTypeSig()
{
return new GenericInstSig(this.Type.ToTypeSig().ToClassOrValueTypeSig(), this.KlassInst);
}
public static GenericClass ResolveClass(TypeSpec type, GenericArgumentContext ctx)
{
var sig = type.TypeSig.ToGenericInstSig();

View File

@ -55,6 +55,14 @@ namespace HybridCLR.Editor.Meta
return hash;
}
public MethodSpec ToMethodSpec()
{
IMethodDefOrRef mt = KlassInst != null ?
(IMethodDefOrRef)new MemberRefUser(this.Method.Module, Method.Name, Method.MethodSig, new TypeSpecUser(new GenericInstSig(this.Method.DeclaringType.ToTypeSig().ToClassOrValueTypeSig(), this.KlassInst)))
: this.Method;
return new MethodSpecUser(mt, new GenericInstMethodSig(MethodInst));
}
public static GenericMethod ResolveMethod(IMethod method, GenericArgumentContext ctx)
{
//Debug.Log($"== resolve method:{method}");