接入obfuz->2.0

This commit is contained in:
Alex-Rachel
2025-07-26 08:10:41 +08:00
parent f2c7ff4336
commit cb86d8868e
713 changed files with 57092 additions and 10 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: fa4650e79a52228488aa85e0690ca52c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,99 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public abstract class AssemblyCacheBase
{
private readonly IAssemblyResolver _assemblyPathResolver;
private readonly ModuleContext _modCtx;
private readonly AssemblyResolver _asmResolver;
private bool _loadedNetstandard;
public ModuleContext ModCtx => _modCtx;
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 TryLoadModule(string moduleName, bool loadReferenceAssemblies = true)
{
string dllPath = _assemblyPathResolver.ResolveAssembly(moduleName, false);
if (string.IsNullOrEmpty(dllPath))
{
return null;
}
return LoadModule(moduleName, loadReferenceAssemblies);
}
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(File.ReadAllBytes(dllPath), _modCtx);
mod.EnableTypeDefFindCache = true;
_asmResolver.AddToCache(mod);
_loadedModulesIncludeNetstandard.Add(mod);
return mod;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3b01fa99119e72141bfee5628c0ffce1
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: 0342c7d8575fdea49896260c77285286
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: 5f8d48774b790364cbd36f1f68fd6614
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,105 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public class AssemblySorter
{
class Node
{
public string Name;
public List<Node> Dependencies = new List<Node>();
public Node(string name)
{
Name = name;
}
}
class TopologicalSorter
{
public static List<Node> Sort(List<Node> nodes)
{
List<Node> sorted = new List<Node>();
HashSet<Node> visited = new HashSet<Node>();
HashSet<Node> tempMarks = new HashSet<Node>();
foreach (var node in nodes)
{
if (!visited.Contains(node))
{
Visit(node, visited, tempMarks, sorted);
}
}
return sorted;
}
private static void Visit(Node node, HashSet<Node> visited, HashSet<Node> tempMarks, List<Node> sorted)
{
if (tempMarks.Contains(node))
{
throw new Exception("Detected cyclic dependency!");
}
if (!visited.Contains(node))
{
tempMarks.Add(node);
foreach (var dependency in node.Dependencies)
{
Visit(dependency, visited, tempMarks, sorted);
}
tempMarks.Remove(node);
visited.Add(node);
sorted.Add(node);
}
}
}
private static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, Dictionary<string, HashSet<string>> refs)
{
var nodes = new List<Node>();
var nodeMap = new Dictionary<string, Node>();
foreach (var assembly in assemblies)
{
var node = new Node(assembly);
nodes.Add(node);
nodeMap.Add(assembly, node);
}
foreach (var assembly in assemblies)
{
var node = nodeMap[assembly];
foreach (var refAssembly in refs[assembly])
{
node.Dependencies.Add(nodeMap[refAssembly]);
}
}
var sortedNodes = TopologicalSorter.Sort(nodes);
return sortedNodes.Select(node => node.Name).ToList();
}
public static List<string> SortAssemblyByReferenceOrder(IEnumerable<string> assemblies, IAssemblyResolver assemblyResolver)
{
var assCache = new AssemblyCache(assemblyResolver);
var assRefAssemblies = new Dictionary<string, HashSet<string>>();
foreach (var assName in assemblies)
{
var refAssemblies = new HashSet<string>();
var mod = assCache.LoadModule(assName, false);
foreach (var refAss in mod.GetAssemblyRefs())
{
if (assemblies.Contains(refAss.Name.ToString()))
{
refAssemblies.Add(refAss.Name.ToString());
}
}
assRefAssemblies.Add(assName, refAssemblies);
}
return SortAssemblyByReferenceOrder(assemblies, assRefAssemblies);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b9b8eb45398fa344daa8c6e9b9fbf291
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: 89b83906438c52d4b9af4aaef055f177
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,43 @@
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 = $"{_rootDir}/{assemblyName}.dll.bytes";
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: f135accd10f42c64b9735c3aa8cb1e77
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,110 @@
using dnlib.DotNet;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HybridCLR.Editor.Meta
{
public class GenericArgumentContext
{
private readonly List<TypeSig> typeArgsStack;
private readonly List<TypeSig> methodArgsStack;
public GenericArgumentContext(List<TypeSig> typeArgsStack, List<TypeSig> methodArgsStack)
{
this.typeArgsStack = typeArgsStack;
this.methodArgsStack = methodArgsStack;
}
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 ByRefSig(Resolve(typeSig.Next));
case ElementType.SZArray: return new SZArraySig(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);
if (newSig == null)
{
throw new Exception();
}
return newSig;
}
case ElementType.MVar:
{
GenericMVar genericVar = (GenericMVar)typeSig;
var newSig = Resolve(methodArgsStack, genericVar.Number);
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:
{
var fptr = (FnPtrSig)typeSig;
var cs = fptr.Signature;
CallingConventionSig ccs;
switch (cs)
{
case MethodSig ms:
{
ccs = new MethodSig(ms.GetCallingConvention(), ms.GenParamCount, Resolve(ms.RetType), ms.Params.Select(p => Resolve(p)).ToList());
break;
}
case PropertySig ps:
{
ccs = new PropertySig(ps.HasThis, Resolve(ps.RetType));
break;
}
case GenericInstMethodSig gims:
{
ccs = new GenericInstMethodSig(gims.GenericArguments.Select(ga => Resolve(ga)).ToArray());
break;
}
default: throw new NotSupportedException(cs.ToString());
}
return new FnPtrSig(ccs);
}
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)
{
return args[(int)number];
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 07595a9b5b2f54c44a67022ae3e077d4
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: c95ff173013909548bd9e2008812f9ff
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: 88ecf3d52ec393b4cac142518944e487
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: f962a018018dbb945a19f82d2e098686
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,217 @@
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.UIntPtr;
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;
}
public static bool IsSupportedPInvokeTypeSig(TypeSig typeSig)
{
typeSig = typeSig.RemovePinnedAndModifiers();
if (typeSig.IsByRef)
{
return true;
}
switch (typeSig.ElementType)
{
case ElementType.SZArray:
case ElementType.Array:
//case ElementType.Class:
case ElementType.String:
//case ElementType.Object:
return false;
default: return true;
}
}
public static bool IsSupportedPInvokeMethodSignature(MethodSig methodSig)
{
return IsSupportedPInvokeTypeSig(methodSig.RetType) && methodSig.Params.All(p => IsSupportedPInvokeTypeSig(p));
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f3dbfe2e8b6a92742b18e287c5d281dd
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: 1c644b0c018fb87498d69c3202439d21
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,40 @@
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)
{
assemblyPath = Path.Combine(path, $"{assemblyName}.dll");
if (File.Exists(assemblyPath))
{
Debug.Log($"resolve {assemblyName} at {assemblyPath}");
return true;
}
assemblyPath = Path.Combine(path, $"{assemblyName}.dll.bytes");
if (File.Exists(assemblyPath))
{
Debug.Log($"resolve {assemblyName} at {assemblyPath}");
return true;
}
}
assemblyPath = null;
return false;
}
}
}

View File

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