[netcore] Implement AppDomain.TypeResolve (mono/mono#18141)
authorRyan Lucia <rylucia@microsoft.com>
Thu, 12 Dec 2019 20:00:28 +0000 (15:00 -0500)
committerGitHub <noreply@github.com>
Thu, 12 Dec 2019 20:00:28 +0000 (15:00 -0500)
Commit migrated from https://github.com/mono/mono/commit/88dde8b7634094bd24c9f32ac894912e4d073b9f

src/mono/mono/metadata/appdomain.c
src/mono/mono/metadata/reflection-internals.h
src/mono/mono/metadata/reflection.c
src/mono/mono/metadata/sre.c
src/mono/netcore/CoreFX.issues.rsp
src/mono/netcore/System.Private.CoreLib/src/LinkerDescriptor/System.Private.CoreLib.xml
src/mono/netcore/System.Private.CoreLib/src/Mono/MonoDomain.cs

index 774e0b9..de85e90 100644 (file)
@@ -811,8 +811,12 @@ leave:
 gboolean
 mono_domain_has_type_resolve (MonoDomain *domain)
 {
+       // Check whether managed code is running, and if the managed AppDomain object doesn't exist neither does the event handler
+       if (!domain->domain)
+               return FALSE;
+
 #ifdef ENABLE_NETCORE
-       return FALSE;
+       return TRUE;
 #else
        MonoObject *o;
 
@@ -823,10 +827,6 @@ mono_domain_has_type_resolve (MonoDomain *domain)
 
        MONO_STATIC_POINTER_INIT_END (MonoClassField, field)
 
-       /*pedump doesn't create an appdomin, so the domain object doesn't exist.*/
-       if (!domain->domain)
-               return FALSE;
-
        mono_field_get_value_internal ((MonoObject*)(domain->domain), field, &o);
        return o != NULL;
 #endif
@@ -855,13 +855,19 @@ mono_domain_try_type_resolve (MonoDomain *domain, char *name, MonoObject *typebu
 
        MonoReflectionAssemblyHandle ret = NULL_HANDLE_INIT;
 
+       // This will not work correctly on netcore
        if (name) {
                MonoStringHandle name_handle = mono_string_new_handle (mono_domain_get (), name, error);
                goto_if_nok (error, exit);
-               ret = mono_domain_try_type_resolve_name (domain, name_handle, error);
+               ret = mono_domain_try_type_resolve_name (domain, NULL, name_handle, error);
        } else {
+#ifndef ENABLE_NETCORE
                MONO_HANDLE_DCL (MonoObject, typebuilder);
                ret = mono_domain_try_type_resolve_typebuilder (domain, MONO_HANDLE_CAST (MonoReflectionTypeBuilder, typebuilder), error);
+#else
+               // TODO: make this work on netcore when working on SRE.TypeBuilder
+               g_assert_not_reached ();
+#endif
        }
 
 exit:
@@ -869,6 +875,50 @@ exit:
        HANDLE_FUNCTION_RETURN_OBJ (ret);
 }
 
+#ifdef ENABLE_NETCORE
+MonoReflectionAssemblyHandle
+mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, MonoStringHandle name, MonoError *error)
+{
+       MonoObjectHandle ret;
+       MonoReflectionAssemblyHandle assembly_handle;
+
+       HANDLE_FUNCTION_ENTER ();
+
+       MONO_STATIC_POINTER_INIT (MonoMethod, method)
+
+               MonoClass *alc_class = mono_class_get_assembly_load_context_class ();
+               g_assert (alc_class);
+               method = mono_class_get_method_from_name_checked (alc_class, "OnTypeResolve", -1, 0, error);
+
+       MONO_STATIC_POINTER_INIT_END (MonoMethod, method)
+
+       goto_if_nok (error, return_null);
+
+       g_assert (domain);
+       g_assert (MONO_HANDLE_BOOL (name));
+
+       if (mono_runtime_get_no_exec ())
+               goto return_null;
+
+       if (assembly) {
+               assembly_handle = mono_assembly_get_object_handle (domain, assembly, error);
+               goto_if_nok (error, return_null);
+       }
+
+       gpointer args [2];
+       args [0] = assembly ? MONO_HANDLE_RAW (assembly_handle) : NULL;
+       args [1] = MONO_HANDLE_RAW (name);
+       ret = mono_runtime_try_invoke_handle (method, NULL_HANDLE, args, error);
+       goto_if_nok (error, return_null);
+       goto exit;
+
+return_null:
+       ret = NULL_HANDLE;
+
+exit:
+       HANDLE_FUNCTION_RETURN_REF (MonoReflectionAssembly, MONO_HANDLE_CAST (MonoReflectionAssembly, ret));
+}
+#else
 /**
  * mono_class_get_appdomain_do_type_resolve_method:
  *
@@ -879,9 +929,7 @@ mono_class_get_appdomain_do_type_resolve_method (MonoError *error)
 {
        MONO_STATIC_POINTER_INIT (MonoMethod, method)
 
-       // not cached yet, fill cache under caller's lock
-
-       method = mono_class_get_method_from_name_checked (mono_class_get_appdomain_class (), "DoTypeResolve", -1, 0, error);
+               method = mono_class_get_method_from_name_checked (mono_class_get_appdomain_class (), "DoTypeResolve", -1, 0, error);
 
        MONO_STATIC_POINTER_INIT_END (MonoMethod, method)
 
@@ -901,9 +949,7 @@ mono_class_get_appdomain_do_type_builder_resolve_method (MonoError *error)
 {
        MONO_STATIC_POINTER_INIT (MonoMethod, method)
 
-       // not cached yet, fill cache under caller's lock
-
-       method = mono_class_get_method_from_name_checked (mono_class_get_appdomain_class (), "DoTypeBuilderResolve", -1, 0, error);
+               method = mono_class_get_method_from_name_checked (mono_class_get_appdomain_class (), "DoTypeBuilderResolve", -1, 0, error);
 
        MONO_STATIC_POINTER_INIT_END (MonoMethod, method)
 
@@ -924,7 +970,7 @@ mono_class_get_appdomain_do_type_builder_resolve_method (MonoError *error)
  * \returns A \c MonoReflectionAssembly or NULL if not found
  */
 MonoReflectionAssemblyHandle
-mono_domain_try_type_resolve_name (MonoDomain *domain, MonoStringHandle name, MonoError *error)
+mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, MonoStringHandle name, MonoError *error)
 {
        HANDLE_FUNCTION_ENTER ();
 
@@ -992,6 +1038,7 @@ return_null:
 exit:
        HANDLE_FUNCTION_RETURN_REF (MonoReflectionAssembly, MONO_HANDLE_CAST (MonoReflectionAssembly, ret));
 }
