Fix marshaling of chars on structs.
authorRodrigo Kumpera <kumpera@gmail.com>
Tue, 14 Dec 2010 16:30:38 +0000 (14:30 -0200)
committerRodrigo Kumpera <kumpera@gmail.com>
Tue, 14 Dec 2010 16:34:45 +0000 (14:34 -0200)
* marshal.c (emit_struct_conv): Take the native type of
the field to decide what kind of conv to use if field
is of type char.

* marshal.c (mono_pinvoke_is_unicode): Unify auto
and default.

* marshal.c (emit_struct_conv_full): Kill this variant
that doesn't make any sense as structures are marshaled
in the same way regardless of the charset of the method.

* metadata.c (mono_type_to_unmanaged): Handle marshalspec
for char.

Fixes the regression on MD caused by 1f3cfba.

mono/metadata/marshal.c
mono/metadata/metadata.c

index 849e475b16f34e6a7a37545c4195e33f4e485ec6..356af5b4af58081ec0fbf30c46366cfbc1de1750 100644 (file)
@@ -1756,7 +1756,7 @@ emit_object_to_ptr_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv
 }
 
 static void
-emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object, gboolean unicode)
+emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
 {
        MonoMarshalType *info;
        int i;
@@ -1859,7 +1859,7 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
                        case MONO_TYPE_R8:
                                mono_mb_emit_ldloc (mb, 1);
                                mono_mb_emit_ldloc (mb, 0);
-                               if (ftype->type == MONO_TYPE_CHAR && !unicode) {
+                               if (ntype == MONO_NATIVE_U1) {
                                        if (to_object) {
                                                mono_mb_emit_byte (mb, CEE_LDIND_U1);
                                                mono_mb_emit_byte (mb, CEE_STIND_I2);
@@ -1975,12 +1975,6 @@ emit_struct_conv_full (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_obje
        }
 }
 
-static void
-emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
-{
-       emit_struct_conv_full (mb, klass, to_object, TRUE);
-}
-
 static void
 emit_struct_free (MonoMethodBuilder *mb, MonoClass *klass, int struct_var)
 {
@@ -6940,13 +6934,12 @@ mono_pinvoke_is_unicode (MonoMethodPInvoke *piinfo)
        case PINVOKE_ATTRIBUTE_CHAR_SET_UNICODE:
                return TRUE;
        case PINVOKE_ATTRIBUTE_CHAR_SET_AUTO:
+       default:
 #ifdef TARGET_WIN32
                return TRUE;
 #else
                return FALSE;
 #endif
-       default:
-               return FALSE;
        }
 }
 
@@ -7074,7 +7067,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                mono_mb_emit_stloc (mb, 1);
 
                                /* emit valuetype conversion code */
-                               emit_struct_conv_full (mb, eklass, FALSE, mono_pinvoke_is_unicode (m->piinfo));
+                               emit_struct_conv (mb, eklass, FALSE);
                        }
 
                        mono_mb_emit_add_to_local (mb, index_var, 1);
@@ -7192,7 +7185,7 @@ emit_marshal_array (EmitMarshalContext *m, int argnum, MonoType *t,
                                        mono_mb_emit_stloc (mb, 1);
 
                                        /* emit valuetype conversion code */
-                                       emit_struct_conv_full (mb, eklass, TRUE, mono_pinvoke_is_unicode (m->piinfo));
+                                       emit_struct_conv (mb, eklass, TRUE);
                                }
 
                                if (need_free) {
index 8dfcd793e6595abc03665c6294faa7a94e4a18f1..2e4dcd87d06913ce0df6aaf167aebd4b17f90354 100644 (file)
@@ -5413,7 +5413,17 @@ handle_enum:
                }
                *conv = MONO_MARSHAL_CONV_BOOL_I4;
                return MONO_NATIVE_BOOLEAN;
-       case MONO_TYPE_CHAR: return unicode ? MONO_NATIVE_U2 : MONO_NATIVE_U1;
+       case MONO_TYPE_CHAR:
+               if (mspec) {
+                       switch (mspec->native) {
+                       case MONO_NATIVE_U2:
+                       case MONO_NATIVE_U1:
+                               return mspec->native;
+                       default:
+                               g_error ("cant marshal char to native type %02x", mspec->native);
+                       }
+               }
+               return unicode ? MONO_NATIVE_U2 : MONO_NATIVE_U1;
        case MONO_TYPE_I1: return MONO_NATIVE_I1;
        case MONO_TYPE_U1: return MONO_NATIVE_U1;
        case MONO_TYPE_I2: return MONO_NATIVE_I2;