/**
* mono_class_setup_fields:
- * @m: pointer to the metadata.
* @class: The class to initialize
*
* Initializes the class->fields.
+ * Assumes the loader lock is held.
*/
static void
mono_class_setup_fields (MonoClass *class)
if (class->size_inited)
return;
+ if (class->inited)
+ mono_class_init (class);
+
class->instance_size = 0;
class->class_size = 0;
/* Prevent infinite loops if the class references itself */
class->size_inited = 1;
- class->fields = g_new0 (MonoClassField, top);
+ class->fields = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoClassField) * top);
/*
* Fetch all the field information.
mono_class_layout_fields (class);
}
+/**
+ * mono_class_setup_fields_locking:
+ * @class: The class to initialize
+ *
+ * Initializes the class->fields.
+ * Aquires the loader lock.
+ */
+static void
+mono_class_setup_fields_locking (MonoClass *class)
+{
+ mono_loader_lock ();
+ mono_class_setup_fields (class);
+ mono_loader_unlock ();
+}
+
/* useful until we keep track of gc-references in corlib etc. */
#define IS_GC_REFERENCE(t) ((t)->type == MONO_TYPE_U || (t)->type == MONO_TYPE_I || (t)->type == MONO_TYPE_PTR)
//printf ("INIT: %s.%s\n", class->name_space, class->name);
if (!class->generic_class && !class->methods) {
- methods = g_new (MonoMethod*, class->method.count);
+ methods = mono_mempool_alloc (class->image->mempool, sizeof (MonoMethod*) * class->method.count);
for (i = 0; i < class->method.count; ++i) {
- methods [i] = mono_get_method (class->image,
- MONO_TOKEN_METHOD_DEF | (i + class->method.first + 1), class);
+ methods [i] = mono_get_method (class->image, MONO_TOKEN_METHOD_DEF | (i + class->method.first + 1), class);
}
}
for (i = 0; i < class->method.count; ++i)
methods [i]->slot = i;
+ /* Leave this assignment as the last op in this function */
class->methods = methods;
mono_loader_unlock ();
if (class->property.count)
mono_class_setup_methods (class);
- properties = g_new0 (MonoProperty, class->property.count);
+ properties = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoProperty) * class->property.count);
for (i = class->property.first; i < last; ++i) {
mono_metadata_decode_row (pt, i, cols, MONO_PROPERTY_SIZE);
properties [i - class->property.first].parent = class;
}
}
+ /* Leave this assignment as the last op in the function */
class->properties = properties;
mono_loader_unlock ();
MonoTableInfo *pt = &class->image->tables [MONO_TABLE_EVENT];
MonoTableInfo *msemt = &class->image->tables [MONO_TABLE_METHODSEMANTICS];
guint32 last;
+ MonoEvent *events;
if (class->events)
return;
+ mono_loader_lock ();
+
+ if (class->events) {
+ mono_loader_unlock ();
+ return;
+ }
class->event.first = mono_metadata_events_from_typedef (class->image, mono_metadata_token_index (class->type_token) - 1, &last);
class->event.count = last - class->event.first;
if (class->event.count)
mono_class_setup_methods (class);
- class->events = g_new0 (MonoEvent, class->event.count);
+ events = mono_mempool_alloc0 (class->image->mempool, sizeof (MonoEvent) * class->event.count);
for (i = class->event.first; i < last; ++i) {
- MonoEvent *event = &class->events [i - class->event.first];
+ MonoEvent *event = &events [i - class->event.first];
mono_metadata_decode_row (pt, i, cols, MONO_EVENT_SIZE);
event->parent = class;
}
}
}
+ /* Leave this assignment as the last op in the function */
+ class->events = events;
+
+ mono_loader_unlock ();
}
static guint
static MonoClassField *
mono_class_get_field_idx (MonoClass *class, int idx)
{
- mono_class_setup_fields (class);
+ mono_class_setup_fields_locking (class);
- if (class->field.count){
- if ((idx >= class->field.first) && (idx < class->field.first + class->field.count)){
- return &class->fields [idx - class->field.first];
+ while (class) {
+ if (class->field.count) {
+ if ((idx >= class->field.first) && (idx < class->field.first + class->field.count)){
+ return &class->fields [idx - class->field.first];
+ }
}
+ class = class->parent;
}
-
- if (!class->parent)
- return NULL;
-
- return mono_class_get_field_idx (class->parent, idx);
+ return NULL;
}
/**
return mono_class_get_field_idx (class, idx - 1);
}
+/**
+ * mono_class_get_field_from_name:
+ * @klass: the class to lookup the field.
+ * @name: the field name
+ *
+ * Search the class @klass and it's parents for a field with the name @name.
+ *
+ * Returns: the MonoClassField pointer of the named field or NULL
+ */
MonoClassField *
mono_class_get_field_from_name (MonoClass *klass, const char *name)
{
int i;
+ mono_class_setup_fields_locking (klass);
while (klass) {
- mono_class_setup_fields (klass);
for (i = 0; i < klass->field.count; ++i) {
if (strcmp (name, klass->fields [i].name) == 0)
return &klass->fields [i];
return NULL;
}
+/**
+ * mono_class_get_field_token:
+ * @field: the field we need the token of
+ *
+ * Get the token of a field. Note that the tokesn is only valid for the image
+ * the field was loaded from. Don't use this function for fields in dynamic types.
+ *
+ * Returns: the token representing the field in the image it was loaded from.
+ */
guint32
mono_class_get_field_token (MonoClassField *field)
{
MonoClass *klass = field->parent;
int i;
+ mono_class_setup_fields_locking (klass);
while (klass) {
- mono_class_setup_fields (klass);
for (i = 0; i < klass->field.count; ++i) {
if (&klass->fields [i] == field)
return mono_metadata_make_token (MONO_TABLE_FIELD, klass->field.first + i + 1);
MonoClassField* field;
if (!iter)
return NULL;
- if (!klass->inited)
- mono_class_init (klass);
+ mono_class_setup_fields_locking (klass);
if (!*iter) {
- mono_class_setup_fields (klass);
/* start from the first */
if (klass->field.count) {
return *iter = &klass->fields [0];