Commit Graph

14 Commits

Author SHA1 Message Date
Robert Xiao
652d76d6fe Implement constructors & methods on constructed generics.
We adopt roughly the same approach as the C# Reflection API: a
GenericMethodDefinition is a method which has no method parameters
substituted, but lives in a open or closed type with some or all
type parameters substituted. To ensure the uniqueness of the MethodInfo,
we cache by the method type arguments, and also cache generated
DeclaredConstructors/DeclaredMethods in the TypeInfo.

This also enables MakeGenericMethod, albeit in a slightly different form
than the Reflection API: MakeGenericMethod lives in MethodBase, so it's
callable from a constructor (even though in C# constructors cannot be
generic). This slight violation of the spec reduces code duplication, so
it's probably worth it.

Finally, VirtualAddress gets set when populating GenericMethods, and so
it'll work whether or not the methods get cached/generated ahead of
time.
2020-06-20 10:17:48 +02:00
Robert Xiao
6fb95c52da Only include GenericMethod definers in Types
Including *every* generated type in Types defeats the purpose of the
Types property, which is to list all types directly referred to by the
Il2Cpp metadata. Therefore, we return to the previous implementation:
only list types referred to by DefinitionIndex, ReferenceIndex, and
classIndexIndex.
2020-06-20 10:17:48 +02:00
Robert Xiao
f395ed3ff5 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.
2020-06-20 10:17:48 +02:00
Robert Xiao
ec6018d012 Add non-generic methods to TestGenerics
In order to select the correct generic type, model.GetGenericMethod is
changed to use Name (which includes generic parameters) instead of
BaseName. The tests for GenericMethodDefinitionInGenericClass* are also
changed to reflect the fact that the chosen methods are fully concrete.

TestGenerics now passes in its entirety.
2020-06-20 10:17:48 +02:00
Robert Xiao
c73aad08b8 Add non-generic methods in generic types to GenericMethods
GenericMethods should contain all MethodSpec-referenced methods,
including those which are non-generic methods inside generic types. This
patch adds those methods, and also implements parameter substitution for
type arguments in parameters & return types.
2020-06-20 10:17:48 +02:00
Robert Xiao
50ea6dac36 Dedup param, array and byref/pointer types
We're aiming to make TypeInfo instances unique - no two TypeInfo
instances within a given model should refer to the same type. This will
allow us to use simple reference equality for comparing types.
2020-06-20 10:17:48 +02:00
Robert Xiao
193cdcdc4a Get rid of TypesByMethodSpecClassIndex.
classIndexIndex only indexes the genericInstance, not the actual generic
instance type. Therefore, for example, A<Int32,Int32> and B<Int32,Int32>
have the same classIndexIndex because the generic parameters are the
same, despite being otherwise unrelated.

Instead of TypesByMethodSpecClassIndex, we simply call MakeGenericType
each time, relying on genericTypeInstances to dedup the resulting
instances. This patch thus also adds all of the types from
genericTypeInstances to the Il2CppModel.Types listing.
2020-06-20 10:17:48 +02:00
Robert Xiao
ab5fc836a1 Introduce a cache for generic type instantiations.
Also add MakeGenericType, which creates type instances from a generic
type definition and arguments. We will use this later to build properly
fleshed out concrete generic types.
2020-06-20 10:17:48 +02:00
Robert Xiao
2c164aec02 Change generic params/args to arrays
The C# functions for GetGenericParameters/GetGenericArguments use
Type[], not lists, so we should conform to that.

Also fix the definition of IsGenericTypeDefinition - because it's
possible for a class to be instantiated with all generic parameters.
2020-06-20 10:17:48 +02:00
Robert Xiao
996fb1ff36 Avoid recreating ref'd types that already exist
Because TypesByReferenceIndex can be populated in two places
(Il2CppModel constructor and GetTypeFromVirtualAddress), we need to
avoid generating the same type multiple times.
2020-06-20 10:17:48 +02:00
Robert Xiao
71bf353ae0 Remove ResolveGenericArguments(int) entirely
It's not really needed anymore, and it is clearer without that method.
2020-06-20 10:17:48 +02:00
Robert Xiao
7797ac2506 Refactor TypeInfo constructors
This patch replaces Il2CppModel.resolveTypeReference by a static
TypeInfo constructor, and simultaneously refactors the TypeInfo
constructors to eliminate duplication between resolveTypeReference and
the original constructors. This will make future refactoring much
easier.
2020-06-20 10:17:48 +02:00
Katy Coe
9f3211281c Model: Ensure all custom attributes are loaded 2020-02-10 06:29:48 +01:00
Katy Coe
e971cb8502 Refactor solution layout 2020-02-06 02:51:42 +01:00