From 6d988af7994d640a50b26e4dccb990f13b89c2c1 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 26 Sep 2023 10:29:27 +0000 Subject: [PATCH 01/13] Prepare test cases for signle dim. --- .../EvaluateOnCallFrameTests.cs | 183 ++++++++++-------- .../debugger-test/debugger-evaluate-test.cs | 64 +++--- 2 files changed, 137 insertions(+), 110 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 60ed3fdd4c288b..f7e66cd5966fb2 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -576,76 +576,83 @@ await EvaluateOnCallFrameAndCheck(id, [ConditionalFact(nameof(RunningOnChrome))] public async Task EvaluateIndexingNegative() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", $"window.setTimeout(function() {{ invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); 1 }})", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); - var (_, res) = await EvaluateOnCallFrame(id, "f.idx0[2]", expect_ok: false ); - Assert.Equal("Unable to evaluate element access 'f.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); + var (_, res) = await EvaluateOnCallFrame(id, "cc.idx0[2]", expect_ok: false ); + Assert.Equal("Unable to evaluate element access 'cc.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(560, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(568, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); - (_, res) = await EvaluateOnCallFrame(id, "f[1]", expect_ok: false ); - Assert.Equal( "Unable to evaluate element access 'f[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.TestEvaluate'", res.Error["result"]?["description"]?.Value()); + (_, res) = await EvaluateOnCallFrame(id, "c[1]", expect_ok: false ); + Assert.Equal( "Unable to evaluate element access 'c[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.ClassWithIndexers'", res.Error["result"]?["description"]?.Value()); }); [Fact] public async Task EvaluateIndexingsByConstant() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f.numList[0]", TNumber(1)), - ("f.textList[1]", TString("2")), - ("f.numArray[1]", TNumber(2)), - ("f.textArray[0]", TString("1"))); + ("cc.numList[0]", TNumber(1)), + ("cc.textList[1]", TString("2")), + ("cc.numArray[1]", TNumber(2)), + ("cc.textArray[0]", TString("1"))); }); [Fact] public async Task EvaluateIndexingByLocalVariable() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f.numList[i]", TNumber(1)), - ("f.textList[j]", TString("2")), - ("f.numArray[j]", TNumber(2)), - ("f.textArray[i]", TString("1"))); + ("cc.numList[i]", TNumber(1)), + ("cc.textList[j]", TString("2")), + ("cc.numArray[j]", TNumber(2)), + ("cc.textArray[i]", TString("1"))); }); [ConditionalFact(nameof(RunningOnChrome))] public async Task EvaluateObjectIndexingByNonIntConst() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f[\"longstring\"]", TBool(true)), - ("f[\"-\"]", TBool(false)), - ("f[\'-\']", TString("res_-")), - ("f[true]", TString("True")), - //("f[1.23]", TNumber(1)) // Not supported yet - float/double - ("f.indexedByStr[\"1\"]", TBool(true)), - ("f.indexedByStr[\"111\"]", TBool(false)), - ("f.indexedByStr[\"true\"]", TBool(true)), - ("f.indexedByChar[\'i\']", TString("I")), - ("f.indexedByChar[\'5\']", TString("5")), - ("f.indexedByBool[true]", TString("TRUE")), - ("f.indexedByBool[false]", TString("FALSE")) + ("c[\"longstring\"]", TBool(true)), + ("c[\"-\"]", TBool(false)), + ("c[\'-\']", TString("res_-")), + ("c[true]", TString("True")), + ("c[1.23]", TNumber(1)), + + // ("s[\"longstring\"]", TBool(true)), + // ("s[\"-\"]", TBool(false)), + // ("s[\'-\']", TString("res_-")), + // ("s[true]", TString("True")), + // ("s[1.23]", TNumber(1)), + + ("cc.indexedByStr[\"1\"]", TBool(true)), + ("cc.indexedByStr[\"111\"]", TBool(false)), + ("cc.indexedByStr[\"true\"]", TBool(true)), + ("cc.indexedByChar[\'i\']", TString("I")), + ("cc.indexedByChar[\'5\']", TString("5")), + ("cc.indexedByBool[true]", TString("TRUE")), + ("cc.indexedByBool[false]", TString("FALSE")) ); - var (_, res) = await EvaluateOnCallFrame(id,"f.indexedByStr[\"invalid\"]", expect_ok: false); - Assert.True(res.Error["result"]?["description"]?.Value().StartsWith("Cannot evaluate '(f.indexedByStr[\"invalid\"]", StringComparison.Ordinal)); - (_, res) = await EvaluateOnCallFrame(id,"f.indexedByStr[null]", expect_ok: false); - Assert.True(res.Error["result"]?["description"]?.Value().StartsWith("Cannot evaluate '(f.indexedByStr[null]", StringComparison.Ordinal)); + var (_, res) = await EvaluateOnCallFrame(id,"cc.indexedByStr[\"invalid\"]", expect_ok: false); + Assert.True(res.Error["result"]?["description"]?.Value().StartsWith("Cannot evaluate '(cc.indexedByStr[\"invalid\"]", StringComparison.Ordinal)); + (_, res) = await EvaluateOnCallFrame(id,"cc.indexedByStr[null]", expect_ok: false); + Assert.True(res.Error["result"]?["description"]?.Value().StartsWith("Cannot evaluate '(cc.indexedByStr[null]", StringComparison.Ordinal)); }); [Fact] @@ -656,15 +663,25 @@ public async Task EvaluateObjectByNonIntLocals() => await CheckInspectLocalsAtBr { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f[longString]", TBool(true)), - ("f[aBool]", TString("True")), - ("f[aChar]", TString("res_9")), - ("f[shortString]", TBool(false)), - ("f[aFloat]", TNumber(1)), - ("f[aDouble]", TNumber(2)), - ("f[aDecimal]", TNumber(3)), - ("f[arr]", TChar('t')), - ("f[objIdx]", TNumber(123)) + ("c[longString]", TBool(true)), + ("c[aBool]", TString("True")), + ("c[aChar]", TString("res_9")), + ("c[shortString]", TBool(false)), + ("c[aFloat]", TNumber(1)), + ("c[aDouble]", TNumber(2)), + ("c[aDecimal]", TNumber(3)), + ("c[arr]", TChar('t')), + ("c[objIdx]", TNumber(123)) + + // ("s[longString]", TBool(true)), + // ("s[aBool]", TString("True")), + // ("s[aChar]", TString("res_9")), + // ("s[shortString]", TBool(false)), + // ("s[aFloat]", TNumber(1)), + // ("s[aDouble]", TNumber(2)), + // ("s[aDecimal]", TNumber(3)), + // ("s[arr]", TChar('t')), + // ("s[objIdx]", TNumber(123)) ); }); @@ -676,24 +693,26 @@ public async Task EvaluateNestedObjectIndexingByNonIntLocals() => await CheckIns { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f[f.textArray[0]]", TBool(false)), // f["1"] - ("f[f.textArray[j]]", TBool(false)) // f["2"] + ("c[cc.textArray[0]]", TBool(false)), // c["1"] + ("c[cc.textArray[j]]", TBool(false)) // c["2"] + // ("s[cc.textArray[0]]", TBool(false)), // s["1"] + // ("s[cc.textArray[j]]", TBool(false)) // s["2"] ); }); // ToDo: https://github.com/dotnet/runtime/issues/76015 [Fact] public async Task EvaluateIndexingByExpression() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f.numList[i + 1]", TNumber(2)), - ("f.textList[(2 * j) - 1]", TString("2")), - ("f.textList[j - 1]", TString("1")), - ("f.numArray[f.numList[j - 1]]", TNumber(2)) + ("cc.numList[i + 1]", TNumber(2)), + ("cc.textList[(2 * j) - 1]", TString("2")), + ("cc.textList[j - 1]", TString("1")), + ("cc.numArray[cc.numList[j - 1]]", TNumber(2)) ); }); @@ -714,63 +733,63 @@ await EvaluateOnCallFrameAndCheck(id, [ConditionalFact(nameof(RunningOnChrome))] public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", $"window.setTimeout(function() {{ invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); 1 }})", wait_for_event_fn: async (pause_location) => { // indexing with expression of a wrong type var id = pause_location["callFrames"][0]["callFrameId"].Value(); - var (_, res) = await EvaluateOnCallFrame(id, "f.numList[\"a\" + 1]", expect_ok: false ); - Assert.Equal("Unable to evaluate element access 'f.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); + var (_, res) = await EvaluateOnCallFrame(id, "cc.numList[\"a\" + 1]", expect_ok: false ); + Assert.Equal("Unable to evaluate element access 'cc.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(560, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(568, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); }); [ConditionalFact(nameof(RunningOnChrome))] public async Task EvaluateIndexingByExpressionContainingUnknownIdentifier() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", $"window.setTimeout(function() {{ invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); 1 }})", wait_for_event_fn: async (pause_location) => { // indexing with expression of a wrong type var id = pause_location["callFrames"][0]["callFrameId"].Value(); - var (_, res) = await EvaluateOnCallFrame(id, "f.numList[\"a\" + x]", expect_ok: false); + var (_, res) = await EvaluateOnCallFrame(id, "cc.numList[\"a\" + x]", expect_ok: false); Assert.Equal("The name x does not exist in the current context", res.Error["result"]?["description"]?.Value()); }); [Fact] public async Task EvaluateIndexingByMemberVariables() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f.idx0", TNumber(0)), - ("f.idx1", TNumber(1)), - ("f.numList[f.idx0]", TNumber(1)), - ("f.textList[f.idx1]", TString("2")), - ("f.numArray[f.idx1]", TNumber(2)), - ("f.textArray[f.idx0]", TString("1"))); + ("cc.idx0", TNumber(0)), + ("cc.idx1", TNumber(1)), + ("cc.numList[cc.idx0]", TNumber(1)), + ("cc.textList[cc.idx1]", TString("2")), + ("cc.numArray[cc.idx1]", TNumber(2)), + ("cc.textArray[cc.idx0]", TString("1"))); }); [Fact] public async Task EvaluateIndexingNested() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("f.idx0", TNumber(0)), - ("f.numList[f.numList[f.idx0]]", TNumber(2)), - ("f.textList[f.numList[f.idx0]]", TString("2")), - ("f.numArray[f.numArray[f.idx0]]", TNumber(2)), - ("f.textArray[f.numArray[f.idx0]]", TString("2"))); + ("cc.idx0", TNumber(0)), + ("cc.numList[cc.numList[cc.idx0]]", TNumber(2)), + ("cc.textList[cc.numList[cc.idx0]]", TString("2")), + ("cc.numArray[cc.numArray[cc.idx0]]", TNumber(2)), + ("cc.textArray[cc.numArray[cc.idx0]]", TString("2"))); }); @@ -841,7 +860,7 @@ await EvaluateOnCallFrameAndCheck(id, [ConditionalFact(nameof(RunningOnChrome))] public async Task EvaluateIndexingJagged() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 5, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 6, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { @@ -849,19 +868,19 @@ public async Task EvaluateIndexingJagged() => await CheckInspectLocalsAtBreakpoi await EvaluateOnCallFrameAndCheck(id, ("j", TNumber(1)), - ("f.idx1", TNumber(1)), - ("f.numArrayOfArrays[1][1]", TNumber(2)), - ("f.numArrayOfArrays[j][j]", TNumber(2)), - ("f.numArrayOfArrays[f.idx1][f.idx1]", TNumber(2)), - ("f.numListOfLists[1][1]", TNumber(2)), - ("f.numListOfLists[j][j]", TNumber(2)), - ("f.numListOfLists[f.idx1][f.idx1]", TNumber(2)), - ("f.textArrayOfArrays[1][1]", TString("2")), - ("f.textArrayOfArrays[j][j]", TString("2")), - ("f.textArrayOfArrays[f.idx1][f.idx1]", TString("2")), - ("f.textListOfLists[1][1]", TString("2")), - ("f.textListOfLists[j][j]", TString("2")), - ("f.textListOfLists[f.idx1][f.idx1]", TString("2"))); + ("cc.idx1", TNumber(1)), + ("cc.numArrayOfArrays[1][1]", TNumber(2)), + ("cc.numArrayOfArrays[j][j]", TNumber(2)), + ("cc.numArrayOfArrays[cc.idx1][cc.idx1]", TNumber(2)), + ("cc.numListOfLists[1][1]", TNumber(2)), + ("cc.numListOfLists[j][j]", TNumber(2)), + ("cc.numListOfLists[cc.idx1][cc.idx1]", TNumber(2)), + ("cc.textArrayOfArrays[1][1]", TString("2")), + ("cc.textArrayOfArrays[j][j]", TString("2")), + ("cc.textArrayOfArrays[cc.idx1][cc.idx1]", TString("2")), + ("cc.textListOfLists[1][1]", TString("2")), + ("cc.textListOfLists[j][j]", TString("2")), + ("cc.textListOfLists[cc.idx1][cc.idx1]", TString("2"))); }); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index cd4fdc20038990..22587cc8ff4d53 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -508,22 +508,33 @@ public class EvaluateLocalsWithIndexingTests { public record Indexer(int index); - public class TestEvaluate + public class CommonCollections { - public List numList; - public List textList; - public int[] numArray; - public string[] textArray; + public List numList = new List { 1, 2 }; + public List textList = new List { "1", "2" }; + public int[] numArray = new int[] { 1, 2 }; + public string[] textArray = new string[] { "1", "2" }; public int[][] numArrayOfArrays; public List> numListOfLists; public string[][] textArrayOfArrays; public List> textListOfLists; - public Dictionary indexedByStr; - public Dictionary indexedByChar; - public Dictionary indexedByBool; - public int idx0; - public int idx1; + public Dictionary indexedByStr = new Dictionary() { { "1", true }, { "111", false }, { "true", true} }; + public Dictionary indexedByChar = new Dictionary() { { 'i', "I" }, { '5', "5" } }; + public Dictionary indexedByBool = new Dictionary() { { true, "TRUE" }, { false, "FALSE" } }; + public int idx0 = 0; + public int idx1 = 1; + public CommonCollections() + { + numArrayOfArrays = new int[][] { numArray, numArray }; + numListOfLists = new List> { numList, numList }; + textArrayOfArrays = new string[][] { textArray, textArray }; + textListOfLists = new List> { textList, textList }; + } + } + + public class ClassWithIndexers + { // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 public string this[char key] => "res_" + key; public string this[bool key] => key.ToString(); @@ -533,31 +544,28 @@ public class TestEvaluate public int this[decimal key] => (int)key; public int this[Indexer indexer] => indexer.index; public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; + } - public void run() - { - numList = new List { 1, 2 }; - textList = new List { "1", "2" }; - numArray = new int[] { 1, 2 }; - textArray = new string[] { "1", "2" }; - numArrayOfArrays = new int[][] { numArray, numArray }; - numListOfLists = new List> { numList, numList }; - textArrayOfArrays = new string[][] { textArray, textArray }; - textListOfLists = new List> { textList, textList }; - indexedByStr = new Dictionary() { { "1", true }, { "111", false }, { "true", true} }; - indexedByChar = new Dictionary() { { 'i', "I" }, { '5', "5" } }; - indexedByBool = new Dictionary() { { true, "TRUE" }, { false, "FALSE" } }; - idx0 = 0; - idx1 = 1; - } + public struct StructWithIndexers + { + // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 + public string this[char key] => "res_" + key; + public string this[bool key] => key.ToString(); + public bool this[string key] => key.Length > 3; + public int this[double key] => (int)key; + public int this[float key] => (int)key; + public int this[decimal key] => (int)key; + public int this[Indexer indexer] => indexer.index; + public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; } public static void EvaluateLocals() { int i = 0; int j = 1; - TestEvaluate f = new TestEvaluate(); - f.run(); + ClassWithIndexers c = new(); + StructWithIndexers s = new(); + CommonCollections cc = new(); string longString = "longString"; string shortString = "9"; char aChar = '9'; From 8c99fd3c548512bf9fc73ec2c02dadbf64b3f24d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:17:30 +0000 Subject: [PATCH 02/13] Fixed for constant indices. --- .../MemberReferenceResolver.cs | 85 ++++++++++++------- .../EvaluateOnCallFrameTests.cs | 14 ++- 2 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 650583a9dc7bf2..605405c44f3231 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -403,7 +403,10 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, var typeInfo = await context.SdbAgent.GetTypeInfo(valueType.TypeId, token); if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray.Count) return (JObject)valueType.InlineArray[elementIdx]["value"]; - throw new InvalidOperationException($"Index is outside the bounds of the inline array"); + JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, indexObject, elementIdxInfo, token); + if (vtResult == null) // ToDo: choose a logical order of operations for inline array, this is messy + throw new InvalidOperationException($"Index is outside the bounds of the inline array"); + return vtResult; } case "array": rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token); @@ -431,36 +434,12 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, if (indexObject is null && elementIdxInfo.IndexingExpression is null) throw new InternalErrorException($"Unable to write index parameter to invoke the method in the runtime."); - var typeIds = await context.SdbAgent.GetTypeIdsForObject(objectId.Value, true, token); - int[] methodIds = await context.SdbAgent.GetMethodIdsByName(typeIds[0], "get_Item", BindingFlags.Default, token); - if (methodIds == null || methodIds.Length == 0) - throw new InvalidOperationException($"Type '{rootObject?["className"]?.Value()}' cannot be indexed."); - - // ToDo: optimize the loop by choosing the right method at once without trying out them all - for (int i = 0; i < methodIds.Length; i++) - { - MethodInfoWithDebugInformation methodInfo = await context.SdbAgent.GetMethodInfo(methodIds[i], token); - ParameterInfo[] paramInfo = methodInfo.GetParametersInfo(); - if (paramInfo.Length == 1) - { - try - { - if (indexObject != null && !CheckParametersCompatibility(paramInfo[0].TypeCode, indexObject)) - continue; - ArraySegment buffer = indexObject is null ? - await WriteLiteralExpressionAsIndex(objectId, elementIdxInfo.IndexingExpression, elementIdxInfo.ElementIdxStr) : - await WriteJObjectAsIndex(objectId, indexObject, elementIdxInfo.ElementIdxStr, paramInfo[0].TypeCode); - JObject getItemRetObj = await context.SdbAgent.InvokeMethod(buffer, methodIds[i], token); - return (JObject)getItemRetObj["value"]; - } - catch (Exception ex) - { - logger.LogDebug($"Attempt number {i + 1} out of {methodIds.Length} of invoking method {methodInfo.Name} with parameter named {paramInfo[0].Name} on type {type} failed. Method Id = {methodIds[i]}.\nInner exception: {ex}."); - continue; - } - } - } - throw new InvalidOperationException($"Cannot apply indexing with [] to an object of type '{rootObject?["className"]?.Value()}'"); + List typeIds = await context.SdbAgent.GetTypeIdsForObject(objectId.Value, true, token); + JObject objResult = await InvokeGetItemOnJObject(rootObject, typeIds[0], objectId, indexObject, elementIdxInfo, token); + if (objResult == null) + throw new InvalidOperationException($"Cannot apply indexing with [] to an object of type '{rootObject?["className"]?.Value()}'"); + return objResult; + default: throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of scheme '{objectId.Scheme}'"); } @@ -526,8 +505,48 @@ async Task GetElementIndexInfo() IsMultidimensional: multiDimensionalArray, IndexingExpression: indexingExpression); } + } + + private async Task InvokeGetItemOnJObject( + JObject rootObject, + int typeId, + DotnetObjectId objectId, + JObject indexObject, + ElementIndexInfo elementIdxInfo, + CancellationToken token) + { + int[] methodIds = await context.SdbAgent.GetMethodIdsByName(typeId, "get_Item", BindingFlags.Default, token); + if (methodIds == null || methodIds.Length == 0) + throw new InvalidOperationException($"Type '{rootObject?["className"]?.Value()}' cannot be indexed."); + var type = rootObject?["type"]?.Value(); + + // ToDo: optimize the loop by choosing the right method at once without trying out them all + for (int i = 0; i < methodIds.Length; i++) + { + MethodInfoWithDebugInformation methodInfo = await context.SdbAgent.GetMethodInfo(methodIds[i], token); + ParameterInfo[] paramInfo = methodInfo.GetParametersInfo(); + if (paramInfo.Length == 1) + { + try + { + if (indexObject != null && !CheckParametersCompatibility(paramInfo[0].TypeCode, indexObject)) + continue; + ArraySegment buffer = indexObject is null ? + await WriteLiteralExpressionAsIndex(objectId, elementIdxInfo.IndexingExpression) : + await WriteJObjectAsIndex(objectId, indexObject, paramInfo[0].TypeCode); + JObject getItemRetObj = await context.SdbAgent.InvokeMethod(buffer, methodIds[i], token); + return (JObject)getItemRetObj["value"]; + } + catch (Exception ex) + { + logger.LogDebug($"Attempt number {i + 1} out of {methodIds.Length} of invoking method {methodInfo.Name} with parameter named {paramInfo[0].Name} on type {type} failed. Method Id = {methodIds[i]}.\nInner exception: {ex}."); + continue; + } + } + } + return null; - async Task> WriteJObjectAsIndex(DotnetObjectId rootObjId, JObject indexObject, string elementIdxStr, ElementType? expectedType) + async Task> WriteJObjectAsIndex(DotnetObjectId rootObjId, JObject indexObject, ElementType? expectedType) { using var writer = new MonoBinaryWriter(); writer.WriteObj(rootObjId, context.SdbAgent); @@ -537,7 +556,7 @@ async Task> WriteJObjectAsIndex(DotnetObjectId rootObjId, JOb return writer.GetParameterBuffer(); } - async Task> WriteLiteralExpressionAsIndex(DotnetObjectId rootObjId, LiteralExpressionSyntax indexingExpression, string elementIdxStr) + async Task> WriteLiteralExpressionAsIndex(DotnetObjectId rootObjId, LiteralExpressionSyntax indexingExpression) { using var writer = new MonoBinaryWriter(); writer.WriteObj(rootObjId, context.SdbAgent); diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index f7e66cd5966fb2..682033a001d352 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -629,18 +629,16 @@ public async Task EvaluateObjectIndexingByNonIntConst() => await CheckInspectLoc { var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, - ("c[\"longstring\"]", TBool(true)), + ("c[\"longstring\"]", TBool(true)), // class ("c[\"-\"]", TBool(false)), ("c[\'-\']", TString("res_-")), ("c[true]", TString("True")), ("c[1.23]", TNumber(1)), - - // ("s[\"longstring\"]", TBool(true)), - // ("s[\"-\"]", TBool(false)), - // ("s[\'-\']", TString("res_-")), - // ("s[true]", TString("True")), - // ("s[1.23]", TNumber(1)), - + ("s[\"longstring\"]", TBool(true)), // struct + ("s[\"-\"]", TBool(false)), + ("s[\'-\']", TString("res_-")), + ("s[true]", TString("True")), + ("s[1.23]", TNumber(1)), ("cc.indexedByStr[\"1\"]", TBool(true)), ("cc.indexedByStr[\"111\"]", TBool(false)), ("cc.indexedByStr[\"true\"]", TBool(true)), From 116200be23ad3fbf61e1afad84e91baeac95dfbf Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:48:27 +0000 Subject: [PATCH 03/13] More tests + fix. --- .../MemberReferenceResolver.cs | 3 +- .../EvaluateOnCallFrameTests.cs | 31 +++++++++---------- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 605405c44f3231..99168d5cb7c337 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -401,7 +401,7 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, if (!context.SdbAgent.ValueCreator.TryGetValueTypeById(objectId.Value, out ValueTypeClass valueType)) throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of scheme '{objectId.Scheme}'"); var typeInfo = await context.SdbAgent.GetTypeInfo(valueType.TypeId, token); - if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray.Count) + if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray?.Count) return (JObject)valueType.InlineArray[elementIdx]["value"]; JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, indexObject, elementIdxInfo, token); if (vtResult == null) // ToDo: choose a logical order of operations for inline array, this is messy @@ -439,7 +439,6 @@ public async Task Resolve(ElementAccessExpressionSyntax elementAccess, if (objResult == null) throw new InvalidOperationException($"Cannot apply indexing with [] to an object of type '{rootObject?["className"]?.Value()}'"); return objResult; - default: throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of scheme '{objectId.Scheme}'"); } diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 682033a001d352..8e038fa3dad2ad 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -655,7 +655,7 @@ await EvaluateOnCallFrameAndCheck(id, [Fact] public async Task EvaluateObjectByNonIntLocals() => await CheckInspectLocalsAtBreakpointSite( - "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 14, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 15, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", wait_for_event_fn: async (pause_location) => { @@ -668,18 +668,17 @@ await EvaluateOnCallFrameAndCheck(id, ("c[aFloat]", TNumber(1)), ("c[aDouble]", TNumber(2)), ("c[aDecimal]", TNumber(3)), - ("c[arr]", TChar('t')), - ("c[objIdx]", TNumber(123)) - - // ("s[longString]", TBool(true)), - // ("s[aBool]", TString("True")), - // ("s[aChar]", TString("res_9")), - // ("s[shortString]", TBool(false)), - // ("s[aFloat]", TNumber(1)), - // ("s[aDouble]", TNumber(2)), - // ("s[aDecimal]", TNumber(3)), - // ("s[arr]", TChar('t')), - // ("s[objIdx]", TNumber(123)) + // ("c[arr]", TChar('t')), // ToFix + ("c[objIdx]", TNumber(123)), + ("s[longString]", TBool(true)), + ("s[aBool]", TString("True")), + ("s[aChar]", TString("res_9")), + ("s[shortString]", TBool(false)), + ("s[aFloat]", TNumber(1)), + ("s[aDouble]", TNumber(2)), + ("s[aDecimal]", TNumber(3)), + // ("s[arr]", TChar('t')), // ToFix + ("s[objIdx]", TNumber(123)) ); }); @@ -692,9 +691,9 @@ public async Task EvaluateNestedObjectIndexingByNonIntLocals() => await CheckIns var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, ("c[cc.textArray[0]]", TBool(false)), // c["1"] - ("c[cc.textArray[j]]", TBool(false)) // c["2"] - // ("s[cc.textArray[0]]", TBool(false)), // s["1"] - // ("s[cc.textArray[j]]", TBool(false)) // s["2"] + ("c[cc.textArray[j]]", TBool(false)), // c["2"] + ("s[cc.textArray[0]]", TBool(false)), // s["1"] + ("s[cc.textArray[j]]", TBool(false)) // s["2"] ); }); From ec15434eca6c53639f6a1b82430601a7a96e5eaf Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 26 Sep 2023 11:52:51 +0000 Subject: [PATCH 04/13] Unblock, working after rebuild. --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 8e038fa3dad2ad..07ba179c52d0f5 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -668,7 +668,7 @@ await EvaluateOnCallFrameAndCheck(id, ("c[aFloat]", TNumber(1)), ("c[aDouble]", TNumber(2)), ("c[aDecimal]", TNumber(3)), - // ("c[arr]", TChar('t')), // ToFix + ("c[arr]", TChar('t')), ("c[objIdx]", TNumber(123)), ("s[longString]", TBool(true)), ("s[aBool]", TString("True")), @@ -677,7 +677,7 @@ await EvaluateOnCallFrameAndCheck(id, ("s[aFloat]", TNumber(1)), ("s[aDouble]", TNumber(2)), ("s[aDecimal]", TNumber(3)), - // ("s[arr]", TChar('t')), // ToFix + ("s[arr]", TChar('t')), ("s[objIdx]", TNumber(123)) ); }); From 4b3e6c1c0fc29202700997d0f587914579c120d3 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 27 Sep 2023 08:48:04 +0000 Subject: [PATCH 05/13] Initial inlined arrays cleanup. --- .../MemberReferenceResolver.cs | 60 +++++++++++++++---- .../debugger-test/debugger-array-test.cs | 4 +- .../debugger-test/debugger-evaluate-test.cs | 26 ++++---- 3 files changed, 66 insertions(+), 24 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 130a911755a1e9..39d10eee85575b 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -408,12 +408,22 @@ public async Task Resolve( if (!context.SdbAgent.ValueCreator.TryGetValueTypeById(objectId.Value, out ValueTypeClass valueType)) throw new InvalidOperationException($"Cannot apply indexing with [] to an expression of scheme '{objectId.Scheme}'"); var typeInfo = await context.SdbAgent.GetTypeInfo(valueType.TypeId, token); - if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray?.Count) + if (valueType.InlineArray == null) + { + try + { + JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, elementIdxInfo, token); + if (vtResult != null) + return vtResult; + } + catch (Exception) + { + logger.LogDebug($"Failed indexing '{objectId.Value}' with an indexer."); + } + } + if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray.Count) return (JObject)valueType.InlineArray[elementIdx]["value"]; - JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, elementIdxInfo, token); - if (vtResult == null) // ToDo: choose a logical order of operations for inline array, this is messy - throw new InvalidOperationException($"Index is outside the bounds of the inline array"); - return vtResult; + throw new InvalidOperationException($"Index is outside the bounds of the inline array"); } case "array": rootObject["value"] = await context.SdbAgent.GetArrayValues(objectId.Value, token); @@ -595,19 +605,47 @@ private static bool CheckParametersCompatibility(ParameterInfo[] paramInfos, Lis return false; foreach ((ParameterInfo paramInfo, object indexObj) in paramInfos.Zip(indexObjects)) { - // shouldn't we check LiteralExpressionSyntax for compatibility as well? - if (indexObj is JObject indexJObj && !CheckParameterCompatibility(paramInfo.TypeCode, indexJObj)) + string argumentType = "", argumentClassName = ""; + if (indexObj is JObject indexJObj) + { + argumentType = indexJObj["type"]?.Value(); + argumentClassName = indexJObj["className"]?.Value(); + } + else if (indexObj is LiteralExpressionSyntax literal) + { + // any primitive literal is an object + if (paramInfo.TypeCode.Value == ElementType.Object) + continue; + switch (literal.Kind()) + { + case SyntaxKind.NumericLiteralExpression: + argumentType = "number"; + break; + case SyntaxKind.StringLiteralExpression: + argumentType = "string"; + break; + case SyntaxKind.TrueLiteralExpression: + case SyntaxKind.FalseLiteralExpression: + argumentType = "boolean"; + break; + case SyntaxKind.CharacterLiteralExpression: + argumentType = "symbol"; + break; + case SyntaxKind.NullLiteralExpression: + // do not check + continue; + } + } + if (!CheckParameterCompatibility(paramInfo.TypeCode, argumentType, argumentClassName)) return false; } return true; } - private static bool CheckParameterCompatibility(ElementType? paramTypeCode, JObject value) + private static bool CheckParameterCompatibility(ElementType? paramTypeCode, string argumentType, string argumentClassName="") { if (!paramTypeCode.HasValue) return true; - var argumentType = value["type"]?.Value(); - var argumentClassName = value["className"]?.Value(); switch (paramTypeCode.Value) { @@ -641,6 +679,8 @@ private static bool CheckParameterCompatibility(ElementType? paramTypeCode, JObj return false; if (argumentType == "object") return false; + if (argumentType == "string" || argumentType == "symbol") + return false; break; case ElementType.String: if (argumentType != "string") diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs index c05329b0c3f49f..fc9fef4ee8c7c7 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs @@ -362,7 +362,7 @@ class One {} class Two {} class Three {} class Four {} - struct E + public struct E { public int x; public int y; @@ -370,7 +370,7 @@ struct E } [System.Runtime.CompilerServices.InlineArray(Length)] - struct Arr1 + public struct Arr1 { public const int Length = 42; public E e; diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index 3a70aa8882d696..286709ad8636aa 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -536,12 +536,12 @@ public CommonCollections() public class ClassWithIndexers { // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 - public string this[char key] => "res_" + key; - public string this[bool key] => key.ToString(); - public bool this[string key] => key.Length > 3; - public int this[double key] => (int)key; - public int this[float key] => (int)key; - public int this[decimal key] => (int)key; + public string this[char keyChar] => "res_" + keyChar; + public string this[bool keyBool] => keyBool.ToString(); + public bool this[string keyStr] => keyStr.Length > 3; + public int this[double keyDouble] => (int)keyDouble; + public int this[float keyFloat] => (int)keyFloat; + public int this[decimal keyDecimal] => (int)keyDecimal; public int this[Indexer indexer] => indexer.index; public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; @@ -552,14 +552,16 @@ public class ClassWithIndexers public struct StructWithIndexers { // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 - public string this[char key] => "res_" + key; - public string this[bool key] => key.ToString(); - public bool this[string key] => key.Length > 3; - public int this[double key] => (int)key; - public int this[float key] => (int)key; - public int this[decimal key] => (int)key; + public string this[char keyChar] => "res_" + keyChar; + public string this[bool keyBool] => keyBool.ToString(); + public bool this[string keyStr] => keyStr.Length > 3; + public int this[double keyDouble] => (int)keyDouble; + public int this[float keyFloat] => (int)keyFloat; + public int this[decimal keyDecimal] => (int)keyDecimal; public int this[Indexer indexer] => indexer.index; public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; + + // public InlineArray.Arr1 inlineArr; // ToDo: Inline Arrays with Indexers fail on debugger side } public static void EvaluateLocals() From 21841f7546c69e30955d8b3828710231f5843763 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Wed, 27 Sep 2023 11:23:04 +0000 Subject: [PATCH 06/13] Lines are shifted again. --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index e3a0a8620e9e7e..6cf80e6f633ce3 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -585,7 +585,7 @@ public async Task EvaluateIndexingNegative() => await CheckInspectLocalsAtBreakp Assert.Equal("Unable to evaluate element access 'cc.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(571, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(573, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); (_, res) = await EvaluateOnCallFrame(id, "c[1]", expect_ok: false ); Assert.Equal( "Unable to evaluate element access 'c[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.ClassWithIndexers'", res.Error["result"]?["description"]?.Value()); @@ -740,7 +740,7 @@ public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLo Assert.Equal("Unable to evaluate element access 'cc.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(571, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(573, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); }); From a8a2ee44ea196ef2fe5e8c740d43bec47c02d7ab Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 28 Sep 2023 06:34:12 +0000 Subject: [PATCH 07/13] @thaystg's fix for inline arrays --- src/mono/mono/component/debugger-agent.c | 20 +++++++++++++++++-- .../BrowserDebugProxy/MonoSDBHelper.cs | 2 +- .../debugger-test/debugger-evaluate-test.cs | 4 +++- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index e5fd65378515aa..358f4ab258f00d 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5353,6 +5353,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void gpointer iter = NULL; MonoDomain *d; ErrorCode err; + int inlineArray = -1; /* is_enum, ignored */ decode_byte (buf, &buf, limit); @@ -5360,7 +5361,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void decode_byte (buf, &buf, limit); klass = decode_typeid (buf, &buf, limit, &d, &err); if (CHECK_PROTOCOL_VERSION(2, 65)) - decode_int (buf, &buf, limit); //ignore inline array + inlineArray = decode_int (buf, &buf, limit); if (err != ERR_NONE) return err; @@ -5385,6 +5386,12 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void if (err != ERR_NONE) return err; nfields --; + if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArray > 0) + { + int element_size = mono_class_instance_size (mono_class_from_mono_type_internal (f->type)) - MONO_ABI_SIZEOF (MonoObject); + for (int i = 1; i < inlineArray; i++) + decode_value (f->type, domain, ((char*)mono_vtype_get_field_addr (addr, f)) + (i*element_size), buf, &buf, limit, check_field_datatype, extra_space, members_in_extra_space); + } } g_assert (nfields == 0); @@ -5459,6 +5466,7 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g gpointer iter = NULL; MonoDomain *d; ErrorCode err; + int inlineArray = -1; /* is_enum, ignored */ decode_byte (buf, &buf, limit); @@ -5466,7 +5474,7 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g decode_byte (buf, &buf, limit); klass = decode_typeid (buf, &buf, limit, &d, &err); if (CHECK_PROTOCOL_VERSION(2, 65)) - decode_int (buf, &buf, limit); //ignore inline array + inlineArray = decode_int (buf, &buf, limit); if (err != ERR_NONE) goto end; @@ -5489,6 +5497,14 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g if (err != ERR_NONE) return err; nfields --; + if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArray > 0) + { + for (int i = 1; i < inlineArray; i++) { + field_size = decode_value_compute_size (f->type, 0, domain, buf, &buf, limit, members_in_extra_space); + if (members_in_extra_space) + ret += field_size; + } + } } g_assert (nfields == 0); diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs index 844ed5b4d54193..9b83089dfd9e24 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MonoSDBHelper.cs @@ -858,7 +858,7 @@ internal sealed partial class MonoSDBHelper private static int debuggerObjectId; private static int cmdId = 1; //cmdId == 0 is used by events which come from runtime - private const int MINOR_VERSION = 65; + private const int MINOR_VERSION = 66; private const int MAJOR_VERSION = 2; private int VmMinorVersion { get; set; } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index 286709ad8636aa..de7ef89a552a98 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -547,6 +547,8 @@ public class ClassWithIndexers public double this[int key1, double key2] => key1 + key2; public string this[char key1, string key2, string key3] => $"{key1}-{key2}-{key3}"; + + public InlineArray.Arr1 inlineArr; } public struct StructWithIndexers @@ -561,7 +563,7 @@ public struct StructWithIndexers public int this[Indexer indexer] => indexer.index; public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; - // public InlineArray.Arr1 inlineArr; // ToDo: Inline Arrays with Indexers fail on debugger side + public InlineArray.Arr1 inlineArr; } public static void EvaluateLocals() From 52dd1f8cf6510153da55906cd14be6976a142810 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 28 Sep 2023 06:55:12 +0000 Subject: [PATCH 08/13] Added test for method on inline array. --- src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs | 8 +++++--- .../debugger/tests/debugger-test/debugger-array-test.cs | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs index 4f1d99c07ef80d..2c559ef98f195d 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/ArrayTests.cs @@ -684,7 +684,7 @@ public async Task InspectInlineArray(string varName) $"'[debugger-test] DebuggerTests.InlineArray:run'" + "); }, 1);"; - var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, 441, 12, "DebuggerTests.InlineArray.run"); + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, 442, 12, "DebuggerTests.InlineArray.run"); var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, ($"{varName}[0]", TObject("DebuggerTests.InlineArray.E")), @@ -714,6 +714,7 @@ await EvaluateOnCallFrameAndCheck(id, o = TObject("DebuggerTests.InlineArray.Two") }, "s_one_props#1"); } + [ConditionalFact(nameof(RunningOnChrome))] public async Task InspectInlineArray2() { @@ -723,13 +724,14 @@ public async Task InspectInlineArray2() $"'[debugger-test] DebuggerTests.InlineArray:run2'" + "); }, 1);"; - var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, 459, 12, "DebuggerTests.InlineArray.run2"); + var pause_location = await EvaluateAndCheck(eval_expr, debugger_test_loc, 460, 12, "DebuggerTests.InlineArray.run2"); var id = pause_location["callFrames"][0]["callFrameId"].Value(); await EvaluateOnCallFrameAndCheck(id, ($"a2[0]", TNumber(1)), ($"a3[0]", TNumber(2)), ($"a4[0]", TObject("DebuggerTests.InlineArray.E")), - ($"Arr4.myStaticField", TNumber(50)) + ($"Arr4.myStaticField", TNumber(50)), + ($"a2.InlineMethod(1)", TNumber(101)) ); var (_, res) = await EvaluateOnCallFrame(id,$"a3[1]", expect_ok: false); diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs index fc9fef4ee8c7c7..6192c60204da5d 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-array-test.cs @@ -381,6 +381,7 @@ struct Arr2 { public const int Length = 42; public int e; + public int InlineMethod(int n) => n + 100; } [System.Runtime.CompilerServices.InlineArray(1)] From 67814162239b836485b14dc429ed5dab84e9c42b Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 28 Sep 2023 07:13:30 +0000 Subject: [PATCH 09/13] Multi-dim works as well. --- .../EvaluateOnCallFrame2Tests.cs | 19 +++++++++++++++++++ .../debugger-test/debugger-evaluate-test.cs | 5 +++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs index 1504422dbbf4e1..b354b8c6caef1f 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrame2Tests.cs @@ -764,5 +764,24 @@ await EvaluateOnCallFrameAndCheck(id, ("c[cc.numArray[cc.numList[0]], cc.numArray[cc.numArray[i]]]", TNumber("4")) ); }); + + [Fact] + public async Task EvaluateValueTypeIndexingMultidimensional() => await CheckInspectLocalsAtBreakpointSite( + "DebuggerTests.EvaluateLocalsWithIndexingTests", "EvaluateLocals", 12, "DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", + "window.setTimeout(function() { invoke_static_method ('[debugger-test] DebuggerTests.EvaluateLocalsWithIndexingTests:EvaluateLocals'); })", + wait_for_event_fn: async (pause_location) => + { + var id = pause_location["callFrames"][0]["callFrameId"].Value(); + + await EvaluateOnCallFrameAndCheck(id, + ("s[j, aDouble]", TNumber("3.34")), //only IdentifierNameSyntaxes + ("s[1, aDouble]", TNumber("3.34")), //IdentifierNameSyntax with LiteralExpressionSyntax + ("s[aChar, \"&\", longString]", TString("9-&-longString")), + ("s[cc.numArray[j], aDouble]", TNumber("4.34")), //ElementAccessExpressionSyntax + ("s[cc.numArray[j], cc.numArray[0]]", TNumber("3")), //multiple ElementAccessExpressionSyntaxes + ("s[cc.numArray[cc.numList[0]], cc.numArray[i]]", TNumber("3")), + ("s[cc.numArray[cc.numList[0]], cc.numArray[cc.numArray[i]]]", TNumber("4")) + ); + }); } } diff --git a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs index de7ef89a552a98..8e3804889a3c7c 100644 --- a/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs +++ b/src/mono/wasm/debugger/tests/debugger-test/debugger-evaluate-test.cs @@ -535,7 +535,6 @@ public CommonCollections() public class ClassWithIndexers { - // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 public string this[char keyChar] => "res_" + keyChar; public string this[bool keyBool] => keyBool.ToString(); public bool this[string keyStr] => keyStr.Length > 3; @@ -553,7 +552,6 @@ public class ClassWithIndexers public struct StructWithIndexers { - // ToDo: add 2d indexing - https://github.com/dotnet/runtime/issues/76062 public string this[char keyChar] => "res_" + keyChar; public string this[bool keyBool] => keyBool.ToString(); public bool this[string keyStr] => keyStr.Length > 3; @@ -563,6 +561,9 @@ public struct StructWithIndexers public int this[Indexer indexer] => indexer.index; public char this[char[] arr] => arr.Length == 0 ? '0' : arr[0]; + public double this[int key1, double key2] => key1 + key2; + public string this[char key1, string key2, string key3] => $"{key1}-{key2}-{key3}"; + public InlineArray.Arr1 inlineArr; } From c4595c4f6076fe38dd8123f2daa7c3613b37309d Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 28 Sep 2023 08:37:32 +0000 Subject: [PATCH 10/13] fix --- .../debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs index 6cf80e6f633ce3..82ea36992d341b 100644 --- a/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs +++ b/src/mono/wasm/debugger/DebuggerTestSuite/EvaluateOnCallFrameTests.cs @@ -585,7 +585,7 @@ public async Task EvaluateIndexingNegative() => await CheckInspectLocalsAtBreakp Assert.Equal("Unable to evaluate element access 'cc.idx0[2]': Cannot apply indexing with [] to a primitive object of type 'number'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(573, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(576, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); (_, res) = await EvaluateOnCallFrame(id, "c[1]", expect_ok: false ); Assert.Equal( "Unable to evaluate element access 'c[1]': Cannot apply indexing with [] to an object of type 'DebuggerTests.EvaluateLocalsWithIndexingTests.ClassWithIndexers'", res.Error["result"]?["description"]?.Value()); @@ -740,7 +740,7 @@ public async Task EvaluateIndexingByExpressionNegative() => await CheckInspectLo Assert.Equal("Unable to evaluate element access 'cc.numList[\"a\" + 1]': Cannot index with an object of type 'string'", res.Error["result"]?["description"]?.Value()); var exceptionDetailsStack = res.Error["exceptionDetails"]?["stackTrace"]?["callFrames"]?[0]; Assert.Equal("DebuggerTests.EvaluateLocalsWithIndexingTests.EvaluateLocals", exceptionDetailsStack?["functionName"]?.Value()); - Assert.Equal(573, exceptionDetailsStack?["lineNumber"]?.Value()); + Assert.Equal(576, exceptionDetailsStack?["lineNumber"]?.Value()); Assert.Equal(12, exceptionDetailsStack?["columnNumber"]?.Value()); }); From 39ace3a76628c719d8dbd9087bfd91dfc115f629 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Fri, 29 Sep 2023 07:11:51 +0000 Subject: [PATCH 11/13] Tentative fix from feedback. --- src/mono/mono/component/debugger-agent.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index 358f4ab258f00d..c3c0aa332d3c59 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5353,7 +5353,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void gpointer iter = NULL; MonoDomain *d; ErrorCode err; - int inlineArray = -1; + int inlineArraySize = -1; /* is_enum, ignored */ decode_byte (buf, &buf, limit); @@ -5361,7 +5361,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void decode_byte (buf, &buf, limit); klass = decode_typeid (buf, &buf, limit, &d, &err); if (CHECK_PROTOCOL_VERSION(2, 65)) - inlineArray = decode_int (buf, &buf, limit); + inlineArraySize = decode_int (buf, &buf, limit); if (err != ERR_NONE) return err; @@ -5386,10 +5386,10 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void if (err != ERR_NONE) return err; nfields --; - if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArray > 0) + if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArraySize > 0) { int element_size = mono_class_instance_size (mono_class_from_mono_type_internal (f->type)) - MONO_ABI_SIZEOF (MonoObject); - for (int i = 1; i < inlineArray; i++) + for (int i = 0; i < inlineArraySize; i++) decode_value (f->type, domain, ((char*)mono_vtype_get_field_addr (addr, f)) + (i*element_size), buf, &buf, limit, check_field_datatype, extra_space, members_in_extra_space); } } @@ -5466,7 +5466,7 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g gpointer iter = NULL; MonoDomain *d; ErrorCode err; - int inlineArray = -1; + int inlineArraySize = -1; /* is_enum, ignored */ decode_byte (buf, &buf, limit); @@ -5474,7 +5474,7 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g decode_byte (buf, &buf, limit); klass = decode_typeid (buf, &buf, limit, &d, &err); if (CHECK_PROTOCOL_VERSION(2, 65)) - inlineArray = decode_int (buf, &buf, limit); + inlineArraySize = decode_int (buf, &buf, limit); if (err != ERR_NONE) goto end; @@ -5497,9 +5497,9 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g if (err != ERR_NONE) return err; nfields --; - if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArray > 0) + if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArraySize > 0) { - for (int i = 1; i < inlineArray; i++) { + for (int i = 0; i < inlineArraySize; i++) { field_size = decode_value_compute_size (f->type, 0, domain, buf, &buf, limit, members_in_extra_space); if (members_in_extra_space) ret += field_size; From 98c6db3fc1dbe65a2946d460578acb0ab1ee0f0e Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Tue, 3 Oct 2023 06:51:35 +0000 Subject: [PATCH 12/13] 0th element is decoded before the loop. --- src/mono/mono/component/debugger-agent.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/mono/mono/component/debugger-agent.c b/src/mono/mono/component/debugger-agent.c index c3c0aa332d3c59..77208dfc2405e9 100644 --- a/src/mono/mono/component/debugger-agent.c +++ b/src/mono/mono/component/debugger-agent.c @@ -5389,7 +5389,7 @@ decode_vtype (MonoType *t, MonoDomain *domain, gpointer void_addr, gpointer void if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArraySize > 0) { int element_size = mono_class_instance_size (mono_class_from_mono_type_internal (f->type)) - MONO_ABI_SIZEOF (MonoObject); - for (int i = 0; i < inlineArraySize; i++) + for (int i = 1; i < inlineArraySize; i++) decode_value (f->type, domain, ((char*)mono_vtype_get_field_addr (addr, f)) + (i*element_size), buf, &buf, limit, check_field_datatype, extra_space, members_in_extra_space); } } @@ -5499,7 +5499,7 @@ decode_vtype_compute_size (MonoType *t, MonoDomain *domain, gpointer void_buf, g nfields --; if (CHECK_PROTOCOL_VERSION(2, 66) && inlineArraySize > 0) { - for (int i = 0; i < inlineArraySize; i++) { + for (int i = 1; i < inlineArraySize; i++) { field_size = decode_value_compute_size (f->type, 0, domain, buf, &buf, limit, members_in_extra_space); if (members_in_extra_space) ret += field_size; From 5d41e6a22ee479c64b1a803d09b97d31df104cd0 Mon Sep 17 00:00:00 2001 From: Ilona Tomkowicz <32700855+ilonatommy@users.noreply.github.com> Date: Thu, 5 Oct 2023 13:18:04 +0000 Subject: [PATCH 13/13] Feedback part 1. --- .../MemberReferenceResolver.cs | 38 ++++++++----------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs index 39d10eee85575b..df40f5528232f5 100644 --- a/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs +++ b/src/mono/wasm/debugger/BrowserDebugProxy/MemberReferenceResolver.cs @@ -410,16 +410,9 @@ public async Task Resolve( var typeInfo = await context.SdbAgent.GetTypeInfo(valueType.TypeId, token); if (valueType.InlineArray == null) { - try - { - JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, elementIdxInfo, token); - if (vtResult != null) - return vtResult; - } - catch (Exception) - { - logger.LogDebug($"Failed indexing '{objectId.Value}' with an indexer."); - } + JObject vtResult = await InvokeGetItemOnJObject(rootObject, valueType.TypeId, objectId, elementIdxInfo, token); + if (vtResult != null) + return vtResult; } if (int.TryParse(elementIdxInfo.ElementIdxStr, out elementIdx) && elementIdx >= 0 && elementIdx < valueType.InlineArray.Count) return (JObject)valueType.InlineArray[elementIdx]["value"]; @@ -552,21 +545,20 @@ private async Task InvokeGetItemOnJObject( { MethodInfoWithDebugInformation methodInfo = await context.SdbAgent.GetMethodInfo(methodIds[i], token); ParameterInfo[] paramInfo = methodInfo.GetParametersInfo(); - if (paramInfo.Length == elementIdxInfo.DimensionsCount) + if (paramInfo.Length != elementIdxInfo.DimensionsCount) + continue; + try { - try - { - if (!CheckParametersCompatibility(paramInfo, elementIdxInfo.Indexers)) - continue; - ArraySegment buffer = await WriteIndexObjectAsIndices(objectId, elementIdxInfo.Indexers, paramInfo); - JObject getItemRetObj = await context.SdbAgent.InvokeMethod(buffer, methodIds[i], token); - return (JObject)getItemRetObj["value"]; - } - catch (Exception ex) - { - logger.LogDebug($"Attempt number {i + 1} out of {methodIds.Length} of invoking method {methodInfo.Name} with parameter named {paramInfo[0].Name} on type {type} failed. Method Id = {methodIds[i]}.\nInner exception: {ex}."); + if (!CheckParametersCompatibility(paramInfo, elementIdxInfo.Indexers)) continue; - } + ArraySegment buffer = await WriteIndexObjectAsIndices(objectId, elementIdxInfo.Indexers, paramInfo); + JObject getItemRetObj = await context.SdbAgent.InvokeMethod(buffer, methodIds[i], token); + return (JObject)getItemRetObj["value"]; + } + catch (Exception ex) + { + logger.LogDebug($"Attempt number {i + 1} out of {methodIds.Length} of invoking method {methodInfo.Name} with parameter named {paramInfo[0].Name} on type {type} failed. Method Id = {methodIds[i]}.\nInner exception: {ex}."); + continue; } } return null;