Skip to content

Commit 962fb01

Browse files
committed
[SoftDebugger] New IInvocableMethodOwnerMirror interface to avoid duplicating of Invoke*, BeginInvoke*, EndInvoke* methods in invocable mirrors. All the API is now static methods taking IInvocableMethodOwnerMirror as the 1st parameter. This refactoring allows to avoid multiple 'if (obj is *) else' in SoftDebuggerAdaptor.
1 parent b719660 commit 962fb01

File tree

7 files changed

+96
-175
lines changed

7 files changed

+96
-175
lines changed

Mono.Debugger.Soft/Mono.Debugger.Soft.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@
6161
<Compile Include="Mono.Debugger.Soft\ExceptionEvent.cs" />
6262
<Compile Include="Mono.Debugger.Soft\ExceptionEventRequest.cs" />
6363
<Compile Include="Mono.Debugger.Soft\FieldInfoMirror.cs" />
64+
<Compile Include="Mono.Debugger.Soft\IInvocableMethodOwnerMirror.cs" />
6465
<Compile Include="Mono.Debugger.Soft\IInvokeAsyncResult.cs" />
6566
<Compile Include="Mono.Debugger.Soft\ILExceptionHandler.cs" />
6667
<Compile Include="Mono.Debugger.Soft\ILInstruction.cs" />
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace Mono.Debugger.Soft
2+
{
3+
/// <summary>
4+
/// Interface to mark a mirror that supports method invocation
5+
/// </summary>
6+
public interface IInvocableMethodOwnerMirror : IMirror
7+
{
8+
/// <summary>
9+
/// Value that will be passed as 'this' reference when invoking a method (can be null e.g. for static methods)
10+
/// </summary>
11+
/// <returns>'this' reference</returns>
12+
Value GetThisObject ();
13+
14+
/// <summary>
15+
/// Make some additional processing of invocation result. See implementation in <see cref="StructMirror"/>
16+
/// </summary>
17+
/// <param name="result"></param>
18+
void ProcessResult (InvokeResult result);
19+
}
20+
}

Mono.Debugger.Soft/Mono.Debugger.Soft/ObjectMirror.cs

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using System.Collections.Generic;
3-
using System.Runtime.Remoting.Messaging;
43
using System.Threading;
54
using System.Threading.Tasks;
65

@@ -22,7 +21,7 @@ public class InvokeResult {
2221
public Value[] OutArgs { get; set; }
2322
}
2423

