#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;
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);
}
}
-/*
- * 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)
{
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);
}
/*
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);
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; \
#endif
case MONO_TYPE_VAR:
case MONO_TYPE_MVAR:
- return type->data.generic_param->owner != NULL;
+ return TRUE;
}
return TRUE;
}
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_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);
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);
- MONO_OBJECT_SETREF (param, ClassImpl, mono_type_get_object (domain, mono_method_signature (method)->params [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)) {
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);
-
+
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 */
}
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];
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;
}
+#if HAVE_SGEN_GC
+static void* reflection_info_desc = NULL;
+#endif
+
/*
* mono_reflection_setup_internal_class:
* @tb: a TypeBuilder object
klass->flags = tb->attrs;
klass->element_class = klass;
- klass->reflection_info = tb; /* FIXME: GC 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);
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);
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;
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.
mono_raise_exception (mono_get_exception_type_load (NULL, NULL));
return;
}
- rmb.refs [i] = ref; /* FIXME: GC object stored in unamanged memory (change also resolve_object() signature) */
+ 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;