[sre] Map fieldref tokens to MonoClassField*
[mono.git] / mono / metadata / sre.c
index cc40e048493bbc1bf8f9d1ccf55cc14ad2cc7de4..b899c830e7898d960ad8418a4afb49c70ef2b882 100644 (file)
@@ -374,6 +374,12 @@ mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
        mono_image_property_insert (image, obj, MONO_PROP_DYNAMIC_CATTR, ainfo);
        mono_loader_unlock ();
 
+}
+#else
+//FIXME some code compiled under DISABLE_REFLECTION_EMIT depends on this function, we should be more aggressively disabling things
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
 }
 #endif
 
@@ -740,7 +746,7 @@ is_field_on_inst (MonoClassField *field)
 
 #ifndef DISABLE_REFLECTION_EMIT
 static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, MonoClassField *field)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field)
 {
        MonoType *type;
        guint32 token;
@@ -748,7 +754,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M
        g_assert (field);
        g_assert (field->parent);
 
-       token = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->handleref_managed, MONO_HANDLE_RAW (f)));
+       token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
        if (token)
                return token;
 
@@ -761,7 +767,7 @@ mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoObjectHandle f, M
        token = mono_image_get_memberref_token (assembly, &field->parent->byval_arg,
                                                                                        mono_field_get_name (field),
                                                                                        mono_dynimage_encode_fieldref_signature (assembly, field->parent->image, type));
-       mono_g_hash_table_insert (assembly->handleref_managed, MONO_HANDLE_RAW (f), GUINT_TO_POINTER(token));
+       g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
        return token;
 }
 
@@ -1022,7 +1028,7 @@ mono_image_insert_string (MonoReflectionModuleBuilderHandle ref_module, MonoStri
        }
 
        token = MONO_TOKEN_STRING | idx;
-       mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str));
+       mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, str), MONO_DYN_IMAGE_TOK_NEW);
 
 leave:
        HANDLE_FUNCTION_RETURN_VAL (token);
@@ -1092,7 +1098,7 @@ mono_image_create_method_token (MonoDynamicImage *assembly, MonoObjectHandle obj
                g_error ("requested method token for %s\n", klass->name);
        }
 
-       mono_dynamic_image_register_token (assembly, token, obj);
+       mono_dynamic_image_register_token (assembly, token, obj, MONO_DYN_IMAGE_TOK_NEW);
        return token;
 fail:
        g_assert (!mono_error_ok (error));
