-
Notifications
You must be signed in to change notification settings - Fork 4.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[wasm][debugger] Support deep member accesses for EvaluteOnCallFrame (#…
…40836) * [wasm][debugger] Support deep member accesses for EvaluteOnCallFrame Eg. `obj.Property.X`, or `obj.Y + obj.Z.p` Each of the member access expressions (like `a.b.c`) must be of only primitive types. Though if the expression is a single member access (and nothing else, like `"a.b.c"`), then that can be a non-primitive type. This works by sending the expression to the browser, where it gets resolved by `library_mono.js`. And that takes an easy route for doing this, essentially just fetching the list of locals/properties, and using that. There are better ways to do this, that will be explored later. * [wasm][debugger][tests] Remove some debug spew * [wasm][debugger] fix formatting with dotnet-format
- Loading branch information
Showing
10 changed files
with
1,090 additions
and
352 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
300 changes: 219 additions & 81 deletions
300
src/mono/wasm/debugger/BrowserDebugProxy/EvaluateExpression.cs
Large diffs are not rendered by default.
Oops, something went wrong.
75 changes: 75 additions & 0 deletions
75
src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using Microsoft.Extensions.Logging; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
|
||
namespace Microsoft.WebAssembly.Diagnostics | ||
{ | ||
internal class MemberReferenceResolver | ||
{ | ||
private MessageId messageId; | ||
private int scopeId; | ||
private MonoProxy proxy; | ||
private ExecutionContext ctx; | ||
private PerScopeCache scopeCache; | ||
private VarInfo[] varIds; | ||
private ILogger logger; | ||
private bool locals_fetched = false; | ||
|
||
public MemberReferenceResolver(MonoProxy proxy, ExecutionContext ctx, MessageId msg_id, int scope_id, ILogger logger) | ||
{ | ||
messageId = msg_id; | ||
scopeId = scope_id; | ||
this.proxy = proxy; | ||
this.ctx = ctx; | ||
this.logger = logger; | ||
scopeCache = ctx.GetCacheForScope(scope_id); | ||
} | ||
|
||
// Checks Locals, followed by `this` | ||
public async Task<JObject> Resolve(string var_name, CancellationToken token) | ||
{ | ||
if (scopeCache.Locals.Count == 0 && !locals_fetched) | ||
{ | ||
var scope_res = await proxy.GetScopeProperties(messageId, scopeId, token); | ||
if (scope_res.IsErr) | ||
throw new Exception($"BUG: Unable to get properties for scope: {scopeId}. {scope_res}"); | ||
locals_fetched = true; | ||
} | ||
|
||
if (scopeCache.Locals.TryGetValue(var_name, out var obj)) | ||
{ | ||
return obj["value"]?.Value<JObject>(); | ||
} | ||
|
||
if (scopeCache.MemberReferences.TryGetValue(var_name, out var ret)) | ||
return ret; | ||
|
||
if (varIds == null) | ||
{ | ||
var scope = ctx.CallStack.FirstOrDefault(s => s.Id == scopeId); | ||
varIds = scope.Method.GetLiveVarsAt(scope.Location.CliLocation.Offset); | ||
} | ||
|
||
var res = await proxy.SendMonoCommand(messageId, MonoCommands.EvaluateMemberAccess(scopeId, var_name, varIds), token); | ||
if (res.IsOk) | ||
{ | ||
ret = res.Value?["result"]?["value"]?["value"]?.Value<JObject>(); | ||
scopeCache.MemberReferences[var_name] = ret; | ||
} | ||
else | ||
{ | ||
logger.LogDebug(res.Error.ToString()); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.