#include <mono/metadata/gc-internal.h>
#include <mono/metadata/mempool-internals.h>
#include <mono/metadata/security-core-clr.h>
+#include <mono/metadata/debug-helpers.h>
#if HAVE_SGEN_GC
static void* reflection_info_desc = NULL;
static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
static MonoReflectionType *mono_reflection_type_get_underlying_system_type (MonoReflectionType* t);
static MonoType* mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve);
+static MonoType* mono_reflection_type_get_handle (MonoReflectionType *ref);
+static MonoReflectionType* mono_reflection_type_resolve_user_types (MonoReflectionType *type);
+
+#define RESOLVE_TYPE(type) do { type = (void*)mono_reflection_type_resolve_user_types ((MonoReflectionType*)type); } while (0)
+#define RESOLVE_ARRAY_TYPE_ELEMENT(array, index) do { \
+ MonoReflectionType *__type = mono_array_get (array, MonoReflectionType*, index); \
+ __type = mono_reflection_type_resolve_user_types (__type); \
+ mono_array_set (arr, MonoReflectionType*, index, __type); \
+} while (0)
+
+#define mono_type_array_get_and_resolve(array, index) mono_reflection_type_get_handle ((MonoReflectionType*)mono_array_get (array, gpointer, index))
void
mono_reflection_init (void)
return;
}
- if (type->type ||
- ((type = mono_reflection_type_get_underlying_system_type (type)) && type->type)) {
- encode_type (assembly, type->type, buf);
- return;
- }
-
- g_assert_not_reached ();
-
+ encode_type (assembly, mono_reflection_type_get_handle (type), buf);
}
static void
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modreq, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modreq, i);
sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
- sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
}
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modopt, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modopt, i);
sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
- sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod));
}
}
}
if (mb->param_modopt && (i < mono_array_length (mb->param_modopt)))
modopt = mono_array_get (mb->param_modopt, MonoArray*, i);
encode_custom_modifiers (assembly, modreq, modopt, &buf);
- pt = mono_type_array_get (mb->parameters, i);
+ pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
if (notypes)
for (i = 0; i < notypes; ++i) {
MonoReflectionType *pt;
- pt = mono_type_array_get (mb->opt_types, i);
+ pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
if (lb->is_pinned)
sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
- encode_reflection_type (assembly, monotype_cast (lb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)lb->type, &buf);
}
sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sigbuffer_free (&buf);
clause->handler_offset = ex_block->start;
clause->handler_len = ex_block->len;
if (ex_block->extype) {
- clause->data.catch_class = mono_class_from_mono_type (monotype_cast (ex_block->extype)->type);
+ clause->data.catch_class = mono_class_from_mono_type (mono_reflection_type_get_handle (ex_block->extype));
} else {
if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
clause->data.filter_offset = ex_block->filter_offset;
mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
finally_start = ex_block->start + ex_block->len;
if (ex_block->extype) {
- val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, monotype_cast (ex_block->extype)->type));
+ val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (ex_block->extype)));
} else {
if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
val = ex_block->filter_offset;
memset (rmb, 0, sizeof (ReflectionMethodBuilder));
rmb->ilgen = mb->ilgen;
- rmb->rtype = monotype_cast (mb->rtype);
+ rmb->rtype = mono_reflection_type_resolve_user_types (mb->rtype);
rmb->parameters = mb->parameters;
rmb->generic_params = mb->generic_params;
rmb->generic_container = mb->generic_container;
sigbuffer_add_value (&buf, 0x06);
encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
/* encode custom attributes before the type */
- encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sigbuffer_free (&buf);
return idx;
/* custom marshaler type name */
if (minfo->marshaltype || minfo->marshaltyperef) {
if (minfo->marshaltyperef)
- str = type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
+ str = type_get_fully_qualified_name (mono_reflection_type_get_handle (minfo->marshaltyperef));
else
str = mono_string_to_utf8 (minfo->marshaltype);
len = strlen (str);
sigbuffer_add_byte (&buf, 0x08);
sigbuffer_add_value (&buf, nparams);
if (mb) {
- encode_reflection_type (assembly, monotype_cast (mb->rtype), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)mb->rtype, &buf);
for (i = 0; i < nparams; ++i) {
- MonoReflectionType *pt = mono_type_array_get (mb->parameters, i);
+ MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
} else if (smb && smb->parameters) {
/* the property type is the last param */
- encode_reflection_type (assembly, mono_type_array_get (smb->parameters, nparams), &buf);
+ encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf);
for (i = 0; i < nparams; ++i) {
- MonoReflectionType *pt = mono_type_array_get (smb->parameters, i);
+ MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
} else {
- encode_reflection_type (assembly, monotype_cast (fb->type), &buf);
+ encode_reflection_type (assembly, (MonoReflectionType*)fb->type, &buf);
}
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
pos = 0;
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modreq, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modreq, i);
t->modifiers [pos].required = 1;
- t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+ t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
- MonoReflectionType *mod = mono_type_array_get (modopt, i);
+ MonoType *mod = mono_type_array_get_and_resolve (modopt, i);
t->modifiers [pos].required = 0;
- t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod->type);
+ t->modifiers [pos].token = mono_image_typedef_or_ref (assembly, mod);
pos ++;
}
}
/* fb->type does not include the custom modifiers */
/* FIXME: We should do this in one place when a fieldbuilder is created */
if (fb->modreq || fb->modopt) {
- custom = add_custom_modifiers (assembly, monotype_cast (fb->type)->type, fb->modreq, fb->modopt);
+ custom = add_custom_modifiers (assembly, mono_reflection_type_get_handle (fb->type), fb->modreq, fb->modopt);
sig = fieldref_encode_signature (assembly, custom);
g_free (custom);
} else {
- sig = fieldref_encode_signature (assembly, monotype_cast (fb->type)->type);
+ sig = fieldref_encode_signature (assembly, mono_reflection_type_get_handle (fb->type));
}
parent = create_generic_typespec (assembly, (MonoReflectionTypeBuilder *) fb->typeb);
modopts = mono_array_get (helper->modopts, MonoArray*, i);
encode_custom_modifiers (assembly, modreqs, modopts, &buf);
- pt = mono_type_array_get (helper->arguments, i);
+ pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
encode_reflection_type (assembly, pt, &buf);
}
idx = sigbuffer_add_to_blob_cached (assembly, &buf);
sig->call_convention = reflection_cc_to_file (m->call_conv);
sig->param_count = nparams;
sig->ret = m->ret? m->ret->type: &mono_defaults.void_class->byval_arg;
- for (i = 0; i < nparams; ++i) {
- MonoReflectionType *t = mono_type_array_get (m->parameters, i);
- sig->params [i] = t->type;
- }
+ for (i = 0; i < nparams; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (m->parameters, i);
for (tmp = assembly->array_methods; tmp; tmp = tmp->next) {
am = tmp->data;
g_free (n);
if (tb->parent && !(is_system && is_object) &&
!(tb->attrs & TYPE_ATTRIBUTE_INTERFACE)) { /* interfaces don't have a parent */
- values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, monotype_cast (tb->parent)->type);
+ values [MONO_TYPEDEF_EXTENDS] = mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (tb->parent));
} else {
values [MONO_TYPEDEF_EXTENDS] = 0;
}
return;
for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
- MonoReflectionType *t = mono_type_array_get (assemblyb->type_forwarders, i);
+ MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType *, i);
+ MonoType *type;
if (!t)
continue;
- g_assert (t->type);
+ type = mono_reflection_type_get_handle (t);
+ g_assert (type);
- klass = mono_class_from_mono_type (t->type);
+ klass = mono_class_from_mono_type (type);
add_exported_type (assemblyb, assembly, klass);
}
} else if (strcmp (klass->name, "MethodOnTypeBuilderInst") == 0) {
MonoReflectionMethodOnTypeBuilderInst *m = (MonoReflectionMethodOnTypeBuilderInst*)obj;
token = mono_image_get_method_on_inst_token (assembly, m, create_methodspec);
+ } else if (strcmp (klass->name, "ArrayType") == 0) {
+ MonoReflectionType *type = (MonoReflectionType *)obj;
+ token = mono_metadata_token_from_dor (
+ mono_image_typedef_or_ref (assembly, mono_reflection_type_get_handle (type)));
} else {
g_error ("requested token for %s\n", klass->name);
}
}
#ifndef DISABLE_REFLECTION_EMIT
+
+static gboolean
+is_corlib_type (MonoReflectionType *ref)
+{
+ return ref && mono_object_class (ref)->image == mono_defaults.corlib;
+}
+
+static gboolean
+is_sre_usertype (MonoReflectionType *ref)
+{
+ MonoClass *class = mono_object_class (ref);
+ return ref && class->image == mono_defaults.corlib && strcmp ("TypeDelegator", class->name);
+}
+
+static gboolean
+is_sre_array (MonoReflectionType *ref)
+{
+ return ref && is_corlib_type (ref) &&
+ !strcmp ("ArrayType", mono_object_class (ref)->name) &&
+ !strcmp ("System.Reflection.Emit", mono_object_class (ref)->name_space);
+}
+
static MonoType*
-mono_reflection_type_get_handle (MonoReflectionType* t)
+mono_reflection_type_get_handle (MonoReflectionType* ref)
+{
+ if (!ref)
+ return NULL;
+ if (ref->type)
+ return ref->type;
+
+ if (!is_sre_usertype (ref))
+ ref = mono_reflection_type_get_underlying_system_type (ref);
+
+ if (is_sre_array (ref)) {
+ MonoType *res;
+ MonoReflectionArrayType *sre_array = (MonoReflectionArrayType*)ref;
+ MonoType *base = mono_reflection_type_get_handle (sre_array->element_type);
+ g_assert (base);
+ res = &mono_array_class_get (mono_class_from_mono_type (base), sre_array->rank)->byval_arg;
+ sre_array->type.type = res;
+ return res;
+ }
+
+ g_error ("Cannot handle corlib user type %s", mono_type_full_name (&mono_object_class(ref)->byval_arg));
+ return NULL;
+}
+
+static MonoReflectionType*
+mono_reflection_type_resolve_user_types (MonoReflectionType *type)
{
- if (t->type)
- return t->type;
+ if (!type || type->type)
+ return type;
- t = mono_reflection_type_get_underlying_system_type (t);
- if (t)
- return t->type;
+ if (!is_sre_usertype (type)) {
+ type = mono_reflection_type_get_underlying_system_type (type);
+ if (!is_sre_usertype (type))
+ mono_raise_exception (mono_get_exception_not_supported ("User defined subclasses of System.Type are not yet supported22"));
+ }
- return NULL;
+ return type;
+}
+
+void
+mono_reflection_create_unmanaged_type (MonoReflectionType *type)
+{
+ mono_reflection_type_get_handle (type);
}
/**
sig = image_g_malloc0 (image, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
sig->param_count = count;
sig->sentinelpos = -1; /* FIXME */
- for (i = 0; i < count; ++i) {
- MonoReflectionType *pt = mono_type_array_get (parameters, i);
- sig->params [i] = mono_reflection_type_get_handle (pt);
- }
+ for (i = 0; i < count; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (parameters, i);
return sig;
}
sig = parameters_to_signature (image, method->parameters);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
- sig->ret = method->rtype? monotype_cast (method->rtype)->type: &mono_defaults.void_class->byval_arg;
+ sig->ret = method->rtype? mono_reflection_type_get_handle (method->rtype): &mono_defaults.void_class->byval_arg;
sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
return sig;
}
if (strcmp (klass->name, "PropertyBuilder") == 0) {
MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *)prop;
*name = mono_string_to_utf8 (pb->name);
- *type = monotype_cast (pb->type)->type;
+ *type = mono_reflection_type_get_handle (pb->type);
} else {
MonoReflectionProperty *p = (MonoReflectionProperty *)prop;
*name = g_strdup (p->property->name);
if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)field;
*name = mono_string_to_utf8 (fb->name);
- *type = monotype_cast (fb->type)->type;
+ *type = mono_reflection_type_get_handle (fb->type);
} else {
MonoReflectionField *f = (MonoReflectionField *)field;
*name = g_strdup (mono_field_get_name (f->field));
MONO_ARCH_SAVE_REGS;
- CHECK_MONOTYPE (tb->parent);
+ RESOLVE_TYPE (tb->parent);
mono_loader_lock ();
/* check so we can compile corlib correctly */
if (strcmp (mono_object_class (tb->parent)->name, "TypeBuilder") == 0) {
/* mono_class_setup_mono_type () guaranteess type->data.klass is valid */
- parent = monotype_cast (tb->parent)->type->data.klass;
+ parent = mono_reflection_type_get_handle (tb->parent)->data.klass;
} else {
- parent = mono_class_from_mono_type (monotype_cast (tb->parent)->type);
+ parent = mono_class_from_mono_type (mono_reflection_type_get_handle (tb->parent));
}
} else {
parent = NULL;
fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
- if (!mono_type_is_valid_enum_basetype (monotype_cast (fb->type)->type)) {
+ if (!mono_type_is_valid_enum_basetype (mono_reflection_type_get_handle (fb->type))) {
mono_loader_unlock ();
return;
}
- enum_basetype = monotype_cast (fb->type)->type;
+ enum_basetype = mono_reflection_type_get_handle (fb->type);
klass->element_class = mono_class_from_mono_type (enum_basetype);
if (!klass->element_class)
klass->element_class = mono_class_from_mono_type (enum_basetype);
case MONO_NATIVE_CUSTOM:
if (minfo->marshaltyperef)
res->data.custom_data.custom_name =
- type_get_fully_qualified_name (monotype_cast (minfo->marshaltyperef)->type);
+ type_get_fully_qualified_name (mono_reflection_type_get_handle (minfo->marshaltyperef));
if (minfo->mcookie)
res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
break;
mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
header->locals [i] = image_g_new0 (image, MonoType, 1);
- memcpy (header->locals [i], monotype_cast (lb->type)->type, sizeof (MonoType));
+ memcpy (header->locals [i], mono_reflection_type_get_handle (lb->type), sizeof (MonoType));
}
header->num_clauses = num_clauses;
field->name = mono_string_to_utf8 (fb->name);
if (fb->attrs || fb->modreq || fb->modopt) {
- field->type = mono_metadata_type_dup (NULL, monotype_cast (fb->type)->type);
+ field->type = mono_metadata_type_dup (NULL, mono_reflection_type_get_handle (fb->type));
field->type->attrs = fb->attrs;
g_assert (klass->image->dynamic);
g_free (field->type);
field->type = custom;
} else {
- field->type = monotype_cast (fb->type)->type;
+ field->type = mono_reflection_type_get_handle (fb->type);
}
if (fb->offset != -1)
field->offset = fb->offset;
klass->interface_count = mono_array_length (tb->interfaces);
klass->interfaces = mono_image_alloc (klass->image, sizeof (MonoClass*) * klass->interface_count);
for (i = 0; i < klass->interface_count; ++i) {
- MonoReflectionType *iface = mono_type_array_get (tb->interfaces, i);
- klass->interfaces [i] = mono_class_from_mono_type (iface->type);
+ MonoType *iface = mono_type_array_get_and_resolve (tb->interfaces, i);
+ klass->interfaces [i] = mono_class_from_mono_type (iface);
ensure_runtime_vtable (klass->interfaces [i]);
}
klass->interfaces_inited = 1;
field = &klass->fields [i];
field->name = mono_string_to_utf8_image (image, fb->name);
if (fb->attrs) {
- field->type = mono_metadata_type_dup (klass->image, monotype_cast (fb->type)->type);
+ field->type = mono_metadata_type_dup (klass->image, mono_reflection_type_get_handle (fb->type));
field->type->attrs = fb->attrs;
} else {
- field->type = monotype_cast (fb->type)->type;
+ field->type = mono_reflection_type_get_handle (fb->type);
}
if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
klass->ext->field_def_values [i].data = mono_array_addr (fb->rva_data, char, 0);
return;
for (i = 0; i < mono_array_length (arr); ++i)
- CHECK_MONOTYPE (mono_array_get (arr, gpointer, i));
+ RESOLVE_ARRAY_TYPE_ELEMENT (arr, i);
}
MonoReflectionType*
/*
* Check for user defined Type subclasses.
*/
- CHECK_MONOTYPE (tb->parent);
+ RESOLVE_TYPE (tb->parent);
check_array_for_usertypes (tb->interfaces);
if (tb->fields) {
for (i = 0; i < mono_array_length (tb->fields); ++i) {
MonoReflectionFieldBuilder *fb = mono_array_get (tb->fields, gpointer, i);
if (fb) {
- CHECK_MONOTYPE (fb->type);
+ RESOLVE_TYPE (fb->type);
check_array_for_usertypes (fb->modreq);
check_array_for_usertypes (fb->modopt);
if (fb->marshal_info && fb->marshal_info->marshaltyperef)
- CHECK_MONOTYPE (fb->marshal_info->marshaltyperef);
+ RESOLVE_TYPE (fb->marshal_info->marshaltyperef);
}
}
}
for (i = 0; i < mono_array_length (tb->methods); ++i) {
MonoReflectionMethodBuilder *mb = mono_array_get (tb->methods, gpointer, i);
if (mb) {
- CHECK_MONOTYPE (mb->rtype);
+ RESOLVE_TYPE (mb->rtype);
check_array_for_usertypes (mb->return_modreq);
check_array_for_usertypes (mb->return_modopt);
check_array_for_usertypes (mb->parameters);
sigbuffer_add_value (&buf, 0x07);
sigbuffer_add_value (&buf, na);
for (i = 0; i < na; ++i) {
- MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
encode_reflection_type (assembly, type, &buf);
}
sigbuffer_add_value (&buf, 0x06);
for (i = 0; i < na; ++i) {
- MonoReflectionType *type = mono_type_array_get (sig->arguments, i);
+ MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType*, i);
encode_reflection_type (assembly, type, &buf);
}
mono_loader_unlock ();
if (!obj) {
if (valid_token)
- g_assert_not_reached ();
+ g_error ("Could not find required dynamic token 0x%08x", token);
else
return NULL;
}
sig->param_count = nargs;
/* TODO: Copy type ? */
sig->ret = helper->return_type->type;
- for (i = 0; i < nargs; ++i) {
- MonoReflectionType *rt = mono_type_array_get (helper->arguments, i);
- sig->params [i] = rt->type;
- }
+ for (i = 0; i < nargs; ++i)
+ sig->params [i] = mono_type_array_get_and_resolve (helper->arguments, i);
result = sig;
*handle_class = NULL;
result = inflate_mono_method (inflated_klass, m->mb->mhandle, (MonoObject*)m->mb);
*handle_class = mono_defaults.methodhandle_class;
mono_metadata_free_type (type);
+ } else if (strcmp (mono_object_get_class(obj)->name, "ArrayType") == 0) {
+ MonoReflectionType *ref_type = (MonoReflectionType *)obj;
+ MonoType *type = mono_reflection_type_get_handle (ref_type);
+ result = mono_class_from_mono_type (type);
+ *handle_class = mono_defaults.typehandle_class;
} else {
g_print (obj->vtable->klass->name);
g_assert_not_reached ();