@@ -1115,25 +1121,35 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                         gboolean create_open_instance, gboolean register_token,
                         MonoError *error)
 {
+       HANDLE_FUNCTION_ENTER ();
        guint32 token = 0;
 
        error_init (error);
 
        MonoClass *klass = mono_handle_class (obj);
+       MonoObjectHandle register_obj = MONO_HANDLE_NEW (MonoObject, NULL);
+       MONO_HANDLE_ASSIGN (register_obj, obj);
 
        /* Check for user defined reflection objects */
        /* TypeDelegator is the only corlib type which doesn't look like a MonoReflectionType */
        if (klass->image != mono_defaults.corlib || (strcmp (klass->name, "TypeDelegator") == 0)) {
                mono_error_set_not_supported (error, "User defined subclasses of System.Type are not yet supported");
-               return 0;
+               goto leave;
        }
 
+       /* This function is called from ModuleBuilder:getToken multiple times for the same objects */
+       int how_collide = MONO_DYN_IMAGE_TOK_SAME_OK;
+
        if (strcmp (klass->name, "RuntimeType") == 0) {
                MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
-               return_val_if_nok (error, 0);
+               if (!is_ok (error))
+                       goto leave;
                MonoClass *mc = mono_class_from_mono_type (type);
                token = mono_metadata_token_from_dor (
                        mono_dynimage_encode_typedef_or_ref_full (assembly, type, !mono_class_is_gtd (mc) || create_open_instance));
+               /* If it's a RuntimeType now, we could have registered a
+                * TypeBuilder for it before, so replacing is okay. */
+               how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
        } else if (strcmp (klass->name, "MonoCMethod") == 0 ||
                           strcmp (klass->name, "MonoMethod") == 0) {
                MonoReflectionMethodHandle m = MONO_HANDLE_CAST (MonoReflectionMethod, obj);
@@ -1152,6 +1168,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                                 * FIXME: do the equivalent for Fields.
                                 */
                                token = method->token;
+                               how_collide = MONO_DYN_IMAGE_TOK_REPLACE;
                        } else {
                                /*
                                 * Each token should have a unique index, but the indexes are
@@ -1160,6 +1177,7 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                                 */
                                method_table_idx --;
                                token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+                               how_collide = MONO_DYN_IMAGE_TOK_NEW;
                        }
                } else {
                        token = mono_image_get_methodref_token (assembly, method, create_open_instance);
@@ -1172,31 +1190,32 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
                        static guint32 field_table_idx = 0xffffff;
                        field_table_idx --;
                        token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+                       how_collide = MONO_DYN_IMAGE_TOK_NEW;
                } else {
-                       token = mono_image_get_fieldref_token (assembly, obj, field);
+                       token = mono_image_get_fieldref_token (assembly, field);
                }
                /*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
        } else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
                MonoReflectionArrayMethodHandle m = MONO_HANDLE_CAST (MonoReflectionArrayMethod, obj);
-               token = mono_image_get_array_token (assembly, m, error);
-               return_val_if_nok (error, 0);
+               guint32 array_token = mono_image_get_array_token (assembly, m, error);
+               if (!is_ok (error))
+                       goto leave;
+               token = array_token;
        } else if (strcmp (klass->name, "SignatureHelper") == 0) {
                MonoReflectionSigHelperHandle s = MONO_HANDLE_CAST (MonoReflectionSigHelper, obj);
-               token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
-               return_val_if_nok (error, 0);
-       } else if (strcmp (klass->name, "EnumBuilder") == 0) {
-               MonoType *type = mono_reflection_type_handle_mono_type (MONO_HANDLE_CAST (MonoReflectionType, obj), error);
-               return_val_if_nok (error, 0);
-               token = mono_metadata_token_from_dor (
-                       mono_image_typedef_or_ref (assembly, type));
+               guint32 sig_token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s, error);
+               if (!is_ok (error))
+                       goto leave;
+               token = sig_token;
        } else {
                g_error ("requested token for %s\n", klass->name);
        }
 
        if (register_token)
-               mono_dynamic_image_register_token (assembly, token, obj);
+               mono_dynamic_image_register_token (assembly, token, register_obj, how_collide);
 
-       return token;
+leave:
+       HANDLE_FUNCTION_RETURN_VAL (token);
 }
 
 
@@ -1204,6 +1223,25 @@ mono_image_create_token (MonoDynamicImage *assembly, MonoObjectHandle obj,
 
 #ifndef DISABLE_REFLECTION_EMIT
 
+static gboolean
+assemblybuilderaccess_can_refonlyload (guint32 access)
+{
+       return (access & 0x4) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_run (guint32 access)
+{
+       return (access & MonoAssemblyBuilderAccess_Run) != 0;
+}
+
+static gboolean
+assemblybuilderaccess_can_save (guint32 access)
+{
+       return (access & MonoAssemblyBuilderAccess_Save) != 0;
+}
+
+
 /*
  * mono_reflection_dynimage_basic_init:
  * @assembly: an assembly builder object
@@ -1222,14 +1260,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
        if (assemblyb->dynamic_assembly)
                return;
 
-#if HAVE_BOEHM_GC
-       /* assembly->assembly.image might be GC allocated */
-       assembly = assemblyb->dynamic_assembly = (MonoDynamicAssembly *)GC_MALLOC (sizeof (MonoDynamicAssembly));
-#else
        assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
-#endif
 
-       mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+       MONO_PROFILER_RAISE (assembly_loading, (&assembly->assembly));
        
        assembly->assembly.ref_count = 1;
        assembly->assembly.dynamic = TRUE;
@@ -1265,8 +1298,9 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
                        assembly->assembly.aname.revision = 0;
         }
 
-       assembly->run = assemblyb->access != 2;
-       assembly->save = assemblyb->access != 1;
+       assembly->assembly.ref_only = assemblybuilderaccess_can_refonlyload (assemblyb->access);
+       assembly->run = assemblybuilderaccess_can_run (assemblyb->access);
+       assembly->save = assemblybuilderaccess_can_save (assemblyb->access);
        assembly->domain = domain;
 
        char *assembly_name = mono_string_to_utf8_checked (assemblyb->name, &error);
