#include "mono/metadata/tabledefs.h"
#include "mono/metadata/metadata-internals.h"
#include "mono/metadata/class-internals.h"
+#include "mono/metadata/gc-internal.h"
#include "mono/metadata/tokentype.h"
#include "mono/metadata/domain-internals.h"
#include "mono/metadata/opcodes.h"
#include "mono/metadata/object-internals.h"
#include <mono/metadata/exception.h>
#include <mono/metadata/marshal.h>
+#include <mono/metadata/security-manager.h>
#include <stdio.h>
#include <glib.h>
#include <errno.h>
#include "mono-endian.h"
#include <mono/os/gc_wrapper.h>
+typedef struct {
+ char *p;
+ char *buf;
+ char *end;
+} SigBuffer;
+
#define TEXT_OFFSET 512
#define CLI_H_SIZE 136
#define FILE_ALIGN 512
MonoObject *type;
MonoString *name;
MonoBoolean init_locals;
+ MonoBoolean skip_visibility;
MonoArray *return_modreq;
MonoArray *return_modopt;
MonoArray *param_modreq;
guint32 nrefs;
gpointer *refs;
/* for PInvoke */
- int charset, lasterr, native_cc;
+ int charset, extra_flags, native_cc;
MonoString *dll, *dllentry;
} ReflectionMethodBuilder;
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 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:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+static gpointer
+mp_g_malloc (MonoMemPool *mp, guint size)
+{
+ if (mp)
+ return mono_mempool_alloc (mp, size);
+ else
+ return g_malloc (size);
+}
+
+/**
+ * mp_g_alloc0:
+ *
+ * Allocate memory from the mempool MP if it is non-NULL. Otherwise, allocate memory
+ * from the C heap.
+ */
+static gpointer
+mp_g_malloc0 (MonoMemPool *mp, guint size)
+{
+ if (mp)
+ return mono_mempool_alloc0 (mp, size);
+ else
+ 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))))
+#define mp_g_new0(mp,struct_type, n_structs) \
+ ((struct_type *) mp_g_malloc0 (mp, ((gsize) sizeof (struct_type)) * ((gsize) (n_structs))))
static void
alloc_table (MonoDynamicTable *table, guint nrows)
return idx;
}
+static guint32
+string_heap_insert_mstring (MonoDynamicStream *sh, MonoString *str)
+{
+ char *name = mono_string_to_utf8 (str);
+ guint32 idx;
+ idx = string_heap_insert (sh, name);
+ g_free (name);
+ return idx;
+}
+
static void
string_heap_init (MonoDynamicStream *sh)
{
guint32 idx;
char *copy;
gpointer oldkey, oldval;
-
+
copy = g_malloc (s1+s2);
memcpy (copy, b1, s1);
memcpy (copy + s1, b2, s2);
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;
- 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);
+ encode_type (assembly, &gclass->container_class->byval_arg, buf);
+ 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);
- mono_metadata_encode_value (type->type, p, &p);
+ /*
+ * 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.
*/
- mono_metadata_encode_value (mono_image_typedef_or_ref (assembly, &k->byval_arg), p, &p);
+ 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 = 21 + nparams * 20 + notypes * 20;
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 = 10 + nl * 10;
- 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;
for (i = mono_array_length (ilgen->ex_handlers) - 1; i >= 0; --i) {
ex_info = (MonoILExceptionInfo*)mono_array_addr (ilgen->ex_handlers, MonoILExceptionInfo, i);
finally_start = ex_info->start + ex_info->len;
- g_assert (ex_info->handlers);
+ if (!ex_info->handlers)
+ continue;
for (j = 0; j < mono_array_length (ex_info->handlers); ++j) {
ex_block = (MonoILExceptionBlock*)mono_array_addr (ex_info->handlers, MonoILExceptionBlock, j);
clause = &(clauses [clause_index]);
if (ex_block->extype) {
clause->data.catch_class = mono_class_from_mono_type (ex_block->extype->type);
} else {
- /* FIXME: handle filters */
- clause->data.filter_offset = 0;
+ if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+ clause->data.filter_offset = ex_block->filter_offset;
+ else
+ clause->data.filter_offset = 0;
}
finally_start = ex_block->start + ex_block->len;
gint maybe_small;
guint32 fat_flags;
char fat_header [12];
- guint32 *intp;
- guint16 *shortp;
+ guint32 int_value;
+ guint16 short_value;
guint32 local_sig = 0;
guint32 header_size = 12;
MonoArray *code;
fat_flags |= METHOD_HEADER_INIT_LOCALS;
fat_header [0] = fat_flags;
fat_header [1] = (header_size / 4 ) << 4;
- shortp = (guint16*)(fat_header + 2);
- *shortp = GUINT16_TO_LE (max_stack);
- intp = (guint32*)(fat_header + 4);
- *intp = GUINT32_TO_LE (code_size);
- intp = (guint32*)(fat_header + 8);
- *intp = GUINT32_TO_LE (local_sig);
+ short_value = GUINT16_TO_LE (max_stack);
+ memcpy (fat_header + 2, &short_value, 2);
+ int_value = GUINT32_TO_LE (code_size);
+ memcpy (fat_header + 4, &int_value, 4);
+ int_value = GUINT32_TO_LE (local_sig);
+ memcpy (fat_header + 8, &int_value, 4);
idx = mono_image_add_stream_data (&assembly->code, fat_header, 12);
/* add to the fixup todo list */
if (mb->ilgen && mb->ilgen->num_token_fixups)
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) {
if (ex_block->extype) {
val = mono_metadata_token_from_dor (mono_image_typedef_or_ref (assembly, ex_block->extype->type));
} else {
- /* FIXME: handle filters */
- val = 0;
+ if (ex_block->type == MONO_EXCEPTION_CLAUSE_FILTER)
+ val = ex_block->filter_offset;
+ else
+ val = 0;
}
val = GUINT32_TO_LE (val);
mono_image_add_stream_data (&assembly->code, (char*)&val, sizeof (guint32));
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)
+{
+ /* FIXME: Need to do more checks */
+ if (cattr->ctor->method && (cattr->ctor->method->klass->image != image)) {
+ int visibility = cattr->ctor->method->klass->flags & TYPE_ATTRIBUTE_VISIBILITY_MASK;
+
+ if ((visibility != TYPE_ATTRIBUTE_PUBLIC) && (visibility != TYPE_ATTRIBUTE_NESTED_PUBLIC))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static MonoCustomAttrInfo*
mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
{
- int i, count;
+ int i, index, count, not_visible;
MonoCustomAttrInfo *ainfo;
MonoReflectionCustomAttr *cattr;
count = mono_array_length (cattrs);
+ /* Skip nonpublic attributes since MS.NET seems to do the same */
+ /* FIXME: This needs to be done more globally */
+ not_visible = 0;
+ for (i = 0; i < count; ++i) {
+ cattr = (MonoReflectionCustomAttr*)mono_array_get (cattrs, gpointer, i);
+ if (!custom_attr_visible (image, cattr))
+ not_visible ++;
+ }
+ count -= not_visible;
+
ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
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);
- ainfo->attrs [i].ctor = cattr->ctor->method;
- /* FIXME: might want to memdup the data here */
- ainfo->attrs [i].data = mono_array_addr (cattr->data, char, 0);
- ainfo->attrs [i].data_size = mono_array_length (cattr->data);
+ 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;
+ 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
mono_custom_attrs_free (MonoCustomAttrInfo *ainfo)
{
- /* they are cached, so we don't free them */
- if (dynamic_custom_attrs && g_hash_table_lookup (dynamic_custom_attrs, ainfo))
- return;
- g_free (ainfo);
+ if (!ainfo->cached)
+ g_free (ainfo);
}
/*
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
guint i, count;
/* room in this table is already allocated */
*mb->table_idx = table->next_idx ++;
g_hash_table_insert (assembly->method_to_table_idx, mb->mhandle, GUINT_TO_POINTER ((*mb->table_idx)));
values = table->values + *mb->table_idx * MONO_METHOD_SIZE;
- name = mono_string_to_utf8 (mb->name);
- values [MONO_METHOD_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_METHOD_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name);
values [MONO_METHOD_FLAGS] = mb->attrs;
values [MONO_METHOD_IMPLFLAGS] = mb->iattrs;
values [MONO_METHOD_SIGNATURE] = method_builder_encode_signature (assembly, mb);
values [MONO_PARAM_FLAGS] = pb->attrs;
values [MONO_PARAM_SEQUENCE] = i;
if (pb->name != NULL) {
- name = mono_string_to_utf8 (pb->name);
- values [MONO_PARAM_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_PARAM_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name);
} else {
values [MONO_PARAM_NAME] = 0;
}
rmb->refs = NULL;
if (mb->dll) {
- rmb->charset = mb->charset & 0xf;
- rmb->lasterr = mb->charset & 0x40;
+ rmb->charset = mb->charset;
+ rmb->extra_flags = mb->extra_flags;
rmb->native_cc = mb->native_cc;
rmb->dllentry = mb->dllentry;
rmb->dll = mb->dll;
rmb->name = mb->name;
rmb->table_idx = NULL;
rmb->init_locals = mb->init_locals;
+ rmb->skip_visibility = mb->skip_visibility;
rmb->return_modreq = NULL;
rmb->return_modopt = NULL;
rmb->param_modreq = NULL;
rmb->refs = NULL;
}
+static void
+mono_image_add_methodimpl (MonoDynamicImage *assembly, MonoReflectionMethodBuilder *mb)
+{
+ MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
+ MonoDynamicTable *table;
+ guint32 *values;
+ guint32 tok;
+
+ if (!mb->override_method)
+ return;
+
+ table = &assembly->tables [MONO_TABLE_METHODIMPL];
+ table->rows ++;
+ alloc_table (table, table->rows);
+ values = table->values + table->rows * MONO_METHODIMPL_SIZE;
+ values [MONO_METHODIMPL_CLASS] = tb->table_idx;
+ values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
+
+ tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE);
+ switch (mono_metadata_token_table (tok)) {
+ case MONO_TABLE_MEMBERREF:
+ tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
+ break;
+ case MONO_TABLE_METHOD:
+ tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ values [MONO_METHODIMPL_DECLARATION] = tok;
+}
+
static void
mono_image_get_method_info (MonoReflectionMethodBuilder *mb, MonoDynamicImage *assembly)
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
ReflectionMethodBuilder rmb;
int i;
reflection_methodbuilder_from_method_builder (&rmb, mb);
mono_image_basic_method (&rmb, assembly);
+ mb->table_idx = *rmb.table_idx;
if (mb->dll) { /* It's a P/Invoke method */
guint32 moduleref;
- int charset = mb->charset & 0xf;
- int lasterr = mb->charset & 0x40;
- int best_fit_mapping = mb->charset & 0x30;
- int throw_on_unmappable = mb->charset & 0x3000;
+ /* map CharSet values to on-disk values */
+ int ncharset = (mb->charset ? (mb->charset - 1) * 2 : 0);
+ int extra_flags = mb->extra_flags;
table = &assembly->tables [MONO_TABLE_IMPLMAP];
table->rows ++;
alloc_table (table, table->rows);
values = table->values + table->rows * MONO_IMPLMAP_SIZE;
- /* map CharSet values to on-disk values */
- values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | (charset ? (charset - 1) * 2: 1) | lasterr | best_fit_mapping | throw_on_unmappable;
+ values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | ncharset | extra_flags;
values [MONO_IMPLMAP_MEMBER] = (mb->table_idx << 1) | 1; /* memberforwarded: method */
- name = mono_string_to_utf8 (mb->dllentry);
- values [MONO_IMPLMAP_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
- name = mono_string_to_utf8 (mb->dll);
- moduleref = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ if (mb->dllentry)
+ values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->dllentry);
+ else
+ values [MONO_IMPLMAP_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->name);
+ moduleref = string_heap_insert_mstring (&assembly->sheap, mb->dll);
if (!(values [MONO_IMPLMAP_SCOPE] = find_index_in_table (assembly, MONO_TABLE_MODULEREF, MONO_MODULEREF_NAME, moduleref))) {
table = &assembly->tables [MONO_TABLE_MODULEREF];
table->rows ++;
}
}
- if (mb->override_method) {
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)mb->type;
- guint32 tok;
- table = &assembly->tables [MONO_TABLE_METHODIMPL];
- table->rows ++;
- alloc_table (table, table->rows);
- values = table->values + table->rows * MONO_METHODIMPL_SIZE;
- values [MONO_METHODIMPL_CLASS] = tb->table_idx;
- values [MONO_METHODIMPL_BODY] = MONO_METHODDEFORREF_METHODDEF | (mb->table_idx << MONO_METHODDEFORREF_BITS);
-
- tok = mono_image_create_token (assembly, (MonoObject*)mb->override_method, FALSE);
- switch (mono_metadata_token_table (tok)) {
- case MONO_TABLE_MEMBERREF:
- tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODREF;
- break;
- case MONO_TABLE_METHOD:
- tok = (mono_metadata_token_index (tok) << MONO_METHODDEFORREF_BITS ) | MONO_METHODDEFORREF_METHODDEF;
- break;
- default:
- g_assert_not_reached ();
- }
- values [MONO_METHODIMPL_DECLARATION] = tok;
- }
-
if (mb->generic_params) {
table = &assembly->tables [MONO_TABLE_GENERICPARAM];
table->rows += mono_array_length (mb->generic_params);
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
mono_image_basic_method (&rmb, assembly);
+ mb->table_idx = *rmb.table_idx;
}
static char*
-type_get_fully_qualified_name (MonoType *type) {
- char *name, *result;
- MonoClass *klass;
- MonoAssembly *ta;
-
- name = mono_type_get_name (type);
- klass = my_mono_class_from_mono_type (type);
- ta = klass->image->assembly;
-
- result = g_strdup_printf ("%s, %s, Version=%d.%d.%d.%d, Culture=%s, PublicKeyToken=%s",
- name, ta->aname.name,
- ta->aname.major, ta->aname.minor, ta->aname.build, ta->aname.revision,
- ta->aname.culture && *ta->aname.culture? ta->aname.culture: "neutral",
- ta->aname.public_key_token [0] ? (char *)ta->aname.public_key_token : "null");
- g_free (name);
- return result;
+type_get_fully_qualified_name (MonoType *type)
+{
+ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_ASSEMBLY_QUALIFIED);
}
static char*
klass = my_mono_class_from_mono_type (type);
if (!klass)
- return mono_type_get_name (type);
+ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
ta = klass->image->assembly;
- if (ta == ass || klass->image == mono_defaults.corlib)
- return mono_type_get_name (type);
+ if (ta->dynamic || (ta == ass))
+ return mono_type_get_name_full (type, MONO_TYPE_NAME_FORMAT_REFLECTION);
- return type_get_fully_qualified_name (type);
+ 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 (64);
+ 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 < 64);
- 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 (64);
-
- 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 < 64);
- 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;
}
char *p, *box_val;
char* buf;
guint32 idx = 0, len = 0, dummy = 0;
+#ifdef ARM_FPU_FPA
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ guint32 fpa_double [2];
+ guint32 *fpa_p;
+#endif
+#endif
p = buf = g_malloc (64);
if (!val) {
break;
case MONO_TYPE_U8:
case MONO_TYPE_I8:
+ len = 8;
+ break;
case MONO_TYPE_R8:
len = 8;
+#ifdef ARM_FPU_FPA
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ fpa_p = (guint32*)box_val;
+ fpa_double [0] = fpa_p [1];
+ fpa_double [1] = fpa_p [0];
+ box_val = (char*)fpa_double;
+#endif
+#endif
break;
case MONO_TYPE_VALUETYPE:
if (val->vtable->klass->enumtype) {
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;
- g_free (str);
- } else {
- mono_metadata_encode_value (0, p, &p);
- }
- if (minfo->marshaltype) {
- 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 {
- mono_metadata_encode_value (0, p, &p);
- }
- if (minfo->marshaltyperef) {
- str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
+ sigbuffer_add_value (&buf, 0);
+ }
+ /* native type name */
+ sigbuffer_add_value (&buf, 0);
+ /* custom marshaler type name */
+ if (minfo->marshaltype || minfo->marshaltyperef) {
+ if (minfo->marshaltyperef)
+ str = type_get_fully_qualified_name (minfo->marshaltyperef->type);
+ 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 {
- mono_metadata_encode_value (0, p, &p);
+ /* FIXME: Actually a bug, since this field is required. Punting for now ... */
+ 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;
}
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
/* maybe this fixup should be done in the C# code */
if (fb->attrs & FIELD_ATTRIBUTE_LITERAL)
fb->table_idx = table->next_idx ++;
g_hash_table_insert (assembly->field_to_table_idx, fb->handle, GUINT_TO_POINTER (fb->table_idx));
values = table->values + fb->table_idx * MONO_FIELD_SIZE;
- name = mono_string_to_utf8 (fb->name);
- values [MONO_FIELD_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_FIELD_NAME] = string_heap_insert_mstring (&assembly->sheap, fb->name);
values [MONO_FIELD_FLAGS] = fb->attrs;
values [MONO_FIELD_SIGNATURE] = field_encode_signature (assembly, fb);
/*
* 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) {
+ } 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;
}
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
guint num_methods = 0;
guint32 semaidx;
table = &assembly->tables [MONO_TABLE_PROPERTY];
pb->table_idx = table->next_idx ++;
values = table->values + pb->table_idx * MONO_PROPERTY_SIZE;
- name = mono_string_to_utf8 (pb->name);
- values [MONO_PROPERTY_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_PROPERTY_NAME] = string_heap_insert_mstring (&assembly->sheap, pb->name);
values [MONO_PROPERTY_FLAGS] = pb->attrs;
values [MONO_PROPERTY_TYPE] = property_encode_signature (assembly, pb);
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
guint num_methods = 0;
guint32 semaidx;
table = &assembly->tables [MONO_TABLE_EVENT];
eb->table_idx = table->next_idx ++;
values = table->values + eb->table_idx * MONO_EVENT_SIZE;
- name = mono_string_to_utf8 (eb->name);
- values [MONO_EVENT_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_EVENT_NAME] = string_heap_insert_mstring (&assembly->sheap, eb->name);
values [MONO_EVENT_FLAGS] = eb->attrs;
values [MONO_EVENT_TYPE] = mono_image_typedef_or_ref (assembly, eb->type->type);
}
}
-static void
-encode_new_constraint (MonoDynamicImage *assembly, guint32 owner)
-{
- static MonoClass *NewConstraintAttr;
- static MonoMethod *NewConstraintAttr_ctor;
- MonoDynamicTable *table;
- guint32 *values;
- guint32 token, type;
- char blob_size [4] = { 0x01, 0x00, 0x00, 0x00 };
- char *buf, *p;
-
- if (!NewConstraintAttr)
- NewConstraintAttr = mono_class_from_name ( mono_defaults.corlib,
- "System.Runtime.CompilerServices", "NewConstraintAttribute");
- g_assert (NewConstraintAttr);
-
- if (!NewConstraintAttr_ctor) {
- NewConstraintAttr_ctor = mono_class_get_method_from_name (NewConstraintAttr, ".ctor", -1);
- g_assert (NewConstraintAttr_ctor);
- }
-
- table = &assembly->tables [MONO_TABLE_CUSTOMATTRIBUTE];
- table->rows += 1;
- alloc_table (table, table->rows);
-
- values = table->values + table->next_idx * MONO_CUSTOM_ATTR_SIZE;
- owner <<= MONO_CUSTOM_ATTR_BITS;
- owner |= MONO_CUSTOM_ATTR_GENERICPAR;
- values [MONO_CUSTOM_ATTR_PARENT] = owner;
-
- token = mono_image_get_methodref_token (assembly, NewConstraintAttr_ctor);
-
- type = mono_metadata_token_index (token);
- type <<= MONO_CUSTOM_ATTR_TYPE_BITS;
- switch (mono_metadata_token_table (token)) {
- case MONO_TABLE_METHOD:
- type |= MONO_CUSTOM_ATTR_TYPE_METHODDEF;
- break;
- case MONO_TABLE_MEMBERREF:
- type |= MONO_CUSTOM_ATTR_TYPE_MEMBERREF;
- break;
- default:
- g_warning ("got wrong token in custom attr");
- return;
- }
- values [MONO_CUSTOM_ATTR_TYPE] = type;
-
- buf = p = g_malloc (1);
- mono_metadata_encode_value (4, p, &p);
- g_assert (p-buf == 1);
-
- values [MONO_CUSTOM_ATTR_VALUE] = add_to_blob_cached (assembly, buf, 1, blob_size, 4);
-
- values += MONO_CUSTOM_ATTR_SIZE;
- ++table->next_idx;
-}
-
static void
encode_constraints (MonoReflectionGenericParam *gparam, guint32 owner, MonoDynamicImage *assembly)
{
values [MONO_GENPARCONSTRAINT_CONSTRAINT] = mono_image_typedef_or_ref (
assembly, constraint->type);
}
-
- if (gparam->attrs & GENERIC_PARAMETER_ATTRIBUTE_CONSTRUCTOR_CONSTRAINT)
- encode_new_constraint (assembly, owner);
}
static void
entry = g_new0 (GenericParamTableEntry, 1);
entry->owner = owner;
- entry->gparam = gparam;
+#ifdef HAVE_SGEN_GC
+ /* FIXME: track where gen_params should be freed and remove the GC root as well */
+ MONO_GC_REGISTER_ROOT (entry->gparam);
+#endif
+ entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */
g_ptr_array_add (assembly->gen_params, entry);
}
values [MONO_GENERICPARAM_FLAGS] = entry->gparam->attrs;
values [MONO_GENERICPARAM_NUMBER] = param->num;
values [MONO_GENERICPARAM_NAME] = string_heap_insert (&assembly->sheap, param->name);
- values [MONO_GENERICPARAM_KIND] = 0;
+
+ mono_image_add_cattrs (assembly, table_idx, MONO_CUSTOM_ATTR_GENERICPAR, entry->gparam->cattrs);
encode_constraints (entry->gparam, table_idx, assembly);
}
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;
+ 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_class) {
+ sigbuffer_free (&buf);
return 0;
- encode_generic_class (assembly, k->generic_class, p, &p);
+ }
+ encode_generic_class (assembly, k->generic_class, &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));
return token;
g_assert (f->field->parent);
type = f->field->generic_info ? f->field->generic_info->generic_type : f->field->type;
- token = mono_image_get_memberref_token (assembly, &f->klass->byval_arg,
+ token = mono_image_get_memberref_token (assembly, &f->field->parent->byval_arg,
f->field->name, fieldref_encode_signature (assembly, type));
g_hash_table_insert (assembly->handleref, f, GUINT_TO_POINTER(token));
return token;
}
static guint32
-encode_generic_method_sig (MonoDynamicImage *assembly, 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 * 10;
+ 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);
+ g_assert (!method->klass->generic_container);
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);
}
static guint32
-mono_image_get_methodspec_token (MonoDynamicImage *assembly, MonoMethod *m)
+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, m));
+ token = GPOINTER_TO_UINT (g_hash_table_lookup (assembly->handleref, method));
if (token)
return token;
- g_assert (m->is_inflated);
- m = mono_get_inflated_method (m);
- imethod = (MonoMethodInflated *) m;
+ g_assert (method->is_inflated);
+ inflated = mono_get_inflated_method (method);
+ imethod = (MonoMethodInflated *) inflated;
if (mono_method_signature (imethod->declaring)->generic_param_count) {
- token = method_encode_methodspec (assembly, m);
+ token = method_encode_methodspec (assembly, inflated);
} else {
guint32 sig = method_encode_signature (
assembly, mono_method_signature (imethod->declaring));
token = mono_image_get_memberref_token (
- assembly, &m->klass->byval_arg, m->name, sig);
+ assembly, &inflated->klass->byval_arg, inflated->name, sig);
}
- g_hash_table_insert (assembly->handleref, m, GUINT_TO_POINTER(token));
+ g_hash_table_insert (assembly->handleref, method, GUINT_TO_POINTER(token));
return 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);
+ sigbuffer_add_value (&buf, MONO_TYPE_GENERICINST);
+ encode_type (assembly, &klass->byval_arg, &buf);
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];
+
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->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;
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);
+ 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;
}
{
int i;
- g_ptr_array_add (types, type);
+ g_ptr_array_add (types, type); /* FIXME: GC object added to unmanaged memory */
if (!type->subtypes)
return;
}
static void
-module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *mb) {
+module_add_cattrs (MonoDynamicImage *assembly, MonoReflectionModuleBuilder *moduleb)
+{
int i;
- mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_MODULE, mb->cattrs);
-
- /* no types in the module */
- if (!mb->types)
- return;
+ mono_image_add_cattrs (assembly, moduleb->table_idx, MONO_CUSTOM_ATTR_MODULE, moduleb->cattrs);
+
+ if (moduleb->global_methods) {
+ for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+ MonoReflectionMethodBuilder* mb = mono_array_get (moduleb->global_methods, MonoReflectionMethodBuilder*, i);
+ mono_image_add_cattrs (assembly, mb->table_idx, MONO_CUSTOM_ATTR_METHODDEF, mb->cattrs);
+ params_add_cattrs (assembly, mb->pinfo);
+ }
+ }
+
+ if (moduleb->global_fields) {
+ for (i = 0; i < mono_array_length (moduleb->global_fields); ++i) {
+ MonoReflectionFieldBuilder *fb = mono_array_get (moduleb->global_fields, MonoReflectionFieldBuilder*, i);
+ mono_image_add_cattrs (assembly, fb->table_idx, MONO_CUSTOM_ATTR_FIELDDEF, fb->cattrs);
+ }
+ }
- for (i = 0; i < mb->num_types; ++i)
- type_add_cattrs (assembly, mono_array_get (mb->types, MonoReflectionTypeBuilder*, i));
+ if (moduleb->types) {
+ for (i = 0; i < moduleb->num_types; ++i)
+ type_add_cattrs (assembly, mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i));
+ }
}
static void
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 ++;
}
{
MonoDynamicTable *table;
int i;
- char *name;
table = &assembly->tables [MONO_TABLE_MODULE];
mb->table_idx = table->next_idx ++;
- name = mono_string_to_utf8 (mb->module.name);
- table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_NAME] = string_heap_insert_mstring (&assembly->sheap, mb->module.name);
i = mono_image_add_stream_data (&assembly->guid, mono_array_addr (mb->guid, char, 0), 16);
i /= 16;
++i;
+ table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_GENERATION] = 0;
table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_MVID] = i;
table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENC] = 0;
table->values [mb->table_idx * MONO_MODULE_SIZE + MONO_MODULE_ENCBASE] = 0;
}
}
+static void
+mono_image_fill_export_table_from_type_forwarders (MonoReflectionAssemblyBuilder *assemblyb, MonoDynamicImage *assembly)
+{
+ MonoDynamicTable *table;
+ MonoClass *klass;
+ guint32 *values;
+ guint32 scope, idx;
+ int i;
+
+ table = &assembly->tables [MONO_TABLE_EXPORTEDTYPE];
+
+ if (assemblyb->type_forwarders) {
+ for (i = 0; i < mono_array_length (assemblyb->type_forwarders); ++i) {
+ MonoReflectionType *t = mono_array_get (assemblyb->type_forwarders, MonoReflectionType*, i);
+ if (!t)
+ continue;
+
+ g_assert (t->type);
+
+ klass = mono_class_from_mono_type (t->type);
+
+ scope = resolution_scope_from_image (assembly, klass->image);
+ g_assert ((scope & MONO_RESOLTION_SCOPE_MASK) == MONO_RESOLTION_SCOPE_ASSEMBLYREF);
+ idx = scope >> MONO_RESOLTION_SCOPE_BITS;
+
+ table->rows++;
+ alloc_table (table, table->rows);
+ values = table->values + table->next_idx * MONO_EXP_TYPE_SIZE;
+
+ values [MONO_EXP_TYPE_FLAGS] = TYPE_ATTRIBUTE_FORWARDER;
+ values [MONO_EXP_TYPE_TYPEDEF] = 0;
+ values [MONO_EXP_TYPE_IMPLEMENTATION] = (idx << MONO_IMPLEMENTATION_BITS) + MONO_IMPLEMENTATION_ASSEMBLYREF;
+ values [MONO_EXP_TYPE_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+ values [MONO_EXP_TYPE_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+ }
+ }
+}
+
#define align_pointer(base,p)\
do {\
guint32 __diff = (unsigned char*)(p)-(unsigned char*)(base);\
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 */
int16val = (guint16*)p;
- *int16val++ = GUINT16_TO_LE (1);
- *int16val = GUINT16_TO_LE (1);
+ *int16val++ = GUINT16_TO_LE (meta->md_version_major);
+ *int16val = GUINT16_TO_LE (meta->md_version_minor);
p += 8;
/* version string */
int32val = (guint32*)p;
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;
if ((assembly->tables [MONO_TABLE_GENERICPARAM].rows > 0) ||
- (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
- (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
- *p++ = 1; /* version */
- *p++ = 1;
+ (assembly->tables [MONO_TABLE_METHODSPEC].rows > 0) ||
+ (assembly->tables [MONO_TABLE_GENERICPARAMCONSTRAINT].rows > 0)) {
+ *p++ = 2; /* version */
+ *p++ = 0;
} else {
*p++ = 1; /* version */
*p++ = 0;
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")) {
}
}
-/*
- * fixup_methodimpl:
- *
- * The METHODIMPL table might contain METHODDEF tokens whose final
- * value is not known when the table is emitted.
- */
-static void
-fixup_methodimpl (MonoDynamicImage *assembly)
-{
- MonoDynamicTable *table;
- guint32 *values;
- guint32 decl, i, idx, token;
- MonoObject *method;
-
- table = &assembly->tables [MONO_TABLE_METHODIMPL];
-
- for (i = 0; i < table->rows; ++i) {
- values = table->values + ((i + 1) * MONO_METHODIMPL_SIZE);
- decl = values [MONO_METHODIMPL_DECLARATION];
-
- idx = decl >> MONO_METHODDEFORREF_BITS;
- if ((decl & MONO_METHODDEFORREF_MASK) != MONO_METHODDEFORREF_METHODDEF)
- continue;
-
- token = mono_metadata_make_token (MONO_TABLE_METHOD, idx);
- method = mono_g_hash_table_lookup (assembly->tokens, GUINT_TO_POINTER (token));
- g_assert (method);
-
- if (!strcmp (method->vtable->klass->name, "MethodBuilder")) {
- token = mono_image_create_token (assembly, method, FALSE);
- idx = mono_metadata_token_index (token);
- values [MONO_METHODIMPL_DECLARATION] = (idx << MONO_METHODDEFORREF_BITS) | MONO_METHODDEFORREF_METHODDEF;
- }
- }
-}
-
static void
assembly_add_resource_manifest (MonoReflectionModuleBuilder *mb, MonoDynamicImage *assembly, MonoReflectionResource *rsrc, guint32 implementation)
{
MonoDynamicTable *table;
guint32 *values;
- char *name;
table = &assembly->tables [MONO_TABLE_MANIFESTRESOURCE];
table->rows++;
values = table->values + table->next_idx * MONO_MANIFEST_SIZE;
values [MONO_MANIFEST_OFFSET] = rsrc->offset;
values [MONO_MANIFEST_FLAGS] = rsrc->attrs;
- name = mono_string_to_utf8 (rsrc->name);
- values [MONO_MANIFEST_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_MANIFEST_NAME] = string_heap_insert_mstring (&assembly->sheap, rsrc->name);
values [MONO_MANIFEST_IMPLEMENTATION] = implementation;
table->next_idx++;
}
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;
idx = MONO_IMPLEMENTATION_FILE | (idx << MONO_IMPLEMENTATION_BITS);
} else {
char sizebuf [4];
- offset = mono_array_length (rsrc->data);
+ char *data;
+ guint len;
+ if (rsrc->data) {
+ data = mono_array_addr (rsrc->data, char, 0);
+ len = mono_array_length (rsrc->data);
+ } else {
+ data = NULL;
+ len = 0;
+ }
+ offset = len;
sizebuf [0] = offset; sizebuf [1] = offset >> 8;
sizebuf [2] = offset >> 16; sizebuf [3] = offset >> 24;
rsrc->offset = mono_image_add_stream_data (&assembly->resources, sizebuf, 4);
- mono_image_add_stream_data (&assembly->resources, mono_array_addr (rsrc->data, char, 0), mono_array_length (rsrc->data));
+ mono_image_add_stream_data (&assembly->resources, data, len);
if (!mb->is_main)
/*
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);
-
- /* need to get the actual value from the key type... */
- assembly->strong_name_size = 128;
+ mono_image_add_stream_data (&assembly->blob, mono_array_addr (pkey, char, 0), len);
+
+ /* Special case: check for ECMA key (16 bytes) */
+ 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) {
+ /* minimum key size (in 2.0) is 384 bits */
+ assembly->strong_name_size = len - MONO_PUBLIC_KEY_HEADER_LENGTH;
+ } else {
+ /* FIXME - verifier */
+ g_warning ("Invalid public key length: %d bits (total: %d)", (int)MONO_PUBLIC_KEY_BIT_SIZE (len), (int)len);
+ assembly->strong_name_size = MONO_DEFAULT_PUBLIC_KEY_LENGTH; /* to be safe */
+ }
assembly->strong_name = g_malloc0 (assembly->strong_name_size);
return token;
MonoReflectionAssemblyBuilder *assemblyb;
MonoDomain *domain;
guint32 *values;
- char *name;
int i;
guint32 module_index;
alloc_table (table, 1);
values = table->values + MONO_ASSEMBLY_SIZE;
values [MONO_ASSEMBLY_HASH_ALG] = assemblyb->algid? assemblyb->algid: ASSEMBLY_HASH_SHA1;
- name = mono_string_to_utf8 (assemblyb->name);
- values [MONO_ASSEMBLY_NAME] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_ASSEMBLY_NAME] = string_heap_insert_mstring (&assembly->sheap, assemblyb->name);
if (assemblyb->culture) {
- name = mono_string_to_utf8 (assemblyb->culture);
- values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, name);
- g_free (name);
+ values [MONO_ASSEMBLY_CULTURE] = string_heap_insert_mstring (&assembly->sheap, assemblyb->culture);
} else {
values [MONO_ASSEMBLY_CULTURE] = string_heap_insert (&assembly->sheap, "");
}
mono_image_fill_export_table_from_module (domain, file_module, module_index, assembly);
}
}
+ if (assemblyb->type_forwarders)
+ mono_image_fill_export_table_from_type_forwarders (assemblyb, assembly);
/* Emit MANIFESTRESOURCE table */
module_index = 0;
MonoDynamicImage *assembly;
MonoReflectionAssemblyBuilder *assemblyb;
MonoDomain *domain;
+ GPtrArray *types;
guint32 *values;
- int i;
+ int i, j;
assemblyb = moduleb->assemblyb;
assembly = moduleb->dynamic_image;
alloc_table (table, 1);
mono_image_fill_module_table (domain, moduleb, assembly);
- /* Emit types */
- {
- /* Collect all types into a list sorted by their table_idx */
- GPtrArray *types = g_ptr_array_new ();
+ /* Collect all types into a list sorted by their table_idx */
+ types = g_ptr_array_new ();
- if (moduleb->types)
- for (i = 0; i < moduleb->num_types; ++i) {
- MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
- collect_types (types, type);
- }
+ if (moduleb->types)
+ for (i = 0; i < moduleb->num_types; ++i) {
+ MonoReflectionTypeBuilder *type = mono_array_get (moduleb->types, MonoReflectionTypeBuilder*, i);
+ collect_types (types, type);
+ }
- g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx);
- table = &assembly->tables [MONO_TABLE_TYPEDEF];
- table->rows += types->len;
- alloc_table (table, table->rows);
+ g_ptr_array_sort (types, (GCompareFunc)compare_types_by_table_idx);
+ table = &assembly->tables [MONO_TABLE_TYPEDEF];
+ table->rows += types->len;
+ alloc_table (table, table->rows);
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
- mono_image_get_type_info (domain, type, assembly);
- }
- g_ptr_array_free (types, TRUE);
+ /*
+ * Emit type names + namespaces at one place inside the string heap,
+ * so load_class_names () needs to touch fewer pages.
+ */
+ for (i = 0; i < types->len; ++i) {
+ MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+ string_heap_insert_mstring (&assembly->sheap, tb->nspace);
+ }
+ for (i = 0; i < types->len; ++i) {
+ MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+ string_heap_insert_mstring (&assembly->sheap, tb->name);
+ }
+
+ for (i = 0; i < types->len; ++i) {
+ MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+ mono_image_get_type_info (domain, type, assembly);
}
/*
/* fixup tokens */
mono_g_hash_table_foreach (assembly->token_fixups, (GHFunc)fixup_method, assembly);
+
+ /* Create the MethodImpl table. We do this after emitting all methods so we already know
+ * the final tokens and don't need another fixup pass. */
+
+ if (moduleb->global_methods) {
+ for (i = 0; i < mono_array_length (moduleb->global_methods); ++i) {
+ MonoReflectionMethodBuilder *mb = mono_array_get (
+ moduleb->global_methods, MonoReflectionMethodBuilder*, i);
+ mono_image_add_methodimpl (assembly, mb);
+ }
+ }
+
+ for (i = 0; i < types->len; ++i) {
+ MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
+ if (type->methods) {
+ for (j = 0; j < type->num_methods; ++j) {
+ MonoReflectionMethodBuilder *mb = mono_array_get (
+ type->methods, MonoReflectionMethodBuilder*, j);
+
+ mono_image_add_methodimpl (assembly, mb);
+ }
+ }
+ }
+
+ g_ptr_array_free (types, TRUE);
+
fixup_cattrs (assembly);
- fixup_methodimpl (assembly);
}
/*
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
} else if (strcmp (klass->name, "MonoField") == 0) {
MonoReflectionField *f = (MonoReflectionField *)obj;
- if ((f->klass->image == &assembly->image) && !f->field->generic_info) {
+ if ((f->field->parent->image == &assembly->image) && !f->field->generic_info) {
static guint32 field_table_idx = 0xffffff;
field_table_idx --;
token = MONO_TOKEN_FIELD_DEF | field_table_idx;
} else if (strcmp (klass->name, "SignatureHelper") == 0) {
MonoReflectionSigHelper *s = (MonoReflectionSigHelper*)obj;
token = MONO_TOKEN_SIGNATURE | mono_image_get_sighelper_token (assembly, s);
+ } else if (strcmp (klass->name, "EnumBuilder") == 0) {
+ MonoReflectionType *tb = (MonoReflectionType *)obj;
+ token = mono_metadata_token_from_dor (
+ mono_image_typedef_or_ref (assembly, tb->type));
} else {
g_error ("requested token for %s\n", klass->name);
}
guint32 flags;
} MonoILT;
-static void register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
+static gpointer register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly);
static MonoDynamicImage*
create_dynamic_mono_image (MonoDynamicAssembly *assembly, char *assembly_name, char *module_name)
image->image.name = assembly_name;
image->image.assembly_name = image->image.name; /* they may be different */
image->image.module_name = module_name;
- image->image.version = version;
+ image->image.version = g_strdup (version);
+ image->image.md_version_major = 1;
+ image->image.md_version_minor = 1;
image->image.dynamic = TRUE;
- image->image.ref_count = 1;
image->image.references = g_new0 (MonoAssembly*, 1);
image->image.references [0] = NULL;
mono_image_init (&image->image);
- image->token_fixups = mono_g_hash_table_new (NULL, NULL);
+ image->token_fixups = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_GC);
image->method_to_table_idx = g_hash_table_new (NULL, NULL);
image->field_to_table_idx = g_hash_table_new (NULL, NULL);
image->method_aux_hash = g_hash_table_new (NULL, NULL);
image->handleref = g_hash_table_new (NULL, NULL);
- image->tokens = mono_g_hash_table_new (NULL, NULL);
+ image->tokens = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC);
image->typespec = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
image->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
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 */
else
assembly->assembly.aname.culture = g_strdup ("");
+ if (assemblyb->version) {
+ char *vstr = mono_string_to_utf8 (assemblyb->version);
+ char **version = g_strsplit (vstr, ".", 4);
+ char **parts = version;
+ assembly->assembly.aname.major = atoi (*parts++);
+ assembly->assembly.aname.minor = atoi (*parts++);
+ assembly->assembly.aname.build = *parts != NULL ? atoi (*parts++) : 0;
+ assembly->assembly.aname.revision = *parts != NULL ? atoi (*parts) : 0;
+
+ g_strfreev (version);
+ g_free (vstr);
+ } else {
+ assembly->assembly.aname.major = 0;
+ assembly->assembly.aname.minor = 0;
+ assembly->assembly.aname.build = 0;
+ assembly->assembly.aname.revision = 0;
+ }
+
assembly->run = assemblyb->access != 2;
assembly->save = assemblyb->access != 1;
assembly->assembly.aname.name = image->image.name;
assembly->assembly.image = &image->image;
- mono_domain_lock (domain);
+ mono_domain_assemblies_lock (domain);
domain->domain_assemblies = g_slist_prepend (domain->domain_assemblies, assembly);
- mono_domain_unlock (domain);
+ mono_domain_assemblies_unlock (domain);
register_assembly (mono_object_domain (assemblyb), &assemblyb->assembly, &assembly->assembly);
mono_assembly_invoke_load_hook ((MonoAssembly*)assembly);
/* Create node */
+ /* FIXME: BUG: this stores managed references in unmanaged memory */
lang_node = g_new0 (ResTreeNode, 1);
lang_node->id = win32_res->lang_id;
lang_node->win32_res = win32_res;
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);
/* write the section tables and section content */
section = (MonoSectionTable*)(pefile->data + section_start);
for (i = 0; i < MONO_SECTION_MAX; ++i) {
- static const char *section_names [] = {
+ static const char section_names [][7] = {
".text", ".rsrc", ".reloc"
};
if (!assembly->sections [i].size)
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);
image = mono_image_open (name, &status);
- if (status) {
+ if (!image) {
MonoException *exc;
if (status == MONO_IMAGE_ERROR_ERRNO)
exc = mono_get_exception_file_not_found (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);
static guint
reflected_hash (gconstpointer a) {
const ReflectedEntry *ea = a;
- return GPOINTER_TO_UINT (ea->item);
+ return mono_aligned_addr_hash (ea->item);
}
#define CHECK_OBJECT(t,p,k) \
e.refclass = (k); \
mono_domain_lock (domain); \
if (!domain->refobject_hash) \
- domain->refobject_hash = mono_g_hash_table_new (reflected_hash, reflected_equal); \
+ domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC); \
if ((_obj = mono_g_hash_table_lookup (domain->refobject_hash, &e))) { \
mono_domain_unlock (domain); \
return _obj; \
} \
+ mono_domain_unlock (domain); \
} while (0)
#if HAVE_BOEHM_GC
#define ALLOC_REFENTRY GC_MALLOC (sizeof (ReflectedEntry))
+#elif HAVE_SGEN_GC
+#define ALLOC_REFENTRY mono_gc_alloc_fixed (sizeof (ReflectedEntry), NULL)
#else
#define ALLOC_REFENTRY mono_mempool_alloc (domain->mp, sizeof (ReflectedEntry))
#endif
-#define CACHE_OBJECT(p,o,k) \
+#define CACHE_OBJECT(t,p,o,k) \
do { \
- ReflectedEntry *e = ALLOC_REFENTRY; \
- e->item = (p); \
- e->refclass = (k); \
- mono_g_hash_table_insert (domain->refobject_hash, e,o); \
+ t _obj; \
+ ReflectedEntry pe; \
+ pe.item = (p); \
+ pe.refclass = (k); \
+ mono_domain_lock (domain); \
+ if (!domain->refobject_hash) \
+ domain->refobject_hash = mono_g_hash_table_new_type (reflected_hash, reflected_equal, MONO_HASH_VALUE_GC); \
+ _obj = mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
+ if (!_obj) { \
+ ReflectedEntry *e = ALLOC_REFENTRY; \
+ e->item = (p); \
+ e->refclass = (k); \
+ mono_g_hash_table_insert (domain->refobject_hash, e,o); \
+ _obj = o; \
+ } \
mono_domain_unlock (domain); \
+ return _obj; \
} while (0)
-static void
+static gpointer
register_assembly (MonoDomain *domain, MonoReflectionAssembly *res, MonoAssembly *assembly)
{
- /* this is done only once */
- mono_domain_lock (domain);
- CACHE_OBJECT (assembly, res, NULL);
+ CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
}
-static void
+static gpointer
register_module (MonoDomain *domain, MonoReflectionModuleBuilder *res, MonoDynamicImage *module)
{
- /* this is done only once */
- mono_domain_lock (domain);
- CACHE_OBJECT (module, res, NULL);
+ CACHE_OBJECT (MonoReflectionModuleBuilder *, module, res, NULL);
}
void
if (ass->modules)
memcpy (new_modules, ass->modules, module_count * sizeof (MonoImage *));
new_modules [module_count] = &image->image;
+ mono_image_addref (&image->image);
g_free (ass->modules);
ass->modules = new_modules;
res = (MonoReflectionAssembly *)mono_object_new (domain, System_Reflection_Assembly);
res->assembly = assembly;
- CACHE_OBJECT (assembly, res, NULL);
- return res;
+ CACHE_OBJECT (MonoReflectionAssembly *, assembly, res, NULL);
}
res = (MonoReflectionModule *)mono_object_new (domain, System_Reflection_Module);
res->image = image;
- res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+ MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
- res->fqname = mono_string_new (domain, image->name);
- res->name = mono_string_new (domain, basename = g_path_get_basename (image->name));
- res->scopename = mono_string_new (domain, image->module_name);
+ MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, image->name));
+ basename = g_path_get_basename (image->name);
+ MONO_OBJECT_SETREF (res, name, mono_string_new (domain, basename));
+ MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, image->module_name));
g_free (basename);
res->token = mono_metadata_make_token (MONO_TABLE_MODULE, 1);
} else {
int i;
- g_assert (image->assembly->image->modules);
res->token = 0;
- for (i = 0; i < image->assembly->image->module_count; i++) {
- if (image->assembly->image->modules [i] == image)
- res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
+ if (image->assembly->image->modules) {
+ for (i = 0; i < image->assembly->image->module_count; i++) {
+ if (image->assembly->image->modules [i] == image)
+ res->token = mono_metadata_make_token (MONO_TABLE_MODULEREF, i + 1);
+ }
+ g_assert (res->token);
}
- g_assert (res->token);
}
- mono_image_addref (image);
-
- CACHE_OBJECT (image, res, NULL);
- return res;
+ CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
}
MonoReflectionModule*
g_assert (table_index < table->rows);
mono_metadata_decode_row (table, table_index, cols, MONO_FILE_SIZE);
- res->image = 0;
- res->assembly = (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly);
+ res->image = NULL;
+ MONO_OBJECT_SETREF (res, assembly, (MonoReflectionAssembly *) mono_assembly_get_object(domain, image->assembly));
name = mono_metadata_string_heap (image, cols [MONO_FILE_NAME]);
/* Check whenever the row has a corresponding row in the moduleref table */
res->image = image->modules [i];
}
- res->fqname = mono_string_new (domain, name);
- res->name = mono_string_new (domain, name);
- res->scopename = mono_string_new (domain, name);
+ MONO_OBJECT_SETREF (res, fqname, mono_string_new (domain, name));
+ MONO_OBJECT_SETREF (res, name, mono_string_new (domain, name));
+ MONO_OBJECT_SETREF (res, scopename, mono_string_new (domain, name));
res->is_resource = cols [MONO_FILE_FLAGS] && FILE_CONTAINS_NO_METADATA;
res->token = mono_metadata_make_token (MONO_TABLE_FILE, table_index + 1);
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) ^ g_str_hash (t1->data.klass->name);
case MONO_TYPE_PTR:
return ((hash << 5) - hash) ^ mymono_metadata_type_hash (t1->data.type);
+ case MONO_TYPE_GENERICINST: {
+ int i;
+ 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) {
+ hash += mymono_metadata_type_hash (inst->type_argv [i]);
+ hash *= 13;
+ }
+ return hash;
+ }
}
return hash;
}
{
static MonoClass *System_Reflection_MonoGenericClass;
MonoReflectionGenericClass *res;
- MonoGenericClass *gclass;
- MonoClass *gklass;
+ MonoClass *klass, *gklass;
if (!System_Reflection_MonoGenericClass) {
System_Reflection_MonoGenericClass = mono_class_from_name (
g_assert (System_Reflection_MonoGenericClass);
}
- gclass = geninst->data.generic_class;
- gklass = gclass->container_class;
+ klass = mono_class_from_mono_type (geninst);
+ gklass = klass->generic_class->container_class;
- mono_class_init (gclass->klass);
+ mono_class_init (klass);
+#ifdef HAVE_SGEN_GC
+ /* FIXME: allow unpinned later */
+ res = (MonoReflectionGenericClass *) mono_gc_alloc_pinned_obj (mono_class_vtable (domain, System_Reflection_MonoGenericClass), mono_class_instance_size (System_Reflection_MonoGenericClass));
+#else
res = (MonoReflectionGenericClass *) mono_object_new (domain, System_Reflection_MonoGenericClass);
+#endif
res->type.type = geninst;
if (gklass->wastypebuilder && gklass->reflection_info)
- res->generic_type = gklass->reflection_info;
+ MONO_OBJECT_SETREF (res, generic_type, gklass->reflection_info);
else
- res->generic_type = mono_type_get_object (domain, &gclass->container_class->byval_arg);
+ MONO_OBJECT_SETREF (res, generic_type, mono_type_get_object (domain, &gklass->byval_arg));
return res;
}
+static gboolean
+verify_safe_for_managed_space (MonoType *type)
+{
+ switch (type->type) {
+#ifdef DEBUG_HARDER
+ case MONO_TYPE_ARRAY:
+ return verify_safe_for_managed_space (&type->data.array->eklass->byval_arg);
+ case MONO_TYPE_PTR:
+ return verify_safe_for_managed_space (type->data.type);
+ case MONO_TYPE_SZARRAY:
+ return verify_safe_for_managed_space (&type->data.klass->byval_arg);
+ case MONO_TYPE_GENERICINST: {
+ MonoGenericInst *inst = type->data.generic_class->inst;
+ int i;
+ if (!inst->is_open)
+ break;
+ for (i = 0; i < inst->type_argc; ++i)
+ if (!verify_safe_for_managed_space (inst->type_argv [i]))
+ return FALSE;
+ break;
+ }
+#endif
+ case MONO_TYPE_VAR:
+ case MONO_TYPE_MVAR:
+ return TRUE;
+ }
+ return TRUE;
+}
+
/*
* mono_type_get_object:
* @domain: an app domain
mono_domain_lock (domain);
if (!domain->type_hash)
- domain->type_hash = mono_g_hash_table_new ((GHashFunc)mymono_metadata_type_hash,
- (GCompareFunc)mymono_metadata_type_equal);
+ domain->type_hash = mono_g_hash_table_new_type ((GHashFunc)mymono_metadata_type_hash,
+ (GCompareFunc)mymono_metadata_type_equal, MONO_HASH_VALUE_GC);
if ((res = mono_g_hash_table_lookup (domain->type_hash, type))) {
mono_domain_unlock (domain);
return res;
mono_domain_unlock (domain);
return res;
}
- if (klass->reflection_info && !klass->wastypebuilder) {
- /* g_assert_not_reached (); */
- /* should this be considered an error condition? */
+
+ if (!verify_safe_for_managed_space (type)) {
+ mono_domain_unlock (domain);
+ mono_raise_exception (mono_get_exception_invalid_operation ("This type cannot be propagated to managed space"));
+ }
+
+ if (klass->reflection_info && !klass->wastypebuilder) {
+ /* g_assert_not_reached (); */
+ /* should this be considered an error condition? */
if (!type->byref) {
mono_domain_unlock (domain);
return klass->reflection_info;
}
}
mono_class_init (klass);
+#ifdef HAVE_SGEN_GC
+ res = (MonoReflectionType *)mono_gc_alloc_pinned_obj (mono_class_vtable (domain, mono_defaults.monotype_class), mono_class_instance_size (mono_defaults.monotype_class));
+#else
res = (MonoReflectionType *)mono_object_new (domain, mono_defaults.monotype_class);
+#endif
res->type = type;
mono_g_hash_table_insert (domain->type_hash, type, res);
mono_domain_unlock (domain);
* We use the same C representation for methods and constructors, but the type
* name in C# is different.
*/
- const char *cname;
+ static MonoClass *System_Reflection_MonoMethod = NULL;
+ static MonoClass *System_Reflection_MonoCMethod = NULL;
+ static MonoClass *System_Reflection_MonoGenericMethod = NULL;
+ static MonoClass *System_Reflection_MonoGenericCMethod = NULL;
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")))
- cname = "MonoGenericCMethod";
- else
- cname = "MonoGenericMethod";
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", cname);
-
+ if ((*method->name == '.') && (!strcmp (method->name, ".ctor") || !strcmp (method->name, ".cctor"))) {
+ if (!System_Reflection_MonoGenericCMethod)
+ System_Reflection_MonoGenericCMethod = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoGenericCMethod");
+ klass = System_Reflection_MonoGenericCMethod;
+ } else {
+ if (!System_Reflection_MonoGenericMethod)
+ System_Reflection_MonoGenericMethod = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoGenericMethod");
+ klass = System_Reflection_MonoGenericMethod;
+ }
gret = (MonoReflectionGenericMethod*)mono_object_new (domain, klass);
gret->method.method = method;
- gret->method.name = mono_string_new (domain, method->name);
- gret->method.reftype = mono_type_get_object (domain, &refclass->byval_arg);
- CACHE_OBJECT (method, gret, refclass);
- return (MonoReflectionMethod *) gret;
+ MONO_OBJECT_SETREF (gret, method.name, mono_string_new (domain, method->name));
+ MONO_OBJECT_SETREF (gret, method.reftype, mono_type_get_object (domain, &refclass->byval_arg));
+ CACHE_OBJECT (MonoReflectionMethod *, method, (MonoReflectionMethod*)gret, refclass);
}
if (!refclass)
refclass = method->klass;
CHECK_OBJECT (MonoReflectionMethod *, method, refclass);
- if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0))
- cname = "MonoCMethod";
- else
- cname = "MonoMethod";
- klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", cname);
-
+ if (*method->name == '.' && (strcmp (method->name, ".ctor") == 0 || strcmp (method->name, ".cctor") == 0)) {
+ if (!System_Reflection_MonoCMethod)
+ System_Reflection_MonoCMethod = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoCMethod");
+ klass = System_Reflection_MonoCMethod;
+ }
+ else {
+ if (!System_Reflection_MonoMethod)
+ System_Reflection_MonoMethod = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "MonoMethod");
+ klass = System_Reflection_MonoMethod;
+ }
ret = (MonoReflectionMethod*)mono_object_new (domain, klass);
ret->method = method;
- ret->name = mono_string_new (domain, method->name);
- ret->reftype = mono_type_get_object (domain, &refclass->byval_arg);
- CACHE_OBJECT (method, ret, refclass);
- return ret;
+ 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;
- res->name = mono_string_new (domain, field->name);
+ MONO_OBJECT_SETREF (res, name, mono_string_new (domain, field->name));
if (field->generic_info)
res->attrs = field->generic_info->generic_type->attrs;
else
res->attrs = field->type->attrs;
- res->type = mono_type_get_object (domain, field->type);
- CACHE_OBJECT (field, res, klass);
- return res;
+ MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
+ CACHE_OBJECT (MonoReflectionField *, field, res, klass);
}
/*
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 (property, res, klass);
- return res;
+ 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 (event, res, klass);
- return res;
+ CACHE_OBJECT (MonoReflectionEvent *, event, res, klass);
}
/*
MonoType *type = NULL;
MonoObject *dbnull = mono_get_dbnull_object (domain);
MonoMarshalSpec **mspecs;
+ MonoMethodSignature *sig;
int i;
if (!System_Reflection_ParameterInfo)
*/
CHECK_OBJECT (MonoArray*, &(method->signature), NULL);
+ sig = mono_method_signature (method);
member = mono_method_get_object (domain, method, NULL);
- names = g_new (char *, mono_method_signature (method)->param_count);
+ names = g_new (char *, sig->param_count);
mono_method_get_param_names (method, (const char **) names);
- mspecs = g_new (MonoMarshalSpec*, mono_method_signature (method)->param_count + 1);
+ mspecs = g_new (MonoMarshalSpec*, sig->param_count + 1);
mono_method_get_marshal_info (method, mspecs);
- res = mono_array_new (domain, System_Reflection_ParameterInfo, mono_method_signature (method)->param_count);
- for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+ res = mono_array_new (domain, System_Reflection_ParameterInfo, sig->param_count);
+ for (i = 0; i < sig->param_count; ++i) {
param = (MonoReflectionParameter *)mono_object_new (domain, System_Reflection_ParameterInfo);
- param->ClassImpl = mono_type_get_object (domain, mono_method_signature (method)->params [i]);
- param->MemberImpl = (MonoObject*)member;
- param->NameImpl = mono_string_new (domain, names [i]);
+ MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, sig->params [i]));
+ MONO_OBJECT_SETREF (param, MemberImpl, (MonoObject*)member);
+ MONO_OBJECT_SETREF (param, NameImpl, mono_string_new (domain, names [i]));
param->PositionImpl = i;
- param->AttrsImpl = mono_method_signature (method)->params [i]->attrs;
+ param->AttrsImpl = sig->params [i]->attrs;
if (!(param->AttrsImpl & PARAM_ATTRIBUTE_HAS_DEFAULT)) {
- param->DefaultValueImpl = dbnull;
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
} else {
if (!blobs) {
- blobs = g_new0 (char *, mono_method_signature (method)->param_count);
- types = g_new0 (guint32, mono_method_signature (method)->param_count);
+ blobs = g_new0 (char *, sig->param_count);
+ types = g_new0 (guint32, sig->param_count);
get_default_param_value_blobs (method, blobs, types);
}
type->data.klass = NULL;
if (types [i] == MONO_TYPE_CLASS)
type->data.klass = mono_defaults.object_class;
- else
+ else if ((sig->params [i]->type == MONO_TYPE_VALUETYPE) && sig->params [i]->data.klass->enumtype) {
+ /* For enums, types [i] contains the base type */
+
+ type->type = MONO_TYPE_VALUETYPE;
+ type->data.klass = mono_class_from_mono_type (sig->params [i]);
+ } else
type->data.klass = mono_class_from_mono_type (type);
-
- param->DefaultValueImpl = mono_get_object_from_blob (domain, type, blobs [i]);
+
+ 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)
- param->DefaultValueImpl = dbnull;
+ MONO_OBJECT_SETREF (param, DefaultValueImpl, dbnull);
}
if (mspecs [i + 1])
- param->MarshalAsImpl = (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]);
+ MONO_OBJECT_SETREF (param, MarshalAsImpl, (MonoObject*)mono_reflection_marshal_from_marshal_spec (domain, method->klass, mspecs [i + 1]));
- mono_array_set (res, gpointer, i, param);
+ mono_array_setref (res, i, param);
}
g_free (names);
g_free (blobs);
mono_metadata_free_marshal_spec (mspecs [i]);
g_free (mspecs);
- CACHE_OBJECT (&(method->signature), res, NULL);
- return res;
+ CACHE_OBJECT (MonoArray *, &(method->signature), res, NULL);
}
/*
ret->init_locals = header->init_locals;
ret->max_stack = header->max_stack;
ret->local_var_sig_token = local_var_sig_token;
- ret->il = mono_array_new (domain, mono_defaults.byte_class, header->code_size);
- memcpy (mono_array_addr (ret->il, guint8*, 0), header->code, header->code_size);
+ MONO_OBJECT_SETREF (ret, il, mono_array_new (domain, mono_defaults.byte_class, header->code_size));
+ memcpy (mono_array_addr (ret->il, guint8, 0), header->code, header->code_size);
/* Locals */
- ret->locals = mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals);
+ MONO_OBJECT_SETREF (ret, locals, mono_array_new (domain, System_Reflection_LocalVariableInfo, header->num_locals));
for (i = 0; i < header->num_locals; ++i) {
MonoReflectionLocalVariableInfo *info = (MonoReflectionLocalVariableInfo*)mono_object_new (domain, System_Reflection_LocalVariableInfo);
- info->local_type = mono_type_get_object (domain, header->locals [i]);
+ MONO_OBJECT_SETREF (info, local_type, mono_type_get_object (domain, header->locals [i]));
info->is_pinned = header->locals [i]->pinned;
info->local_index = i;
- mono_array_set (ret->locals, MonoReflectionLocalVariableInfo*, i, info);
+ mono_array_setref (ret->locals, i, info);
}
/* Exceptions */
- ret->clauses = mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses);
+ MONO_OBJECT_SETREF (ret, clauses, mono_array_new (domain, System_Reflection_ExceptionHandlingClause, header->num_clauses));
for (i = 0; i < header->num_clauses; ++i) {
MonoReflectionExceptionHandlingClause *info = (MonoReflectionExceptionHandlingClause*)mono_object_new (domain, System_Reflection_ExceptionHandlingClause);
MonoExceptionClause *clause = &header->clauses [i];
if (clause->flags == MONO_EXCEPTION_CLAUSE_FILTER)
info->filter_offset = clause->data.filter_offset;
else if (clause->data.catch_class)
- info->catch_type = mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg);
+ MONO_OBJECT_SETREF (info, catch_type, mono_type_get_object (mono_domain_get (), &clause->data.catch_class->byval_arg));
- mono_array_set (ret->clauses, MonoReflectionExceptionHandlingClause*, i, info);
+ mono_array_setref (ret->clauses, i, info);
}
- CACHE_OBJECT (method, ret, NULL);
+ CACHE_OBJECT (MonoReflectionMethodBody *, method, ret, NULL);
return ret;
}
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);
if (!methodsig->param_count)
return;
- if (klass->generic_class) {
- return; /* FIXME - ??? */
- }
-
mono_class_init (klass);
if (klass->image->dynamic) {
- MonoReflectionMethodAux *aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
+ MonoReflectionMethodAux *aux;
+ if (method->is_inflated)
+ method = ((MonoMethodInflated*)method)->declaring;
+ aux = g_hash_table_lookup (((MonoDynamicImage*)method->klass->image)->method_aux_hash, method);
if (aux && aux->param_defaults) {
memcpy (blobs, &(aux->param_defaults [1]), methodsig->param_count * sizeof (char*));
memcpy (types, &(aux->param_default_types [1]), methodsig->param_count * sizeof (guint32));
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 != ',')
*
* Returns: 0 on parse error.
*/
-int
-mono_reflection_parse_type (char *name, MonoTypeNameParse *info) {
-
- char *start, *p, *w, *last_point, *startn;
+static int
+_mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
+ MonoTypeNameParse *info)
+{
+ char *start, *p, *w, *temp, *last_point, *startn;
int in_modifiers = 0;
- int isbyref = 0, rank;
+ int isbyref = 0, rank, arity = 0, i;
start = p = w = name;
info->name = info->name_space = NULL;
info->nested = NULL;
info->modifiers = NULL;
+ info->type_arguments = NULL;
/* last_point separates the namespace from the name */
last_point = NULL;
}
break;
case '.':
- last_point = w;
+ last_point = p;
break;
case '\\':
++p;
case '*':
case '[':
case ',':
+ case ']':
in_modifiers = 1;
break;
+ case '`':
+ ++p;
+ i = strtol (p, &temp, 10);
+ arity += i;
+ if (p == temp)
+ return 0;
+ p = temp-1;
+ break;
default:
break;
}
if (in_modifiers)
break;
- *w++ = *p++;
+ // *w++ = *p++;
+ p++;
}
if (!info->name) {
*p++ = 0;
break;
case '[':
+ if (arity != 0) {
+ *p++ = 0;
+ info->type_arguments = g_ptr_array_new ();
+ for (i = 0; i < arity; i++) {
+ MonoTypeNameParse *subinfo = g_new0 (MonoTypeNameParse, 1);
+ gboolean fqname = FALSE;
+
+ g_ptr_array_add (info->type_arguments, subinfo);
+
+ if (*p == '[') {
+ p++;
+ fqname = TRUE;
+ }
+
+ if (!_mono_reflection_parse_type (p, &p, TRUE, subinfo))
+ return 0;
+
+ if (fqname) {
+ char *aname;
+
+ if (*p != ',')
+ return 0;
+ *p++ = 0;
+
+ aname = p;
+ while (*p && (*p != ']'))
+ p++;
+
+ if (*p != ']')
+ return 0;
+
+ *p++ = 0;
+ while (*aname) {
+ if (g_ascii_isspace (*aname)) {
+ ++aname;
+ continue;
+ }
+ break;
+ }
+ if (!*aname ||
+ !assembly_name_to_aname (&subinfo->assembly, aname))
+ return 0;
+ }
+
+ if (i + 1 < arity) {
+ if (*p != ',')
+ return 0;
+ } else {
+ if (*p != ']')
+ return 0;
+ }
+ *p++ = 0;
+ }
+
+ arity = 0;
+ break;
+ }
rank = 1;
*p++ = 0;
while (*p) {
return 0;
info->modifiers = g_list_append (info->modifiers, GUINT_TO_POINTER (rank));
break;
+ case ']':
+ if (is_recursed)
+ goto end;
+ return 0;
case ',':
+ if (is_recursed)
+ goto end;
*p++ = 0;
while (*p) {
if (g_ascii_isspace (*p)) {
break;
default:
return 0;
- break;
}
if (info->assembly.name)
break;
}
- *w = 0; /* terminate class name */
+ // *w = 0; /* terminate class name */
+ end:
if (!info->name || !*info->name)
return 0;
+ if (endptr)
+ *endptr = p;
/* add other consistency checks */
return 1;
}
+int
+mono_reflection_parse_type (char *name, MonoTypeNameParse *info)
+{
+ return _mono_reflection_parse_type (name, NULL, FALSE, info);
+}
+
+static MonoType*
+_mono_reflection_get_type_from_info (MonoTypeNameParse *info, MonoImage *image, gboolean ignorecase)
+{
+ gboolean type_resolve = FALSE;
+ MonoType *type;
+ MonoImage *rootimage = image;
+
+ if (info->assembly.name) {
+ MonoAssembly *assembly = mono_assembly_loaded (&info->assembly);
+ if (!assembly) {
+ /* then we must load the assembly ourselve - see #60439 */
+ assembly = mono_assembly_load (&info->assembly, NULL, NULL);
+ if (!assembly)
+ return NULL;
+ }
+ image = assembly->image;
+ } else if (!image) {
+ image = mono_defaults.corlib;
+ }
+
+ 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_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;
if (!klass)
return NULL;
mono_class_init (klass);
+
+ if (info->type_arguments) {
+ MonoType **type_args = g_new0 (MonoType *, info->type_arguments->len);
+ MonoReflectionType *the_type;
+ MonoType *instance;
+ int i;
+
+ 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, rootimage, ignorecase);
+ if (!type_args [i]) {
+ g_free (type_args);
+ return NULL;
+ }
+ }
+
+ the_type = mono_type_get_object (mono_domain_get (), &klass->byval_arg);
+
+ instance = mono_reflection_bind_generic_parameters (
+ the_type, info->type_arguments->len, type_args);
+
+ if (!instance) {
+ g_free (type_args);
+ return NULL;
+ }
+
+ klass = mono_class_from_mono_type (instance);
+ }
+
for (mod = info->modifiers; mod; mod = mod->next) {
modval = GPOINTER_TO_UINT (mod->data);
if (!modval) { /* byref: must be last modifier */
*/
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);
+}
+
+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);
+ type = mono_reflection_get_type_internal (rootimage, image, info, ignorecase);
if (type)
return type;
if (!mono_domain_has_type_resolve (mono_domain_get ()))
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);
+ 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 (mod->image, info, ignorecase);
+ type = mono_reflection_get_type_internal (rootimage, mod->image, info, ignorecase);
if (type)
break;
}
}
}
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)
+{
+ g_list_free (info->modifiers);
+ g_list_free (info->nested);
+
+ if (info->type_arguments) {
+ int i;
+
+ for (i = 0; i < info->type_arguments->len; i++) {
+ MonoTypeNameParse *subinfo = g_ptr_array_index (info->type_arguments, i);
+
+ free_type_info (subinfo);
+ }
+
+ g_ptr_array_free (info->type_arguments, TRUE);
+ }
+}
+
/*
* mono_reflection_type_from_name:
* @name: type name.
MonoType*
mono_reflection_type_from_name (char *name, MonoImage *image)
{
- MonoType *type;
+ MonoType *type = NULL;
MonoTypeNameParse info;
- MonoAssembly *assembly;
char *tmp;
- gboolean type_resolve = FALSE;
/* Make a copy since parse_type modifies its argument */
tmp = g_strdup (name);
/*g_print ("requested type %s\n", str);*/
- if (!mono_reflection_parse_type (tmp, &info)) {
- g_free (tmp);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
- return NULL;
- }
-
- if (info.assembly.name) {
- assembly = mono_assembly_loaded (&info.assembly);
- if (!assembly) {
- /* then we must load the assembly ourselve - see #60439 */
- assembly = mono_assembly_load (&info.assembly, NULL, NULL);
- if (!assembly) {
- g_free (tmp);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
- return NULL;
- }
- }
- image = assembly->image;
- } else if (image == NULL) {
- image = mono_defaults.corlib;
- }
-
- type = mono_reflection_get_type (image, &info, FALSE, &type_resolve);
- if (type == NULL && !info.assembly.name && image != mono_defaults.corlib) {
- image = mono_defaults.corlib;
- type = mono_reflection_get_type (image, &info, FALSE, &type_resolve);
+ if (mono_reflection_parse_type (tmp, &info)) {
+ type = _mono_reflection_get_type_from_info (&info, image, FALSE);
}
g_free (tmp);
- g_list_free (info.modifiers);
- g_list_free (info.nested);
+ 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;
- MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)fb->typeb;
- if (tb->generic_params) {
- g_assert_not_reached ();
- } else {
- token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
- }
+ token = fb->table_idx | MONO_TOKEN_FIELD_DEF;
} else if (strcmp (klass->name, "TypeBuilder") == 0) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder *)obj;
token = tb->table_idx | MONO_TOKEN_TYPE_DEF;
MonoReflectionType *tb = (MonoReflectionType *)obj;
token = mono_class_from_mono_type (tb->type)->type_token;
} else if (strcmp (klass->name, "MonoCMethod") == 0 ||
- strcmp (klass->name, "MonoMethod") == 0) {
+ strcmp (klass->name, "MonoMethod") == 0 ||
+ strcmp (klass->name, "MonoGenericMethod") == 0 ||
+ strcmp (klass->name, "MonoGenericCMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
if (m->method->is_inflated) {
- g_assert_not_reached ();
- } else if (mono_method_signature (m->method)->generic_param_count) {
- g_assert_not_reached ();
- } else if (m->method->klass->generic_class) {
- g_assert_not_reached ();
+ MonoMethodInflated *inflated = (MonoMethodInflated *) m->method;
+ return inflated->declaring->token;
} else {
token = m->method->token;
}
} else if (strcmp (klass->name, "MonoField") == 0) {
MonoReflectionField *f = (MonoReflectionField*)obj;
+ if (f->field->generic_info && f->field->generic_info->reflection_info)
+ return mono_reflection_get_token (f->field->generic_info->reflection_info);
+
token = mono_class_get_field_token (f->field);
} else if (strcmp (klass->name, "MonoProperty") == 0) {
MonoReflectionProperty *p = (MonoReflectionProperty*)obj;
load_cattr_value (MonoImage *image, MonoType *t, const char *p, const char **end)
{
int slen, type = t->type;
+ MonoClass *tklass = t->data.klass;
+
handle_enum:
switch (type) {
case MONO_TYPE_U1:
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;
} else if (subt == 0x0E) {
type = MONO_TYPE_STRING;
goto handle_enum;
+ } else if (subt == 0x1D) {
+ MonoType simple_type = {{0}};
+ 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);
+ goto handle_enum;
} else if (subt == 0x55) {
char *n;
MonoType *t;
n [slen] = 0;
t = mono_reflection_type_from_name (n, image);
if (!t)
- g_warning ("Cannot load type '%s'", n);
+ g_error ("Cannot load type '%s'", n);
g_free (n);
p += slen;
subc = mono_class_from_mono_type (t);
*end = p;
return NULL;
}
- arr = mono_array_new (mono_domain_get(), t->data.klass, alen);
- basetype = t->data.klass->byval_arg.type;
+ arr = mono_array_new (mono_domain_get(), tklass, alen);
+ basetype = tklass->byval_arg.type;
+ if (basetype == MONO_TYPE_VALUETYPE && tklass->enumtype)
+ basetype = tklass->enum_basetype->type;
switch (basetype)
{
case MONO_TYPE_U1:
}
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++) {
case MONO_TYPE_OBJECT:
case MONO_TYPE_STRING:
for (i = 0; i < alen; i++) {
- MonoObject *item = load_cattr_value (image, &t->data.klass->byval_arg, p, &p);
- mono_array_set (arr, gpointer, i, item);
+ MonoObject *item = load_cattr_value (image, &tklass->byval_arg, p, &p);
+ mono_array_setref (arr, i, item);
}
break;
default:
- g_error("Type 0x%02x not handled in custom attr array decoding",t->data.type->type);
+ g_error ("Type 0x%02x not handled in custom attr array decoding", basetype);
}
*end=p;
return arr;
return NULL;
}
+static MonoObject*
+create_cattr_typed_arg (MonoType *t, MonoObject *val)
+{
+ static MonoClass *klass;
+ static MonoMethod *ctor;
+ MonoObject *retval;
+ void *params [2], *unboxed;
+
+ if (!klass)
+ klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeTypedArgument");
+ if (!ctor)
+ ctor = mono_class_get_method_from_name (klass, ".ctor", 2);
+
+ params [0] = mono_type_get_object (mono_domain_get (), t);
+ params [1] = val;
+ retval = mono_object_new (mono_domain_get (), klass);
+ unboxed = mono_object_unbox (retval);
+ mono_runtime_invoke (ctor, unboxed, params, NULL);
+
+ return retval;
+}
+
+static MonoObject*
+create_cattr_named_arg (void *minfo, MonoObject *typedarg)
+{
+ static MonoClass *klass;
+ static MonoMethod *ctor;
+ MonoObject *retval;
+ void *unboxed, *params [2];
+
+ if (!klass)
+ klass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "CustomAttributeNamedArgument");
+ if (!ctor)
+ ctor = mono_class_get_method_from_name (klass, ".ctor", 2);
+
+ params [0] = minfo;
+ params [1] = typedarg;
+ retval = mono_object_new (mono_domain_get (), klass);
+ unboxed = mono_object_unbox (retval);
+ mono_runtime_invoke (ctor, unboxed, params, NULL);
+
+ return retval;
+}
+
static gboolean
type_is_reference (MonoType *type)
{
}
static MonoObject*
-create_custom_attr (MonoImage *image, MonoMethod *method, const char *data, guint32 len)
+create_custom_attr (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
{
- const char *p = data;
+ const char *p = (const char*)data;
const char *named;
guint32 i, j, num_named;
MonoObject *attr;
named += 2;
for (j = 0; j < num_named; j++) {
gint name_len;
- gboolean is_boxed = FALSE;
char *name, named_type, data_type;
named_type = *named++;
data_type = *named++; /* type of data */
- if (data_type == 0x51)
- is_boxed = TRUE;
-
- if (data_type == 0x55) {
+ if (data_type == MONO_TYPE_SZARRAY)
+ data_type = *named++;
+ if (data_type == MONO_TYPE_ENUM) {
gint type_len;
char *type_name;
type_len = mono_metadata_decode_blob_size (named, &named);
type_name [type_len] = 0;
named += type_len;
/* FIXME: lookup the type and check type consistency */
- } else if (data_type == MONO_TYPE_SZARRAY && (named_type == 0x54 || named_type == 0x53)) {
- /* this seems to be the type of the element of the array */
- /* g_print ("skipping 0x%02x after prop\n", *named); */
- named++;
+ g_free (type_name);
}
name_len = mono_metadata_decode_blob_size (named, &named);
name = g_malloc (name_len + 1);
return attr;
}
+static MonoObject*
+create_custom_attr_data (MonoImage *image, MonoMethod *method, const guchar *data, guint32 len)
+{
+ MonoArray *typedargs, *namedargs;
+ MonoClass *attrklass;
+ static MonoMethod *ctor;
+ MonoDomain *domain;
+ MonoObject *attr;
+ const char *p = (const char*)data;
+ const char *named;
+ guint32 i, j, num_named;
+ void *params [3];
+
+ mono_class_init (method->klass);
+
+ if (!ctor)
+ 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, 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);
+ return attr;
+ }
+
+ if (len < 2 || read16 (p) != 0x0001) /* Prolog */
+ return NULL;
+
+ typedargs = mono_array_new (domain, mono_get_object_class (), mono_method_signature (method)->param_count);
+
+ /* skip prolog */
+ p += 2;
+ for (i = 0; i < mono_method_signature (method)->param_count; ++i) {
+ MonoObject *obj, *typedarg;
+ void *val;
+
+ val = load_cattr_value (image, mono_method_signature (method)->params [i], p, &p);
+ obj = type_is_reference (mono_method_signature (method)->params [i]) ?
+ val : mono_value_box (domain, mono_class_from_mono_type (mono_method_signature (method)->params [i]), val);
+ typedarg = create_cattr_typed_arg (mono_method_signature (method)->params [i], obj);
+ mono_array_setref (typedargs, i, typedarg);
+
+ if (!type_is_reference (mono_method_signature (method)->params [i]))
+ g_free (val);
+ }
+
+ named = p;
+ num_named = read16 (named);
+ namedargs = mono_array_new (domain, mono_get_object_class (), num_named);
+ named += 2;
+ attrklass = method->klass;
+ for (j = 0; j < num_named; j++) {
+ gint name_len;
+ char *name, named_type, data_type;
+ named_type = *named++;
+ data_type = *named++; /* type of data */
+ if (data_type == MONO_TYPE_SZARRAY)
+ data_type = *named++;
+ if (data_type == MONO_TYPE_ENUM) {
+ gint type_len;
+ char *type_name;
+ type_len = mono_metadata_decode_blob_size (named, &named);
+ type_name = g_malloc (type_len + 1);
+ memcpy (type_name, named, type_len);
+ type_name [type_len] = 0;
+ named += type_len;
+ /* FIXME: lookup the type and check type consistency */
+ g_free (type_name);
+ }
+ name_len = mono_metadata_decode_blob_size (named, &named);
+ name = g_malloc (name_len + 1);
+ memcpy (name, named, name_len);
+ name [name_len] = 0;
+ named += name_len;
+ if (named_type == 0x53) {
+ MonoObject *obj, *typedarg, *namedarg;
+ MonoClassField *field = mono_class_get_field_from_name (attrklass, name);
+ void *minfo, *val = load_cattr_value (image, field->type, named, &named);
+
+ minfo = mono_field_get_object (domain, NULL, field);
+ obj = type_is_reference (field->type) ? val : mono_value_box (domain, mono_class_from_mono_type (field->type), val);
+ typedarg = create_cattr_typed_arg (field->type, obj);
+ namedarg = create_cattr_named_arg (minfo, typedarg);
+ mono_array_setref (namedargs, j, namedarg);
+ if (!type_is_reference (field->type))
+ g_free (val);
+ } else if (named_type == 0x54) {
+ MonoObject *obj, *typedarg, *namedarg;
+ MonoType *prop_type;
+ void *val, *minfo;
+ MonoProperty *prop = mono_class_get_property_from_name (attrklass, name);
+
+ prop_type = prop->get? mono_method_signature (prop->get)->ret :
+ mono_method_signature (prop->set)->params [mono_method_signature (prop->set)->param_count - 1];
+ minfo = mono_property_get_object (domain, NULL, prop);
+ val = load_cattr_value (image, prop_type, named, &named);
+ obj = type_is_reference (prop_type) ? val : mono_value_box (domain, mono_class_from_mono_type (prop_type), val);
+ typedarg = create_cattr_typed_arg (prop_type, obj);
+ namedarg = create_cattr_named_arg (minfo, typedarg);
+ mono_array_setref (namedargs, j, namedarg);
+ if (!type_is_reference (prop_type))
+ g_free (val);
+ }
+ g_free (name);
+ }
+ 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_runtime_invoke (ctor, attr, params, NULL);
+ return attr;
+}
+
MonoArray*
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_set (result, gpointer, i, attr);
+ mono_array_setref (result, i, attr);
+ }
+ return result;
+}
+
+static MonoArray*
+mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
+{
+ MonoArray *result;
+ MonoObject *attr;
+ int i, n;
+
+ n = 0;
+ for (i = 0; i < cinfo->num_attrs; ++i) {
+ if (mono_class_is_assignable_from (attr_klass, cinfo->attrs [i].ctor->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)) {
+ attr = create_custom_attr (cinfo->image, cinfo->attrs [i].ctor, cinfo->attrs [i].data, cinfo->attrs [i].data_size);
+ mono_array_setref (result, n, attr);
+ n ++;
+ }
+ }
+ return result;
+}
+
+static MonoArray*
+mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
+{
+ MonoArray *result;
+ MonoObject *attr;
+ int i;
+
+ 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 = data;
+ ainfo->attrs [i].data = (guchar*)data;
}
g_list_free (list);
MonoCustomAttrInfo *cinfo;
guint32 idx;
- 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 (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;
MonoReflectionMethodAux *aux;
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;
method_index = mono_method_get_index (method);
ca = &image->tables [MONO_TABLE_METHOD];
- if (method->klass->generic_class || mono_method_signature (method)->generic_param_count) {
- /* FIXME FIXME FIXME */
- return NULL;
- }
-
param_list = mono_metadata_decode_row_col (ca, method_index - 1, MONO_METHOD_PARAMLIST);
if (method_index == ca->rows) {
ca = &image->tables [MONO_TABLE_PARAM];
} else if (strcmp ("ModuleBuilder", klass->name) == 0) {
MonoReflectionModuleBuilder *mb = (MonoReflectionModuleBuilder*)obj;
cinfo = mono_custom_attrs_from_builders (&mb->dynamic_image->image, mb->cattrs);
+ } else if (strcmp ("ConstructorBuilder", klass->name) == 0) {
+ MonoReflectionCtorBuilder *cb = (MonoReflectionCtorBuilder*)obj;
+ cinfo = mono_custom_attrs_from_builders (cb->mhandle->klass->image, cb->cattrs);
+ } else if (strcmp ("MethodBuilder", klass->name) == 0) {
+ MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder*)obj;
+ cinfo = mono_custom_attrs_from_builders (mb->mhandle->klass->image, mb->cattrs);
+ } 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 { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
}
/*
- * mono_reflection_get_custom_attrs:
+ * mono_reflection_get_custom_attrs_by_type:
* @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. If @attr_klass is non-NULL, only custom attributes
+ * of that type are returned. The objects are fully build. Return NULL if a loading error
+ * occurs.
*/
MonoArray*
-mono_reflection_get_custom_attrs (MonoObject *obj)
+mono_reflection_get_custom_attrs_by_type (MonoObject *obj, MonoClass *attr_klass)
{
MonoArray *result;
MonoCustomAttrInfo *cinfo;
cinfo = mono_reflection_get_custom_attrs_info (obj);
if (cinfo) {
- result = mono_custom_attrs_construct (cinfo);
+ if (attr_klass)
+ result = mono_custom_attrs_construct_by_type (cinfo, attr_klass);
+ else
+ result = mono_custom_attrs_construct (cinfo);
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;
}
+/*
+ * mono_reflection_get_custom_attrs:
+ * @obj: a reflection object handle
+ *
+ * Return an array with all the custom attributes defined of the
+ * reflection handle @obj. The objects are fully build. Return NULL if a loading error
+ * occurs.
+ */
+MonoArray*
+mono_reflection_get_custom_attrs (MonoObject *obj)
+{
+ return mono_reflection_get_custom_attrs_by_type (obj, NULL);
+}
+
+/*
+ * mono_reflection_get_custom_attrs_data:
+ * @obj: a reflection obj handle
+ *
+ * Returns an array of System.Reflection.CustomAttributeData,
+ * which include information about attributes reflected on
+ * types loaded using the Reflection Only methods
+ */
+MonoArray*
+mono_reflection_get_custom_attrs_data (MonoObject *obj)
+{
+ MonoArray *result;
+ MonoCustomAttrInfo *cinfo;
+
+ cinfo = mono_reflection_get_custom_attrs_info (obj);
+ if (cinfo) {
+ result = mono_custom_attrs_data_construct (cinfo);
+ if (!cinfo->cached)
+ mono_custom_attrs_free (cinfo);
+ } 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.
+ */
static MonoMethodSignature*
-parameters_to_signature (MonoArray *parameters) {
+parameters_to_signature (MonoMemPool *mp, MonoArray *parameters) {
MonoMethodSignature *sig;
int count, i;
count = parameters? mono_array_length (parameters): 0;
- sig = g_malloc0 (sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
+ sig = mp_g_malloc0 (mp, sizeof (MonoMethodSignature) + sizeof (MonoType*) * count);
sig->param_count = count;
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;
}
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
static MonoMethodSignature*
-ctor_builder_to_signature (MonoReflectionCtorBuilder *ctor) {
+ctor_builder_to_signature (MonoMemPool *mp, MonoReflectionCtorBuilder *ctor) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (ctor->parameters);
+ sig = parameters_to_signature (mp, ctor->parameters);
sig->hasthis = ctor->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
sig->ret = &mono_defaults.void_class->byval_arg;
return sig;
}
+/**
+ * LOCKING: Assumes the loader lock is held.
+ */
static MonoMethodSignature*
-method_builder_to_signature (MonoReflectionMethodBuilder *method) {
+method_builder_to_signature (MonoMemPool *mp, MonoReflectionMethodBuilder *method) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (method->parameters);
+ sig = parameters_to_signature (mp, method->parameters);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
sig->generic_param_count = method->generic_params ? mono_array_length (method->generic_params) : 0;
dynamic_method_to_signature (MonoReflectionDynamicMethod *method) {
MonoMethodSignature *sig;
- sig = parameters_to_signature (method->parameters);
+ sig = parameters_to_signature (NULL, method->parameters);
sig->hasthis = method->attrs & METHOD_ATTRIBUTE_STATIC? 0: 1;
sig->ret = method->rtype? method->rtype->type: &mono_defaults.void_class->byval_arg;
sig->generic_param_count = 0;
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 types 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);
*retbuffer = buffer;
eclass = type->data.klass;
arg_eclass = mono_object_class (arg)->element_class;
- if (eclass->valuetype && arg_eclass->valuetype) {
+
+ if (!eclass) {
+ /* Happens when we are called from the MONO_TYPE_OBJECT case below */
+ eclass = mono_defaults.object_class;
+ }
+ if (eclass == mono_defaults.object_class && arg_eclass->valuetype) {
+ char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
+ int elsize = mono_class_array_element_size (arg_eclass);
+ for (i = 0; i < len; ++i) {
+ encode_cattr_value (assembly, buffer, p, &buffer, &p, buflen, &arg_eclass->byval_arg, NULL, elptr);
+ elptr += elsize;
+ }
+ } else if (eclass->valuetype && arg_eclass->valuetype) {
char *elptr = mono_array_addr ((MonoArray*)arg, char, 0);
int elsize = mono_class_array_element_size (eclass);
for (i = 0; i < len; ++i) {
}
break;
}
- /* it may be a boxed value or a Type */
case MONO_TYPE_OBJECT: {
MonoClass *klass;
char *str;
guint32 slen;
+ /*
+ * The parameter type is 'object' but the type of the actual
+ * argument is not. So we have to add type information to the blob
+ * too. This is completely undocumented in the spec.
+ */
+
if (arg == NULL) {
*p++ = MONO_TYPE_STRING; // It's same hack as MS uses
*p++ = 0xFF;
klass = mono_object_class (arg);
- if (mono_object_isinst (arg, mono_defaults.monotype_class)) {
+ if (mono_object_isinst (arg, mono_defaults.systemtype_class)) {
*p++ = 0x50;
goto handle_type;
} else if (klass->enumtype) {
simple_type = MONO_TYPE_STRING;
*p++ = 0x0E;
goto handle_enum;
+ } else if (klass->rank == 1) {
+ *p++ = 0x1D;
+ 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;
}
static void
-encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
+encode_field_or_prop_type (MonoType *type, char *p, char **retp)
{
- int len;
- /* Preallocate a large enough buffer */
- if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
- char *str = type_get_qualified_name (type, NULL);
- len = strlen (str);
- g_free (str);
- } else {
- len = 0;
- }
- len += strlen (name);
-
- if ((p-buffer) + 20 + len >= *buflen) {
- char *newbuf;
- *buflen *= 2;
- *buflen += len;
- newbuf = g_realloc (buffer, *buflen);
- p = newbuf + (p-buffer);
- buffer = newbuf;
- }
-
if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
char *str = type_get_qualified_name (type, NULL);
int slen = strlen (str);
} else {
mono_metadata_encode_value (type->type, p, &p);
if (type->type == MONO_TYPE_SZARRAY)
- mono_metadata_encode_value (type->data.klass->this_arg.type, p, &p);
+ /* See the examples in Partition VI, Annex B */
+ encode_field_or_prop_type (&type->data.klass->byval_arg, p, &p);
+ }
+
+ *retp = p;
+}
+
+static void
+encode_named_val (MonoReflectionAssembly *assembly, char *buffer, char *p, char **retbuffer, char **retp, guint32 *buflen, MonoType *type, char *name, MonoObject *value)
+{
+ int len;
+ /* Preallocate a large enough buffer */
+ if (type->type == MONO_TYPE_VALUETYPE && type->data.klass->enumtype) {
+ char *str = type_get_qualified_name (type, NULL);
+ len = strlen (str);
+ g_free (str);
+ } else if (type->type == MONO_TYPE_SZARRAY && type->data.klass->enumtype) {
+ char *str = type_get_qualified_name (&type->data.klass->byval_arg, NULL);
+ len = strlen (str);
+ g_free (str);
+ } else {
+ len = 0;
+ }
+ len += strlen (name);
+
+ if ((p-buffer) + 20 + len >= *buflen) {
+ char *newbuf;
+ *buflen *= 2;
+ *buflen += len;
+ newbuf = g_realloc (buffer, *buflen);
+ p = newbuf + (p-buffer);
+ buffer = newbuf;
}
+
+ encode_field_or_prop_type (type, p, &p);
+
len = strlen (name);
mono_metadata_encode_value (len, p, &p);
memcpy (p, name, len);
MONO_ARCH_SAVE_REGS;
if (strcmp (ctor->vtable->klass->name, "MonoCMethod")) {
- sig = ctor_builder_to_signature ((MonoReflectionCtorBuilder*)ctor);
+ /* sig is freed later so allocate it in the heap */
+ sig = ctor_builder_to_signature (NULL, (MonoReflectionCtorBuilder*)ctor);
} else {
sig = mono_method_signature (((MonoReflectionMethod*)ctor)->method);
}
+
g_assert (mono_array_length (ctorArgs) == sig->param_count);
buflen = 256;
p = buffer = g_malloc (buflen);
return result;
}
+#if HAVE_SGEN_GC
+static void* reflection_info_desc = NULL;
+#define MOVING_GC_REGISTER(addr) do { \
+ if (!reflection_info_desc) { \
+ gsize bmap = 1; \
+ reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1); \
+ } \
+ mono_gc_register_root ((addr), sizeof (gpointer), reflection_info_desc); \
+ } while (0)
+#else
+#define MOVING_GC_REGISTER(addr)
+#endif
+
/*
* mono_reflection_setup_internal_class:
* @tb: a TypeBuilder object
klass = mono_class_from_mono_type (tb->type.type);
klass->parent = NULL;
/* fool mono_class_setup_parent */
- g_free (klass->supertypes);
klass->supertypes = NULL;
mono_class_setup_parent (klass, parent);
mono_class_setup_mono_type (klass);
mono_loader_unlock ();
return;
}
-
- klass = g_new0 (MonoClass, 1);
+
+ klass = mono_mempool_alloc0 (tb->module->dynamic_image->image.mempool, sizeof (MonoClass));
klass->image = &tb->module->dynamic_image->image;
klass->inited = 1; /* we lie to the runtime */
- klass->name = mono_string_to_utf8 (tb->name);
- klass->name_space = mono_string_to_utf8 (tb->nspace);
+ klass->name = mono_string_to_utf8_mp (klass->image->mempool, tb->name);
+ 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;
klass->element_class = klass;
- klass->reflection_info = tb; /* need to pin. */
+
+ MOVING_GC_REGISTER (&klass->reflection_info);
+ klass->reflection_info = tb;
/* Put into cache so mono_class_get () will find it */
mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
return;
tb->generic_container = g_new0 (MonoGenericContainer, 1);
- tb->generic_container->klass = klass;
-
- tb->generic_container->context.container = tb->generic_container;
+ 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;
g_assert (klass->generic_container->type_params [i].owner);
}
- klass->generic_container->context.gclass = mono_get_shared_generic_class (klass->generic_container, TRUE);
+ klass->generic_container->context.class_inst = mono_get_shared_generic_inst (klass->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)
if (spec->data.custom_data.custom_name) {
mtype = mono_reflection_type_from_name (spec->data.custom_data.custom_name, klass->image);
if (mtype)
- minfo->marshaltyperef = mono_type_get_object (domain, mtype);
+ MONO_OBJECT_SETREF (minfo, marshaltyperef, mono_type_get_object (domain, mtype));
- minfo->marshaltype = mono_string_new (domain, spec->data.custom_data.custom_name);
+ MONO_OBJECT_SETREF (minfo, marshaltype, mono_string_new (domain, spec->data.custom_data.custom_name));
}
if (spec->data.custom_data.cookie)
- minfo->mcookie = mono_string_new (domain, spec->data.custom_data.cookie);
+ MONO_OBJECT_SETREF (minfo, mcookie, mono_string_new (domain, spec->data.custom_data.cookie));
break;
default:
MonoMethodNormal *pm;
MonoMarshalSpec **specs;
MonoReflectionMethodAux *method_aux;
+ MonoMemPool *mp;
+ 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
+ * malloc'd.
+ */
+ dynamic = rmb->refs != NULL;
+ mp = dynamic ? NULL : klass->image->mempool;
+
+ mono_loader_lock ();
+
if ((rmb->attrs & METHOD_ATTRIBUTE_PINVOKE_IMPL) ||
(rmb->iattrs & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL))
- m = (MonoMethod *)g_new0 (MonoMethodPInvoke, 1);
+ m = (MonoMethod *)mp_g_new0 (mp, MonoMethodPInvoke, 1);
else if (rmb->refs)
- m = (MonoMethod *)g_new0 (MonoMethodWrapper, 1);
+ m = (MonoMethod *)mp_g_new0 (mp, MonoMethodWrapper, 1);
else
- m = (MonoMethod *)g_new0 (MonoMethodNormal, 1);
+ m = (MonoMethod *)mp_g_new0 (mp, MonoMethodNormal, 1);
pm = (MonoMethodNormal*)m;
+ m->dynamic = dynamic;
m->slot = -1;
m->flags = rmb->attrs;
m->iflags = rmb->iattrs;
- m->name = mono_string_to_utf8 (rmb->name);
+ m->name = mp_string_to_utf8 (mp, rmb->name);
m->klass = klass;
m->signature = sig;
+ m->skip_visibility = rmb->skip_visibility;
if (rmb->table_idx)
m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
method_aux = g_new0 (MonoReflectionMethodAux, 1);
- method_aux->dllentry = g_strdup (mono_string_to_utf8 (rmb->dllentry));
- method_aux->dll = g_strdup (mono_string_to_utf8 (rmb->dll));
+ method_aux->dllentry = rmb->dllentry ? mono_string_to_utf8_mp (mp, rmb->dllentry) : mono_mempool_strdup (mp, m->name);
+ method_aux->dll = mono_string_to_utf8_mp (mp, rmb->dll);
- ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 1) | rmb->lasterr;
+ ((MonoMethodPInvoke*)m)->piflags = (rmb->native_cc << 8) | (rmb->charset ? (rmb->charset - 1) * 2 : 0) | rmb->extra_flags;
if (klass->image->dynamic)
g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+ mono_loader_unlock ();
+
return m;
- } else if (!m->klass->dummy &&
- !(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
+ } else if (!(m->flags & METHOD_ATTRIBUTE_ABSTRACT) &&
!(m->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
MonoMethodHeader *header;
guint32 code_size;
}
}
- header = g_malloc0 (sizeof (MonoMethodHeader) +
+ header = mp_g_malloc0 (mp, sizeof (MonoMethodHeader) +
(num_locals - MONO_ZERO_LEN_ARRAY) * sizeof (MonoType*));
header->code_size = code_size;
- header->code = g_malloc (code_size);
+ header->code = mp_g_malloc (mp, code_size);
memcpy ((char*)header->code, code, code_size);
header->max_stack = max_stack;
header->init_locals = rmb->init_locals;
MonoReflectionLocalBuilder *lb =
mono_array_get (rmb->ilgen->locals, MonoReflectionLocalBuilder*, i);
- header->locals [i] = g_new0 (MonoType, 1);
+ header->locals [i] = mp_g_new0 (mp, MonoType, 1);
memcpy (header->locals [i], lb->type->type, sizeof (MonoType));
}
int count = mono_array_length (rmb->generic_params);
MonoGenericContainer *container;
- pm->generic_container = container = rmb->generic_container;
+ 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 =
container->type_params [i] = *gp->type.type->data.generic_param;
}
+
+ if (klass->generic_container) {
+ container->parent = klass->generic_container;
+ container->context.class_inst = klass->generic_container->context.class_inst;
+ }
+ container->context.method_inst = mono_get_shared_generic_inst (container);
}
if (rmb->refs) {
m->wrapper_type = MONO_WRAPPER_DYNAMIC_METHOD;
- mw->method_data = data = g_new (gpointer, rmb->nrefs + 1);
+ mw->method_data = data = mp_g_new (mp, gpointer, rmb->nrefs + 1);
data [0] = GUINT_TO_POINTER (rmb->nrefs);
for (i = 0; i < rmb->nrefs; ++i)
data [i + 1] = rmb->refs [i];
/* Parameter info */
if (rmb->pinfo) {
if (!method_aux)
- method_aux = g_new0 (MonoReflectionMethodAux, 1);
- method_aux->param_names = g_new0 (char *, mono_method_signature (m)->param_count + 1);
+ method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
+ method_aux->param_names = mp_g_new0 (mp, char *, mono_method_signature (m)->param_count + 1);
for (i = 0; i <= m->signature->param_count; ++i) {
MonoReflectionParamBuilder *pb;
if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
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]->attrs = pb->attrs;
}
- if (pb->def_value) {
+ if (pb->attrs & PARAM_ATTRIBUTE_HAS_DEFAULT) {
MonoDynamicImage *assembly;
guint32 idx, def_type, len;
char *p;
const char *p2;
if (!method_aux->param_defaults) {
- method_aux->param_defaults = g_new0 (guint8*, m->signature->param_count + 1);
- method_aux->param_default_types = g_new0 (guint32, m->signature->param_count + 1);
+ method_aux->param_defaults = mp_g_new0 (mp, guint8*, m->signature->param_count + 1);
+ method_aux->param_default_types = mp_g_new0 (mp, guint32, m->signature->param_count + 1);
}
assembly = (MonoDynamicImage*)klass->image;
idx = encode_constant (assembly, pb->def_value, &def_type);
p = assembly->blob.data + idx;
len = mono_metadata_decode_blob_size (p, &p2);
len += p2 - p;
- method_aux->param_defaults [i] = g_malloc (len);
+ method_aux->param_defaults [i] = mp_g_malloc (mp, len);
method_aux->param_default_types [i] = def_type;
memcpy ((gpointer)method_aux->param_defaults [i], p, len);
}
if (pb->name)
- method_aux->param_names [i] = mono_string_to_utf8 (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 = g_new0 (MonoCustomAttrInfo*, m->signature->param_count + 1);
+ method_aux->param_cattr = mp_g_new0 (mp, MonoCustomAttrInfo*, m->signature->param_count + 1);
method_aux->param_cattr [i] = mono_custom_attrs_from_builders (klass->image, pb->cattrs);
}
}
if ((pb = mono_array_get (rmb->pinfo, MonoReflectionParamBuilder*, i))) {
if (pb->marshal_info) {
if (specs == NULL)
- specs = g_new0 (MonoMarshalSpec*, sig->param_count + 1);
+ specs = mp_g_new0 (mp, MonoMarshalSpec*, sig->param_count + 1);
specs [pb->position] =
mono_marshal_spec_from_builder (klass->image->assembly, pb->marshal_info);
}
}
if (specs != NULL) {
if (!method_aux)
- method_aux = g_new0 (MonoReflectionMethodAux, 1);
+ method_aux = mp_g_new0 (mp, MonoReflectionMethodAux, 1);
method_aux->param_marshall = specs;
}
if (klass->image->dynamic && method_aux)
g_hash_table_insert (((MonoDynamicImage*)klass->image)->method_aux_hash, m, method_aux);
+ mono_loader_unlock ();
+
return m;
}
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
- sig = ctor_builder_to_signature (mb);
+ mono_loader_lock ();
+ sig = ctor_builder_to_signature (klass->image->mempool, mb);
+ mono_loader_unlock ();
reflection_methodbuilder_from_ctor_builder (&rmb, mb);
ReflectionMethodBuilder rmb;
MonoMethodSignature *sig;
- sig = method_builder_to_signature (mb);
+ mono_loader_lock ();
+ sig = method_builder_to_signature (klass->image->mempool, mb);
+ mono_loader_unlock ();
reflection_methodbuilder_from_method_builder (&rmb, mb);
const char *p, *p2;
guint32 len, idx;
- if (fb->handle)
- return fb->handle;
-
field = g_new0 (MonoClassField, 1);
field->name = mono_string_to_utf8 (fb->name);
field->type = fb->type->type;
}
if ((fb->attrs & FIELD_ATTRIBUTE_HAS_FIELD_RVA) && fb->rva_data)
- field->data = mono_array_addr (fb->rva_data, char, 0);
+ field->data = mono_array_addr (fb->rva_data, char, 0); /* FIXME: GC pin array */
if (fb->offset != -1)
field->offset = fb->offset;
field->parent = klass;
- fb->handle = field;
mono_save_custom_attrs (klass->image, field, fb->cattrs);
if (fb->def_value) {
return field;
}
-static MonoType*
-do_mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types,
- MonoType *parent)
+MonoType*
+mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
{
MonoClass *klass;
MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericClass *gclass, *cached;
- MonoDynamicGenericClass *dgclass = NULL;
gboolean is_dynamic = FALSE;
MonoDomain *domain;
- MonoType *geninst;
- int icount, i;
-
- klass = mono_class_from_mono_type (type->type);
- if (!klass->generic_container && !klass->generic_class &&
- !(klass->nested_in && klass->nested_in->generic_container))
- return NULL;
+ MonoClass *geninst;
mono_loader_lock ();
if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
tb = (MonoReflectionTypeBuilder *) type;
- icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
is_dynamic = TRUE;
} else if (!strcmp (((MonoObject *) type)->vtable->klass->name, "MonoGenericClass")) {
MonoReflectionGenericClass *rgi = (MonoReflectionGenericClass *) type;
g_assert (!strcmp (((MonoObject *) rgt)->vtable->klass->name, "TypeBuilder"));
tb = (MonoReflectionTypeBuilder *) rgt;
- icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
is_dynamic = TRUE;
- } else {
- icount = klass->interface_count;
- }
-
- if (is_dynamic) {
- dgclass = g_new0 (MonoDynamicGenericClass, 1);
- gclass = &dgclass->generic_class;
- gclass->is_dynamic = TRUE;
- } else
- gclass = g_new0 (MonoGenericClass, 1);
-
- gclass->inst = g_new0 (MonoGenericInst, 1);
-
- gclass->inst->type_argc = type_argc;
- gclass->inst->type_argv = types;
- gclass->inst->is_reference = 1;
-
- for (i = 0; i < gclass->inst->type_argc; ++i) {
- if (!gclass->inst->is_open)
- gclass->inst->is_open = mono_class_is_open_constructed_type (types [i]);
- if (gclass->inst->is_reference)
- gclass->inst->is_reference = MONO_TYPE_IS_REFERENCE (types [i]);
- }
-
- gclass->container_class = klass;
-
- if (klass->generic_class) {
- MonoGenericClass *kgclass = klass->generic_class;
- MonoGenericClass *ogclass = gclass;
-
- ogclass->context = g_new0 (MonoGenericContext, 1);
- ogclass->context->container = ogclass->container_class->generic_container;
- ogclass->context->gclass = ogclass;
-
- if (is_dynamic) {
- dgclass = g_new0 (MonoDynamicGenericClass, 1);
- gclass = &dgclass->generic_class;
- gclass->is_dynamic = TRUE;
- } else
- gclass = g_new0 (MonoGenericClass, 1);
-
- 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, ogclass->context);
-
- 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->container_class = kgclass->container_class;
}
- geninst = g_new0 (MonoType, 1);
- geninst->type = MONO_TYPE_GENERICINST;
+ /* FIXME: fix the CreateGenericParameters protocol to avoid the two stage setup of TypeBuilders */
+ if (tb && tb->generic_container)
+ mono_reflection_create_generic_class (tb);
- cached = mono_metadata_lookup_generic_class (gclass);
- if (cached) {
- g_free (gclass);
+ klass = mono_class_from_mono_type (type->type);
+ if (!klass->generic_container) {
mono_loader_unlock ();
- geninst->data.generic_class = cached;
- return geninst;
+ return NULL;
}
- geninst->data.generic_class = gclass;
-
- gclass->parent = parent;
-
- gclass->context = g_new0 (MonoGenericContext, 1);
- gclass->context->container = gclass->container_class->generic_container;
- gclass->context->gclass = gclass;
-
- gclass->ifaces = g_new0 (MonoType *, icount);
- gclass->count_ifaces = icount;
-
- for (i = 0; i < icount; i++) {
- MonoReflectionType *itype;
+ if (klass->wastypebuilder) {
+ tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
- if (tb)
- itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
- else
- itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
- gclass->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
- if (!gclass->ifaces [i])
- gclass->ifaces [i] = itype->type;
+ is_dynamic = TRUE;
}
- mono_class_create_generic (gclass);
-
mono_loader_unlock ();
- return geninst;
+ geninst = mono_class_bind_generic_parameters (klass, type_argc, types, is_dynamic);
+
+ return &geninst->byval_arg;
}
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
+MonoClass*
+mono_class_bind_generic_parameters (MonoClass *klass, int type_argc, MonoType **types, gboolean is_dynamic)
{
- MonoClass *klass, *pklass = NULL;
- MonoReflectionType *parent = NULL;
- MonoType *the_parent = NULL, *geninst;
- MonoReflectionTypeBuilder *tb = NULL;
MonoGenericClass *gclass;
- MonoDomain *domain;
+ MonoGenericInst *inst;
+ int i;
- domain = mono_object_domain (type);
- klass = mono_class_from_mono_type (type->type);
+ g_assert (klass->generic_container);
- if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
- tb = (MonoReflectionTypeBuilder *) type;
+ inst = g_new0 (MonoGenericInst, 1);
+ inst->type_argc = type_argc;
+ inst->type_argv = g_new0 (MonoType *, inst->type_argc);
- if (tb->parent) {
- parent = tb->parent;
- pklass = mono_class_from_mono_type (parent->type);
- }
- } else {
- pklass = klass->parent;
- if (pklass)
- parent = mono_type_get_object (domain, &pklass->byval_arg);
- else if (klass->generic_class && klass->generic_class->parent) {
- parent = mono_type_get_object (domain, klass->generic_class->parent);
- pklass = mono_class_from_mono_type (klass->generic_class->parent);
- }
- }
+ for (i = 0; i < inst->type_argc; ++i) {
+ MonoType *t = dup_type (types [i]);
- if (pklass && pklass->generic_class)
- the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
+ if (!inst->is_open)
+ inst->is_open = mono_class_is_open_constructed_type (t);
- geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent);
- if (!geninst)
- return NULL;
+ inst->type_argv [i] = t;
+ }
- gclass = geninst->data.generic_class;
+ inst = mono_metadata_lookup_generic_inst (inst);
+ gclass = mono_metadata_lookup_generic_class (klass, inst, is_dynamic);
- return geninst;
+ return mono_generic_class_get_class (gclass);
}
static inline MonoType*
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;
}
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;
int count, i;
method = rmethod->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 = ((MonoMethodNormal*) method)->generic_container;
+ 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);
+ (GHashFunc) mono_metadata_generic_context_hash,
+ (GCompareFunc) mono_metadata_generic_context_equal);
ginst = g_new0 (MonoGenericInst,1 );
ginst->type_argc = count;
ginst->type_argv = g_new0 (MonoType *, count);
- ginst->is_reference = 1;
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]);
}
ginst = mono_metadata_lookup_generic_inst (ginst);
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->container = container;
- gmethod->inst = ginst;
-
- inflated = g_hash_table_lookup (container->method_hash, gmethod);
- if (inflated) {
- g_free (gmethod);
+ 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, &tmp_context);
+ if (inflated)
return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
- }
- gmethod->reflection_info = rmethod;
+ inflated = mono_class_inflate_generic_method (method, &tmp_context);
+ imethod = (MonoMethodInflated *) inflated;
- context = g_new0 (MonoGenericContext, 1);
- context->container = container;
- context->gclass = method->klass->generic_class;
- context->gmethod = gmethod;
+ MOVING_GC_REGISTER (&imethod->reflection_info);
+ imethod->reflection_info = rmethod;
- inflated = mono_class_inflate_generic_method (method, context, NULL);
- g_hash_table_insert (container->method_hash, gmethod, inflated);
+ g_hash_table_insert (container->method_hash, mono_method_get_context (inflated), inflated);
return mono_method_get_object (mono_object_domain (rmethod), inflated, NULL);
}
static MonoMethod *
inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
{
- MonoGenericMethod *gmethod;
- MonoGenericClass *gclass;
+ MonoMethodInflated *imethod;
+ MonoGenericContext tmp_context;
MonoGenericContext *context;
- int i;
-
- gclass = type->type.type->data.generic_class;
-
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->inst = g_new0 (MonoGenericInst, 1);
- gmethod->reflection_info = obj;
+ MonoClass *klass;
- gmethod->inst->type_argc = mono_method_signature (method)->generic_param_count;
- gmethod->inst->type_argv = g_new0 (MonoType *, gmethod->inst->type_argc);
+ klass = mono_class_from_mono_type (type->type.type);
+ g_assert (klass->generic_class);
+ context = mono_class_get_context (klass);
- for (i = 0; i < gmethod->inst->type_argc; i++) {
- MonoMethodNormal *mn = (MonoMethodNormal *) method;
- MonoGenericParam *gparam = &mn->generic_container->type_params [i];
+ if (method->generic_container) {
+ g_assert (method->klass == klass->generic_class->container_class);
- g_assert (gparam->pklass);
- gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
+ tmp_context.class_inst = klass->generic_class->context.class_inst;
+ tmp_context.method_inst = method->generic_container->context.method_inst;
+ context = &tmp_context;
}
- context = g_new0 (MonoGenericContext, 1);
- context->container = gclass->container_class->generic_container;
- context->gclass = gclass;
- context->gmethod = gmethod;
-
- return mono_class_inflate_generic_method (method, context, gclass->klass);
+ 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 (MonoMethod *) imethod;
}
static MonoMethod *
inflate_method (MonoReflectionGenericClass *type, MonoObject *obj)
{
MonoMethod *method;
- MonoClass *klass;
+ MonoClass *gklass;
- klass = mono_class_from_mono_type (type->type.type);
+ gklass = mono_class_from_mono_type (type->generic_type->type);
if (!strcmp (obj->vtable->klass->name, "MethodBuilder"))
- method = methodbuilder_to_mono_method (klass, (MonoReflectionMethodBuilder *) obj);
+ method = methodbuilder_to_mono_method (gklass, (MonoReflectionMethodBuilder *) obj);
else if (!strcmp (obj->vtable->klass->name, "ConstructorBuilder"))
- method = ctorbuilder_to_mono_method (klass, (MonoReflectionCtorBuilder *) obj);
+ method = ctorbuilder_to_mono_method (gklass, (MonoReflectionCtorBuilder *) obj);
else if (!strcmp (obj->vtable->klass->name, "MonoMethod") || !strcmp (obj->vtable->klass->name, "MonoCMethod"))
method = ((MonoReflectionMethod *) obj)->method;
else {
{
MonoGenericClass *gclass;
MonoDynamicGenericClass *dgclass;
- MonoClass *klass, *gklass, *pklass;
+ MonoClass *klass, *gklass;
int i;
MONO_ARCH_SAVE_REGS;
gklass = gclass->container_class;
mono_class_init (gklass);
- if (gclass->parent)
- pklass = mono_class_from_mono_type (gclass->parent);
- else
- pklass = gklass->parent;
-
- mono_class_setup_parent (klass, pklass);
-
dgclass->count_methods = methods ? mono_array_length (methods) : 0;
dgclass->count_ctors = ctors ? mono_array_length (ctors) : 0;
dgclass->count_fields = fields ? mono_array_length (fields) : 0;
ifield = g_new0 (MonoInflatedField, 1);
ifield->generic_type = field->type;
+ MOVING_GC_REGISTER (&ifield->reflection_info);
ifield->reflection_info = obj;
dgclass->fields [i] = *field;
+ dgclass->fields [i].parent = klass;
dgclass->fields [i].generic_info = ifield;
- dgclass->fields [i].type = mono_class_inflate_generic_type (field->type, gclass->context);
+ dgclass->fields [i].type = mono_class_inflate_generic_type (
+ field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
}
for (i = 0; i < dgclass->count_properties; i++) {
ensure_runtime_vtable (MonoClass *klass)
{
MonoReflectionTypeBuilder *tb = klass->reflection_info;
- int i, num, j, onum;
- MonoMethod **overrides;
+ int i, num, j;
if (!tb || klass->wastypebuilder)
return;
num = tb->ctors? mono_array_length (tb->ctors): 0;
num += tb->num_methods;
klass->method.count = num;
- klass->methods = g_new (MonoMethod*, num);
+ klass->methods = mono_mempool_alloc (klass->image->mempool, sizeof (MonoMethod*) * num);
num = tb->ctors? mono_array_length (tb->ctors): 0;
for (i = 0; i < num; ++i)
klass->methods [i] = ctorbuilder_to_mono_method (klass, mono_array_get (tb->ctors, MonoReflectionCtorBuilder*, i));
if (tb->interfaces) {
klass->interface_count = mono_array_length (tb->interfaces);
- klass->interfaces = g_new (MonoClass*, klass->interface_count);
+ klass->interfaces = mono_mempool_alloc (klass->image->mempool, sizeof (MonoClass*) * klass->interface_count);
for (i = 0; i < klass->interface_count; ++i) {
MonoReflectionType *iface = mono_array_get (tb->interfaces, gpointer, i);
klass->interfaces [i] = mono_class_from_mono_type (iface->type);
}
}
- if (klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+ if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
for (i = 0; i < klass->method.count; ++i)
klass->methods [i]->slot = i;
+
+ mono_class_setup_interface_offsets (klass);
+ }
+
+ /*
+ * The generic vtable is needed even if image->run is not set since some
+ * runtime code like ves_icall_Type_GetMethodsByName depends on
+ * method->slot being defined.
+ */
+
+ /*
+ * tb->methods could not be freed since it is used for determining
+ * overrides during dynamic vtable construction.
+ */
+}
+
+void
+mono_reflection_get_dynamic_overrides (MonoClass *klass, MonoMethod ***overrides, int *num_overrides)
+{
+ MonoReflectionTypeBuilder *tb;
+ int i, onum;
+
+ *overrides = NULL;
+ *num_overrides = 0;
- if (!((MonoDynamicImage*)klass->image)->run)
- /* No need to create a generic vtable */
+ g_assert (klass->image->dynamic);
+
+ if (!klass->reflection_info)
return;
- /* Overrides */
+ g_assert (strcmp (((MonoObject*)klass->reflection_info)->vtable->klass->name, "TypeBuilder") == 0);
+
+ tb = (MonoReflectionTypeBuilder*)klass->reflection_info;
+
onum = 0;
if (tb->methods) {
for (i = 0; i < tb->num_methods; ++i) {
}
}
- overrides = g_new0 (MonoMethod*, onum * 2);
+ if (onum) {
+ *overrides = g_new0 (MonoMethod*, onum * 2);
- if (tb->methods) {
onum = 0;
for (i = 0; i < tb->num_methods; ++i) {
MonoReflectionMethodBuilder *mb =
mono_array_get (tb->methods, MonoReflectionMethodBuilder*, i);
if (mb->override_method) {
- /* FIXME: What if 'override_method' is a MethodBuilder ? */
- overrides [onum * 2] =
+ (*overrides) [onum * 2] =
mb->override_method->method;
- overrides [onum * 2 + 1] =
+ (*overrides) [onum * 2 + 1] =
mb->mhandle;
+ /* FIXME: What if 'override_method' is a MethodBuilder ? */
+ g_assert (mb->override_method->method);
g_assert (mb->mhandle);
onum ++;
}
}
- mono_class_setup_vtable_general (klass, overrides, onum);
- g_free (overrides);
+ *num_overrides = onum;
}
static void
klass->field.count = tb->num_fields;
klass->field.first = 0;
- klass->field.last = klass->field.count;
if (!klass->field.count)
return;
klass->property.count = tb->properties ? mono_array_length (tb->properties) : 0;
klass->property.first = 0;
- klass->property.last = klass->property.count;
klass->properties = g_new0 (MonoProperty, klass->property.count);
for (i = 0; i < klass->property.count; ++i) {
klass->properties [i].get = pb->get_method->mhandle;
if (pb->set_method)
klass->properties [i].set = pb->set_method->mhandle;
+
+ mono_save_custom_attrs (klass->image, &klass->properties [i], pb->cattrs);
}
}
klass->event.count = tb->events ? mono_array_length (tb->events) : 0;
klass->event.first = 0;
- klass->event.last = klass->event.count;
klass->events = g_new0 (MonoEvent, klass->event.count);
for (i = 0; i < klass->event.count; ++i) {
mono_reflection_create_runtime_class (MonoReflectionTypeBuilder *tb)
{
MonoClass *klass;
+ MonoDomain* domain;
MonoReflectionType* res;
int i;
MONO_ARCH_SAVE_REGS;
+ domain = mono_object_domain (tb);
klass = my_mono_class_from_mono_type (tb->type.type);
mono_save_custom_attrs (klass->image, klass, tb->cattrs);
-
+
+ /*
+ * we need to lock the domain because the lock will be taken inside
+ * So, we need to keep the locking order correct.
+ */
+ mono_domain_lock (domain);
mono_loader_lock ();
if (klass->wastypebuilder) {
mono_loader_unlock ();
+ mono_domain_unlock (domain);
return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
}
/*
klass->has_cctor = 1;
klass->has_finalize = 1;
+#if 0
if (!((MonoDynamicImage*)klass->image)->run) {
if (klass->generic_container) {
/* FIXME: The code below can't handle generic classes */
klass->wastypebuilder = TRUE;
mono_loader_unlock ();
+ mono_domain_unlock (domain);
return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
}
}
+#endif
/* enums are done right away */
if (!klass->enumtype)
if (klass->parent) {
if (!klass->parent->size_inited)
mono_class_init (klass->parent);
- klass->instance_size += klass->parent->instance_size;
- klass->class_size += klass->parent->class_size;
+ klass->instance_size = klass->parent->instance_size;
+ klass->sizes.class_size = 0;
klass->min_align = klass->parent->min_align;
/* if the type has no fields we won't call the field_setup
* routine which sets up klass->has_references.
typebuilder_setup_properties (klass);
typebuilder_setup_events (klass);
-
+
klass->wastypebuilder = TRUE;
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);
+
return res;
}
gparam->mbuilder->generic_container = g_new0 (MonoGenericContainer, 1);
param->owner = gparam->mbuilder->generic_container;
} else if (gparam->tbuilder) {
- MonoReflectionTypeBuilder *nesting = (MonoReflectionTypeBuilder*) gparam->tbuilder->nesting_type;
- MonoGenericContainer *container = gparam->tbuilder->generic_container;
-
- while (nesting) {
- int count;
-
- count = nesting->generic_params ? mono_array_length (nesting->generic_params) : 0;
- if (gparam->index >= count)
- break;
-
- container = nesting->generic_container;
- nesting = (MonoReflectionTypeBuilder*) nesting->nesting_type;
- }
-
- g_assert (container);
- param->owner = container;
+ 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;
image = &gparam->tbuilder->module->dynamic_image->image;
mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
- param->pklass->reflection_info = gparam;
+ MOVING_GC_REGISTER (¶m->pklass->reflection_info);
+ param->pklass->reflection_info = gparam; /* FIXME: GC pin gparam */
gparam->type.type = g_new0 (MonoType, 1);
gparam->type.type->type = gparam->mbuilder ? MONO_TYPE_MVAR : MONO_TYPE_VAR;
guint32 na = mono_array_length (sig->arguments);
guint32 buflen, i;
MonoArray *result;
- char *buf, *p;
-
- MONO_ARCH_SAVE_REGS;
+ SigBuffer buf;
- p = buf = g_malloc (10 + na * 10);
+ 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;
+ 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;
}
guint32 na = mono_array_length (sig->arguments);
guint32 buflen, i;
MonoArray *result;
- char *buf, *p;
-
- MONO_ARCH_SAVE_REGS;
+ SigBuffer buf;
- p = buf = g_malloc (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;
+ 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;
+ GSList *l;
int i;
sig = dynamic_method_to_signature (mb);
/*
* Resolve references.
*/
+ /*
+ * Every second entry in the refs array is reserved for storing handle_class,
+ * which is needed by the ldtoken implementation in the JIT.
+ */
rmb.nrefs = mb->nrefs;
rmb.refs = g_new0 (gpointer, mb->nrefs + 1);
- for (i = 0; i < mb->nrefs; ++i) {
+ 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));
- 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);
+ if (!ref) {
+ g_free (rmb.refs);
+ mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
+ return;
+ }
}
- rmb.refs [i] = ref;
+
+ 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);
+ /* 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);
/* ilgen is no longer needed */
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:
*
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) {
- result = ((MonoReflectionMethod*)obj)->method;
- *handle_class = mono_defaults.methodhandle_class;
- g_assert (result);
- } else if (strcmp (obj->vtable->klass->name, "MonoCMethod") == 0) {
+ } else if (strcmp (obj->vtable->klass->name, "MonoMethod") == 0 ||
+ strcmp (obj->vtable->klass->name, "MonoCMethod") == 0 ||
+ strcmp (obj->vtable->klass->name, "MonoGenericCMethod") == 0 ||
+ strcmp (obj->vtable->klass->name, "MonoGenericMethod") == 0) {
result = ((MonoReflectionMethod*)obj)->method;
*handle_class = mono_defaults.methodhandle_class;
g_assert (result);
result = sig;
*handle_class = NULL;
+ } else if (strcmp (obj->vtable->klass->name, "DynamicMethod") == 0) {
+ MonoReflectionDynamicMethod *method = (MonoReflectionDynamicMethod*)obj;
+ /* Already created by the managed code */
+ g_assert (method->mhandle);
+ result = method->mhandle;
+ *handle_class = mono_defaults.methodhandle_class;
} 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];
return FALSE;
/* we want the original as the wrapper is "free" of the security informations */
- if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
method = mono_marshal_method_from_wrapper (method);
if (!method)
return FALSE;
return FALSE;
/* we want the original as the wrapper is "free" of the security informations */
- if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
method = mono_marshal_method_from_wrapper (method);
if (!method)
return FALSE;
return FALSE;
/* we want the original as the wrapper is "free" of the security informations */
- if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE) {
+ if (method->wrapper_type == MONO_WRAPPER_MANAGED_TO_NATIVE || method->wrapper_type == MONO_WRAPPER_MANAGED_TO_MANAGED) {
method = mono_marshal_method_from_wrapper (method);
if (!method)
return FALSE;
}
gboolean
-mono_reflection_call_is_assignable_from (MonoClass *klass, MonoClass *oklass)
+mono_reflection_call_is_assignable_to (MonoClass *klass, MonoClass *oklass)
{
MonoObject *res, *exc;
void *params [1];
+ static MonoClass *System_Reflection_Emit_TypeBuilder = NULL;
static MonoMethod *method = NULL;
+ if (!System_Reflection_Emit_TypeBuilder) {
+ System_Reflection_Emit_TypeBuilder = mono_class_from_name (mono_defaults.corlib, "System.Reflection.Emit", "TypeBuilder");
+ g_assert (System_Reflection_Emit_TypeBuilder);
+ }
if (method == NULL) {
- method = mono_class_get_method_from_name (mono_defaults.monotype_class->parent, "IsAssignableFrom", 1);
+ method = mono_class_get_method_from_name (System_Reflection_Emit_TypeBuilder, "IsAssignableTo", 1);
g_assert (method);
}
+ /*
+ * The result of mono_type_get_object () might be a System.MonoType but we
+ * need a TypeBuilder so use klass->reflection_info.
+ */
+ g_assert (klass->reflection_info);
+ g_assert (!strcmp (((MonoObject*)(klass->reflection_info))->vtable->klass->name, "TypeBuilder"));
+
params [0] = mono_type_get_object (mono_domain_get (), &oklass->byval_arg);
- res = mono_runtime_invoke (method, mono_type_get_object (mono_domain_get (), &klass->byval_arg), params, &exc);
+ res = mono_runtime_invoke (method, (MonoObject*)(klass->reflection_info), params, &exc);
if (exc)
return FALSE;
else
return *(MonoBoolean*)mono_object_unbox (res);
}
-