From 8f4970e44e5000e989ee4e52fd83c74130499789 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Tue, 21 Oct 2025 23:00:48 -0700 Subject: [PATCH 1/2] Allow method overrides to be modified --- .../Contexts/InjectedMethodAnalysisContext.cs | 4 - .../Model/Contexts/MethodAnalysisContext.cs | 114 ++++++++++-------- 2 files changed, 61 insertions(+), 57 deletions(-) diff --git a/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs index 7078290e..c4555cb8 100644 --- a/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/InjectedMethodAnalysisContext.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Reflection; namespace Cpp2IL.Core.Model.Contexts; @@ -19,9 +18,6 @@ public class InjectedMethodAnalysisContext : MethodAnalysisContext protected override int CustomAttributeIndex => -1; - public override IEnumerable Overrides => OverridesList; - public List OverridesList { get; } = []; - public InjectedMethodAnalysisContext( TypeAnalysisContext parent, string name, diff --git a/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs index e20e75a7..3a997182 100644 --- a/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs @@ -122,84 +122,92 @@ public override List GenericParameters public MethodAnalysisContext? BaseMethod => Overrides.FirstOrDefault(m => m.DeclaringType?.IsInterface is false); + private List? _overrides; + /// /// The set of methods which this method overrides. /// - public virtual IEnumerable Overrides + public List Overrides { get { - if (Definition == null) - return []; + // Lazy load the overrides + return _overrides ??= GetOverrides().ToList(); + } + } - var declaringTypeDefinition = DeclaringType?.Definition; - if (declaringTypeDefinition == null) - return []; + private IEnumerable GetOverrides() + { + if (Definition == null) + return []; + + var declaringTypeDefinition = DeclaringType?.Definition; + if (declaringTypeDefinition == null) + return []; - var vtable = declaringTypeDefinition.VTable; - if (vtable == null) - return []; + var vtable = declaringTypeDefinition.VTable; + if (vtable == null) + return []; - return GetOverriddenMethods(declaringTypeDefinition, vtable); + return GetOverriddenMethods(declaringTypeDefinition, vtable); - bool TryGetMethodForSlot(TypeAnalysisContext declaringType, int slot, [NotNullWhen(true)] out MethodAnalysisContext? method) + bool TryGetMethodForSlot(TypeAnalysisContext declaringType, int slot, [NotNullWhen(true)] out MethodAnalysisContext? method) + { + if (declaringType is GenericInstanceTypeAnalysisContext genericInstanceType) { - if (declaringType is GenericInstanceTypeAnalysisContext genericInstanceType) + var genericMethod = genericInstanceType.GenericType.Methods.FirstOrDefault(m => m.Slot == slot); + if (genericMethod is not null) { - var genericMethod = genericInstanceType.GenericType.Methods.FirstOrDefault(m => m.Slot == slot); - if (genericMethod is not null) - { - method = new ConcreteGenericMethodAnalysisContext(genericMethod, genericInstanceType.GenericArguments, []); - return true; - } + method = new ConcreteGenericMethodAnalysisContext(genericMethod, genericInstanceType.GenericArguments, []); + return true; } - else + } + else + { + var baseMethod = declaringType.Methods.FirstOrDefault(m => m.Slot == slot); + if (baseMethod is not null) { - var baseMethod = declaringType.Methods.FirstOrDefault(m => m.Slot == slot); - if (baseMethod is not null) - { - method = baseMethod; - return true; - } + method = baseMethod; + return true; } - - method = null; - return false; } - IEnumerable GetOverriddenMethods(Il2CppTypeDefinition declaringTypeDefinition, MetadataUsage?[] vtable) + method = null; + return false; + } + + IEnumerable GetOverriddenMethods(Il2CppTypeDefinition declaringTypeDefinition, MetadataUsage?[] vtable) + { + for (var i = 0; i < vtable.Length; ++i) { - for (var i = 0; i < vtable.Length; ++i) - { - var vtableEntry = vtable[i]; - if (vtableEntry is null or { Type: not MetadataUsageType.MethodDef }) - continue; + var vtableEntry = vtable[i]; + if (vtableEntry is null or { Type: not MetadataUsageType.MethodDef }) + continue; - if (vtableEntry.AsMethod() != Definition) - continue; + if (vtableEntry.AsMethod() != Definition) + continue; - // Normal inheritance - var baseType = DeclaringType?.BaseType; - while (baseType is not null) + // Normal inheritance + var baseType = DeclaringType?.BaseType; + while (baseType is not null) + { + if (TryGetMethodForSlot(baseType, i, out var method)) { - if (TryGetMethodForSlot(baseType, i, out var method)) - { - yield return method; - break; // We only want direct overrides, not the entire inheritance chain. - } - baseType = baseType.BaseType; + yield return method; + break; // We only want direct overrides, not the entire inheritance chain. } + baseType = baseType.BaseType; + } - // Interface inheritance - foreach (var interfaceOffset in declaringTypeDefinition.InterfaceOffsets) + // Interface inheritance + foreach (var interfaceOffset in declaringTypeDefinition.InterfaceOffsets) + { + if (i >= interfaceOffset.offset) { - if (i >= interfaceOffset.offset) + var interfaceTypeContext = interfaceOffset.Type.ToContext(CustomAttributeAssembly); + if (interfaceTypeContext != null && TryGetMethodForSlot(interfaceTypeContext, i - interfaceOffset.offset, out var method)) { - var interfaceTypeContext = interfaceOffset.Type.ToContext(CustomAttributeAssembly); - if (interfaceTypeContext != null && TryGetMethodForSlot(interfaceTypeContext, i - interfaceOffset.offset, out var method)) - { - yield return method; - } + yield return method; } } } From 3922d889ee783ffd49837342c30e232eae0c5bc1 Mon Sep 17 00:00:00 2001 From: ds5678 <49847914+ds5678@users.noreply.github.com> Date: Mon, 27 Oct 2025 10:41:36 -0700 Subject: [PATCH 2/2] DefaultBaseType instead of BaseType --- Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs b/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs index 3a997182..0657b038 100644 --- a/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs +++ b/Cpp2IL.Core/Model/Contexts/MethodAnalysisContext.cs @@ -188,7 +188,7 @@ IEnumerable GetOverriddenMethods(Il2CppTypeDefinition dec continue; // Normal inheritance - var baseType = DeclaringType?.BaseType; + var baseType = DeclaringType?.DefaultBaseType; while (baseType is not null) { if (TryGetMethodForSlot(baseType, i, out var method)) @@ -196,7 +196,7 @@ IEnumerable GetOverriddenMethods(Il2CppTypeDefinition dec yield return method; break; // We only want direct overrides, not the entire inheritance chain. } - baseType = baseType.BaseType; + baseType = baseType.DefaultBaseType; } // Interface inheritance