Author: zoltan
Date: 2005-05-12 16:29:08 -0400 (Thu, 12 May 2005)
New Revision: 44463
Modified:
trunk/mono/mono/metadata/ChangeLog
trunk/mono/mono/metadata/marshal.c
Log:
2005-05-12 Zoltan Varga <[EMAIL PROTECTED]>
* marshal.c (emit_marshal_custom): Add some error checking and call the
methods in the ICustomMarshaler interface. Fixes #74875.
Modified: trunk/mono/mono/metadata/ChangeLog
===================================================================
--- trunk/mono/mono/metadata/ChangeLog 2005-05-12 19:21:32 UTC (rev 44462)
+++ trunk/mono/mono/metadata/ChangeLog 2005-05-12 20:29:08 UTC (rev 44463)
@@ -1,8 +1,11 @@
2005-05-12 Zoltan Varga <[EMAIL PROTECTED]>
+ * marshal.c (emit_marshal_custom): Add some error checking and call the
+ methods in the ICustomMarshaler interface. Fixes #74875.
+
* marshal.c (emit_marshal_array): Implement [Out] marshalling in
native->managed wrappers.
-
+
2005-05-12 Martin Baulig <[EMAIL PROTECTED]>
* mono-debug-debugger.cs (mono_debugger_lock/unlock): Always lock
Modified: trunk/mono/mono/metadata/marshal.c
===================================================================
--- trunk/mono/mono/metadata/marshal.c 2005-05-12 19:21:32 UTC (rev 44462)
+++ trunk/mono/mono/metadata/marshal.c 2005-05-12 20:29:08 UTC (rev 44463)
@@ -4128,28 +4128,74 @@
{
MonoType *mtype;
MonoClass *mklass;
- MonoMethod *get_instance, *cleanup_native, *cleanup_managed;
- MonoMethod *marshal_managed_to_native, *marshal_native_to_managed;
+ static MonoClass *ICustomMarshaler = NULL;
+ static MonoMethod *cleanup_native, *cleanup_managed;
+ static MonoMethod *marshal_managed_to_native,
*marshal_native_to_managed;
+ MonoMethod *get_instance;
MonoMethodBuilder *mb = m->mb;
+ char *exception_msg = NULL;
guint32 loc1;
int pos2;
+ if (!ICustomMarshaler) {
+ ICustomMarshaler = mono_class_from_name (mono_defaults.corlib,
"System.Runtime.InteropServices", "ICustomMarshaler");
+ g_assert (ICustomMarshaler);
+
+ cleanup_native = mono_class_get_method_from_name
(ICustomMarshaler, "CleanUpNativeData", 1);
+ g_assert (cleanup_native);
+ cleanup_managed = mono_class_get_method_from_name
(ICustomMarshaler, "CleanUpManagedData", 1);
+ g_assert (cleanup_managed);
+ marshal_managed_to_native = mono_class_get_method_from_name
(ICustomMarshaler, "MarshalManagedToNative", 1);
+ g_assert (marshal_managed_to_native);
+ marshal_native_to_managed = mono_class_get_method_from_name
(ICustomMarshaler, "MarshalNativeToManaged", 1);
+ g_assert (marshal_native_to_managed);
+ }
+
mtype = mono_reflection_type_from_name
(spec->data.custom_data.custom_name, mb->method->klass->image);
g_assert (mtype != NULL);
mklass = mono_class_from_mono_type (mtype);
g_assert (mklass != NULL);
- get_instance = mono_class_get_method_from_name (mklass, "GetInstance",
1);
- g_assert (get_instance);
- cleanup_native = mono_class_get_method_from_name (mklass,
"CleanUpNativeData", 1);
- g_assert (cleanup_native);
- cleanup_managed = mono_class_get_method_from_name (mklass,
"CleanUpManagedData", 1);
- g_assert (cleanup_managed);
- marshal_managed_to_native = mono_class_get_method_from_name (mklass,
"MarshalManagedToNative", 1);
- g_assert (marshal_managed_to_native);
- marshal_native_to_managed = mono_class_get_method_from_name (mklass,
"MarshalNativeToManaged", 1);
- g_assert (marshal_native_to_managed);
+ if (!mono_class_is_assignable_from (ICustomMarshaler, mklass))
+ exception_msg = g_strdup_printf ("Custom marshaler '%s' does
not implement the ICustomMarshaler interface.", mklass->name);
+ get_instance = mono_class_get_method_from_name_flags (mklass,
"GetInstance", 1, METHOD_ATTRIBUTE_STATIC);
+ if (get_instance) {
+ MonoMethodSignature *get_sig = mono_method_signature
(get_instance);
+ if ((get_sig->ret->type != MONO_TYPE_CLASS) ||
+ (mono_class_from_mono_type (get_sig->ret) !=
ICustomMarshaler) ||
+ (get_sig->params [0]->type != MONO_TYPE_STRING))
+ get_instance = NULL;
+ }
+
+ if (!get_instance)
+ exception_msg = g_strdup_printf ("Custom marshaler '%s' does
not implement a static GetInstance method that takes a single string parameter
and returns an ICustomMarshaler.", mklass->name);
+
+ /* Throw exception and emit compensation code if neccesary */
+ if (exception_msg) {
+ switch (action) {
+ case MARSHAL_ACTION_CONV_IN:
+ case MARSHAL_ACTION_CONV_RESULT:
+ case MARSHAL_ACTION_MANAGED_CONV_RESULT:
+ if ((action == MARSHAL_ACTION_CONV_RESULT) || (action
== MARSHAL_ACTION_MANAGED_CONV_RESULT))
+ mono_mb_emit_byte (mb, CEE_POP);
+
+ mono_mb_emit_exception_full (mb, "System",
"ApplicationException", exception_msg);
+ g_free (exception_msg);
+
+ break;
+ case MARSHAL_ACTION_PUSH:
+ mono_mb_emit_byte (mb, CEE_LDNULL);
+ break;
+ default:
+ break;
+ }
+ return 0;
+ }
+
+ /* FIXME: MS.NET seems to create one instance for each klass + cookie
pair */
+ /* FIXME: MS.NET throws an exception if GetInstance returns null */
+
switch (action) {
case MARSHAL_ACTION_CONV_IN:
switch (t->type) {
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches