2002-07-18 Dietmar Maurer <dietmar@ximian.com>
authorDietmar Maurer <dietmar@mono-cvs.ximian.com>
Thu, 18 Jul 2002 16:34:46 +0000 (16:34 -0000)
committerDietmar Maurer <dietmar@mono-cvs.ximian.com>
Thu, 18 Jul 2002 16:34:46 +0000 (16:34 -0000)
* x86.brg (ARG_OBJ): allow zero sized ARG_OBJ

* marshal.c (mono_marshal_get_native_wrapper): we an now return value types

svn path=/trunk/mono/; revision=5895

mono/cil/cil-opcodes.xml
mono/cil/opcode.def
mono/jit/ChangeLog
mono/jit/jit.c
mono/jit/x86.brg
mono/metadata/ChangeLog
mono/metadata/marshal.c
mono/tests/Makefile.am
mono/tests/libtest.c
mono/tests/pinvoke4.cs [new file with mode: 0755]

index f4071d9c3e9630ccc95ef535d1026e1a9c52d8ff..2c47cc4438d408490765172a33c76c19baa0a5b7 100644 (file)
 <opcode name="mono_func1" input="Pop1" output="PushI" args="ShortInlineI" o1="0xF0" o2="0x00" flow="next"/>\r
 <opcode name="mono_proc3" input="PopI+PopI+PopI" output="Push0" args="ShortInlineI" o1="0xF0" o2="0x01" flow="next"/>\r
 <opcode name="mono_free" input="Pop1" output="Push0" args="InlineNone" o1="0xF0" o2="0x02" flow="next"/>\r
-<opcode name="mono_objaddr" input="Pop1" output="Push1" args="InlineNone" o1="0xF0" o2="0x03" flow="next"/>\r
+<opcode name="mono_objaddr" input="Pop1" output="PushI" args="InlineNone" o1="0xF0" o2="0x03" flow="next"/>\r
 <opcode name="mono_ldptr" input="Pop0" output="PushI" args="InlineI" o1="0xF0" o2="0x04" flow="next"/>\r
 \r
+<opcode name="mono_vtaddr" input="Pop1" output="PushI" args="InlineNone" o1="0xF0" o2="0x05" flow="next"/>\r
+\r
 </opdesc>\r
index 052ec732dbe6fda9bb3491868e086d5f1092f4fb..ec171513b4328247601cf05ba4dac652bba93c9a 100644 (file)
@@ -294,8 +294,9 @@ OPDEF(CEE_ENDMAC, "endmac", Pop0, Push0, InlineNone, X, 2, 0x00, 0x00, META)
 OPDEF(CEE_MONO_FUNC1, "mono_func1", Pop1, PushI, ShortInlineI, X, 2, 0xF0, 0x00, NEXT)
 OPDEF(CEE_MONO_PROC3, "mono_proc3", PopI+PopI+PopI, Push0, ShortInlineI, X, 2, 0xF0, 0x01, NEXT)
 OPDEF(CEE_MONO_FREE, "mono_free", Pop1, Push0, InlineNone, X, 2, 0xF0, 0x02, NEXT)
-OPDEF(CEE_MONO_OBJADDR, "mono_objaddr", Pop1, Push1, InlineNone, X, 2, 0xF0, 0x03, NEXT)
+OPDEF(CEE_MONO_OBJADDR, "mono_objaddr", Pop1, PushI, InlineNone, X, 2, 0xF0, 0x03, NEXT)
 OPDEF(CEE_MONO_LDPTR, "mono_ldptr", Pop0, PushI, InlineI, X, 2, 0xF0, 0x04, NEXT)
+OPDEF(CEE_MONO_VTADDR, "mono_vtaddr", Pop1, PushI, InlineNone, X, 2, 0xF0, 0x05, NEXT)
 #ifndef OPALIAS
 #define _MONO_CIL_OPALIAS_DEFINED_
 #define OPALIAS(a,s,r)
index 70e660aad2e080e92b150ed0bb303066d63f5199..2fd348f19f8cad5e54bd0a70caea2d7704f303e9 100644 (file)
@@ -1,5 +1,7 @@
 2002-07-18  Dietmar Maurer  <dietmar@ximian.com>
 
+       * x86.brg (ARG_OBJ): allow zero sized ARG_OBJ
+
        * exception.c (arch_handle_exception): removed duplicated code,
        added support for exception filters
 
