Skip to content

Update debugger proxy to match Mono commit b777471fcace8 #19826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Linq;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
Expand All @@ -11,12 +11,45 @@
using Microsoft.Extensions.Logging;

namespace WebAssembly.Net.Debugging {
internal class SessionId {
public string sessionId;
internal struct SessionId {
public readonly string sessionId;

public SessionId (string sessionId)
{
this.sessionId = sessionId;
}

public override int GetHashCode ()
=> sessionId?.GetHashCode () ?? 0;

public override bool Equals (object obj)
=> (obj is SessionId) ? ((SessionId) obj).sessionId == sessionId : false;

public override string ToString ()
=> $"session-{sessionId}";
}

internal class MessageId : SessionId {
public int id;
internal struct MessageId {
public readonly string sessionId;
public readonly int id;

public MessageId (string sessionId, int id)
{
this.sessionId = sessionId;
this.id = id;
}

public static implicit operator SessionId (MessageId id)
=> new SessionId (id.sessionId);

public override string ToString ()
=> $"msg-{sessionId}:::{id}";

public override int GetHashCode ()
=> (sessionId?.GetHashCode () ?? 0) ^ id.GetHashCode ();

public override bool Equals (object obj)
=> (obj is MessageId) ? ((MessageId) obj).sessionId == sessionId && ((MessageId) obj).id == id : false;
}

internal struct Result {
Expand All @@ -28,17 +61,17 @@ internal struct Result {

Result (JObject result, JObject error)
{
if (result != null && error != null)
throw new ArgumentException ($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null.");

bool resultHasError = String.Compare ((result? ["result"] as JObject)? ["subtype"]?. Value<string> (), "error") == 0;
if (result != null && resultHasError) {
this.Value = null;
this.Error = result;
} else {
this.Value = result;
this.Error = error;
}
if (result != null && error != null)
throw new ArgumentException ($"Both {nameof(result)} and {nameof(error)} arguments cannot be non-null.");

bool resultHasError = String.Compare ((result? ["result"] as JObject)? ["subtype"]?. Value<string> (), "error") == 0;
if (result != null && resultHasError) {
this.Value = null;
this.Error = result;
} else {
this.Value = result;
this.Error = error;
}
}

public static Result FromJson (JObject obj)
Expand Down Expand Up @@ -120,12 +153,13 @@ public Task Pump (CancellationToken token)
internal class DevToolsProxy {
TaskCompletionSource<bool> side_exception = new TaskCompletionSource<bool> ();
TaskCompletionSource<bool> client_initiated_close = new TaskCompletionSource<bool> ();
List<(MessageId, TaskCompletionSource<Result>)> pending_cmds = new List<(MessageId, TaskCompletionSource<Result>)> ();
Dictionary<MessageId, TaskCompletionSource<Result>> pending_cmds = new Dictionary<MessageId, TaskCompletionSource<Result>> ();
ClientWebSocket browser;
WebSocket ide;
int next_cmd_id;
List<Task> pending_ops = new List<Task> ();
List<DevToolsQueue> queues = new List<DevToolsQueue> ();

protected readonly ILogger logger;

public DevToolsProxy (ILoggerFactory loggerFactory)
Expand Down Expand Up @@ -219,11 +253,11 @@ void OnResponse (MessageId id, Result result)
{
//logger.LogTrace ("got id {0} res {1}", id, result);
// Fixme
var idx = pending_cmds.FindIndex (e => e.Item1.id == id.id && e.Item1.sessionId == id.sessionId);
var item = pending_cmds [idx];
pending_cmds.RemoveAt (idx);

item.Item2.SetResult (result);
if (pending_cmds.Remove (id, out var task)) {
task.SetResult (result);
return;
}
logger.LogError ("Cannot respond to command: {id} with result: {result} - command is not pending", id, result);
}

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

if (res ["id"] == null)
pending_ops.Add (OnEvent (new SessionId { sessionId = res ["sessionId"]?.Value<string> () }, res ["method"].Value<string> (), res ["params"] as JObject, token));
pending_ops.Add (OnEvent (new SessionId (res ["sessionId"]?.Value<string> ()), res ["method"].Value<string> (), res ["params"] as JObject, token));
else
OnResponse (new MessageId { id = res ["id"].Value<int> (), sessionId = res ["sessionId"]?.Value<string> () }, Result.FromJson (res));
OnResponse (new MessageId (res ["sessionId"]?.Value<string> (), res ["id"].Value<int> ()), Result.FromJson (res));
}

void ProcessIdeMessage (string msg, CancellationToken token)
{
Log ("protocol", $"ide: {msg}");
if (!string.IsNullOrEmpty (msg)) {
var res = JObject.Parse (msg);
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));
pending_ops.Add (OnCommand (
new MessageId (res ["sessionId"]?.Value<string> (), res ["id"].Value<int> ()),
res ["method"].Value<string> (),
res ["params"] as JObject, token));
}
}

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

var msgId = new MessageId { id = id, sessionId = sessionId.sessionId };
var msgId = new MessageId (sessionId.sessionId, id);
//Log ("verbose", $"add cmd id {sessionId}-{id}");
pending_cmds.Add ((msgId , tcs));
pending_cmds[msgId] = tcs;

Send (this.browser, o, token);
return tcs.Task;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,24 +134,22 @@ public DebugStore Store {
}

internal class MonoProxy : DevToolsProxy {
Dictionary<string, ExecutionContext> contexts = new Dictionary<string, ExecutionContext> ();
Dictionary<SessionId, ExecutionContext> contexts = new Dictionary<SessionId, ExecutionContext> ();

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

ExecutionContext GetContext (SessionId sessionId)
{
var id = sessionId?.sessionId ?? "default";
if (contexts.TryGetValue (id, out var context))
if (contexts.TryGetValue (sessionId, out var context))
return context;

throw new ArgumentException ($"Invalid Session: \"{id}\"", nameof (sessionId));
throw new ArgumentException ($"Invalid Session: \"{sessionId}\"", nameof (sessionId));
}

bool UpdateContext (SessionId sessionId, ExecutionContext executionContext, out ExecutionContext previousExecutionContext)
{
var id = sessionId?.sessionId ?? "default";
var previous = contexts.TryGetValue (id, out previousExecutionContext);
contexts[id] = executionContext;
var previous = contexts.TryGetValue (sessionId, out previousExecutionContext);
contexts[sessionId] = executionContext;
return previous;
}

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

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

var ret_code = res.Value? ["result"]? ["value"]?.Value<int> ();

if (ret_code.HasValue && ret_code.Value == 0) {
context.CallStack = null;
await SendCommand (msg_id, "Debugger.stepOut", new JObject (), token);
return false;
}

SendResponse (msg_id, Result.Ok (new JObject ()), token);

context.CallStack = null;
Expand Down