* (C) 2002 Ximian, Inc.
* Copyright 2003-2011 Novell Inc (http://www.novell.com)
* Copyright 2011 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>
#include <math.h>
#include "jit-icalls.h"
#include <mono/utils/mono-error-internals.h>
#include <mono/metadata/threads-types.h>
+#include <mono/metadata/reflection-internals.h>
#ifdef ENABLE_LLVM
#include "mini-llvm-cpp.h"
mono_ldftn (MonoMethod *method)
{
gpointer addr;
+ MonoError error;
if (mono_llvm_only) {
// FIXME: No error handling
return addr;
}
- addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE);
-
+ addr = mono_create_jump_trampoline (mono_domain_get (), method, FALSE, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return mono_create_ftnptr (mono_domain_get (), addr);
}
void
mono_helper_stelem_ref_check (MonoArray *array, MonoObject *val)
{
+ MonoError error;
if (!array) {
mono_set_pending_exception (mono_get_exception_null_reference ());
return;
}
- if (val && !mono_object_isinst (val, array->obj.vtable->klass->element_class)) {
+ if (val && !mono_object_isinst_checked (val, array->obj.vtable->klass->element_class, &error)) {
+ if (mono_error_set_pending_exception (&error))
+ return;
mono_set_pending_exception (mono_get_exception_array_type_mismatch ());
return;
}
gpointer
mono_class_static_field_address (MonoDomain *domain, MonoClassField *field)
{
+ MonoError error;
MonoVTable *vtable;
gpointer addr;
mono_class_init (field->parent);
- vtable = mono_class_vtable_full (domain, field->parent, TRUE);
- if (!vtable->initialized)
- mono_runtime_class_init (vtable);
+ vtable = mono_class_vtable_full (domain, field->parent, &error);
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ if (!vtable->initialized) {
+ if (!mono_runtime_class_init_full (vtable, &error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ }
//printf ("SFLDA1 %p\n", (char*)vtable->data + field->offset);
return NULL;
}
- return mono_object_new (mono_domain_get (), klass);
+ MonoObject *obj = mono_object_new_checked (mono_domain_get (), klass, &error);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
+ return obj;
}
/*
MonoObject*
mono_object_castclass_unbox (MonoObject *obj, MonoClass *klass)
{
+ MonoError error;
MonoJitTlsData *jit_tls = NULL;
MonoClass *oklass;
oklass = obj->vtable->klass;
if ((klass->enumtype && oklass == klass->element_class) || (oklass->enumtype && klass == oklass->element_class))
return obj;
- if (mono_object_isinst (obj, klass))
+ if (mono_object_isinst_checked (obj, klass, &error))
return obj;
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
if (mini_get_debug_options ()->better_cast_details) {
jit_tls->class_cast_from = oklass;
MonoObject*
mono_object_castclass_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache)
{
+ MonoError error;
MonoJitTlsData *jit_tls = NULL;
gpointer cached_vtable, obj_vtable;
if (cached_vtable == obj_vtable)
return obj;
- if (mono_object_isinst (obj, klass)) {
+ if (mono_object_isinst_checked (obj, klass, &error)) {
*cache = obj_vtable;
return obj;
}
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
if (mini_get_debug_options ()->better_cast_details) {
jit_tls->class_cast_from = obj->vtable->klass;
MonoObject*
mono_object_isinst_with_cache (MonoObject *obj, MonoClass *klass, gpointer *cache)
{
+ MonoError error;
size_t cached_vtable, obj_vtable;
if (!obj)
return (cached_vtable & 0x1) ? NULL : obj;
}
- if (mono_object_isinst (obj, klass)) {
+ if (mono_object_isinst_checked (obj, klass, &error)) {
*cache = (gpointer)obj_vtable;
return obj;
} else {
+ if (mono_error_set_pending_exception (&error))
+ return NULL;
/*negative cache*/
*cache = (gpointer)(obj_vtable | 0x1);
return NULL;
}
static MonoMethod*
-constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg)
+constrained_gsharedvt_call_setup (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gpointer *this_arg, MonoError *error)
{
MonoMethod *m;
int vt_slot, iface_offset;
+ mono_error_init (error);
+
if (klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
MonoObject *this_obj;
/*
* Calling a non-vtype method with a vtype receiver, has to box.
*/
- *this_arg = mono_value_box (mono_domain_get (), klass, mp);
+ *this_arg = mono_value_box_checked (mono_domain_get (), klass, mp, error);
else if (klass->valuetype)
/*
* Calling a vtype method with a vtype receiver
* mono_gsharedvt_constrained_call:
*
* Make a call to CMETHOD using the receiver MP, which is assumed to be of type KLASS. ARGS contains
- * the arguments to the method in the format used by mono_runtime_invoke ().
+ * the arguments to the method in the format used by mono_runtime_invoke_checked ().
*/
MonoObject*
mono_gsharedvt_constrained_call (gpointer mp, MonoMethod *cmethod, MonoClass *klass, gboolean deref_arg, gpointer *args)
{
+ MonoError error;
+ MonoObject *o;
MonoMethod *m;
gpointer this_arg;
gpointer new_args [16];
- m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg);
+ m = constrained_gsharedvt_call_setup (mp, cmethod, klass, &this_arg, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
if (!m)
return NULL;
if (args && deref_arg) {
args [0] = this_arg;
this_arg = NULL;
}
- return mono_runtime_invoke (m, this_arg, args, NULL);
+
+ o = mono_runtime_invoke_checked (m, this_arg, args, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+
+ return o;
}
void
mono_gc_wbarrier_generic_store (dest, *(MonoObject**)src);
}
+void
+ves_icall_runtime_class_init (MonoVTable *vtable)
+{
+ MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
+
+ mono_runtime_class_init_full (vtable, &error);
+ mono_error_set_pending_exception (&error);
+}
+
+
void
mono_generic_class_init (MonoVTable *vtable)
{
- mono_runtime_class_init (vtable);
+ MonoError error;
+ mono_runtime_class_init_full (vtable, &error);
+ mono_error_set_pending_exception (&error);
}
gpointer
mono_fill_class_rgctx (MonoVTable *vtable, int index)
{
- return mono_class_fill_runtime_generic_context (vtable, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_class_fill_runtime_generic_context (vtable, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
gpointer
mono_fill_method_rgctx (MonoMethodRuntimeGenericContext *mrgctx, int index)
{
- return mono_method_fill_runtime_generic_context (mrgctx, index);
+ MonoError error;
+ gpointer res;
+
+ res = mono_method_fill_runtime_generic_context (mrgctx, index, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
+ return res;
}
/*
*/
if (G_UNLIKELY (!ftndesc)) {
gpointer addr = mono_compile_method (del->method);
+
+ if (del->method->klass->valuetype && mono_method_signature (del->method)->hasthis)
+ addr = mono_aot_get_unbox_trampoline (del->method);
+
gpointer arg = mini_get_delegate_arg (del->method, addr);
ftndesc = mini_create_llvmonly_ftndesc (mono_domain_get (), addr, arg);
del->method = method;
del->method_ptr = mono_compile_method (method);
+ if (method->klass->valuetype)
+ del->method_ptr = mono_aot_get_unbox_trampoline (method);
del->extra_arg = mini_get_delegate_arg (del->method, del->method_ptr);
}
MonoObject*
mono_get_assembly_object (MonoImage *image)
{
- return (MonoObject*)mono_assembly_get_object (mono_domain_get (), image->assembly);
+ MonoError error;
+ MonoObject *result;
+ result = (MonoObject*)mono_assembly_get_object_checked (mono_domain_get (), image->assembly, &error);
+ if (!result)
+ mono_error_set_pending_exception (&error);
+ return result;
}
MonoObject*
mono_get_method_object (MonoMethod *method)
{
- return (MonoObject*)mono_method_get_object (mono_domain_get (), method, method->klass);
+ MonoError error;
+ MonoObject * result;
+ result = (MonoObject*)mono_method_get_object_checked (mono_domain_get (), method, method->klass, &error);
+ mono_error_set_pending_exception (&error);
+ return result;
}
double
return d;
}
-void
-mono_llvmonly_set_calling_assembly (MonoImage *image)
-{
- MonoJitTlsData *jit_tls = NULL;
-
- jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
- g_assert (jit_tls);
- jit_tls->calling_image = image;
-}
-
-MonoObject*
-mono_llvmonly_get_calling_assembly (void)
-{
- MonoJitTlsData *jit_tls = NULL;
-
- jit_tls = (MonoJitTlsData *)mono_native_tls_get_value (mono_jit_tls_id);
- g_assert (jit_tls);
- if (!jit_tls->calling_image) {
- mono_set_pending_exception (mono_get_exception_not_supported ("Stack walks are not supported on this platform."));
- return NULL;
- }
- return (MonoObject*)mono_assembly_get_object (mono_domain_get (), jit_tls->calling_image->assembly);
-}
-
/*
* mono_interruption_checkpoint_from_trampoline:
*