index f2171d512b05778bd5402d8aff259d41f5e75b02..11fef968459ea5c9cc9f6a3c4bc423b3e60f1468 100644 (file)
@@ -2171,6 +2171,9 @@ mono_analyze_stack (MonoFlowGraph *cfg)
 
                        if (MONO_TYPE_ISSTRUCT (csig->ret)) {
                                size = mono_type_size (csig->ret, &align);
+                               if (csig->pinvoke && MONO_TYPE_ISSTRUCT ((csig->ret)))
+                                       mono_class_native_size (csig->ret->data.klass);
+
                                vtype_num = arch_allocate_var (cfg, size, align, MONO_TEMPVAR, VAL_UNKNOWN);
                                /* we push a pointer to the vtype as argument */
                                args_size += sizeof (gpointer);
@@ -3198,6 +3201,14 @@ mono_analyze_stack (MonoFlowGraph *cfg)
                                PUSH_TREE (t1, VAL_POINTER);
                                break;
                        }
+                       case CEE_MONO_VTADDR: {
+                               ++ip;
+
+                               sp -= 1;
+                               t1 = mono_ctree_new (mp, MB_TERM_VTADDR, *sp, NULL);
+                               PUSH_TREE (t1, VAL_POINTER);
+                               break;
+                       }
                        case CEE_MONO_LDPTR: {
                                guint32 token;
                                ++ip;
index c9a16c6553f922485bef842d0aecce02907900f6..23be36952d67aeb522527d33d93beee111f38ec8 100644 (file)
@@ -240,7 +240,7 @@ debug_memcopy (void *dest, const void *src, size_t n);
 %term REMOTE_STIND_I8 REMOTE_STIND_R4 REMOTE_STIND_R8 REMOTE_STIND_OBJ
 %term SIN COS SQRT
 
-%term FUNC1 PROC3 FREE OBJADDR
+%term FUNC1 PROC3 FREE OBJADDR VTADDR
 
 #
 # we start at stmt
@@ -1735,6 +1735,12 @@ reg: OBJADDR (reg) {
                x86_mov_reg_reg (s->code, tree->reg1, tree->left->reg1, 4);
 }
 
+reg: VTADDR (ADDR_L) {
+       int offset = VARINFO (s, tree->left->data.i).offset;
+
+       x86_lea_membase (s->code, tree->reg1, X86_EBP, offset);
+}
+
 stmt: FREE (reg) {
        x86_push_reg (s->code, X86_EAX);
        x86_push_reg (s->code, X86_ECX);
@@ -4810,7 +4816,9 @@ stmt: ARG_OBJ (reg) {
        int size = tree->data.i;
        int sa;
        
-       mono_assert (size > 0);
+       if (!size)
+               return;
+
        sa = size + 3;
        sa &= ~3;
 
index 73f648684b636a5d3229d672406e18f0a79ad61e..44bad5e78f911b54f204d2adce5a75f2c0793487 100644 (file)
@@ -1,6 +1,7 @@
 2002-07-18  Dietmar Maurer  <dietmar@ximian.com>
 
        * marshal.c (mono_marshal_get_runtime_invoke): use exception filters
+       (mono_marshal_get_native_wrapper): we an now return value types
 
 Wed Jul 17 18:21:29 CEST 2002 Paolo Molaro <lupus@ximian.com>
 
index 98afa5edc20ac22592a4a41632deaddf11c67b7b..e9d34ce80698b3a0679cda9e022baefd6753736b 100644 (file)
@@ -515,7 +515,7 @@ emit_ptr_to_str_conv (MonoMethodBuilder *mb, MonoType *type, MonoMarshalConv con
        case MONO_MARSHAL_CONV_STR_BYVALWSTR: 
        case MONO_MARSHAL_CONV_BOOL_VARIANTBOOL:
        default:
-               g_warning ("marshalling conversion %d not implemented", conv);
+               g_warning ("marshaling conversion %d not implemented", conv);
                g_assert_not_reached ();
        }
 }
@@ -699,8 +699,14 @@ emit_struct_conv (MonoMethodBuilder *mb, MonoClass *klass, gboolean to_object)
                                }
                                emit_struct_conv (mb, ftype->data.klass, to_object);
                                continue;
+                       case MONO_TYPE_CLASS:
+                       case MONO_TYPE_OBJECT:
+                               /* fixme: handle MONO_TYPE_CLASS and delegates */
+                               g_assert_not_reached ();
+                               break;
                        default:
-                               g_error ("marshalling type %02x not implemented", ftype->type);
+                               g_warning ("marshaling type %02x not implemented", ftype->type);
+                               g_assert_not_reached ();
                        }
                        break;
                }
