#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"
MonoObject *type;
MonoString *name;
MonoBoolean init_locals;
+ MonoBoolean skip_visibility;
MonoArray *return_modreq;
MonoArray *return_modopt;
MonoArray *param_modreq;
static MonoObject *mono_get_object_from_blob (MonoDomain *domain, MonoType *type, const char *blob);
static inline MonoType *dup_type (const MonoType *original);
+/**
+ * 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);
+}
+
+#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)
{
guint32 idx;
char *copy;
gpointer oldkey, oldval;
-
+
copy = g_malloc (s1+s2);
memcpy (copy, b1, s1);
memcpy (copy + s1, b2, s2);
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]);
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);
}
/*
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)
{
}
}
- 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);
entry = g_new0 (GenericParamTableEntry, 1);
entry->owner = owner;
- entry->gparam = gparam;
+ entry->gparam = gparam; /* FIXME: GC object stored in unmanaged mem */
g_ptr_array_add (assembly->gen_params, entry);
}
{
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
+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);\
}
}
-/*
- * 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)
{
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);
- /*
- * 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);
- char *n;
+ /*
+ * 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);
+ char *n;
- n = mono_string_to_utf8 (tb->nspace);
- string_heap_insert (&assembly->sheap, n);
- g_free (n);
- }
- for (i = 0; i < types->len; ++i) {
- MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
- char *n;
+ n = mono_string_to_utf8 (tb->nspace);
+ string_heap_insert (&assembly->sheap, n);
+ g_free (n);
+ }
+ for (i = 0; i < types->len; ++i) {
+ MonoReflectionTypeBuilder *tb = g_ptr_array_index (types, i);
+ char *n;
- n = mono_string_to_utf8 (tb->name);
- string_heap_insert (&assembly->sheap, n);
- g_free (n);
- }
+ n = mono_string_to_utf8 (tb->name);
+ string_heap_insert (&assembly->sheap, n);
+ g_free (n);
+ }
- 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);
+ 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);
}
/*
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);
assembly->assembly.aname.culture = g_strdup ("");
if (assemblyb->version) {
- char **version = g_strsplit (mono_string_to_utf8 (assemblyb->version), ".", 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);
+ 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->assembly.aname.major = 0;
+ assembly->assembly.aname.minor = 0;
+ assembly->assembly.aname.build = 0;
+ assembly->assembly.aname.revision = 0;
}
assembly->run = assemblyb->access != 2;
/* 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;
if (image->assembly->image->modules)
memcpy (new_modules, image->assembly->image->modules, module_count * sizeof (MonoImage *));
new_modules [module_count] = image;
+ mono_image_addref (image);
g_free (image->assembly->image->modules);
image->assembly->image->modules = new_modules;
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; \
#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
pe.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); \
_obj = mono_g_hash_table_lookup (domain->refobject_hash, &pe); \
if (!_obj) { \
ReflectedEntry *e = ALLOC_REFENTRY; \
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 = (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);
g_assert (res->token);
}
- mono_image_addref (image);
-
CACHE_OBJECT (MonoReflectionModule *, image, res, NULL);
}
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);
gclass = mono_get_inflated_generic_class (geninst->data.generic_class);
gklass = gclass->generic_class.container_class;
+ g_assert (gklass->generic_container);
mono_class_init (gclass->klass);
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->generic_class.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 (!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? */
}
}
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);
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")))
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);
+ 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);
}
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);
+ 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);
}
res = (MonoReflectionField *)mono_object_new (domain, oklass);
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);
+ MONO_OBJECT_SETREF (res, type, mono_type_get_object (domain, field->type));
CACHE_OBJECT (MonoReflectionField *, field, 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);
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 (MonoReflectionMethodBody *, method, ret, NULL);
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:
} else if (subt == 0x0E) {
type = MONO_TYPE_STRING;
goto handle_enum;
+ } else if (subt == 0x1D) {
+ MonoType simple_type = {{0}};
+ int etype = *p;
+ p ++;
+
+ 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;
*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;
switch (basetype)
{
case MONO_TYPE_U1:
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:
}
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;
}
static MonoObject*
-create_custom_attr_data (MonoImage *image, MonoMethod *method, const char *data, guint32 len)
+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 = data;
+ const char *p = (const char*)data;
const char *named;
guint32 i, j, num_named;
void *params [3];
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_set (typedargs, void*, i, typedarg);
+ mono_array_setref (typedargs, i, typedarg);
if (!type_is_reference (mono_method_signature (method)->params [i]))
g_free (val);
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_set (namedargs, void*, j, namedarg);
+ mono_array_setref (namedargs, j, namedarg);
if (!type_is_reference (field->type))
g_free (val);
} else if (named_type == 0x54) {
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_set (namedargs, void*, j, namedarg);
+ mono_array_setref (namedargs, j, namedarg);
if (!type_is_reference (prop_type))
g_free (val);
}
result = mono_array_new (mono_domain_get (), klass, 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;
}
-MonoArray*
+static MonoArray*
mono_custom_attrs_construct_by_type (MonoCustomAttrInfo *cinfo, MonoClass *attr_klass)
{
MonoArray *result;
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_set (result, gpointer, n, attr);
+ mono_array_setref (result, n, attr);
n ++;
}
}
return result;
}
-MonoArray*
+static MonoArray*
mono_custom_attrs_data_construct (MonoCustomAttrInfo *cinfo)
{
MonoArray *result;
result = mono_array_new (mono_domain_get (), klass, 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_set (result, gpointer, i, attr);
+ mono_array_setref (result, i, attr);
}
return result;
}
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;
+ ainfo->attrs [i].data = (guchar*)data;
}
g_list_free (list);
return result;
}
+/**
+ * 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) {
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;
*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) {
+ simple_type = MONO_TYPE_SZARRAY;
+ *p++ = 0x1D;
+ *p++ = klass->element_class->byval_arg.type;
+ 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;
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;
+#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. */
+
+#if HAVE_SGEN_GC
+ if (!reflection_info_desc) {
+ gsize bmap = 1;
+ reflection_info_desc = mono_gc_make_descr_from_bitmap (&bmap, 1);
+ }
+ mono_gc_register_root (&klass->reflection_info, sizeof (gpointer), reflection_info_desc);
+#endif
+ 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);
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->slot = -1;
m->flags = rmb->attrs;
m->iflags = rmb->iattrs;
- m->name = mono_string_to_utf8 (rmb->name);
+ m->name = dynamic ? mono_string_to_utf8 (rmb->name) : mono_string_to_utf8_mp (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 = rmb->dllentry ? g_strdup (mono_string_to_utf8 (rmb->dllentry)) : g_strdup (m->name);
- 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 : 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));
}
if (rmb->generic_params) {
int count = mono_array_length (rmb->generic_params);
MonoGenericContainer *container;
+ MonoGenericContext *context;
m->generic_container = container = rmb->generic_container;
container->type_argc = count;
mono_array_get (rmb->generic_params, MonoReflectionGenericParam*, i);
container->type_params [i] = *gp->type.type->data.generic_param;
+ container->type_params [i].method = m;
}
+
+ context = &container->context;
+ context->container = container;
+ if (klass->generic_container) {
+ container->parent = klass->generic_container;
+ context->gclass = klass->generic_container->context.gclass;
+ }
+ context->gmethod = mono_get_shared_generic_method (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;
}
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] = dynamic ? mono_string_to_utf8 (pb->name) : mono_string_to_utf8_mp (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;
gboolean is_dynamic = FALSE;
MonoDomain *domain;
MonoType *geninst;
- int icount, i;
+ int i;
klass = mono_class_from_mono_type (type->type);
if (!klass->generic_container && !klass->generic_class &&
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 if (klass->wastypebuilder) {
tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
- icount = tb->interfaces ? mono_array_length (tb->interfaces) : 0;
is_dynamic = TRUE;
- } else {
- icount = klass->interface_count;
}
if (is_dynamic) {
gclass->context->container = gclass->container_class->generic_container;
gclass->context->gclass = gclass;
- if (is_dynamic) {
- dgclass->parent = parent;
- dgclass->ifaces = g_new0 (MonoType *, icount);
- dgclass->count_ifaces = icount;
-
- for (i = 0; i < icount; i++) {
- MonoReflectionType *itype;
-
- if (tb)
- itype = mono_array_get (tb->interfaces, MonoReflectionType *, i);
- else
- itype = mono_type_get_object (domain, &klass->interfaces [i]->byval_arg);
- dgclass->ifaces [i] = mono_reflection_bind_generic_parameters (itype, type_argc, types);
- if (!dgclass->ifaces [i])
- dgclass->ifaces [i] = itype->type;
- }
- }
-
mono_loader_unlock ();
return geninst;
}
-MonoType*
-mono_reflection_bind_generic_parameters (MonoReflectionType *type, int type_argc, MonoType **types)
-{
- MonoClass *klass, *pklass = NULL;
- MonoReflectionType *parent = NULL;
- MonoType *the_parent = NULL, *geninst;
- MonoReflectionTypeBuilder *tb = NULL;
- MonoGenericClass *gclass;
- MonoDomain *domain;
-
- domain = mono_object_domain (type);
- klass = mono_class_from_mono_type (type->type);
-
- if (!strcmp (((MonoObject *) type)->vtable->klass->name, "TypeBuilder")) {
- tb = (MonoReflectionTypeBuilder *) type;
-
- if (tb->parent) {
- parent = tb->parent;
- pklass = mono_class_from_mono_type (parent->type);
- }
- } else if (klass->wastypebuilder) {
- tb = (MonoReflectionTypeBuilder *) klass->reflection_info;
- 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->is_dynamic) {
- MonoDynamicGenericClass *dgclass;
-
- dgclass = (MonoDynamicGenericClass *) klass->generic_class;
- if (dgclass->parent) {
- parent = mono_type_get_object (domain, dgclass->parent);
- pklass = mono_class_from_mono_type (dgclass->parent);
- }
- }
- }
-
- if (pklass && pklass->generic_class)
- the_parent = mono_reflection_bind_generic_parameters (parent, type_argc, types);
-
- geninst = do_mono_reflection_bind_generic_parameters (type, type_argc, types, the_parent);
- if (!geninst)
- return NULL;
-
- gclass = geninst->data.generic_class;
-
- return geninst;
-}
-
MonoType*
mono_class_bind_generic_parameters (MonoType *type, int type_argc, MonoType **types)
{
MonoGenericClass *gclass, *cached;
MonoInflatedGenericClass *igclass;
MonoType *geninst;
- int icount, i;
+ int i;
klass = mono_class_from_mono_type (type);
if (!klass->generic_container && !klass->generic_class &&
mono_loader_lock ();
- icount = klass->interface_count;
-
igclass = g_new0 (MonoInflatedGenericClass, 1);
gclass = &igclass->generic_class;
gclass->is_inflated = TRUE;
static MonoMethod *
inflate_mono_method (MonoReflectionGenericClass *type, MonoMethod *method, MonoObject *obj)
{
- MonoGenericMethod *gmethod;
+ MonoGenericMethod *gmethod = NULL;
MonoInflatedGenericClass *gclass;
MonoGenericContext *context;
- int i;
+ MonoClass *klass;
+ int i, n;
+ klass = mono_class_from_mono_type (type->type.type);
gclass = mono_get_inflated_generic_class (type->type.type->data.generic_class);
+ n = mono_method_signature (method)->generic_param_count;
- gmethod = g_new0 (MonoGenericMethod, 1);
- gmethod->generic_class = &gclass->generic_class;
- gmethod->inst = g_new0 (MonoGenericInst, 1);
- gmethod->reflection_info = obj;
+ context = gclass->generic_class.context;
+ g_assert (context && context->container);
+ if (n) {
+ gmethod = g_new0 (MonoGenericMethod, 1);
+ gmethod->generic_class = &gclass->generic_class;
+ gmethod->container = method->generic_container;
+ gmethod->reflection_info = obj;
- gmethod->inst->type_argc = mono_method_signature (method)->generic_param_count;
- gmethod->inst->type_argv = g_new0 (MonoType *, gmethod->inst->type_argc);
+ gmethod->inst = g_new0 (MonoGenericInst, 1);
+ gmethod->inst->type_argc = n;
+ gmethod->inst->type_argv = g_new0 (MonoType *, n);
- for (i = 0; i < gmethod->inst->type_argc; i++) {
- MonoGenericParam *gparam = &method->generic_container->type_params [i];
+ for (i = 0; i < n; i++) {
+ MonoGenericParam *gparam = &method->generic_container->type_params [i];
+ g_assert (gparam->pklass);
+ gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
+ }
- g_assert (gparam->pklass);
- gmethod->inst->type_argv [i] = &gparam->pklass->byval_arg;
- }
+ g_assert (gmethod->container->parent == context->container);
- context = g_new0 (MonoGenericContext, 1);
- context->container = gclass->generic_class.container_class->generic_container;
- context->gclass = &gclass->generic_class;
- context->gmethod = gmethod;
+ context = g_new0 (MonoGenericContext, 1);
+ context->container = gmethod->container;
+ context->gclass = &gclass->generic_class;
+ context->gmethod = gmethod;
+ }
return mono_class_inflate_generic_method (method, context);
}
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 (dgclass->parent)
- pklass = mono_class_from_mono_type (dgclass->parent);
- else
- pklass = gklass->parent;
-
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;
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
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);
}
}
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->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.
res = mono_type_get_object (mono_object_domain (tb), &klass->byval_arg);
g_assert (res != (MonoReflectionType*)tb);
+
return res;
}
image = &gparam->tbuilder->module->dynamic_image->image;
mono_class_from_generic_parameter (param, image, gparam->mbuilder != NULL);
- param->pklass->reflection_info = gparam;
+ 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;
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;
}
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 ();
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;