#include "mono/metadata/exception.h"
#include "mono/metadata/debug-helpers.h"
#include "mono/metadata/reflection-internals.h"
+#include "mono/metadata/assembly.h"
typedef enum {
MONO_MARSHAL_NONE, /* No marshalling needed */
static MonoObject *
mono_remoting_wrapper (MonoMethod *method, gpointer *params);
+static MonoException *
+mono_remoting_update_exception (MonoException *exc);
+
static gint32
mono_marshal_set_domain_by_id (gint32 id, MonoBoolean push);
static MonoReflectionType *
type_from_handle (MonoType *handle);
+static void
+mono_context_set_icall (MonoAppContext *new_context);
+
+static MonoAppContext*
+mono_context_get_icall (void);
+
+
/* Class lazy loading functions */
static GENERATE_GET_CLASS_WITH_CACHE (remoting_services, "System.Runtime.Remoting", "RemotingServices")
static GENERATE_GET_CLASS_WITH_CACHE (call_context, "System.Runtime.Remoting.Messaging", "CallContext")
register_icall (ves_icall_mono_marshal_xdomain_copy_value, "ves_icall_mono_marshal_xdomain_copy_value", "object object", FALSE);
register_icall (mono_marshal_xdomain_copy_out_value, "mono_marshal_xdomain_copy_out_value", "void object object", FALSE);
register_icall (mono_remoting_wrapper, "mono_remoting_wrapper", "object ptr ptr", FALSE);
+ register_icall (mono_remoting_update_exception, "mono_remoting_update_exception", "object object", FALSE);
register_icall (mono_upgrade_remote_class_wrapper, "mono_upgrade_remote_class_wrapper", "void object object", FALSE);
#ifndef DISABLE_JIT
register_icall (mono_compile_method_icall, "mono_compile_method_icall", "ptr ptr", FALSE);
#endif
+ register_icall (mono_context_get_icall, "mono_context_get_icall", "object", FALSE);
+ register_icall (mono_context_set_icall, "mono_context_set_icall", "void object", FALSE);
+
}
icalls_registered = TRUE;
if (exc) {
error_init (&error);
+ exc = (MonoObject*) mono_remoting_update_exception ((MonoException*)exc);
mono_error_set_exception_instance (&error, (MonoException *)exc);
goto fail;
}
return NULL;
}
+/*
+ * Handles exception transformation at appdomain call boundary.
+ * Note this is called from target appdomain inside xdomain wrapper, but from
+ * source domain in the mono_remoting_wrapper slowpath.
+ */
+static MonoException *
+mono_remoting_update_exception (MonoException *exc)
+{
+ MonoInternalThread *thread;
+ MonoClass *klass = mono_object_get_class ((MonoObject*)exc);
+
+ /* Serialization error can only happen when still in the target appdomain */
+ if (!(mono_class_get_flags (klass) & TYPE_ATTRIBUTE_SERIALIZABLE)) {
+ MonoException *ret;
+ char *aname = mono_stringify_assembly_name (&klass->image->assembly->aname);
+ char *message = g_strdup_printf ("Type '%s' in Assembly '%s' is not marked as serializable", klass->name, aname);
+ ret = mono_get_exception_serialization (message);
+ g_free (aname);
+ g_free (message);
+ return ret;
+ }
+
+ thread = mono_thread_internal_current ();
+ if (mono_object_get_class ((MonoObject*)exc) == mono_defaults.threadabortexception_class &&
+ thread->flags & MONO_THREAD_FLAG_APPDOMAIN_ABORT) {
+ mono_thread_internal_reset_abort (thread);
+ return mono_get_exception_appdomain_unloaded ();
+ }
+ return exc;
+}
+
+/**
+ * mono_marshal_get_remoting_invoke:
+ */
MonoMethod *
mono_marshal_get_remoting_invoke (MonoMethod *method)
{
/* handler code */
main_clause->handler_offset = mono_mb_get_label (mb);
+
+ mono_mb_emit_icall (mb, mono_remoting_update_exception);
+ mono_mb_emit_op (mb, CEE_CASTCLASS, mono_defaults.exception_class);
mono_mb_emit_managed_call (mb, method_rs_serialize_exc, NULL);
mono_mb_emit_stloc (mb, loc_serialized_exc);
mono_mb_emit_ldarg (mb, 2);
mono_mb_emit_ldloc (mb, loc_serialized_exc);
mono_mb_emit_byte (mb, CEE_STIND_REF);
mono_mb_emit_branch (mb, CEE_LEAVE);
+
main_clause->handler_len = mono_mb_get_pos (mb) - main_clause->handler_offset;
/* end catch */
-
mono_mb_patch_branch (mb, pos_leave);
if (copy_return)
return res;
}
-/* mono_marshal_get_xappdomain_invoke ()
+/**
+ * mono_marshal_get_xappdomain_invoke:
* Generates a fast remoting wrapper for cross app domain calls.
*/
MonoMethod *
/* Save thread domain data */
- mono_mb_emit_icall (mb, mono_context_get);
+ mono_mb_emit_icall (mb, mono_context_get_icall);
mono_mb_emit_byte (mb, CEE_DUP);
mono_mb_emit_stloc (mb, loc_context);
/* Restore thread domain data */
mono_mb_emit_ldloc (mb, loc_context);
- mono_mb_emit_icall (mb, mono_context_set);
+ mono_mb_emit_icall (mb, mono_context_set_icall);
/* if (loc_serialized_exc != null) ... */
return res;
}
+/**
+ * mono_marshal_get_remoting_invoke_for_target:
+ */
MonoMethod *
mono_marshal_get_remoting_invoke_for_target (MonoMethod *method, MonoRemotingTarget target_type)
{
return compiled_ptr;
}
+/**
+ * mono_marshal_get_remoting_invoke_with_check:
+ */
MonoMethod *
mono_marshal_get_remoting_invoke_with_check (MonoMethod *method)
{
return res;
}
-/*
+/**
* mono_marshal_get_ldfld_wrapper:
- * @type: the type of the field
+ * \param type the type of the field
*
* This method generates a function which can be use to load a field with type
- * @type from an object. The generated function has the following signature:
- * <@type> ldfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset)
+ * \p type from an object. The generated function has the following signature:
+ *
+ * <code><i>type</i> ldfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset)</code>
*/
MonoMethod *
mono_marshal_get_ldfld_wrapper (MonoType *type)
mono_mb_emit_byte (mb, CEE_LDIND_REF);
mono_mb_emit_ldflda (mb, MONO_STRUCT_OFFSET (MonoRealProxy, context));
mono_mb_emit_byte (mb, CEE_LDIND_REF);
- mono_mb_emit_icall (mb, mono_context_get);
+ mono_mb_emit_icall (mb, mono_context_get_icall);
pos3 = mono_mb_emit_branch (mb, CEE_BEQ);
mono_mb_emit_exception_full (mb, "System", "InvalidOperationException", "Attempt to load field address from object in another context.");
}
-/*
+/**
* mono_marshal_get_stfld_wrapper:
- * @type: the type of the field
+ * \param type the type of the field
*
* This method generates a function which can be use to store a field with type
- * @type. The generated function has the following signature:
- * void stfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset, <@type> val)
+ * \p type. The generated function has the following signature:
+ *
+ * <code>void stfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset, <i>type</i> val)</code>
*/
MonoMethod *
mono_marshal_get_stfld_wrapper (MonoType *type)
return res;
}
+/**
+ * mono_marshal_get_proxy_cancast:
+ */
MonoMethod *
mono_marshal_get_proxy_cancast (MonoClass *klass)
{
/**
* mono_marshal_xdomain_copy_value_handle:
- * @val: The value to copy.
- * @error: set on failure.
- *
- * Makes a copy of @val suitable for the current domain.
- * On failure returns NULL and sets @error.
+ * \param val The value to copy.
+ * \param error set on failure.
+ * Makes a copy of \p val suitable for the current domain.
+ * On failure returns NULL and sets \p error.
*/
MonoObjectHandle
mono_marshal_xdomain_copy_value_handle (MonoObjectHandle val, MonoError *error)
mono_error_set_pending_exception (&error);
return result;
}
+
+void
+mono_context_set_icall (MonoAppContext *new_context_raw)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MONO_HANDLE_DCL (MonoAppContext, new_context);
+ mono_context_set_handle (new_context);
+ HANDLE_FUNCTION_RETURN ();
+}
+
+static MonoAppContext*
+mono_context_get_icall (void)
+{
+ HANDLE_FUNCTION_ENTER ();
+ MonoAppContextHandle context = mono_context_get_handle ();
+ HANDLE_FUNCTION_RETURN_OBJ (context);
+}