static MonoString*
mono_ldstr_metadata_sig (MonoDomain *domain, const char* sig);
+static void
+free_main_args (void);
+
#define ldstr_lock() EnterCriticalSection (&ldstr_section)
#define ldstr_unlock() LeaveCriticalSection (&ldstr_section)
static CRITICAL_SECTION ldstr_section;
* mono_release_type_locks
*/
DeleteCriticalSection (&type_initialization_section);
+ g_hash_table_destroy (type_initialization_hash);
+ type_initialization_hash = NULL;
#endif
DeleteCriticalSection (&ldstr_section);
+ g_hash_table_destroy (blocked_thread_hash);
+ blocked_thread_hash = NULL;
+
+ free_main_args ();
}
/**
MonoVTable *module_vtable = mono_class_vtable_full (vtable->domain, module_klass, raise_exception);
if (!module_vtable)
return NULL;
- mono_runtime_class_init (module_vtable);
+ exc = mono_runtime_class_init_full (module_vtable, raise_exception);
+ if (exc)
+ return exc;
}
}
method = mono_class_get_cctor (klass);
* The IMT thunk might be called with an instance of one of the
* generic virtual methods, so has to fallback to the IMT trampoline.
*/
- imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], callbacks.get_imt_trampoline (i));
+ imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], callbacks.get_imt_trampoline ? callbacks.get_imt_trampoline (i) : NULL);
} else {
imt [i] = initialize_imt_slot (vt, domain, imt_builder [i], NULL);
}
if (!class->vtable_size)
mono_class_setup_vtable (class);
+ if (class->generic_class && !class->vtable)
+ mono_class_check_vtable_constraints (class, NULL);
+
if (class->exception_type) {
mono_domain_unlock (domain);
mono_loader_unlock ();
gboolean is_static = FALSE;
gboolean is_ref = FALSE;
gboolean is_literal = FALSE;
+ gboolean is_ptr = FALSE;
+ MonoError error;
+ MonoType *type = mono_field_get_type_checked (field, &error);
+
+ if (!mono_error_ok (&error))
+ mono_error_raise_exception (&error);
- switch (field->type->type) {
+ switch (type->type) {
case MONO_TYPE_STRING:
case MONO_TYPE_OBJECT:
case MONO_TYPE_CLASS:
case MONO_TYPE_I8:
case MONO_TYPE_R8:
case MONO_TYPE_VALUETYPE:
- is_ref = field->type->byref;
+ is_ref = type->byref;
break;
case MONO_TYPE_GENERICINST:
- is_ref = !mono_type_generic_inst_is_valuetype (field->type);
+ is_ref = !mono_type_generic_inst_is_valuetype (type);
+ break;
+ case MONO_TYPE_PTR:
+ is_ptr = TRUE;
break;
default:
g_error ("type 0x%x not handled in "
- "mono_field_get_value_object", field->type->type);
+ "mono_field_get_value_object", type->type);
return NULL;
}
- if (field->type->attrs & FIELD_ATTRIBUTE_LITERAL)
+ if (type->attrs & FIELD_ATTRIBUTE_LITERAL)
is_literal = TRUE;
- if (field->type->attrs & FIELD_ATTRIBUTE_STATIC) {
+ if (type->attrs & FIELD_ATTRIBUTE_STATIC) {
is_static = TRUE;
if (!is_literal) {
return o;
}
+ if (is_ptr) {
+ static MonoMethod *m;
+ gpointer args [2];
+ gpointer *ptr;
+ gpointer v;
+
+ if (!m) {
+ MonoClass *ptr_klass = mono_class_from_name_cached (mono_defaults.corlib, "System.Reflection", "Pointer");
+ m = mono_class_get_method_from_name_flags (ptr_klass, "Box", 2, METHOD_ATTRIBUTE_STATIC);
+ g_assert (m);
+ }
+
+ v = &ptr;
+ if (is_literal) {
+ get_default_field_value (domain, field, v);
+ } else if (is_static) {
+ mono_field_static_get_value (vtable, field, v);
+ } else {
+ mono_field_get_value (obj, field, v);
+ }
+
+ /* MONO_TYPE_PTR is passed by value to runtime_invoke () */
+ args [0] = *ptr;
+ args [1] = mono_type_get_object (mono_domain_get (), type);
+
+ return mono_runtime_invoke (m, NULL, args, NULL);
+ }
+
/* boxed value type */
- klass = mono_class_from_mono_type (field->type);
+ klass = mono_class_from_mono_type (type);
if (mono_class_is_nullable (klass))
return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass);
* mono_get_delegate_invoke:
* @klass: The delegate class
*
- * Returns: the MonoMethod for the "Invoke" method in the delegate klass
+ * Returns: the MonoMethod for the "Invoke" method in the delegate klass or NULL if @klass is a broken delegate type
*/
MonoMethod *
mono_get_delegate_invoke (MonoClass *klass)
if (klass->exception_type)
return NULL;
im = mono_class_get_method_from_name (klass, "Invoke", -1);
- g_assert (im);
-
return im;
}
return res;
}
+static void
+free_main_args (void)
+{
+ int i;
+
+ for (i = 0; i < num_main_args; ++i)
+ g_free (main_args [i]);
+ g_free (main_args);
+}
+
/**
* mono_runtime_run_main:
* @method: the method to start the application with (usually Main)
MonoArray *args = NULL;
MonoDomain *domain = mono_domain_get ();
gchar *utf8_fullpath;
+ MonoMethodSignature *sig;
g_assert (method != NULL);
}
argc--;
argv++;
- if (mono_method_signature (method)->param_count) {
+
+ sig = mono_method_signature (method);
+ if (!sig) {
+ g_print ("Unable to load Main method.\n");
+ exit (-1);
+ }
+
+ if (sig->param_count) {
args = (MonoArray*)mono_array_new (domain, mono_defaults.string_class, argc);
for (i = 0; i < argc; ++i) {
/* The encodings should all work, given that
MonoString *news;
size = sizeof (MonoString) + 2 * (mono_string_length (str) + 1);
news = mono_gc_alloc_pinned_obj (((MonoObject*)str)->vtable, size);
- memcpy (mono_string_chars (news), mono_string_chars (str), mono_string_length (str) * 2);
- news->length = mono_string_length (str);
+ if (news) {
+ memcpy (mono_string_chars (news), mono_string_chars (str), mono_string_length (str) * 2);
+ news->length = mono_string_length (str);
+ }
return news;
}
}
if (insert) {
str = mono_string_get_pinned (str);
- mono_g_hash_table_insert (ldstr_table, str, str);
+ if (str)
+ mono_g_hash_table_insert (ldstr_table, str, str);
ldstr_unlock ();
return str;
} else {
}
o = mono_string_get_pinned (o);
- mono_g_hash_table_insert (domain->ldstr_table, o, o);
+ if (o)
+ mono_g_hash_table_insert (domain->ldstr_table, o, o);
ldstr_unlock ();
return o;
* mono_string_to_utf8:
* @s: a System.String
*
- * Return the UTF8 representation for @s.
- * the resulting buffer nedds to be freed with g_free().
+ * Returns the UTF8 representation for @s.
+ * The resulting buffer needs to be freed with mono_free().
*
* @deprecated Use mono_string_to_utf8_checked to avoid having an exception arbritraly raised.
*/
return result;
}
+/**
+ * mono_string_to_utf8_checked:
+ * @s: a System.String
+ * @error: a MonoError.
+ *
+ * Converts a MonoString to its UTF8 representation. May fail; check
+ * @error to determine whether the conversion was successful.
+ * The resulting buffer should be freed with mono_free().
+ */
char *
mono_string_to_utf8_checked (MonoString *s, MonoError *error)
{
return ret;
}
+/**
+ * mono_object_to_string:
+ * @obj: The object
+ * @exc: Any exception thrown by ToString (). May be NULL.
+ *
+ * Returns: the result of calling ToString () on an object.
+ */
+MonoString *
+mono_object_to_string (MonoObject *obj, MonoObject **exc)
+{
+ static MonoMethod *to_string = NULL;
+ MonoMethod *method;
+
+ g_assert (obj);
+
+ if (!to_string)
+ to_string = mono_class_get_method_from_name_flags (mono_get_object_class (), "ToString", 0, METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_PUBLIC);
+
+ method = mono_object_get_virtual_method (obj, to_string);
+
+ return (MonoString *) mono_runtime_invoke (method, obj, NULL, exc);
+}
+
/**
* mono_print_unhandled_exception:
* @exc: The exception
void
mono_print_unhandled_exception (MonoObject *exc)
{
- MonoError error;
- char *message = (char *) "";
- MonoString *str;
- MonoMethod *method;
- MonoClass *klass;
+ MonoString * str;
+ char *message = (char*)"";
gboolean free_message = FALSE;
+ MonoError error;
- if (mono_object_isinst (exc, mono_defaults.exception_class)) {
- klass = exc->vtable->klass;
- method = NULL;
- while (klass && method == NULL) {
- method = mono_class_get_method_from_name_flags (klass, "ToString", 0, METHOD_ATTRIBUTE_VIRTUAL | METHOD_ATTRIBUTE_PUBLIC);
- if (method == NULL)
- klass = klass->parent;
- }
-
- g_assert (method);
-
- str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
+ if (exc == (MonoObject*)mono_object_domain (exc)->out_of_memory_ex) {
+ message = g_strdup ("OutOfMemoryException");
+ } else {
+ str = mono_object_to_string (exc, NULL);
if (str) {
message = mono_string_to_utf8_checked (str, &error);
if (!mono_error_ok (&error)) {
mono_error_cleanup (&error);
- message = (char *)"";
+ message = (char *) "";
} else {
free_message = TRUE;
}
}
- }
+ }
/*
* g_printerr ("\nUnhandled Exception: %s.%s: %s\n", exc->vtable->klass->name_space,