using dnlib.DotNet; using HybridCLR.Editor.Meta; 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 a, List 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.IntPtr; case ElementType.ByRef: return corTypes.IntPtr; 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} 未能找到定义"); } 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} 未能找到定义"); } 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 ToShareTypeSigs(ICorLibTypes corTypes, IList typeSigs) { if (typeSigs == null) { return null; } return typeSigs.Select(s => ToShareTypeSig(corTypes, s)).ToList(); } public static IAssemblyResolver CreateHotUpdateAssemblyResolver(BuildTarget target, List 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(); 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 hotUpdateDlls) { return new CombinedAssemblyResolver( CreateHotUpdateAssemblyResolver(target, hotUpdateDlls), CreateAOTAssemblyResolver(target) ); } public static List CreateDefaultGenericParams(ModuleDef module, int genericParamCount) { var methodGenericParams = new List(); for (int i = 0; i < genericParamCount; i++) { methodGenericParams.Add(module.CorLibTypes.Object); } return methodGenericParams; } } }