Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Analysis/MetadataResolver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ private static void ResolveMetadataUsages(MethodAnalysisContext method)
// Type metadata usage (Il2CppType* / Il2CppClass*).
if (method.DeclaringType is { } declaringType)
{
var typeContext = libContext.GetTypeGlobalByAddress(address)?.ToContext(declaringType.DeclaringAssembly);
var typeContext = libContext.GetTypeGlobalByAddress(address)?.ToContext(declaringType.AppContext);
if (typeContext != null)
{
instruction.Operands[1] = typeContext;
Expand Down
9 changes: 9 additions & 0 deletions Cpp2IL.Core/Model/Contexts/ApplicationAnalysisContext.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
Expand All @@ -11,6 +12,7 @@
using Cpp2IL.Core.Logging;
using Cpp2IL.Core.Utils;
using LibCpp2IL;
using LibCpp2IL.BinaryStructures;
using LibCpp2IL.Metadata;

namespace Cpp2IL.Core.Model.Contexts;
Expand Down Expand Up @@ -87,6 +89,11 @@ public class ApplicationAnalysisContext : ContextWithDataStorage

private readonly Dictionary<Il2CppImageDefinition, AssemblyAnalysisContext> AssembliesByImageDefinition = new();

/// <summary>
/// Cache for <see cref="GenericInstanceTypeAnalysisContext.GetOrCreate(Il2CppType, AssemblyAnalysisContext)"/>
/// </summary>
internal readonly ConcurrentDictionary<Il2CppType, Lazy<GenericInstanceTypeAnalysisContext>> GenericInstanceTypesByIl2CppType = new();

public ApplicationAnalysisContext(LibCpp2IlContext context)
{
LibCpp2IlContext = context;
Expand Down Expand Up @@ -179,13 +186,15 @@ private void PopulateMethodsByAddressTable()
return AssembliesByName[name];
}

[return: NotNullIfNotNull(nameof(imageDefinition))]
public AssemblyAnalysisContext? ResolveContextForAssembly(Il2CppImageDefinition? imageDefinition)
{
return imageDefinition is not null
? AssembliesByImageDefinition[imageDefinition]
: null;
}

[return: NotNullIfNotNull(nameof(assemblyDefinition))]
public AssemblyAnalysisContext? ResolveContextForAssembly(Il2CppAssemblyDefinition? assemblyDefinition)
{
return ResolveContextForAssembly(assemblyDefinition?.Image);
Expand Down
8 changes: 4 additions & 4 deletions Cpp2IL.Core/Model/Contexts/ArrayTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace Cpp2IL.Core.Model.Contexts;

public class ArrayTypeAnalysisContext(TypeAnalysisContext elementType, int rank, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class ArrayTypeAnalysisContext(TypeAnalysisContext elementType, int rank)
: WrappedTypeAnalysisContext(elementType)
{
public ArrayTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
: this(referencedFrom.ResolveIl2CppType(rawType.GetArrayElementType()), rawType.GetArrayRank(), referencedFrom)
public ArrayTypeAnalysisContext(Il2CppType rawType, ApplicationAnalysisContext context)
: this(context.ResolveIl2CppType(rawType.GetArrayElementType()), rawType.GetArrayRank())
{
}

Expand Down
6 changes: 0 additions & 6 deletions Cpp2IL.Core/Model/Contexts/AssemblyAnalysisContext.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -169,11 +168,6 @@ public byte[]? PublicKey

private readonly Dictionary<Il2CppTypeDefinition, TypeAnalysisContext> TypesByDefinition = new();

/// <summary>
/// Cache for <see cref="GenericInstanceTypeAnalysisContext.GetOrCreate(Il2CppType, AssemblyAnalysisContext)"/>
/// </summary>
internal readonly ConcurrentDictionary<Il2CppType, Lazy<GenericInstanceTypeAnalysisContext>> GenericInstanceTypesByIl2CppType = new();

public override string DefaultName => Definition?.AssemblyName.Name ?? throw new($"Injected assemblies should override {nameof(DefaultName)}");

protected override bool IsInjected => Definition is null;
Expand Down
8 changes: 4 additions & 4 deletions Cpp2IL.Core/Model/Contexts/BoxedTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

namespace Cpp2IL.Core.Model.Contexts;

public class BoxedTypeAnalysisContext(TypeAnalysisContext elementType, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class BoxedTypeAnalysisContext(TypeAnalysisContext elementType)
: WrappedTypeAnalysisContext(elementType)
{
public BoxedTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
: this(referencedFrom.ResolveIl2CppType(rawType.GetEncapsulatedType()), referencedFrom)
public BoxedTypeAnalysisContext(Il2CppType rawType, ApplicationAnalysisContext context)
: this(context.ResolveIl2CppType(rawType.GetEncapsulatedType()))
{
}

Expand Down
9 changes: 2 additions & 7 deletions Cpp2IL.Core/Model/Contexts/ByRefTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,9 @@

namespace Cpp2IL.Core.Model.Contexts;

public class ByRefTypeAnalysisContext(TypeAnalysisContext elementType, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class ByRefTypeAnalysisContext(TypeAnalysisContext elementType)
: WrappedTypeAnalysisContext(elementType)
{
public ByRefTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
: this(default(TypeAnalysisContext)!, referencedFrom)
{
}

public sealed override Il2CppTypeEnum Type => Il2CppTypeEnum.IL2CPP_TYPE_BYREF;

public sealed override string DefaultName => $"{ElementType.DefaultName}&";
Expand Down
26 changes: 11 additions & 15 deletions Cpp2IL.Core/Model/Contexts/ConcreteGenericMethodAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ namespace Cpp2IL.Core.Model.Contexts;

public class ConcreteGenericMethodAnalysisContext : MethodAnalysisContext
{
public readonly AssemblyAnalysisContext DeclaringAsm;
public readonly Cpp2IlMethodRef? MethodRef;
public readonly MethodAnalysisContext BaseMethodContext;

Expand Down Expand Up @@ -61,10 +60,9 @@ private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef methodRef, Assembly
: this(
methodRef,
ResolveBaseMethod(methodRef, declaringAssembly.GetTypeByDefinition(methodRef.DeclaringType)!),
ResolveDeclaringType(methodRef, declaringAssembly),
ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly),
ResolveTypeArray(methodRef.MethodGenericParams, declaringAssembly),
declaringAssembly)
ResolveDeclaringType(methodRef, declaringAssembly.AppContext),
ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly.AppContext),
ResolveTypeArray(methodRef.MethodGenericParams, declaringAssembly.AppContext))
{
}

Expand All @@ -88,8 +86,7 @@ private ConcreteGenericMethodAnalysisContext(MethodAnalysisContext baseMethod, T
baseMethod,
typeGenericParameters.Length > 0 ? baseMethod.DeclaringType!.MakeGenericInstanceType(typeGenericParameters) : baseMethod.DeclaringType!,
typeGenericParameters,
methodGenericParameters,
baseMethod.CustomAttributeAssembly)
methodGenericParameters)
{
if (baseMethod.DeclaringType!.GenericParameters.Count != typeGenericParameters.Length)
throw new ArgumentException("The number of type generic parameters must match the number of generic parameters on the declaring type.");
Expand All @@ -98,11 +95,10 @@ private ConcreteGenericMethodAnalysisContext(MethodAnalysisContext baseMethod, T
throw new ArgumentException("The number of method generic parameters must match the number of generic parameters on the base method.");
}

private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef? methodRef, MethodAnalysisContext baseMethodContext, TypeAnalysisContext declaringType, TypeAnalysisContext[] typeGenericParameters, TypeAnalysisContext[] methodGenericParameters, AssemblyAnalysisContext declaringAssembly)
private ConcreteGenericMethodAnalysisContext(Cpp2IlMethodRef? methodRef, MethodAnalysisContext baseMethodContext, TypeAnalysisContext declaringType, TypeAnalysisContext[] typeGenericParameters, TypeAnalysisContext[] methodGenericParameters)
: base(null, declaringType)
{
MethodRef = methodRef;
DeclaringAsm = declaringAssembly;
BaseMethodContext = baseMethodContext;

TypeGenericParameters = typeGenericParameters;
Expand Down Expand Up @@ -132,28 +128,28 @@ private static AssemblyAnalysisContext ResolveDeclaringAssembly(Cpp2IlMethodRef
?? throw new($"Unable to resolve declaring assembly {methodRef.DeclaringType.DeclaringAssembly?.Name} for generic method {methodRef}");
}

private static TypeAnalysisContext ResolveDeclaringType(Cpp2IlMethodRef methodRef, AssemblyAnalysisContext declaringAssembly)
private static TypeAnalysisContext ResolveDeclaringType(Cpp2IlMethodRef methodRef, ApplicationAnalysisContext appContext)
{
var baseType = declaringAssembly.AppContext.ResolveContextForType(methodRef.DeclaringType)
var baseType = appContext.ResolveContextForType(methodRef.DeclaringType)
?? throw new($"Unable to resolve declaring type {methodRef.DeclaringType.FullName} for generic method {methodRef}");

if (methodRef.TypeGenericParams.Length == 0)
return baseType;

var genericParams = ResolveTypeArray(methodRef.TypeGenericParams, declaringAssembly);
var genericParams = ResolveTypeArray(methodRef.TypeGenericParams, appContext);

return new GenericInstanceTypeAnalysisContext(baseType, genericParams, declaringAssembly);
return new GenericInstanceTypeAnalysisContext(baseType, genericParams);
}

private static TypeAnalysisContext[] ResolveTypeArray(Il2CppTypeReflectionData[] array, AssemblyAnalysisContext declaringAssembly)
private static TypeAnalysisContext[] ResolveTypeArray(Il2CppTypeReflectionData[] array, ApplicationAnalysisContext appContext)
{
if (array.Length == 0)
return [];

var ret = new TypeAnalysisContext[array.Length];
for (var i = 0; i < array.Length; i++)
{
ret[i] = array[i].ToContext(declaringAssembly)
ret[i] = array[i].ToContext(appContext)
?? throw new($"Unable to resolve generic parameter {array[i]} for generic method.");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

namespace Cpp2IL.Core.Model.Contexts;

public class CustomModifierTypeAnalysisContext(TypeAnalysisContext elementType, TypeAnalysisContext modifierType, bool required, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class CustomModifierTypeAnalysisContext(TypeAnalysisContext elementType, TypeAnalysisContext modifierType, bool required)
: WrappedTypeAnalysisContext(elementType)
{
public TypeAnalysisContext ModifierType { get; } = modifierType;

Expand Down
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Model/Contexts/EventAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public EventAttributes Attributes
set => OverrideAttributes = value;
}

public virtual TypeAnalysisContext DefaultEventType => DeclaringType.DeclaringAssembly.ResolveIl2CppType(Definition?.RawType) ?? throw new($"Subclasses must override {nameof(DefaultEventType)}.");
public virtual TypeAnalysisContext DefaultEventType => AppContext.ResolveIl2CppType(Definition?.RawType) ?? throw new($"Subclasses must override {nameof(DefaultEventType)}.");

public TypeAnalysisContext? OverrideEventType { get; set; }

Expand Down
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Model/Contexts/FieldAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public int Offset
set => OverrideOffset = value;
}

public virtual TypeAnalysisContext DefaultFieldType => DeclaringType.DeclaringAssembly.ResolveIl2CppType(RawFieldType)
public virtual TypeAnalysisContext DefaultFieldType => AppContext.ResolveIl2CppType(RawFieldType)
?? throw new($"Field type {RawFieldType} could not be resolved.");

public TypeAnalysisContext? OverrideFieldType { get; set; }
Expand Down
16 changes: 8 additions & 8 deletions Cpp2IL.Core/Model/Contexts/GenericInstanceTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,29 +43,29 @@ public sealed override string? OverrideNamespace
public sealed override bool IsValueType => GenericType.IsValueType; //We don't set a definition so the default implementation cannot determine if we're a value type or not.

// instances being constructed on the current thread, keyed by their cache identity (see GetOrCreate for why)
[ThreadStatic] private static Dictionary<(AssemblyAnalysisContext, Il2CppType), GenericInstanceTypeAnalysisContext>? _underConstruction;
[ThreadStatic] private static Dictionary<(ApplicationAnalysisContext, Il2CppType), GenericInstanceTypeAnalysisContext>? _underConstruction;

private GenericInstanceTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom) : base(referencedFrom)
private GenericInstanceTypeAnalysisContext(Il2CppType rawType, ApplicationAnalysisContext context) : base(context.ResolveContextForAssembly(rawType.GetGenericClass().TypeDefinition.DeclaringAssembly!))
{
var underConstruction = _underConstruction ??= new();
underConstruction[(referencedFrom, rawType)] = this;
underConstruction[(context, rawType)] = this;
try
{
//Generic type has to be a type definition
var gClass = rawType.GetGenericClass();
GenericType = AppContext.ResolveContextForType(gClass.TypeDefinition) ?? throw new($"Could not resolve type {gClass.TypeDefinition.FullName} for generic instance base type");
GenericType = context.ResolveContextForType(gClass.TypeDefinition) ?? throw new($"Could not resolve type {gClass.TypeDefinition.FullName} for generic instance base type");

GenericArguments.AddRange(gClass.Context.ClassInst!.Types.Select(referencedFrom.ResolveIl2CppType)!);
GenericArguments.AddRange(gClass.Context.ClassInst!.Types.Select(context.ResolveIl2CppType)!);

SetDeclaringType();
}
finally
{
underConstruction.Remove((referencedFrom, rawType));
underConstruction.Remove((context, rawType));
}
}

public GenericInstanceTypeAnalysisContext(TypeAnalysisContext genericType, IEnumerable<TypeAnalysisContext> genericArguments, AssemblyAnalysisContext referencedFrom) : base(referencedFrom)
public GenericInstanceTypeAnalysisContext(TypeAnalysisContext genericType, IEnumerable<TypeAnalysisContext> genericArguments) : base(genericType.CustomAttributeAssembly)
{
GenericType = genericType;
GenericArguments.AddRange(genericArguments);
Expand All @@ -80,7 +80,7 @@ public GenericInstanceTypeAnalysisContext(TypeAnalysisContext genericType, IEnum
/// <param name="rawType">The underlying <see cref="Il2CppType"/>.</param>
/// <param name="referencedFrom">The assembly that is referencing this generic instance.</param>
/// <returns>The context for the <paramref name="rawType"/>.</returns>
public static GenericInstanceTypeAnalysisContext GetOrCreate(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
public static GenericInstanceTypeAnalysisContext GetOrCreate(Il2CppType rawType, ApplicationAnalysisContext referencedFrom)
{
if (rawType.Type != Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST)
throw new ArgumentException($"Cannot create {nameof(GenericInstanceTypeAnalysisContext)} from type {rawType.Type}. Expected {Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST}.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public List<TypeAnalysisContext> ConstraintTypes
{
get
{
_constraintTypes ??= definition?.ConstraintTypes.Select(t => DeclaringAssembly.ResolveIl2CppType(t)).ToList() ?? [];
_constraintTypes ??= definition?.ConstraintTypes.Select(t => AppContext.ResolveIl2CppType(t)).ToList() ?? [];
return _constraintTypes;
}
}
Expand Down
6 changes: 3 additions & 3 deletions Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public override List<GenericParameterTypeAnalysisContext> GenericParameters

private ushort Slot => Definition?.slot ?? ushort.MaxValue;

public virtual TypeAnalysisContext DefaultReturnType => DeclaringType?.DeclaringAssembly.ResolveIl2CppType(Definition?.RawReturnType) ?? throw new($"Subclasses of MethodAnalysisContext should override {nameof(DefaultReturnType)}");
public virtual TypeAnalysisContext DefaultReturnType => AppContext.ResolveIl2CppType(Definition?.RawReturnType) ?? throw new($"Subclasses of MethodAnalysisContext should override {nameof(DefaultReturnType)}");

public TypeAnalysisContext? OverrideReturnType { get; set; }

Expand Down Expand Up @@ -236,7 +236,7 @@ IEnumerable<MethodAnalysisContext> GetOverriddenMethods(Il2CppTypeDefinition dec
{
if (i >= interfaceOffset.offset)
{
var interfaceTypeContext = interfaceOffset.Type.ToContext(CustomAttributeAssembly);
var interfaceTypeContext = interfaceOffset.Type.ToContext(AppContext);
var slot = i - interfaceOffset.offset;
if (interfaceTypeContext != null && TryGetMethodForSlot(interfaceTypeContext, slot, out var method) && !IsInterfaceSlot(method, slot))
{
Expand All @@ -258,7 +258,7 @@ private static bool IsInterfaceSlot(MethodAnalysisContext method, int slot)
{
if (slot >= interfaceOffset.offset)
{
var interfaceTypeContext = interfaceOffset.Type.ToContext(method.CustomAttributeAssembly);
var interfaceTypeContext = interfaceOffset.Type.ToContext(method.AppContext);
if (interfaceTypeContext != null && HasMethodForSlot(interfaceTypeContext, slot - interfaceOffset.offset))
{
return true;
Expand Down
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Model/Contexts/ParameterAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public ParameterAttributes Attributes
/// </summary>
public Il2CppParameterDefaultValue? DefaultValue { get; }

public virtual TypeAnalysisContext DefaultParameterType => DeclaringMethod.DeclaringType!.DeclaringAssembly.ResolveIl2CppType(Definition?.RawType) ?? throw new("Subclasses of ParameterAnalysisContext must provide a parameter type");
public virtual TypeAnalysisContext DefaultParameterType => AppContext.ResolveIl2CppType(Definition?.RawType) ?? throw new("Subclasses of ParameterAnalysisContext must provide a parameter type");

public TypeAnalysisContext? OverrideParameterType { get; set; }

Expand Down
8 changes: 4 additions & 4 deletions Cpp2IL.Core/Model/Contexts/PinnedTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

namespace Cpp2IL.Core.Model.Contexts;

public class PinnedTypeAnalysisContext(TypeAnalysisContext elementType, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class PinnedTypeAnalysisContext(TypeAnalysisContext elementType)
: WrappedTypeAnalysisContext(elementType)
{
public PinnedTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
: this(referencedFrom.ResolveIl2CppType(rawType.GetEncapsulatedType()), referencedFrom)
public PinnedTypeAnalysisContext(Il2CppType rawType, ApplicationAnalysisContext context)
: this(context.ResolveIl2CppType(rawType.GetEncapsulatedType()))
{
}

Expand Down
8 changes: 4 additions & 4 deletions Cpp2IL.Core/Model/Contexts/PointerTypeAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@

namespace Cpp2IL.Core.Model.Contexts;

public class PointerTypeAnalysisContext(TypeAnalysisContext elementType, AssemblyAnalysisContext referencedFrom)
: WrappedTypeAnalysisContext(elementType, referencedFrom)
public class PointerTypeAnalysisContext(TypeAnalysisContext elementType)
: WrappedTypeAnalysisContext(elementType)
{
public PointerTypeAnalysisContext(Il2CppType rawType, AssemblyAnalysisContext referencedFrom)
: this(referencedFrom.ResolveIl2CppType(rawType.GetEncapsulatedType()), referencedFrom)
public PointerTypeAnalysisContext(Il2CppType rawType, ApplicationAnalysisContext context)
: this(context.ResolveIl2CppType(rawType.GetEncapsulatedType()))
{
}

Expand Down
2 changes: 1 addition & 1 deletion Cpp2IL.Core/Model/Contexts/PropertyAnalysisContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public PropertyAttributes Attributes
set => OverrideAttributes = value;
}

public virtual TypeAnalysisContext DefaultPropertyType => DeclaringType.DeclaringAssembly.ResolveIl2CppType(Definition?.RawPropertyType)
public virtual TypeAnalysisContext DefaultPropertyType => AppContext.ResolveIl2CppType(Definition?.RawPropertyType)
?? throw new($"Subclasses must override {nameof(DefaultPropertyType)}.");

public TypeAnalysisContext? OverridePropertyType { get; set; }
Expand Down
Loading
Loading