[fix] 修复计算桥接函数时未考虑到补充元数据泛型实例化会导致访问到一些非公开的函数的情况,导致少生成一些必要的桥接函数

main
walon 2023-06-07 11:47:17 +08:00
parent adbdbf3a00
commit c462aeb2ef
6 changed files with 31 additions and 8 deletions

View File

@ -136,7 +136,7 @@ namespace HybridCLR.Editor.ABI
(int typeSize, int typeAligment) = ComputeSizeAndAligment(type); (int typeSize, int typeAligment) = ComputeSizeAndAligment(type);
if (TryCreateCustomValueTypeInfo(type, typeSize, typeAligment, out var typeInfo)) if (TryCreateCustomValueTypeInfo(type, typeSize, typeAligment, out var typeInfo))
{ {
Debug.Log($"[{GetType().Name}] CustomeValueType:{type} => {typeInfo.CreateSigName()}"); //Debug.Log($"[{GetType().Name}] CustomeValueType:{type} => {typeInfo.CreateSigName()}");
return typeInfo; return typeInfo;
} }
else else

View File

@ -79,7 +79,7 @@ namespace HybridCLR.Editor.AOT
return IsAotType(method.DeclaringType) && method.HasGenericParameters; return IsAotType(method.DeclaringType) && method.HasGenericParameters;
} }
private void OnNewMethod(GenericMethod method) private void OnNewMethod(MethodDef methodDef, List<TypeSig> klassGenericInst, List<TypeSig> methodGenericInst, GenericMethod method)
{ {
if(method == null) if(method == null)
{ {

View File

@ -37,6 +37,7 @@ namespace HybridCLR.Editor.Commands
OutputFile = outputFile, OutputFile = outputFile,
GenericMethods = analyzer.GenericMethods, GenericMethods = analyzer.GenericMethods,
NotGenericMethods = analyzer.NotGenericMethods, NotGenericMethods = analyzer.NotGenericMethods,
SpeicalPreserveMethods = analyzer.SpeicalPreserveMethods,
}); });
g.PrepareMethods(); g.PrepareMethods();

View File

@ -1,4 +1,5 @@
using dnlib.DotNet; using dnlib.DotNet;
using HybridCLR.Editor.ABI;
using System; using System;
using System.Collections.Concurrent; using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
@ -10,11 +11,11 @@ namespace HybridCLR.Editor.Meta
{ {
public class MethodReferenceAnalyzer public class MethodReferenceAnalyzer
{ {
private readonly Action<GenericMethod> _onNewMethod; private readonly Action<MethodDef, List<TypeSig>, List<TypeSig>, GenericMethod> _onNewMethod;
private readonly ConcurrentDictionary<MethodDef, List<IMethod>> _methodEffectInsts = new ConcurrentDictionary<MethodDef, List<IMethod>>(); private readonly ConcurrentDictionary<MethodDef, List<IMethod>> _methodEffectInsts = new ConcurrentDictionary<MethodDef, List<IMethod>>();
public MethodReferenceAnalyzer(Action<GenericMethod> onNewMethod) public MethodReferenceAnalyzer(Action<MethodDef, List<TypeSig>, List<TypeSig>, GenericMethod> onNewMethod)
{ {
_onNewMethod = onNewMethod; _onNewMethod = onNewMethod;
} }
@ -37,7 +38,7 @@ namespace HybridCLR.Editor.Meta
foreach (var met in effectInsts) foreach (var met in effectInsts)
{ {
var resolveMet = GenericMethod.ResolveMethod(met, ctx)?.ToGenericShare(); var resolveMet = GenericMethod.ResolveMethod(met, ctx)?.ToGenericShare();
_onNewMethod(resolveMet); _onNewMethod(method, klassGenericInst, methodGenericInst, resolveMet);
} }
return; return;
} }
@ -69,7 +70,7 @@ namespace HybridCLR.Editor.Meta
continue; continue;
} }
effectInsts.Add(met); effectInsts.Add(met);
_onNewMethod(resolveMet); _onNewMethod(method, klassGenericInst, methodGenericInst, resolveMet);
break; break;
} }
case ITokenOperand token: case ITokenOperand token:

View File

