Send FromTypeReference back to Il2CppModel

Now that FromTypeReference uses public Make* methods instead of private
TypeInfo constructors, it doesn't need to be in TypeInfo anymore. Move
it back to Il2CppModel, where it was before.
This commit is contained in:
Robert Xiao
2020-04-11 22:32:43 -07:00
committed by Katy
parent 1970879e52
commit f395ed3ff5
2 changed files with 73 additions and 73 deletions

View File

@@ -85,7 +85,7 @@ namespace Il2CppInspector.Reflection
} }
var typeRef = Package.TypeReferences[typeRefIndex]; var typeRef = Package.TypeReferences[typeRefIndex];
var referencedType = TypeInfo.FromTypeReference(this, typeRef); var referencedType = resolveTypeReference(typeRef);
TypesByReferenceIndex[typeRefIndex] = referencedType; TypesByReferenceIndex[typeRefIndex] = referencedType;
} }
@@ -151,6 +151,77 @@ namespace Il2CppInspector.Reflection
return genericTypeArguments.Select(a => GetTypeFromVirtualAddress((ulong) a)).ToArray(); return genericTypeArguments.Select(a => GetTypeFromVirtualAddress((ulong) a)).ToArray();
} }
// Initialize type from type reference (TypeRef)
// Much of the following is adapted from il2cpp::vm::Class::FromIl2CppType
private TypeInfo resolveTypeReference(Il2CppType typeRef) {
var image = Package.BinaryImage;
TypeInfo underlyingType;
switch (typeRef.type) {
// Classes defined in the metadata (reference to a TypeDef)
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
underlyingType = TypesByDefinitionIndex[typeRef.datapoint]; // klassIndex
break;
// Constructed types
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
// TODO: Replace with array load from Il2CppMetadataRegistration.genericClasses
var generic = image.ReadMappedObject<Il2CppGenericClass>(typeRef.datapoint); // Il2CppGenericClass *
// We have seen one test case where the TypeRef can point to no generic instance
// This is going to leave the TypeInfo in an undefined state
if (generic.typeDefinitionIndex == 0x0000_0000_ffff_ffff)
return null;
var genericTypeDef = TypesByDefinitionIndex[generic.typeDefinitionIndex];
// Get the instantiation
// TODO: Replace with array load from Il2CppMetadataRegistration.genericInsts
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
var genericArguments = ResolveGenericArguments(genericInstance);
underlyingType = genericTypeDef.MakeGenericType(genericArguments);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
var descriptor = image.ReadMappedObject<Il2CppArrayType>(typeRef.datapoint);
var elementType = GetTypeFromVirtualAddress(descriptor.etype);
underlyingType = elementType.MakeArrayType(descriptor.rank);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
elementType = GetTypeFromVirtualAddress(typeRef.datapoint);
underlyingType = elementType.MakeArrayType(1);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
elementType = GetTypeFromVirtualAddress(typeRef.datapoint);
underlyingType = elementType.MakePointerType();
break;
// Generic type and generic method parameters
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR:
underlyingType = GetGenericParameterType((int)typeRef.datapoint);
break;
// Primitive types
default:
underlyingType = getTypeDefinitionFromTypeEnum(typeRef.type);
break;
}
// Create a reference type if necessary
return typeRef.byref ? underlyingType.MakeByRefType() : underlyingType;
}
// Basic primitive types are specified via a flag value
private TypeInfo getTypeDefinitionFromTypeEnum(Il2CppTypeEnum t) {
if ((int)t >= Il2CppConstants.FullNameTypeString.Count)
return null;
var fqn = Il2CppConstants.FullNameTypeString[(int)t];
return TypesByFullName[fqn];
}
// Get a TypeRef by its virtual address // Get a TypeRef by its virtual address
// These are always nested types from references within another TypeRef // These are always nested types from references within another TypeRef
public TypeInfo GetTypeFromVirtualAddress(ulong ptr) { public TypeInfo GetTypeFromVirtualAddress(ulong ptr) {
@@ -160,7 +231,7 @@ namespace Il2CppInspector.Reflection
return TypesByReferenceIndex[typeRefIndex]; return TypesByReferenceIndex[typeRefIndex];
var type = Package.TypeReferences[typeRefIndex]; var type = Package.TypeReferences[typeRefIndex];
var referencedType = TypeInfo.FromTypeReference(this, type); var referencedType = resolveTypeReference(type);
TypesByReferenceIndex[typeRefIndex] = referencedType; TypesByReferenceIndex[typeRefIndex] = referencedType;
return referencedType; return referencedType;

View File

@@ -729,77 +729,6 @@ namespace Il2CppInspector.Reflection {
DeclaredEvents.Add(new EventInfo(pkg, e, this)); DeclaredEvents.Add(new EventInfo(pkg, e, this));
} }
// Initialize type from type reference (TypeRef)
// Much of the following is adapted from il2cpp::vm::Class::FromIl2CppType
internal static TypeInfo FromTypeReference(Il2CppModel model, Il2CppType typeRef) {
var image = model.Package.BinaryImage;
TypeInfo underlyingType;
switch (typeRef.type) {
// Classes defined in the metadata (reference to a TypeDef)
case Il2CppTypeEnum.IL2CPP_TYPE_CLASS:
case Il2CppTypeEnum.IL2CPP_TYPE_VALUETYPE:
underlyingType = model.TypesByDefinitionIndex[typeRef.datapoint]; // klassIndex
break;
// Constructed types
case Il2CppTypeEnum.IL2CPP_TYPE_GENERICINST:
// TODO: Replace with array load from Il2CppMetadataRegistration.genericClasses
var generic = image.ReadMappedObject<Il2CppGenericClass>(typeRef.datapoint); // Il2CppGenericClass *
// We have seen one test case where the TypeRef can point to no generic instance
// This is going to leave the TypeInfo in an undefined state
if (generic.typeDefinitionIndex == 0x0000_0000_ffff_ffff)
return null;
var genericTypeDef = model.TypesByDefinitionIndex[generic.typeDefinitionIndex];
// Get the instantiation
// TODO: Replace with array load from Il2CppMetadataRegistration.genericInsts
var genericInstance = image.ReadMappedObject<Il2CppGenericInst>(generic.context.class_inst);
var genericArguments = model.ResolveGenericArguments(genericInstance);
underlyingType = genericTypeDef.MakeGenericType(genericArguments);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_ARRAY:
var descriptor = image.ReadMappedObject<Il2CppArrayType>(typeRef.datapoint);
var elementType = model.GetTypeFromVirtualAddress(descriptor.etype);
underlyingType = elementType.MakeArrayType(descriptor.rank);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_SZARRAY:
elementType = model.GetTypeFromVirtualAddress(typeRef.datapoint);
underlyingType = elementType.MakeArrayType(1);
break;
case Il2CppTypeEnum.IL2CPP_TYPE_PTR:
elementType = model.GetTypeFromVirtualAddress(typeRef.datapoint);
underlyingType = elementType.MakePointerType();
break;
// Generic type and generic method parameters
case Il2CppTypeEnum.IL2CPP_TYPE_VAR:
case Il2CppTypeEnum.IL2CPP_TYPE_MVAR:
underlyingType = model.GetGenericParameterType((int)typeRef.datapoint);
break;
// Primitive types
default:
underlyingType = FromTypeEnum(model, typeRef.type);
break;
}
// Create a reference type if necessary
return typeRef.byref ? underlyingType.MakeByRefType() : underlyingType;
}
// Basic primitive types are specified via a flag value
internal static TypeInfo FromTypeEnum(Il2CppModel model, Il2CppTypeEnum t) {
if ((int)t >= Il2CppConstants.FullNameTypeString.Count)
return null;
var fqn = Il2CppConstants.FullNameTypeString[(int)t];
return model.TypesByFullName[fqn];
}
// Initialize a type from a concrete generic instance // Initialize a type from a concrete generic instance
private TypeInfo(TypeInfo genericTypeDef, TypeInfo[] genericArgs) : base(genericTypeDef.Assembly) { private TypeInfo(TypeInfo genericTypeDef, TypeInfo[] genericArgs) : base(genericTypeDef.Assembly) {
if (!genericTypeDef.IsGenericTypeDefinition) if (!genericTypeDef.IsGenericTypeDefinition)