@@ -1290,7 +1324,7 @@ mono_reflection_dynimage_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 
        register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
        
-       mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+       MONO_PROFILER_RAISE (assembly_loaded, (&assembly->assembly));
        
        mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
 }
@@ -1650,10 +1684,18 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *
                        goto leave;
                g_assert (base);
                gint32 rank = MONO_HANDLE_GETVAL (sre_array, rank);
-               if (rank == 0) //single dimentional array
-                       result = &mono_array_class_get (mono_class_from_mono_type (base), 1)->byval_arg;
-               else
-                       result = &mono_bounded_array_class_get (mono_class_from_mono_type (base), rank, TRUE)->byval_arg;
+               MonoClass *eclass = mono_class_from_mono_type (base);
+               result = mono_image_new0 (eclass->image, MonoType, 1);
+               if (rank == 0)  {
+                       result->type = MONO_TYPE_SZARRAY;
+                       result->data.klass = eclass;
+               } else {
+                       MonoArrayType *at = (MonoArrayType *)mono_image_alloc0 (eclass->image, sizeof (MonoArrayType));
+                       result->type = MONO_TYPE_ARRAY;
+                       result->data.array = at;
+                       at->eklass = eclass;
+                       at->rank = rank;
+               }
                MONO_HANDLE_SETVAL (ref, type, MonoType*, result);
        } else if (is_sre_byref (klass)) {
                MonoReflectionDerivedTypeHandle sre_byref = MONO_HANDLE_CAST (MonoReflectionDerivedType, ref);
@@ -2430,7 +2472,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
        klass->type_token = MONO_TOKEN_TYPE_DEF | table_idx;
        mono_class_set_flags (klass, MONO_HANDLE_GETVAL (ref_tb, attrs));
        
-       mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
+       MONO_PROFILER_RAISE (class_loading, (klass));
 
        klass->element_class = klass;
 
@@ -2451,7 +2493,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
        */
        mono_image_append_class_to_reflection_info_set (klass);
 
-       mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb));
+       mono_dynamic_image_register_token (dynamic_image, MONO_TOKEN_TYPE_DEF | table_idx, MONO_HANDLE_CAST (MonoObject, ref_tb), MONO_DYN_IMAGE_TOK_NEW);
 
        if ((!strcmp (klass->name, "ValueType") && !strcmp (klass->name_space, "System")) ||
                        (!strcmp (klass->name, "Object") && !strcmp (klass->name_space, "System")) ||
@@ -2522,7 +2564,7 @@ reflection_setup_internal_class_internal (MonoReflectionTypeBuilderHandle ref_tb
 
        /*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
 
-       mono_profiler_class_loaded (klass, MONO_PROFILE_OK);
+       MONO_PROFILER_RAISE (class_loaded, (klass));
        
 leave:
        mono_loader_unlock ();
@@ -2750,7 +2792,7 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                        (rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
                m = (MonoMethod *)image_g_new0 (image, MonoMethodPInvoke, 1);
        else
-               m = (MonoMethod *)image_g_new0 (image, MonoMethodWrapper, 1);
+               m = (MonoMethod *)image_g_new0 (image, MonoDynamicMethod, 1);
 
        wrapperm = (MonoMethodWrapper*)m;
 
@@ -2845,6 +2887,8 @@ reflection_methodbuilder_to_mono_method (MonoClass *klass,
                }
 
                wrapperm->header = header;
+               MonoDynamicMethod *dm = (MonoDynamicMethod*)wrapperm;
+               dm->assembly = klass->image->assembly;
        }
 
        if (rmb->generic_params) {
@@ -3881,6 +3925,7 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono
                rmb.refs [i + 1] = handle_class;
        }               
 
+       MonoAssembly *ass = NULL;
        if (mb->owner) {
                MonoType *owner_type = mono_reflection_type_get_handle ((MonoReflectionType*)mb->owner, error);
                if (!is_ok (error)) {
@@ -3888,11 +3933,14 @@ reflection_create_dynamic_method (MonoReflectionDynamicMethodHandle ref_mb, Mono
                        return FALSE;
                }
                klass = mono_class_from_mono_type (owner_type);
+               ass = klass->image->assembly;
        } else {
                klass = mono_defaults.object_class;
+               ass = (mb->module && mb->module->image) ? mb->module->image->assembly : NULL;
        }
 
        mb->mhandle = handle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig, error);
+       ((MonoDynamicMethod*)handle)->assembly = ass;
        g_free (rmb.refs);
        return_val_if_nok (error, FALSE);
 
@@ -4264,7 +4312,7 @@ mono_reflection_type_handle_mono_type (MonoReflectionTypeHandle ref, MonoError *
 void
 mono_sre_generic_param_table_entry_free (GenericParamTableEntry *entry)
 {
-       mono_gc_deregister_root ((char*) &entry->gparam);
+       MONO_GC_UNREGISTER_ROOT_IF_MOVING (entry->gparam);
        g_free (entry);
 }
 
@@ -4314,19 +4362,17 @@ void
 ves_icall_ModuleBuilder_RegisterToken (MonoReflectionModuleBuilderHandle mb, MonoObjectHandle obj, guint32 token, MonoError *error)
 {
        error_init (error);
-       mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj);
+       /* This function may be called by ModuleBuilder.FixupTokens to update
+        * an existing token, so replace is okay here. */
+       mono_dynamic_image_register_token (MONO_HANDLE_GETVAL (mb, dynamic_image), token, obj, MONO_DYN_IMAGE_TOK_REPLACE);
 }
 
-MonoObject*
-ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilder *mb, guint32 token)
+MonoObjectHandle
+ves_icall_ModuleBuilder_GetRegisteredToken (MonoReflectionModuleBuilderHandle mb, guint32 token, MonoError *error)
 {
-       MonoObject *obj;
-
-       mono_loader_lock ();
-       obj = (MonoObject *)mono_g_hash_table_lookup (mb->dynamic_image->tokens, GUINT_TO_POINTER (token));
-       mono_loader_unlock ();
-
-       return obj;
+       error_init (error);
+       MonoDynamicImage *dynamic_image = MONO_HANDLE_GETVAL (mb, dynamic_image);
+       return mono_dynamic_image_get_registered_token (dynamic_image, token, error);
 }
 
 #ifndef DISABLE_REFLECTION_EMIT
