v8/test/inspector/debugger/wasm-evaluate-on-call-frame-expected.txt

138 lines
3.3 KiB
Plaintext
Raw Normal View History

Test wasm debug evaluate
Running test: testInstanceAndModule
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
> instance = Instance
> module = Module
Running test: testGlobals
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> globals = Globals
> typeof globals = "object"
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> Object.keys(globals) = Array(2)
> globals[0] = i32 {0}
> globals[1] = i32 {1}
> globals[2] = i64 {2n}
> globals[3] = i64 {3n}
> globals["$global0"] = i32 {0}
> $global0 = i32 {0}
> globals["$global3"] = i64 {2n}
> $global3 = i64 {2n}
Stepping twice in main.
Debugger paused in main.
> globals[0] = i32 {0}
> globals[1] = i32 {1}
> globals[2] = i64 {2n}
> globals[3] = i64 {42n}
> globals["$global0"] = i32 {0}
> $global0 = i32 {0}
> globals["$global3"] = i64 {2n}
> $global3 = i64 {2n}
Changing global from JavaScript.
> globals[0] = i32 {0}
> globals[1] = i32 {21}
> globals[2] = i64 {2n}
> globals[3] = i64 {42n}
> globals["$global0"] = i32 {0}
> $global0 = i32 {0}
> globals["$global3"] = i64 {2n}
> $global3 = i64 {2n}
Running test: testFunctions
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> functions = Functions
> typeof functions = "object"
> Object.keys(functions) = Array(4)
> functions[0] = function 0() { [native code] }
> functions[1] = function 1() { [native code] }
> functions[2] = function 2() { [native code] }
> functions[3] = function 3() { [native code] }
> functions[4] = function 4() { [native code] }
> functions["$foo.bar"] = function 0() { [native code] }
> functions["$main"] = function 1() { [native code] }
> $main = function 1() { [native code] }
> functions["$func2"] = function 2() { [native code] }
> $func2 = function 2() { [native code] }
> functions["$func4"] = function 4() { [native code] }
> $func4 = function 4() { [native code] }
Running test: testLocals
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> locals = Locals
> typeof locals = "object"
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> Object.keys(locals) = Array(2)
> locals[0] = i32 {3}
> locals[1] = i32 {6}
> locals[2] = i32 {0}
> locals["$x"] = i32 {3}
> $x = i32 {3}
> locals["$var2"] = i32 {0}
> $var2 = i32 {0}
Stepping twice in main.
Debugger paused in main.
> locals[0] = i32 {3}
> locals[1] = i32 {6}
> locals[2] = i32 {42}
> locals["$x"] = i32 {3}
> $x = i32 {3}
> locals["$var2"] = i32 {42}
> $var2 = i32 {42}
Running test: testMemories
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> memories = Memories
> typeof memories = "object"
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> Object.keys(memories) = Array(1)
> memories[0] = Memory(1)
> memories["$foo"] = Memory(1)
> $foo = Memory(1)
Running test: testTables
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> tables = Tables
> typeof tables = "object"
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
> Object.keys(tables) = Array(1)
> tables[0] = Table
> tables["$bar"] = Table
> $bar = Table
[inspector] Implement Debug Proxy API via Interceptors. Previously the Debug Proxy API that's exposed on Wasm frames by Runtime.evaluateOnCallFrame() was implemented via actual JSProxy instances. That means that all entities such as "memories", "tables", "stack", "globals", etc. were JSProxy instances with "get" and "has" traps. But that has a couple of down-sides: 1. In DevTools front-end, the proxies are shown as JSProxy, which is not very useful to developers, since they cannot interact with them nor can they inspect their contents. And the object preview also only shows "Proxy {}" for them. 2. The performance doesn't scale well, which becomes a painful bottleneck with larger Wasm modules that contain hundreds of thousands of functions or globals. 3. We cannot use the JSProxy instances in the Scope view (for the reasons outlined in 1.) and hence we have different logic to provide Scope values than values in the rest of DevTools, which led to subtle but annoying bugs and inconsistencies. This also changes the "locals" implementation by querying the values ahead of time, similar to the object exposed to the Scope view, instead of on-demand, since the "locals" object might survive the current debugger pause and peeking into the stack afterwards would read invalid memory (and might even be a security issue). For being able to change locals we need to look into a similar solution as what we have for JavaScript locals already. The expression stack already works this way. For performance reasons (especially scaling to huge, realistic Wasm modules), we cache the per-instance proxies ("functions", "memories", "tables" and "globals") on the WasmInstanceObject and reuse them (which is safe since they have a `null` prototype and are non-extensible), and we also cache the proxy maps (with the interceptors) on the JSGlobalObject per native context. Doc: http://bit.ly/devtools-wasm-entities Bug: chromium:1127914, chromium:1159402, chromium:1071432, chromium:1164241 Change-Id: I6191035fdfd887835ae533fcdaabb5bbc8e661ae Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2606058 Commit-Queue: Benedikt Meurer <bmeurer@chromium.org> Auto-Submit: Benedikt Meurer <bmeurer@chromium.org> Reviewed-by: Yang Guo <yangguo@chromium.org> Cr-Commit-Position: refs/heads/master@{#71981}
2021-01-08 14:35:58 +00:00
Running test: testStack
Compile module.
Set breakpoint in main.
Instantiate module.
Call main.
Debugger paused in main.
> stack = Stack
> typeof stack = "object"
> Object.keys(stack) = Array(0)
Stepping twice in main.
Debugger paused in main.
> stack = Stack
> Object.keys(stack) = Array(2)
> stack[0] = i32 {5}
> stack[1] = i32 {42}