Merge pull request #2868 from akoeplinger/maccore-fixes
[mono.git] / mono / metadata / icall.c
index 8e2fbdf3b650902ff1cd6d1324ae2a89271b5686..c342e592a4c21c6df409727bfff139047d0e0499 100644 (file)
@@ -1270,6 +1270,22 @@ ves_icall_System_Reflection_Emit_AssemblyBuilder_InternalAddModule (MonoReflecti
        return result;
 }
 
+/**
+ * ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class:
+ * @tb: a TypeBuilder object
+ *
+ * (icall)
+ * Creates the generic class after all generic parameters have been added.
+ */
+ICALL_EXPORT void
+ves_icall_System_Reflection_Emit_TypeBuilder_create_generic_class (MonoReflectionTypeBuilder *tb)
+{
+       MonoError error;
+       (void) mono_reflection_create_generic_class (tb, &error);
+       mono_error_set_pending_exception (&error);
+}
+
+#ifndef DISABLE_REFLECTION_EMIT
 ICALL_EXPORT MonoArray*
 ves_icall_System_Reflection_Emit_CustomAttributeBuilder_GetBlob (MonoReflectionAssembly *assembly, MonoObject *ctor, MonoArray *ctorArgs, MonoArray *properties, MonoArray *propValues, MonoArray *fields, MonoArray* fieldValues)
 {
@@ -1278,9 +1294,10 @@ ves_icall_System_Reflection_Emit_CustomAttributeBuilder_GetBlob (MonoReflectionA
        mono_error_set_pending_exception (&error);
        return result;
 }
+#endif
 
 static gboolean
-get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
        MonoMethod **dest = (MonoMethod **)data;
 
@@ -1288,11 +1305,9 @@ get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer dat
        if (!managed)
                return FALSE;
 
-       if (m == *dest) {
-               *dest = NULL;
-               return FALSE;
-       }
        if (!(*dest)) {
+               if (!strcmp (m->klass->name_space, "System.Reflection"))
+                       return FALSE;
                *dest = m;
                return TRUE;
        }
@@ -1300,7 +1315,7 @@ get_caller (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer dat
 }
 
 static gboolean
-get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
        MonoMethod **dest = (MonoMethod **)data;
 
@@ -1308,9 +1323,18 @@ get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer
        if (!managed)
                return FALSE;
 
+       if (m->wrapper_type != MONO_WRAPPER_NONE)
+               return FALSE;
+
+       if (m == *dest) {
+               *dest = NULL;
+               return FALSE;
+       }
+
+       if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
+               return FALSE;
+
        if (!(*dest)) {
-               if (!strcmp (m->klass->name_space, "System.Reflection"))
-                       return FALSE;
                *dest = m;
                return TRUE;
        }
@@ -1318,7 +1342,7 @@ get_executing (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer
 }
 
 static gboolean
-get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
+get_caller_no_system_or_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed, gpointer data)
 {
        MonoMethod **dest = (MonoMethod **)data;
 
@@ -1329,13 +1353,15 @@ get_caller_no_reflection (MonoMethod *m, gint32 no, gint32 ilo, gboolean managed
        if (m->wrapper_type != MONO_WRAPPER_NONE)
                return FALSE;
 
-       if (m->klass->image == mono_defaults.corlib && !strcmp (m->klass->name_space, "System.Reflection"))
-               return FALSE;
-
        if (m == *dest) {
                *dest = NULL;
                return FALSE;
        }
+
+       if (m->klass->image == mono_defaults.corlib && ((!strcmp (m->klass->name_space, "System.Reflection"))
+                                                                                                       || (!strcmp (m->klass->name_space, "System"))))
+               return FALSE;
+
        if (!(*dest)) {
                *dest = m;
                return TRUE;
@@ -1351,6 +1377,7 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
        MonoType *type = NULL;
        MonoAssembly *assembly = NULL;
        gboolean type_resolve = FALSE;
+       MonoImage *rootimage = NULL;
 
        mono_error_init (error);
 
@@ -1361,10 +1388,23 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
         */
        m = mono_method_get_last_managed ();
        dest = m;
-
-       mono_stack_walk_no_il (get_caller_no_reflection, &dest);
-       if (!dest)
-               dest = m;
+       if (m && m->klass->image != mono_defaults.corlib) {
+               /* Happens with inlining */
+       } else {
+               /* Ugly hack: type_from_parsed_name is called from
+                * System.Type.internal_from_name, which is called most
+                * directly from System.Type.GetType(string,bool,bool) but
+                * also indirectly from places such as
+                * System.Type.GetType(string,func,func) (via
+                * System.TypeNameParser.GetType and System.TypeSpec.Resolve)
+                * so we need to skip over all of those to find the true caller.
+                *
+                * It would be nice if we had stack marks.
+                */
+               mono_stack_walk_no_il (get_caller_no_system_or_reflection, &dest);
+               if (!dest)
+                       dest = m;
+       }
 
        /*
         * FIXME: mono_method_get_last_managed() sometimes returns NULL, thus
@@ -1377,6 +1417,7 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
        if (dest) {
                assembly = dest->klass->image->assembly;
                type_resolve = TRUE;
+               rootimage = assembly->image;
        } else {
                g_warning (G_STRLOC);
        }
@@ -1384,21 +1425,28 @@ type_from_parsed_name (MonoTypeNameParse *info, MonoBoolean ignoreCase, MonoErro
        if (info->assembly.name)
                assembly = mono_assembly_load (&info->assembly, assembly ? assembly->basedir : NULL, NULL);
 
-
        if (assembly) {
                /* When loading from the current assembly, AppDomain.TypeResolve will not be called yet */
-               type = mono_reflection_get_type_checked (assembly->image, info, ignoreCase, &type_resolve, error);
+               type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
                return_val_if_nok (error, NULL);
        }
 
+       // XXXX - aleksey -
+       //  Say we're looking for System.Generic.Dict<int, Local>
+       //  we FAIL the get type above, because S.G.Dict isn't in assembly->image.  So we drop down here.
+       //  but then we FAIL AGAIN because now we pass null as the image and the rootimage and everything
+       //  is messed up when we go to construct the Local as the type arg...
+       //
+       // By contrast, if we started with Mine<System.Generic.Dict<int, Local>> we'd go in with assembly->image
+       // as the root and then even the detour into generics would still not screw us when we went to load Local.
        if (!info->assembly.name && !type) {
                /* try mscorlib */
-               type = mono_reflection_get_type_checked (NULL, info, ignoreCase, &type_resolve, error);
+               type = mono_reflection_get_type_checked (rootimage, NULL, info, ignoreCase, &type_resolve, error);
                return_val_if_nok (error, NULL);
        }
        if (assembly && !type && type_resolve) {
                type_resolve = FALSE; /* This will invoke TypeResolve if not done in the first 'if' */
-               type = mono_reflection_get_type_checked (assembly->image, info, ignoreCase, &type_resolve, error);
+               type = mono_reflection_get_type_checked (rootimage, assembly->image, info, ignoreCase, &type_resolve, error);
                return_val_if_nok (error, NULL);
        }
 
@@ -1424,10 +1472,12 @@ ves_icall_System_Type_internal_from_name (MonoString *name,
        /* mono_reflection_parse_type() mangles the string */
        if (!parsedOk) {
                mono_reflection_free_type_info (&info);
-               g_free (str);
                if (throwOnError) {
-                       mono_set_pending_exception (mono_get_exception_argument("typeName", "failed parse"));
+                       mono_error_init (&error);
+                       mono_error_set_argument (&error, "typeName", "failed parse: %s", str);
+                       mono_error_set_pending_exception (&error);
                }
+               g_free (str);
                return NULL;
        }
 
@@ -1450,7 +1500,6 @@ ves_icall_System_Type_internal_from_name (MonoString *name,
                if (throwOnError)
                        e = mono_get_exception_type_load (name, NULL);
 
-               mono_loader_clear_error ();
                if (e) {
                        mono_set_pending_exception (e);
                        return NULL;
@@ -3803,8 +3852,7 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla
        /* An optimization for calls made from Delegate:CreateDelegate () */
        if (klass->delegate && name && !strcmp (name, "Invoke") && (bflags == (BFLAGS_Public | BFLAGS_Static | BFLAGS_Instance))) {
                method = mono_get_delegate_invoke (klass);
-               if (mono_loader_get_last_error ())
-                       goto loader_error;
+               g_assert (method);
 
                g_ptr_array_add (array, method);
                return array;
@@ -3812,7 +3860,7 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla
 
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
+       if (mono_class_has_failure (klass))
                goto loader_error;
 
        if (is_generic_parameter (&klass->byval_arg))
@@ -3828,7 +3876,7 @@ mono_class_get_methods_by_name (MonoClass *klass, const char *name, guint32 bfla
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
+       if (mono_class_has_failure (klass))
                goto loader_error;              
 
        iter = NULL;
@@ -3888,8 +3936,7 @@ loader_error:
        if (mono_class_has_failure (klass)) {
                *ex = mono_class_get_exception_for_failure (klass);
        } else {
-               *ex = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
-               mono_loader_clear_error ();
+               *ex = mono_get_exception_execution_engine ("Unknown error");
        }
        return NULL;
 }
@@ -4127,7 +4174,7 @@ ves_icall_Type_GetPropertiesByName (MonoReflectionType *type, MonoString *name,
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
+       if (mono_class_has_failure (klass))
                goto loader_error;
 
        iter = NULL;
@@ -4200,9 +4247,6 @@ handle_parent:
 loader_error:
        if (mono_class_has_failure (klass)) {
                mono_error_set_exception_instance (&error, mono_class_get_exception_for_failure (klass));
-       } else {
-               mono_error_set_from_loader_error (&error);
-               mono_loader_clear_error ();
        }
 
 failure:
@@ -4261,7 +4305,7 @@ ves_icall_Type_GetEvents_internal (MonoReflectionType *type, MonoString *name, g
 handle_parent:
        mono_class_setup_methods (klass);
        mono_class_setup_vtable (klass);
-       if (mono_class_has_failure (klass) || mono_loader_get_last_error ())
+       if (mono_class_has_failure (klass))
                goto loader_error;
 
        iter = NULL;
@@ -4344,9 +4388,6 @@ handle_parent:
 loader_error:
        if (mono_class_has_failure (klass)) {
                mono_error_set_exception_instance (&error, mono_class_get_exception_for_failure (klass));
-       } else {
-               mono_error_set_from_loader_error (&error);
-               mono_loader_clear_error ();
        }
 
 failure:
@@ -4481,7 +4522,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
 
        if (module != NULL) {
                if (module->image) {
-                       type = mono_reflection_get_type_checked (module->image, &info, ignoreCase, &type_resolve, &error);
+                       type = mono_reflection_get_type_checked (module->image, module->image, &info, ignoreCase, &type_resolve, &error);
                        if (!is_ok (&error)) {
                                g_free (str);
                                mono_reflection_free_type_info (&info);
@@ -4501,7 +4542,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        if (abuilder->modules) {
                                for (i = 0; i < mono_array_length (abuilder->modules); ++i) {
                                        MonoReflectionModuleBuilder *mb = mono_array_get (abuilder->modules, MonoReflectionModuleBuilder*, i);
-                                       type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
+                                       type = mono_reflection_get_type_checked (&mb->dynamic_image->image, &mb->dynamic_image->image, &info, ignoreCase, &type_resolve, &error);
                                        if (!is_ok (&error)) {
                                                g_free (str);
                                                mono_reflection_free_type_info (&info);
@@ -4516,7 +4557,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        if (!type && abuilder->loaded_modules) {
                                for (i = 0; i < mono_array_length (abuilder->loaded_modules); ++i) {
                                        MonoReflectionModule *mod = mono_array_get (abuilder->loaded_modules, MonoReflectionModule*, i);
-                                       type = mono_reflection_get_type_checked (mod->image, &info, ignoreCase, &type_resolve, &error);
+                                       type = mono_reflection_get_type_checked (mod->image, mod->image, &info, ignoreCase, &type_resolve, &error);
                                        if (!is_ok (&error)) {
                                                g_free (str);
                                                mono_reflection_free_type_info (&info);
@@ -4529,7 +4570,7 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                        }
                }
                else {
-                       type = mono_reflection_get_type_checked (assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
+                       type = mono_reflection_get_type_checked (assembly->assembly->image, assembly->assembly->image, &info, ignoreCase, &type_resolve, &error);
                        if (!is_ok (&error)) {
                                g_free (str);
                                mono_reflection_free_type_info (&info);
@@ -4545,20 +4586,9 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                if (throwOnError)
                        e = mono_get_exception_type_load (name, NULL);
 
-               if (mono_loader_get_last_error () && mono_defaults.generic_ilist_class)
-                       e = mono_loader_error_prepare_exception (mono_loader_get_last_error ());
-
-               mono_loader_clear_error ();
-
                if (e != NULL)
                        mono_set_pending_exception (e);
                return NULL;
-       } else if (mono_loader_get_last_error ()) {
-               if (throwOnError) {
-                       mono_set_pending_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
-                       return NULL;
-               }
-               mono_loader_clear_error ();
        }
 
        if (type->type == MONO_TYPE_CLASS) {
@@ -4568,7 +4598,6 @@ ves_icall_System_Reflection_Assembly_InternalGetType (MonoReflectionAssembly *as
                if (throwOnError && mono_class_has_failure (klass)) {
                        /* report SecurityException (or others) that occured when loading the assembly */
                        MonoException *exc = mono_class_get_exception_for_failure (klass);
-                       mono_loader_clear_error ();
                        mono_set_pending_exception (exc);
                        return NULL;
                }
@@ -5603,7 +5632,6 @@ mono_module_get_types (MonoDomain *domain, MonoImage *image, MonoArray **excepti
        for (i = 1; i < tdef->rows; ++i) {
                if (!exportedOnly || mono_module_type_is_visible (tdef, image, i + 1)) {
                        klass = mono_class_get_checked (image, (i + 1) | MONO_TOKEN_TYPE_DEF, error);
-                       mono_loader_assert_no_error (); /* Plug any leaks */
                        
                        if (klass) {
                                rt = mono_type_get_object_checked (domain, &klass->byval_arg, error);
@@ -5708,8 +5736,6 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
                MonoArray *exl = NULL;
                int j, length = g_list_length (list) + ex_count;
 
-               mono_loader_clear_error ();
-
                exl = mono_array_new (domain, mono_defaults.exception_class, length);
                /* Types for which mono_class_get_checked () succeeded */
                for (i = 0, tmp = list; tmp; i++, tmp = tmp->next) {
@@ -5733,7 +5759,6 @@ ves_icall_System_Reflection_Assembly_GetTypes (MonoReflectionAssembly *assembly,
                        mono_error_set_pending_exception (&error);
                        return NULL;
                }
-               mono_loader_clear_error ();
                mono_set_pending_exception (exc);
                return NULL;
        }
@@ -8054,12 +8079,7 @@ custom_attrs_get_by_type (MonoObject *obj, MonoReflectionType *attr_type)
                return NULL;
        }
 
-       if (mono_loader_get_last_error ()) {
-               mono_set_pending_exception (mono_loader_error_prepare_exception (mono_loader_get_last_error ()));
-               return NULL;
-       } else {
-               return res;
-       }
+       return res;
 }
 
 ICALL_EXPORT MonoArray*