Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Addressing @radical comments.
  • Loading branch information
thaystg committed Dec 20, 2021
commit d7a3b53d18f0adac493da99675cc5ea5fd1084dc
53 changes: 36 additions & 17 deletions src/mono/wasm/debugger/BrowserDebugProxy/DevToolsHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,40 +60,59 @@ public MessageId(string sessionId, int id)
internal class DotnetObjectId
{
public string Scheme { get; }
public string Value { get; }
public string SubScheme { get; }
public string SubValue { get; }
public int Value { get; }
public int SubValue { get; set; }

public static bool TryParse(JToken jToken, out DotnetObjectId objectId) => TryParse(jToken?.Value<string>(), out objectId);

public static bool TryParse(string id, out DotnetObjectId objectId)
{
objectId = null;
if (id == null)
return false;

if (!id.StartsWith("dotnet:"))
return false;
try {
if (id == null)
return false;

string[] parts = id.Split(":", 5);
if (!id.StartsWith("dotnet:"))
return false;

if (parts.Length < 3)
return false;
string[] parts = id.Split(":");

objectId = new DotnetObjectId(parts[1], parts[2], parts.Length > 3 ? parts[3] : "", parts.Length > 3 ? parts[4] : "");
if (parts.Length < 3)
return false;

return true;
objectId = new DotnetObjectId(parts[1], int.Parse(parts[2]));
switch (objectId.Scheme)
{
case "methodId":
{
parts = id.Split(":");
objectId.SubValue = int.Parse(parts[3]);
break;
}
}
return true;
}
catch (Exception)
{
return false;
}
}

public DotnetObjectId(string scheme, string value, string subscheme = "", string subvalue = "")
public DotnetObjectId(string scheme, int value)
{
Scheme = scheme;
Value = value;
SubScheme = subscheme;
SubValue = subvalue;
}

public override string ToString() => $"dotnet:{Scheme}:{Value}";
public override string ToString()
{
switch (Scheme)
{
case "methodId":
return $"dotnet:{Scheme}:{Value}:{SubValue}";
}
return $"dotnet:{Scheme}:{Value}";
}
}

