* Copyright 2001-2003 Ximian, Inc (http://www.ximian.com)
* Copyright 2004-2011 Novell, Inc (http://www.novell.com)
* Copyright 2001 Xamarin Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <config.h>
#ifdef HAVE_ALLOCA_H
mono_type_initialization_unlock ();
}
-static gpointer
-default_trampoline (MonoMethod *method)
-{
- return method;
-}
-
-static gpointer
-default_jump_trampoline (MonoDomain *domain, MonoMethod *method, gboolean add_sync_wrapper)
-{
- g_assert_not_reached ();
-
- return NULL;
-}
-
#ifndef DISABLE_REMOTING
static gpointer
* mono_remote_class:
* @domain: the application domain
* @class_name: name of the remote class
+ * @error: set on error
*
* Creates and initializes a MonoRemoteClass object for a remote type.
*
- * Can raise an exception on failure.
+ * On failure returns NULL and sets @error
*/
MonoRemoteClass*
-mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class)
+mono_remote_class (MonoDomain *domain, MonoString *class_name, MonoClass *proxy_class, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
MonoRemoteClass *rc;
gpointer* key, *mp_key;
char *name;
+ mono_error_init (error);
+
key = create_remote_class_key (NULL, proxy_class);
mono_domain_lock (domain);
return rc;
}
- name = mono_string_to_utf8_mp (domain->mp, class_name, &error);
- if (!mono_error_ok (&error)) {
+ name = mono_string_to_utf8_mp (domain->mp, class_name, error);
+ if (!is_ok (error)) {
g_free (key);
mono_domain_unlock (domain);
- mono_error_raise_exception (&error);
+ return NULL;
}
mp_key = copy_remote_class_key (domain, key);
MonoObject *
mono_field_get_value_object (MonoDomain *domain, MonoClassField *field, MonoObject *obj)
{
+ MonoError error;
+ MonoObject* result = mono_field_get_value_object_checked (domain, field, obj, &error);
+ mono_error_assert_ok (&error);
+ return result;
+}
+
+/**
+ * mono_field_get_value_object_checked:
+ * @domain: domain where the object will be created (if boxing)
+ * @field: MonoClassField describing the field to fetch information from
+ * @obj: The object instance for the field.
+ * @error: Set on error.
+ *
+ * Returns: a new MonoObject with the value from the given field. If the
+ * field represents a value type, the value is boxed. On error returns NULL and sets @error.
+ *
+ */
+MonoObject *
+mono_field_get_value_object_checked (MonoDomain *domain, MonoClassField *field, MonoObject *obj, MonoError *error)
+{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
+ mono_error_init (error);
+
MonoObject *o;
MonoClass *klass;
MonoVTable *vtable = NULL;
gboolean is_ref = FALSE;
gboolean is_literal = FALSE;
gboolean is_ptr = FALSE;
- MonoType *type = mono_field_get_type_checked (field, &error);
+ MonoType *type = mono_field_get_type_checked (field, error);
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return_val_if_nok (error, NULL);
switch (type->type) {
case MONO_TYPE_STRING:
is_static = TRUE;
if (!is_literal) {
- vtable = mono_class_vtable_full (domain, field->parent, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ vtable = mono_class_vtable_full (domain, field->parent, error);
+ return_val_if_nok (error, NULL);
if (!vtable->initialized) {
- mono_runtime_class_init_full (vtable, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_class_init_full (vtable, error);
+ return_val_if_nok (error, NULL);
}
}
} else {
/* MONO_TYPE_PTR is passed by value to runtime_invoke () */
args [0] = ptr ? *ptr : NULL;
- args [1] = mono_type_get_object_checked (mono_domain_get (), type, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ args [1] = mono_type_get_object_checked (mono_domain_get (), type, error);
+ return_val_if_nok (error, NULL);
- o = mono_runtime_invoke_checked (m, NULL, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ o = mono_runtime_invoke_checked (m, NULL, args, error);
+ return_val_if_nok (error, NULL);
return o;
}
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);
+ return mono_nullable_box (mono_field_get_addr (obj, vtable, field), klass, error);
- o = mono_object_new_checked (domain, klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ o = mono_object_new_checked (domain, klass, error);
+ return_val_if_nok (error, NULL);
v = ((gchar *) o) + sizeof (MonoObject);
if (is_literal) {
* mono_nullable_box:
* @buf: The buffer representing the data to be boxed
* @klass: the type to box it as.
+ * @error: set on oerr
*
* Creates a boxed vtype or NULL from the Nullable structure pointed to by
- * @buf.
+ * @buf. On failure returns NULL and sets @error
*/
MonoObject*
-mono_nullable_box (guint8 *buf, MonoClass *klass)
+mono_nullable_box (guint8 *buf, MonoClass *klass, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
-
+ mono_error_init (error);
MonoClass *param_class = klass->cast_class;
mono_class_setup_fields_locking (klass);
g_assert (mono_class_from_mono_type (klass->fields [1].type) == mono_defaults.boolean_class);
if (*(guint8*)(buf + klass->fields [1].offset - sizeof (MonoObject))) {
- MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ MonoObject *o = mono_object_new_checked (mono_domain_get (), param_class, error);
+ return_val_if_nok (error, NULL);
if (param_class->has_references)
mono_gc_wbarrier_value_copy (mono_object_unbox (o), buf + klass->fields [0].offset - sizeof (MonoObject), 1, param_class);
else
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoClassField *field;
MonoDomain *current_domain, *root_domain;
MonoObject *current_appdomain_delegate = NULL, *root_appdomain_delegate = NULL;
current_domain = mono_domain_get ();
root_domain = mono_get_root_domain ();
- root_appdomain_delegate = mono_field_get_value_object (root_domain, field, (MonoObject*) root_domain->domain);
- if (current_domain != root_domain)
- current_appdomain_delegate = mono_field_get_value_object (current_domain, field, (MonoObject*) current_domain->domain);
+ root_appdomain_delegate = mono_field_get_value_object_checked (root_domain, field, (MonoObject*) root_domain->domain, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (current_domain != root_domain) {
+ current_appdomain_delegate = mono_field_get_value_object_checked (current_domain, field, (MonoObject*) current_domain->domain, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
if (!current_appdomain_delegate && !root_appdomain_delegate) {
mono_print_unhandled_exception (exc);
* boxed object in the arg array with the copy.
*/
MonoObject *orig = mono_array_get (params, MonoObject*, i);
- MonoObject *copy = mono_value_box (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig));
+ MonoObject *copy = mono_value_box_checked (mono_domain_get (), orig->vtable->klass, mono_object_unbox (orig), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
mono_array_setref (params, i, copy);
}
if (!params)
return NULL;
- else
- return mono_value_box (mono_domain_get (), method->klass->cast_class, pa [0]);
+ else {
+ MonoObject *result = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, pa [0], &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return result;
+ }
}
if (!obj) {
else
o = obj;
} else if (method->klass->valuetype) {
- obj = mono_value_box (mono_domain_get (), method->klass, obj);
+ obj = mono_value_box_checked (mono_domain_get (), method->klass, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
if (exc) {
nullable = mono_object_new_checked (mono_domain_get (), method->klass, &error);
mono_error_raise_exception (&error); /* FIXME don't raise here */
- mono_nullable_init ((guint8 *)mono_object_unbox (nullable), mono_value_box (mono_domain_get (), method->klass->cast_class, obj), method->klass);
+ MonoObject *boxed = mono_value_box_checked (mono_domain_get (), method->klass->cast_class, obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_nullable_init ((guint8 *)mono_object_unbox (nullable), boxed, method->klass);
obj = mono_object_unbox (nullable);
}
im = mono_class_get_method_from_name (klass, "CreateProxyForType", 1);
if (!im) {
- mono_error_set_generic_error (error, "System", "NotSupportedException", "Linked away.");
+ mono_error_set_not_supported (error, "Linked away.");
return NULL;
}
vtable->domain->create_proxy_for_type_method = im;
MonoObject *
mono_value_box (MonoDomain *domain, MonoClass *klass, gpointer value)
{
- MONO_REQ_GC_UNSAFE_MODE;
-
MonoError error;
+ MonoObject *result = mono_value_box_checked (domain, klass, value, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+/**
+ * mono_value_box_checked:
+ * @domain: the domain of the new object
+ * @class: the class of the value
+ * @value: a pointer to the unboxed data
+ * @error: set on error
+ *
+ * Returns: A newly created object which contains @value. On failure
+ * returns NULL and sets @error.
+ */
+MonoObject *
+mono_value_box_checked (MonoDomain *domain, MonoClass *klass, gpointer value, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
MonoObject *res;
int size;
MonoVTable *vtable;
+ mono_error_init (error);
+
g_assert (klass->valuetype);
if (mono_class_is_nullable (klass))
- return mono_nullable_box ((guint8 *)value, klass);
+ return mono_nullable_box ((guint8 *)value, klass, error);
vtable = mono_class_vtable (domain, klass);
if (!vtable)
return NULL;
size = mono_class_instance_size (klass);
- res = mono_object_new_alloc_specific_checked (vtable, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ res = mono_object_new_alloc_specific_checked (vtable, error);
+ return_val_if_nok (error, NULL);
size = size - sizeof (MonoObject);
#endif
#endif
if (klass->has_finalize) {
- mono_object_register_finalizer (res, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_object_register_finalizer (res, error);
+ return_val_if_nok (error, NULL);
}
return res;
}
* @obj: an object
* @klass: a pointer to a class
*
- * Returns: @obj if @obj is derived from @klass
+ * Returns: @obj if @obj is derived from @klass or NULL otherwise.
*/
MonoObject *
mono_object_isinst (MonoObject *obj, MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+ MonoObject *result = mono_object_isinst_checked (obj, klass, &error);
+ mono_error_cleanup (&error);
+ return result;
+}
+
+
+/**
+ * mono_object_isinst_checked:
+ * @obj: an object
+ * @klass: a pointer to a class
+ * @error: set on error
+ *
+ * Returns: @obj if @obj is derived from @klass or NULL if it isn't.
+ * On failure returns NULL and sets @error.
+ */
+MonoObject *
+mono_object_isinst_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
+ mono_error_init (error);
+
+ MonoObject *result = NULL;
+
if (!klass->inited)
mono_class_init (klass);
- if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE))
- return mono_object_isinst_mbyref (obj, klass);
+ if (mono_class_is_marshalbyref (klass) || (klass->flags & TYPE_ATTRIBUTE_INTERFACE)) {
+ result = mono_object_isinst_mbyref_checked (obj, klass, error);
+ return result;
+ }
if (!obj)
return NULL;
MONO_REQ_GC_UNSAFE_MODE;
MonoError error;
+ MonoObject *result = mono_object_isinst_mbyref_checked (obj, klass, &error);
+ mono_error_cleanup (&error); /* FIXME better API that doesn't swallow the error */
+ return result;
+}
+
+MonoObject *
+mono_object_isinst_mbyref_checked (MonoObject *obj, MonoClass *klass, MonoError *error)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+
MonoVTable *vt;
+ mono_error_init (error);
+
if (!obj)
return NULL;
im = mono_object_get_virtual_method (rp, im);
g_assert (im);
- pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ pa [0] = mono_type_get_object_checked (domain, &klass->byval_arg, error);
+ return_val_if_nok (error, NULL);
pa [1] = obj;
- res = mono_runtime_invoke_checked (im, rp, pa, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ res = mono_runtime_invoke_checked (im, rp, pa, error);
+ return_val_if_nok (error, NULL);
if (*(MonoBoolean *) mono_object_unbox(res)) {
/* Update the vtable of the remote type, so it can safely cast to this new type */
* @obj: an object
* @klass: a pointer to a class
*
- * Returns: @obj if @obj is derived from @klass, throws an exception otherwise
+ * Returns: @obj if @obj is derived from @klass, returns NULL otherwise.
*/
MonoObject *
mono_object_castclass_mbyref (MonoObject *obj, MonoClass *klass)
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
if (!obj) return NULL;
- if (mono_object_isinst_mbyref (obj, klass)) return obj;
-
- mono_raise_exception (mono_exception_from_name (mono_defaults.corlib,
- "System",
- "InvalidCastException"));
+ if (mono_object_isinst_mbyref_checked (obj, klass, &error)) return obj;
+ mono_error_cleanup (&error);
return NULL;
}
mono_ldstr (MonoDomain *domain, MonoImage *image, guint32 idx)
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
if (image->dynamic) {
- MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL);
+ MonoString *str = (MonoString *)mono_lookup_dynamic_token (image, MONO_TOKEN_STRING | idx, NULL, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
return str;
} else {
if (!mono_verifier_verify_string_signature (image, idx, NULL))
if (!im) {
im = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "PrivateInvoke", 4);
if (!im) {
- mono_error_set_generic_error (error, "System", "NotSupportedException", "Linked away.");
+ mono_error_set_not_supported (error, "Linked away.");
return NULL;
}
real_proxy->vtable->domain->private_invoke_method = im;
klass = mono_class_from_mono_type (sig->params [i]);
- if (klass->valuetype)
- arg = mono_value_box (domain, klass, vpos);
- else
+ if (klass->valuetype) {
+ arg = mono_value_box_checked (domain, klass, vpos, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)vpos);
mono_array_setref (msg->args, i, arg);
mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
}
- if (field_class->valuetype)
- arg = mono_value_box (domain, field_class, val);
- else
+ if (field_class->valuetype) {
+ arg = mono_value_box_checked (domain, field_class, val, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ } else
arg = *((MonoObject **)val);