Merge pull request #3247 from lateralusX/jlorenss/win-x64-lmf-exception
[mono.git] / mono / metadata / marshal.c
index 4d7f6cb95a1069c95ce4ad51e24fddfc9f19cece..3edf257bee53630bcae260331657d73c757d2a3a 100644 (file)
@@ -45,6 +45,7 @@
 #include "mono/utils/mono-memory-model.h"
 #include "mono/utils/atomic.h"
 #include <mono/utils/mono-threads.h>
+#include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-error-internals.h>
 
 #include <string.h>
@@ -86,6 +87,9 @@ static MonoFtnPtrEHCallback ftnptr_eh_callback = ftnptr_eh_callback_default;
 static void
 delegate_hash_table_add (MonoDelegate *d);
 
+static void
+delegate_hash_table_remove (MonoDelegate *d);
+
 static void
 emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object);
 
@@ -263,6 +267,15 @@ ves_icall_mono_string_from_utf16 (gunichar2 *data)
        return result;
 }
 
+static char*
+ves_icall_mono_string_to_utf8 (MonoString *str)
+{
+       MonoError error;
+       char *result = mono_string_to_utf8_checked (str, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
+}
+
 void
 mono_marshal_init (void)
 {
@@ -282,7 +295,7 @@ mono_marshal_init (void)
                register_icall (mono_string_from_byvalwstr, "mono_string_from_byvalwstr", "obj ptr int", FALSE);
                register_icall (mono_string_new_wrapper, "mono_string_new_wrapper", "obj ptr", FALSE);
                register_icall (mono_string_new_len_wrapper, "mono_string_new_len_wrapper", "obj ptr int", FALSE);
-               register_icall (mono_string_to_utf8, "mono_string_to_utf8", "ptr obj", FALSE);
+               register_icall (ves_icall_mono_string_to_utf8, "ves_icall_mono_string_to_utf8", "ptr obj", FALSE);
                register_icall (mono_string_to_lpstr, "mono_string_to_lpstr", "ptr obj", FALSE);
                register_icall (mono_string_to_ansibstr, "mono_string_to_ansibstr", "ptr object", FALSE);
                register_icall (mono_string_builder_to_utf8, "mono_string_builder_to_utf8", "ptr object", FALSE);
@@ -314,7 +327,6 @@ mono_marshal_init (void)
                register_icall (mono_struct_delete_old, "mono_struct_delete_old", "void ptr ptr", FALSE);
                register_icall (mono_delegate_begin_invoke, "mono_delegate_begin_invoke", "object object ptr", FALSE);
                register_icall (mono_delegate_end_invoke, "mono_delegate_end_invoke", "object object ptr", FALSE);
-               register_icall (mono_compile_method, "mono_compile_method", "ptr ptr", FALSE);
                register_icall (mono_context_get, "mono_context_get", "object", FALSE);
                register_icall (mono_context_set, "mono_context_set", "void object", FALSE);
                register_icall (mono_gc_wbarrier_generic_nostore, "wb_generic", "void ptr", FALSE);
@@ -324,6 +336,8 @@ mono_marshal_init (void)
                register_icall (mono_marshal_ftnptr_eh_callback, "mono_marshal_ftnptr_eh_callback", "void uint32", TRUE);
                register_icall (mono_threads_enter_gc_safe_region_unbalanced, "mono_threads_enter_gc_safe_region_unbalanced", "ptr ptr", TRUE);
                register_icall (mono_threads_exit_gc_safe_region_unbalanced, "mono_threads_exit_gc_safe_region_unbalanced", "void ptr ptr", TRUE);
+               register_icall (mono_threads_attach_coop, "mono_threads_attach_coop", "ptr ptr ptr", TRUE);
+               register_icall (mono_threads_detach_coop, "mono_threads_detach_coop", "void ptr ptr", TRUE);
 
                mono_cominterop_init ();
                mono_remoting_init ();
@@ -395,19 +409,22 @@ mono_delegate_to_ftnptr (MonoDelegate *delegate)
 
        wrapper = mono_marshal_get_managed_wrapper (method, klass, target_handle);
 
-       delegate->delegate_trampoline = mono_compile_method (wrapper);
+       delegate->delegate_trampoline = mono_compile_method_checked (wrapper, &error);
+       if (!is_ok (&error))
+               goto fail;
 
        // Add the delegate to the delegate hash table
        delegate_hash_table_add (delegate);
 
        /* when the object is collected, collect the dynamic method, too */
-       mono_object_register_finalizer ((MonoObject*)delegate, &error);
-       if (!mono_error_ok (&error)) {
-               mono_error_set_pending_exception (&error);
-               return NULL;
-       }
+       mono_object_register_finalizer ((MonoObject*)delegate);
 
        return delegate->delegate_trampoline;
+
+fail:
+       mono_gchandle_free (target_handle);
+       mono_error_set_pending_exception (&error);
+       return NULL;
 }
 
 /* 
@@ -572,7 +589,12 @@ mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
                        mono_error_set_pending_exception (&error);
                        return NULL;
                }
-               mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, mono_compile_method (wrapper), wrapper);
+               gpointer compiled_ptr = mono_compile_method_checked (wrapper, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
+               mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, compiled_ptr, wrapper, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
        }
 
        if (d->object.vtable->domain != mono_domain_get ()) {
@@ -940,7 +962,7 @@ mono_string_utf16_to_builder (MonoStringBuilder *sb, gunichar2 *text)
  *
  * Returns: a utf8 string with the contents of the StringBuilder.
  *
- * The return value must be released with g_free.
+ * The return value must be released with mono_marshal_free.
  *
  * This is a JIT icall, it sets the pending exception and returns NULL on error.
  */
@@ -961,14 +983,14 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
 
        if (gerror) {
                g_error_free (gerror);
-               g_free (str_utf16);
+               mono_marshal_free (str_utf16);
                mono_set_pending_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
                return NULL;
        } else {
                guint len = mono_string_builder_capacity (sb) + 1;
                gchar *res = (gchar *)mono_marshal_alloc (len * sizeof (gchar), &error);
                if (!mono_error_ok (&error)) {
-                       g_free (str_utf16);
+                       mono_marshal_free (str_utf16);
                        g_free (tmp);
                        mono_error_set_pending_exception (&error);
                        return NULL;
@@ -978,7 +1000,7 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
                memcpy (res, tmp, str_len * sizeof (gchar));
                res[str_len] = '\0';
 
-               g_free (str_utf16);
+               mono_marshal_free (str_utf16);
                g_free (tmp);
                return res;
        }
@@ -992,7 +1014,8 @@ mono_string_builder_to_utf8 (MonoStringBuilder *sb)
  *
  * Returns: a utf16 string with the contents of the StringBuilder.
  *
- * The return value must not be freed.
+ * The return value must be released with mono_marshal_free.
+ *
  * This is a JIT icall, it sets the pending exception and returns NULL on error.
  */
 gunichar2*
@@ -1072,7 +1095,10 @@ mono_string_to_lpstr (MonoString *s)
                return as;
        }
 #else
-       return mono_string_to_utf8 (s);
+       MonoError error;
+       char *result = mono_string_to_utf8_checked (s, &error);
+       mono_error_set_pending_exception (&error);
+       return result;
 #endif
 }      
 