25-
public class ObjectMirror : Value {
24+
public class ObjectMirror : Value, IInvocableMethodOwnerMirror {
2625
TypeMirror type;
2726
AppDomainMirror domain;
2827

@@ -142,37 +141,43 @@ public long Address {
142141
}
143142
}
144143

145-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
146-
return InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
144+
Value IInvocableMethodOwnerMirror.GetThisObject () {
145+
return this;
147146
}
148147

149-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
150-
return InvokeMethod (vm, thread, method, this, arguments, options);
148+
void IInvocableMethodOwnerMirror.ProcessResult (InvokeResult result)
149+
{
150+
}
151+
152+
// Public invocation API
153+
154+
public static Value InvokeMethod (IInvocableMethodOwnerMirror mirror, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
155+
return InvokeMethod (mirror, mirror.VirtualMachine, thread, method, mirror.GetThisObject (), arguments, options);
151156
}
152157

153158
[Obsolete ("Use the overload without the 'vm' argument")]
154-
public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
155-
return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
159+
public static IAsyncResult BeginInvokeMethod (IInvocableMethodOwnerMirror mirror, VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
160+
return BeginInvokeMethod (vm, thread, method, mirror.GetThisObject (), arguments, options, callback, state);
156161
}
157162

158-
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
159-
return BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
163+
public static IAsyncResult BeginInvokeMethod (IInvocableMethodOwnerMirror mirror, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
164+
return BeginInvokeMethod (mirror.VirtualMachine, thread, method, mirror.GetThisObject (), arguments, options, callback, state);
160165
}
161166

162-
public Value EndInvokeMethod (IAsyncResult asyncResult) {
163-
return EndInvokeMethodInternal (asyncResult);
167+
public static Value EndInvokeMethod (IInvocableMethodOwnerMirror mirror, IAsyncResult asyncResult) {
168+
return EndInvokeMethodInternal (mirror, asyncResult);
164169
}
165170

166-
public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) {
167-
return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult);
171+
public static InvokeResult EndInvokeMethodWithResult (IInvocableMethodOwnerMirror mirror, IAsyncResult asyncResult) {
172+
return EndInvokeMethodInternalWithResult (mirror, asyncResult);
168173
}
169174

170-
public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
175+
public static Task<Value> InvokeMethodAsync (IInvocableMethodOwnerMirror mirror, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
171176
var tcs = new TaskCompletionSource<Value> ();
172-
BeginInvokeMethod (thread, method, arguments, options, iar =>
177+
BeginInvokeMethod (mirror, thread, method, arguments, options, iar =>
173178
{
174179
try {
175-
tcs.SetResult (EndInvokeMethod (iar));
180+
tcs.SetResult (EndInvokeMethod (mirror, iar));
176181
} catch (OperationCanceledException) {
177182
tcs.TrySetCanceled ();
178183
} catch (Exception ex) {
@@ -182,12 +187,12 @@ public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method,
182187
return tcs.Task;
183188
}
184189

185-
public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
190+
public static Task<InvokeResult> InvokeMethodAsyncWithResult (IInvocableMethodOwnerMirror mirror, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
186191
var tcs = new TaskCompletionSource<InvokeResult> ();
187-
BeginInvokeMethod (thread, method, arguments, options, iar =>
192+
BeginInvokeMethod (mirror, thread, method, arguments, options, iar =>
188193
{
189194
try {
190-
tcs.SetResult (EndInvokeMethodInternalWithResult (iar));
195+
tcs.SetResult (EndInvokeMethodInternalWithResult (mirror, iar));
191196
} catch (OperationCanceledException) {
192197
tcs.TrySetCanceled ();
193198
} catch (Exception ex) {
@@ -202,11 +207,11 @@ public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, Meth
202207
// finished. The callback will be called with a different IAsyncResult that represents one method invocation.
203208
// From protocol version 2.22.
204209
//
205-
public IAsyncResult BeginInvokeMultiple (ThreadMirror thread, MethodMirror[] methods, IList<IList<Value>> arguments, InvokeOptions options, AsyncCallback callback, object state) {
206-
return BeginInvokeMultiple (vm, thread, methods, this, arguments, options, callback, state);
210+
public static IAsyncResult BeginInvokeMultiple (IInvocableMethodOwnerMirror mirror, ThreadMirror thread, MethodMirror[] methods, IList<IList<Value>> arguments, InvokeOptions options, AsyncCallback callback, object state) {
211+
return BeginInvokeMultiple (mirror.VirtualMachine, thread, methods, mirror.GetThisObject (), arguments, options, callback, state);
207212
}
208213

209-
public void EndInvokeMultiple (IAsyncResult asyncResult) {
214+
public static void EndInvokeMultiple (IAsyncResult asyncResult) {
210215
EndInvokeMultipleInternal (asyncResult);
211216
}
212217

@@ -281,7 +286,7 @@ public void Abort ()
281286
if (ID == 0) // Ooops
282287
return;
283288

284-
ObjectMirror.AbortInvoke (VM, Thread, ID);
289+
AbortInvoke (VM, Thread, ID);
285290
}
286291
}
287292

@@ -334,7 +339,13 @@ static void InvokeCB (ValueImpl v, ValueImpl exc, ValueImpl out_this, ValueImpl[
334339
r.Callback.BeginInvoke (r, null, null);
335340
}
336341

337-
internal static InvokeResult EndInvokeMethodInternalWithResult (IAsyncResult asyncResult) {
342+
internal static InvokeResult EndInvokeMethodInternalWithResult (IInvocableMethodOwnerMirror mirror, IAsyncResult asyncResult) {
343+
var result = EndInvokeMethodInternalWithResultImpl (asyncResult);
344+
mirror.ProcessResult (result);
345+
return result;
346+
}
347+
348+
internal static InvokeResult EndInvokeMethodInternalWithResultImpl (IAsyncResult asyncResult) {
338349
if (asyncResult == null)
339350
throw new ArgumentNullException ("asyncResult");
340351

@@ -368,8 +379,8 @@ internal static InvokeResult EndInvokeMethodInternalWithResult (IAsyncResult asy
368379
}
369380
}
370381

371-
internal static Value EndInvokeMethodInternal (IAsyncResult asyncResult) {
372-
InvokeResult res = EndInvokeMethodInternalWithResult (asyncResult);
382+
internal static Value EndInvokeMethodInternal (IInvocableMethodOwnerMirror mirror, IAsyncResult asyncResult) {
383+
InvokeResult res = EndInvokeMethodInternalWithResult (mirror, asyncResult);
373384
return res.Result;
374385
}
375386

@@ -383,8 +394,8 @@ internal static void EndInvokeMultipleInternal (IAsyncResult asyncResult) {
383394
r.AsyncWaitHandle.WaitOne ();
384395
}
385396

386-
internal static Value InvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
387-
return EndInvokeMethodInternal (BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
397+
internal static Value InvokeMethod (IInvocableMethodOwnerMirror mirror, VirtualMachine vm, ThreadMirror thread, MethodMirror method, Value this_obj, IList<Value> arguments, InvokeOptions options) {
398+
return EndInvokeMethodInternal (mirror, BeginInvokeMethod (vm, thread, method, this_obj, arguments, options, null, null));
388399
}
389400

390401
internal static void AbortInvoke (VirtualMachine vm, ThreadMirror thread, int id)
Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
1-
using System;
2-
using System.Collections.Generic;
3-
41
namespace Mono.Debugger.Soft
52
{
63
/*
74
* Represents a value of a primitive type in the debuggee
85
*/
9-
public class PrimitiveValue : Value {
6+
public class PrimitiveValue : Value, IInvocableMethodOwnerMirror {
107
object value;
118

129
public PrimitiveValue (VirtualMachine vm, object value) : base (vm, 0) {
@@ -34,30 +31,18 @@ public override int GetHashCode () {
3431
return base.GetHashCode ();
3532
}
3633

37-
public override string ToString () {
38-
object v = Value;
39-
40-
return "PrimitiveValue<" + (v != null ? v.ToString () : "(null)") + ">";
41-
}
42-
43-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
44-
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
34+
Value IInvocableMethodOwnerMirror.GetThisObject () {
35+
return this;
4536
}
4637

47-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
48-
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, options);
38+
void IInvocableMethodOwnerMirror.ProcessResult (InvokeResult result)
39+
{
4940
}
5041

51-
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
52-
return ObjectMirror.BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
53-
}
54-
55-
public Value EndInvokeMethod (IAsyncResult asyncResult) {
56-
return ObjectMirror.EndInvokeMethodInternal (asyncResult);
57-
}
42+
public override string ToString () {
43+
object v = Value;
5844

59-
public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) {
60-
return ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult);
45+
return "PrimitiveValue<" + (v != null ? v.ToString () : "(null)") + ">";
6146
}
6247
}
6348
}
Lines changed: 5 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
using System;
2-
using System.Collections.Generic;
3-
using System.Threading.Tasks;
42

53
namespace Mono.Debugger.Soft
64
{
75
/*
86
* Represents a valuetype value in the debuggee
97
*/
10-
public class StructMirror : Value {
8+
public class StructMirror : Value, IInvocableMethodOwnerMirror {
119

1210
TypeMirror type;
1311
Value[] fields;
@@ -66,69 +64,16 @@ internal void SetField (int index, Value value) {
6664
fields [index] = value;
6765
}
6866

69-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments) {
70-
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, InvokeOptions.None);
67+
Value IInvocableMethodOwnerMirror.GetThisObject () {
68+
return this;
7169
}
7270

73-
public Value InvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options) {
74-
return ObjectMirror.InvokeMethod (vm, thread, method, this, arguments, options);
75-
}
76-
77-
[Obsolete ("Use the overload without the 'vm' argument")]
78-
public IAsyncResult BeginInvokeMethod (VirtualMachine vm, ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
79-
return ObjectMirror.BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
80-
}
81-
82-
public IAsyncResult BeginInvokeMethod (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options, AsyncCallback callback, object state) {
83-
return ObjectMirror.BeginInvokeMethod (vm, thread, method, this, arguments, options, callback, state);
84-
}
85-
86-
public Value EndInvokeMethod (IAsyncResult asyncResult) {
87-
var result = ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult);
88-
var outThis = result.OutThis as StructMirror;
89-
if (outThis != null) {
90-
SetFields (outThis.Fields);
91-
}
92-
return result.Result;
93-
}
94-
95-
public InvokeResult EndInvokeMethodWithResult (IAsyncResult asyncResult) {
96-
var result = ObjectMirror.EndInvokeMethodInternalWithResult (asyncResult);
71+
void IInvocableMethodOwnerMirror.ProcessResult (InvokeResult result)
72+
{
9773
var outThis = result.OutThis as StructMirror;
9874
if (outThis != null) {
9975
SetFields (outThis.Fields);
10076
}
101-
return result;
102-
}
103-
104-
public Task<Value> InvokeMethodAsync (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
105-
var tcs = new TaskCompletionSource<Value> ();
106-
BeginInvokeMethod (thread, method, arguments, options, iar =>
107-
{
108-
try {
109-
tcs.SetResult (EndInvokeMethod (iar));
110-
} catch (OperationCanceledException) {
111-
tcs.TrySetCanceled ();
112-
} catch (Exception ex) {
113-
tcs.TrySetException (ex);
114-
}
115-
}, null);
116-
return tcs.Task;
117-
}
118-
119-
public Task<InvokeResult> InvokeMethodAsyncWithResult (ThreadMirror thread, MethodMirror method, IList<Value> arguments, InvokeOptions options = InvokeOptions.None) {
120-
var tcs = new TaskCompletionSource<InvokeResult> ();
121-
BeginInvokeMethod (thread, method, arguments, options, iar =>
122-
{
123-
try {
124-
tcs.SetResult (ObjectMirror.EndInvokeMethodInternalWithResult (iar));
125-
} catch (OperationCanceledException) {
126-
tcs.TrySetCanceled ();
127-
} catch (Exception ex) {
128-
tcs.TrySetException (ex);
129-
}
130-
}, null);
131-
return tcs.Task;
13277
}
13378
}
13479
}

0 commit comments

Comments
 (0)