Skip to content

Commit ea01f90

Browse files
committed
lib: reduce usage of static state
1 parent 58871c2 commit ea01f90

14 files changed

+735
-317
lines changed

LibCpp2IL/BinaryStructures/Il2CppArrayType.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,30 @@
1+
using System;
2+
13
namespace LibCpp2IL.BinaryStructures;
24

35
public class Il2CppArrayType : ReadableClass
46
{
7+
// Populated by the caller after reading.
8+
internal Il2CppBinary? OwningBinary { get; set; }
9+
510
public ulong etype;
611
public byte rank;
712
public byte numsizes;
813
public byte numlobounds;
914
public ulong sizes;
1015
public ulong lobounds;
1116

12-
public Il2CppType ElementType => LibCpp2IlMain.Binary!.GetIl2CppTypeFromPointer(etype);
17+
public Il2CppType? ElementType
18+
{
19+
get
20+
{
21+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
22+
return binary == null ? null : binary.GetIl2CppTypeFromPointer(etype);
23+
}
24+
}
25+
26+
public Il2CppType GetElementTypeOrThrow()
27+
=> ElementType ?? throw new InvalidOperationException("No binary context available to resolve Il2CppArrayType.ElementType");
1328

1429
public override void Read(ClassReadingBinaryReader reader)
1530
{

LibCpp2IL/BinaryStructures/Il2CppCodeGenModule.cs

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
using System;
2+
13
namespace LibCpp2IL.BinaryStructures;
24

35
public class Il2CppCodeGenModule : ReadableClass
@@ -32,18 +34,36 @@ public class Il2CppCodeGenModule : ReadableClass
3234

3335
private string? _cachedName;
3436

37+
internal Il2CppBinary? OwningBinary { get; set; }
38+
3539
public string Name
3640
{
3741
get
3842
{
3943
if (_cachedName == null)
40-
_cachedName = LibCpp2IlMain.Binary!.ReadStringToNull(LibCpp2IlMain.Binary.MapVirtualAddressToRaw(moduleName));
44+
{
45+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
46+
if (binary == null)
47+
throw new InvalidOperationException("No binary context available to resolve Il2CppCodeGenModule.Name");
48+
49+
_cachedName = binary.ReadStringToNull(binary.MapVirtualAddressToRaw(moduleName));
50+
}
4151

4252
return _cachedName!;
4353
}
4454
}
4555

46-
public Il2CppTokenRangePair[] RGCTXRanges => LibCpp2IlMain.Binary!.GetRgctxRangePairsForModule(this);
56+
public Il2CppTokenRangePair[] RGCTXRanges
57+
{
58+
get
59+
{
60+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
61+
if (binary == null)
62+
throw new InvalidOperationException("No binary context available to resolve Il2CppCodeGenModule.RGCTXRanges");
63+
64+
return binary.GetRgctxRangePairsForModule(this);
65+
}
66+
}
4767

4868
public override void Read(ClassReadingBinaryReader reader)
4969
{
Lines changed: 42 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,58 @@
1+
using System;
12
using LibCpp2IL.Metadata;
23

34
namespace LibCpp2IL.BinaryStructures;
45

56
public class Il2CppGenericClass : ReadableClass
67
{
8+
// Populated by the caller after reading.
9+
internal Il2CppBinary? OwningBinary { get; set; }
10+
internal Il2CppMetadata? OwningMetadata { get; set; }
11+
712
[Version(Max = 24.5f)] public long TypeDefinitionIndex; /* the generic type definition */
813

914
[Version(Min = 27.0f)] public ulong V27TypePointer;
1015

1116
public Il2CppGenericContext Context = null!; /* a context that contains the type instantiation doesn't contain any method instantiation */
1217
public ulong CachedClass; /* if present, the Il2CppClass corresponding to the instantiation. */
1318

14-
public Il2CppTypeDefinition TypeDefinition => LibCpp2IlMain.MetadataVersion < 27f
15-
? LibCpp2IlMain.TheMetadata!.GetTypeDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppTypeDefinition>.MakeTemporaryForFixedWidthUsage((int)TypeDefinitionIndex)) //DynWidth: TypeDefinitionIndex removed in v24.5, never dynamic
16-
: V27BaseType!.AsClass();
19+
private float EffectiveMetadataVersion => OwningMetadata?.MetadataVersion ?? LibCpp2IlMain.MetadataVersion;
20+
21+
public Il2CppTypeDefinition TypeDefinition
22+
{
23+
get
24+
{
25+
if (EffectiveMetadataVersion < 27f)
26+
{
27+
var md = OwningMetadata ?? LibCpp2IlMain.TheMetadata;
28+
if (md == null)
29+
throw new InvalidOperationException("No metadata context available for generic class type definition resolution.");
30+
31+
return md.GetTypeDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppTypeDefinition>.MakeTemporaryForFixedWidthUsage((int)TypeDefinitionIndex));
32+
}
33+
34+
return V27BaseType!.AsClass();
35+
}
36+
}
37+
38+
public Il2CppType? V27BaseType
39+
{
40+
get
41+
{
42+
if (EffectiveMetadataVersion < 27f)
43+
return null;
1744

18-
public Il2CppType? V27BaseType => LibCpp2IlMain.MetadataVersion < 27f ? null : LibCpp2IlMain.Binary!.ReadReadableAtVirtualAddress<Il2CppType>(V27TypePointer);
45+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
46+
if (binary == null)
47+
return null;
48+
49+
var t = binary.ReadReadableAtVirtualAddress<Il2CppType>(V27TypePointer);
50+
t.OwningBinary = binary;
51+
t.OwningMetadata = OwningMetadata ?? LibCpp2IlMain.TheMetadata;
52+
t.Il2CppTypeHasNumMods5Bits ??= (OwningMetadata?.MetadataVersion ?? LibCpp2IlMain.MetadataVersion) >= 27.2f;
53+
return t;
54+
}
55+
}
1956

2057
public override void Read(ClassReadingBinaryReader reader)
2158
{
@@ -25,6 +62,7 @@ public override void Read(ClassReadingBinaryReader reader)
2562
TypeDefinitionIndex = reader.ReadNInt();
2663

2764
Context = reader.ReadReadableHereNoLock<Il2CppGenericContext>();
65+
Context.OwningBinary = OwningBinary;
2866
CachedClass = reader.ReadNUint();
2967
}
3068
}

LibCpp2IL/BinaryStructures/Il2CppGenericContext.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,40 @@ namespace LibCpp2IL.BinaryStructures;
22

33
public class Il2CppGenericContext : ReadableClass
44
{
5+
// Populated by the caller after reading.
6+
internal Il2CppBinary? OwningBinary { get; set; }
7+
58
/* The instantiation corresponding to the class generic parameters */
69
public ulong class_inst;
710

811
/* The instantiation corresponding to the method generic parameters */
912
public ulong method_inst;
1013

11-
public Il2CppGenericInst ClassInst => LibCpp2IlMain.Binary!.ReadReadableAtVirtualAddress<Il2CppGenericInst>(class_inst);
12-
public Il2CppGenericInst MethodInst => LibCpp2IlMain.Binary!.ReadReadableAtVirtualAddress<Il2CppGenericInst>(method_inst);
14+
public Il2CppGenericInst? ClassInst
15+
{
16+
get
17+
{
18+
if (class_inst == 0) return null;
19+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
20+
if (binary == null) return null;
21+
var inst = binary.ReadReadableAtVirtualAddress<Il2CppGenericInst>(class_inst);
22+
inst.OwningBinary = binary;
23+
return inst;
24+
}
25+
}
26+
27+
public Il2CppGenericInst? MethodInst
28+
{
29+
get
30+
{
31+
if (method_inst == 0) return null;
32+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
33+
if (binary == null) return null;
34+
var inst = binary.ReadReadableAtVirtualAddress<Il2CppGenericInst>(method_inst);
35+
inst.OwningBinary = binary;
36+
return inst;
37+
}
38+
}
1339

1440
public override void Read(ClassReadingBinaryReader reader)
1541
{

LibCpp2IL/BinaryStructures/Il2CppGenericInst.cs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,29 @@ namespace LibCpp2IL.BinaryStructures;
44

55
public class Il2CppGenericInst : ReadableClass
66
{
7+
// Populated by the caller after reading.
8+
internal Il2CppBinary? OwningBinary { get; set; }
9+
710
public ulong pointerCount;
811
public ulong pointerStart;
912

10-
public ulong[] Pointers => LibCpp2IlMain.Binary!.ReadNUintArrayAtVirtualAddress(pointerStart, (long)pointerCount);
13+
public ulong[] Pointers
14+
{
15+
get
16+
{
17+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
18+
return binary == null ? [] : binary.ReadNUintArrayAtVirtualAddress(pointerStart, (long)pointerCount);
19+
}
20+
}
1121

12-
public Il2CppType[] Types => Pointers.Select(LibCpp2IlMain.Binary!.GetIl2CppTypeFromPointer).ToArray();
22+
public Il2CppType[] Types
23+
{
24+
get
25+
{
26+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
27+
return binary == null ? [] : Pointers.Select(binary.GetIl2CppTypeFromPointer).ToArray();
28+
}
29+
}
1330

1431
public override void Read(ClassReadingBinaryReader reader)
1532
{

LibCpp2IL/BinaryStructures/Il2CppMethodSpec.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,43 @@ namespace LibCpp2IL.BinaryStructures;
88

99
public class Il2CppMethodSpec : ReadableClass
1010
{
11+
// Populated by Il2CppBinary.Init for per-context usage.
12+
internal Il2CppBinary? OwningBinary { get; set; }
13+
internal Il2CppMetadata? OwningMetadata { get; set; }
14+
1115
public int methodDefinitionIndex;
1216
public int classIndexIndex;
1317
public int methodIndexIndex;
1418

1519
public Il2CppMethodDefinition? MethodDefinition
16-
=> LibCpp2IlMain.TheMetadata?.GetMethodDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppMethodDefinition>.MakeTemporaryForFixedWidthUsage(methodDefinitionIndex)); //DynWidth: Il2CppMethodSpec is in-binary, dynamic widths weren't applied here.
20+
=> (OwningMetadata ?? LibCpp2IlMain.TheMetadata)
21+
?.GetMethodDefinitionFromIndex(Il2CppVariableWidthIndex<Il2CppMethodDefinition>.MakeTemporaryForFixedWidthUsage(methodDefinitionIndex)); //DynWidth: Il2CppMethodSpec is in-binary, dynamic widths weren't applied here.
1722

18-
public Il2CppGenericInst? GenericClassInst => LibCpp2IlMain.Binary?.GetGenericInst(classIndexIndex);
23+
public Il2CppGenericInst? GenericClassInst
24+
{
25+
get
26+
{
27+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
28+
if (binary == null) return null;
29+
if (classIndexIndex < 0) return null;
30+
var inst = binary.GetGenericInst(classIndexIndex);
31+
inst.OwningBinary = binary;
32+
return inst;
33+
}
34+
}
1935

20-
public Il2CppGenericInst? GenericMethodInst => LibCpp2IlMain.Binary?.GetGenericInst(methodIndexIndex);
36+
public Il2CppGenericInst? GenericMethodInst
37+
{
38+
get
39+
{
40+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
41+
if (binary == null) return null;
42+
if (methodIndexIndex < 0) return null;
43+
var inst = binary.GetGenericInst(methodIndexIndex);
44+
inst.OwningBinary = binary;
45+
return inst;
46+
}
47+
}
2148

2249
public Il2CppTypeReflectionData[] GenericClassParams => classIndexIndex == -1 ? [] : LibCpp2ILUtils.GetGenericTypeParams(GenericClassInst!)!;
2350

LibCpp2IL/BinaryStructures/Il2CppRGCTXDefinition.cs

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,36 @@ namespace LibCpp2IL.BinaryStructures;
55

66
public class Il2CppRGCTXDefinition : ReadableClass
77
{
8+
// Populated by Il2CppBinary.Init (codegen module init) for per-context usage.
9+
internal Il2CppBinary? OwningBinary { get; set; }
10+
internal Il2CppMetadata? OwningMetadata { get; set; }
11+
812
public Il2CppRGCTXDataType type;
913
public int _rawIndex;
1014

1115
public int MethodIndex => _defData?.MethodIndex ?? _constrainedData!.MethodIndex;
1216

1317
public int TypeIndex => _defData?.TypeIndex ?? _constrainedData!.TypeIndex;
1418

15-
public Il2CppMethodSpec? MethodSpec => LibCpp2IlMain.Binary?.GetMethodSpec(MethodIndex);
19+
public Il2CppMethodSpec? MethodSpec
20+
{
21+
get
22+
{
23+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
24+
return binary?.GetMethodSpec(MethodIndex);
25+
}
26+
}
1627

17-
public Il2CppTypeReflectionData? Type => LibCpp2ILUtils.GetTypeReflectionData(LibCpp2IlMain.Binary!.GetType(Il2CppVariableWidthIndex<Il2CppType>.MakeTemporaryForFixedWidthUsage(TypeIndex)));
28+
public Il2CppTypeReflectionData? Type
29+
{
30+
get
31+
{
32+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
33+
if (binary == null) return null;
34+
var t = binary.GetType(Il2CppVariableWidthIndex<Il2CppType>.MakeTemporaryForFixedWidthUsage(TypeIndex));
35+
return LibCpp2ILUtils.GetTypeReflectionData(t);
36+
}
37+
}
1838

1939

2040
public class Il2CppRGCTXDefinitionData : ReadableClass
@@ -45,6 +65,7 @@ public override void Read(ClassReadingBinaryReader reader)
4565
private Il2CppRGCTXConstrainedData? _constrainedData;
4666

4767
private Il2CppRGCTXDefinitionData? _defData;
68+
4869
public override void Read(ClassReadingBinaryReader reader)
4970
{
5071
type = IsLessThan(29) ? (Il2CppRGCTXDataType)reader.ReadInt32() : (Il2CppRGCTXDataType)reader.ReadInt64();
@@ -56,24 +77,30 @@ public override void Read(ClassReadingBinaryReader reader)
5677
else
5778
{
5879
var va = reader.ReadNUint();
80+
var bakPosition = reader.Position;
81+
82+
var binary = OwningBinary ?? LibCpp2IlMain.Binary;
83+
if (binary == null)
84+
{
85+
// Can't resolve VA -> raw without a binary context. Leave as-is.
86+
reader.Position = bakPosition;
87+
return;
88+
}
89+
90+
reader.Position = binary.MapVirtualAddressToRaw(va);
91+
5992
if (type == Il2CppRGCTXDataType.IL2CPP_RGCTX_DATA_CONSTRAINED)
6093
{
61-
var bakPosition = reader.Position;
62-
reader.Position = LibCpp2IlMain.Binary!.MapVirtualAddressToRaw(va);
6394
_constrainedData = new Il2CppRGCTXConstrainedData();
6495
_constrainedData.Read(reader);
65-
reader.Position = bakPosition;
6696
}
6797
else
6898
{
69-
var bakPosition = reader.Position;
70-
reader.Position = LibCpp2IlMain.Binary!.MapVirtualAddressToRaw(va);
7199
_defData = new Il2CppRGCTXDefinitionData();
72100
_defData.Read(reader);
73-
reader.Position = bakPosition;
74101
}
75102

103+
reader.Position = bakPosition;
76104
}
77-
78105
}
79106
}

0 commit comments

Comments
 (0)