* the Module.ResolveXXXToken () methods to work.
*/
void
-mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObjectHandle obj)
+mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObjectHandle obj, int how_collide)
{
MONO_REQ_GC_UNSAFE_MODE;
+ g_assert (!MONO_HANDLE_IS_NULL (obj));
dynamic_image_lock (assembly);
+ MonoObject *prev = (MonoObject *)mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+ if (prev) {
+ switch (how_collide) {
+ case MONO_DYN_IMAGE_TOK_NEW:
+ g_assert_not_reached ();
+ case MONO_DYN_IMAGE_TOK_SAME_OK:
+ g_assert (prev == MONO_HANDLE_RAW (obj));
+ break;
+ case MONO_DYN_IMAGE_TOK_REPLACE:
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ }
mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), MONO_HANDLE_RAW (obj));
dynamic_image_unlock (assembly);
}
#else
void
-mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObjectHandle obj)
+mono_dynamic_image_register_token (MonoDynamicImage *assembly, guint32 token, MonoObjectHandle obj, int how_collide)
{
}
#endif
if ((klass->image == &assembly->image) && (type->type != MONO_TYPE_VAR) &&
(type->type != MONO_TYPE_MVAR)) {
token = MONO_TYPEDEFORREF_TYPEDEF | (MONO_HANDLE_GETVAL (tb, table_idx) << MONO_TYPEDEFORREF_BITS);
- mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
+ /* This function is called multiple times from sre and sre-save, so same object is okay */
+ mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
goto leave;
}
token = MONO_TYPEDEFORREF_TYPEREF | (table->next_idx << MONO_TYPEDEFORREF_BITS); /* typeref */
g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
table->next_idx ++;
- mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb));
+
+
+ if (!MONO_HANDLE_IS_NULL (tb)) {
+ /* This function is called multiple times from sre and sre-save, so same object is okay */
+ mono_dynamic_image_register_token (assembly, token, MONO_HANDLE_CAST (MonoObject, tb), MONO_DYN_IMAGE_TOK_SAME_OK);
+ }
+
leave:
HANDLE_FUNCTION_RETURN_VAL (token);
}
}
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);
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));
return 0;
}
+ /* 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);
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);
* 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
*/
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);
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);
}
}
if (register_token)
- mono_dynamic_image_register_token (assembly, token, obj);
+ mono_dynamic_image_register_token (assembly, token, obj, how_collide);
return token;
}
*/
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")) ||
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);
}
MonoObjectHandle