@@ -4347,10 +4393,24 @@ ves_icall_AssemblyBuilder_basic_init (MonoReflectionAssemblyBuilder *assemblyb)
 }
 
 void
-ves_icall_EnumBuilder_setup_enum_type (MonoReflectionType *enumtype,
-                                                                          MonoReflectionType *t)
+ves_icall_AssemblyBuilder_UpdateNativeCustomAttributes (MonoReflectionAssemblyBuilderHandle assemblyb, MonoError *error)
 {
-       enumtype->type = t->type;
+       MonoArrayHandle cattrs = MONO_HANDLE_NEW_GET (MonoArray, assemblyb, cattrs);
+
+       MonoReflectionAssemblyHandle assembly_handle = MONO_HANDLE_CAST (MonoReflectionAssembly, assemblyb);
+       MonoAssembly *assembly = MONO_HANDLE_GETVAL (assembly_handle, assembly);
+       g_assert (assembly);
+
+       mono_save_custom_attrs (assembly->image, assembly, MONO_HANDLE_RAW (cattrs));
+}
+
+void
+ves_icall_EnumBuilder_setup_enum_type (MonoReflectionTypeHandle enumtype,
+                                      MonoReflectionTypeHandle t,
+                                      MonoError *error)
+{
+       error_init (error);
+       MONO_HANDLE_SETVAL (enumtype, type, MonoType*, MONO_HANDLE_GETVAL (t, type));
 }
 
 void
@@ -4367,10 +4427,12 @@ ves_icall_ModuleBuilder_getUSIndex (MonoReflectionModuleBuilderHandle module, Mo
 }
 
 void
-ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilder *moduleb, MonoReflectionType *type)
+ves_icall_ModuleBuilder_set_wrappers_type (MonoReflectionModuleBuilderHandle moduleb, MonoReflectionTypeHandle ref_type, MonoError *error)
 {
-       MonoDynamicImage *image = moduleb->dynamic_image;
+       error_init (error);
+       MonoDynamicImage *image = MONO_HANDLE_GETVAL (moduleb, dynamic_image);
+       MonoType *type = MONO_HANDLE_GETVAL (ref_type, type);
 
-       g_assert (type->type);
-       image->wrappers_type = mono_class_from_mono_type (type->type);
+       g_assert (type);
+       image->wrappers_type = mono_class_from_mono_type (type);
 }