-
/*
* reflection.c: Routines for creating an image at runtime.
*
static char* type_get_qualified_name (MonoType *type, MonoAssembly *ass);
static void ensure_runtime_vtable (MonoClass *klass);
static gpointer resolve_object (MonoImage *image, MonoObject *obj);
+static void encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf);
+static guint32 type_get_signature_size (MonoType *type);
+
static void
alloc_table (MonoDynamicTable *table, guint nrows)
}
}
+static void
+encode_generic_inst (MonoDynamicImage *assembly, MonoGenericInst *ginst, char *p, char **endbuf)
+{
+ int i;
+
+ if (!ginst) {
+ g_assert_not_reached ();
+ return;
+ }
+
+ mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
+ encode_type (assembly, ginst->generic_type, p, &p);
+ mono_metadata_encode_value (ginst->type_argc, p, &p);
+ for (i = 0; i < ginst->type_argc; ++i)
+ encode_type (assembly, ginst->type_argv [i], p, &p);
+
+ *endbuf = p;
+}
+
static void
encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf)
{
mono_metadata_encode_value (0, p, &p); /* FIXME: set to 0 for now */
mono_metadata_encode_value (0, p, &p);
break;
- case MONO_TYPE_GENERICINST: {
- int i;
- mono_metadata_encode_value (type->type, p, &p);
- encode_type (assembly, type->data.generic_inst->generic_type, p, &p);
- mono_metadata_encode_value (type->data.generic_inst->type_argc, p, &p);
- for (i = 0; i < type->data.generic_inst->type_argc; ++i) {
- encode_type (assembly, type->data.generic_inst->type_argv [i], p, &p);
- }
+ case MONO_TYPE_GENERICINST:
+ encode_generic_inst (assembly, type->data.generic_inst, p, &p);
break;
- }
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
mono_metadata_encode_value (type->type, p, &p);
*endbuf = p;
}
+static guint32
+generic_inst_get_signature_size (MonoGenericInst *ginst)
+{
+ guint32 size = 0;
+ int i;
+
+ if (!ginst) {
+ g_assert_not_reached ();
+ }
+
+ size += 1 + type_get_signature_size (ginst->generic_type);
+ size += 4;
+ for (i = 0; i < ginst->type_argc; ++i)
+ size += type_get_signature_size (ginst->type_argv [i]);
+
+ return size;
+}
+
+static guint32
+type_get_signature_size (MonoType *type)
+{
+ guint32 size = 0;
+
+ if (!type) {
+ g_assert_not_reached ();
+ }
+
+ if (type->byref)
+ size++;
+
+ switch (type->type){
+ case MONO_TYPE_VOID:
+ case MONO_TYPE_BOOLEAN:
+ case MONO_TYPE_CHAR:
+ case MONO_TYPE_I1:
+ case MONO_TYPE_U1:
+ case MONO_TYPE_I2:
+ case MONO_TYPE_U2:
+ case MONO_TYPE_I4:
+ case MONO_TYPE_U4:
+ case MONO_TYPE_I8:
+ case MONO_TYPE_U8:
+ case MONO_TYPE_R4:
+ case MONO_TYPE_R8:
+ case MONO_TYPE_I:
+ case MONO_TYPE_U:
+ case MONO_TYPE_STRING:
+ case MONO_TYPE_OBJECT:
+ case MONO_TYPE_TYPEDBYREF:
+ return size + 1;
+ case MONO_TYPE_PTR:
+ return size + 1 + type_get_signature_size (type->data.type);
+ case MONO_TYPE_SZARRAY:
+ return size + 1 + type_get_signature_size (&type->data.klass->byval_arg);
+
+ case MONO_TYPE_VALUETYPE:
+ case MONO_TYPE_CLASS:
+ return size + 5;
+
+ case MONO_TYPE_ARRAY:
+ return size + 7 + type_get_signature_size (&type->data.array->eklass->byval_arg);
+ case MONO_TYPE_GENERICINST:
+ return size + generic_inst_get_signature_size (type->data.generic_inst);
+ case MONO_TYPE_VAR:
+ case MONO_TYPE_MVAR:
+ return size + 5;
+
+ default:
+ g_error ("need to encode type %x", type->type);
+ return size;
+ }
+}
+
+static guint32
+method_get_signature_size (MonoMethodSignature *sig)
+{
+ guint32 size;
+ int i;
+
+ size = type_get_signature_size (sig->ret);
+ for (i = 0; i < sig->param_count; i++)
+ size += type_get_signature_size (sig->params [i]);
+
+ if (sig->generic_param_count)
+ size += 4;
+
+ return size;
+}
+
static guint32
method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
{
char *p;
int i;
guint32 nparams = sig->param_count;
- guint32 size = 10 + nparams * 10;
+ guint32 size = 11 + method_get_signature_size (sig);
guint32 idx;
char blob_size [6];
char *b = blob_size;
num_exception = method_count_clauses (mb->ilgen);
} else {
code = mb->code;
- if (code == NULL)
- mono_raise_exception (mono_get_exception_argument (NULL, "a method does not have any IL associated"));
+ if (code == NULL){
+ char *name = mono_string_to_utf8 (mb->name);
+ char *str = g_strdup_printf ("Method %s does not have any IL associated", name);
+ MonoException *exception = mono_get_exception_argument (NULL, "a method does not have any IL associated");
+ g_free (str);
+ g_free (name);
+ mono_raise_exception (exception);
+ }
code_size = mono_array_length (code);
max_stack = 8; /* we probably need to run a verifier on the code... */
mono_image_basic_method (&rmb, assembly);
}
+static char*
+type_get_fully_qualified_name (MonoType *type) {
+ char *name, *result;
+ MonoClass *klass;
+ MonoAssembly *ta;
+
+ name = mono_type_get_name (type);
+ klass = my_mono_class_from_mono_type (type);
+ ta = klass->image->assembly;
+
+ /* missing public key */
+ result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s",
+ name, ta->aname.name,
+ ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
+ ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral");
+ g_free (name);
+ return result;
+}
+
+static char*
+type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
+ MonoClass *klass;
+ MonoAssembly *ta;
+
+ klass = my_mono_class_from_mono_type (type);
+ ta = klass->image->assembly;
+ if (ta == ass || klass->image == mono_defaults.corlib)
+ return mono_type_get_name (type);
+
+ return type_get_fully_qualified_name (type);
+}
+
static guint32
fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
{
mono_metadata_encode_value (0, p, &p);
}
if (minfo->marshaltyperef) {
- str = type_get_qualified_name (minfo->marshaltyperef->type, assembly->image.assembly);
+ str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
len = strlen (str);
mono_metadata_encode_value (len, p, &p);
if (p + len >= buf + bufsize) {
values [MONO_CONSTANT_TYPE] = field_type;
values [MONO_CONSTANT_PADDING] = 0;
}
- if (fb->rva_data) {
+ if (fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) {
guint32 rva_idx;
table = &assembly->tables [MONO_TABLE_FIELDRVA];
table->rows ++;
/*
* We store it in the code section because it's simpler for now.
*/
- rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
+ if (fb->rva_data)
+ rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
+ else
+ rva_idx = mono_image_add_stream_zero (&assembly->code, mono_class_value_size (fb->handle->parent, NULL));
values [MONO_FIELD_RVA_RVA] = rva_idx + assembly->text_rva;
}
if (fb->marshal_info) {
MonoClass *k = mono_class_from_mono_type (type);
if (!k || !k->generic_inst)
return 0;
- encode_type (assembly, k->generic_inst, p, &p);
+ encode_generic_inst (assembly, k->generic_inst, p, &p);
break;
}
default:
}
static guint32
-mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoClassField *field, MonoClass *klass)
+mono_image_get_fieldref_token (MonoDynamicImage *assembly, MonoReflectionField *f)
{
+ MonoType *type;
guint32 token;
-
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field));
- if (token)
- return token;
- field->parent = klass;
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg,
- field->name, fieldref_encode_signature (assembly, field->type));
- g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
- return token;
-}
-
-static guint32
-field_encode_inflated_field (MonoDynamicImage *assembly, MonoReflectionInflatedField *field)
-{
- guint32 sig, token;
- MonoClass *klass;
- const gchar *name;
-
- klass = field->rfield.klass;
- name = field->rfield.field->name;
- sig = fieldref_encode_signature (assembly, field->declaring->type);
- token = mono_image_get_memberref_token (assembly, &klass->byval_arg, name, sig);
- return token;
-}
-
-static guint32
-mono_image_get_inflated_field_token (MonoDynamicImage *assembly, MonoReflectionInflatedField *field)
-{
- guint32 token;
-
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, field->rfield.field));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, f));
if (token)
return token;
- token = field_encode_inflated_field (assembly, field);
- g_hash_table_insert (assembly->handleref, field, GUINT_TO_POINTER(token));
+ g_assert (f->field->parent);
+ type = f->field->generic_type ? f->field->generic_type : f->field->type;
+ token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg,
+ f->field->name, fieldref_encode_signature (assembly, type));
+ g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
return token;
}
static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericInst *ginst)
+encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmethod)
{
char *buf;
char *p;
int i;
- guint32 nparams = ginst->type_argc;
+ guint32 nparams = gmethod->mtype_argc;
guint32 size = 10 + nparams * 10;
guint32 idx;
char blob_size [6];
mono_metadata_encode_value (nparams, p, &p);
for (i = 0; i < nparams; i++)
- encode_type (assembly, ginst->type_argv [i], p, &p);
+ encode_type (assembly, gmethod->mtype_argv [i], p, &p);
/* store length */
g_assert (p - buf < size);
}
static guint32
-method_encode_methodspec (MonoDynamicImage *assembly, MonoGenericInst *ginst)
+method_encode_methodspec (MonoDynamicImage *assembly, MonoMethod *method)
{
MonoDynamicTable *table;
guint32 *values;
guint32 token, mtoken = 0, sig;
+ MonoMethodInflated *imethod;
+ MonoMethod *declaring;
table = &assembly->tables [MONO_TABLE_METHODSPEC];
- g_assert (ginst);
- if (ginst->generic_method) {
- MonoMethod *gm = ginst->generic_method;
- MonoClass *k = ginst->klass ? ginst->klass : gm->klass;
+ g_assert (method->signature->is_inflated);
+ imethod = (MonoMethodInflated *) method;
+ declaring = imethod->declaring;
- sig = method_encode_signature (assembly, gm->signature);
- mtoken = mono_image_get_memberref_token (assembly, &k->byval_arg, gm->name, sig);
+ sig = method_encode_signature (assembly, declaring->signature);
+ mtoken = mono_image_get_memberref_token (assembly, &method->klass->byval_arg,
+ declaring->name, sig);
- if (!ginst->generic_method->signature->generic_param_count)
- return mtoken;
- }
- else
- g_assert_not_reached ();
+ if (!declaring->signature->generic_param_count)
+ return mtoken;
switch (mono_metadata_token_table (mtoken)) {
case MONO_TABLE_MEMBERREF:
g_assert_not_reached ();
}
- sig = encode_generic_method_sig (assembly, ginst);
+ sig = encode_generic_method_sig (assembly, imethod->context->gmethod);
if (assembly->save) {
alloc_table (table, table->rows + 1);
}
static guint32
-mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method, MonoGenericInst *ginst)
+mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
{
+ MonoMethodInflated *imethod;
guint32 token;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, m));
if (token)
return token;
- token = method_encode_methodspec (assembly, ginst);
- g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
+
+ g_assert (m->signature->is_inflated);
+ imethod = (MonoMethodInflated *) m;
+
+ if (imethod->declaring->signature->generic_param_count)
+ token = method_encode_methodspec (assembly, m);
+ else {
+ guint32 sig = method_encode_signature (
+ assembly, imethod->declaring->signature);
+ token = mono_image_get_memberref_token (
+ assembly, &m->klass->byval_arg, m->name, sig);
+ }
+
+ g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
return token;
}
mono_image_get_property_info (
mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i), assembly);
}
+
+ mono_image_add_decl_security (assembly,
+ mono_metadata_make_token (MONO_TABLE_TYPEDEF, tb->table_idx),
+ tb->permissions);
+
if (tb->subtypes) {
MonoDynamicTable *ntable;
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
g_assert (m->klass->generic_inst);
continue;
- } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoInflatedMethod") ||
- !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedCtor") ||
- !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedField")) {
- continue;
} else if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
continue;
+ } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
+ MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
+ g_assert (f->generic_type);
+ continue;
} else {
g_assert_not_reached ();
}
MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
g_assert (m->signature->generic_param_count);
continue;
- } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoInflatedMethod") ||
- !strcmp (iltoken->member->vtable->klass->name, "MonoInflatedCtor")) {
- continue;
} else {
g_assert_not_reached ();
}
}
}
+/*
+ * fixup_cattrs:
+ *
+ * The CUSTOM_ATTRIBUTE table might contain METHODDEF tokens whose final
+ * value is not known when the table is emitted.
+ */
+static void
+fixup_cattrs (MonoDynamicImage *assembly)
+{
+ MonoDynamicTable *table;
+ guint32 *values;
+ guint32 type, i, idx, token;
+ MonoObject *ctor;
+
+ table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+
+ for (i = 0; i < table->rows; ++i) {
+ values = table->values + ((i + 1) * MONO_CUSTOM_ATTR_SIZE);
+
+ type = values [MONO_CUSTOM_ATTR_TYPE];
+ if ((type & CUSTOM_ATTR_TYPE_MASK) == CUSTOM_ATTR_TYPE_METHODDEF) {
+ idx = type >> CUSTOM_ATTR_TYPE_BITS;
+ token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
+ ctor = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
+ g_assert (ctor);
+
+ if (!strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
+ MonoMethod *m = ((MonoReflectionMethod*)ctor)->method;
+ idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
+ values [MONO_CUSTOM_ATTR_TYPE] = (idx << CUSTOM_ATTR_TYPE_BITS) | CUSTOM_ATTR_TYPE_METHODDEF;
+ }
+ }
+ }
+}
+
static void
assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation)
{
/* fixup tokens */
mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
+ fixup_cattrs (assembly);
}
/*
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, tb->type));
}
+ else if (strcmp (klass->name, "MonoGenericInst") == 0) {
+ MonoReflectionType *tb = (MonoReflectionType *)obj;
+ token = mono_metadata_token_from_dor (
+ mono_image_typedef_or_ref (assembly, tb->type));
+ }
else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
- if (m->method->signature->generic_param_count) {
+ if (m->method->signature->is_inflated) {
+ token = mono_image_get_methodspec_token (assembly, m->method);
+ } else if (m->method->signature->generic_param_count) {
g_assert_not_reached ();
- token = mono_image_get_methodspec_token (assembly, m->method, NULL);
} else if ((m->method->klass->image == &assembly->image) &&
!m->method->klass->generic_inst) {
static guint32 method_table_idx = 0xffffff;
token = mono_image_get_methodref_token (assembly, m->method);
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
}
- else if (strcmp (klass->name, "MonoInflatedMethod") == 0 ||
- strcmp (klass->name, "MonoInflatedCtor") == 0) {
- MonoReflectionInflatedMethod *m = (MonoReflectionInflatedMethod *)obj;
- token = mono_image_get_methodspec_token (assembly, m->rmethod.method, m->ginst);
- }
- else if (strcmp (klass->name, "MonoInflatedField") == 0) {
- MonoReflectionInflatedField *f = (MonoReflectionInflatedField *)obj;
- token = mono_image_get_inflated_field_token (assembly, f);
- }
else if (strcmp (klass->name, "MonoField") == 0) {
MonoReflectionField *f = (MonoReflectionField *)obj;
- if (f->klass->image == &assembly->image) {
+ if ((f->klass->image == &assembly->image) && !f->field->generic_type) {
static guint32 field_table_idx = 0xffffff;
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
} else
- token = mono_image_get_fieldref_token (assembly, f->field, f->klass);
+ token = mono_image_get_fieldref_token (assembly, f);
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
}
else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
cli_header->ch_size = GUINT32_FROM_LE (72);
cli_header->ch_runtime_major = GUINT16_FROM_LE (2);
cli_header->ch_flags = GUINT32_FROM_LE (CLI_FLAGS_ILONLY);
- if (assemblyb->entry_point)
- cli_header->ch_entry_point = GUINT32_FROM_LE (assemblyb->entry_point->table_idx | MONO_TOKEN_METHOD_DEF);
+ if (assemblyb->entry_point) {
+ guint32 table_idx = 0;
+ if (!strcmp (assemblyb->entry_point->object.vtable->klass->name, "MethodBuilder")) {
+ MonoReflectionMethodBuilder *methodb = (MonoReflectionMethodBuilder*)assemblyb->entry_point;
+ table_idx = methodb->table_idx;
+ }
+ else
+ table_idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, assemblyb->entry_point->method));
+ cli_header->ch_entry_point = GUINT32_FROM_LE (table_idx | MONO_TOKEN_METHOD_DEF);
+ }
else
cli_header->ch_entry_point = GUINT32_FROM_LE (0);
/* The embedded managed resources */
return hash;
}
+static MonoReflectionGenericInst*
+mono_generic_inst_get_object (MonoDomain *domain, MonoType *geninst)
+{
+ static MonoClass *System_Reflection_MonoGenericInst;
+ MonoReflectionGenericInst *res;
+ MonoGenericInst *ginst;
+ MonoClass *gklass;
+
+ if (!System_Reflection_MonoGenericInst) {
+ System_Reflection_MonoGenericInst = mono_class_from_name (
+ mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
+ g_assert (System_Reflection_MonoGenericInst);
+ }
+
+ ginst = geninst->data.generic_inst;
+ gklass = mono_class_from_mono_type (ginst->generic_type);
+
+ mono_class_init (ginst->klass);
+
+ res = (MonoReflectionGenericInst *) mono_object_new (domain, System_Reflection_MonoGenericInst);
+
+ res->type.type = geninst;
+ if (gklass->wastypebuilder && gklass->reflection_info)
+ res->generic_type = gklass->reflection_info;
+ else
+ res->generic_type = mono_type_get_object (domain, ginst->generic_type);
+
+ return res;
+}
+
/*
* mono_type_get_object:
* @domain: an app domain
mono_domain_unlock (domain);
return res;
}
+ if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_inst->is_dynamic) {
+ res = (MonoReflectionType *)mono_generic_inst_get_object (domain, type);
+ mono_g_hash_table_insert (domain->type_hash, type, res);
+ mono_domain_unlock (domain);
+ return res;
+ }
if (klass->reflection_info && !klass->wastypebuilder) {
//g_assert_not_reached ();
/* should this be considered an error condition? */
MonoObject *attr;
void **params;
+ mono_class_init (method->klass);
+
+ if (len == 0) {
+ attr = mono_object_new (mono_domain_get (), method->klass);
+ mono_runtime_invoke (method, attr, NULL, NULL);
+ return attr;
+ }
+
if (len < 2 || read16 (p) != 0x0001) /* Prolog */
return NULL;
- mono_class_init (method->klass);
/*g_print ("got attr %s\n", method->klass->name);*/
params = g_new (void*, method->signature->param_count);
return mono_custom_attrs_from_index (assembly->image, idx);
}
-MonoCustomAttrInfo*
+static MonoCustomAttrInfo*
mono_custom_attrs_from_module (MonoImage *image)
{
MonoCustomAttrInfo *cinfo;
guint32 i, idx, method_index;
guint32 param_list, param_last, param_pos, found;
MonoImage *image;
-
- /* FIXME: handle dynamic custom attrs for parameters */
- /*if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
- return cinfo;*/
+ MonoReflectionMethodAux *aux;
+
+ if (method->klass->image->dynamic) {
+ aux = mono_g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ if (!aux || !aux->param_cattr)
+ return NULL;
+ return aux->param_cattr [param];
+ }
+
image = method->klass->image;
method_index = find_method_index (method);
ca = &image->tables [MONO_TABLE_METHOD];
cinfo = mono_custom_attrs_from_module (module->image);
} else if (strcmp ("MonoProperty", klass->name) == 0) {
MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
- cinfo = mono_custom_attrs_from_property (rprop->klass, rprop->property);
+ cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
} else if (strcmp ("MonoEvent", klass->name) == 0) {
MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
- cinfo = mono_custom_attrs_from_event (revent->klass, revent->event);
+ cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
} else if (strcmp ("MonoField", klass->name) == 0) {
MonoReflectionField *rfield = (MonoReflectionField*)obj;
- cinfo = mono_custom_attrs_from_field (rfield->klass, rfield->field);
+ cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field);
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
cinfo = mono_custom_attrs_from_method (rmethod->method);
}
}
-static char*
-type_get_qualified_name (MonoType *type, MonoAssembly *ass) {
- char *name, *result;
- MonoClass *klass;
- MonoAssembly *ta;
-
- name = mono_type_get_name (type);
- klass = my_mono_class_from_mono_type (type);
- ta = klass->image->assembly;
- if (ta == ass || klass->image == mono_defaults.corlib)
- return name;
-
- /* missing public key */
- result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s",
- name, ta->aname.name,
- ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
- ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral");
- g_free (name);
- return result;
-}
-
static void
encode_cattr_value (char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, MonoObject *arg)
{
MonoReflectionGenericParam *gparam = mono_array_get (tb->generic_params, gpointer, i);
klass->gen_params [i] = *gparam->type.type->data.generic_param;
}
-
- ensure_runtime_vtable (klass);
}
/*
case MONO_NATIVE_CUSTOM:
if (minfo->marshaltyperef)
res->data.custom_data.custom_name =
- type_get_qualified_name (minfo->marshaltyperef->type,
- assembly);
+ type_get_fully_qualified_name (minfo->marshaltyperef->type);
if (minfo->mcookie)
res->data.custom_data.cookie = mono_string_to_utf8 (minfo->mcookie);
break;
static MonoMethod*
reflection_methodbuilder_to_mono_method (MonoClass *klass,
- ReflectionMethodBuilder *rmb,
- MonoMethodSignature *sig)
+ ReflectionMethodBuilder *rmb,
+ MonoMethodSignature *sig)
{
MonoMethod *m;
MonoMethodNormal *pm;
header->num_clauses = num_clauses;
if (num_clauses) {
header->clauses = method_encode_clauses ((MonoDynamicImage*)klass->image,
- rmb->ilgen,
- num_clauses);
+ rmb->ilgen,
+ num_clauses);
+ }
+
+ if (rmb->generic_params) {
+ int count = mono_array_length (rmb->generic_params);
+ header->gen_params = g_new0 (MonoGenericParam, count);
+ for (i = 0; i < count; i++) {
+ MonoReflectionGenericParam *gp =
+ mono_array_get (rmb->generic_params,
+ MonoReflectionGenericParam*, i);
+
+ header->gen_params [i] = *gp->type.type->data.generic_param;
+ }
}
pm->header = header;
method_aux = NULL;
/* Parameter names */
- if (rmb->parameters) {
+ if (rmb->pinfo) {
if (!method_aux)
method_aux = g_new0 (MonoReflectionMethodAux, 1);
- method_aux->param_names = g_new0 (char *, m->signature->param_count);
- for (i = 0; i < m->signature->param_count; ++i) {
+ method_aux->param_names = g_new0 (char *, m->signature->param_count + 1);
+ for (i = 0; i <= m->signature->param_count; ++i) {
MonoReflectionParamBuilder *pb;
- if ((pb = mono_array_get (rmb->parameters, MonoReflectionParamBuilder*, i))) {
+ if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
if (pb->name)
method_aux->param_names [i] = mono_string_to_utf8 (pb->name);
+ if (pb->cattrs) {
+ if (!method_aux->param_cattr)
+ method_aux->param_cattr = g_new0 (MonoCustomAttrInfo*, m->signature->param_count + 1);
+ method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs);
+ }
}
}
}
return field;
}
-static MonoReflectionInflatedMethod*
-inflated_method_get_object (MonoDomain *domain, MonoMethod *method, MonoReflectionMethod *declaring,
- MonoGenericInst *ginst)
-{
- const char *cname;
- MonoClass *klass, *refclass;
- MonoReflectionInflatedMethod *ret;
-
- refclass = method->klass;
-
- CHECK_OBJECT (MonoReflectionInflatedMethod *, method, refclass);
- if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
- cname = "MonoInflatedCtor";
- else
- cname = "MonoInflatedMethod";
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", cname);
- g_assert (klass);
-
- ret = (MonoReflectionInflatedMethod*)mono_object_new (domain, klass);
- ret->rmethod.method = method;
- ret->rmethod.name = mono_string_new (domain, method->name);
- ret->rmethod.reftype = mono_type_get_object (domain, &refclass->byval_arg);
- ret->declaring = declaring;
- ret->ginst = ginst;
- CACHE_OBJECT (method, ret, refclass);
- return ret;
-}
-
-MonoReflectionGenericInst*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, MonoArray *types)
+static MonoType*
+do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc,
+ MonoType **types, MonoType *nested_in)
{
- static MonoClass *System_Reflection_MonoGenericInst;
+ MonoClass *klass;
+ MonoReflectionTypeBuilder *tb = NULL;
+ MonoGenericInst *ginst;
MonoDomain *domain;
MonoType *geninst;
- MonoGenericInst *ginst;
- MonoArray *ifaces = NULL;
- MonoReflectionType *ptype = NULL;
- MonoClass *klass, *iklass, *pklass = NULL;
- MonoReflectionGenericInst *res, *parent = NULL;
- MonoReflectionTypeBuilder *tb = NULL;
- int i;
-
- domain = mono_object_domain (type);
+ int icount, i;
klass = mono_class_from_mono_type (type->type);
- if (!klass->gen_params && !klass->generic_inst)
+ if (!klass->gen_params && !klass->generic_inst &&
+ !(klass->nested_in && klass->nested_in->gen_params))
return NULL;
- if (!System_Reflection_MonoGenericInst) {
- System_Reflection_MonoGenericInst = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "MonoGenericInst");
- g_assert (System_Reflection_MonoGenericInst);
- }
-
- if (klass->wastypebuilder && klass->reflection_info) {
- tb = klass->reflection_info;
+ mono_loader_lock ();
- ptype = tb->parent;
- if (ptype)
- pklass = mono_class_from_mono_type (ptype->type);
- } else {
- pklass = klass->parent;
- if (pklass)
- ptype = mono_type_get_object (domain, &pklass->byval_arg);
- }
-
- if (pklass && pklass->generic_inst)
- parent = mono_reflection_bind_generic_parameters (ptype, types);
- else if (!pklass) {
- int icount;
-
- pklass = mono_defaults.object_class;
-
- icount = klass->interface_count;
- ifaces = mono_array_new (domain, System_Reflection_MonoGenericInst, icount);
-
- for (i = 0; i < icount; i++) {
- MonoReflectionGenericInst *iface;
- MonoReflectionType *itype;
-
- if (tb)
- itype = mono_array_get (tb->interfaces, gpointer, i);
- else
- itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
- iface = mono_reflection_bind_generic_parameters (itype, types);
-
- mono_array_set (ifaces, gpointer, i, iface);
- }
- }
+ domain = mono_object_domain (type);
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
- geninst->data.generic_inst = ginst = g_new0 (MonoGenericInst, 1);
+ ginst = g_new0 (MonoGenericInst, 1);
- if (klass->gen_params) {
- ginst->type_argc = mono_array_length (types);
- ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
+ if (!klass->generic_inst) {
+ ginst->type_argc = type_argc;
+ ginst->type_argv = types;
for (i = 0; i < ginst->type_argc; ++i) {
- MonoReflectionType *garg = mono_array_get (types, gpointer, i);
-
- ginst->type_argv [i] = garg->type;
-
if (!ginst->is_open)
- ginst->is_open = mono_class_is_open_constructed_type (garg->type);
+ ginst->is_open = mono_class_is_open_constructed_type (types [i]);
}
ginst->generic_type = &klass->byval_arg;
} else {
- MonoGenericInst *kginst = klass->generic_inst->data.generic_inst;
+ MonoGenericInst *kginst = klass->generic_inst;
ginst->type_argc = kginst->type_argc;
ginst->type_argv = g_new0 (MonoType *, ginst->type_argc);
for (i = 0; i < ginst->type_argc; i++) {
MonoType *t = kginst->type_argv [i];
- if (t->type == MONO_TYPE_VAR) {
- int num = t->data.generic_param->num;
- MonoReflectionType *garg = mono_array_get (types, gpointer, num);
-
- t = garg->type;
- }
+ if (t->type == MONO_TYPE_VAR)
+ t = types [t->data.generic_param->num];
if (!ginst->is_open)
ginst->is_open = mono_class_is_open_constructed_type (t);
ginst->generic_type = kginst->generic_type;
}
- iklass = mono_class_from_generic (geninst, FALSE);
+ geninst = g_hash_table_lookup (klass->image->generic_inst_cache, ginst);
+ if (geninst) {
+ g_free (ginst);
+ mono_loader_unlock ();
+ return geninst;
+ }
- mono_class_setup_parent (iklass, parent ? parent->klass : pklass);
- mono_class_setup_mono_type (iklass);
+ ginst->context = g_new0 (MonoGenericContext, 1);
+ ginst->context->ginst = ginst;
- res = (MonoReflectionGenericInst *)mono_object_new (domain, System_Reflection_MonoGenericInst);
+ geninst = g_new0 (MonoType, 1);
+ geninst->type = MONO_TYPE_GENERICINST;
+ geninst->data.generic_inst = ginst;
- res->type.type = iklass->generic_inst;
- res->klass = iklass;
- res->parent = parent;
- res->generic_type = type;
- res->interfaces = ifaces;
+ if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+ tb = (MonoReflectionTypeBuilder *) type;
- return res;
+ icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+ ginst->is_dynamic = TRUE;
+ } else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericInst")) {
+ MonoReflectionGenericInst *rgi = (MonoReflectionGenericInst *) type;
+ MonoReflectionType *rgt = rgi->generic_type;
+
+ g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
+ tb = (MonoReflectionTypeBuilder *) rgt;
+
+ icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
+ ginst->is_dynamic = TRUE;
+ } else
+ icount = klass->interface_count;
+
+ ginst->ifaces = g_new0 (MonoType *, icount);
+ ginst->count_ifaces = icount;
+
+ for (i = 0; i < icount; i++) {
+ MonoReflectionType *itype;
+
+ if (tb)
+ itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
+ else
+ itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
+ ginst->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
+ if (!ginst->ifaces [i])
+ ginst->ifaces [i] = itype->type;
+ }
+
+ ginst->nested_in = nested_in;
+
+ mono_class_create_generic (ginst);
+
+ g_hash_table_insert (klass->image->generic_inst_cache, ginst, geninst);
+
+ mono_loader_unlock ();
+
+ return geninst;
+}
+
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
+{
+ MonoClass *klass, *pklass = NULL, *oklass = NULL;
+ MonoReflectionType *parent = NULL, *outer = NULL;
+ MonoType *geninst, *nested_in = NULL;
+ MonoReflectionTypeBuilder *tb = NULL;
+ MonoGenericInst *ginst;
+ MonoDomain *domain;
+
+ domain = mono_object_domain (type);
+ klass = mono_class_from_mono_type (type->type);
+
+ if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
+ tb = (MonoReflectionTypeBuilder *) type;
+
+ if (tb->parent) {
+ parent = tb->parent;
+ pklass = mono_class_from_mono_type (parent->type);
+ }
+ if (tb->nesting_type) {
+ outer = tb->nesting_type;
+ oklass = mono_class_from_mono_type (outer->type);
+ }
+ } else {
+ pklass = klass->parent;
+ if (pklass)
+ parent = mono_type_get_object (domain, &pklass->byval_arg);
+ oklass = klass->nested_in;
+ if (oklass)
+ outer = mono_type_get_object (domain, &oklass->byval_arg);
+ }
+
+ if (oklass)
+ nested_in = mono_reflection_bind_generic_parameters (outer, oklass->num_gen_params, types);
+
+ geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, nested_in);
+ if (!geninst)
+ return NULL;
+
+ ginst = geninst->data.generic_inst;
+
+ if (pklass && pklass->generic_inst)
+ ginst->parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
+
+ return geninst;
}
-MonoReflectionInflatedMethod*
+void
+mono_reflection_generic_inst_get_nested_types (MonoReflectionGenericInst *type)
+{
+ MonoReflectionTypeBuilder *tb;
+ MonoGenericInst *ginst;
+ int i;
+
+ ginst = type->type.type->data.generic_inst;
+ if (ginst->nested)
+ return;
+
+ if (strcmp (((MonoObject *) type->generic_type)->vtable->klass->name, "TypeBuilder"))
+ return;
+
+ tb = (MonoReflectionTypeBuilder *) type->generic_type;
+
+ ginst->count_nested = tb->subtypes ? mono_array_length (tb->subtypes) : 0;
+ ginst->nested = g_new0 (MonoType *, ginst->count_nested);
+
+ for (i = 0; i < ginst->count_nested; i++) {
+ MonoReflectionTypeBuilder *ntype;
+ MonoType **ntypes;
+ int ntype_argc, j;
+
+ ntype = mono_array_get (tb->subtypes, gpointer, i);
+ ntype_argc = ntype->generic_params ? mono_array_length (ntype->generic_params) : 0;
+
+ if (ntype_argc > ginst->type_argc) {
+ ntypes = g_new0 (MonoType *, ntype_argc);
+
+ for (j = 0; j < ginst->type_argc; j++)
+ ntypes [j] = ginst->type_argv [j];
+
+ for (j = ginst->type_argc; j < ntype_argc; j++) {
+ MonoReflectionGenericParam *ngparam;
+ MonoType *pt = g_new0 (MonoType, 1);
+
+ ngparam = mono_array_get (ntype->generic_params, gpointer, j);
+
+ pt->type = MONO_TYPE_VAR;
+ pt->data.generic_param = ngparam->type.type->data.generic_param;
+
+ ntypes [j] = pt;
+ }
+ } else
+ ntypes = ginst->type_argv;
+
+ ginst->nested [i] = mono_reflection_bind_generic_parameters ((MonoReflectionType *) ntype, ntype_argc, ntypes);
+ }
+}
+
+MonoReflectionMethod*
mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
{
MonoMethod *method, *inflated;
MonoReflectionMethodBuilder *mb = NULL;
- MonoGenericInst *ginst;
+ MonoGenericMethod *gmethod;
+ MonoGenericContext *context;
int count, i;
MONO_ARCH_SAVE_REGS;
if (count != mono_array_length (types))
return NULL;
- ginst = g_new0 (MonoGenericInst, 1);
- ginst->generic_method = method;
- ginst->type_argc = count;
- ginst->type_argv = g_new0 (MonoType *, count);
+ gmethod = g_new0 (MonoGenericMethod, 1);
+ gmethod->mtype_argc = count;
+ gmethod->mtype_argv = g_new0 (MonoType *, count);
for (i = 0; i < count; i++) {
MonoReflectionType *garg = mono_array_get (types, gpointer, i);
- ginst->type_argv [i] = garg->type;
+ gmethod->mtype_argv [i] = garg->type;
}
- inflated = mono_class_inflate_generic_method (method, ginst);
+ context = g_new0 (MonoGenericContext, 1);
+ context->ginst = method->klass->generic_inst;
+ context->gmethod = gmethod;
+
+ inflated = mono_class_inflate_generic_method (method, context, NULL);
- return inflated_method_get_object (mono_object_domain (rmethod), inflated, rmethod, ginst);
+ return mono_method_get_object (
+ mono_object_domain (rmethod), inflated, NULL);
}
-MonoReflectionInflatedMethod*
-mono_reflection_inflate_method_or_ctor (MonoReflectionGenericInst *declaring_type,
- MonoReflectionGenericInst *reflected_type,
- MonoObject *obj)
+static MonoMethod *
+inflate_mono_method (MonoReflectionGenericInst *type, MonoMethod *method, MonoObject *obj)
{
- MonoGenericInst *ginst, *type_ginst;
- MonoMethod *method = NULL, *inflated;
- MonoReflectionInflatedMethod *res;
- MonoClass *klass;
+ MonoGenericMethod *gmethod;
+ MonoGenericInst *ginst;
+ MonoGenericContext *context;
- MONO_ARCH_SAVE_REGS;
+ ginst = type->type.type->data.generic_inst;
- klass = mono_class_from_mono_type (reflected_type->type.type);
- type_ginst = reflected_type->type.type->data.generic_inst;
+ gmethod = g_new0 (MonoGenericMethod, 1);
+ gmethod->reflection_info = obj;
+
+ context = g_new0 (MonoGenericContext, 1);
+ context->ginst = ginst;
+ context->gmethod = gmethod;
+
+ return mono_class_inflate_generic_method (method, context, ginst->klass);
+}
+
+static MonoMethod *
+inflate_method (MonoReflectionGenericInst *type, MonoObject *obj)
+{
+ MonoMethod *method;
+ MonoClass *klass;
+
+ klass = mono_class_from_mono_type (type->type.type);
if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj);
else if (!strcmp (obj->vtable->klass->name, "MonoMethod") ||
!strcmp (obj->vtable->klass->name, "MonoCMethod"))
method = ((MonoReflectionMethod *) obj)->method;
- else if (!strcmp (obj->vtable->klass->name, "MonoInflatedMethod") ||
- !strcmp (obj->vtable->klass->name, "MonoInflatedCtor"))
- method = ((MonoReflectionInflatedMethod *) obj)->rmethod.method;
- else
+ else {
+ method = NULL; /* prevent compiler warning */
g_assert_not_reached ();
+ }
- ginst = g_new0 (MonoGenericInst, 1);
- ginst->generic_method = method;
- ginst->generic_type = reflected_type->type.type;
- ginst->type_argc = type_ginst->type_argc;
- ginst->type_argv = type_ginst->type_argv;
- ginst->is_open = type_ginst->is_open;
+ return inflate_mono_method (type, method, obj);
+}
+
+void
+mono_reflection_generic_inst_initialize (MonoReflectionGenericInst *type,
+ MonoArray *methods, MonoArray *ctors,
+ MonoArray *fields, MonoArray *properties,
+ MonoArray *events)
+{
+ MonoGenericInst *ginst;
+ MonoDynamicGenericInst *dginst;
+ MonoClass *klass, *gklass, *pklass;
+ int i;
+
+ MONO_ARCH_SAVE_REGS;
+
+ klass = mono_class_from_mono_type (type->type.type);
+ ginst = type->type.type->data.generic_inst;
+
+ if (ginst->initialized)
+ return;
- ginst->klass = mono_class_from_generic (ginst->generic_type, FALSE);
+ dginst = ginst->dynamic_info = g_new0 (MonoDynamicGenericInst, 1);
- if (type_ginst->is_open)
- inflated = method;
+ gklass = mono_class_from_mono_type (ginst->generic_type);
+ mono_class_init (gklass);
+
+ if (ginst->parent)
+ pklass = mono_class_from_mono_type (ginst->parent);
else
- inflated = mono_class_inflate_generic_method (method, ginst);
+ pklass = gklass->parent;
- res = inflated_method_get_object (
- mono_object_domain (reflected_type), inflated, (MonoReflectionMethod *) obj, ginst);
+ mono_class_setup_parent (klass, pklass);
- res->declaring_type = declaring_type;
- res->reflected_type = reflected_type;
+ dginst->count_methods = methods ? mono_array_length (methods) : 0;
+ dginst->count_ctors = ctors ? mono_array_length (ctors) : 0;
+ dginst->count_fields = fields ? mono_array_length (fields) : 0;
+ dginst->count_properties = properties ? mono_array_length (properties) : 0;
+ dginst->count_events = events ? mono_array_length (events) : 0;
- return res;
-}
+ dginst->methods = g_new0 (MonoMethod *, dginst->count_methods);
+ dginst->ctors = g_new0 (MonoMethod *, dginst->count_ctors);
+ dginst->fields = g_new0 (MonoClassField, dginst->count_fields);
+ dginst->properties = g_new0 (MonoProperty, dginst->count_properties);
+ dginst->events = g_new0 (MonoEvent, dginst->count_events);
-MonoReflectionInflatedField*
-mono_reflection_inflate_field (MonoReflectionGenericInst *declaring_type,
- MonoReflectionGenericInst *reflected_type,
- MonoObject *obj)
-{
- static MonoClass *System_Reflection_MonoInflatedField;
- MonoGenericInst *ginst, *type_ginst;
- MonoClassField *field = NULL, *inflated;
- MonoReflectionInflatedField *res;
- MonoDomain *domain;
- MonoClass *klass;
+ for (i = 0; i < dginst->count_methods; i++) {
+ MonoObject *obj = mono_array_get (methods, gpointer, i);
- MONO_ARCH_SAVE_REGS;
+ dginst->methods [i] = inflate_method (type, obj);
+ }
+
+ for (i = 0; i < dginst->count_ctors; i++) {
+ MonoObject *obj = mono_array_get (ctors, gpointer, i);
- if (!System_Reflection_MonoInflatedField) {
- System_Reflection_MonoInflatedField = mono_class_from_name (
- mono_defaults.corlib, "System.Reflection", "MonoInflatedField");
- g_assert (System_Reflection_MonoInflatedField);
+ dginst->ctors [i] = inflate_method (type, obj);
}
- klass = mono_class_from_mono_type (reflected_type->type.type);
- type_ginst = reflected_type->type.type->data.generic_inst;
+ for (i = 0; i < dginst->count_fields; i++) {
+ MonoObject *obj = mono_array_get (fields, gpointer, i);
+ MonoClassField *field;
- if (!strcmp (obj->vtable->klass->name, "FieldBuilder")) {
- field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
- } else if (!strcmp (obj->vtable->klass->name, "MonoField"))
- field = ((MonoReflectionField *) obj)->field;
- else
- g_assert_not_reached ();
+ if (!strcmp (obj->vtable->klass->name, "FieldBuilder"))
+ field = fieldbuilder_to_mono_class_field (klass, (MonoReflectionFieldBuilder *) obj);
+ else if (!strcmp (obj->vtable->klass->name, "MonoField"))
+ field = ((MonoReflectionField *) obj)->field;
+ else {
+ field = NULL; /* prevent compiler warning */
+ g_assert_not_reached ();
+ }
- ginst = g_new0 (MonoGenericInst, 1);
- ginst->generic_type = reflected_type->type.type;
- ginst->type_argc = type_ginst->type_argc;
- ginst->type_argv = type_ginst->type_argv;
-
- inflated = g_new0 (MonoClassField, 1);
- *inflated = *field;
- inflated->type = mono_class_inflate_generic_type (field->type, ginst);
-
- domain = mono_object_domain (obj);
-
- res = (MonoReflectionInflatedField *)mono_object_new (domain, System_Reflection_MonoInflatedField);
- res->declaring = field;
- res->declaring_type = declaring_type;
- res->reflected_type = reflected_type;
- res->rfield.klass = klass;
- res->rfield.field = inflated;
- res->rfield.name = mono_string_new (domain, inflated->name);
- res->rfield.attrs = inflated->type->attrs;
- res->rfield.type = mono_type_get_object (domain, inflated->type);
- CACHE_OBJECT (inflated, res, field->parent);
- return res;
+ dginst->fields [i] = *field;
+ dginst->fields [i].generic_type = field->type;
+ dginst->fields [i].type = mono_class_inflate_generic_type (field->type, ginst->context);
+ }
+
+ for (i = 0; i < dginst->count_properties; i++) {
+ MonoObject *obj = mono_array_get (properties, gpointer, i);
+ MonoProperty *property = &dginst->properties [i];
+
+ if (!strcmp (obj->vtable->klass->name, "PropertyBuilder")) {
+ MonoReflectionPropertyBuilder *pb = (MonoReflectionPropertyBuilder *) obj;
+
+ property->parent = klass;
+ property->attrs = pb->attrs;
+ property->name = mono_string_to_utf8 (pb->name);
+ if (pb->get_method)
+ property->get = inflate_method (type, (MonoObject *) pb->get_method);
+ if (pb->set_method)
+ property->set = inflate_method (type, (MonoObject *) pb->set_method);
+ } else if (!strcmp (obj->vtable->klass->name, "MonoProperty")) {
+ *property = *((MonoReflectionProperty *) obj)->property;
+
+ if (property->get)
+ property->get = inflate_mono_method (type, property->get, NULL);
+ if (property->set)
+ property->set = inflate_mono_method (type, property->set, NULL);
+ } else
+ g_assert_not_reached ();
+ }
+
+ for (i = 0; i < dginst->count_events; i++) {
+ MonoObject *obj = mono_array_get (events, gpointer, i);
+ MonoEvent *event = &dginst->events [i];
+
+ if (!strcmp (obj->vtable->klass->name, "EventBuilder")) {
+ MonoReflectionEventBuilder *eb = (MonoReflectionEventBuilder *) obj;
+
+ event->parent = klass;
+ event->attrs = eb->attrs;
+ event->name = mono_string_to_utf8 (eb->name);
+ if (eb->add_method)
+ event->add = inflate_method (type, (MonoObject *) eb->add_method);
+ if (eb->remove_method)
+ event->remove = inflate_method (type, (MonoObject *) eb->remove_method);
+ } else if (!strcmp (obj->vtable->klass->name, "MonoEvent")) {
+ *event = *((MonoReflectionEvent *) obj)->event;
+
+ if (event->add)
+ event->add = inflate_mono_method (type, event->add, NULL);
+ if (event->remove)
+ event->remove = inflate_mono_method (type, event->remove, NULL);
+ } else
+ g_assert_not_reached ();
+ }
+
+ ginst->initialized = TRUE;
}
static void
klass->properties = g_new0 (MonoProperty, klass->property.count);
for (i = 0; i < klass->property.count; ++i) {
pb = mono_array_get (tb->properties, MonoReflectionPropertyBuilder*, i);
+ klass->properties [i].parent = klass;
klass->properties [i].attrs = pb->attrs;
klass->properties [i].name = mono_string_to_utf8 (pb->name);
if (pb->get_method)
}
}
+MonoReflectionEvent *
+mono_reflection_event_builder_get_event_info (MonoReflectionTypeBuilder *tb, MonoReflectionEventBuilder *eb)
+{
+ MonoEvent *event = g_new0 (MonoEvent, 1);
+ MonoClass *klass;
+ int j;
+
+ klass = my_mono_class_from_mono_type (tb->type.type);
+
+ event->parent = klass;
+ event->attrs = eb->attrs;
+ event->name = mono_string_to_utf8 (eb->name);
+ if (eb->add_method)
+ event->add = eb->add_method->mhandle;
+ if (eb->remove_method)
+ event->remove = eb->remove_method->mhandle;
+ if (eb->raise_method)
+ event->raise = eb->raise_method->mhandle;
+
+ if (eb->other_methods) {
+ event->other = g_new0 (MonoMethod*, mono_array_length (eb->other_methods));
+ for (j = 0; j < mono_array_length (eb->other_methods); ++j) {
+ MonoReflectionMethodBuilder *mb =
+ mono_array_get (eb->other_methods,
+ MonoReflectionMethodBuilder*, j);
+ event->other [j] = mb->mhandle;
+ }
+ }
+
+ return mono_event_get_object (mono_object_domain (tb), klass, event);
+}
+
static void
typebuilder_setup_events (MonoClass *klass)
{
klass->events = g_new0 (MonoEvent, klass->event.count);
for (i = 0; i < klass->event.count; ++i) {
eb = mono_array_get (tb->events, MonoReflectionEventBuilder*, i);
+ klass->events [i].parent = klass;
klass->events [i].attrs = eb->attrs;
klass->events [i].name = mono_string_to_utf8 (eb->name);
if (eb->add_method)
rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
for (i = 0; i < mb->nrefs; ++i) {
gpointer ref = resolve_object (mb->module->image,
- mono_array_get (mb->refs, MonoObject*, i));
+ mono_array_get (mb->refs, MonoObject*, i));
if (!ref) {
g_free (rmb.refs);
mono_raise_exception (mono_get_exception_type_load (NULL));