MonoObject *type;
MonoString *name;
MonoBoolean init_locals;
+ MonoMethod *mhandle;
} ReflectionMethodBuilder;
const unsigned char table_sizes [64] = {
0 /* 0x2A */
};
+/**
+ * These macros can be used to allocate long living atomic data so it won't be
+ * tracked by the garbage collector.
+ */
+#ifdef HAVE_BOEHM_GC
+#define ALLOC_ATOMIC(size) GC_MALLOC_ATOMIC (size)
+#define FREE_ATOMIC(ptr)
+#define REALLOC_ATOMIC(ptr, size) GC_REALLOC ((ptr), (size))
+#else
+#define ALLOC_ATOMIC(size) g_malloc (size)
+#define FREE_ATOMIC(ptr) g_free (ptr)
+#define REALLOC_ATOMIC(ptr, size) g_realloc ((ptr), (size))
+#endif
+
static guint32 mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type);
static guint32 mono_image_get_methodref_token (MonoDynamicAssembly *assembly, MonoMethod *method);
static guint32 mono_image_get_sighelper_token (MonoDynamicAssembly *assembly, MonoReflectionSigHelper *helper);
{
table->rows = nrows;
g_assert (table->columns);
- table->values = g_realloc (table->values, (1 + table->rows) * table->columns * sizeof (guint32));
+ if (nrows + 1 >= table->alloc_rows) {
+ while (nrows + 1 >= table->alloc_rows)
+ if (table->alloc_rows == 0)
+ table->alloc_rows = 16;
+ else
+ table->alloc_rows *= 2;
+
+ table->values = REALLOC_ATOMIC (table->values, (table->alloc_rows) * table->columns * sizeof (guint32));
+ }
}
+static void
+make_room_in_stream (MonoDynamicStream *stream, int size)
+{
+ while (stream->alloc_size <= size) {
+ if (stream->alloc_size < 4096)
+ stream->alloc_size = 4096;
+ else
+ stream->alloc_size *= 2;
+ }
+ stream->data = REALLOC_ATOMIC (stream->data, stream->alloc_size);
+}
+
static guint32
string_heap_insert (MonoDynamicStream *sh, const char *str)
{
len = strlen (str) + 1;
idx = sh->index;
- if (idx + len > sh->alloc_size) {
- sh->alloc_size += len + 4096;
- sh->data = g_realloc (sh->data, sh->alloc_size);
- }
+ if (idx + len > sh->alloc_size)
+ make_room_in_stream (sh, idx + len);
+
/*
* We strdup the string even if we already copy them in sh->data
* so that the string pointers in the hash remain valid even if
{
sh->index = 0;
sh->alloc_size = 4096;
- sh->data = g_malloc (4096);
+ sh->data = ALLOC_ATOMIC (4096);
sh->hash = g_hash_table_new (g_str_hash, g_str_equal);
string_heap_insert (sh, "");
}
static void
string_heap_free (MonoDynamicStream *sh)
{
- g_free (sh->data);
+ FREE_ATOMIC (sh->data);
g_hash_table_foreach (sh->hash, (GHFunc)g_free, NULL);
g_hash_table_destroy (sh->hash);
}
mono_image_add_stream_data (MonoDynamicStream *stream, const char *data, guint32 len)
{
guint32 idx;
- if (stream->alloc_size < stream->index + len) {
- stream->alloc_size += len + 4096;
- stream->data = g_realloc (stream->data, stream->alloc_size);
- }
+ if (stream->alloc_size < stream->index + len)
+ make_room_in_stream (stream, stream->index + len);
memcpy (stream->data + stream->index, data, len);
idx = stream->index;
stream->index += len;
mono_image_add_stream_zero (MonoDynamicStream *stream, guint32 len)
{
guint32 idx;
- if (stream->alloc_size < stream->index + len) {
- stream->alloc_size += len + 4096;
- stream->data = g_realloc (stream->data, stream->alloc_size);
- }
+ if (stream->alloc_size < stream->index + len)
+ make_room_in_stream (stream, stream->index + len);
memset (stream->data + stream->index, 0, len);
idx = stream->index;
stream->index += len;
guint len, h;
const char *end;
len = mono_metadata_decode_blob_size (str, &str);
- end = str + len;
- h = *str;
- for (str += 1; str < end; str++)
- h = (h << 5) - h + *str;
- return h;
+ if (len > 0) {
+ end = str + len;
+ h = *str;
+ for (str += 1; str < end; str++)
+ h = (h << 5) - h + *str;
+ return h;
+ }
+ else
+ return 0;
}
static gboolean
char *copy;
gpointer oldkey, oldval;
- copy = g_malloc (s1+s2);
+ copy = ALLOC_ATOMIC (s1+s2);
memcpy (copy, b1, s1);
memcpy (copy + s1, b2, s2);
- if (g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
- g_free (copy);
+ if (mono_g_hash_table_lookup_extended (assembly->blob_cache, copy, &oldkey, &oldval)) {
+ FREE_ATOMIC (copy);
idx = GPOINTER_TO_UINT (oldval);
} else {
idx = mono_image_add_stream_data (&assembly->blob, b1, s1);
mono_image_add_stream_data (&assembly->blob, b2, s2);
- g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
+ mono_g_hash_table_insert (assembly->blob_cache, copy, GUINT_TO_POINTER (idx));
}
return idx;
}
guint32 idx;
char blob_size [6];
char *b = blob_size;
-
+
+ if (!assembly->save)
+ return 0;
+
p = buf = g_malloc (size);
/*
* FIXME: vararg, explicit_this, differenc call_conv values...
clauses = g_new0 (MonoExceptionClause, num_clauses);
clause_index = 0;
- for (i = 0; i < mono_array_length (ilgen->ex_handlers); ++i) {
+ 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);
num_exception = method_count_clauses (mb->ilgen);
} else {
code = mb->code;
+ if (code == NULL)
+ mono_raise_exception (mono_get_exception_argument (NULL, "a method does not have any IL associated"));
+
code_size = mono_array_length (code);
max_stack = 8; /* we probably need to run a verifier on the code... */
}
return 0;
}
-typedef struct {
- MonoMethod *ctor;
- guint32 data_size;
- guchar* data;
-} CustomAttrEntry;
-
-typedef struct {
- int num_attrs;
- MonoImage *image;
- CustomAttrEntry attrs [MONO_ZERO_LEN_ARRAY];
-} CustomAttrInfo;
-
static GHashTable *dynamic_custom_attrs = NULL;
-static void
-mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+static MonoCustomAttrInfo*
+mono_custom_attrs_from_builders (MonoImage *image, MonoArray *cattrs)
{
int i, count;
- CustomAttrInfo *ainfo;
+ MonoCustomAttrInfo *ainfo;
MonoReflectionCustomAttr *cattr;
if (!cattrs)
- return;
+ return NULL;
/* FIXME: check in assembly the Run flag is set */
count = mono_array_length (cattrs);
- ainfo = g_malloc0 (sizeof (CustomAttrInfo) + sizeof (CustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
+ ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (count - MONO_ZERO_LEN_ARRAY));
ainfo->image = image;
ainfo->num_attrs = count;
ainfo->attrs [i].data_size = mono_array_length (cattr->data);
}
+ return ainfo;
+}
+
+static void
+mono_save_custom_attrs (MonoImage *image, void *obj, MonoArray *cattrs)
+{
+ MonoCustomAttrInfo *ainfo = mono_custom_attrs_from_builders (image, cattrs);
+
+ if (!ainfo)
+ return;
+
if (!dynamic_custom_attrs)
dynamic_custom_attrs = g_hash_table_new (NULL, NULL);
g_hash_table_insert (dynamic_custom_attrs, obj, ainfo);
}
+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);
+}
+
/*
* idx is the table index of the object
* type is one of CUSTOM_ATTR_*
/* room in this table is already allocated */
table = &assembly->tables [MONO_TABLE_METHOD];
*mb->table_idx = table->next_idx ++;
+ mono_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;
if (mb->name) {
name = mono_string_to_utf8 (mb->name);
rmb.name = mb->name;
rmb.table_idx = &mb->table_idx;
rmb.init_locals = mb->init_locals;
+ rmb.mhandle = mb->mhandle;
mono_image_basic_method (&rmb, assembly);
table->rows ++;
alloc_table (table, table->rows);
values = table->values + table->rows * MONO_IMPLMAP_SIZE;
- values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | mb->charset;
+ /* map CharSet values to on-disk values */
+ values [MONO_IMPLMAP_FLAGS] = (mb->native_cc << 8) | (mb->charset ? (mb->charset - 1) * 2: 1);
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);
rmb.name = NULL;
rmb.table_idx = &mb->table_idx;
rmb.init_locals = mb->init_locals;
+ rmb.mhandle = mb->mhandle;
mono_image_basic_method (&rmb, assembly);
char *p;
char* buf;
guint32 idx;
-
+
+ if (!assembly->save)
+ return 0;
+
p = buf = g_malloc (64);
mono_metadata_encode_value (0x06, p, &p);
fb->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
table = &assembly->tables [MONO_TABLE_FIELD];
fb->table_idx = table->next_idx ++;
+ mono_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);
default:
return 0;
}
-
- 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);
table = &assembly->tables [MONO_TABLE_TYPESPEC];
- alloc_table (table, table->rows + 1);
- values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
- values [MONO_TYPESPEC_SIGNATURE] = token;
+ 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);
+ alloc_table (table, table->rows + 1);
+ values = table->values + table->next_idx * MONO_TYPESPEC_SIZE;
+ values [MONO_TYPESPEC_SIGNATURE] = token;
+ }
token = TYPEDEFORREF_TYPESPEC | (table->next_idx << TYPEDEFORREF_BITS);
g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
* Despite the name, we handle also TypeSpec (with the above helper).
*/
static guint32
-mono_image_typedef_or_ref_aux (MonoDynamicAssembly *assembly, MonoType *type,
- gboolean force_ref)
+mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
{
MonoDynamicTable *table;
guint32 *values;
/*
* If it's in the same module:
*/
- if (!force_ref && (klass->image == assembly->assembly.image)) {
+ if (klass->image == assembly->assembly.image) {
MonoReflectionTypeBuilder *tb = klass->reflection_info;
token = TYPEDEFORREF_TYPEDEF | (tb->table_idx << TYPEDEFORREF_BITS);
mono_g_hash_table_insert (assembly->tokens, GUINT_TO_POINTER (token), klass);
scope = resolution_scope_from_image (assembly, klass->image);
}
table = &assembly->tables [MONO_TABLE_TYPEREF];
- alloc_table (table, table->rows + 1);
- values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
- values [MONO_TYPEREF_SCOPE] = scope;
- values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
- values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+ if (assembly->save) {
+ alloc_table (table, table->rows + 1);
+ values = table->values + table->next_idx * MONO_TYPEREF_SIZE;
+ values [MONO_TYPEREF_SCOPE] = scope;
+ values [MONO_TYPEREF_NAME] = string_heap_insert (&assembly->sheap, klass->name);
+ values [MONO_TYPEREF_NAMESPACE] = string_heap_insert (&assembly->sheap, klass->name_space);
+ }
token = TYPEDEFORREF_TYPEREF | (table->next_idx << TYPEDEFORREF_BITS); /* typeref */
g_hash_table_insert (assembly->typeref, type, GUINT_TO_POINTER(token));
table->next_idx ++;
return token;
}
-static guint32
-mono_image_typedef_or_ref (MonoDynamicAssembly *assembly, MonoType *type)
-{
- return mono_image_typedef_or_ref_aux (assembly, type, FALSE);
-}
-
/*
* Insert a memberef row into the metadata: the token that point to the memberref
* is returned. Caching is done in the caller (mono_image_get_methodref_token() or
guint32 token, pclass;
guint32 parent;
- parent = mono_image_typedef_or_ref_aux (assembly, type, TRUE);
+ parent = mono_image_typedef_or_ref (assembly, type);
switch (parent & TYPEDEFORREF_MASK) {
case TYPEDEFORREF_TYPEREF:
pclass = MEMBERREF_PARENT_TYPEREF;
parent >>= TYPEDEFORREF_BITS;
table = &assembly->tables [MONO_TABLE_MEMBERREF];
- alloc_table (table, table->rows + 1);
- values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
- values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
- values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
- values [MONO_MEMBERREF_SIGNATURE] = sig;
+
+ if (assembly->save) {
+ alloc_table (table, table->rows + 1);
+ values = table->values + table->next_idx * MONO_MEMBERREF_SIZE;
+ values [MONO_MEMBERREF_CLASS] = pclass | (parent << MEMBERREF_PARENT_BITS);
+ values [MONO_MEMBERREF_NAME] = string_heap_insert (&assembly->sheap, name);
+ values [MONO_MEMBERREF_SIGNATURE] = sig;
+ }
+
token = MONO_TOKEN_MEMBER_REF | table->next_idx;
table->next_idx ++;
char blob_size [6];
char *b = blob_size;
+ if (!assembly->save)
+ return 0;
+
/* FIXME: */
g_assert (helper->type == 2);
mono_metadata_signature_equal (am->sig, sig)) {
g_free (name);
g_free (sig);
+ m->table_idx = am->token & 0xffffff;
return am->token;
}
}
am->sig = sig;
am->parent = m->parent->type;
am->token = mono_image_get_memberref_token (assembly, am->parent,
- name, method_encode_signature (assembly, sig));
+ name, method_encode_signature (assembly, sig));
assembly->array_methods = g_list_prepend (assembly->array_methods, am);
m->table_idx = am->token & 0xffffff;
return am->token;
MonoReflectionCtorBuilder *ctor;
MonoReflectionMethodBuilder *method;
MonoReflectionTypeBuilder *tb;
+ MonoReflectionArrayMethod *am;
guint32 i, idx;
unsigned char *target;
target = assembly->code.data + code_idx + iltoken->code_pos;
switch (target [3]) {
case MONO_TABLE_FIELD:
- if (strcmp (iltoken->member->vtable->klass->name, "FieldBuilder"))
+ if (!strcmp (iltoken->member->vtable->klass->name, "FieldBuilder")) {
+ field = (MonoReflectionFieldBuilder *)iltoken->member;
+ idx = field->table_idx;
+ } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoField")) {
+ MonoClassField *f = ((MonoReflectionField*)iltoken->member)->field;
+ idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->field_to_table_idx, f));
+ } else {
g_assert_not_reached ();
- field = (MonoReflectionFieldBuilder *)iltoken->member;
- idx = field->table_idx;
+ }
break;
case MONO_TABLE_METHOD:
if (!strcmp (iltoken->member->vtable->klass->name, "MethodBuilder")) {
} else if (!strcmp (iltoken->member->vtable->klass->name, "ConstructorBuilder")) {
ctor = (MonoReflectionCtorBuilder *)iltoken->member;
idx = ctor->table_idx;
+ } else if (!strcmp (iltoken->member->vtable->klass->name, "MonoMethod")) {
+ MonoMethod *m = ((MonoReflectionMethod*)iltoken->member)->method;
+ idx = GPOINTER_TO_UINT (mono_g_hash_table_lookup (assembly->method_to_table_idx, m));
} else {
g_assert_not_reached ();
}
tb = (MonoReflectionTypeBuilder *)iltoken->member;
idx = tb->table_idx;
break;
+ case MONO_TABLE_MEMBERREF:
+ if (strcmp (iltoken->member->vtable->klass->name, "MonoArrayMethod"))
+ g_assert_not_reached ();
+ am = (MonoReflectionArrayMethod*)iltoken->member;
+ idx = am->table_idx;
+ break;
default:
g_error ("got unexpected table 0x%02x in fixup", target [3]);
}
MonoReflectionTypeBuilder *type = g_ptr_array_index (types, i);
mono_image_get_type_info (domain, type, assembly);
}
- g_ptr_array_free (types, FALSE);
+ g_ptr_array_free (types, TRUE);
}
/*
if (!assembly->dynamic_assembly)
mono_image_basic_init (assembly);
- mono_metadata_encode_value (1 | (str->length * 2), b, &b);
- idx = mono_image_add_stream_data (&assembly->dynamic_assembly->us, buf, b-buf);
+
+ if (assembly->dynamic_assembly->save) {
+ mono_metadata_encode_value (1 | (str->length * 2), b, &b);
+ idx = mono_image_add_stream_data (&assembly->dynamic_assembly->us, buf, b-buf);
#if G_BYTE_ORDER != G_LITTLE_ENDIAN
{
char *swapped = g_malloc (2 * mono_string_length (str));
mono_image_add_stream_data (&assembly->dynamic_assembly->us, (const char*)mono_string_chars (str), str->length * 2);
#endif
mono_image_add_stream_data (&assembly->dynamic_assembly->us, "", 1);
+ }
+ else
+ idx = assembly->dynamic_assembly->us.index ++;
mono_g_hash_table_insert (assembly->dynamic_assembly->tokens,
GUINT_TO_POINTER (MONO_TOKEN_STRING | idx), str);
MonoClass *klass;
guint32 token;
- if (!obj)
- g_error ("System.Array methods not yet supported");
-
klass = obj->vtable->klass;
if (strcmp (klass->name, "MethodBuilder") == 0) {
MonoReflectionMethodBuilder *mb = (MonoReflectionMethodBuilder *)obj;
else if (strcmp (klass->name, "MonoCMethod") == 0 ||
strcmp (klass->name, "MonoMethod") == 0) {
MonoReflectionMethod *m = (MonoReflectionMethod *)obj;
- token = mono_image_get_methodref_token (assembly, m->method);
+ if (m->method->klass->image == assembly->assembly.image) {
+ static guint32 method_table_idx = 0xffffff;
+ /*
+ * Each token should have a unique index, but the indexes are
+ * assigned by managed code, so we don't know about them. An
+ * easy solution is to count backwards...
+ */
+ method_table_idx --;
+ token = MONO_TOKEN_METHOD_DEF | method_table_idx;
+ } else
+ token = mono_image_get_methodref_token (assembly, m->method);
/*g_print ("got token 0x%08x for %s\n", token, m->method->name);*/
}
else if (strcmp (klass->name, "MonoField") == 0) {
MonoReflectionField *f = (MonoReflectionField *)obj;
- token = mono_image_get_fieldref_token (assembly, f->field, f->klass);
+ if (f->klass->image == assembly->assembly.image) {
+ static guint32 field_table_idx = 0xffffff;
+ field_table_idx --;
+ token = MONO_TOKEN_FIELD_DEF | field_table_idx;
+ } else
+ token = mono_image_get_fieldref_token (assembly, f->field, f->klass);
/*g_print ("got token 0x%08x for %s\n", token, f->field->name);*/
}
else if (strcmp (klass->name, "MonoArrayMethod") == 0) {
image->managed_wrapper_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
image->native_wrapper_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
image->remoting_invoke_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
+ image->synchronized_cache = g_hash_table_new (g_direct_hash, g_direct_equal);
return image;
}
assembly->assembly.dynamic = assembly;
assemblyb->assembly.assembly = (MonoAssembly*)assembly;
assembly->token_fixups = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
+ assembly->method_to_table_idx = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
+ assembly->field_to_table_idx = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
assembly->handleref = g_hash_table_new (g_direct_hash, g_direct_equal);
assembly->tokens = mono_g_hash_table_new (g_direct_hash, g_direct_equal);
assembly->typeref = g_hash_table_new ((GHashFunc)mono_metadata_type_hash, (GCompareFunc)mono_metadata_type_equal);
- assembly->blob_cache = g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
+ assembly->blob_cache = mono_g_hash_table_new ((GHashFunc)mono_blob_entry_hash, (GCompareFunc)mono_blob_entry_equal);
string_heap_init (&assembly->sheap);
mono_image_add_stream_data (&assembly->us, "", 1);
assembly->tables [i].columns = table_sizes [i];
}
+ assembly->run = assemblyb->access != 2;
+ assembly->save = assemblyb->access != 1;
+
image = create_dynamic_mono_image (mono_string_to_utf8 (assemblyb->name), g_strdup ("RefEmit_YouForgotToDefineAModule"));
assembly->assembly.aname.name = image->name;
image->assembly = (MonoAssembly*)assembly;
memcpy (pefile->data + text_offset, assembly->assembly.image->raw_metadata, assembly->meta_size);
text_offset += assembly->meta_size;
memcpy (pefile->data + text_offset, assembly->strong_name, assembly->strong_name_size);
+
+ g_free (assembly->assembly.image->raw_metadata);
break;
case MONO_SECTION_RELOC:
rva = (guint32*)(pefile->data + assembly->sections [i].offset);
if (!method->signature->param_count)
return NULL;
- member = mono_method_get_object (domain, method, NULL);
- names = g_new (char *, method->signature->param_count);
- mono_method_get_param_names (method, (const char **) names);
-
/* Note: the cache is based on the address of the signature into the method
* since we already cache MethodInfos with the method as keys.
*/
CHECK_OBJECT (MonoReflectionParameter**, &(method->signature), NULL);
+
+ member = mono_method_get_object (domain, method, NULL);
+ names = g_new (char *, method->signature->param_count);
+ mono_method_get_param_names (method, (const char **) names);
+
oklass = mono_class_from_name (mono_defaults.corlib, "System.Reflection", "ParameterInfo");
#if HAVE_BOEHM_GC
res = GC_MALLOC (sizeof (MonoReflectionParameter*) * method->signature->param_count);
assembly->name = p;
assembly->culture = "";
- while (*p && (isalnum (*p) || *p == '.'))
+ while (*p && (isalnum (*p) || *p == '.' || *p == '-'))
p++;
found_sep = 0;
while (*p == ' ' || *p == ',') {
case '+':
*p = 0; /* NULL terminate the name */
startn = p + 1;
+ info->nested = g_list_append (info->nested, startn);
/* we have parsed the nesting namespace + name */
- if (info->name) {
- info->nested = g_list_append (info->nested, startn);
+ if (info->name)
break;
- }
if (last_point) {
info->name_space = start;
*last_point = 0;
*w++ = *p++;
}
- if (info->name) {
- info->nested = g_list_append (info->nested, startn);
- } else {
+ if (!info->name) {
if (last_point) {
info->name_space = start;
*last_point = 0;
type = mono_reflection_get_type_internal (image, info, ignorecase);
if (type)
return type;
- if (!image || !mono_domain_has_type_resolve (mono_domain_get ()))
+ if (!mono_domain_has_type_resolve (mono_domain_get ()))
return NULL;
// Reconstruct the type name
assembly =
mono_domain_try_type_resolve (
mono_domain_get (), fullName->str, NULL);
- if (assembly)
+ if (assembly && (!image || (assembly->assembly->image == image)))
type = mono_reflection_get_type_internal (assembly->assembly->image,
info, ignorecase);
g_string_free (fullName, TRUE);
case MONO_TYPE_CLASS: {
char *n;
MonoType *t;
+ if (*p == (char)0xFF) {
+ *end = p + 1;
+ return NULL;
+ }
handle_type:
slen = mono_metadata_decode_value (p, &p);
n = g_memdup (p, slen + 1);
if (subt == 0x50) {
goto handle_type;
+ } else if (subt == 0x0E) {
+ type = MONO_TYPE_STRING;
+ goto handle_enum;
} else if (subt == 0x55) {
char *n;
MonoType *t;
case MONO_TYPE_SZARRAY:
{
MonoArray *arr;
- guint32 i,alen;
- alen=read32(p);
- p+=4;
- arr=mono_array_new(mono_domain_get(),mono_class_from_mono_type(t->data.type),alen);
+ guint32 i, alen;
+ alen = read32 (p);
+ p += 4;
+ if (alen == 0xffffffff) {
+ *end = p;
+ return NULL;
+ }
+ arr = mono_array_new (mono_domain_get(), mono_class_from_mono_type (t->data.type), alen);
switch (t->data.type->type)
{
case MONO_TYPE_U1:
p+=8;
}
break;
+ case MONO_TYPE_CLASS:
case MONO_TYPE_STRING:
- for (i=0;i<alen;i++)
- {
- if (*p==(char)0xff)
- {
- mono_array_set(arr,gpointer,i,NULL);
- p++;
- }
- else
- {
- slen=mono_metadata_decode_value(p,&p);
- mono_array_set(arr,gpointer,i,mono_string_new_len(mono_domain_get(),p,slen));
- p+=slen;
- }
+ for (i = 0; i < alen; i++) {
+ MonoObject *item = load_cattr_value (image, t->data.type, p, &p);
+ mono_array_set (arr, gpointer, i, item);
}
break;
default:
named += 2;
for (j = 0; j < num_named; j++) {
gint name_len;
- char *name, named_type;
+ char *name, named_type, data_type;
named_type = *named++;
- named++; /* type of data */
+ data_type = *named++; /* type of data */
+ if (data_type == 0x55) {
+ gint type_len;
+ char *type_name;
+ if ((unsigned char) *named == 0x80) /* no idea what this is, but it looks optional */
+ named++;
+ 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 */
+ }
name_len = mono_metadata_decode_blob_size (named, &named);
name = g_malloc (name_len + 1);
memcpy (name, named, name_len);
if (!type_is_reference (field->type))
g_free (val);
} else if (named_type == 0x54) {
- MonoProperty *prop = mono_class_get_property_from_name (mono_object_class (attr), name);
+ MonoProperty *prop;
void *pparams [1];
MonoType *prop_type;
+
+ prop = mono_class_get_property_from_name (mono_object_class (attr), name);
/* can we have more that 1 arg in a custom attr named property? */
prop_type = prop->get? prop->get->signature->ret: prop->set->signature->params [prop->set->signature->param_count - 1];
pparams [0] = load_cattr_value (image, prop_type, named, &named);
return attr;
}
-static MonoArray*
-attr_array_from_attr_info (CustomAttrInfo *cinfo)
+MonoArray*
+mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo)
{
MonoArray *result;
MonoClass *klass;
return result;
}
+MonoCustomAttrInfo*
+mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
+{
+ guint32 mtoken, i, len;
+ guint32 cols [MONO_CUSTOM_ATTR_SIZE];
+ MonoTableInfo *ca;
+ MonoCustomAttrInfo *ainfo;
+ GList *tmp, *list = NULL;
+ const char *data;
+
+ ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
+ /* the table is not sorted */
+ for (i = 0; i < ca->rows; ++i) {
+ if (mono_metadata_decode_row_col (ca, i, MONO_CUSTOM_ATTR_PARENT) != idx)
+ continue;
+ list = g_list_prepend (list, GUINT_TO_POINTER (i));
+ }
+ len = g_list_length (list);
+ if (!len)
+ return NULL;
+ ainfo = g_malloc0 (sizeof (MonoCustomAttrInfo) + sizeof (MonoCustomAttrEntry) * (len - MONO_ZERO_LEN_ARRAY));
+ ainfo->num_attrs = len;
+ ainfo->image = image;
+ for (i = 0, tmp = list; i < len; ++i, tmp = tmp->next) {
+ mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
+ mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
+ switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
+ case CUSTOM_ATTR_TYPE_METHODDEF:
+ mtoken |= MONO_TOKEN_METHOD_DEF;
+ break;
+ case CUSTOM_ATTR_TYPE_MEMBERREF:
+ mtoken |= MONO_TOKEN_MEMBER_REF;
+ break;
+ default:
+ g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
+ 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);
+ 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;
+ }
+ g_list_free (list);
+
+ return ainfo;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_method (MonoMethod *method)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, method)))
+ return cinfo;
+ idx = find_method_index (method);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_METHODDEF;
+ return mono_custom_attrs_from_index (method->klass->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_class (MonoClass *klass)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass)))
+ return cinfo;
+ idx = mono_metadata_token_index (klass->type_token);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_TYPEDEF;
+ return mono_custom_attrs_from_index (klass->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_assembly (MonoAssembly *assembly)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, assembly)))
+ return cinfo;
+ idx = 1; /* there is only one assembly */
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_ASSEMBLY;
+ return mono_custom_attrs_from_index (assembly->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, property)))
+ return cinfo;
+ idx = find_property_index (klass, property);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_PROPERTY;
+ return mono_custom_attrs_from_index (klass->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, event)))
+ return cinfo;
+ idx = find_event_index (klass, event);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_EVENT;
+ return mono_custom_attrs_from_index (klass->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
+{
+ MonoCustomAttrInfo *cinfo;
+ guint32 idx;
+
+ if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
+ return cinfo;
+ idx = find_field_index (klass, field);
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_FIELDDEF;
+ return mono_custom_attrs_from_index (klass->image, idx);
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
+{
+ MonoTableInfo *ca;
+ guint32 i, idx, method_index;
+ guint32 param_list, param_last, param_pos, found;
+ MonoImage *image;
+
+ /* FIXME: handle dynamic custom attrs for parameters */
+ /*if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, field)))
+ return cinfo;*/
+ image = method->klass->image;
+ method_index = find_method_index (method);
+ ca = &image->tables [MONO_TABLE_METHOD];
+
+ 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];
+ param_last = ca->rows + 1;
+ } else {
+ param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
+ ca = &image->tables [MONO_TABLE_PARAM];
+ }
+ found = FALSE;
+ for (i = param_list; i < param_last; ++i) {
+ param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
+ if (param_pos == param) {
+ found = TRUE;
+ break;
+ }
+ }
+ if (!found)
+ return NULL;
+ idx = i;
+ idx <<= CUSTOM_ATTR_BITS;
+ idx |= CUSTOM_ATTR_PARAMDEF;
+ return mono_custom_attrs_from_index (image, idx);
+}
+
/*
* mono_reflection_get_custom_attrs:
* @obj: a reflection object handle
MonoArray*
mono_reflection_get_custom_attrs (MonoObject *obj)
{
- guint32 idx, mtoken, i, len;
- guint32 cols [MONO_CUSTOM_ATTR_SIZE];
MonoClass *klass;
- MonoImage *image;
- MonoTableInfo *ca;
- MonoMethod *method;
- MonoObject *attr;
MonoArray *result;
- GList *list = NULL;
- MonoArray *dynamic_attrs = NULL;
- CustomAttrInfo *cinfo;
+ MonoCustomAttrInfo *cinfo;
MONO_ARCH_SAVE_REGS;
if (klass == mono_defaults.monotype_class) {
MonoReflectionType *rtype = (MonoReflectionType*)obj;
klass = mono_class_from_mono_type (rtype->type);
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, klass)))
- return attr_array_from_attr_info (cinfo);
- idx = mono_metadata_token_index (klass->type_token);
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_TYPEDEF;
- image = klass->image;
+ cinfo = mono_custom_attrs_from_class (klass);
} else if (strcmp ("Assembly", klass->name) == 0) {
MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
- idx = 1; /* there is only one assembly */
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_ASSEMBLY;
- image = rassembly->assembly->image;
+ cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
} else if (strcmp ("MonoProperty", klass->name) == 0) {
MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, rprop->property)))
- return attr_array_from_attr_info (cinfo);
- idx = find_property_index (rprop->klass, rprop->property);
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_PROPERTY;
- image = rprop->klass->image;
+ cinfo = mono_custom_attrs_from_property (rprop->klass, rprop->property);
} else if (strcmp ("MonoEvent", klass->name) == 0) {
MonoReflectionEvent *revent = (MonoReflectionEvent*)obj;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, revent->event)))
- return attr_array_from_attr_info (cinfo);
- idx = find_event_index (revent->klass, revent->event);
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_EVENT;
- image = revent->klass->image;
+ cinfo = mono_custom_attrs_from_event (revent->klass, revent->event);
} else if (strcmp ("MonoField", klass->name) == 0) {
MonoReflectionField *rfield = (MonoReflectionField*)obj;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, rfield->field)))
- return attr_array_from_attr_info (cinfo);
- idx = find_field_index (rfield->klass, rfield->field);
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_FIELDDEF;
- image = rfield->klass->image;
+ cinfo = mono_custom_attrs_from_field (rfield->klass, rfield->field);
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
- if (dynamic_custom_attrs && (cinfo = g_hash_table_lookup (dynamic_custom_attrs, rmethod->method)))
- return attr_array_from_attr_info (cinfo);
- idx = find_method_index (rmethod->method);
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_METHODDEF;
- image = rmethod->method->klass->image;
+ cinfo = mono_custom_attrs_from_method (rmethod->method);
} else if (strcmp ("ParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
- guint32 method_index = find_method_index (rmethod->method);
- guint32 param_list, param_last, param_pos, found;
-
- /* FIXME: handle dynamic custom attrs for parameters */
- image = rmethod->method->klass->image;
- ca = &image->tables [MONO_TABLE_METHOD];
-
- 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];
- param_last = ca->rows + 1;
- } else {
- param_last = mono_metadata_decode_row_col (ca, method_index, MONO_METHOD_PARAMLIST);
- ca = &image->tables [MONO_TABLE_PARAM];
- }
- found = 0;
- for (i = param_list; i < param_last; ++i) {
- param_pos = mono_metadata_decode_row_col (ca, i - 1, MONO_PARAM_SEQUENCE);
- if (param_pos == param->PositionImpl) {
- found = 1;
- break;
- }
- }
- if (!found)
- return mono_array_new (mono_domain_get (), mono_defaults.object_class, 0);
- idx = i;
- idx <<= CUSTOM_ATTR_BITS;
- idx |= CUSTOM_ATTR_PARAMDEF;
+ cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl);
} else if (strcmp ("AssemblyBuilder", klass->name) == 0) {
MonoReflectionAssemblyBuilder *assemblyb = (MonoReflectionAssemblyBuilder*)obj;
- dynamic_attrs = assemblyb->cattrs;
- if (!dynamic_attrs)
- return mono_array_new (mono_domain_get (), mono_defaults.object_class, 0);
+ cinfo = mono_custom_attrs_from_builders (assemblyb->assembly.assembly->image, assemblyb->cattrs);
} else { /* handle other types here... */
g_error ("get custom attrs not yet supported for %s", klass->name);
}
- if (dynamic_attrs) {
- len = mono_array_length (dynamic_attrs);
- for (i = 0; i < len; ++i) {
- MonoReflectionCustomAttr *cattr = (MonoReflectionCustomAttr*)mono_array_get (dynamic_attrs, gpointer, i);
- attr = create_custom_attr (image, cattr->ctor->method, mono_array_addr (cattr->data, int, 0), mono_array_length (cattr->data));
- list = g_list_prepend (list, attr);
- }
+ if (cinfo) {
+ result = mono_custom_attrs_construct (cinfo);
} else {
- /* at this point image and index are set correctly for searching the custom attr */
- ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
- /* the table is not sorted */
- for (i = 0; i < ca->rows; ++i) {
- mono_metadata_decode_row (ca, i, cols, MONO_CUSTOM_ATTR_SIZE);
- if (cols [MONO_CUSTOM_ATTR_PARENT] != idx)
- continue;
- mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> CUSTOM_ATTR_TYPE_BITS;
- switch (cols [MONO_CUSTOM_ATTR_TYPE] & CUSTOM_ATTR_TYPE_MASK) {
- case CUSTOM_ATTR_TYPE_METHODDEF:
- mtoken |= MONO_TOKEN_METHOD_DEF;
- break;
- case CUSTOM_ATTR_TYPE_MEMBERREF:
- mtoken |= MONO_TOKEN_MEMBER_REF;
- break;
- default:
- g_error ("Unknown table for custom attr type %08x", cols [MONO_CUSTOM_ATTR_TYPE]);
- break;
- }
- method = mono_get_method (image, mtoken, NULL);
- if (!method)
- g_error ("Can't find custom attr constructor image: %s mtoken: 0x%08x", image->name, mtoken);
-
- {
- int data_len;
- const char *data = mono_metadata_blob_heap (image, cols [MONO_CUSTOM_ATTR_VALUE]);
- data_len = mono_metadata_decode_value (data, &data);
-
- attr = create_custom_attr (image, method, data, data_len);
- }
- list = g_list_prepend (list, attr);
- }
- }
-
- len = g_list_length (list);
- /*
- * The return type is really object[], but System/Attribute.cs does a cast
- * to (Attribute []) and that is not allowed: I'm lazy for now, but we should
- * probably fix that.
- */
- klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
- result = mono_array_new (mono_domain_get (), klass, len);
- for (i = 0; i < len; ++i) {
- mono_array_set (result, gpointer, i, list->data);
- list = list->next;
+ klass = mono_class_from_name (mono_defaults.corlib, "System", "Attribute");
+ result = mono_array_new (mono_domain_get (), klass, 0);
}
- g_list_free (g_list_first (list));
return result;
}
case MONO_TYPE_CLASS: {
char *str;
guint32 slen;
- MonoClass *k = mono_object_class (arg);
+ MonoClass *k;
+ if (!arg) {
+ *p++ = 0xFF;
+ 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);
g_free (str);
break;
}
+ case MONO_TYPE_SZARRAY: {
+ int len, i;
+ MonoClass *eclass;
+
+ if (!arg) {
+ *p++ = 0xff; *p++ = 0xff; *p++ = 0xff; *p++ = 0xff;
+ break;
+ }
+ len = mono_array_length ((MonoArray*)arg);
+ *p++ = len & 0xff;
+ *p++ = (len >> 8) & 0xff;
+ *p++ = (len >> 16) & 0xff;
+ *p++ = (len >> 24) & 0xff;
+ *retp = p;
+ *retbuffer = buffer;
+ eclass = mono_class_from_mono_type (type)->element_class;
+ for (i = 0; i < len; ++i) {
+ encode_cattr_value (buffer, p, &buffer, &p, buflen, &eclass->byval_arg, mono_array_get ((MonoArray*)arg, MonoObject*, i));
+ }
+ break;
+ }
/* it may be a boxed value or a Type */
case MONO_TYPE_OBJECT: {
MonoClass *klass = mono_object_class (arg);
goto handle_type;
} else if (klass->enumtype) {
*p++ = 0x55;
+ } else if (klass == mono_defaults.string_class) {
+ simple_type = MONO_TYPE_STRING;
+ *p++ = 0x0E;
+ goto handle_enum;
} 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;
} else {
sig = ((MonoReflectionMethod*)ctor)->method->signature;
}
+ g_assert (mono_array_length (ctorArgs) == sig->param_count);
buflen = 256;
p = buffer = g_malloc (buflen);
/* write the prolog */
*p++ = 1;
*p++ = 0;
for (i = 0; i < sig->param_count; ++i) {
- if (sig->params[i]->type==MONO_TYPE_SZARRAY)
- {
- guint32 alen=mono_array_length(ctorArgs) - i;
- guint32 j;
- if ((p-buffer) + 10 >= buflen) {
- char *newbuf;
- buflen *= 2;
- newbuf = g_realloc (buffer, buflen);
- p = newbuf + (p-buffer);
- buffer = newbuf;
- }
- *p++=alen&0xff;
- *p++=(alen>>8)&0xff;
- *p++=(alen>>16)&0xff;
- *p++=(alen>>24)&0xff;
- for (j=0;j<alen;j++)
- {
- arg=(MonoObject*)mono_array_get(ctorArgs,gpointer,i+j);
- encode_cattr_value(buffer,p,&buffer,&p,&buflen,sig->params[i]->data.type,arg);
- }
- }
- else
- {
- arg = (MonoObject*)mono_array_get (ctorArgs, gpointer, i);
- encode_cattr_value (buffer, p, &buffer, &p, &buflen, sig->params [i], arg);
- }
+ arg = mono_array_get (ctorArgs, MonoObject*, i);
+ encode_cattr_value (buffer, p, &buffer, &p, &buflen, sig->params [i], arg);
}
i = 0;
if (properties)
prop = mono_array_get (properties, gpointer, i);
get_prop_name_and_type (prop, &pname, &ptype);
*p++ = 0x54; /* PROPERTY signature */
- mono_metadata_encode_value (ptype->type, p, &p);
+ if (ptype->type == MONO_TYPE_VALUETYPE && ptype->data.klass->enumtype) {
+ char *str = type_get_qualified_name (ptype, NULL);
+ int slen = strlen (str);
+ if ((p-buffer) + 10 + slen >= buflen) {
+ char *newbuf;
+ buflen *= 2;
+ buflen += slen;
+ newbuf = g_realloc (buffer, buflen);
+ p = newbuf + (p-buffer);
+ buffer = newbuf;
+ }
+ *p++ = 0x55;
+ /*
+ * This seems to be optional...
+ * *p++ = 0x80;
+ */
+ mono_metadata_encode_value (slen, p, &p);
+ memcpy (p, str, slen);
+ p += slen;
+ g_free (str);
+ } else {
+ mono_metadata_encode_value (ptype->type, p, &p);
+ }
len = strlen (pname);
mono_metadata_encode_value (len, p, &p);
memcpy (p, pname, len);
field = mono_array_get (fields, gpointer, i);
get_field_name_and_type (field, &fname, &ftype);
*p++ = 0x53; /* FIELD signature */
- mono_metadata_encode_value (ftype->type, p, &p);
+ if (ftype->type == MONO_TYPE_VALUETYPE && ftype->data.klass->enumtype) {
+ char *str = type_get_qualified_name (ftype, NULL);
+ int slen = strlen (str);
+ if ((p-buffer) + 10 + slen >= buflen) {
+ char *newbuf;
+ buflen *= 2;
+ buflen += slen;
+ newbuf = g_realloc (buffer, buflen);
+ p = newbuf + (p-buffer);
+ buffer = newbuf;
+ }
+ *p++ = 0x55;
+ /*
+ * This seems to be optional...
+ * *p++ = 0x80;
+ */
+ mono_metadata_encode_value (slen, p, &p);
+ memcpy (p, str, slen);
+ p += slen;
+ g_free (str);
+ } else {
+ mono_metadata_encode_value (ftype->type, p, &p);
+ }
len = strlen (fname);
mono_metadata_encode_value (len, p, &p);
memcpy (p, fname, len);
}
mono_class_setup_mono_type (klass);
+ mono_class_setup_supertypes (klass);
+
/*
* FIXME: handle interfaces.
*/
tb->type.type = &klass->byval_arg;
+ if (tb->nesting_type) {
+ g_assert (tb->nesting_type->type);
+ klass->nested_in = mono_class_from_mono_type (tb->nesting_type->type);
+ }
+
/*g_print ("setup %s as %s (%p)\n", klass->name, ((MonoObject*)tb)->vtable->klass->name, tb);*/
}
m->name = mono_string_to_utf8 (rmb->name);
m->klass = klass;
m->signature = sig;
+ m->token = MONO_TOKEN_METHOD_DEF | (*rmb->table_idx);
- /* TODO: What about m->token ? */
if (m->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) {
if (klass == mono_defaults.string_class && !strcmp (m->name, ".ctor"))
m->string_ctor = 1;
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
+
+ if (!((MonoDynamicAssembly*)klass->image->assembly->dynamic)->save) {
+ /* ilgen is no longer needed */
+ mb->ilgen = NULL;
+ }
+
return mb->mhandle;
}
mb->mhandle = reflection_methodbuilder_to_mono_method (klass, &rmb, sig);
mono_save_custom_attrs (klass->image, mb->mhandle, mb->cattrs);
+
+ if (!((MonoDynamicAssembly*)klass->image->assembly->dynamic)->save) {
+ /* ilgen is no longer needed */
+ mb->ilgen = NULL;
+ }
return mb->mhandle;
}
}
}
+ if (klass->flags & TYPE_ATTRIBUTE_INTERFACE)
+ for (i = 0; i < klass->method.count; ++i)
+ klass->methods [i]->slot = i;
+
/* Overrides */
onum = 0;
if (tb->methods) {
MonoReflectionTypeBuilder *tb = klass->reflection_info;
MonoReflectionFieldBuilder *fb;
MonoClassField *field;
+ const char *p, *p2;
int i;
+ guint32 len, idx;
klass->field.count = tb->fields? mono_array_length (tb->fields): 0;
+ klass->field.first = 0;
+ klass->field.last = klass->field.count;
if (!klass->field.count)
return;
field->parent = klass;
fb->handle = field;
mono_save_custom_attrs (klass->image, field, fb->cattrs);
+
+ if (fb->def_value) {
+ field->type->attrs |= FIELD_ATTRIBUTE_HAS_DEFAULT;
+ MonoDynamicAssembly *assembly = klass->image->assembly->dynamic;
+ field->def_value = g_new0 (MonoConstant, 1);
+ idx = encode_constant (assembly, fb->def_value, &field->def_value->type);
+ /* Copy the data from the blob since it might get realloc-ed */
+ p = assembly->blob.data + idx;
+ len = mono_metadata_decode_blob_size (p, &p2);
+ len += p2 - p;
+ field->def_value->value = g_malloc (len);
+ memcpy (field->def_value->value, p, len);
+ }
}
mono_class_layout_fields (klass);
}
klass->flags = tb->attrs;
klass->element_class = klass;
+ if (!((MonoDynamicAssembly*)klass->image->assembly->dynamic)->run)
+ /* No need to fully construct the type */
+ return mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
+
/* enums are done right away */
if (!klass->enumtype)
ensure_runtime_vtable (klass);
klass->min_align = 1;
}
- if (tb->nesting_type) {
- g_assert (tb->nesting_type->type);
- klass->nested_in = mono_class_from_mono_type (tb->nesting_type->type);
- }
-
/* FIXME: handle packing_size and instance_size */
typebuilder_setup_fields (klass);
}
+
+