Skip to content

Commit

Permalink
Port generator to use AsmResolver (#124)
Browse files Browse the repository at this point in the history
  • Loading branch information
ds5678 authored Sep 8, 2024
1 parent 63e3948 commit 06cd048
Show file tree
Hide file tree
Showing 72 changed files with 2,321 additions and 2,026 deletions.
17 changes: 3 additions & 14 deletions Il2CppInterop.CLI/Utils.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
using Mono.Cecil;
using AsmResolver.DotNet;

namespace Il2CppInterop;

internal static class Utils
{
public static List<AssemblyDefinition> LoadAssembliesFrom(DirectoryInfo directoryInfo)
{
var resolver = new BasicResolver();
var inputAssemblies = directoryInfo.EnumerateFiles("*.dll").Select(f => AssemblyDefinition.ReadAssembly(
f.FullName,
new ReaderParameters { AssemblyResolver = resolver })).ToList();
foreach (var assembly in inputAssemblies)
{
resolver.Register(assembly);
}
var inputAssemblies = directoryInfo.EnumerateFiles("*.dll").Select(f => AssemblyDefinition.FromFile(
f.FullName)).ToList();

return inputAssemblies;
}

private class BasicResolver : DefaultAssemblyResolver
{
public void Register(AssemblyDefinition ad) => RegisterAssembly(ad);
}
}
83 changes: 43 additions & 40 deletions Il2CppInterop.Generator/Contexts/AssemblyRewriteContext.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System.Collections.Generic;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using Il2CppInterop.Generator.Extensions;
using Il2CppInterop.Generator.Utils;
using Mono.Cecil;

namespace Il2CppInterop.Generator.Contexts;

Expand All @@ -28,7 +28,7 @@ public AssemblyRewriteContext(RewriteGlobalContext globalContext, AssemblyDefini
NewAssembly = newAssembly;
GlobalContext = globalContext;

Imports = ImportsMap.GetOrCreate(newAssembly.MainModule,
Imports = ImportsMap.GetOrCreate(newAssembly.ManifestModule!,
mod => new RuntimeAssemblyReferences(mod, globalContext));
}

Expand Down Expand Up @@ -57,63 +57,66 @@ public void RegisterTypeRewrite(TypeRewriteContext context)
myNameTypeMap[(context.OriginalType ?? context.NewType).FullName] = context;
}

public MethodReference RewriteMethodRef(MethodReference methodRef)
public IMethodDefOrRef RewriteMethodRef(IMethodDefOrRef methodRef)
{
var newType = GlobalContext.GetNewTypeForOriginal(methodRef.DeclaringType.Resolve());
return newType.GetMethodByOldMethod(methodRef.Resolve()).NewMethod;
var newType = GlobalContext.GetNewTypeForOriginal(methodRef.DeclaringType!.Resolve()!);
var newMethod = newType.GetMethodByOldMethod(methodRef.Resolve()!).NewMethod;
return NewAssembly.ManifestModule!.DefaultImporter.ImportMethod(newMethod);
}

public TypeReference RewriteTypeRef(TypeReference? typeRef)
public ITypeDefOrRef RewriteTypeRef(ITypeDescriptor typeRef)
{
if (typeRef == null) return Imports.Il2CppObjectBase;
return RewriteTypeRef(typeRef?.ToTypeSignature()).ToTypeDefOrRef();
}

public TypeSignature RewriteTypeRef(TypeSignature? typeRef)
{
if (typeRef == null)
return Imports.Il2CppObjectBase;

var sourceModule = NewAssembly.MainModule;
var sourceModule = NewAssembly.ManifestModule!;

if (typeRef is ArrayType arrayType)
if (typeRef is ArrayBaseTypeSignature arrayType)
{
if (arrayType.Rank != 1)
return Imports.Il2CppObjectBase;

var elementType = arrayType.ElementType;
var elementType = arrayType.BaseType;
if (elementType.FullName == "System.String")
return Imports.Il2CppStringArray;

var convertedElementType = RewriteTypeRef(elementType);
if (elementType.IsGenericParameter)
return new GenericInstanceType(Imports.Il2CppArrayBase) { GenericArguments = { convertedElementType } };
if (elementType is GenericParameterSignature)
return new GenericInstanceTypeSignature(Imports.Il2CppArrayBase.ToTypeDefOrRef(), false, convertedElementType);

return new GenericInstanceType(convertedElementType.IsValueType
? Imports.Il2CppStructArray
: Imports.Il2CppReferenceArray)
{ GenericArguments = { convertedElementType } };
return new GenericInstanceTypeSignature(convertedElementType.IsValueType
? Imports.Il2CppStructArray.ToTypeDefOrRef()
: Imports.Il2CppReferenceArray.ToTypeDefOrRef(), false, convertedElementType);
}

if (typeRef is GenericParameter genericParameter)
if (typeRef is GenericParameterSignature genericParameter)
{
var genericParameterDeclaringType = genericParameter.DeclaringType;
if (genericParameterDeclaringType != null)
return RewriteTypeRef(genericParameterDeclaringType).GenericParameters[genericParameter.Position];

return RewriteMethodRef(genericParameter.DeclaringMethod).GenericParameters[genericParameter.Position];
return new GenericParameterSignature(sourceModule, genericParameter.ParameterType, genericParameter.Index);
}

if (typeRef is ByReferenceType byRef)
return new ByReferenceType(RewriteTypeRef(byRef.ElementType));
if (typeRef is ByReferenceTypeSignature byRef)
return new ByReferenceTypeSignature(RewriteTypeRef(byRef.BaseType));

if (typeRef is PointerType pointerType)
return new PointerType(RewriteTypeRef(pointerType.ElementType));
if (typeRef is PointerTypeSignature pointerType)
return new PointerTypeSignature(RewriteTypeRef(pointerType.BaseType));

if (typeRef is GenericInstanceType genericInstance)
if (typeRef is GenericInstanceTypeSignature genericInstance)
{
var newRef = new GenericInstanceType(RewriteTypeRef(genericInstance.ElementType));
foreach (var originalParameter in genericInstance.GenericArguments)
newRef.GenericArguments.Add(RewriteTypeRef(originalParameter));
var genericType = RewriteTypeRef(genericInstance.GenericType.ToTypeSignature()).ToTypeDefOrRef();
var newRef = new GenericInstanceTypeSignature(genericType, genericType.IsValueType);
foreach (var originalParameter in genericInstance.TypeArguments)
newRef.TypeArguments.Add(RewriteTypeRef(originalParameter));

return newRef;
}

if (typeRef.IsPrimitive || typeRef.FullName == "System.TypedReference")
return sourceModule.ImportCorlibReference(typeRef.Namespace, typeRef.Name);
if (typeRef.IsPrimitive() || typeRef.FullName == "System.TypedReference")
return sourceModule.ImportCorlibReference(typeRef.FullName);

if (typeRef.FullName == "System.Void")
return Imports.Module.Void();
Expand All @@ -122,18 +125,18 @@ public TypeReference RewriteTypeRef(TypeReference? typeRef)
return Imports.Module.String();

if (typeRef.FullName == "System.Object")
return sourceModule.ImportReference(GlobalContext.GetAssemblyByName("mscorlib")
.GetTypeByName("System.Object").NewType);
return sourceModule.DefaultImporter.ImportType(GlobalContext.GetAssemblyByName("mscorlib")
.GetTypeByName("System.Object").NewType).ToTypeSignature();

if (typeRef.FullName == "System.Attribute")
return sourceModule.ImportReference(GlobalContext.GetAssemblyByName("mscorlib")
.GetTypeByName("System.Attribute").NewType);
return sourceModule.DefaultImporter.ImportType(GlobalContext.GetAssemblyByName("mscorlib")
.GetTypeByName("System.Attribute").NewType).ToTypeSignature();

var originalTypeDef = typeRef.Resolve();
var targetAssembly = GlobalContext.GetNewAssemblyForOriginal(originalTypeDef.Module.Assembly);
var originalTypeDef = typeRef.Resolve()!;
var targetAssembly = GlobalContext.GetNewAssemblyForOriginal(originalTypeDef.Module!.Assembly!);
var target = targetAssembly.GetContextForOriginalType(originalTypeDef).NewType;

return sourceModule.ImportReference(target);
return sourceModule.DefaultImporter.ImportType(target).ToTypeSignature();
}

public TypeRewriteContext GetTypeByName(string name)
Expand Down
25 changes: 15 additions & 10 deletions Il2CppInterop.Generator/Contexts/FieldRewriteContext.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using AsmResolver.DotNet;
using AsmResolver.DotNet.Signatures;
using AsmResolver.PE.DotNet.Metadata.Tables;
using Il2CppInterop.Generator.Extensions;
using Il2CppInterop.Generator.Utils;
using Mono.Cecil;

namespace Il2CppInterop.Generator.Contexts;

Expand All @@ -14,7 +15,7 @@ public class FieldRewriteContext
public readonly TypeRewriteContext DeclaringType;
public readonly FieldDefinition OriginalField;

public readonly FieldReference PointerField;
public readonly MemberReference PointerField;
public readonly string UnmangledName;

public FieldRewriteContext(TypeRewriteContext declaringType, FieldDefinition originalField,
Expand All @@ -31,35 +32,39 @@ public FieldRewriteContext(TypeRewriteContext declaringType, FieldDefinition ori

declaringType.NewType.Fields.Add(pointerField);

PointerField = new FieldReference(pointerField.Name, pointerField.FieldType, DeclaringType.SelfSubstitutedRef);
Debug.Assert(pointerField.Signature is not null);
PointerField = new MemberReference(DeclaringType.SelfSubstitutedRef, pointerField.Name, new FieldSignature(pointerField.Signature!.FieldType));
}

private string UnmangleFieldNameBase(FieldDefinition field, GeneratorOptions options)
{
if (options.PassthroughNames) return field.Name;
if (options.PassthroughNames)
return field.Name!;

if (!field.Name.IsObfuscated(options))
{
if (!field.Name.IsInvalidInSource())
return field.Name;
return field.Name!;
return field.Name.FilterInvalidInSourceChars();
}

Debug.Assert(field.Signature is not null);
var accessModString = MethodAccessTypeLabels[(int)(field.Attributes & FieldAttributes.FieldAccessMask)];
var staticString = field.IsStatic ? "_Static" : "";
return "field_" + accessModString + staticString + "_" +
DeclaringType.AssemblyContext.RewriteTypeRef(field.FieldType).GetUnmangledName();
DeclaringType.AssemblyContext.RewriteTypeRef(field.Signature!.FieldType).GetUnmangledName(field.DeclaringType);
}

private string UnmangleFieldName(FieldDefinition field, GeneratorOptions options,
Dictionary<string, int>? renamedFieldCounts)
{
if (options.PassthroughNames) return field.Name;
if (options.PassthroughNames)
return field.Name!;

if (!field.Name.IsObfuscated(options))
{
if (!field.Name.IsInvalidInSource())
return field.Name;
return field.Name!;
return field.Name.FilterInvalidInSourceChars();
}

Expand Down
Loading

0 comments on commit 06cd048

Please sign in to comment.