@ -30,6 +30,8 @@ namespace HybridCLR.Editor.MethodBridge
private readonly HashSet<GenericClass> _genericTypes = new HashSet<GenericClass>(); private readonly HashSet<GenericClass> _genericTypes = new HashSet<GenericClass>();
private readonly HashSet<GenericMethod> _genericMethods = new HashSet<GenericMethod>(); private readonly HashSet<GenericMethod> _genericMethods = new HashSet<GenericMethod>();
private readonly HashSet<GenericMethod> _speicalPreserveMethods = new HashSet<GenericMethod>();
private List<GenericMethod> _processingMethods = new List<GenericMethod>(); private List<GenericMethod> _processingMethods = new List<GenericMethod>();
private List<GenericMethod> _newMethods = new List<GenericMethod>(); private List<GenericMethod> _newMethods = new List<GenericMethod>();
@ -37,6 +39,8 @@ namespace HybridCLR.Editor.MethodBridge
public IReadOnlyList<MethodDef> NotGenericMethods => _notGenericMethods; public IReadOnlyList<MethodDef> NotGenericMethods => _notGenericMethods;
public HashSet<GenericMethod> SpeicalPreserveMethods => _speicalPreserveMethods;
public IReadOnlyCollection<GenericClass> GenericTypes => _genericTypes; public IReadOnlyCollection<GenericClass> GenericTypes => _genericTypes;
public IReadOnlyCollection<GenericMethod> GenericMethods => _genericMethods; public IReadOnlyCollection<GenericMethod> GenericMethods => _genericMethods;
@ -67,7 +71,7 @@ namespace HybridCLR.Editor.MethodBridge
} }
} }
private void OnNewMethod(GenericMethod method) private void OnNewMethod(MethodDef methodDef, List<TypeSig> klassGenericInst, List<TypeSig> methodGenericInst, GenericMethod method)
{ {
lock(_lock) lock(_lock)
{ {
@ -75,6 +79,10 @@ namespace HybridCLR.Editor.MethodBridge
{ {
_newMethods.Add(method); _newMethods.Add(method);
} }
if (methodDef.HasGenericParameters)
{
_speicalPreserveMethods.Add(method);
}
if (method.KlassInst != null) if (method.KlassInst != null)
{ {
TryAddAndWalkGenericType(new GenericClass(method.Method.DeclaringType, method.KlassInst)); TryAddAndWalkGenericType(new GenericClass(method.Method.DeclaringType, method.KlassInst));

View File

@ -4,6 +4,7 @@ using HybridCLR.Editor.Meta;
using HybridCLR.Editor.Template; using HybridCLR.Editor.Template;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
@ -28,6 +29,8 @@ namespace HybridCLR.Editor.MethodBridge
public IReadOnlyList<MethodDef> NotGenericMethods { get; set; } public IReadOnlyList<MethodDef> NotGenericMethods { get; set; }
public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; } public IReadOnlyCollection<GenericMethod> GenericMethods { get; set; }
public HashSet<GenericMethod> SpeicalPreserveMethods { get; set; }
} }
private PlatformABI _platformABI; private PlatformABI _platformABI;
@ -36,6 +39,8 @@ namespace HybridCLR.Editor.MethodBridge
private readonly IReadOnlyCollection<GenericMethod> _genericMethods; private readonly IReadOnlyCollection<GenericMethod> _genericMethods;
private readonly HashSet<GenericMethod> _preservedMethods;
private readonly string _templateCode; private readonly string _templateCode;
private readonly string _outputFile; private readonly string _outputFile;
@ -61,6 +66,7 @@ namespace HybridCLR.Editor.MethodBridge
_platformABI = options.PlatformABI; _platformABI = options.PlatformABI;
_notGenericMethods = options.NotGenericMethods; _notGenericMethods = options.NotGenericMethods;
_genericMethods = options.GenericMethods; _genericMethods = options.GenericMethods;
_preservedMethods = options.SpeicalPreserveMethods;
_templateCode = options.TemplateCode; _templateCode = options.TemplateCode;
_outputFile = options.OutputFile; _outputFile = options.OutputFile;
_platformAdaptor = CreatePlatformAdaptor(options.PlatformABI); _platformAdaptor = CreatePlatformAdaptor(options.PlatformABI);
@ -121,9 +127,16 @@ namespace HybridCLR.Editor.MethodBridge
private void ProcessMethod(MethodDef method, List<TypeSig> klassInst, List<TypeSig> methodInst) private void ProcessMethod(MethodDef method, List<TypeSig> klassInst, List<TypeSig> methodInst)
{ {
if (method.IsPrivate || (method.IsAssembly && !method.IsPublic && !method.IsFamily)) if (method.IsPrivate || (method.IsAssembly && !method.IsPublic && !method.IsFamily))
{
if (!_preservedMethods.Contains(new GenericMethod(method, klassInst, methodInst)))
{ {
return; return;
} }
else
{
//Debug.Log($"[PreservedMethod] method:{method}");
}
}
TypeSig returnType; TypeSig returnType;
List<TypeSig> parameters; List<TypeSig> parameters;