[sdb] Fix interface/virtual calls to valuetype methods.
authorZoltan Varga <vargaz@gmail.com>
Wed, 3 Jun 2015 17:52:46 +0000 (13:52 -0400)
committerZoltan Varga <vargaz@gmail.com>
Wed, 3 Jun 2015 17:52:52 +0000 (13:52 -0400)
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mono/mini/debugger-agent.c

index c8c037d7a50bc4f6ea243075487f98a4079e8144..dcc840d9886e84e0036186db99d1817271a348ea 100644 (file)
@@ -80,7 +80,7 @@ public class Tests2 {
        }
 }
 
-public struct AStruct {
+public struct AStruct : ITest2 {
        public int i;
        public string s;
        public byte k;
@@ -116,6 +116,14 @@ public struct AStruct {
        public void invoke_mutate () {
                l = 5;
        }
+
+       public int invoke_iface () {
+               return i;
+       }
+
+       public override string ToString () {
+               return i.ToString ();
+       }
 }
 
 public class GClass<T> {
index 409e775fd66473399a9a7658b4df4edf67fc4803..b6baca8a5189ca2c374dae5e8109ff1960a56f9e 100644 (file)
@@ -1625,8 +1625,8 @@ public class DebuggerTests
                                AssertValue ("AB", vals [i]);
                        if (locals [i].Name == "t")
                                AssertValue ("ABC", vals [i]);
-                       if (locals [i].Name == "alist")
-                               ;
+                       if (locals [i].Name == "alist") {
+                       }
                }
 
                // Argument checking
@@ -2269,6 +2269,17 @@ public class DebuggerTests
                task = s.InvokeMethodAsyncWithResult (e.Thread, m, null);
                out_this = task.Result.OutThis as StructMirror;
                Assert.AreEqual (null, out_this);
+
+               // interface method
+               var cl1 = frame.Method.DeclaringType.Assembly.GetType ("ITest2");
+               m = cl1.GetMethod ("invoke_iface");
+               v = s.InvokeMethod (e.Thread, m, null);
+               AssertValue (42, v);
+
+               // virtual method
+               m = vm.RootDomain.Corlib.GetType ("System.Object").GetMethod ("ToString");
+               v = s.InvokeMethod (e.Thread, m, null, InvokeOptions.Virtual);
+               AssertValue ("42", v);
 #endif
        }
 
index 6214eec2fd7bde1f0f1d037f05b2254ede7e9069..dcecc4dfb05f191a8cd5d187d3d271ff44410c8f 100644 (file)
@@ -6535,12 +6535,21 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
                        return ERR_INVALID_ARGUMENT;
                }
                m = mono_object_get_virtual_method (this, m);
+               /* Transform this to the format the rest of the code expects it to be */
+               if (m->klass->valuetype) {
+                       this_buf = g_alloca (mono_class_instance_size (m->klass));
+                       memcpy (this_buf, mono_object_unbox (this), mono_class_instance_size (m->klass));
+               }
        } else if ((m->flags & METHOD_ATTRIBUTE_VIRTUAL) && !m->klass->valuetype && invoke->flags & INVOKE_FLAG_VIRTUAL) {
                if (!this) {
                        DEBUG_PRINTF (1, "[%p] Error: invoke with INVOKE_FLAG_VIRTUAL flag set without this argument.\n", (gpointer)GetCurrentThreadId ());
                        return ERR_INVALID_ARGUMENT;
                }
                m = mono_object_get_virtual_method (this, m);
+               if (m->klass->valuetype) {
+                       this_buf = g_alloca (mono_class_instance_size (m->klass));
+                       memcpy (this_buf, mono_object_unbox (this), mono_class_instance_size (m->klass));
+               }
        }
 
        DEBUG_PRINTF (1, "[%p] Invoking method '%s' on receiver '%s'.\n", (gpointer)GetCurrentThreadId (), mono_method_full_name (m, TRUE), this ? this->vtable->klass->name : "<null>");