[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; private readonly HashSet<string> _hotUpdateAssemblyFiles;
public ConstraintContext ConstraintContext { get; } = new ConstraintContext();
public List<GenericClass> AotGenericTypes { get; } = new List<GenericClass>(); public List<GenericClass> AotGenericTypes { get; } = new List<GenericClass>();
public List<GenericMethod> AotGenericMethods { get; } = new List<GenericMethod>(); public List<GenericMethod> AotGenericMethods { get; } = new List<GenericMethod>();
@ -195,7 +197,7 @@ namespace HybridCLR.Editor.AOT
private void FilterAOTGenericTypeAndMethods() private void FilterAOTGenericTypeAndMethods()
{ {
var cc = new ConstraintContext(); ConstraintContext cc = this.ConstraintContext;
AotGenericTypes.AddRange(_genericTypes.Where(type => IsAotType(type.Type)).Select(gc => cc.ApplyConstraints(gc))); 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))); 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;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@ -7,8 +8,58 @@ using System.Threading.Tasks;
namespace HybridCLR.Editor.AOT namespace HybridCLR.Editor.AOT
{ {
public class ConstraintContext 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) public GenericClass ApplyConstraints(GenericClass gc)
{ {
return gc; return gc;

View File

@ -20,18 +20,28 @@ namespace HybridCLR.Editor.AOT
codes.Add("public class AOTGenericReferences : UnityEngine.MonoBehaviour"); codes.Add("public class AOTGenericReferences : UnityEngine.MonoBehaviour");
codes.Add("{"); 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) 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("\tpublic void RefMethods()");
codes.Add("\t{"); codes.Add("\t{");
foreach(var method in methods) foreach(var method in methods)
{ {
codes.Add($"\t\t// {method.Method}"); codes.Add($"\t\t// {method.ToMethodSpec()}");
} }
codes.Add("\t}"); codes.Add("\t}");

View File

@ -9,6 +9,19 @@ namespace HybridCLR.Editor
{ {
public static class EqualityUtil 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) public static bool EqualsTypeSigArray(List<TypeSig> a, List<TypeSig> b)
{ {
if (a == b) if (a == b)

View File

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

View File

@ -55,6 +55,14 @@ namespace HybridCLR.Editor.Meta
return hash; 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) public static GenericMethod ResolveMethod(IMethod method, GenericArgumentContext ctx)
{ {
//Debug.Log($"== resolve method:{method}"); //Debug.Log($"== resolve method:{method}");