+#endif
 
 /**
  * mono_domain_owns_vtable_slot:
index b528146..797d1ca 100644 (file)
@@ -20,10 +20,12 @@ TYPED_HANDLE_DECL (MonoReflectionAssembly)
 TYPED_HANDLE_DECL (MonoReflectionTypeBuilder)
 
 MonoReflectionAssemblyHandle
-mono_domain_try_type_resolve_name (MonoDomain *domain, MonoStringHandle name, MonoError *error);
+mono_domain_try_type_resolve_name (MonoDomain *domain, MonoAssembly *assembly, MonoStringHandle name, MonoError *error);
 
+#ifndef ENABLE_NETCORE
 MonoReflectionAssemblyHandle
 mono_domain_try_type_resolve_typebuilder (MonoDomain *domain, MonoReflectionTypeBuilderHandle typebuilder, MonoError *error);
+#endif
 
 MonoReflectionTypeBuilderHandle
 mono_class_get_ref_info (MonoClass *klass);
index 9fd4cd9..f51f139 100644 (file)
@@ -2234,6 +2234,7 @@ mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext *alc, MonoImage
 
        MonoType *type;
        MonoReflectionAssemblyHandle reflection_assembly;
+       MonoDomain *domain = mono_alc_domain (alc);
        GString *fullName = NULL;
        GList *mod;
 
@@ -2247,7 +2248,7 @@ mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext *alc, MonoImage
 
        if (type)
                goto exit;
-       if (!mono_domain_has_type_resolve (mono_domain_get ()))
+       if (!mono_domain_has_type_resolve (domain))
                goto return_null;
 
        if (type_resolve) {
@@ -2268,7 +2269,8 @@ mono_reflection_get_type_with_rootimage (MonoAssemblyLoadContext *alc, MonoImage
        MonoStringHandle name_handle;
        name_handle = mono_string_new_handle (mono_domain_get (), fullName->str, error);
        goto_if_nok (error, return_null);
-       reflection_assembly = mono_domain_try_type_resolve_name ( mono_domain_get (), name_handle, error);
+
+       reflection_assembly = mono_domain_try_type_resolve_name (domain, image->assembly, name_handle, error);
        goto_if_nok (error, return_null);
 
        if (MONO_HANDLE_BOOL (reflection_assembly)) {
index ae200da..be32563 100644 (file)
@@ -4264,6 +4264,7 @@ ensure_complete_type (MonoClass *klass, MonoError *error)
        error_init (error);
 
        if (image_is_dynamic (klass->image) && !klass->wastypebuilder && mono_class_has_ref_info (klass)) {
+#ifndef ENABLE_NETCORE
                MonoReflectionTypeBuilderHandle tb = mono_class_get_ref_info (klass);
 
                mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb, error);
@@ -4271,6 +4272,10 @@ ensure_complete_type (MonoClass *klass, MonoError *error)
 
                // Asserting here could break a lot of code
                //g_assert (klass->wastypebuilder);
+#else
+               // TODO: make this work on netcore when working on SRE.TypeBuilder
+               g_assert_not_reached ();
+#endif
        }
 
        if (mono_class_is_ginst (klass)) {
@@ -4367,13 +4372,18 @@ mono_reflection_resolve_object (MonoImage *image, MonoObject *obj, MonoClass **h
                if (klass->wastypebuilder) {
                        /* Already created */
                        result = klass;
