<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
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)
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
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);
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;
%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
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);
int size = tree->data.i;
int sa;
- mono_assert (size > 0);
+ if (!size)
+ return;
+
sa = size + 3;
sa &= ~3;
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>
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 ();
}
}
}
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;
}
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:
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);
pinvoke1.cs \
pinvoke2.cs \
pinvoke3.cs \
+ pinvoke4.cs \
box.cs \
array.cs \
enum.cs \
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)
{
--- /dev/null
+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;
+ }
+}