@@ -1826,7 +1832,7 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
                        mono_mb_emit_ldloc (mb, tmp_locals [i]);
                        mono_mb_emit_byte (mb, CEE_STLOC_1);
 
-                       /* emit valuetype convnversion code code */
+                       /* emit valuetype conversion code */
                        emit_struct_conv (mb, klass, FALSE);
                        break;
                case MONO_TYPE_STRING:
@@ -1975,16 +1981,30 @@ mono_marshal_get_native_wrapper (MonoMethod *method)
                case MONO_TYPE_BOOLEAN:
                        /* maybe we need to make sure that it fits within 8 bits */
                        break;
-               case MONO_TYPE_VALUETYPE:
+               case MONO_TYPE_VALUETYPE: {
+                       int tmp;
                        if (sig->ret->data.klass->enumtype) {
                                type = sig->ret->data.klass->enum_basetype->type;
                                goto handle_enum;
-                       } else {
-                               g_warning ("generic valutype %s not handled", 
-                                          sig->ret->data.klass->name);
-                               g_assert_not_reached ();
                        }
+
+                       tmp = mono_mb_add_local (mb, sig->ret);
+                       g_assert (tmp);
+                       /* load pointer to returned value type */
+                       mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
+                       mono_mb_emit_byte (mb, CEE_MONO_VTADDR);
+                       /* store the address of the source into local variable 0 */
+                       mono_mb_emit_byte (mb, CEE_STLOC_0);
+                       /* set dst_ptr */
+                       mono_mb_emit_ldloc_addr (mb, tmp);
+                       mono_mb_emit_byte (mb, CEE_STLOC_1);
+
+                       /* emit valuetype conversion code */
+                       emit_struct_conv (mb, sig->ret->data.klass, TRUE);
+
+                       mono_mb_emit_ldloc (mb, tmp);
                        break;
+               }
                case MONO_TYPE_STRING:
                        mono_mb_emit_byte (mb, MONO_CUSTOM_PREFIX);
                        mono_mb_emit_byte (mb, CEE_MONO_FUNC1);
index 2acf38409839bcad8c994cd02a76c0361a3cf3f0..72d38e321702e20fe5a0a26839d261f3adf874cc 100644 (file)
@@ -43,6 +43,7 @@ TESTSRC=                      \
        pinvoke1.cs             \
        pinvoke2.cs             \
        pinvoke3.cs             \
+       pinvoke4.cs             \
        box.cs                  \
        array.cs                \
        enum.cs                 \
index 2bc89f1069df0d6a6b2f73ddf457f9a1fe14a0c5..e86ced4545167dab91e1bdcd5a2a18d8c2c6cb4a 100644 (file)
@@ -75,6 +75,19 @@ typedef struct {
        char *d;
 } simplestruct;
 
+simplestruct
+mono_test_return_vtype ()
+{
+       simplestruct res;
+
+       res.a = 0;
+       res.b = 1;
+       res.c = 0;
+       res.d = "TEST";
+
+       return res;
+}
+
 int 
 mono_test_marshal_struct (simplestruct ss)
 {
diff --git a/mono/tests/pinvoke4.cs b/mono/tests/pinvoke4.cs
new file mode 100755 (executable)
index 0000000..30e57a7
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+using System.Runtime.InteropServices;
+
+public class Test {
+
+       [StructLayout (LayoutKind.Sequential)]
+       public struct SimpleStruct {
+               public bool a;
+               public bool b;
+               public bool c;
+               public string d;
+       }
+
+       [DllImport ("libtest.so", EntryPoint="mono_test_return_vtype")]
+       public static extern SimpleStruct mono_test_return_vtype ();
+
+
+       public static int Main () {
+               SimpleStruct ss = mono_test_return_vtype ();
+
+               if (!ss.a && ss.b && !ss.c && ss.d == "TEST")
+                       return 0;
+               
+               return 1;
+       }
+}