diff --git a/Cpp2IL.Core/Cpp2IL.Core.csproj b/Cpp2IL.Core/Cpp2IL.Core.csproj index 3abe82ea..6b2dc001 100644 --- a/Cpp2IL.Core/Cpp2IL.Core.csproj +++ b/Cpp2IL.Core/Cpp2IL.Core.csproj @@ -40,8 +40,8 @@ - - + + diff --git a/Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs b/Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs index 08ae8118..3b899d98 100644 --- a/Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs +++ b/Cpp2IL.Core/OutputFormats/AsmResolverDummyDllOutputFormat.cs @@ -147,26 +147,26 @@ protected virtual void FillMethodBodies(AssemblyAnalysisContext context) private List BuildStubAssemblies(ApplicationAnalysisContext context) { - var assemblyResolver = new Il2CppAssemblyResolver(); - var metadataResolver = new DefaultMetadataResolver(assemblyResolver); - var corlib = context.Assemblies.First(a => a.Name == "mscorlib"); - MostRecentCorLib = BuildStubAssembly(corlib, null, metadataResolver); - assemblyResolver.DummyAssemblies.Add(MostRecentCorLib.Name!, MostRecentCorLib); + MostRecentCorLib = BuildStubAssembly(corlib, null, null); + + // The runtime info is irrelevant because we're creating our own corlib, but AsmResolver still requires that we specify one. + var runtimeContext = new RuntimeContext(DotNetRuntimeInfo.NetCoreApp(9, 0), (bool?)null, MostRecentCorLib); + runtimeContext.AddAssembly(MostRecentCorLib); + + context.PutExtraData("AsmResolverRuntimeContext", runtimeContext); var ret = context.Assemblies // .AsParallel() .Where(a => a.Name != "mscorlib") - .Select(a => BuildStubAssembly(a, MostRecentCorLib, metadataResolver)) + .Select(a => BuildStubAssembly(a, MostRecentCorLib, runtimeContext)) .ToList(); - ret.ForEach(a => assemblyResolver.DummyAssemblies.Add(a.Name!, a)); - ret.Add(MostRecentCorLib); return ret; } - private static AssemblyDefinition BuildStubAssembly(AssemblyAnalysisContext assemblyContext, AssemblyDefinition? corLib, IMetadataResolver metadataResolver) + private static AssemblyDefinition BuildStubAssembly(AssemblyAnalysisContext assemblyContext, AssemblyDefinition? corLib, RuntimeContext? runtimeContext) { //Get the name of the assembly (= the name of the DLL without the file extension) //Build an AsmResolver assembly from this definition @@ -182,12 +182,11 @@ private static AssemblyDefinition BuildStubAssembly(AssemblyAnalysisContext asse var moduleName = assemblyContext.CleanAssemblyName + ".dll"; //Use either ourself as corlib, if we are corlib, otherwise the provided one - var managedModule = new ModuleDefinition(moduleName, corLib is not null ? new(corLib) : null) - { - MetadataResolver = metadataResolver - }; + var managedModule = new ModuleDefinition(moduleName, corLib is not null ? new(corLib) : null); ourAssembly.Modules.Add(managedModule); + runtimeContext?.AddAssembly(ourAssembly); + foreach (var il2CppTypeDefinition in assemblyContext.TopLevelTypes) { if (il2CppTypeDefinition.Name != "") diff --git a/Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs b/Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs index d0428fa5..c49277e3 100644 --- a/Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs +++ b/Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs @@ -500,6 +500,7 @@ private static void CopyEventsInType(ReferenceImporter importer, TypeAnalysisCon public static void AddExplicitInterfaceImplementations(AssemblyAnalysisContext asmContext) { var managedAssembly = asmContext.GetExtraData("AsmResolverAssembly") ?? throw new("AsmResolver assembly not found in assembly analysis context for " + asmContext); + var runtimeContext = asmContext.AppContext.GetExtraData("AsmResolverRuntimeContext") ?? throw new("AsmResolver runtime context not found in application analysis context"); var importer = managedAssembly.ManifestModule!.DefaultImporter; @@ -514,7 +515,7 @@ public static void AddExplicitInterfaceImplementations(AssemblyAnalysisContext a try #endif { - AddExplicitInterfaceImplementations(managedType, typeContext, importer); + AddExplicitInterfaceImplementations(managedType, typeContext, importer, runtimeContext); } #if !DEBUG catch (Exception e) @@ -525,7 +526,7 @@ public static void AddExplicitInterfaceImplementations(AssemblyAnalysisContext a } } - private static void AddExplicitInterfaceImplementations(TypeDefinition type, TypeAnalysisContext typeContext, ReferenceImporter importer) + private static void AddExplicitInterfaceImplementations(TypeDefinition type, TypeAnalysisContext typeContext, ReferenceImporter importer, RuntimeContext runtimeContext) { List<(PropertyDefinition InterfaceProperty, TypeSignature InterfaceType, MethodDefinition Method)>? getMethodsToCreate = null; List<(PropertyDefinition InterfaceProperty, TypeSignature InterfaceType, MethodDefinition Method)>? setMethodsToCreate = null; @@ -540,20 +541,20 @@ private static void AddExplicitInterfaceImplementations(TypeDefinition type, Typ var interfaceMethod = (IMethodDefOrRef)overrideContext.ToMethodDescriptor(importer.TargetModule); var method = methodContext.GetExtraData("AsmResolverMethod") ?? throw new($"AsmResolver method not found in method analysis context for {methodContext}"); type.MethodImplementations.Add(new MethodImplementation(interfaceMethod, method)); - var interfaceMethodResolved = interfaceMethod.Resolve(); - if (interfaceMethodResolved != null) + var resolutionStatus = interfaceMethod.Resolve(runtimeContext, out var interfaceMethodResolved); + if (resolutionStatus == ResolutionStatus.Success && interfaceMethodResolved != null) { if (interfaceMethodResolved.IsGetMethod && !method.IsGetMethod) { getMethodsToCreate ??= []; var interfacePropertyResolved = interfaceMethodResolved.DeclaringType!.Properties.First(p => p.Semantics.Contains(interfaceMethodResolved.Semantics)); - getMethodsToCreate.Add((interfacePropertyResolved, interfaceMethod.DeclaringType!.ToTypeSignature(), method)); + getMethodsToCreate.Add((interfacePropertyResolved, interfaceMethod.DeclaringType!.ToTypeSignature(runtimeContext), method)); } else if (interfaceMethodResolved.IsSetMethod && !method.IsSetMethod) { setMethodsToCreate ??= []; var interfacePropertyResolved = interfaceMethodResolved.DeclaringType!.Properties.First(p => p.Semantics.Contains(interfaceMethodResolved.Semantics)); - setMethodsToCreate.Add((interfacePropertyResolved, interfaceMethod.DeclaringType!.ToTypeSignature(), method)); + setMethodsToCreate.Add((interfacePropertyResolved, interfaceMethod.DeclaringType!.ToTypeSignature(runtimeContext), method)); } } } @@ -566,7 +567,7 @@ private static void AddExplicitInterfaceImplementations(TypeDefinition type, Typ { var (interfaceProperty, interfaceType, getMethod) = entry; var setMethod = setMethodsToCreate? - .FirstOrDefault(e => e.InterfaceProperty == interfaceProperty && SignatureComparer.Default.Equals(e.InterfaceType, interfaceType)) + .FirstOrDefault(e => e.InterfaceProperty == interfaceProperty && runtimeContext.SignatureComparer.Equals(e.InterfaceType, interfaceType)) .Method; var name = $"{interfaceType.FullName}.{interfaceProperty.Name}"; @@ -583,7 +584,7 @@ private static void AddExplicitInterfaceImplementations(TypeDefinition type, Typ foreach (var entry in setMethodsToCreate) { var (interfaceProperty, interfaceType, setMethod) = entry; - if (getMethodsToCreate?.Any(e => e.InterfaceProperty == interfaceProperty && SignatureComparer.Default.Equals(e.InterfaceType, interfaceType)) == true) + if (getMethodsToCreate?.Any(e => e.InterfaceProperty == interfaceProperty && runtimeContext.SignatureComparer.Equals(e.InterfaceType, interfaceType)) == true) continue; var name = $"{interfaceType.FullName}.{interfaceProperty.Name}"; var propertySignature = setMethod.IsStatic diff --git a/Cpp2IL.Core/Utils/AsmResolver/AsmResolverUtils.cs b/Cpp2IL.Core/Utils/AsmResolver/AsmResolverUtils.cs index 862aee15..cc849ed1 100644 --- a/Cpp2IL.Core/Utils/AsmResolver/AsmResolverUtils.cs +++ b/Cpp2IL.Core/Utils/AsmResolver/AsmResolverUtils.cs @@ -143,7 +143,8 @@ public static TypeDefinition GetPrimitiveTypeDef(Il2CppTypeEnum type) => typeArguments[i] = typeArgument; } - return baseType.MakeGenericInstanceType(typeArguments); + var runtimeContext = Cpp2IlApi.CurrentAppContext!.GetExtraData("RuntimeContext") ?? throw new("AsmResolver runtime context not found in application analysis context"); + return baseType.MakeGenericInstanceType(runtimeContext, typeArguments); } private readonly record struct ParsedTypeString(string BaseType, string Suffix, string[] GenericArguments); diff --git a/Cpp2IL.Core/Utils/AsmResolver/ContextToTypeSignature.cs b/Cpp2IL.Core/Utils/AsmResolver/ContextToTypeSignature.cs index 6873ebd2..9a2127ed 100644 --- a/Cpp2IL.Core/Utils/AsmResolver/ContextToTypeSignature.cs +++ b/Cpp2IL.Core/Utils/AsmResolver/ContextToTypeSignature.cs @@ -17,7 +17,7 @@ private static TypeDefinition GetTypeDefinition(this TypeAnalysisContext context public static TypeSignature ToTypeSignature(this TypeAnalysisContext context, ModuleDefinition parentModule) => context switch { ReferencedTypeAnalysisContext referencedTypeAnalysisContext => referencedTypeAnalysisContext.ToTypeSignature(parentModule), - _ => parentModule.DefaultImporter.ImportType(context.GetTypeDefinition()).ToTypeSignature() + _ => parentModule.DefaultImporter.ImportType(context.GetTypeDefinition()).ToTypeSignature(parentModule.RuntimeContext) }; public static TypeSignature ToTypeSignature(this ReferencedTypeAnalysisContext context, ModuleDefinition parentModule) => context switch diff --git a/Cpp2IL.Core/Utils/AsmResolver/Il2CppAssemblyResolver.cs b/Cpp2IL.Core/Utils/AsmResolver/Il2CppAssemblyResolver.cs deleted file mode 100644 index bfe3daa5..00000000 --- a/Cpp2IL.Core/Utils/AsmResolver/Il2CppAssemblyResolver.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; -using AsmResolver.DotNet; - -namespace Cpp2IL.Core.Utils.AsmResolver; - -internal class Il2CppAssemblyResolver : IAssemblyResolver -{ - internal readonly Dictionary DummyAssemblies = new(); - - public AssemblyDefinition? Resolve(AssemblyDescriptor assembly) - { - if (DummyAssemblies.TryGetValue(assembly.Name!, out var ret)) - return ret; - - return null; - } - - public void AddToCache(AssemblyDescriptor descriptor, AssemblyDefinition definition) - { - //no-op - } - - public bool RemoveFromCache(AssemblyDescriptor descriptor) - { - //no-op - return true; - } - - public bool HasCached(AssemblyDescriptor descriptor) - { - return true; - } - - public void ClearCache() - { - //no-op - } -}