@@ -1095,6 +1121,7 @@ mono_string_to_ansibstr (MonoString *string_obj)
 void
 mono_string_to_byvalstr (gpointer dst, MonoString *src, int size)
 {
+       MonoError error;
        char *s;
        int len;
 
@@ -1105,7 +1132,9 @@ mono_string_to_byvalstr (gpointer dst, MonoString *src, int size)
        if (!src)
                return;
 
-       s = mono_string_to_utf8 (src);
+       s = mono_string_to_utf8_checked (src, &error);
+       if (mono_error_set_pending_exception (&error))
+               return;
        len = MIN (size, strlen (s));
        if (len >= size)
                len--;
@@ -2224,8 +2253,12 @@ mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
                        MonoArray *out_args;
                        method = delegate->method;
 
-                       msg = mono_method_call_message_new (mono_marshal_method_from_wrapper (method), params, NULL, &async_callback, &state);
-                       ares = mono_async_result_new (mono_domain_get (), NULL, state, NULL, NULL);
+                       msg = mono_method_call_message_new (mono_marshal_method_from_wrapper (method), params, NULL, &async_callback, &state, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
+                       ares = mono_async_result_new (mono_domain_get (), NULL, state, NULL, NULL, &error);
+                       if (mono_error_set_pending_exception (&error))
+                               return NULL;
                        MONO_OBJECT_SETREF (ares, async_delegate, (MonoObject *)delegate);
                        MONO_OBJECT_SETREF (ares, async_callback, (MonoObject *)async_callback);
                        MONO_OBJECT_SETREF (msg, async_result, ares);
@@ -2952,7 +2985,9 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
 
        sig = mono_signature_no_pinvoke (method);
 
-       msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
+       msg = mono_method_call_message_new (method, params, NULL, NULL, NULL, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
 
        ares = (MonoAsyncResult *)mono_array_get (msg->args, gpointer, sig->param_count - 1);
        if (ares == NULL) {
@@ -2974,7 +3009,9 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
                        mono_error_set_pending_exception (&error);
                        return NULL;
                }
-               mono_message_init (domain, msg, delegate->method_info, NULL);
+               mono_message_init (domain, msg, delegate->method_info, NULL, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
                msg->call_type = CallType_EndInvoke;
                MONO_OBJECT_SETREF (msg, async_result, ares);
                res = mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args, &error);
@@ -2985,17 +3022,23 @@ mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
        } else
 #endif
        {
-               res = mono_threadpool_ms_end_invoke (ares, &out_args, &exc);
+               res = mono_threadpool_ms_end_invoke (ares, &out_args, &exc, &error);
+               if (mono_error_set_pending_exception (&error))
+                       return NULL;
        }
 
        if (exc) {
                if (((MonoException*)exc)->stack_trace) {
-                       char *strace = mono_string_to_utf8 (((MonoException*)exc)->stack_trace);
-                       char  *tmp;
-                       tmp = g_strdup_printf ("%s\nException Rethrown at:\n", strace);
-                       g_free (strace);        
-                       MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, mono_string_new (domain, tmp));
-                       g_free (tmp);
+                       MonoError inner_error;
+                       char *strace = mono_string_to_utf8_checked (((MonoException*)exc)->stack_trace, &inner_error);
+                       if (is_ok (&inner_error)) {
+                               char  *tmp;
+                               tmp = g_strdup_printf ("%s\nException Rethrown at:\n", strace);
+                               g_free (strace);        
+                               MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, mono_string_new (domain, tmp));
+                               g_free (tmp);
+                       } else
+                               mono_error_cleanup (&inner_error); /* no stack trace, but at least throw the original exception */
                }
                mono_set_pending_exception ((MonoException*)exc);
        }
