Skip to content

Commit 4d1eccb

Browse files
ds5678SamboyCoding
authored andcommitted
Improve Il2CppType handling
1 parent 84cff19 commit 4d1eccb

File tree

6 files changed

+8
-215
lines changed

6 files changed

+8
-215
lines changed

Cpp2IL.Core/Model/Contexts/TypeAnalysisContext.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,6 @@ public virtual Il2CppTypeEnum Type
103103
{
104104
if (AppContext.SystemTypes.TryGetIl2CppTypeEnum(this, out var value))
105105
return value;
106-
107-
if (Definition is { RawType: {} rawType })
108-
return rawType.Type;
109106

110107
if (IsEnumType)
111108
return Il2CppTypeEnum.IL2CPP_TYPE_ENUM;
@@ -309,6 +306,9 @@ public static ITypeInfoProvider GetSndnProviderForType(ApplicationAnalysisContex
309306
public virtual bool IsValueType => Definition?.IsValueType ?? BaseType is { Namespace: "System", Name: "ValueType" };
310307
public bool IsEnumType => Definition?.IsEnumType ?? BaseType is { Namespace: "System", Name: "Enum" };
311308
public bool IsInterface => Definition?.IsInterface ?? ((TypeAttributes & TypeAttributes.Interface) != default);
309+
public bool IsAbstract => (TypeAttributes & TypeAttributes.Abstract) != default;
310+
public bool IsSealed => (TypeAttributes & TypeAttributes.Sealed) != default;
311+
public bool IsStatic => IsAbstract && IsSealed;
312312
public IEnumerable<ITypeInfoProvider> GenericArgumentInfoProviders => Array.Empty<ITypeInfoProvider>();
313313
public IEnumerable<IFieldInfoProvider> FieldInfoProviders => Fields;
314314
public IEnumerable<IMethodInfoProvider> MethodInfoProviders => Methods;

Cpp2IL.Core/Utils/AsmResolver/AsmResolverAssemblyPopulator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ private static TypeSignature GetTypeSigFromAttributeArg(AssemblyDefinition paren
6060
parameter switch
6161
{
6262
CustomAttributePrimitiveParameter primitiveParameter => AsmResolverUtils.GetPrimitiveTypeDef(primitiveParameter.PrimitiveType).ToTypeSignature(),
63-
CustomAttributeEnumParameter enumParameter => AsmResolverUtils.GetTypeSignatureFromIl2CppType(parentAssembly.ManifestModule!, enumParameter.EnumType ?? throw new("Enum type not found for " + enumParameter)),
63+
CustomAttributeEnumParameter enumParameter => enumParameter.EnumTypeContext.ToTypeSignature(parentAssembly.ManifestModule!),
6464
BaseCustomAttributeTypeParameter => TypeDefinitionsAsmResolver.Type.ToTypeSignature(),
6565
CustomAttributeArrayParameter arrayParameter => AsmResolverUtils.GetPrimitiveTypeDef(arrayParameter.ArrType).ToTypeSignature().MakeSzArrayType(),
6666
_ => throw new ArgumentException("Unknown custom attribute parameter type: " + parameter.GetType().FullName)

Cpp2IL.Core/Utils/AsmResolver/AsmResolverUtils.cs

Lines changed: 1 addition & 138 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
using System.Linq;
66
using AsmResolver.DotNet;
77
using AsmResolver.DotNet.Signatures;
8-
using LibCpp2IL;
98
using LibCpp2IL.BinaryStructures;
109

1110
namespace Cpp2IL.Core.Utils.AsmResolver;
@@ -49,142 +48,6 @@ public static TypeDefinition GetPrimitiveTypeDef(Il2CppTypeEnum type) =>
4948
_ => throw new ArgumentException($"Type is not a primitive - {type}", nameof(type))
5049
};
5150

52-
public static TypeSignature GetTypeSignatureFromIl2CppType(ModuleDefinition module, Il2CppType il2CppType)
53-
{
54-
//Module is needed for generic params
55-
if (il2CppType == null)
56-
throw new ArgumentNullException(nameof(il2CppType));
57-
58-
TypeSignature ret;
59-
switch (il2CppType.Type)
60-
{
61-
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
62-
case Il2CppTypeEnum.IL2CPP_TYPE_VOID:
63-
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
64-
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
65-
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
66-
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
67-
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
68-
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
69-
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
70-
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
71-
case Il2CppTypeEnum.IL2CPP_TYPE_I:
72-
case Il2CppTypeEnum.IL2CPP_TYPE_U:
73-
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
74-
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
75-
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
76-
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
77-
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
78-
case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF:
79-
ret = module.DefaultImporter.ImportType(GetPrimitiveTypeDef(il2CppType.Type))
80-
.ToTypeSignature();
81-
break;
82-
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
83-
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
84-
ret = module.DefaultImporter.ImportType(TypeDefsByIndex[il2CppType.Data.ClassIndex])
85-
.ToTypeSignature();
86-
break;
87-
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
88-
ret = GetTypeSignatureFromIl2CppType(module, il2CppType.GetArrayElementType())
89-
.MakeArrayTypeWithLowerBounds(il2CppType.GetArrayRank());
90-
break;
91-
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
92-
ret = GetTypeSignatureFromIl2CppType(module, il2CppType.GetEncapsulatedType())
93-
.MakeSzArrayType();
94-
break;
95-
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
96-
ret = GetTypeSignatureFromIl2CppType(module, il2CppType.GetEncapsulatedType())
97-
.MakePointerType();
98-
break;
99-
case Il2CppTypeEnum.IL2CPP_TYPE_VAR: //Generic type parameter
100-
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR: //Generic method parameter
101-
var method = il2CppType.Type == Il2CppTypeEnum.IL2CPP_TYPE_MVAR;
102-
ret = new GenericParameterSignature(module, method ? GenericParameterType.Method : GenericParameterType.Type, il2CppType.GetGenericParameterDef().genericParameterIndexInOwner);
103-
break;
104-
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
105-
{
106-
var genericClass = il2CppType.GetGenericClass();
107-
108-
//Get base type
109-
TypeDefsByIndex.TryGetValue(genericClass.TypeDefinitionIndex, out var typeDefinition);
110-
if (Cpp2IlApi.CurrentAppContext!.MetadataVersion >= 27f) //TODO: we should pass in the app context to this method
111-
{
112-
//V27 - type indexes are pointers now.
113-
var type = LibCpp2IlMain.Binary!.ReadReadableAtVirtualAddress<Il2CppType>((ulong)genericClass.TypeDefinitionIndex);
114-
typeDefinition = GetTypeSignatureFromIl2CppType(module, type).Resolve() ?? throw new Exception("Unable to resolve base type for generic inst");
115-
}
116-
117-
var genericInstanceType = new GenericInstanceTypeSignature(module.DefaultImporter.ImportType(typeDefinition!), typeDefinition!.IsValueType);
118-
119-
//Get generic arguments
120-
var genericArgumentTypes = genericClass.Context.ClassInst.Types;
121-
122-
//Add arguments to generic instance
123-
foreach (var type in genericArgumentTypes)
124-
genericInstanceType.TypeArguments.Add(GetTypeSignatureFromIl2CppType(module, type));
125-
126-
ret = genericInstanceType;
127-
break;
128-
}
129-
default:
130-
throw new("Don't know how to make a type signature from " + il2CppType.Type);
131-
}
132-
133-
if (il2CppType.Byref == 1)
134-
ret = ret.MakeByReferenceType();
135-
136-
return ret;
137-
}
138-
139-
/// <summary>
140-
/// Imports the managed representation of the given il2cpp type using the given importer, and returns said type.
141-
/// <br/><br/>
142-
/// Prefer <see cref="GetTypeSignatureFromIl2CppType"/> where possible, only use this where an actual type reference is needed.
143-
/// Such cases would include generic parameter constraints, base types/interfaces, and event types.
144-
/// </summary>
145-
public static ITypeDefOrRef ImportReferenceFromIl2CppType(ModuleDefinition module, Il2CppType il2CppType)
146-
{
147-
if (il2CppType == null)
148-
throw new ArgumentNullException(nameof(il2CppType));
149-
150-
switch (il2CppType.Type)
151-
{
152-
case Il2CppTypeEnum.IL2CPP_TYPE_OBJECT:
153-
case Il2CppTypeEnum.IL2CPP_TYPE_VOID:
154-
case Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN:
155-
case Il2CppTypeEnum.IL2CPP_TYPE_CHAR:
156-
case Il2CppTypeEnum.IL2CPP_TYPE_I1:
157-
case Il2CppTypeEnum.IL2CPP_TYPE_U1:
158-
case Il2CppTypeEnum.IL2CPP_TYPE_I2:
159-
case Il2CppTypeEnum.IL2CPP_TYPE_U2:
160-
case Il2CppTypeEnum.IL2CPP_TYPE_I4:
161-
case Il2CppTypeEnum.IL2CPP_TYPE_U4:
162-
case Il2CppTypeEnum.IL2CPP_TYPE_I:
163-
case Il2CppTypeEnum.IL2CPP_TYPE_U:
164-
case Il2CppTypeEnum.IL2CPP_TYPE_I8:
165-
case Il2CppTypeEnum.IL2CPP_TYPE_U8:
166-
case Il2CppTypeEnum.IL2CPP_TYPE_R4:
167-
case Il2CppTypeEnum.IL2CPP_TYPE_R8:
168-
case Il2CppTypeEnum.IL2CPP_TYPE_STRING:
169-
case Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF:
170-
//This case, and the one below, are faster to go this way rather than delegating to type signature creation, because we can go straight from def -> ref.
171-
return module.DefaultImporter.ImportType(GetPrimitiveTypeDef(il2CppType.Type));
172-
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
173-
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
174-
return module.DefaultImporter.ImportType(TypeDefsByIndex[il2CppType.Data.ClassIndex]);
175-
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
176-
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
177-
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
178-
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
179-
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
180-
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR:
181-
//For the rest of these, we have to make a type signature first anyway, so just delegate to signature getter
182-
return GetTypeSignatureFromIl2CppType(module, il2CppType).ToTypeDefOrRef();
183-
default:
184-
throw new("Don't know how to import a type reference from an il2cpp type of type " + il2CppType.Type);
185-
}
186-
}
187-
18851
public static TypeDefinition? TryLookupTypeDefKnownNotGeneric(string? name)
18952
{
19053
if (name == null)
@@ -198,7 +61,7 @@ public static ITypeDefOrRef ImportReferenceFromIl2CppType(ModuleDefinition modul
19861
if (CachedTypeDefsByName.TryGetValue(key, out var ret))
19962
return ret;
20063

201-
var definedType = Cpp2IlApi.CurrentAppContext!.AllTypes.FirstOrDefault(t => t.Definition != null && string.Equals(t.Definition.FullName, name, StringComparison.OrdinalIgnoreCase));
64+
var definedType = Cpp2IlApi.CurrentAppContext!.AllTypes.FirstOrDefault(t => string.Equals(t.FullName, name, StringComparison.OrdinalIgnoreCase));
20265

20366
//Try subclasses
20467
definedType ??= Cpp2IlApi.CurrentAppContext.AllTypes.FirstOrDefault(t =>

Cpp2IL.Core/Utils/AttributeInjectionUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ private static Il2CppType GetAttributeTargetsType(AssemblyAnalysisContext mscorl
168168
}
169169
else
170170
{
171-
return LibCpp2IlReflection.GetTypeFromDefinition(targetsEnum.Definition) ?? throw new("Could not get the Il2CppType for AttributeTargets");
171+
return targetsEnum.Definition.RawType;
172172
}
173173
}
174174

Cpp2IL.Core/Utils/Il2CppTypeToContext.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System.Diagnostics.CodeAnalysis;
22
using Cpp2IL.Core.Model.Contexts;
33
using LibCpp2IL.BinaryStructures;
4+
using LibCpp2IL.Reflection;
45

56
namespace Cpp2IL.Core.Utils;
67

@@ -15,7 +16,7 @@ public static class Il2CppTypeToContext
1516
TypeAnalysisContext ret;
1617

1718
if (type.Type.IsIl2CppPrimitive())
18-
ret = context.AppContext.SystemTypes.GetPrimitive(type.Type);
19+
ret = context.AppContext.ResolveContextForType(LibCpp2IlReflection.PrimitiveTypeDefinitions[type.Type]) ?? throw new($"Could not resolve type context for type {type.Type}");
1920
else if (type.Type is Il2CppTypeEnum.IL2CPP_TYPE_CLASS or Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE)
2021
ret = context.AppContext.ResolveContextForType(type.AsClass()) ?? throw new($"Could not resolve type context for type {type.AsClass().FullName}");
2122
else if (type.Type is Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST)

LibCpp2IL/Reflection/LibCpp2IlReflection.cs

Lines changed: 0 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -228,75 +228,4 @@ public static Il2CppTypeDefinition GetDeclaringTypeFromField(Il2CppFieldDefiniti
228228

229229
return FieldDeclaringTypes[fieldDefinition];
230230
}
231-
232-
public static Il2CppType? GetTypeFromDefinition(Il2CppTypeDefinition definition)
233-
{
234-
if (LibCpp2IlMain.Binary == null)
235-
return null;
236-
237-
switch (definition.FullName)
238-
{
239-
case "System.SByte":
240-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I1];
241-
case "System.Int16":
242-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I2];
243-
case "System.Int32":
244-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I4];
245-
case "System.Int64":
246-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I8];
247-
case "System.Byte":
248-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_U1];
249-
case "System.UInt16":
250-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_U2];
251-
case "System.UInt32":
252-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_U4];
253-
case "System.UInt64":
254-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_U8];
255-
case "System.IntPtr":
256-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_I];
257-
case "System.UIntPtr":
258-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_U];
259-
case "System.Single":
260-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_R4];
261-
case "System.Double":
262-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_R8];
263-
case "System.Boolean":
264-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_BOOLEAN];
265-
case "System.Char":
266-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_CHAR];
267-
case "System.String":
268-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_STRING];
269-
case "System.Void":
270-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_VOID];
271-
case "System.TypedReference":
272-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_TYPEDBYREF];
273-
case "System.Object":
274-
return PrimitiveTypeCache[Il2CppTypeEnum.IL2CPP_TYPE_OBJECT];
275-
}
276-
277-
var index = definition.TypeIndex;
278-
279-
if (Il2CppTypeCache.TryGetValue(index, out var cachedType))
280-
{
281-
return cachedType;
282-
}
283-
284-
foreach (var type in LibCpp2IlMain.Binary.AllTypes)
285-
{
286-
if (type.Type is not Il2CppTypeEnum.IL2CPP_TYPE_CLASS and not Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE)
287-
continue;
288-
289-
if (type.Data.ClassIndex == index && type.Byref == 0)
290-
{
291-
lock (Il2CppTypeCache)
292-
{
293-
Il2CppTypeCache[index] = type;
294-
}
295-
296-
return type;
297-
}
298-
}
299-
300-
return null;
301-
}
302231
}

0 commit comments

Comments
 (0)