#include "mono/metadata/reflection.h"
#include "mono/metadata/tabledefs.h"
#include "mono/metadata/metadata-internals.h"
+#include <mono/metadata/profiler-private.h>
#include "mono/metadata/class-internals.h"
#include "mono/metadata/gc-internal.h"
#include "mono/metadata/tokentype.h"
#include "cil-coff.h"
#include "rawbuffer.h"
#include "mono-endian.h"
-#include <mono/os/gc_wrapper.h>
+#include <mono/metadata/gc-internal.h>
+
+typedef struct {
+ char *p;
+ char *buf;
+ char *end;
+} SigBuffer;
#define TEXT_OFFSET 512
#define CLI_H_SIZE 136
static void reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb);
static void reflection_methodbuilder_from_ctor_builder (ReflectionMethodBuilder *rmb, MonoReflectionCtorBuilder *mb);
static guint32 mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type);
+static guint32 mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec);
static guint32 mono_image_get_methodref_token (MonoDynamicImage *assembly, MonoMethod *method);
static guint32 mono_image_get_methodbuilder_token (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb);
static guint32 mono_image_get_ctorbuilder_token (MonoDynamicImage *assembly, MonoReflectionCtorBuilder *cb);
static guint32 encode_constant (MonoDynamicImage *assembly, MonoObject *val, guint32 *ret_type);
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, MonoClass **handle_class);
-static void encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf);
-static guint32 type_get_signature_size (MonoType *type);
+static gpointer resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context);
+static void encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf);
static void get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types);
static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
-static inline MonoType *dup_type (const MonoType *original);
+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);
+
+#define mono_reflection_lock() EnterCriticalSection (&reflection_mutex)
+#define mono_reflection_unlock() LeaveCriticalSection (&reflection_mutex)
+static CRITICAL_SECTION reflection_mutex;
+
+void
+mono_reflection_init (void)
+{
+ InitializeCriticalSection (&reflection_mutex);
+}
+
+static void
+sigbuffer_init (SigBuffer *buf, int size)
+{
+ buf->buf = g_malloc (size);
+ buf->p = buf->buf;
+ buf->end = buf->buf + size;
+}
+
+static void
+sigbuffer_make_room (SigBuffer *buf, int size)
+{
+ if (buf->end - buf->p < size) {
+ int new_size = buf->end - buf->buf + size + 32;
+ char *p = g_realloc (buf->buf, new_size);
+ size = buf->p - buf->buf;
+ buf->buf = p;
+ buf->p = p + size;
+ buf->end = buf->buf + new_size;
+ }
+}
+
+static void
+sigbuffer_add_value (SigBuffer *buf, guint32 val)
+{
+ sigbuffer_make_room (buf, 6);
+ mono_metadata_encode_value (val, buf->p, &buf->p);
+}
+
+static void
+sigbuffer_add_byte (SigBuffer *buf, guint8 val)
+{
+ sigbuffer_make_room (buf, 1);
+ buf->p [0] = val;
+ buf->p++;
+}
+
+static void
+sigbuffer_add_mem (SigBuffer *buf, char *p, guint32 size)
+{
+ sigbuffer_make_room (buf, size);
+ memcpy (buf->p, p, size);
+ buf->p += size;
+}
+
+static void
+sigbuffer_free (SigBuffer *buf)
+{
+ g_free (buf->buf);
+}
/**
* mp_g_alloc:
return g_malloc0 (size);
}
+/**
+ * mp_string_to_utf8:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate
+ * memory from the C heap.
+ */
+static char *
+mp_string_to_utf8 (MonoMemPool *mp, MonoString *s)
+{
+ if (mp)
+ return mono_string_to_utf8_mp (mp, s);
+ else
+ return mono_string_to_utf8 (s);
+}
+
#define mp_g_new(mp,struct_type, n_structs) \
((struct_type *) mp_g_malloc (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
return idx;
}
+static guint32
+sigbuffer_add_to_blob_cached (MonoDynamicImage *assembly, SigBuffer *buf)
+{
+ char blob_size [8];
+ char *b = blob_size;
+ guint32 size = buf->p - buf->buf;
+ /* store length */
+ g_assert (size <= (buf->end - buf->buf));
+ mono_metadata_encode_value (size, b, &b);
+ return add_to_blob_cached (assembly, blob_size, b-blob_size, buf->buf, size);
+}
+
/*
* Copy len * nelem bytes from val to dest, swapping bytes to LE if necessary.
* dest may be misaligned.
case MONO_TYPE_STRING:
return mono_defaults.string_class;
default:
- g_warning ("implement me 0x%02x\n", type->type);
+ g_warning ("default_class_from_mono_type: implement me 0x%02x\n", type->type);
g_assert_not_reached ();
}
}
static void
-encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, char *p, char **endbuf)
+encode_generic_class (MonoDynamicImage *assembly, MonoGenericClass *gclass, SigBuffer *buf)
{
int i;
+ MonoGenericInst *class_inst;
+ MonoClass *klass;
- if (!gclass) {
- g_assert_not_reached ();
- return;
- }
+ g_assert (gclass);
- mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
- encode_type (assembly, &gclass->container_class->byval_arg, p, &p);
- mono_metadata_encode_value (gclass->inst->type_argc, p, &p);
- for (i = 0; i < gclass->inst->type_argc; ++i)
- encode_type (assembly, gclass->inst->type_argv [i], p, &p);
+ class_inst = gclass->context.class_inst;
+
+ sigbuffer_add_value (buf, MONO_TYPE_GENERICINST);
+ klass = gclass->container_class;
+ sigbuffer_add_value (buf, klass->byval_arg.type);
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
+
+ sigbuffer_add_value (buf, class_inst->type_argc);
+ for (i = 0; i < class_inst->type_argc; ++i)
+ encode_type (assembly, class_inst->type_argv [i], buf);
- *endbuf = p;
}
static void
-encode_type (MonoDynamicImage *assembly, MonoType *type, char *p, char **endbuf)
+encode_type (MonoDynamicImage *assembly, MonoType *type, SigBuffer *buf)
{
if (!type) {
g_assert_not_reached ();
}
if (type->byref)
- mono_metadata_encode_value (MONO_TYPE_BYREF, p, &p);
+ sigbuffer_add_value (buf, MONO_TYPE_BYREF);
switch (type->type){
case MONO_TYPE_VOID:
case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
case MONO_TYPE_TYPEDBYREF:
- mono_metadata_encode_value (type->type, p, &p);
+ sigbuffer_add_value (buf, type->type);
break;
case MONO_TYPE_PTR:
- mono_metadata_encode_value (type->type, p, &p);
- encode_type (assembly, type->data.type, p, &p);
+ sigbuffer_add_value (buf, type->type);
+ encode_type (assembly, type->data.type, buf);
break;
case MONO_TYPE_SZARRAY:
- mono_metadata_encode_value (type->type, p, &p);
- encode_type (assembly, &type->data.klass->byval_arg, p, &p);
+ sigbuffer_add_value (buf, type->type);
+ encode_type (assembly, &type->data.klass->byval_arg, buf);
break;
case MONO_TYPE_VALUETYPE:
case MONO_TYPE_CLASS: {
MonoClass *k = mono_class_from_mono_type (type);
- /*
- * Make sure we use the correct type.
- */
- mono_metadata_encode_value (k->byval_arg.type, p, &p);
- /*
- * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
- * otherwise two typerefs could point to the same type, leading to
- * verification errors.
- */
- mono_metadata_encode_value (mono_image_typedef_or_ref (assembly, &k->byval_arg), p, &p);
+
+ if (k->generic_container) {
+ MonoGenericClass *gclass = mono_metadata_lookup_generic_class (k, k->generic_container->context.class_inst, TRUE);
+ encode_generic_class (assembly, gclass, buf);
+ } else {
+ /*
+ * Make sure we use the correct type.
+ */
+ sigbuffer_add_value (buf, k->byval_arg.type);
+ /*
+ * ensure only non-byref gets passed to mono_image_typedef_or_ref(),
+ * otherwise two typerefs could point to the same type, leading to
+ * verification errors.
+ */
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, &k->byval_arg));
+ }
break;
}
case MONO_TYPE_ARRAY:
- mono_metadata_encode_value (type->type, p, &p);
- encode_type (assembly, &type->data.array->eklass->byval_arg, p, &p);
- mono_metadata_encode_value (type->data.array->rank, p, &p);
- mono_metadata_encode_value (0, p, &p); /* FIXME: set to 0 for now */
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (buf, type->type);
+ encode_type (assembly, &type->data.array->eklass->byval_arg, buf);
+ sigbuffer_add_value (buf, type->data.array->rank);
+ sigbuffer_add_value (buf, 0); /* FIXME: set to 0 for now */
+ sigbuffer_add_value (buf, 0);
break;
case MONO_TYPE_GENERICINST:
- encode_generic_class (assembly, type->data.generic_class, p, &p);
+ encode_generic_class (assembly, type->data.generic_class, buf);
break;
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
- mono_metadata_encode_value (type->type, p, &p);
- mono_metadata_encode_value (type->data.generic_param->num, p, &p);
+ sigbuffer_add_value (buf, type->type);
+ sigbuffer_add_value (buf, type->data.generic_param->num);
break;
default:
g_error ("need to encode type %x", type->type);
}
- *endbuf = p;
}
static void
-encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, char *p, char **endbuf)
+encode_reflection_type (MonoDynamicImage *assembly, MonoReflectionType *type, SigBuffer *buf)
{
if (!type) {
- mono_metadata_encode_value (MONO_TYPE_VOID, p, endbuf);
+ sigbuffer_add_value (buf, MONO_TYPE_VOID);
return;
}
- if (type->type) {
- encode_type (assembly, type->type, p, endbuf);
+
+ if (type->type ||
+ ((type = mono_reflection_type_get_underlying_system_type (type)) && type->type)) {
+ encode_type (assembly, type->type, buf);
return;
}
}
static void
-encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, char *p, char **endbuf)
+encode_custom_modifiers (MonoDynamicImage *assembly, MonoArray *modreq, MonoArray *modopt, SigBuffer *buf)
{
int i;
if (modreq) {
for (i = 0; i < mono_array_length (modreq); ++i) {
MonoReflectionType *mod = mono_array_get (modreq, MonoReflectionType*, i);
- *p = MONO_TYPE_CMOD_REQD;
- p++;
- mono_metadata_encode_value (mono_image_typedef_or_ref (assembly, mod->type), p, &p);
+ sigbuffer_add_byte (buf, MONO_TYPE_CMOD_REQD);
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
}
}
if (modopt) {
for (i = 0; i < mono_array_length (modopt); ++i) {
MonoReflectionType *mod = mono_array_get (modopt, MonoReflectionType*, i);
- *p = MONO_TYPE_CMOD_OPT;
- p++;
- mono_metadata_encode_value (mono_image_typedef_or_ref (assembly, mod->type), p, &p);
+ sigbuffer_add_byte (buf, MONO_TYPE_CMOD_OPT);
+ sigbuffer_add_value (buf, mono_image_typedef_or_ref (assembly, mod->type));
}
}
- *endbuf = p;
-}
-
-static guint32
-generic_class_get_signature_size (MonoGenericClass *gclass)
-{
- guint32 size = 0;
- int i;
-
- if (!gclass) {
- g_assert_not_reached ();
- }
-
- size += 1 + type_get_signature_size (&gclass->container_class->byval_arg);
- size += 4;
- for (i = 0; i < gclass->inst->type_argc; ++i)
- size += type_get_signature_size (gclass->inst->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_class_get_signature_size (type->data.generic_class);
- 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;
- if (sig->sentinelpos >= 0)
- size++;
-
- return size;
}
static guint32
method_encode_signature (MonoDynamicImage *assembly, MonoMethodSignature *sig)
{
- char *buf;
- char *p;
+ SigBuffer buf;
int i;
guint32 nparams = sig->param_count;
- guint32 size = 11 + method_get_signature_size (sig);
guint32 idx;
- char blob_size [6];
- char *b = blob_size;
if (!assembly->save)
return 0;
- p = buf = g_malloc (size);
+ sigbuffer_init (&buf, 32);
/*
* FIXME: vararg, explicit_this, differenc call_conv values...
*/
- *p = sig->call_convention;
+ idx = sig->call_convention;
if (sig->hasthis)
- *p |= 0x20; /* hasthis */
+ idx |= 0x20; /* hasthis */
if (sig->generic_param_count)
- *p |= 0x10; /* generic */
- p++;
+ idx |= 0x10; /* generic */
+ sigbuffer_add_byte (&buf, idx);
if (sig->generic_param_count)
- mono_metadata_encode_value (sig->generic_param_count, p, &p);
- mono_metadata_encode_value (nparams, p, &p);
- encode_type (assembly, sig->ret, p, &p);
+ sigbuffer_add_value (&buf, sig->generic_param_count);
+ sigbuffer_add_value (&buf, nparams);
+ encode_type (assembly, sig->ret, &buf);
for (i = 0; i < nparams; ++i) {
if (i == sig->sentinelpos)
- *p++ = MONO_TYPE_SENTINEL;
- encode_type (assembly, sig->params [i], p, &p);
+ sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
+ encode_type (assembly, sig->params [i], &buf);
}
- /* store length */
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
/*
* FIXME: reuse code from method_encode_signature().
*/
- char *buf;
- char *p;
+ SigBuffer buf;
int i;
guint32 nparams = mb->parameters ? mono_array_length (mb->parameters): 0;
guint32 ngparams = mb->generic_params ? mono_array_length (mb->generic_params): 0;
guint32 notypes = mb->opt_types ? mono_array_length (mb->opt_types): 0;
- guint32 size = 41 + nparams * 40 + notypes * 40;
guint32 idx;
- char blob_size [6];
- char *b = blob_size;
- p = buf = g_malloc (size);
+ sigbuffer_init (&buf, 32);
/* LAMESPEC: all the call conv spec is foobared */
- *p = mb->call_conv & 0x60; /* has-this, explicit-this */
+ idx = mb->call_conv & 0x60; /* has-this, explicit-this */
if (mb->call_conv & 2)
- *p |= 0x5; /* vararg */
+ idx |= 0x5; /* vararg */
if (!(mb->attrs & METHOD_ATTRIBUTE_STATIC))
- *p |= 0x20; /* hasthis */
+ idx |= 0x20; /* hasthis */
if (ngparams)
- *p |= 0x10; /* generic */
- p++;
+ idx |= 0x10; /* generic */
+ sigbuffer_add_byte (&buf, idx);
if (ngparams)
- mono_metadata_encode_value (ngparams, p, &p);
- mono_metadata_encode_value (nparams + notypes, p, &p);
- encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, p, &p);
- encode_reflection_type (assembly, mb->rtype, p, &p);
+ sigbuffer_add_value (&buf, ngparams);
+ sigbuffer_add_value (&buf, nparams + notypes);
+ encode_custom_modifiers (assembly, mb->return_modreq, mb->return_modopt, &buf);
+ encode_reflection_type (assembly, mb->rtype, &buf);
for (i = 0; i < nparams; ++i) {
MonoArray *modreq = NULL;
MonoArray *modopt = NULL;
modreq = mono_array_get (mb->param_modreq, MonoArray*, i);
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, p, &p);
+ encode_custom_modifiers (assembly, modreq, modopt, &buf);
pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, p, &p);
+ encode_reflection_type (assembly, pt, &buf);
}
if (notypes)
- *p++ = MONO_TYPE_SENTINEL;
+ sigbuffer_add_byte (&buf, MONO_TYPE_SENTINEL);
for (i = 0; i < notypes; ++i) {
MonoReflectionType *pt;
pt = mono_array_get (mb->opt_types, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, p, &p);
+ encode_reflection_type (assembly, pt, &buf);
}
- /* store length */
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
{
MonoDynamicTable *table;
guint32 *values;
- char *p;
- guint32 idx, sig_idx, size;
+ guint32 idx, sig_idx;
guint nl = mono_array_length (ilgen->locals);
- char *buf;
- char blob_size [6];
- char *b = blob_size;
+ SigBuffer buf;
int i;
- size = 50 + nl * 30;
- p = buf = g_malloc (size);
+ sigbuffer_init (&buf, 32);
table = &assembly->tables [MONO_TABLE_STANDALONESIG];
idx = table->next_idx ++;
table->rows ++;
alloc_table (table, table->rows);
values = table->values + idx * MONO_STAND_ALONE_SIGNATURE_SIZE;
- mono_metadata_encode_value (0x07, p, &p);
- mono_metadata_encode_value (nl, p, &p);
+ sigbuffer_add_value (&buf, 0x07);
+ sigbuffer_add_value (&buf, nl);
for (i = 0; i < nl; ++i) {
MonoReflectionLocalBuilder *lb = mono_array_get (ilgen->locals, MonoReflectionLocalBuilder*, i);
if (lb->is_pinned)
- mono_metadata_encode_value (MONO_TYPE_PINNED, p, &p);
+ sigbuffer_add_value (&buf, MONO_TYPE_PINNED);
- encode_reflection_type (assembly, lb->type, p, &p);
+ encode_reflection_type (assembly, lb->type, &buf);
}
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- sig_idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ sig_idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
values [MONO_STAND_ALONE_SIGNATURE] = sig_idx;
sheader [1] = num_exception & 0xff;
sheader [2] = (num_exception >> 8) & 0xff;
sheader [3] = (num_exception >> 16) & 0xff;
- mono_image_add_stream_data (&assembly->code, sheader, 4);
+ mono_image_add_stream_data (&assembly->code, (char*)sheader, 4);
/* fat header, so we are already aligned */
/* reverse order */
for (i = mono_array_length (mb->ilgen->ex_handlers) - 1; i >= 0; --i) {
return 0;
}
+/* protected by reflection_mutex:
+ * maps a mono runtime reflection handle to MonoCustomAttrInfo*
+ */
static GHashTable *dynamic_custom_attrs = NULL;
+static MonoCustomAttrInfo*
+lookup_custom_attr (void *member)
+{
+ MonoCustomAttrInfo *ainfo, *res;
+ int size;
+
+ mono_reflection_lock ();
+ ainfo = g_hash_table_lookup (dynamic_custom_attrs, member);
+ mono_reflection_unlock ();
+
+ if (ainfo) {
+ /* Need to copy since it will be freed later */
+ size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+ res = g_malloc0 (size);
+ memcpy (res, ainfo, size);
+ return res;
+ }
+ return NULL;
+}
+
static gboolean
custom_attr_visible (MonoImage *image, MonoReflectionCustomAttr *cattr)
{
ainfo->image = image;
ainfo->num_attrs = count;
index = 0;
+ mono_loader_lock ();
for (i = 0; i < count; ++i) {
cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
if (custom_attr_visible (image, cattr)) {
+ unsigned char *saved = mono_mempool_alloc (image->mempool, mono_array_length (cattr->data));
+ memcpy (saved, mono_array_addr (cattr->data, char, 0), mono_array_length (cattr->data));
ainfo->attrs [index].ctor = cattr->ctor->method;
- /* FIXME: might want to memdup the data here */
- ainfo->attrs [index].data = mono_array_addr (cattr->data, char, 0);
+ ainfo->attrs [index].data = saved;
ainfo->attrs [index].data_size = mono_array_length (cattr->data);
index ++;
}
}
+ mono_loader_unlock ();
return ainfo;
}
if (!ainfo)
return;
+ mono_reflection_lock ();
if (!dynamic_custom_attrs)
dynamic_custom_attrs = g_hash_table_new (NULL, NULL);
g_hash_table_insert (dynamic_custom_attrs, obj, ainfo);
ainfo->cached = TRUE;
+ mono_reflection_unlock ();
}
void
static void
reflection_methodbuilder_from_method_builder (ReflectionMethodBuilder *rmb, MonoReflectionMethodBuilder *mb)
{
+ memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
rmb->ilgen = mb->ilgen;
rmb->rtype = mb->rtype;
rmb->parameters = mb->parameters;
rmb->name = mb->name;
rmb->table_idx = &mb->table_idx;
rmb->init_locals = mb->init_locals;
+ rmb->skip_visibility = FALSE;
rmb->return_modreq = mb->return_modreq;
rmb->return_modopt = mb->return_modopt;
rmb->param_modreq = mb->param_modreq;
{
const char *name = mb->attrs & METHOD_ATTRIBUTE_STATIC ? ".cctor": ".ctor";
+ memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
rmb->ilgen = mb->ilgen;
rmb->rtype = mono_type_get_object (mono_domain_get (), &mono_defaults.void_class->byval_arg);
rmb->parameters = mb->parameters;
rmb->name = mono_string_new (mono_domain_get (), name);
rmb->table_idx = &mb->table_idx;
rmb->init_locals = mb->init_locals;
+ rmb->skip_visibility = FALSE;
rmb->return_modreq = NULL;
rmb->return_modopt = NULL;
rmb->param_modreq = mb->param_modreq;
static void
reflection_methodbuilder_from_dynamic_method (ReflectionMethodBuilder *rmb, MonoReflectionDynamicMethod *mb)
{
+ memset (rmb, 0, sizeof (ReflectionMethodBuilder));
+
rmb->ilgen = mb->ilgen;
rmb->rtype = mb->rtype;
rmb->parameters = mb->parameters;
rmb->iattrs = 0;
rmb->call_conv = mb->call_conv;
rmb->code = NULL;
- rmb->type = NULL;
+ rmb->type = (MonoObject *) mb->owner;
rmb->name = mb->name;
rmb->table_idx = NULL;
rmb->init_locals = mb->init_locals;
if (!klass)
return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
ta = klass->image->assembly;
- if (ta->dynamic || (ta == ass))
- return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
+ if (ta->dynamic || (ta == ass)) {
+ if (klass->generic_class)
+ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_FULL_NAME);
+ else
+ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
+ }
return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
}
static guint32
fieldref_encode_signature (MonoDynamicImage *assembly, MonoType *type)
{
- char blob_size [64];
- char *b = blob_size;
- char *p;
- char* buf;
+ SigBuffer buf;
guint32 idx;
if (!assembly->save)
return 0;
- p = buf = g_malloc (256);
+ sigbuffer_init (&buf, 32);
- mono_metadata_encode_value (0x06, p, &p);
+ sigbuffer_add_value (&buf, 0x06);
/* encode custom attributes before the type */
- encode_type (assembly, type, p, &p);
- g_assert (p-buf < 256);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ encode_type (assembly, type, &buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
static guint32
field_encode_signature (MonoDynamicImage *assembly, MonoReflectionFieldBuilder *fb)
{
- char blob_size [64];
- char *b = blob_size;
- char *p;
- char* buf;
+ SigBuffer buf;
guint32 idx;
+
+ sigbuffer_init (&buf, 32);
- p = buf = g_malloc (256);
-
- mono_metadata_encode_value (0x06, p, &p);
- encode_custom_modifiers (assembly, fb->modreq, fb->modopt, p, &p);
+ sigbuffer_add_value (&buf, 0x06);
+ encode_custom_modifiers (assembly, fb->modreq, fb->modopt, &buf);
/* encode custom attributes before the type */
- encode_reflection_type (assembly, fb->type, p, &p);
- g_assert (p-buf < 256);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ encode_reflection_type (assembly, fb->type, &buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
g_free (buf);
return idx;
}
+ case MONO_TYPE_GENERICINST:
+ *ret_type = val->vtable->klass->generic_class->container_class->byval_arg.type;
+ goto handle_enum;
default:
g_error ("we don't encode constant type 0x%02x yet", *ret_type);
}
static guint32
encode_marshal_blob (MonoDynamicImage *assembly, MonoReflectionMarshal *minfo) {
- char blob_size [64];
- char *b = blob_size;
- char *p, *buf, *str;
- guint32 idx, len, bufsize = 256;
-
- p = buf = g_malloc (bufsize);
+ char *str;
+ SigBuffer buf;
+ guint32 idx, len;
- mono_metadata_encode_value (minfo->type, p, &p);
+ sigbuffer_init (&buf, 32);
+
+ sigbuffer_add_value (&buf, minfo->type);
switch (minfo->type) {
case MONO_NATIVE_BYVALTSTR:
case MONO_NATIVE_BYVALARRAY:
- mono_metadata_encode_value (minfo->count, p, &p);
+ sigbuffer_add_value (&buf, minfo->count);
break;
case MONO_NATIVE_LPARRAY:
if (minfo->eltype || minfo->has_size) {
- mono_metadata_encode_value (minfo->eltype, p, &p);
+ sigbuffer_add_value (&buf, minfo->eltype);
if (minfo->has_size) {
- if (minfo->param_num != -1)
- mono_metadata_encode_value (minfo->param_num, p, &p);
- else
- mono_metadata_encode_value (0, p, &p);
- if (minfo->count != -1)
- mono_metadata_encode_value (minfo->count, p, &p);
- else
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, minfo->param_num != -1? minfo->param_num: 0);
+ sigbuffer_add_value (&buf, minfo->count != -1? minfo->count: 0);
/* LAMESPEC: ElemMult is undocumented */
- if (minfo->param_num != -1)
- mono_metadata_encode_value (1, p, &p);
- else
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, minfo->param_num != -1? 1: 0);
}
}
break;
if (minfo->guid) {
str = mono_string_to_utf8 (minfo->guid);
len = strlen (str);
- mono_metadata_encode_value (len, p, &p);
- memcpy (p, str, len);
- p += len;
+ sigbuffer_add_value (&buf, len);
+ sigbuffer_add_mem (&buf, str, len);
g_free (str);
} else {
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, 0);
}
/* native type name */
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, 0);
/* custom marshaler type name */
if (minfo->marshaltype || minfo->marshaltyperef) {
if (minfo->marshaltyperef)
else
str = mono_string_to_utf8 (minfo->marshaltype);
len = strlen (str);
- mono_metadata_encode_value (len, p, &p);
- if (p + len >= buf + bufsize) {
- idx = p - buf;
- bufsize *= 2;
- buf = g_realloc (buf, bufsize);
- p = buf + idx;
- }
- memcpy (p, str, len);
- p += len;
+ sigbuffer_add_value (&buf, len);
+ sigbuffer_add_mem (&buf, str, len);
g_free (str);
} else {
/* FIXME: Actually a bug, since this field is required. Punting for now ... */
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, 0);
}
if (minfo->mcookie) {
str = mono_string_to_utf8 (minfo->mcookie);
len = strlen (str);
- mono_metadata_encode_value (len, p, &p);
- if (p + len >= buf + bufsize) {
- idx = p - buf;
- bufsize *= 2;
- buf = g_realloc (buf, bufsize);
- p = buf + idx;
- }
- memcpy (p, str, len);
- p += len;
+ sigbuffer_add_value (&buf, len);
+ sigbuffer_add_mem (&buf, str, len);
g_free (str);
} else {
- mono_metadata_encode_value (0, p, &p);
+ sigbuffer_add_value (&buf, 0);
}
break;
default:
break;
}
- len = p-buf;
- mono_metadata_encode_value (len, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, len);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
/*
* We store it in the code section because it's simpler for now.
*/
- if (fb->rva_data)
+ if (fb->rva_data) {
+ if (mono_array_length (fb->rva_data) >= 10)
+ stream_data_align (&assembly->code);
rva_idx = mono_image_add_stream_data (&assembly->code, mono_array_addr (fb->rva_data, char, 0), mono_array_length (fb->rva_data));
- else
+ } 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;
}
static guint32
property_encode_signature (MonoDynamicImage *assembly, MonoReflectionPropertyBuilder *fb)
{
- char *buf, *p;
- char blob_size [6];
- char *b = blob_size;
+ SigBuffer buf;
guint32 nparams = 0;
MonoReflectionMethodBuilder *mb = fb->get_method;
MonoReflectionMethodBuilder *smb = fb->set_method;
- guint32 idx, i, size;
+ guint32 idx, i;
if (mb && mb->parameters)
nparams = mono_array_length (mb->parameters);
if (!mb && smb && smb->parameters)
nparams = mono_array_length (smb->parameters) - 1;
- size = 24 + nparams * 10;
- buf = p = g_malloc (size);
- *p = 0x08;
- p++;
- mono_metadata_encode_value (nparams, p, &p);
+ sigbuffer_init (&buf, 32);
+ sigbuffer_add_byte (&buf, 0x08);
+ sigbuffer_add_value (&buf, nparams);
if (mb) {
- encode_reflection_type (assembly, mb->rtype, p, &p);
+ encode_reflection_type (assembly, mb->rtype, &buf);
for (i = 0; i < nparams; ++i) {
MonoReflectionType *pt = mono_array_get (mb->parameters, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, p, &p);
+ encode_reflection_type (assembly, pt, &buf);
}
} else if (smb && smb->parameters) {
/* the property type is the last param */
- encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), p, &p);
+ encode_reflection_type (assembly, mono_array_get (smb->parameters, MonoReflectionType*, nparams), &buf);
for (i = 0; i < nparams; ++i) {
MonoReflectionType *pt = mono_array_get (smb->parameters, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, p, &p);
+ encode_reflection_type (assembly, pt, &buf);
}
- }
- else {
- encode_reflection_type (assembly, fb->type, p, &p);
+ } else {
+ encode_reflection_type (assembly, fb->type, &buf);
}
- /* store length */
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
if ((pubkey = mono_image_get_public_key (image, &publen))) {
guchar pubtoken [9];
pubtoken [0] = 8;
- mono_digest_get_public_token (pubtoken + 1, pubkey, publen);
- values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, pubtoken, 9);
+ mono_digest_get_public_token (pubtoken + 1, (guchar*)pubkey, publen);
+ values [MONO_ASSEMBLYREF_PUBLIC_KEY] = mono_image_add_stream_data (&assembly->blob, (char*)pubtoken, 9);
} else {
values [MONO_ASSEMBLYREF_PUBLIC_KEY] = 0;
}
MonoDynamicTable *table;
guint32 *values;
guint32 token;
- char sig [128];
- char *p = sig;
- char blob_size [6];
- char *b = blob_size;
+ SigBuffer buf;
+
+ if ((token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typespec, type))))
+ return token;
+ sigbuffer_init (&buf, 32);
switch (type->type) {
case MONO_TYPE_FNPTR:
case MONO_TYPE_PTR:
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
case MONO_TYPE_GENERICINST:
- encode_type (assembly, type, p, &p);
+ encode_type (assembly, type, &buf);
break;
case MONO_TYPE_CLASS:
case MONO_TYPE_VALUETYPE: {
MonoClass *k = mono_class_from_mono_type (type);
- if (!k || !k->generic_class)
+ if (!k || !k->generic_container) {
+ sigbuffer_free (&buf);
return 0;
- encode_generic_class (assembly, k->generic_class, p, &p);
+ }
+ encode_type (assembly, type, &buf);
break;
}
default:
+ sigbuffer_free (&buf);
return 0;
}
table = &assembly->tables [MONO_TABLE_TYPESPEC];
if (assembly->save) {
- g_assert (p-sig < 128);
- mono_metadata_encode_value (p-sig, b, &b);
- token = add_to_blob_cached (assembly, blob_size, b-blob_size, sig, p-sig);
+ token = sigbuffer_add_to_blob_cached (assembly, &buf);
alloc_table (table, table->rows + 1);
values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
values [MONO_TYPESPEC_SIGNATURE] = token;
}
+ sigbuffer_free (&buf);
token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
- g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->typespec, type, GUINT_TO_POINTER(token));
table->next_idx ++;
return token;
}
-/*
- * Despite the name, we handle also TypeSpec (with the above helper).
- */
static guint32
-mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
+mono_image_typedef_or_ref_full (MonoDynamicImage *assembly, MonoType *type, gboolean try_typespec)
{
MonoDynamicTable *table;
guint32 *values;
guint32 token, scope, enclosing;
MonoClass *klass;
- token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
- if (token)
+ /* if the type requires a typespec, we must try that first*/
+ if (try_typespec && (token = create_typespec (assembly, type)))
return token;
- token = create_typespec (assembly, type);
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->typeref, type));
if (token)
return token;
klass = my_mono_class_from_mono_type (type);
}
if (klass->nested_in) {
- enclosing = mono_image_typedef_or_ref (assembly, &klass->nested_in->byval_arg);
+ enclosing = mono_image_typedef_or_ref_full (assembly, &klass->nested_in->byval_arg, FALSE);
/* get the typeref idx of the enclosing type */
enclosing >>= MONO_TYPEDEFORREF_BITS;
scope = (enclosing << MONO_RESOLTION_SCOPE_BITS) | MONO_RESOLTION_SCOPE_TYPEREF;
return token;
}
+/*
+ * Despite the name, we handle also TypeSpec (with the above helper).
+ */
+static guint32
+mono_image_typedef_or_ref (MonoDynamicImage *assembly, MonoType *type)
+{
+ return mono_image_typedef_or_ref_full (assembly, type, TRUE);
+}
+
/*
* Insert a memberef row into the metadata: the token that point to the memberref
* is returned. Caching is done in the caller (mono_image_get_methodref_token() or
}
static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericMethod *gmethod)
+encode_generic_method_sig (MonoDynamicImage *assembly, MonoGenericContext *context)
{
- char *buf;
- char *p;
+ SigBuffer buf;
int i;
- guint32 nparams = gmethod->inst->type_argc;
- guint32 size = 10 + nparams * 30;
+ guint32 nparams = context->method_inst->type_argc;
guint32 idx;
- char blob_size [6];
- char *b = blob_size;
if (!assembly->save)
return 0;
- p = buf = g_malloc (size);
+ sigbuffer_init (&buf, 32);
/*
* FIXME: vararg, explicit_this, differenc call_conv values...
*/
- mono_metadata_encode_value (0xa, p, &p); /* FIXME FIXME FIXME */
- mono_metadata_encode_value (nparams, p, &p);
+ sigbuffer_add_value (&buf, 0xa); /* FIXME FIXME FIXME */
+ sigbuffer_add_value (&buf, nparams);
for (i = 0; i < nparams; i++)
- encode_type (assembly, gmethod->inst->type_argv [i], p, &p);
+ encode_type (assembly, context->method_inst->type_argv [i], &buf);
- /* store length */
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
table = &assembly->tables [MONO_TABLE_METHODSPEC];
g_assert (method->is_inflated);
- method = mono_get_inflated_method (method);
imethod = (MonoMethodInflated *) method;
declaring = imethod->declaring;
g_assert_not_reached ();
}
- sig = encode_generic_method_sig (assembly, imethod->context->gmethod);
+ sig = encode_generic_method_sig (assembly, mono_method_get_context (method));
if (assembly->save) {
alloc_table (table, table->rows + 1);
mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *method)
{
MonoMethodInflated *imethod;
- MonoMethod *inflated;
guint32 token;
token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
return token;
g_assert (method->is_inflated);
- inflated = mono_get_inflated_method (method);
- imethod = (MonoMethodInflated *) inflated;
+ imethod = (MonoMethodInflated *) method;
if (mono_method_signature (imethod->declaring)->generic_param_count) {
- token = method_encode_methodspec (assembly, inflated);
+ token = method_encode_methodspec (assembly, method);
} else {
guint32 sig = method_encode_signature (
assembly, mono_method_signature (imethod->declaring));
token = mono_image_get_memberref_token (
- assembly, &inflated->klass->byval_arg, inflated->name, sig);
+ assembly, &method->klass->byval_arg, method->name, sig);
}
g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
MonoMethodInflated *imethod = (MonoMethodInflated *) m;
guint32 sig, token;
- m = mono_get_inflated_method (m);
-
sig = method_encode_signature (assembly, mono_method_signature (imethod->declaring));
token = mono_image_get_memberref_token (
assembly, &m->klass->byval_arg, m->name, sig);
MonoClass *klass;
guint32 *values;
guint32 token;
- char sig [128];
- char *p = sig;
- char blob_size [6];
- char *b = blob_size;
+ SigBuffer buf;
int count, i;
/*
if (token)
return token;
+ sigbuffer_init (&buf, 32);
+
g_assert (tb->generic_params);
klass = mono_class_from_mono_type (tb->type.type);
- mono_metadata_encode_value (MONO_TYPE_GENERICINST, p, &p);
- encode_type (assembly, &klass->byval_arg, p, &p);
+ if (tb->generic_container)
+ mono_reflection_create_generic_class (tb);
+
+ sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
+ g_assert (klass->generic_container);
+ sigbuffer_add_value (&buf, klass->byval_arg.type);
+ sigbuffer_add_value (&buf, mono_image_typedef_or_ref_full (assembly, &klass->byval_arg, FALSE));
count = mono_array_length (tb->generic_params);
- mono_metadata_encode_value (count, p, &p);
+ sigbuffer_add_value (&buf, count);
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gparam;
gparam = mono_array_get (tb->generic_params, MonoReflectionGenericParam *, i);
- encode_type (assembly, gparam->type.type, p, &p);
+ encode_type (assembly, gparam->type.type, &buf);
}
table = &assembly->tables [MONO_TABLE_TYPESPEC];
- g_assert (p-sig < 128);
if (assembly->save) {
- mono_metadata_encode_value (p-sig, b, &b);
- token = add_to_blob_cached (assembly, blob_size, b-blob_size, sig, p-sig);
+ token = sigbuffer_add_to_blob_cached (assembly, &buf);
alloc_table (table, table->rows + 1);
values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
values [MONO_TYPESPEC_SIGNATURE] = token;
}
+ sigbuffer_free (&buf);
token = MONO_TYPEDEFORREF_TYPESPEC | (table->next_idx << MONO_TYPEDEFORREF_BITS);
g_hash_table_insert (assembly->typespec, tb->type.type, GUINT_TO_POINTER(token));
static guint32
mono_reflection_encode_sighelper (MonoDynamicImage *assembly, MonoReflectionSigHelper *helper)
{
- char *buf;
- char *p;
+ SigBuffer buf;
guint32 nargs;
guint32 size;
guint32 i, idx;
- char blob_size [6];
- char *b = blob_size;
if (!assembly->save)
return 0;
- /* FIXME: */
+ /* FIXME: this means SignatureHelper.SignatureHelpType.HELPER_METHOD */
g_assert (helper->type == 2);
if (helper->arguments)
size = 10 + (nargs * 10);
- p = buf = g_malloc (size);
+ sigbuffer_init (&buf, 32);
/* Encode calling convention */
/* Change Any to Standard */
helper->call_conv &= 0x20;
if (helper->call_conv == 0) { /* Unmanaged */
- *p = helper->unmanaged_call_conv - 1;
+ idx = helper->unmanaged_call_conv - 1;
} else {
/* Managed */
- *p = helper->call_conv & 0x60; /* has_this + explicit_this */
+ idx = helper->call_conv & 0x60; /* has_this + explicit_this */
if (helper->call_conv & 0x02) /* varargs */
- *p += 0x05;
+ idx += 0x05;
}
- p++;
- mono_metadata_encode_value (nargs, p, &p);
- encode_reflection_type (assembly, helper->return_type, p, &p);
+ sigbuffer_add_byte (&buf, idx);
+ sigbuffer_add_value (&buf, nargs);
+ encode_reflection_type (assembly, helper->return_type, &buf);
for (i = 0; i < nargs; ++i) {
- MonoReflectionType *pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
- encode_reflection_type (assembly, pt, p, &p);
+ MonoArray *modreqs = NULL;
+ MonoArray *modopts = NULL;
+ MonoReflectionType *pt;
+
+ if (helper->modreqs && (i < mono_array_length (helper->modreqs)))
+ modreqs = mono_array_get (helper->modreqs, MonoArray*, i);
+ if (helper->modopts && (i < mono_array_length (helper->modopts)))
+ modopts = mono_array_get (helper->modopts, MonoArray*, i);
+
+ encode_custom_modifiers (assembly, modreqs, modopts, &buf);
+ pt = mono_array_get (helper->arguments, MonoReflectionType*, i);
+ encode_reflection_type (assembly, pt, &buf);
}
- /* store length */
- g_assert (p - buf < size);
- mono_metadata_encode_value (p-buf, b, &b);
- idx = add_to_blob_cached (assembly, blob_size, b-blob_size, buf, p-buf);
- g_free (buf);
+ idx = sigbuffer_add_to_blob_cached (assembly, &buf);
+ sigbuffer_free (&buf);
return idx;
}
g_free (path);
mono_metadata_encode_value (20, b, &b);
values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
- mono_image_add_stream_data (&assembly->blob, hash, 20);
+ mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
table->next_idx ++;
}
heapt_size &= ~3;
meta_size += heapt_size;
meta->raw_metadata = g_malloc0 (meta_size);
- p = meta->raw_metadata;
+ p = (unsigned char*)meta->raw_metadata;
/* the metadata signature */
*p++ = 'B'; *p++ = 'S'; *p++ = 'J'; *p++ = 'B';
/* version numbers and 4 bytes reserved */
table_offset += GUINT32_FROM_LE (*int32val);
table_offset += 3; table_offset &= ~3;
p += 8;
- strcpy (p, stream_desc [i].name);
+ strcpy ((char*)p, stream_desc [i].name);
p += strlen (stream_desc [i].name) + 1;
align_pointer (meta->raw_metadata, p);
}
* now copy the data, the table stream header and contents goes first.
*/
g_assert ((p - (unsigned char*)meta->raw_metadata) < assembly->tstream.offset);
- p = meta->raw_metadata + assembly->tstream.offset;
+ p = (guchar*)meta->raw_metadata + assembly->tstream.offset;
int32val = (guint32*)p;
*int32val = GUINT32_TO_LE (0); /* reserved */
p += 4;
continue;
if (assembly->tables [i].columns != mono_metadata_table_count (bitfield))
g_error ("col count mismatch in %d: %d %d", i, assembly->tables [i].columns, mono_metadata_table_count (bitfield));
- meta->tables [i].base = p;
+ meta->tables [i].base = (char*)p;
for (row = 1; row <= meta->tables [i].rows; ++row) {
values = assembly->tables [i].values + row * assembly->tables [i].columns;
for (col = 0; col < assembly->tables [i].columns; ++col) {
for (i = 0; i < ilgen->num_token_fixups; ++i) {
iltoken = (MonoReflectionILTokenInfo *)mono_array_addr_with_size (ilgen->token_fixups, sizeof (MonoReflectionILTokenInfo), i);
- target = assembly->code.data + code_idx + iltoken->code_pos;
+ target = (guchar*)assembly->code.data + code_idx + iltoken->code_pos;
switch (target [3]) {
case MONO_TABLE_FIELD:
if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
g_assert (f->generic_info);
continue;
- } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
+ } else if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder") ||
+ !strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
continue;
} else {
g_assert_not_reached ();
mono_sha1_get_digest_from_file (name, hash);
mono_metadata_encode_value (20, b, &b);
values [MONO_FILE_HASH_VALUE] = mono_image_add_stream_data (&assembly->blob, blob_size, b-blob_size);
- mono_image_add_stream_data (&assembly->blob, hash, 20);
+ mono_image_add_stream_data (&assembly->blob, (char*)hash, 20);
g_free (name);
idx = table->next_idx++;
rsrc->offset = 0;
len = mono_array_length (pkey);
mono_metadata_encode_value (len, b, &b);
token = mono_image_add_stream_data (&assembly->blob, blob_size, b - blob_size);
- mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, guint8, 0), len);
+ mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);
+
+ assembly->public_key = g_malloc (len);
+ memcpy (assembly->public_key, mono_array_addr (pkey, char, 0), len);
+ assembly->public_key_len = len;
/* Special case: check for ECMA key (16 bytes) */
- if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, guint8, 0), len)) {
+ if ((len == MONO_ECMA_KEY_LENGTH) && mono_is_ecma_key (mono_array_addr (pkey, char, 0), len)) {
/* In this case we must reserve 128 bytes (1024 bits) for the signature */
assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH;
} else if (len >= MONO_PUBLIC_KEY_HEADER_LENGTH + MONO_MINIMUM_PUBLIC_KEY_LENGTH) {
* Get a token to insert in the IL code stream for the given MemberInfo.
* @obj can be one of:
* ConstructorBuilder
- * MethodBuilder
+ * EnumBuilder
* FieldBuilder
+ * GenericTypeParameterBuilder
+ * MethodBuilder
+ * MonoArrayMethod
* MonoCMethod
* MonoMethod
* MonoField
+ * MonoGenericClass
+ * MonoGenericMethod
+ * MonoGenericCMethod
* MonoType
+ * SignatureHelperxo
* TypeBuilder
*/
guint32
klass = obj->vtable->klass;
if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
- if (((MonoReflectionTypeBuilder*)mb->type)->module->dynamic_image == assembly)
+ if (tb->module->dynamic_image == assembly && !tb->generic_params)
token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
else
token = mono_image_get_methodbuilder_token (assembly, mb);
/*g_print ("got token 0x%08x for %s\n", token, mono_string_to_utf8 (mb->name));*/
} else if (strcmp (klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *mb = (MonoReflectionCtorBuilder *)obj;
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)mb->type;
- if (((MonoReflectionTypeBuilder*)mb->type)->module->dynamic_image == assembly)
+ if (tb->module->dynamic_image == assembly && !tb->generic_params)
token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
else
token = mono_image_get_ctorbuilder_token (assembly, mb);
} else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
- } else if (strcmp (klass->name, "MonoType") == 0 ||
- strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
+ } else if (strcmp (klass->name, "MonoType") == 0) {
+ MonoReflectionType *tb = (MonoReflectionType *)obj;
+ MonoClass *mc = mono_class_from_mono_type (tb->type);
+ token = mono_metadata_token_from_dor (
+ mono_image_typedef_or_ref_full (assembly, tb->type, mc->generic_container == NULL));
+ } else if (strcmp (klass->name, "GenericTypeParameterBuilder") == 0) {
MonoReflectionType *tb = (MonoReflectionType *)obj;
token = mono_metadata_token_from_dor (
mono_image_typedef_or_ref (assembly, tb->type));
#else
image = g_new0 (MonoDynamicImage, 1);
#endif
-
+
+ mono_profiler_module_event (&image->image, MONO_PROFILE_START_LOAD);
+
/*g_print ("created image %p\n", image);*/
/* keep in sync with image.c */
image->image.name = assembly_name;
mono_image_add_stream_data (&image->us, "", 1);
add_to_blob_cached (image, (char*) "", 1, NULL, 0);
/* import tables... */
- mono_image_add_stream_data (&image->code, entrycode, sizeof (entrycode));
+ mono_image_add_stream_data (&image->code, (char*)entrycode, sizeof (entrycode));
image->iat_offset = mono_image_add_stream_zero (&image->code, 8); /* two IAT entries */
image->idt_offset = mono_image_add_stream_zero (&image->code, 2 * sizeof (MonoIDT)); /* two IDT entries */
image->imp_names_offset = mono_image_add_stream_zero (&image->code, 2); /* flags for name entry */
image->save = assembly->save;
image->pe_kind = 0x1; /* ILOnly */
image->machine = 0x14c; /* I386 */
+
+ mono_profiler_module_loaded (&image->image, MONO_PROFILE_OK);
return image;
}
assembly = assemblyb->dynamic_assembly = g_new0 (MonoDynamicAssembly, 1);
#endif
+ mono_profiler_assembly_event (&assembly->assembly, MONO_PROFILE_START_LOAD);
+
assembly->assembly.ref_count = 1;
assembly->assembly.dynamic = TRUE;
assembly->assembly.corlib_internal = assemblyb->corlib_internal;
mono_domain_assemblies_unlock (domain);
register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
+
+ mono_profiler_assembly_loaded (&assembly->assembly, MONO_PROFILE_OK);
+
mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
}
resource_tree_encode (tree, p, p, &p);
- g_assert (p - buf < size);
+ g_assert (p - buf <= size);
assembly->win32_res = g_malloc (p - buf);
assembly->win32_res_size = p - buf;
/* The DOS header and stub */
g_assert (sizeof (MonoMSDOSHeader) == sizeof (msheader));
- mono_image_add_stream_data (pefile, msheader, sizeof (msheader));
+ mono_image_add_stream_data (pefile, (char*)msheader, sizeof (msheader));
/* the dotnet header */
header_start = mono_image_add_stream_zero (pefile, sizeof (MonoDotNetHeader));
rva = (guint32*)(assembly->code.data + assembly->idt_offset + G_STRUCT_OFFSET (MonoIDT, import_lookup_table));
*rva = GUINT32_FROM_LE (assembly->text_rva + assembly->ilt_offset);
- p = (assembly->code.data + assembly->ilt_offset);
+ p = (guchar*)(assembly->code.data + assembly->ilt_offset);
value = (assembly->text_rva + assembly->imp_names_offset);
*p++ = (value) & 0xff;
*p++ = (value >> 8) & (0xff);
switch (i) {
case MONO_SECTION_TEXT:
/* patch entry point */
- p = (assembly->code.data + 2);
+ p = (guchar*)(assembly->code.data + 2);
value = (virtual_base + assembly->text_rva + assembly->iat_offset);
*p++ = (value) & 0xff;
*p++ = (value >> 8) & 0xff;
}
MonoReflectionModule *
-mono_image_load_module (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
+mono_image_load_module_dynamic (MonoReflectionAssemblyBuilder *ab, MonoString *fileName)
{
char *name;
MonoImage *image;
MonoDynamicAssembly *assembly;
guint32 module_count;
MonoImage **new_modules;
+ gboolean *new_modules_loaded;
name = mono_string_to_utf8 (fileName);
module_count = image->assembly->image->module_count;
new_modules = g_new0 (MonoImage *, module_count + 1);
+ new_modules_loaded = g_new0 (gboolean, module_count + 1);
if (image->assembly->image->modules)
memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
+ if (image->assembly->image->modules_loaded)
+ memcpy (new_modules_loaded, image->assembly->image->modules_loaded, module_count * sizeof (gboolean));
new_modules [module_count] = image;
+ new_modules_loaded [module_count] = TRUE;
mono_image_addref (image);
g_free (image->assembly->image->modules);
image->assembly->image->modules = new_modules;
+ image->assembly->image->modules_loaded = new_modules_loaded;
image->assembly->image->module_count ++;
mono_assembly_load_references (image, &status);
mono_domain_unlock (domain); \
} while (0)
-#if HAVE_BOEHM_GC
-#define ALLOC_REFENTRY GC_MALLOC (sizeof (ReflectedEntry))
-#elif HAVE_SGEN_GC
+#ifndef HAVE_NULL_GC
#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL)
#else
#define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
return t1->data.array->eklass == t2->data.array->eklass;
case MONO_TYPE_GENERICINST: {
int i;
- if (t1->data.generic_class->inst->type_argc != t2->data.generic_class->inst->type_argc)
+ MonoGenericInst *i1 = t1->data.generic_class->context.class_inst;
+ MonoGenericInst *i2 = t2->data.generic_class->context.class_inst;
+ if (i1->type_argc != i2->type_argc)
return FALSE;
if (!mono_metadata_type_equal (&t1->data.generic_class->container_class->byval_arg,
&t2->data.generic_class->container_class->byval_arg))
return FALSE;
- for (i = 0; i < t1->data.generic_class->inst->type_argc; ++i) {
- if (!mono_metadata_type_equal (t1->data.generic_class->inst->type_argv [i], t2->data.generic_class->inst->type_argv [i]))
+ /* FIXME: we should probably just compare the instance pointers directly. */
+ for (i = 0; i < i1->type_argc; ++i) {
+ if (!mono_metadata_type_equal (i1->type_argv [i], i2->type_argv [i]))
return FALSE;
}
return TRUE;
return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
case MONO_TYPE_GENERICINST: {
int i;
- MonoGenericInst *inst = t1->data.generic_class->inst;
+ MonoGenericInst *inst = t1->data.generic_class->context.class_inst;
hash += g_str_hash (t1->data.generic_class->container_class->name);
hash *= 13;
for (i = 0; i < inst->type_argc; ++i) {
#endif
res->type.type = geninst;
- if (gklass->wastypebuilder && gklass->reflection_info)
- MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
- else
- MONO_OBJECT_SETREF (res, generic_type, mono_type_get_object (domain, &gklass->byval_arg));
+ g_assert (gklass->reflection_info);
+ g_assert (!strcmp (((MonoObject*)gklass->reflection_info)->vtable->klass->name, "TypeBuilder"));
+ MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
return res;
}
mono_domain_unlock (domain);
return res;
}
- if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic) {
+ /* Create a MonoGenericClass object for instantiations of not finished TypeBuilders */
+ if ((type->type == MONO_TYPE_GENERICINST) && type->data.generic_class->is_dynamic && !type->data.generic_class->container_class->wastypebuilder) {
res = (MonoReflectionType *)mono_generic_class_get_object (domain, type);
mono_g_hash_table_insert (domain->type_hash, type, res);
mono_domain_unlock (domain);
static MonoClass *System_Reflection_MonoCMethod = NULL;
static MonoClass *System_Reflection_MonoGenericMethod = NULL;
static MonoClass *System_Reflection_MonoGenericCMethod = NULL;
- const char *cname;
MonoClass *klass;
MonoReflectionMethod *ret;
if (method->is_inflated) {
MonoReflectionGenericMethod *gret;
- method = mono_get_inflated_method (method);
refclass = method->klass;
CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) {
}
ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
ret->method = method;
- MONO_OBJECT_SETREF (ret, name, mono_string_new (domain, method->name));
MONO_OBJECT_SETREF (ret, reftype, mono_type_get_object (domain, &refclass->byval_arg));
CACHE_OBJECT (MonoReflectionMethod *, method, ret, refclass);
}
mono_field_get_object (MonoDomain *domain, MonoClass *klass, MonoClassField *field)
{
MonoReflectionField *res;
- MonoClass *oklass;
+ static MonoClass *monofield_klass;
CHECK_OBJECT (MonoReflectionField *, field, klass);
- oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoField");
- res = (MonoReflectionField *)mono_object_new (domain, oklass);
+ if (!monofield_klass)
+ monofield_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoField");
+ res = (MonoReflectionField *)mono_object_new (domain, monofield_klass);
res->klass = klass;
res->field = field;
MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
mono_property_get_object (MonoDomain *domain, MonoClass *klass, MonoProperty *property)
{
MonoReflectionProperty *res;
- MonoClass *oklass;
+ static MonoClass *monoproperty_klass;
CHECK_OBJECT (MonoReflectionProperty *, property, klass);
- oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoProperty");
- res = (MonoReflectionProperty *)mono_object_new (domain, oklass);
+ if (!monoproperty_klass)
+ monoproperty_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoProperty");
+ res = (MonoReflectionProperty *)mono_object_new (domain, monoproperty_klass);
res->klass = klass;
res->property = property;
CACHE_OBJECT (MonoReflectionProperty *, property, res, klass);
mono_event_get_object (MonoDomain *domain, MonoClass *klass, MonoEvent *event)
{
MonoReflectionEvent *res;
- MonoClass *oklass;
+ static MonoClass *monoevent_klass;
CHECK_OBJECT (MonoReflectionEvent *, event, klass);
- oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
- res = (MonoReflectionEvent *)mono_object_new (domain, oklass);
+ if (!monoevent_klass)
+ monoevent_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoEvent");
+ res = (MonoReflectionEvent *)mono_object_new (domain, monoevent_klass);
res->klass = klass;
res->event = event;
CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
}
+/**
+ * mono_get_reflection_missing_object:
+ * @domain: Domain where the object lives
+ *
+ * Returns the System.Reflection.Missing.Value singleton object
+ * (of type System.Reflection.Missing).
+ *
+ * Used as the value for ParameterInfo.DefaultValue when Optional
+ * is present
+ */
+static MonoObject *
+mono_get_reflection_missing_object (MonoDomain *domain)
+{
+ MonoObject *obj;
+ static MonoClassField *missing_value_field = NULL;
+
+ if (!missing_value_field) {
+ MonoClass *missing_klass;
+ missing_klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "Missing");
+ mono_class_init (missing_klass);
+ missing_value_field = mono_class_get_field_from_name (missing_klass, "Value");
+ g_assert (missing_value_field);
+ }
+ obj = mono_field_get_value_object (domain, missing_value_field, NULL);
+ g_assert (obj);
+ return obj;
+}
+
+static MonoObject*
+get_dbnull (MonoDomain *domain, MonoObject **dbnull)
+{
+ if (!*dbnull)
+ *dbnull = mono_get_dbnull_object (domain);
+ return *dbnull;
+}
+
+static MonoObject*
+get_reflection_missing (MonoDomain *domain, MonoObject **reflection_missing)
+{
+ if (!*reflection_missing)
+ *reflection_missing = mono_get_reflection_missing_object (domain);
+ return *reflection_missing;
+}
+
/*
* mono_param_get_objects:
* @domain: an app domain
char **names, **blobs = NULL;
guint32 *types = NULL;
MonoType *type = NULL;
- MonoObject *dbnull = mono_get_dbnull_object (domain);
+ MonoObject *dbnull = NULL;
+ MonoObject *missing = NULL;
MonoMarshalSpec **mspecs;
MonoMethodSignature *sig;
int i;
param->AttrsImpl = sig->params [i]->attrs;
if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
- MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
+ if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
+ else
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
} else {
if (!blobs) {
MONO_OBJECT_SETREF (param, DefaultValueImpl, mono_get_object_from_blob (domain, type, blobs [i]));
/* Type in the Constant table is MONO_TYPE_CLASS for nulls */
- if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl)
- MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
+ if (types [i] != MONO_TYPE_CLASS && !param->DefaultValueImpl) {
+ if (param->AttrsImpl & PARAM_ATTRIBUTE_OPTIONAL)
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, get_reflection_missing (domain, &missing));
+ else
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, get_dbnull (domain, &dbnull));
+ }
}
return ret;
}
+/**
+ * mono_get_dbnull_object:
+ * @domain: Domain where the object lives
+ *
+ * Returns the System.DBNull.Value singleton object
+ *
+ * Used as the value for ParameterInfo.DefaultValue
+ */
MonoObject *
mono_get_dbnull_object (MonoDomain *domain)
{
MonoObject *obj;
- MonoClass *klass;
static MonoClassField *dbnull_value_field = NULL;
if (!dbnull_value_field) {
- klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
- mono_class_init (klass);
- dbnull_value_field = mono_class_get_field_from_name (klass, "Value");
+ MonoClass *dbnull_klass;
+ dbnull_klass = mono_class_from_name (mono_defaults.corlib, "System", "DBNull");
+ mono_class_init (dbnull_klass);
+ dbnull_value_field = mono_class_get_field_from_name (dbnull_klass, "Value");
g_assert (dbnull_value_field);
}
obj = mono_field_get_value_object (domain, dbnull_value_field, NULL);
return obj;
}
-
static void
get_default_param_value_blobs (MonoMethod *method, char **blobs, guint32 *types)
{
len = (p - start + 1);
if (len > MONO_PUBLIC_KEY_TOKEN_LENGTH)
len = MONO_PUBLIC_KEY_TOKEN_LENGTH;
- g_strlcpy (assembly->public_key_token, start, len);
+ g_strlcpy ((char*)assembly->public_key_token, start, len);
}
} else {
while (*p && *p != ',')
start = p = w = name;
+ //FIXME could we just zero the whole struct? memset (&info, 0, sizeof (MonoTypeNameParse))
memset (&info->assembly, 0, sizeof (MonoAssemblyName));
info->name = info->name_space = NULL;
info->nested = NULL;
{
gboolean type_resolve = FALSE;
MonoType *type;
+ MonoImage *rootimage = image;
if (info->assembly.name) {
MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
image = mono_defaults.corlib;
}
- type = mono_reflection_get_type (image, info, ignorecase, &type_resolve);
+ type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
if (type == NULL && !info->assembly.name && image != mono_defaults.corlib) {
image = mono_defaults.corlib;
- type = mono_reflection_get_type (image, info, ignorecase, &type_resolve);
+ type = mono_reflection_get_type_with_rootimage (rootimage, image, info, ignorecase, &type_resolve);
}
return type;
}
static MonoType*
-mono_reflection_get_type_internal (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
+mono_reflection_get_type_internal (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase)
{
MonoClass *klass;
GList *mod;
for (i = 0; i < info->type_arguments->len; i++) {
MonoTypeNameParse *subinfo = g_ptr_array_index (info->type_arguments, i);
- type_args [i] = _mono_reflection_get_type_from_info (subinfo, image, ignorecase);
+ type_args [i] = _mono_reflection_get_type_from_info (subinfo, rootimage, ignorecase);
if (!type_args [i]) {
g_free (type_args);
return NULL;
instance = mono_reflection_bind_generic_parameters (
the_type, info->type_arguments->len, type_args);
- if (!instance) {
- g_free (type_args);
+ g_free (type_args);
+ if (!instance)
return NULL;
- }
klass = mono_class_from_mono_type (instance);
}
*/
MonoType*
-mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
+mono_reflection_get_type (MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve) {
+ return mono_reflection_get_type_with_rootimage(image, image, info, ignorecase, type_resolve);
+}
+
+static MonoType*
+mono_reflection_get_type_internal_dynamic (MonoImage *rootimage, MonoAssembly *assembly, MonoTypeNameParse *info, gboolean ignorecase)
+{
+ MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)mono_assembly_get_object (mono_domain_get (), assembly);
+ MonoType *type;
+ int i;
+
+ g_assert (assembly->dynamic);
+
+ /* Enumerate all modules */
+
+ type = NULL;
+ 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_internal (rootimage, &mb->dynamic_image->image, info, ignorecase);
+ if (type)
+ break;
+ }
+ }
+
+ 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_internal (rootimage, mod->image, info, ignorecase);
+ if (type)
+ break;
+ }
+ }
+
+ return type;
+}
+
+MonoType*
+mono_reflection_get_type_with_rootimage (MonoImage *rootimage, MonoImage* image, MonoTypeNameParse *info, gboolean ignorecase, gboolean *type_resolve)
{
MonoType *type;
MonoReflectionAssembly *assembly;
GString *fullName;
GList *mod;
- type = mono_reflection_get_type_internal (image, info, ignorecase);
+ if (image && image->dynamic)
+ type = mono_reflection_get_type_internal_dynamic (rootimage, image->assembly, info, ignorecase);
+ else
+ type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase);
if (type)
return type;
if (!mono_domain_has_type_resolve (mono_domain_get ()))
assembly = mono_domain_try_type_resolve ( mono_domain_get (), fullName->str, NULL);
if (assembly) {
- if (assembly->assembly->dynamic) {
- /* Enumerate all modules */
- MonoReflectionAssemblyBuilder *abuilder = (MonoReflectionAssemblyBuilder*)assembly;
- int i;
-
- type = NULL;
- 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_internal (&mb->dynamic_image->image, info, ignorecase);
- if (type)
- break;
- }
- }
-
- 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_internal (mod->image, info, ignorecase);
- if (type)
- break;
- }
- }
- }
+ if (assembly->assembly->dynamic)
+ type = mono_reflection_get_type_internal_dynamic (rootimage, assembly->assembly, info, ignorecase);
else
- type = mono_reflection_get_type_internal (assembly->assembly->image,
+ type = mono_reflection_get_type_internal (rootimage, assembly->assembly->image,
info, ignorecase);
}
g_string_free (fullName, TRUE);
return type;
}
-static void
-free_type_info (MonoTypeNameParse *info)
+void
+mono_reflection_free_type_info (MonoTypeNameParse *info)
{
g_list_free (info->modifiers);
g_list_free (info->nested);
for (i = 0; i < info->type_arguments->len; i++) {
MonoTypeNameParse *subinfo = g_ptr_array_index (info->type_arguments, i);
- free_type_info (subinfo);
+ mono_reflection_free_type_info (subinfo);
+ /*We free the subinfo since it is allocated by _mono_reflection_parse_type*/
+ g_free (subinfo);
}
g_ptr_array_free (info->type_arguments, TRUE);
}
g_free (tmp);
- free_type_info (&info);
+ mono_reflection_free_type_info (&info);
return type;
}
token = mb->table_idx | MONO_TOKEN_METHOD_DEF;
} else if (strcmp (klass->name, "FieldBuilder") == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder *)obj;
- token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
+
+ /* Call mono_image_create_token so the object gets added to the tokens hash table */
+ token = mono_image_create_token (((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image, obj, FALSE);
} else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
case MONO_TYPE_U: /* error out instead? this should probably not happen */
case MONO_TYPE_I:
#endif
- case MONO_TYPE_R8:
case MONO_TYPE_U8:
case MONO_TYPE_I8: {
guint64 *val = g_malloc (sizeof (guint64));
*end = p + 8;
return val;
}
+ case MONO_TYPE_R8: {
+ double *val = g_malloc (sizeof (double));
+ readr8 (p, val);
+ *end = p + 8;
+ return val;
+ }
case MONO_TYPE_VALUETYPE:
if (t->data.klass->enumtype) {
type = t->data.klass->enum_basetype->type;
int etype = *p;
p ++;
+ if (etype == 0x51)
+ /* See Partition II, Appendix B3 */
+ etype = MONO_TYPE_OBJECT;
type = MONO_TYPE_SZARRAY;
simple_type.type = etype;
tklass = mono_class_from_mono_type (&simple_type);
}
break;
case MONO_TYPE_R8:
+ for (i = 0; i < alen; i++) {
+ double val;
+ readr8 (p, &val);
+ mono_array_set (arr, double, i, val);
+ p += 8;
+ }
+ break;
case MONO_TYPE_U8:
case MONO_TYPE_I8:
for (i = 0; i < alen; i++) {
{
MonoArray *typedargs, *namedargs;
MonoClass *attrklass;
- static MonoClass *klass;
static MonoMethod *ctor;
MonoDomain *domain;
MonoObject *attr;
void *params [3];
mono_class_init (method->klass);
-
- if (!klass)
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
+
if (!ctor)
- ctor = mono_class_get_method_from_name (klass, ".ctor", 3);
-
+ ctor = mono_class_get_method_from_name (mono_defaults.customattribute_data_class, ".ctor", 3);
+
domain = mono_domain_get ();
if (len == 0) {
/* This is for Attributes with no parameters */
- attr = mono_object_new (domain, klass);
+ attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
params [0] = mono_method_get_object (domain, method, NULL);
params [1] = params [2] = NULL;
mono_runtime_invoke (method, attr, params, NULL);
}
g_free (name);
}
- attr = mono_object_new (domain, klass);
+ attr = mono_object_new (domain, mono_defaults.customattribute_data_class);
params [0] = mono_method_get_object (domain, method, NULL);
params [1] = typedargs;
params [2] = namedargs;
mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
{
MonoArray *result;
- MonoClass *klass;
MonoObject *attr;
int i;
- klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
- result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs);
+ result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, cinfo->num_attrs);
for (i = 0; i < cinfo->num_attrs; ++i) {
attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
mono_array_setref (result, i, attr);
{
MonoArray *result;
MonoObject *attr;
- MonoClass *klass;
int i, n;
n = 0;
n ++;
}
- klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
- result = mono_array_new (mono_domain_get (), klass, n);
+ result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, n);
n = 0;
for (i = 0; i < cinfo->num_attrs; ++i) {
if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->klass)) {
mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
{
MonoArray *result;
- static MonoClass *klass;
MonoObject *attr;
int i;
-
- if (!klass)
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
- result = mono_array_new (mono_domain_get (), klass, cinfo->num_attrs);
+ result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, cinfo->num_attrs);
for (i = 0; i < cinfo->num_attrs; ++i) {
attr = create_custom_attr_data (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
mono_array_setref (result, i, attr);
return result;
}
+/**
+ * mono_custom_attrs_from_index:
+ *
+ * Returns: NULL if no attributes are found or if a loading error occurs.
+ */
MonoCustomAttrInfo*
mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
{
break;
}
ainfo->attrs [i].ctor = mono_get_method (image, mtoken, NULL);
- if (!ainfo->attrs [i].ctor)
- g_error ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
+ if (!ainfo->attrs [i].ctor) {
+ g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
+ g_list_free (list);
+ g_free (ainfo);
+ return NULL;
+ }
data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
ainfo->attrs [i].data_size = mono_metadata_decode_value (data, &data);
ainfo->attrs [i].data = (guchar*)data;
{
MonoCustomAttrInfo *cinfo;
guint32 idx;
+
+ /*
+ * An instantiated method has the same cattrs as the generic method definition.
+ *
+ * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
+ * Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
+ */
+ if (method->is_inflated)
+ method = ((MonoMethodInflated *) method)->declaring;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, method)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (method)))
return cinfo;
idx = mono_method_get_index (method);
idx <<= MONO_CUSTOM_ATTR_BITS;
{
MonoCustomAttrInfo *cinfo;
guint32 idx;
+
+ if (klass->generic_class)
+ klass = klass->generic_class->container_class;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (klass)))
return cinfo;
idx = mono_metadata_token_index (klass->type_token);
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoCustomAttrInfo *cinfo;
guint32 idx;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, assembly)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (assembly)))
return cinfo;
idx = 1; /* there is only one assembly */
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoCustomAttrInfo *cinfo;
guint32 idx;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, image)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (image)))
return cinfo;
idx = 1; /* there is only one module */
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoCustomAttrInfo *cinfo;
guint32 idx;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, property)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (property)))
return cinfo;
idx = find_property_index (klass, property);
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoCustomAttrInfo *cinfo;
guint32 idx;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, event)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (event)))
return cinfo;
idx = find_event_index (klass, event);
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoCustomAttrInfo *cinfo;
guint32 idx;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
+ if (dynamic_custom_attrs && (cinfo = lookup_custom_attr (field)))
return cinfo;
idx = find_field_index (klass, field);
idx <<= MONO_CUSTOM_ATTR_BITS;
MonoImage *image;
MonoReflectionMethodAux *aux;
+ /*
+ * An instantiated method has the same cattrs as the generic method definition.
+ *
+ * LAMESPEC: The .NET SRE throws an exception for instantiations of generic method builders
+ * Note that this stanza is not necessary for non-SRE types, but it's a micro-optimization
+ */
+ if (method->is_inflated)
+ method = ((MonoMethodInflated *) method)->declaring;
+
if (method->klass->image->dynamic) {
+ MonoCustomAttrInfo *res, *ainfo;
+ int size;
+
aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
if (!aux || !aux->param_cattr)
return NULL;
- return aux->param_cattr [param];
+
+ /* Need to copy since it will be freed later */
+ ainfo = aux->param_cattr [param];
+ size = sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (ainfo->num_attrs - MONO_ZERO_LEN_ARRAY);
+ res = g_malloc0 (size);
+ memcpy (res, ainfo, size);
+ return res;
}
image = method->klass->image;
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
cinfo = mono_custom_attrs_from_method (rmethod->method);
} else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
- MonoMethod *method = mono_get_inflated_method (((MonoReflectionMethod*)obj)->method);
- cinfo = mono_custom_attrs_from_method (method);
+ MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
+ cinfo = mono_custom_attrs_from_method (rmethod->method);
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
} else if (strcmp ("FieldBuilder", klass->name) == 0) {
MonoReflectionFieldBuilder *fb = (MonoReflectionFieldBuilder*)obj;
cinfo = mono_custom_attrs_from_builders (&((MonoReflectionTypeBuilder*)fb->typeb)->module->dynamic_image->image, fb->cattrs);
+ } else if (strcmp ("MonoGenericClass", klass->name) == 0) {
+ MonoReflectionGenericClass *gclass = (MonoReflectionGenericClass*)obj;
+ cinfo = mono_reflection_get_custom_attrs_info ((MonoObject*)gclass->generic_type);
} else { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
*
* Return an array with all the custom attributes defined of the
* reflection handle @obj. If @attr_klass is non-NULL, only custom attributes
- * of that type are returned. The objects are fully build.
+ * of that type are returned. The objects are fully build. Return NULL if a loading error
+ * occurs.
*/
MonoArray*
mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
} else {
- MonoClass *klass;
- klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
- result = mono_array_new (mono_domain_get (), klass, 0);
+ if (mono_loader_get_last_error ())
+ return NULL;
+ result = mono_array_new (mono_domain_get (), mono_defaults.attribute_class, 0);
}
return result;
* @obj: a reflection object handle
*
* Return an array with all the custom attributes defined of the
- * reflection handle @obj. The objects are fully build.
+ * reflection handle @obj. The objects are fully build. Return NULL if a loading error
+ * occurs.
*/
MonoArray*
mono_reflection_get_custom_attrs (MonoObject *obj)
result = mono_custom_attrs_data_construct (cinfo);
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
- } else {
- MonoClass *klass;
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeData");
- result = mono_array_new (mono_domain_get (), klass, 0);
- }
+ } else
+ result = mono_array_new (mono_domain_get (), mono_defaults.customattribute_data_class, 0);
return result;
}
+static MonoReflectionType*
+mono_reflection_type_get_underlying_system_type (MonoReflectionType* t)
+{
+ MonoMethod *method_get_underlying_system_type;
+
+ method_get_underlying_system_type = mono_object_get_virtual_method ((MonoObject *) t,
+ mono_class_get_method_from_name (mono_object_class (t),
+ "get_UnderlyingSystemType",
+ 0));
+ return (MonoReflectionType *) mono_runtime_invoke (method_get_underlying_system_type, t, NULL, NULL);
+}
+
+static MonoType*
+mono_reflection_type_get_handle (MonoReflectionType* t)
+{
+ if (t->type)
+ return t->type;
+
+ t = mono_reflection_type_get_underlying_system_type (t);
+ if (t)
+ return t->type;
+
+ return NULL;
+}
+
/**
* LOCKING: Assumes the loader lock is held.
*/
sig->sentinelpos = -1; /* FIXME */
for (i = 0; i < count; ++i) {
MonoReflectionType *pt = mono_array_get (parameters, MonoReflectionType*, i);
- sig->params [i] = pt->type;
+ sig->params [i] = mono_reflection_type_get_handle (pt);
}
return sig;
}
swap_with_size (p, argval, 4, 1);
p += 4;
break;
+ case MONO_TYPE_R8:
+#if defined(ARM_FPU_FPA) && G_BYTE_ORDER == G_LITTLE_ENDIAN
+ p [0] = argval [4];
+ p [1] = argval [5];
+ p [2] = argval [6];
+ p [3] = argval [7];
+ p [4] = argval [0];
+ p [5] = argval [1];
+ p [6] = argval [2];
+ p [7] = argval [3];
+#else
+ swap_with_size (p, argval, 8, 1);
+#endif
+ p += 8;
+ break;
case MONO_TYPE_U8:
case MONO_TYPE_I8:
- case MONO_TYPE_R8:
swap_with_size (p, argval, 8, 1);
p += 8;
break;
}
k = mono_object_class (arg);
if (!mono_object_isinst (arg, mono_defaults.monotype_class) &&
- (strcmp (k->name, "TypeBuilder") || strcmp (k->name_space, "System.Reflection.Emit")))
- g_error ("Only System.Type allowed, not %s.%s", k->name_space, k->name);
+ (strcmp (k->name, "TypeBuilder") || strcmp (k->name_space, "System.Reflection.Emit"))) {
+ MonoReflectionType* rt = mono_reflection_type_get_underlying_system_type ((MonoReflectionType*) arg);
+ MonoClass *rtc;
+
+ if (rt && (rtc = mono_object_class (rt)) &&
+ (mono_object_isinst ((MonoObject *) rt, mono_defaults.monotype_class) ||
+ !strcmp (rtc->name, "TypeBuilder") || !strcmp (rtc->name_space, "System.Reflection.Emit"))) {
+ arg = (MonoObject *) rt;
+ k = rtc;
+ } else
+ g_error ("Only System.Type allowed, not %s.%s", k->name_space, k->name);
+ }
handle_type:
str = type_get_qualified_name (((MonoReflectionType*)arg)->type, NULL);
slen = strlen (str);
}
} else {
for (i = 0; i < len; ++i) {
- encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL);
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i), NULL);
}
}
break;
*p++ = 0x0E;
goto handle_enum;
} else if (klass->rank == 1) {
- simple_type = MONO_TYPE_SZARRAY;
*p++ = 0x1D;
- *p++ = klass->element_class->byval_arg.type;
- goto handle_enum;
+ if (klass->element_class->byval_arg.type == MONO_TYPE_OBJECT)
+ /* See Partition II, Appendix B3 */
+ *p++ = 0x51;
+ else
+ *p++ = klass->element_class->byval_arg.type;
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &klass->byval_arg, arg, NULL);
+ break;
} else if (klass->byval_arg.type >= MONO_TYPE_BOOLEAN && klass->byval_arg.type <= MONO_TYPE_R8) {
*p++ = simple_type = klass->byval_arg.type;
goto handle_enum;
klass->name_space = mono_string_to_utf8_mp (klass->image->mempool, tb->nspace);
klass->type_token = MONO_TOKEN_TYPE_DEF | tb->table_idx;
klass->flags = tb->attrs;
+
+ mono_profiler_class_event (klass, MONO_PROFILE_START_LOAD);
klass->element_class = klass;
/*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_loader_unlock ();
}
return;
tb->generic_container = g_new0 (MonoGenericContainer, 1);
- tb->generic_container->klass = klass;
+ tb->generic_container->owner.klass = klass;
}
/*
if (klass->generic_container || (count == 0))
return;
- g_assert (tb->generic_container && (tb->generic_container->klass == klass));
+ g_assert (tb->generic_container && (tb->generic_container->owner.klass == klass));
klass->generic_container = tb->generic_container;
fb = mono_array_get (tb->fields, MonoReflectionFieldBuilder*, 0);
+ if (!mono_type_is_valid_enum_basetype (fb->type->type)) {
+ mono_loader_unlock ();
+ return;
+ }
+
klass->enum_basetype = fb->type->type;
klass->element_class = my_mono_class_from_mono_type (klass->enum_basetype);
if (!klass->element_class)
gboolean dynamic;
int i;
- g_assert (!klass->generic_class);
-
/*
* Methods created using a MethodBuilder should have their memory allocated
* inside the image mempool, while dynamic methods should have their memory
dynamic = rmb->refs != NULL;
mp = dynamic ? NULL : klass->image->mempool;
+ if (!dynamic)
+ g_assert (!klass->generic_class);
+
mono_loader_lock ();
if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
pm = (MonoMethodNormal*)m;
+ m->dynamic = dynamic;
m->slot = -1;
m->flags = rmb->attrs;
m->iflags = rmb->iattrs;
- m->name = dynamic ? mono_string_to_utf8 (rmb->name) : mono_string_to_utf8_mp (mp, rmb->name);
+ m->name = mp_string_to_utf8 (mp, rmb->name);
m->klass = klass;
m->signature = sig;
m->skip_visibility = rmb->skip_visibility;
m->generic_container = container = rmb->generic_container;
container->type_argc = count;
container->type_params = g_new0 (MonoGenericParam, count);
+ container->owner.method = m;
for (i = 0; i < count; i++) {
MonoReflectionGenericParam *gp =
mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
container->type_params [i] = *gp->type.type->data.generic_param;
- container->type_params [i].method = m;
}
if (klass->generic_container) {
container->parent = klass->generic_container;
container->context.class_inst = klass->generic_container->context.class_inst;
}
- container->context.gmethod = mono_get_shared_generic_method (container);
+ container->context.method_inst = mono_get_shared_generic_inst (container);
}
if (rmb->refs) {
if ((i > 0) && (pb->attrs)) {
/* Make a copy since it might point to a shared type structure */
/* FIXME: Alloc this from a mempool */
- m->signature->params [i - 1] = g_memdup (m->signature->params [i - 1], sizeof (MonoType) + ((m->signature->params [i - 1]->num_mods - MONO_ZERO_LEN_ARRAY) * sizeof (MonoCustomMod)));
+ m->signature->params [i - 1] = mono_metadata_type_dup (NULL, m->signature->params [i - 1]);
m->signature->params [i - 1]->attrs = pb->attrs;
}
}
if (pb->name)
- method_aux->param_names [i] = dynamic ? mono_string_to_utf8 (pb->name) : mono_string_to_utf8_mp (mp, pb->name);
+ method_aux->param_names [i] = mp_string_to_utf8 (mp, pb->name);
if (pb->cattrs) {
if (!method_aux->param_cattr)
method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1);
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
- if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
+ /* If we are in a generic class, we might be called multiple times from inflate_method */
+ if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
/* ilgen is no longer needed */
mb->ilgen = NULL;
}
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
- if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save) {
+ /* If we are in a generic class, we might be called multiple times from inflate_method */
+ if (!((MonoDynamicImage*)(MonoDynamicImage*)klass->image)->save && !klass->generic_container) {
/* ilgen is no longer needed */
mb->ilgen = NULL;
}
{
MonoClass *klass;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericClass *gclass, *cached;
gboolean is_dynamic = FALSE;
MonoDomain *domain;
- MonoType *geninst;
- int i;
+ MonoClass *geninst;
mono_loader_lock ();
is_dynamic = TRUE;
} else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
- MonoReflectionType *rgt = rgi->generic_type;
-
- g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
- tb = (MonoReflectionTypeBuilder *) rgt;
+ tb = rgi->generic_type;
is_dynamic = TRUE;
}
is_dynamic = TRUE;
}
- if (is_dynamic) {
- MonoDynamicGenericClass *dgclass = g_new0 (MonoDynamicGenericClass, 1);
- MonoInflatedGenericClass *igclass = &dgclass->generic_class;
- gclass = &igclass->generic_class;
- gclass->is_dynamic = TRUE;
- gclass->is_inflated = TRUE;
- } else {
- MonoInflatedGenericClass *igclass = g_new0 (MonoInflatedGenericClass, 1);
- gclass = &igclass->generic_class;
- gclass->is_inflated = TRUE;
- }
-
- gclass->inst = g_new0 (MonoGenericInst, 1);
-
- gclass->inst->type_argc = type_argc;
- gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
- gclass->inst->is_reference = 1;
-
- for (i = 0; i < gclass->inst->type_argc; ++i) {
- MonoType *t = dup_type (types [i]);
-
- if (!gclass->inst->is_open)
- gclass->inst->is_open = mono_class_is_open_constructed_type (t);
- if (gclass->inst->is_reference)
- gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
- gclass->inst->type_argv [i] = t;
- }
-
- gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
- gclass->container_class = klass;
-
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
-
- cached = mono_metadata_lookup_generic_class (gclass);
- if (cached) {
- g_free (gclass);
- mono_loader_unlock ();
- geninst->data.generic_class = cached;
- return geninst;
- }
-
- geninst->data.generic_class = gclass;
-
mono_loader_unlock ();
- return geninst;
+ geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);
+
+ return &geninst->byval_arg;
}
-MonoType*
-mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types)
+MonoClass*
+mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
{
- MonoClass *klass;
- MonoGenericClass *gclass, *cached;
- MonoInflatedGenericClass *igclass;
- MonoType *geninst;
- int i;
-
- klass = mono_class_from_mono_type (type);
- if (!klass->generic_container && !klass->generic_class &&
- !(klass->nested_in && klass->nested_in->generic_container))
- return NULL;
-
- mono_loader_lock ();
-
- igclass = g_new0 (MonoInflatedGenericClass, 1);
- gclass = &igclass->generic_class;
- gclass->is_inflated = TRUE;
-
- gclass->inst = g_new0 (MonoGenericInst, 1);
- gclass->inst->type_argc = type_argc;
- gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
- gclass->inst->is_reference = 1;
-
- for (i = 0; i < gclass->inst->type_argc; ++i) {
- MonoType *t = dup_type (types [i]);
-
- if (!gclass->inst->is_open)
- gclass->inst->is_open = mono_class_is_open_constructed_type (t);
- if (gclass->inst->is_reference)
- gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
-
- gclass->inst->type_argv [i] = t;
- }
-
- gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
- gclass->container_class = klass;
-
- if (klass->generic_class) {
- MonoGenericClass *kgclass = klass->generic_class;
- MonoGenericClass *ogclass = gclass;
-
- igclass = g_new0 (MonoInflatedGenericClass, 1);
- gclass = &igclass->generic_class;
- gclass->is_inflated = TRUE;
-
- gclass->inst = g_new0 (MonoGenericInst, 1);
- gclass->inst->type_argc = kgclass->inst->type_argc;
- gclass->inst->type_argv = g_new0 (MonoType *, gclass->inst->type_argc);
- gclass->inst->is_reference = 1;
-
- for (i = 0; i < gclass->inst->type_argc; i++) {
- MonoType *t = kgclass->inst->type_argv [i];
-
- t = mono_class_inflate_generic_type (t, mono_generic_class_get_context (ogclass));
-
- if (!gclass->inst->is_open)
- gclass->inst->is_open = mono_class_is_open_constructed_type (t);
- if (gclass->inst->is_reference)
- gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (t);
-
- gclass->inst->type_argv [i] = t;
- }
-
- gclass->inst = mono_metadata_lookup_generic_inst (gclass->inst);
-
- gclass->container_class = kgclass->container_class;
- }
-
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
-
- cached = mono_metadata_lookup_generic_class (gclass);
- if (cached) {
- g_free (gclass);
- mono_loader_unlock ();
- geninst->data.generic_class = cached;
- return geninst;
- }
-
- geninst->data.generic_class = gclass;
+ MonoGenericClass *gclass;
+ MonoGenericInst *inst;
- mono_loader_unlock ();
+ g_assert (klass->generic_container);
- return geninst;
-}
+ inst = mono_metadata_get_generic_inst (type_argc, types);
+ gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
-static inline MonoType*
-dup_type (const MonoType *original)
-{
- MonoType *r = g_new0 (MonoType, 1);
- *r = *original;
- r->attrs = original->attrs;
- r->byref = original->byref;
- if (original->type == MONO_TYPE_PTR)
- r->data.type = dup_type (original->data.type);
- else if (original->type == MONO_TYPE_ARRAY)
- r->data.array = mono_dup_array_type (original->data.array);
- else if (original->type == MONO_TYPE_FNPTR)
- r->data.method = mono_metadata_signature_deep_dup (original->data.method);
- mono_stats.generics_metadata_size += sizeof (MonoType);
- return r;
+ return mono_generic_class_get_class (gclass);
}
MonoReflectionMethod*
mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, MonoArray *types)
{
+ MonoClass *klass;
MonoMethod *method, *inflated;
+ MonoMethodInflated *imethod;
MonoReflectionMethodBuilder *mb = NULL;
- MonoGenericContainer *container;
- MonoGenericMethod *gmethod;
- MonoGenericContext *context;
+ MonoGenericContext tmp_context;
MonoGenericInst *ginst;
+ MonoType **type_argv;
int count, i;
MONO_ARCH_SAVE_REGS;
method = rmethod->method;
}
- method = mono_get_inflated_method (method);
+ klass = method->klass;
+
+ if (method->is_inflated)
+ method = ((MonoMethodInflated *) method)->declaring;
count = mono_method_signature (method)->generic_param_count;
if (count != mono_array_length (types))
return NULL;
- container = method->generic_container;
- g_assert (container);
-
- if (!container->method_hash)
- container->method_hash = g_hash_table_new (
- (GHashFunc) mono_metadata_generic_method_hash,
- (GCompareFunc) mono_metadata_generic_method_equal);
-
- ginst = g_new0 (MonoGenericInst,1 );
- ginst->type_argc = count;
- ginst->type_argv = g_new0 (MonoType *, count);
- ginst->is_reference = 1;
+ type_argv = g_new0 (MonoType *, count);
for (i = 0; i < count; i++) {
MonoReflectionType *garg = mono_array_get (types, gpointer, i);
- ginst->type_argv [i] = dup_type (garg->type);
-
- if (!ginst->is_open)
- ginst->is_open = mono_class_is_open_constructed_type (ginst->type_argv [i]);
- if (ginst->is_reference)
- ginst->is_reference = MONO_TYPE_IS_REFERENCE (ginst->type_argv [i]);
+ type_argv [i] = garg->type;
}
- ginst = mono_metadata_lookup_generic_inst (ginst);
+ ginst = mono_metadata_get_generic_inst (count, type_argv);
+ g_free (type_argv);
- gmethod = g_new0 (MonoGenericMethod, 1);
- if (method->klass->generic_class)
- gmethod->class_inst = method->klass->generic_class->inst;
- gmethod->container = container;
- gmethod->inst = ginst;
+ tmp_context.class_inst = klass->generic_class ? klass->generic_class->context.class_inst : NULL;
+ tmp_context.method_inst = ginst;
- inflated = g_hash_table_lookup (container->method_hash, gmethod);
- if (inflated) {
- g_free (gmethod);
-
- return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
- }
-
- MOVING_GC_REGISTER (&gmethod->reflection_info);
- gmethod->reflection_info = rmethod;
-
- context = g_new0 (MonoGenericContext, 1);
- context->class_inst = gmethod->class_inst;
- context->gmethod = gmethod;
-
- if (method->is_inflated)
- method = ((MonoMethodInflated *) method)->declaring;
+ inflated = mono_class_inflate_generic_method (method, &tmp_context);
+ imethod = (MonoMethodInflated *) inflated;
- inflated = mono_class_inflate_generic_method (method, context);
- g_hash_table_insert (container->method_hash, gmethod, inflated);
+ MOVING_GC_REGISTER (&imethod->reflection_info);
+ imethod->reflection_info = rmethod;
return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
}
static MonoMethod *
inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
{
- MonoGenericMethod *gmethod = NULL;
+ MonoMethodInflated *imethod;
MonoGenericContext *context;
MonoClass *klass;
- int i, n;
klass = mono_class_from_mono_type (type->type.type);
g_assert (klass->generic_class);
context = mono_class_get_context (klass);
- n = mono_method_signature (method)->generic_param_count;
- if (n) {
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->class_inst = klass->generic_class->inst;
- gmethod->container = method->generic_container;
- MOVING_GC_REGISTER (&gmethod->reflection_info);
- gmethod->reflection_info = obj;
-
- gmethod->inst = g_new0 (MonoGenericInst, 1);
- gmethod->inst->type_argc = n;
- gmethod->inst->type_argv = g_new0 (MonoType *, n);
-
- for (i = 0; i < n; i++) {
- MonoGenericParam *gparam = &method->generic_container->type_params [i];
- g_assert (gparam->pklass);
- gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
- }
-
- g_assert (gmethod->container->parent == klass->generic_class->container_class->generic_container);
-
- context = g_new0 (MonoGenericContext, 1);
- context->class_inst = klass->generic_class->inst;
- context->gmethod = gmethod;
+ imethod = (MonoMethodInflated *) mono_class_inflate_generic_method_full (method, klass, context);
+ if (method->generic_container) {
+ MOVING_GC_REGISTER (&imethod->reflection_info);
+ imethod->reflection_info = obj;
}
-
- return mono_class_inflate_generic_method (method, context);
+ return (MonoMethod *) imethod;
}
static MonoMethod *
MonoMethod *method;
MonoClass *gklass;
- gklass = mono_class_from_mono_type (type->generic_type->type);
+ gklass = mono_class_from_mono_type (type->generic_type->type.type);
if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj);
MONO_ARCH_SAVE_REGS;
klass = mono_class_from_mono_type (type->type.type);
+ g_assert (type->type.type->type == MONO_TYPE_GENERICINST);
gclass = type->type.type->data.generic_class;
g_assert (gclass->is_dynamic);
}
}
+static gboolean
+remove_instantiations_of (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ MonoType *type = (MonoType*)key;
+ MonoClass *klass = (MonoClass*)user_data;
+
+ if ((type->type == MONO_TYPE_GENERICINST) && (type->data.generic_class->container_class == klass))
+ return TRUE;
+ else
+ return FALSE;
+}
+
MonoReflectionType*
mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
{
typebuilder_setup_properties (klass);
typebuilder_setup_events (klass);
-
+
klass->wastypebuilder = TRUE;
+
+ /*
+ * If we are a generic TypeBuilder, there might be instantiations in the type cache
+ * which have type System.Reflection.MonoGenericClass, but after the type is created,
+ * we want to return normal System.MonoType objects, so clear these out from the cache.
+ */
+ if (domain->type_hash && klass->generic_container)
+ mono_g_hash_table_foreach_remove (domain->type_hash, remove_instantiations_of, klass);
+
mono_loader_unlock ();
mono_domain_unlock (domain);
+ if (klass->enumtype && !mono_class_is_valid_enum (klass)) {
+ mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_raise_exception (mono_get_exception_type_load (tb->name, NULL));
+ }
+
res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
g_assert (res != (MonoReflectionType*)tb);
param = g_new0 (MonoGenericParam, 1);
if (gparam->mbuilder) {
- if (!gparam->mbuilder->generic_container)
+ if (!gparam->mbuilder->generic_container) {
gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
+ gparam->mbuilder->generic_container->is_method = TRUE;
+ }
param->owner = gparam->mbuilder->generic_container;
} else if (gparam->tbuilder) {
g_assert (gparam->tbuilder->generic_container);
param->owner = gparam->tbuilder->generic_container;
}
- param->method = NULL;
param->name = mono_string_to_utf8 (gparam->name);
param->num = gparam->index;
{
MonoDynamicImage *assembly = sig->module->dynamic_image;
guint32 na = mono_array_length (sig->arguments);
- guint32 buflen, i, size;
+ guint32 buflen, i;
MonoArray *result;
- char *buf, *p;
-
- MONO_ARCH_SAVE_REGS;
+ SigBuffer buf;
- p = buf = g_malloc (size = 50 + na * 50);
+ sigbuffer_init (&buf, 32);
- mono_metadata_encode_value (0x07, p, &p);
- mono_metadata_encode_value (na, p, &p);
+ sigbuffer_add_value (&buf, 0x07);
+ sigbuffer_add_value (&buf, na);
for (i = 0; i < na; ++i) {
MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
- encode_reflection_type (assembly, type, p, &p);
+ encode_reflection_type (assembly, type, &buf);
}
- buflen = p - buf;
- g_assert (buflen < size);
+ buflen = buf.p - buf.buf;
result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
- p = mono_array_addr (result, char, 0);
- memcpy (p, buf, buflen);
- g_free (buf);
+ memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
+ sigbuffer_free (&buf);
return result;
}
{
MonoDynamicImage *assembly = sig->module->dynamic_image;
guint32 na = mono_array_length (sig->arguments);
- guint32 buflen, i, size;
+ guint32 buflen, i;
MonoArray *result;
- char *buf, *p;
-
- MONO_ARCH_SAVE_REGS;
+ SigBuffer buf;
- p = buf = g_malloc (size = 10 + na * 10);
+ sigbuffer_init (&buf, 32);
- mono_metadata_encode_value (0x06, p, &p);
+ sigbuffer_add_value (&buf, 0x06);
for (i = 0; i < na; ++i) {
MonoReflectionType *type = mono_array_get (sig->arguments, MonoReflectionType *, i);
- encode_reflection_type (assembly, type, p, &p);
+ encode_reflection_type (assembly, type, &buf);
}
- buflen = p - buf;
- g_assert (buflen < size);
+ buflen = buf.p - buf.buf;
result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, buflen);
- p = mono_array_addr (result, char, 0);
- memcpy (p, buf, buflen);
- g_free (buf);
+ memcpy (mono_array_addr (result, char, 0), buf.buf, buflen);
+ sigbuffer_free (&buf);
return result;
}
{
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
+ MonoClass *klass;
+ GSList *l;
int i;
sig = dynamic_method_to_signature (mb);
rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
for (i = 0; i < mb->nrefs; i += 2) {
MonoClass *handle_class;
- gpointer ref = resolve_object (mb->module->image,
- mono_array_get (mb->refs, MonoObject*, i), &handle_class);
- if (!ref) {
- g_free (rmb.refs);
- mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
- return;
+ gpointer ref;
+ MonoObject *obj = mono_array_get (mb->refs, MonoObject*, i);
+
+ if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
+ MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
+ /*
+ * The referenced DynamicMethod should already be created by the managed
+ * code, except in the case of circular references. In that case, we store
+ * method in the refs array, and fix it up later when the referenced
+ * DynamicMethod is created.
+ */
+ if (method->mhandle) {
+ ref = method->mhandle;
+ } else {
+ /* FIXME: GC object stored in unmanaged memory */
+ ref = method;
+
+ /* FIXME: GC object stored in unmanaged memory */
+ method->referenced_by = g_slist_append (method->referenced_by, mb);
+ }
+ handle_class = mono_defaults.methodhandle_class;
+ } else {
+ ref = resolve_object (mb->module->image, obj, &handle_class, NULL);
+ if (!ref) {
+ g_free (rmb.refs);
+ mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+ return;
+ }
}
+
rmb.refs [i] = ref; /* FIXME: GC object stored in unmanaged memory (change also resolve_object() signature) */
rmb.refs [i + 1] = handle_class;
}
- /* FIXME: class */
- mb->mhandle = reflection_methodbuilder_to_mono_method (mono_defaults.object_class, &rmb, sig);
+ klass = mb->owner ? mono_class_from_mono_type (mb->owner->type) : mono_defaults.object_class;
+
+ mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
+
+ /* Fix up refs entries pointing at us */
+ for (l = mb->referenced_by; l; l = l->next) {
+ MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)l->data;
+ MonoMethodWrapper *wrapper = (MonoMethodWrapper*)method->mhandle;
+ gpointer *data;
+
+ g_assert (method->mhandle);
+
+ data = (gpointer*)wrapper->method_data;
+ for (i = 0; i < GPOINTER_TO_UINT (data [0]); i += 2) {
+ if ((data [i + 1] == mb) && (data [i + 1 + 1] == mono_defaults.methodhandle_class))
+ data [i + 1] = mb->mhandle;
+ }
+ }
+ g_slist_free (mb->referenced_by);
g_free (rmb.refs);
mb->ilgen = NULL;
}
+void
+mono_reflection_destroy_dynamic_method (MonoReflectionDynamicMethod *mb)
+{
+ g_assert (mb);
+
+ if (mb->mhandle)
+ mono_runtime_free_method (
+ mono_object_get_domain ((MonoObject*)mb), mb->mhandle);
+}
+
/**
* mono_reflection_lookup_dynamic_token:
*
* Finish the Builder object pointed to by TOKEN and return the corresponding
- * runtime structure. HANDLE_CLASS is set to the class required by
- * mono_ldtoken.
+ * runtime structure. If HANDLE_CLASS is not NULL, it is set to the class required by
+ * mono_ldtoken. If valid_token is TRUE, assert if it is not found in the token->object
+ * mapping table.
*/
gpointer
-mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, MonoClass **handle_class)
+mono_reflection_lookup_dynamic_token (MonoImage *image, guint32 token, gboolean valid_token, MonoClass **handle_class, MonoGenericContext *context)
{
MonoDynamicImage *assembly = (MonoDynamicImage*)image;
MonoObject *obj;
+ MonoClass *klass;
obj = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
- g_assert (obj);
+ if (!obj) {
+ if (valid_token)
+ g_assert_not_reached ();
+ else
+ return NULL;
+ }
- return resolve_object (image, obj, handle_class);
+ if (!handle_class)
+ handle_class = &klass;
+ return resolve_object (image, obj, handle_class, context);
}
static gpointer
-resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class)
+resolve_object (MonoImage *image, MonoObject *obj, MonoClass **handle_class, MonoGenericContext *context)
{
gpointer result = NULL;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
MonoReflectionType *tb = (MonoReflectionType*)obj;
- result = mono_class_from_mono_type (tb->type);
+ if (context) {
+ MonoType *inflated = mono_class_inflate_generic_type (tb->type, context);
+ result = mono_class_from_mono_type (inflated);
+ mono_metadata_free_type (inflated);
+ } else {
+ result = mono_class_from_mono_type (tb->type);
+ }
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
+ result = mono_class_inflate_generic_method (result, context);
*handle_class = mono_defaults.methodhandle_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MethodBuilder") == 0) {
*/
result = mb->mhandle;
}
+ result = mono_class_inflate_generic_method (result, context);
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorBuilder") == 0) {
MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
result = cb->mhandle;
}
+ result = mono_class_inflate_generic_method (result, context);
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "MonoField") == 0) {
result = ((MonoReflectionField*)obj)->field;
mono_domain_try_type_resolve (mono_domain_get (), NULL, (MonoObject*)tb);
result = fb->handle;
}
+
+ if (fb->handle && fb->handle->parent->generic_container) {
+ MonoClass *klass = fb->handle->parent;
+ MonoClass *inflated = mono_class_from_mono_type (mono_class_inflate_generic_type (&klass->byval_arg, context));
+
+ result = mono_class_get_field_from_name (inflated, fb->handle->name);
+ g_assert (result);
+ }
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)obj;
g_assert (method->mhandle);
result = method->mhandle;
*handle_class = mono_defaults.methodhandle_class;
+ } else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
+ MonoReflectionType *tb = (MonoReflectionType*)obj;
+ result = mono_class_from_mono_type (mono_class_inflate_generic_type (tb->type, context));
+ *handle_class = mono_defaults.typehandle_class;
+ g_assert (result);
+ } else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
+ MonoReflectionGenericClass *ref = (MonoReflectionGenericClass*)obj;
+ result = mono_class_from_mono_type (mono_class_inflate_generic_type (ref->type.type, context));
+ *handle_class = mono_defaults.typehandle_class;
+ g_assert (result);
} else {
g_print (obj->vtable->klass->name);
g_assert_not_reached ();
static guint32
mono_declsec_get_flags (MonoImage *image, guint32 token)
{
- guint32 index = mono_metadata_declsec_from_index (image, token);
+ int index = mono_metadata_declsec_from_index (image, token);
MonoTableInfo *t = &image->tables [MONO_TABLE_DECLSECURITY];
guint32 result = 0;
guint32 action;
int i;
+ /* HasSecurity can be present for other, not specially encoded, attributes,
+ e.g. SuppressUnmanagedCodeSecurityAttribute */
+ if (index < 0)
+ return 0;
+
for (i = index; i < t->rows; i++) {
guint32 cols [MONO_DECL_SECURITY_SIZE];