#include "il2cpp-config.h" #include #include "icalls/mscorlib/System.Reflection/MethodBase.h" #include "il2cpp-class-internals.h" #include "il2cpp-api.h" #include "vm/Class.h" #include "vm/Exception.h" #include "vm/GenericClass.h" #include "vm/Reflection.h" #include "vm/StackTrace.h" #include "vm/MetadataCache.h" #include "metadata/GenericMetadata.h" namespace il2cpp { namespace icalls { namespace mscorlib { namespace System { namespace Reflection { static Il2CppClass* il2cpp_class_get_generic_type_definition(Il2CppClass *klass) { return klass->generic_class ? il2cpp::vm::GenericClass::GetTypeDefinition(klass->generic_class) : klass; } Il2CppReflectionMethod * MethodBase::GetMethodFromHandleInternalType(intptr_t method, intptr_t type) { Il2CppClass *klass = NULL; MethodInfo* methodInfo = (MethodInfo*)method; if (type) { klass = vm::Class::FromIl2CppType((Il2CppType*)type); if (il2cpp_class_get_generic_type_definition(methodInfo->klass) != il2cpp_class_get_generic_type_definition(klass)) return NULL; // See the VerifyTwoArgumentGetMethodFromHandleWithGenericType for the failing test. Once we have support for inflating methods // we can implement this case as well and make that test pass. if (methodInfo->klass != klass) IL2CPP_NOT_IMPLEMENTED_ICALL(MethodBase::GetMethodFromHandleInternalType); } else { klass = methodInfo->klass; } return il2cpp::vm::Reflection::GetMethodObject(methodInfo, klass); } Il2CppReflectionMethod* MethodBase::GetCurrentMethod() { NOT_SUPPORTED_IL2CPP(MethodBase::GetCurrentMethod, "This icall is not supported by il2cpp. Use the il2cpp_codegen_get_method_object intrinsic instead."); return NULL; } void* /* System.Reflection.MethodBody */ MethodBase::GetMethodBodyInternal(intptr_t handle) { NOT_SUPPORTED_IL2CPP(MethodBase::GetMethodBodyInternal, "This icall is not supported by il2cpp."); return 0; } static const MethodInfo* il2cpp_method_get_equivalent_method(const MethodInfo *method, Il2CppClass *klass) { int offset = -1, i; if (method->is_inflated) { const Il2CppGenericContext *context = il2cpp::vm::MetadataCache::GetMethodGenericContext(method); if (context->method_inst) { const MethodInfo *result; //MonoMethodInflated *inflated = (MonoMethodInflated*)method; //method is inflated, we should inflate it on the other class Il2CppGenericContext newCtx; newCtx.method_inst = context->method_inst; newCtx.class_inst = context->class_inst; if (klass->generic_class) { newCtx.class_inst = klass->generic_class->context.class_inst; } else if (klass->genericContainerIndex != kGenericContainerIndexInvalid) { IL2CPP_NOT_IMPLEMENTED(il2cpp_method_get_equivalent_method: generic_container_case); //const Il2CppGenericContainer *genericContainer = il2cpp::vm::MetadataCache::GetGenericContainerFromIndex(klass->genericContainerIndex); //newCtx.class_inst = genericContainer->context.class_inst; } result = il2cpp::metadata::GenericMetadata::Inflate(method, &newCtx); return result; } } il2cpp::vm::Class::SetupMethods(method->klass); for (i = 0; i < method->klass->method_count; ++i) { if (method->klass->methods[i] == method) { offset = i; break; } } il2cpp::vm::Class::SetupMethods(klass); IL2CPP_ASSERT(offset >= 0 && offset < klass->method_count); return klass->methods[offset]; } Il2CppReflectionMethod* MethodBase::GetMethodFromHandleInternalType_native(intptr_t method_handle, intptr_t type_handle, bool genericCheck) { Il2CppReflectionMethod *res = NULL; Il2CppClass *klass; const MethodInfo *method = (const MethodInfo*)method_handle; if (type_handle && genericCheck) { klass = il2cpp_class_from_il2cpp_type((Il2CppType*)type_handle); if (il2cpp_class_get_generic_type_definition(method->klass) != il2cpp_class_get_generic_type_definition(klass)) return NULL; if (method->klass != klass) { method = il2cpp_method_get_equivalent_method(method, klass); if (!method) return NULL; } } else if (type_handle) klass = il2cpp_class_from_il2cpp_type((Il2CppType*)type_handle); else klass = method->klass; res = il2cpp_method_get_object(method, klass); return res; } } /* namespace Reflection */ } /* namespace System */ } /* namespace mscorlib */ } /* namespace icalls */ } /* namespace il2cpp */