-               }
-               else {
+               } else {
+#ifndef ENABLE_NETCORE
                        mono_domain_try_type_resolve_typebuilder (mono_domain_get (), tb, error);
                        goto_if_nok (error, return_null);
                        result = type->data.klass;
                        g_assert (result);
+#else
+                       // TODO: make this work on netcore when working on SRE.TypeBuilder
+                       g_assert_not_reached();
+#endif
                }
+
                *handle_class = mono_defaults.typehandle_class;
        } else if (strcmp (oklass->name, "SignatureHelper") == 0) {
                MonoReflectionSigHelper *helper = (MonoReflectionSigHelper*)obj;
index 8dba0b5..4d698ea 100644 (file)
 
 # These events are not wired up in mono
 # https://github.com/mono/mono/issues/16246
--nomethod System.Tests.AppDomainTests.TypeResolve
 -nomethod System.Tests.AppDomainTests.ResourceResolve
 -nomethod System.Tests.AppDomainTests.AssemblyLoad
 -nomethod System.Tests.AppDomainTests.FirstChanceException_Called
index a302689..3215cd0 100644 (file)
@@ -5,10 +5,6 @@
                <!-- domain.c: mono_defaults.appdomain_class -->
                <type fullname="Mono.MonoDomain">
                        <field name="_mono_app_domain"/>
-                       <!-- appdomain.c: mono_domain_try_type_resolve -->
-                       <method name="DoTypeResolve" />
-                       <!-- appdomain.c: mono_domain_try_type_builder_resolve -->
-                       <method name="DoTypeBuilderResolve" />
                        <!-- appdomain.c: mono_domain_fire_assembly_load -->
                        <method name="DoAssemblyLoad" />
                </type>
index 7a04490..3e1d774 100644 (file)
@@ -24,16 +24,6 @@ namespace Mono
                        return; /* FIXME */
                }
 
-               internal Assembly? DoTypeResolve (string name)
-               {
-                       return null;
-               }
-
-               internal Assembly? DoTypeBuilderResolve (System.Reflection.Emit.TypeBuilder tb)
-               {
-                       return null;
-               }
-
                public event UnhandledExceptionEventHandler UnhandledException;
 
                public event EventHandler ProcessExit;