public struct Result
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public async Task<JObject> GetValueFromObject(JToken objRet, CancellationToken t
{
if (DotnetObjectId.TryParse(objRet?["value"]?["objectId"]?.Value<string>(), out DotnetObjectId objectId))
{
var exceptionObject = await context.SdbAgent.GetObjectValues(int.Parse(objectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token);
var exceptionObject = await context.SdbAgent.GetObjectValues(objectId.Value, GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.OwnProperties, token);
var exceptionObjectMessage = exceptionObject.FirstOrDefault(attr => attr["name"].Value<string>().Equals("_message"));
exceptionObjectMessage["value"]["value"] = objRet["value"]?["className"]?.Value<string>() + ": " + exceptionObjectMessage["value"]?["value"]?.Value<string>();
return exceptionObjectMessage["value"]?.Value<JObject>();
Expand Down Expand Up @@ -342,15 +342,15 @@ public async Task<JObject> Resolve(ElementAccessExpressionSyntax elementAccess,
switch (objectId.Scheme)
{
case "array":
rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token);
rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token);
return (JObject)rootObject["value"][elementIdx]["value"];
case "object":
var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token);
var typeIds = await context.SdbAgent.GetTypeIdFromObject(objectId.Value, true, token);
int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], "ToArray", token);
var toArrayRetMethod = await context.SdbAgent.InvokeMethodInObject(int.Parse(objectId.Value), methodId, elementAccess.Expression.ToString(), token);
var toArrayRetMethod = await context.SdbAgent.InvokeMethodInObject(objectId.Value, methodId, elementAccess.Expression.ToString(), token);
rootObject = await GetValueFromObject(toArrayRetMethod, token);
DotnetObjectId.TryParse(rootObject?["objectId"]?.Value<string>(), out DotnetObjectId arrayObjectId);
rootObject["value"] = await context.SdbAgent.GetArrayValues(int.Parse(arrayObjectId.Value), token);
rootObject["value"] = await context.SdbAgent.GetArrayValues(arrayObjectId.Value, token);
return (JObject)rootObject["value"][elementIdx]["value"];
default:
throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of type '{objectId.Scheme}'");
Expand Down Expand Up @@ -389,7 +389,7 @@ public async Task<JObject> Resolve(InvocationExpressionSyntax method, Dictionary
if (rootObject != null)
{
DotnetObjectId.TryParse(rootObject?["objectId"]?.Value<string>(), out DotnetObjectId objectId);
var typeIds = await context.SdbAgent.GetTypeIdFromObject(int.Parse(objectId.Value), true, token);
var typeIds = await context.SdbAgent.GetTypeIdFromObject(objectId.Value, true, token);
int methodId = await context.SdbAgent.GetMethodIdByName(typeIds[0], methodName, token);
var className = await context.SdbAgent.GetTypeNameOriginal(typeIds[0], token);
if (methodId == 0) //try to search on System.Linq.Enumerable
Expand Down
35 changes: 17 additions & 18 deletions src/mono/wasm/debugger/BrowserDebugProxy/MonoProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ protected override async Task<bool> AcceptCommand(MessageId id, string method, J
{
case "scope":
return await OnSetVariableValue(id,
int.Parse(objectId.Value),
objectId.Value,
args?["variableName"]?.Value<string>(),
args?["newValue"],
token);
Expand Down Expand Up @@ -449,7 +449,7 @@ protected override async Task<bool> AcceptCommand(MessageId id, string method, J
{
case "scope":
return await OnEvaluateOnCallFrame(id,
int.Parse(objectId.Value),
objectId.Value,
args?["expression"]?.Value<string>(), token);
default:
return false;
Expand Down Expand Up @@ -586,16 +586,17 @@ private async Task<bool> CallOnFunction(MessageId id, JObject args, Cancellation
switch (objectId.Scheme)
{
case "object":
args["details"] = await context.SdbAgent.GetObjectProxy(int.Parse(objectId.Value), token);
case "methodId":
args["details"] = await context.SdbAgent.GetObjectProxy(objectId.Value, token);
break;
case "valuetype":
args["details"] = await context.SdbAgent.GetValueTypeProxy(int.Parse(objectId.Value), token);
args["details"] = await context.SdbAgent.GetValueTypeProxy(objectId.Value, token);
break;
case "pointer":
args["details"] = await context.SdbAgent.GetPointerContent(int.Parse(objectId.Value), token);
args["details"] = await context.SdbAgent.GetPointerContent(objectId.Value, token);
break;
case "array":
args["details"] = await context.SdbAgent.GetArrayValuesProxy(int.Parse(objectId.Value), token);
args["details"] = await context.SdbAgent.GetArrayValuesProxy(objectId.Value, token);
break;
case "cfo_res":
{
Expand Down Expand Up @@ -680,27 +681,25 @@ internal async Task<JToken> RuntimeGetPropertiesInternal(SessionId id, DotnetObj
{
case "scope":
{
var res = await GetScopeProperties(id, int.Parse(objectId.Value), token);
var res = await GetScopeProperties(id, objectId.Value, token);
return res.Value?["result"];
}
case "valuetype":
return await context.SdbAgent.GetValueTypeValues(int.Parse(objectId.Value), accessorPropertiesOnly, token);
return await context.SdbAgent.GetValueTypeValues(objectId.Value, accessorPropertiesOnly, token);
case "array":
return await context.SdbAgent.GetArrayValues(int.Parse(objectId.Value), token);
case "object":
return await context.SdbAgent.GetArrayValues(objectId.Value, token);
case "methodId":
{
if (objectId.SubScheme == "methodId") //getter
{
var objRet = await context.SdbAgent.InvokeMethodInObject(int.Parse(objectId.Value), int.Parse(objectId.SubValue), "", token);
return new JArray(objRet);
}
return await context.SdbAgent.GetObjectValues(int.Parse(objectId.Value), objectValuesOpt, token);
var objRet = await context.SdbAgent.InvokeMethodInObject(objectId.Value, objectId.SubValue, "", token);
return new JArray(objRet);
}
case "object":
return await context.SdbAgent.GetObjectValues(objectId.Value, objectValuesOpt, token);
case "pointer":
return new JArray{await context.SdbAgent.GetPointerContent(int.Parse(objectId.Value), token)};
return new JArray{await context.SdbAgent.GetPointerContent(objectId.Value, token)};
case "cfo_res":
{
Result res = await SendMonoCommand(id, MonoCommands.GetDetails(RuntimeId, int.Parse(objectId.Value), args), token);
Result res = await SendMonoCommand(id, MonoCommands.GetDetails(RuntimeId, objectId.Value, args), token);
string value_json_str = res.Value["result"]?["value"]?["__value_as_json_string__"]?.Value<string>();
return value_json_str != null ? JArray.Parse(value_json_str) : null;
}
Expand Down
23 changes: 12 additions & 11 deletions src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -514,11 +514,11 @@ public void WriteObj(DotnetObjectId objectId, MonoSDBHelper SdbHelper)
{
if (objectId.Scheme == "object")
{
Write(ElementType.Class, int.Parse(objectId.Value));
Write(ElementType.Class, objectId.Value);
}
else if (objectId.Scheme == "valuetype")
{
Write(SdbHelper.valueTypes[int.Parse(objectId.Value)].valueTypeBuffer);
Write(SdbHelper.valueTypes[objectId.Value].valueTypeBuffer);
}
}
public async Task<bool> WriteConst(LiteralExpressionSyntax constValue, MonoSDBHelper SdbHelper, CancellationToken token)
Expand Down Expand Up @@ -1566,13 +1566,14 @@ public async Task<int> GetPropertyMethodIdByName(int typeId, string propertyName
return -1;
}

public async Task<JArray> CreateJArrayForProperties(int typeId, ArraySegment<byte> object_buffer, JArray attributes, bool isAutoExpandable, string objectId, bool isOwn, CancellationToken token)
public async Task<JArray> CreateJArrayForProperties(int typeId, ArraySegment<byte> object_buffer, JArray attributes, bool isAutoExpandable, string objectIdStr, bool isOwn, CancellationToken token)
{
JArray ret = new JArray();
using var retDebuggerCmdReader = await GetTypePropertiesReader(typeId, token);
if (retDebuggerCmdReader == null)
return null;

if (!DotnetObjectId.TryParse(objectIdStr, out DotnetObjectId objectId))
return null;
var nProperties = retDebuggerCmdReader.ReadInt32();
for (int i = 0 ; i < nProperties; i++)
{
Expand Down Expand Up @@ -1602,11 +1603,11 @@ public async Task<JArray> CreateJArrayForProperties(int typeId, ArraySegment<byt
get = new
{
type = "function",
objectId = $"{objectId}:methodId:{getMethodId}",
objectId = $"dotnet:methodId:{objectId.Value}:{getMethodId}",
className = "Function",
description = "get " + propertyNameStr + " ()",
methodId = getMethodId,
objectIdValue = objectId
objectIdValue = objectIdStr
},
name = propertyNameStr
});
Expand Down Expand Up @@ -2061,10 +2062,10 @@ public async Task<JArray> GetHoistedLocalVariables(int objectId, JArray asyncLoc
{
if (DotnetObjectId.TryParse(asyncLocal?["value"]?["objectId"]?.Value<string>(), out DotnetObjectId dotnetObjectId))
{
if (int.TryParse(dotnetObjectId.Value, out int objectIdToGetInfo) && !objectsAlreadyRead.Contains(objectIdToGetInfo))
if (!objectsAlreadyRead.Contains(dotnetObjectId.Value))
{
var asyncLocalsFromObject = await GetObjectValues(objectIdToGetInfo, GetObjectCommandOptions.WithProperties, token);
var hoistedLocalVariable = await GetHoistedLocalVariables(objectIdToGetInfo, asyncLocalsFromObject, token);
var asyncLocalsFromObject = await GetObjectValues(dotnetObjectId.Value, GetObjectCommandOptions.WithProperties, token);
var hoistedLocalVariable = await GetHoistedLocalVariables(dotnetObjectId.Value, asyncLocalsFromObject, token);
asyncLocalsFull = new JArray(asyncLocalsFull.Union(hoistedLocalVariable));
}
}
Expand Down Expand Up @@ -2302,7 +2303,7 @@ public async Task<JArray> GetValuesFromDebuggerProxyAttribute(int objectId, int

var retMethod = await InvokeMethod(invokeParamsWriter.GetParameterBuffer(), methodId, "methodRet", token);
DotnetObjectId.TryParse(retMethod?["value"]?["objectId"]?.Value<string>(), out DotnetObjectId dotnetObjectId);
var displayAttrs = await GetObjectValues(int.Parse(dotnetObjectId.Value), GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.ForDebuggerProxyAttribute, token);
var displayAttrs = await GetObjectValues(dotnetObjectId.Value, GetObjectCommandOptions.WithProperties | GetObjectCommandOptions.ForDebuggerProxyAttribute, token);
return displayAttrs;
}
}
Expand Down Expand Up @@ -2392,7 +2393,7 @@ public async Task<JArray> GetObjectValues(int objectId, GetObjectCommandOptions
if (!getCommandType.HasFlag(GetObjectCommandOptions.WithProperties))
return ret;
using var commandParamsObjWriter = new MonoBinaryWriter();
commandParamsObjWriter.WriteObj(new DotnetObjectId("object", $"{objectId}"), this);
commandParamsObjWriter.WriteObj(new DotnetObjectId("object", objectId), this);
var props = await CreateJArrayForProperties(typeId[i], commandParamsObjWriter.GetParameterBuffer(), ret, getCommandType.HasFlag(GetObjectCommandOptions.ForDebuggerProxyAttribute), $"dotnet:object:{objectId}", i == 0, token);
ret = new JArray(ret.Union(props));

Expand Down