[sdb] Allow invoking of valuetype ctors.
authorZoltan Varga <vargaz@gmail.com>
Tue, 7 Jul 2015 20:32:57 +0000 (16:32 -0400)
committerZoltan Varga <vargaz@gmail.com>
Tue, 7 Jul 2015 20:33:09 +0000 (16:33 -0400)
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/mini/debugger-agent.c

index 5d7773d2477c4738b9099c7b7b8b320244449e31..e842e379cca2f57efdacb327f440290cc1b8b3c8 100644 (file)
@@ -87,6 +87,22 @@ public struct AStruct : ITest2 {
        public IntPtr j;
        public int l;
 
+       public AStruct () {
+               i = 0;
+               s = null;
+               k = 0;
+               j = IntPtr.Zero;
+               l = 0;
+       }
+
+       public AStruct (int arg) {
+               i = arg;
+               s = null;
+               k = 0;
+               j = IntPtr.Zero;
+               l = 0;
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public int foo (int val) {
                return val;
index a115bc97a065bcfbecccb467e66c3a33aad540de..f00aad4ece07d391067354372d2da3eae945a29e 100644 (file)
@@ -2303,6 +2303,13 @@ public class DebuggerTests
                v = s.InvokeMethod (e.Thread, m, null);
                AssertValue (42, v);
 
+               // .ctor
+               s = frame.GetArgument (1) as StructMirror;
+               t = s.Type;
+               m = t.GetMethods ().First (method => method.Name == ".ctor" && method.GetParameters ().Length == 1);
+               v = t.InvokeMethod (e.Thread, m, new Value [] { vm.CreateValue (1) });
+               AssertValue (1, (v as StructMirror)["i"]);
+
 #if NET_4_5
                // Invoke a method which changes state
                s = frame.GetArgument (1) as StructMirror;
index 1fd3ff90b475ac5d78f20e846f4639defb069303..665df3ee6c11a8e5413ae8711914bda7b177f66a 100644 (file)
@@ -6518,6 +6518,19 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                        return ERR_INVALID_ARGUMENT;
                }
                memset (this_buf, 0, mono_class_instance_size (m->klass));
+       } else if (m->klass->valuetype && !strcmp (m->name, ".ctor")) {
+                       /* Could be null */
+                       guint8 *tmp_p;
+
+                       int type = decode_byte (p, &tmp_p, end);
+                       if (type == VALUE_TYPE_ID_NULL) {
+                               memset (this_buf, 0, mono_class_instance_size (m->klass));
+                               p = tmp_p;
+                       } else {
+                               err = decode_value (&m->klass->byval_arg, domain, this_buf, p, &p, end);
+                               if (err)
+                                       return err;
+                       }
        } else {
                err = decode_value (&m->klass->byval_arg, domain, this_buf, p, &p, end);
                if (err)
@@ -6648,11 +6661,14 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                        out_args = TRUE;
                buffer_add_byte (buf, 1 + (out_this ? 2 : 0) + (out_args ? 4 : 0));
                if (sig->ret->type == MONO_TYPE_VOID) {
-                       if (!strcmp (m->name, ".ctor") && !m->klass->valuetype) {
-                               buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &this, domain);
-                       }
-                       else
+                       if (!strcmp (m->name, ".ctor")) {
+                               if (!m->klass->valuetype)
+                                       buffer_add_value (buf, &mono_defaults.object_class->byval_arg, &this, domain);
+                               else
+                                       buffer_add_value (buf, &m->klass->byval_arg, this_buf, domain);
+                       } else {
                                buffer_add_value (buf, &mono_defaults.void_class->byval_arg, NULL, domain);
+                       }
                } else if (MONO_TYPE_IS_REFERENCE (sig->ret)) {
                        buffer_add_value (buf, sig->ret, &res, domain);
                } else if (mono_class_from_mono_type (sig->ret)->valuetype || sig->ret->type == MONO_TYPE_PTR || sig->ret->type == MONO_TYPE_FNPTR) {