上传新的package

This commit is contained in:
2025-04-11 10:35:10 +08:00
parent 2511dc60dc
commit f7e101d56e
290 changed files with 195 additions and 170 deletions

View File

@@ -0,0 +1,20 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class AssemblyCache : AssemblyCacheBase
{
public AssemblyCache(IAssemblyResolver assemblyResolver) : base(assemblyResolver)
{
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c9916e9cd98115a4e813f9d227f4d524
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,107 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public abstract class AssemblyCacheBase : IDisposable
{
private readonly IAssemblyResolver _assemblyPathResolver;
private readonly ModuleContext _modCtx;
private readonly AssemblyResolver _asmResolver;
private bool disposedValue;
private bool _loadedNetstandard;
public Dictionary<string, ModuleDefMD> LoadedModules { get; } = new Dictionary<string, ModuleDefMD>();
private readonly List<ModuleDefMD> _loadedModulesIncludeNetstandard = new List<ModuleDefMD>();
protected AssemblyCacheBase(IAssemblyResolver assemblyResolver)
{
_assemblyPathResolver = assemblyResolver;
_modCtx = ModuleDef.CreateModuleContext();
_asmResolver = (AssemblyResolver)_modCtx.AssemblyResolver;
_asmResolver.EnableTypeDefCache = true;
_asmResolver.UseGAC = false;
}
public ModuleDefMD LoadModule(string moduleName, bool loadReferenceAssemblies = true)
{
// Debug.Log($"load module:{moduleName}");
if (LoadedModules.TryGetValue(moduleName, out var mod))
{
return mod;
}
if (moduleName == "netstandard")
{
if (!_loadedNetstandard)
{
LoadNetStandard();
}
return null;
}
mod = DoLoadModule(_assemblyPathResolver.ResolveAssembly(moduleName, true));
LoadedModules.Add(moduleName, mod);
if (loadReferenceAssemblies)
{
foreach (var refAsm in mod.GetAssemblyRefs())
{
LoadModule(refAsm.Name);
}
}
return mod;
}
private void LoadNetStandard()
{
string netstandardDllPath = _assemblyPathResolver.ResolveAssembly("netstandard", false);
if (!string.IsNullOrEmpty(netstandardDllPath))
{
DoLoadModule(netstandardDllPath);
}
else
{
DoLoadModule(MetaUtil.ResolveNetStandardAssemblyPath("netstandard2.0"));
DoLoadModule(MetaUtil.ResolveNetStandardAssemblyPath("netstandard2.1"));
}
_loadedNetstandard = true;
}
private ModuleDefMD DoLoadModule(string dllPath)
{
//Debug.Log($"do load module:{dllPath}");
ModuleDefMD mod = ModuleDefMD.Load(dllPath, _modCtx);
_asmResolver.AddToCache(mod);
_loadedModulesIncludeNetstandard.Add(mod);
return mod;
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
foreach (var mod in _loadedModulesIncludeNetstandard)
{
mod.Dispose();
}
_loadedModulesIncludeNetstandard.Clear();
LoadedModules.Clear();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e640f5657ae667947b7330b660191943
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,50 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class AssemblyReferenceDeepCollector : AssemblyCacheBase
{
private readonly List<string> _rootAssemblies;
public IReadOnlyList<string> GetRootAssemblyNames()
{
return _rootAssemblies;
}
public List<ModuleDefMD> GetLoadedModulesExcludeRootAssemblies()
{
return LoadedModules.Where(e => !_rootAssemblies.Contains(e.Key)).Select(e => e.Value).ToList();
}
public List<ModuleDefMD> GetLoadedModules()
{
return LoadedModules.Select(e => e.Value).ToList();
}
public List<ModuleDefMD> GetLoadedModulesOfRootAssemblies()
{
return _rootAssemblies.Select(ass => LoadedModules[ass]).ToList();
}
public AssemblyReferenceDeepCollector(IAssemblyResolver assemblyResolver, List<string> rootAssemblies) : base(assemblyResolver)
{
_rootAssemblies = rootAssemblies;
LoadAllAssembiles();
}
private void LoadAllAssembiles()
{
foreach (var asm in _rootAssemblies)
{
LoadModule(asm);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8242ecc75b20deb489e7d9cadbb4d478
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public abstract class AssemblyResolverBase : IAssemblyResolver
{
public string ResolveAssembly(string assemblyName, bool throwExIfNotFind)
{
if (TryResolveAssembly(assemblyName, out string assemblyPath))
{
return assemblyPath;
}
if (throwExIfNotFind)
{
if (SettingsUtil.HotUpdateAssemblyNamesIncludePreserved.Contains(assemblyName))
{
throw new Exception($"resolve Hot update dll:{assemblyName} failed! Please make sure that this hot update dll exists or the search path is configured in the external hot update path.");
}
else
{
throw new Exception($"resolve AOT dll:{assemblyName} failed! Please make sure that the AOT project has referenced the dll and generated the trimmed AOT dll correctly.");
}
}
return null;
}
protected abstract bool TryResolveAssembly(string assemblyName, out string assemblyPath);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd22e83fb27da4d49a6a22b4e724b789
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public class CombinedAssemblyResolver : AssemblyResolverBase
{
private readonly IAssemblyResolver[] _resolvers;
public CombinedAssemblyResolver(params IAssemblyResolver[] resolvers)
{
_resolvers = resolvers;
}
protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath)
{
foreach(var resolver in _resolvers)
{
var assembly = resolver.ResolveAssembly(assemblyName, false);
if (assembly != null)
{
assemblyPath = assembly;
return true;
}
}
assemblyPath = null;
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e5b98951f11c35e44884fea72fb99e56
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,37 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class FixedSetAssemblyResolver : AssemblyResolverBase
{
private readonly string _rootDir;
private readonly HashSet<string> _fileNames;
public FixedSetAssemblyResolver(string rootDir, IEnumerable<string> fileNameNotExts)
{
_rootDir = rootDir;
_fileNames = new HashSet<string>(fileNameNotExts);
}
protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath)
{
if (_fileNames.Contains(assemblyName))
{
assemblyPath = $"{_rootDir}/{assemblyName}.dll";
if (File.Exists(assemblyPath))
{
Debug.Log($"[FixedSetAssemblyResolver] resolve:{assemblyName} path:{assemblyPath}");
return true;
}
}
assemblyPath = null;
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5b53789283b21a240a8fa65b68900dfe
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,104 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
/// <summary>
/// Replaces generic type/method var with its generic argument
/// </summary>
public sealed class GenericArgumentContext
{
List<TypeSig> typeArgsStack = new List<TypeSig>();
List<TypeSig> methodArgsStack = new List<TypeSig>();
public GenericArgumentContext(List<TypeSig> typeArgsStack, List<TypeSig> methodArgsStack)
{
this.typeArgsStack = typeArgsStack;
this.methodArgsStack = methodArgsStack;
}
/// <summary>
/// Replaces a generic type/method var with its generic argument (if any). If
/// <paramref name="typeSig"/> isn't a generic type/method var or if it can't
/// be resolved, it itself is returned. Else the resolved type is returned.
/// </summary>
/// <param name="typeSig">Type signature</param>
/// <returns>New <see cref="TypeSig"/> which is never <c>null</c> unless
/// <paramref name="typeSig"/> is <c>null</c></returns>
public TypeSig Resolve(TypeSig typeSig)
{
if (!typeSig.ContainsGenericParameter)
{
return typeSig;
}
typeSig = typeSig.RemovePinnedAndModifiers();
switch (typeSig.ElementType)
{
case ElementType.Ptr: return new PtrSig(Resolve(typeSig.Next));
case ElementType.ByRef: return new PtrSig(Resolve(typeSig.Next));
case ElementType.SZArray: return new PtrSig(Resolve(typeSig.Next));
case ElementType.Array:
{
var ara = (ArraySig)typeSig;
return new ArraySig(Resolve(typeSig.Next), ara.Rank, ara.Sizes, ara.LowerBounds);
}
case ElementType.Var:
{
GenericVar genericVar = (GenericVar)typeSig;
var newSig = Resolve(typeArgsStack, genericVar.Number, true);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.MVar:
{
GenericMVar genericVar = (GenericMVar)typeSig;
var newSig = Resolve(methodArgsStack, genericVar.Number, true);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.GenericInst:
{
var gia = (GenericInstSig)typeSig;
return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => Resolve(ga)).ToList());
}
case ElementType.FnPtr:
{
throw new NotSupportedException(typeSig.ToString());
}
case ElementType.ValueArray:
{
var vas = (ValueArraySig)typeSig;
return new ValueArraySig(Resolve(vas.Next), vas.Size);
}
default: return typeSig;
}
}
private TypeSig Resolve(List<TypeSig> args, uint number, bool isTypeVar)
{
var typeSig = args[(int)number];
var gvar = typeSig as GenericSig;
if (gvar is null || gvar.IsTypeVar != isTypeVar)
return typeSig;
return gvar;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8fb1ac43c73a55e4d98e853efca62e46
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,74 @@
using dnlib.DotNet;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class GenericClass
{
public TypeDef Type { get; }
public List<TypeSig> KlassInst { get; }
private readonly int _hashCode;
public GenericClass(TypeDef type, List<TypeSig> classInst)
{
Type = type;
KlassInst = classInst;
_hashCode = ComputHashCode();
}
public GenericClass ToGenericShare()
{
return new GenericClass(Type, MetaUtil.ToShareTypeSigs(Type.Module.CorLibTypes, KlassInst));
}
public override bool Equals(object obj)
{
if (obj is GenericClass gc)
{
return Type == gc.Type && MetaUtil.EqualsTypeSigArray(KlassInst, gc.KlassInst);
}
return false;
}
public override int GetHashCode()
{
return _hashCode;
}
private int ComputHashCode()
{
int hash = TypeEqualityComparer.Instance.GetHashCode(Type);
if (KlassInst != null)
{
hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(KlassInst));
}
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();
if (sig == null)
{
return null;
}
TypeDef def = type.ResolveTypeDef();
if (def == null)
{
Debug.LogWarning($"type:{type} ResolveTypeDef() == null");
return null;
}
var klassInst = ctx != null ? sig.GenericArguments.Select(ga => MetaUtil.Inflate(ga, ctx)).ToList() : sig.GenericArguments.ToList();
return new GenericClass(def, klassInst);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 72167574ca223e34cb0b704882225877
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,109 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class GenericMethod
{
public MethodDef Method { get; }
public List<TypeSig> KlassInst { get; }
public List<TypeSig> MethodInst { get; }
private readonly int _hashCode;
public GenericMethod(MethodDef method, List<TypeSig> classInst, List<TypeSig> methodInst)
{
Method = method;
KlassInst = classInst;
MethodInst = methodInst;
_hashCode = ComputHashCode();
}
public GenericMethod ToGenericShare()
{
ICorLibTypes corLibTypes = Method.Module.CorLibTypes;
return new GenericMethod(Method, MetaUtil.ToShareTypeSigs(corLibTypes, KlassInst), MetaUtil.ToShareTypeSigs(corLibTypes, MethodInst));
}
public override bool Equals(object obj)
{
GenericMethod o = (GenericMethod)obj;
return Method == o.Method
&& MetaUtil.EqualsTypeSigArray(KlassInst, o.KlassInst)
&& MetaUtil.EqualsTypeSigArray(MethodInst, o.MethodInst);
}
public override int GetHashCode()
{
return _hashCode;
}
public override string ToString()
{
return $"{Method}|{string.Join(",", (IEnumerable<TypeSig>)KlassInst ?? Array.Empty<TypeSig>())}|{string.Join(",", (IEnumerable<TypeSig>)MethodInst ?? Array.Empty<TypeSig>())}";
}
private int ComputHashCode()
{
int hash = MethodEqualityComparer.CompareDeclaringTypes.GetHashCode(Method);
if (KlassInst != null)
{
hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(KlassInst));
}
if (MethodInst != null)
{
hash = HashUtil.CombineHash(hash, HashUtil.ComputHash(MethodInst));
}
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}");
TypeDef typeDef = null;
List<TypeSig> klassInst = null;
List<TypeSig> methodInst = null;
MethodDef methodDef = null;
var decalringType = method.DeclaringType;
typeDef = decalringType.ResolveTypeDef();
if (typeDef == null)
{
return null;
}
GenericInstSig gis = decalringType.TryGetGenericInstSig();
if (gis != null)
{
klassInst = ctx != null ? gis.GenericArguments.Select(ga => MetaUtil.Inflate(ga, ctx)).ToList() : gis.GenericArguments.ToList();
}
methodDef = method.ResolveMethodDef();
if (methodDef == null)
{
Debug.LogWarning($"method:{method} ResolveMethodDef() == null");
return null;
}
if (method is MethodSpec methodSpec)
{
methodInst = ctx != null ? methodSpec.GenericInstMethodSig.GenericArguments.Select(ga => MetaUtil.Inflate(ga, ctx)).ToList()
: methodSpec.GenericInstMethodSig.GenericArguments.ToList();
}
return new GenericMethod(methodDef, klassInst, methodInst);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 5110d4398a0b6504c94ed3c37b0da2e9
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public interface IAssemblyResolver
{
string ResolveAssembly(string assemblyName, bool throwExIfNotFind);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7cbf06fa49b97cf48a56cb6aeefc7563
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,193 @@
using dnlib.DotNet;
using HybridCLR.Editor.Meta;
using HybridCLR.Editor.Settings;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEditor;
namespace HybridCLR.Editor.Meta
{
public static class MetaUtil
{
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)
{
return true;
}
if (a != null && b != null)
{
if (a.Count != b.Count)
{
return false;
}
for (int i = 0; i < a.Count; i++)
{
if (!TypeEqualityComparer.Instance.Equals(a[i], b[i]))
{
return false;
}
}
return true;
}
return false;
}
public static TypeSig Inflate(TypeSig sig, GenericArgumentContext ctx)
{
if (!sig.ContainsGenericParameter)
{
return sig;
}
return ctx.Resolve(sig);
}
public static TypeSig ToShareTypeSig(ICorLibTypes corTypes, TypeSig typeSig)
{
var a = typeSig.RemovePinnedAndModifiers();
switch (a.ElementType)
{
case ElementType.Void: return corTypes.Void;
case ElementType.Boolean: return corTypes.Byte;
case ElementType.Char: return corTypes.UInt16;
case ElementType.I1: return corTypes.SByte;
case ElementType.U1:return corTypes.Byte;
case ElementType.I2: return corTypes.Int16;
case ElementType.U2: return corTypes.UInt16;
case ElementType.I4: return corTypes.Int32;
case ElementType.U4: return corTypes.UInt32;
case ElementType.I8: return corTypes.Int64;
case ElementType.U8: return corTypes.UInt64;
case ElementType.R4: return corTypes.Single;
case ElementType.R8: return corTypes.Double;
case ElementType.String: return corTypes.Object;
case ElementType.TypedByRef: return corTypes.TypedReference;
case ElementType.I: return corTypes.IntPtr;
case ElementType.U: return corTypes.UIntPtr;
case ElementType.Object: return corTypes.Object;
case ElementType.Sentinel: return typeSig;
case ElementType.Ptr: return corTypes.UIntPtr;
case ElementType.ByRef: return corTypes.UIntPtr;
case ElementType.SZArray: return corTypes.Object;
case ElementType.Array: return corTypes.Object;
case ElementType.ValueType:
{
TypeDef typeDef = a.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef == null)
{
throw new Exception($"type:{a} definition could not be found");
}
if (typeDef.IsEnum)
{
return ToShareTypeSig(corTypes, typeDef.GetEnumUnderlyingType());
}
return typeSig;
}
case ElementType.Var:
case ElementType.MVar:
case ElementType.Class: return corTypes.Object;
case ElementType.GenericInst:
{
var gia = (GenericInstSig)a;
TypeDef typeDef = gia.GenericType.ToTypeDefOrRef().ResolveTypeDef();
if (typeDef == null)
{
throw new Exception($"type:{a} definition could not be found");
}
if (typeDef.IsEnum)
{
return ToShareTypeSig(corTypes, typeDef.GetEnumUnderlyingType());
}
if (!typeDef.IsValueType)
{
return corTypes.Object;
}
return new GenericInstSig(gia.GenericType, gia.GenericArguments.Select(ga => ToShareTypeSig(corTypes, ga)).ToList());
}
case ElementType.FnPtr: return corTypes.IntPtr;
case ElementType.ValueArray: return typeSig;
case ElementType.Module: return typeSig;
default:
throw new NotSupportedException(typeSig.ToString());
}
}
public static List<TypeSig> ToShareTypeSigs(ICorLibTypes corTypes, IList<TypeSig> typeSigs)
{
if (typeSigs == null)
{
return null;
}
return typeSigs.Select(s => ToShareTypeSig(corTypes, s)).ToList();
}
public static IAssemblyResolver CreateHotUpdateAssemblyResolver(BuildTarget target, List<string> hotUpdateDlls)
{
var externalDirs = HybridCLRSettings.Instance.externalHotUpdateAssembliyDirs;
var defaultHotUpdateOutputDir = SettingsUtil.GetHotUpdateDllsOutputDirByTarget(target);
IAssemblyResolver defaultHotUpdateResolver = new FixedSetAssemblyResolver(defaultHotUpdateOutputDir, hotUpdateDlls);
if (externalDirs == null || externalDirs.Length == 0)
{
return defaultHotUpdateResolver;
}
else
{
var resolvers = new List<IAssemblyResolver>();
foreach (var dir in externalDirs)
{
resolvers.Add(new FixedSetAssemblyResolver($"{dir}/{target}", hotUpdateDlls));
resolvers.Add(new FixedSetAssemblyResolver(dir, hotUpdateDlls));
}
resolvers.Add(defaultHotUpdateResolver);
return new CombinedAssemblyResolver(resolvers.ToArray());
}
}
public static IAssemblyResolver CreateAOTAssemblyResolver(BuildTarget target)
{
return new PathAssemblyResolver(SettingsUtil.GetAssembliesPostIl2CppStripDir(target));
}
public static IAssemblyResolver CreateHotUpdateAndAOTAssemblyResolver(BuildTarget target, List<string> hotUpdateDlls)
{
return new CombinedAssemblyResolver(
CreateHotUpdateAssemblyResolver(target, hotUpdateDlls),
CreateAOTAssemblyResolver(target)
);
}
public static string ResolveNetStandardAssemblyPath(string assemblyName)
{
return $"{SettingsUtil.HybridCLRDataPathInPackage}/NetStandard/{assemblyName}.dll";
}
public static List<TypeSig> CreateDefaultGenericParams(ModuleDef module, int genericParamCount)
{
var methodGenericParams = new List<TypeSig>();
for (int i = 0; i < genericParamCount; i++)
{
methodGenericParams.Add(module.CorLibTypes.Object);
}
return methodGenericParams;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a2e0aa5795138414ea5139e7691e0185
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,79 @@
using dnlib.DotNet;
using HybridCLR.Editor.ABI;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public class MethodReferenceAnalyzer
{
private readonly Action<MethodDef, List<TypeSig>, List<TypeSig>, GenericMethod> _onNewMethod;
private readonly ConcurrentDictionary<MethodDef, List<IMethod>> _methodEffectInsts = new ConcurrentDictionary<MethodDef, List<IMethod>>();
public MethodReferenceAnalyzer(Action<MethodDef, List<TypeSig>, List<TypeSig>, GenericMethod> onNewMethod)
{
_onNewMethod = onNewMethod;
}
public void WalkMethod(MethodDef method, List<TypeSig> klassGenericInst, List<TypeSig> methodGenericInst)
{
var ctx = new GenericArgumentContext(klassGenericInst, methodGenericInst);
if (_methodEffectInsts.TryGetValue(method, out var effectInsts))
{
foreach (var met in effectInsts)
{
var resolveMet = GenericMethod.ResolveMethod(met, ctx)?.ToGenericShare();
_onNewMethod(method, klassGenericInst, methodGenericInst, resolveMet);
}
return;
}
var body = method.Body;
if (body == null || !body.HasInstructions)
{
return;
}
effectInsts = new List<IMethod>();
foreach (var inst in body.Instructions)
{
if (inst.Operand == null)
{
continue;
}
switch (inst.Operand)
{
case IMethod met:
{
if (!met.IsMethod)
{
continue;
}
var resolveMet = GenericMethod.ResolveMethod(met, ctx)?.ToGenericShare();
if (resolveMet == null)
{
continue;
}
effectInsts.Add(met);
_onNewMethod(method, klassGenericInst, methodGenericInst, resolveMet);
break;
}
case ITokenOperand token:
{
//GenericParamContext paramContext = method.HasGenericParameters || method.DeclaringType.HasGenericParameters ?
// new GenericParamContext(method.DeclaringType, method) : default;
//method.Module.ResolveToken(token.MDToken, paramContext);
break;
}
}
}
_methodEffectInsts.TryAdd(method, effectInsts);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c41435d2422e114eac193c405264d1d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,35 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
namespace HybridCLR.Editor.Meta
{
public class PathAssemblyResolver : AssemblyResolverBase
{
private readonly string[] _searchPaths;
public PathAssemblyResolver(params string[] searchPaths)
{
_searchPaths = searchPaths;
}
protected override bool TryResolveAssembly(string assemblyName, out string assemblyPath)
{
foreach(var path in _searchPaths)
{
string assPath = Path.Combine(path, assemblyName + ".dll");
if (File.Exists(assPath))
{
Debug.Log($"resolve {assemblyName} at {assPath}");
assemblyPath = assPath;
return true;
}
}
assemblyPath = null;
return false;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 94848f63e75d660448de23b230886219
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: