X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fremoting.c;h=dccb077b4f72cc41ccf1b0a47e9dee452794ad3d;hb=76640001ebd9d400a59c78cf98d29c4616f6fd2e;hp=ecc5f94248485b893960e154aeda2b7b1d1a6d61;hpb=d2a6ce3a93e6a54b7835262609580c4acc034fa9;p=mono.git diff --git a/mono/metadata/remoting.c b/mono/metadata/remoting.c index ecc5f942484..dccb077b4f7 100644 --- a/mono/metadata/remoting.c +++ b/mono/metadata/remoting.c @@ -1,5 +1,6 @@ -/* - * remoting.c: Remoting support +/** + * \file + * Remoting support * * Copyright 2002-2003 Ximian, Inc (http://www.ximian.com) * Copyright 2004-2009 Novell, Inc (http://www.novell.com) @@ -20,6 +21,7 @@ #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 */ @@ -51,6 +53,9 @@ typedef struct _MonoRemotingMethods MonoRemotingMethods; 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); @@ -69,6 +74,13 @@ mono_marshal_xdomain_copy_out_value (MonoObject *src, MonoObject *dst); 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") @@ -198,12 +210,16 @@ mono_remoting_marshal_init (void) 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; @@ -414,6 +430,7 @@ mono_remoting_wrapper (MonoMethod *method, gpointer *params) if (exc) { error_init (&error); + exc = (MonoObject*) mono_remoting_update_exception ((MonoException*)exc); mono_error_set_exception_instance (&error, (MonoException *)exc); goto fail; } @@ -433,7 +450,41 @@ 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) { @@ -880,15 +931,18 @@ mono_marshal_get_xappdomain_dispatch (MonoMethod *method, int *marshal_types, in /* 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) @@ -907,7 +961,8 @@ mono_marshal_get_xappdomain_dispatch (MonoMethod *method, int *marshal_types, in return res; } -/* mono_marshal_get_xappdomain_invoke () +/** + * mono_marshal_get_xappdomain_invoke: * Generates a fast remoting wrapper for cross app domain calls. */ MonoMethod * @@ -991,7 +1046,7 @@ mono_marshal_get_xappdomain_invoke (MonoMethod *method) /* 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); @@ -1132,7 +1187,7 @@ mono_marshal_get_xappdomain_invoke (MonoMethod *method) /* 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) ... */ @@ -1237,6 +1292,9 @@ mono_marshal_get_xappdomain_invoke (MonoMethod *method) return res; } +/** + * mono_marshal_get_remoting_invoke_for_target: + */ MonoMethod * mono_marshal_get_remoting_invoke_for_target (MonoMethod *method, MonoRemotingTarget target_type) { @@ -1269,6 +1327,9 @@ mono_marshal_load_remoting_wrapper (MonoRealProxy *rp, MonoMethod *method) return compiled_ptr; } +/** + * mono_marshal_get_remoting_invoke_with_check: + */ MonoMethod * mono_marshal_get_remoting_invoke_with_check (MonoMethod *method) { @@ -1330,13 +1391,14 @@ 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: + * + * type ldfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset) */ MonoMethod * mono_marshal_get_ldfld_wrapper (MonoType *type) @@ -1581,7 +1643,7 @@ mono_marshal_get_ldflda_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."); @@ -1624,13 +1686,14 @@ mono_marshal_get_ldflda_wrapper (MonoType *type) } -/* +/** * 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: + * + * void stfld_wrapper (MonoObject *this_obj, MonoClass *klass, MonoClassField *field, int offset, type val) */ MonoMethod * mono_marshal_get_stfld_wrapper (MonoType *type) @@ -1770,6 +1833,9 @@ mono_marshal_get_stfld_wrapper (MonoType *type) return res; } +/** + * mono_marshal_get_proxy_cancast: + */ MonoMethod * mono_marshal_get_proxy_cancast (MonoClass *klass) { @@ -1931,11 +1997,10 @@ leave: /** * 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) @@ -2035,3 +2100,20 @@ ves_icall_mono_marshal_xdomain_copy_value (MonoObject *val) 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); +}