Skip to content

Commit f1b812e

Browse files
Update ws-proxy code (#19826)
1 parent 9343d2b commit f1b812e

File tree

2 files changed

+77
-34
lines changed

2 files changed

+77
-34
lines changed

src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/DevToolsProxy.cs

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Linq;
33
using System.Threading.Tasks;
44
using Newtonsoft.Json.Linq;
@@ -11,12 +11,45 @@
1111
using Microsoft.Extensions.Logging;
1212

1313
namespace WebAssembly.Net.Debugging {
14-
internal class SessionId {
15-
public string sessionId;
14+
internal struct SessionId {
15+
public readonly string sessionId;
16+
17+
public SessionId (string sessionId)
18+
{
19+
this.sessionId = sessionId;
20+
}
21+
22+
public override int GetHashCode ()
23+
=> sessionId?.GetHashCode () ?? 0;
24+
25+
public override bool Equals (object obj)
26+
=> (obj is SessionId) ? ((SessionId) obj).sessionId == sessionId : false;
27+
28+
public override string ToString ()
29+
=> $"session-{sessionId}";
1630
}
1731

18-
internal class MessageId : SessionId {
19-
public int id;
32+
internal struct MessageId {
33+
public readonly string sessionId;
34+
public readonly int id;
35+
36+
public MessageId (string sessionId, int id)
37+
{
38+
this.sessionId = sessionId;
39+
this.id = id;
40+
}
41+
42+
public static implicit operator SessionId (MessageId id)
43+
=> new SessionId (id.sessionId);
44+
45+
public override string ToString ()
46+
=> $"msg-{sessionId}:::{id}";
47+
48+
public override int GetHashCode ()
49+
=> (sessionId?.GetHashCode () ?? 0) ^ id.GetHashCode ();
50+
51+
public override bool Equals (object obj)
52+
=> (obj is MessageId) ? ((MessageId) obj).sessionId == sessionId && ((MessageId) obj).id == id : false;
2053
}
2154

2255
internal struct Result {
@@ -28,17 +61,17 @@ internal struct Result {
2861

2962
Result (JObject result, JObject error)
3063
{
31-
if (result != null && error != null)
32-
throw new ArgumentException ($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null.");
33-
34-
bool resultHasError = String.Compare ((result? ["result"] as JObject)? ["subtype"]?. Value<string> (), "error") == 0;
35-
if (result != null && resultHasError) {
36-
this.Value = null;
37-
this.Error = result;
38-
} else {
39-
this.Value = result;
40-
this.Error = error;
41-
}
64+
if (result != null && error != null)
65+
throw new ArgumentException ($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null.");
66+
67+
bool resultHasError = String.Compare ((result? ["result"] as JObject)? ["subtype"]?. Value<string> (), "error") == 0;
68+
if (result != null && resultHasError) {
69+
this.Value = null;
70+
this.Error = result;
71+
} else {
72+
this.Value = result;
73+
this.Error = error;
74+
}
4275
}
4376

4477
public static Result FromJson (JObject obj)
@@ -120,12 +153,13 @@ public Task Pump (CancellationToken token)
120153
internal class DevToolsProxy {
121154
TaskCompletionSource<bool> side_exception = new TaskCompletionSource<bool> ();
122155
TaskCompletionSource<bool> client_initiated_close = new TaskCompletionSource<bool> ();
123-
List<(MessageId, TaskCompletionSource<Result>)> pending_cmds = new List<(MessageId, TaskCompletionSource<Result>)> ();
156+
Dictionary<MessageId, TaskCompletionSource<Result>> pending_cmds = new Dictionary<MessageId, TaskCompletionSource<Result>> ();
124157
ClientWebSocket browser;
125158
WebSocket ide;
126159
int next_cmd_id;
127160
List<Task> pending_ops = new List<Task> ();
128161
List<DevToolsQueue> queues = new List<DevToolsQueue> ();
162+
129163
protected readonly ILogger logger;
130164

131165
public DevToolsProxy (ILoggerFactory loggerFactory)
@@ -219,11 +253,11 @@ void OnResponse (MessageId id, Result result)
219253
{
220254
//logger.LogTrace ("got id {0} res {1}", id, result);
221255
// Fixme
222-
var idx = pending_cmds.FindIndex (e => e.Item1.id == id.id && e.Item1.sessionId == id.sessionId);
223-
var item = pending_cmds [idx];
224-
pending_cmds.RemoveAt (idx);
225-
226-
item.Item2.SetResult (result);
256+
if (pending_cmds.Remove (id, out var task)) {
257+
task.SetResult (result);
258+
return;
259+
}
260+
logger.LogError ("Cannot respond to command: {id} with result: {result} - command is not pending", id, result);
227261
}
228262

229263
void ProcessBrowserMessage (string msg, CancellationToken token)
@@ -232,17 +266,20 @@ void ProcessBrowserMessage (string msg, CancellationToken token)
232266
var res = JObject.Parse (msg);
233267

234268
if (res ["id"] == null)
235-
pending_ops.Add (OnEvent (new SessionId { sessionId = res ["sessionId"]?.Value<string> () }, res ["method"].Value<string> (), res ["params"] as JObject, token));
269+
pending_ops.Add (OnEvent (new SessionId (res ["sessionId"]?.Value<string> ()), res ["method"].Value<string> (), res ["params"] as JObject, token));
236270
else
237-
OnResponse (new MessageId { id = res ["id"].Value<int> (), sessionId = res ["sessionId"]?.Value<string> () }, Result.FromJson (res));
271+
OnResponse (new MessageId (res ["sessionId"]?.Value<string> (), res ["id"].Value<int> ()), Result.FromJson (res));
238272
}
239273

240274
void ProcessIdeMessage (string msg, CancellationToken token)
241275
{
242276
Log ("protocol", $"ide: {msg}");
243277
if (!string.IsNullOrEmpty (msg)) {
244278
var res = JObject.Parse (msg);
245-
pending_ops.Add (OnCommand (new MessageId { id = res ["id"].Value<int> (), sessionId = res ["sessionId"]?.Value<string> () }, res ["method"].Value<string> (), res ["params"] as JObject, token));
279+
pending_ops.Add (OnCommand (
280+
new MessageId (res ["sessionId"]?.Value<string> (), res ["id"].Value<int> ()),
281+
res ["method"].Value<string> (),
282+
res ["params"] as JObject, token));
246283
}
247284
}
248285

@@ -263,9 +300,9 @@ Task<Result> SendCommandInternal (SessionId sessionId, string method, JObject ar
263300
});
264301
var tcs = new TaskCompletionSource<Result> ();
265302

266-
var msgId = new MessageId { id = id, sessionId = sessionId.sessionId };
303+
var msgId = new MessageId (sessionId.sessionId, id);
267304
//Log ("verbose", $"add cmd id {sessionId}-{id}");
268-
pending_cmds.Add ((msgId , tcs));
305+
pending_cmds[msgId] = tcs;
269306

270307
Send (this.browser, o, token);
271308
return tcs.Task;

src/Components/WebAssembly/DebugProxy/src/MonoDebugProxy/ws-proxy/MonoProxy.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -134,24 +134,22 @@ public DebugStore Store {
134134
}
135135

136136
internal class MonoProxy : DevToolsProxy {
137-
Dictionary<string, ExecutionContext> contexts = new Dictionary<string, ExecutionContext> ();
137+
Dictionary<SessionId, ExecutionContext> contexts = new Dictionary<SessionId, ExecutionContext> ();
138138

139139
public MonoProxy (ILoggerFactory loggerFactory) : base(loggerFactory) { }
140140

141141
ExecutionContext GetContext (SessionId sessionId)
142142
{
143-
var id = sessionId?.sessionId ?? "default";
144-
if (contexts.TryGetValue (id, out var context))
143+
if (contexts.TryGetValue (sessionId, out var context))
145144
return context;
146145

147-
throw new ArgumentException ($"Invalid Session: \"{id}\"", nameof (sessionId));
146+
throw new ArgumentException ($"Invalid Session: \"{sessionId}\"", nameof (sessionId));
148147
}
149148

150149
bool UpdateContext (SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext)
151150
{
152-
var id = sessionId?.sessionId ?? "default";
153-
var previous = contexts.TryGetValue (id, out previousExecutionContext);
154-
contexts[id] = executionContext;
151+
var previous = contexts.TryGetValue (sessionId, out previousExecutionContext);
152+
contexts[sessionId] = executionContext;
155153
return previous;
156154
}
157155

@@ -494,6 +492,14 @@ async Task<bool> Step (MessageId msg_id, StepKind kind, CancellationToken token)
494492

495493
var res = await SendMonoCommand (msg_id, MonoCommands.StartSingleStepping (kind), token);
496494

495+
var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();
496+
497+
if (ret_code.HasValue && ret_code.Value == 0) {
498+
context.CallStack = null;
499+
await SendCommand (msg_id, "Debugger.stepOut", new JObject (), token);
500+
return false;
501+
}
502+
497503
SendResponse (msg_id, Result.Ok (new JObject ()), token);
498504

499505
context.CallStack = null;

0 commit comments

Comments
 (0)