@@ -4177,7 +4220,6 @@ mono_marshal_get_runtime_invoke (MonoMethod *method, gboolean virtual_)
  * ARGS should contain the this argument too.
  * This wrapper serves the same purpose as the runtime-invoke wrappers, but there
  * is only one copy of it, which is useful in full-aot.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_runtime_invoke_dynamic (void)
@@ -4404,7 +4446,6 @@ mono_mb_emit_auto_layout_exception (MonoMethodBuilder *mb, MonoClass *klass)
 /*
  * generates IL code for the icall wrapper (the generated method
  * calls the unmanaged code in func)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gconstpointer func, gboolean check_exceptions)
@@ -4415,6 +4456,10 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon
        int i;
        WrapperInfo *info;
        
+       GHashTable *cache = get_cache (&mono_defaults.object_class->image->icall_wrapper_cache, mono_aligned_addr_hash, NULL);
+       if ((res = mono_marshal_find_in_cache (cache, (gpointer) func)))
+               return res;
+
        g_assert (sig->pinvoke);
 
        mb = mono_mb_new (mono_defaults.object_class, name, MONO_WRAPPER_MANAGED_TO_NATIVE);
@@ -4449,7 +4494,7 @@ mono_marshal_get_icall_wrapper (MonoMethodSignature *sig, const char *name, gcon
 
        info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_ICALL_WRAPPER);
        info->d.icall.func = (gpointer)func;
-       res = mono_mb_create (mb, csig, csig->param_count + 16, info);
+       res = mono_mb_create_and_cache_full (cache, (gpointer) func, mb, csig, csig->param_count + 16, info, NULL);
        mono_mb_free (mb);
 
        return res;
@@ -7282,7 +7327,6 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
        MonoClass *klass;
        int i, argnum, *tmp_locals;
        int type, param_shift = 0;
-       static MonoMethodSignature *get_last_error_sig = NULL;
        int coop_gc_stack_dummy, coop_gc_var;
 
        memset (&m, 0, sizeof (m));
@@ -7408,33 +7452,16 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
                }
        }
 
-       if (MONO_TYPE_ISSTRUCT (sig->ret)) {
-               MonoClass *klass = mono_class_from_mono_type (sig->ret);
-               mono_class_init (klass);
-               if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
-                       /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
-                       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
-                       mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
-                       mono_mb_emit_stloc (mb, m.vtaddr_var);
-               }
-       }
-
-       /* Unblock before converting the result, since that can involve calls into the runtime */
-       if (mono_threads_is_coop_enabled ()) {
-               mono_mb_emit_ldloc (mb, coop_gc_var);
-               mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
-               mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
-       }
-
        /* Set LastError if needed */
        if (piinfo->piflags & PINVOKE_ATTRIBUTE_SUPPORTS_LAST_ERROR) {
+#ifdef TARGET_WIN32
+               static MonoMethodSignature *get_last_error_sig = NULL;
                if (!get_last_error_sig) {
                        get_last_error_sig = mono_metadata_signature_alloc (mono_defaults.corlib, 0);
                        get_last_error_sig->ret = &mono_defaults.int_class->byval_arg;
                        get_last_error_sig->pinvoke = 1;
                }
 
-#ifdef TARGET_WIN32
                /*
                 * Have to call GetLastError () early and without a wrapper, since various runtime components could
                 * clobber its value.
@@ -7446,6 +7473,24 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
 #endif
        }
 
+       if (MONO_TYPE_ISSTRUCT (sig->ret)) {
+               MonoClass *klass = mono_class_from_mono_type (sig->ret);
+               mono_class_init (klass);
+               if (!(((klass->flags & TYPE_ATTRIBUTE_LAYOUT_MASK) == TYPE_ATTRIBUTE_EXPLICIT_LAYOUT) || klass->blittable)) {
+                       /* This is used by emit_marshal_vtype (), but it needs to go right before the call */
+                       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+                       mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
+                       mono_mb_emit_stloc (mb, m.vtaddr_var);
+               }
+       }
+
+       /* Unblock before converting the result, since that can involve calls into the runtime */
+       if (mono_threads_is_coop_enabled ()) {
+               mono_mb_emit_ldloc (mb, coop_gc_var);
+               mono_mb_emit_ldloc_addr (mb, coop_gc_stack_dummy);
+               mono_mb_emit_icall (mb, mono_threads_exit_gc_safe_region_unbalanced);
+       }
+
        /* convert the result */
        if (!sig->ret->byref) {
                MonoMarshalSpec *spec = mspecs [0];
@@ -7547,7 +7592,6 @@ mono_marshal_emit_native_wrapper (MonoImage *image, MonoMethodBuilder *mb, MonoM
  *
  * generates IL code for the pinvoke wrapper (the generated method
  * calls the unmanaged code in piinfo->addr)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_native_wrapper (MonoMethod *method, gboolean check_exceptions, gboolean aot)
@@ -7943,7 +7987,7 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
 #else
        MonoMethodSignature *sig, *csig;
        MonoExceptionClause *clauses, *clause_finally, *clause_catch;
-       int i, *tmp_locals, ex_local, e_local;
+       int i, *tmp_locals, ex_local, e_local, attach_cookie_local, attach_dummy_local;
        int leave_try_pos, leave_catch_pos, ex_m1_pos;
        gboolean closed = FALSE;
 
@@ -7978,10 +8022,14 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
        ex_local = mono_mb_add_local (mb, &mono_defaults.uint32_class->byval_arg);
        e_local = mono_mb_add_local (mb, &mono_defaults.exception_class->byval_arg);
 
+       attach_cookie_local = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+       attach_dummy_local = mono_mb_add_local (mb, &mono_defaults.int_class->byval_arg);
+
        /*
         * guint32 ex = -1;
         * try {
-        *   mono_jit_attach ();
+        *   // does (STARTING|RUNNING|BLOCKING) -> RUNNING + set/switch domain
+        *   mono_threads_attach_coop ();
         *
         *   <interrupt check>
         *
@@ -7989,7 +8037,8 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
         * } catch (Exception e) {
         *   ex = mono_gchandle_new (e, false);
         * } finally {
-        *   mono_jit_detach ();
+        *   // does RUNNING -> (RUNNING|BLOCKING) + unset/switch domain
+        *   mono_threads_detach_coop ();
         *
         *   if (ex != -1)
         *     mono_marshal_ftnptr_eh_callback (ex);
@@ -8017,16 +8066,17 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
        /* try { */
        clause_catch->try_offset = clause_finally->try_offset = mono_mb_get_label (mb);
 
-       /*
-        * Might need to attach the thread to the JIT or change the
-        * domain for the callback.
-        *
-        * Also does the (STARTING|BLOCKING|RUNNING) -> RUNNING thread state transtion
-        *
-        * mono_jit_attach ();
-        */
-       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
-       mono_mb_emit_byte (mb, CEE_MONO_JIT_ATTACH);
+       if (!mono_threads_is_coop_enabled ()) {
+               mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+               mono_mb_emit_byte (mb, CEE_MONO_JIT_ATTACH);
+       } else {
+               /* mono_threads_attach_coop (); */
+               mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+               mono_mb_emit_byte (mb, CEE_MONO_LDDOMAIN);
+               mono_mb_emit_ldloc_addr (mb, attach_dummy_local);
+               mono_mb_emit_icall (mb, mono_threads_attach_coop);
+               mono_mb_emit_stloc (mb, attach_cookie_local);
+       }
 
        /* <interrupt check> */
        emit_thread_interrupt_checkpoint (mb);
@@ -8194,13 +8244,15 @@ mono_marshal_emit_managed_wrapper (MonoMethodBuilder *mb, MonoMethodSignature *i
        clause_finally->try_len = mono_mb_get_label (mb) - clause_finally->try_offset;
        clause_finally->handler_offset = mono_mb_get_label (mb);
 
-       /*
-        * Also does the RUNNING -> (BLOCKING|RUNNING) thread state transition
-        *
-        * mono_jit_detach ();
-        */
-       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
-       mono_mb_emit_byte (mb, CEE_MONO_JIT_DETACH);
+       if (!mono_threads_is_coop_enabled ()) {
+               mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+               mono_mb_emit_byte (mb, CEE_MONO_JIT_DETACH);
+       } else {
+               /* mono_threads_detach_coop (); */
+               mono_mb_emit_ldloc (mb, attach_cookie_local);
+               mono_mb_emit_ldloc_addr (mb, attach_dummy_local);
+               mono_mb_emit_icall (mb, mono_threads_detach_coop);
+       }
 
        /* if (ex != -1) */
        mono_mb_emit_ldloc (mb, ex_local);
@@ -8501,7 +8553,9 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
                                mono_metadata_free_marshal_spec (mspecs [i]);
                g_free (mspecs);
 
-               return mono_compile_method (method);
+               gpointer compiled_ptr = mono_compile_method_checked (method, &error);
+               mono_error_assert_ok (&error);
+               return compiled_ptr;
        }
 
        sig = mono_method_signature (method);
@@ -8524,7 +8578,9 @@ mono_marshal_get_vtfixup_ftnptr (MonoImage *image, guint32 token, guint16 type)
        method = mono_mb_create (mb, sig, param_count, NULL);
        mono_mb_free (mb);
 
-       return mono_compile_method (method);
+       gpointer compiled_ptr = mono_compile_method_checked (method, &error);
+       mono_error_assert_ok (&error);
+       return compiled_ptr;
 }
 
 #ifndef DISABLE_JIT
@@ -8594,7 +8650,6 @@ generate_check_cache (int obj_arg_position, int class_arg_position, int cache_ar
 
 /*
  * This does the equivalent of mono_object_castclass_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_castclass_with_cache (void)
@@ -8655,12 +8710,14 @@ mono_marshal_get_castclass_with_cache (void)
        return cached;
 }
 
+/* this is an icall */
 static MonoObject *
 mono_marshal_isinst_with_cache (MonoObject *obj, MonoClass *klass, uintptr_t *cache)
 {
        MonoError error;
        MonoObject *isinst = mono_object_isinst_checked (obj, klass, &error);
-       mono_error_raise_exception (&error); /* FIXME don't raise here */
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
 
 #ifndef DISABLE_REMOTING
        if (obj->vtable->klass == mono_defaults.transparent_proxy_class)
@@ -8678,7 +8735,6 @@ mono_marshal_isinst_with_cache (MonoObject *obj, MonoClass *klass, uintptr_t *ca
 
 /*
  * This does the equivalent of mono_object_isinst_with_cache.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_isinst_with_cache (void)
@@ -8855,7 +8911,6 @@ mono_marshal_get_isinst (MonoClass *klass)
  * an instance of the given type, icluding the case where the object is a proxy.
  * The generated function has the following signature:
  * MonoObject* __castclass_wrapper_ (MonoObject *obj)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_castclass (MonoClass *klass)
@@ -8938,7 +8993,6 @@ mono_marshal_get_castclass (MonoClass *klass)
  * @klass:
  *
  * generates IL code for StructureToPtr (object structure, IntPtr ptr, bool fDeleteOld)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_struct_to_ptr (MonoClass *klass)
@@ -9012,7 +9066,6 @@ mono_marshal_get_struct_to_ptr (MonoClass *klass)
  * @klass:
  *
  * generates IL code for PtrToStructure (IntPtr src, object structure)
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_ptr_to_struct (MonoClass *klass)
@@ -9091,7 +9144,6 @@ mono_marshal_get_ptr_to_struct (MonoClass *klass)
  * This is used to avoid infinite recursion since it is hard to determine where to
  * replace a method with its synchronized wrapper, and where not.
  * The runtime should execute METHOD instead of the wrapper.
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod *
 mono_marshal_get_synchronized_inner_wrapper (MonoMethod *method)
@@ -9459,8 +9511,6 @@ record_slot_vstore (MonoObject *array, size_t index, MonoObject *value)
 #endif
 
 /*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- *
  * TODO:
  *     - Separate simple interfaces from variant interfaces or mbr types. This way we can avoid the icall for them.
  *     - Emit a (new) mono bytecode that produces OP_COND_EXC_NE_UN to raise ArrayTypeMismatch
@@ -9869,9 +9919,6 @@ mono_marshal_get_virtual_stelemref_wrappers (int *nwrappers)
        return res;
 }
 
-/*
- * The wrapper info for the wrapper is a WrapperInfo structure.
- */
 MonoMethod*
 mono_marshal_get_stelemref (void)
 {
@@ -10022,8 +10069,6 @@ mono_marshal_get_stelemref (void)
  * mono_marshal_get_gsharedvt_in_wrapper:
  *
  *   This wrapper handles calls from normal code to gsharedvt code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_gsharedvt_in_wrapper (void)
@@ -10058,8 +10103,6 @@ mono_marshal_get_gsharedvt_in_wrapper (void)
  * mono_marshal_get_gsharedvt_out_wrapper:
  *
  *   This wrapper handles calls from gsharedvt code to normal code.
- *
- * The wrapper info for the wrapper is a WrapperInfo structure.
  */
 MonoMethod*
 mono_marshal_get_gsharedvt_out_wrapper (void)
@@ -10738,6 +10781,7 @@ ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure_type (gpointer s
 int
 ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *type, MonoString *field_name)
 {
+       MonoError error;
        MonoMarshalType *info;
        MonoClass *klass;
        char *fname;
@@ -10746,7 +10790,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *t
        MONO_CHECK_ARG_NULL (type, 0);
        MONO_CHECK_ARG_NULL (field_name, 0);
 
-       fname = mono_string_to_utf8 (field_name);
+       fname = mono_string_to_utf8_checked (field_name, &error);
+       if (mono_error_set_pending_exception (&error))
+               return 0;
        klass = mono_class_from_mono_type (type->type);
        if (!mono_class_init (klass)) {
                mono_set_pending_exception (mono_class_get_exception_for_failure (klass));
@@ -10795,10 +10841,13 @@ ves_icall_System_Runtime_InteropServices_Marshal_OffsetOf (MonoReflectionType *t
 gpointer
 ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString *string)
 {
+       MonoError error;
 #ifdef HOST_WIN32
        char* tres, *ret;
        size_t len;
-       tres = mono_string_to_utf8 (string);
+       tres = mono_string_to_utf8_checked (string, &error);
+       if (mono_error_set_pending_exception (&error))
+               return NULL;
        if (!tres)
                return tres;
 
@@ -10809,7 +10858,9 @@ ves_icall_System_Runtime_InteropServices_Marshal_StringToHGlobalAnsi (MonoString
        return ret;
 
 #else
-       return mono_string_to_utf8 (string);
+       char *ret = mono_string_to_utf8_checked (string, &error);
+       mono_error_set_pending_exception (&error);
+       return ret;
 #endif
 }