Commit 354f4f08 authored by Simon Zünd's avatar Simon Zünd Committed by V8 LUCI CQ

[debug] Refactor 'shadowing' tests for debug-evaluate

We currently use 1 test case per file for tests that check that
debug-evaluate correctly blocks the lookup of stack-allocated
variables.

This CL adapts a similar approach to `debug-scopes.js`, making it
easier to add new test cases in the future.

R=kimanh@chromium.org

Bug: chromium:1363561
Change-Id: I8ff8cfe7d59f0b9808dc02c5579e058f490553eb
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3904544
Commit-Queue: Simon Zünd <szuend@chromium.org>
Reviewed-by: 's avatarKim-Anh Tran <kimanh@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83315}
parent ec4b480e
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test that debug-evaluate correctly collects free outer variables
// and does not get confused by variables in nested scopes.
Debug = debug.Debug
var exception = null;
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
assertThrows(() => exec_state.frame(0).evaluate("x").value());
} catch (e) {
exception = e;
print(e + e.stack);
}
}
Debug.setListener(listener);
(function() {
var x = 1; // context allocate x
(() => x);
(function() {
var x = 2; // stack allocate shadowing x
(function() {
{ // context allocate x in a nested scope
let x = 3;
(() => x);
}
debugger;
})();
})();
})();
Debug.setListener(null);
assertNull(exception);
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test that debug-evaluate properly shadows stack-allocated variables.
Debug = debug.Debug
let exception = null;
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
assertEquals(2, exec_state.frame(0).evaluate("b").value());
assertEquals(3, exec_state.frame(0).evaluate("c").value())
assertThrows(() => exec_state.frame(0).evaluate("a").value());
} catch (e) {
exception = e;
print(e + e.stack);
}
}
Debug.setListener(listener);
(function f() {
let a = 1;
let b = 2;
let c = 3;
() => a + c; // a and c are context-allocated
return function g() {
let a = 2; // a is stack-allocated
return function h() {
b; // b is allocated onto f's context.
debugger;
}
}
})()()();
Debug.setListener(null);
assertNull(exception);
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test that debug-evaluate properly shadows stack-allocated variables.
Debug = debug.Debug
let exception = null;
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
assertThrows(() => exec_state.frame(0).evaluate("a").value());
} catch (e) {
exception = e;
print(e + e.stack);
}
}
Debug.setListener(listener);
(function f() {
let a = 1;
() => a; // a is context-allocated
return function g() {
let a = 2; // a is stack-allocated
{
let b = 3;
return function h() {
debugger;
}
}
}
})()()();
Debug.setListener(null);
assertNull(exception);
......@@ -11,56 +11,86 @@
Debug = debug.Debug
var exception = null;
let test_name;
let listener_delegate;
let listener_called;
let exception;
let begin_test_count = 0;
let end_test_count = 0;
let break_count = 0;
// Debug event listener which delegates.
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
for (var i = 0; i < exec_state.frameCount() - 1; i++) {
var frame = exec_state.frame(i);
var value;
try {
value = frame.evaluate("x").value();
} catch (e) {
value = e.name;
}
print(frame.sourceLineText());
var expected = frame.sourceLineText().match(/\/\/ (.*$)/)[1];
assertEquals(String(expected), String(value));
if (event == Debug.DebugEvent.Break) {
break_count++;
listener_called = true;
listener_delegate(exec_state);
}
assertEquals("[object global]",
String(exec_state.frame(0).evaluate("this").value()));
assertEquals("y", exec_state.frame(0).evaluate("y").value());
assertEquals("a", exec_state.frame(0).evaluate("a").value());
exec_state.frame(0).evaluate("a = 'A'");
assertThrows(() => exec_state.frame(0).evaluate("z"), ReferenceError);
} catch (e) {
exception = e;
print(e + e.stack);
print(e, e.stack);
}
}
Debug.setListener(listener);
function BeginTest(name) {
test_name = name;
listener_called = false;
exception = null;
begin_test_count++;
}
function EndTest() {
assertTrue(listener_called, "listener not called for " + test_name);
assertNull(exception, test_name + " / " + exception);
end_test_count++;
}
BeginTest("Check that 'x' resolves correctly and 'a' is written correctly");
var a = "a";
(function() {
function f1() {
var x = 1; // context allocate x
(() => x);
var y = "y";
var z = "z";
(function() {
(function () {
var x = 2; // stack allocate shadowing x
(function() {
(function () {
y; // access y
debugger; // ReferenceError
})(); // 2
})(); // 1
return y;
})();
}
listener_delegate = function(exec_state) {
for (var i = 0; i < exec_state.frameCount() - 1; i++) {
var frame = exec_state.frame(i);
var value;
try {
value = frame.evaluate("x").value();
} catch (e) {
value = e.name;
}
print(frame.sourceLineText());
var expected = frame.sourceLineText().match(/\/\/ (.*$)/)[1];
assertEquals(String(expected), String(value));
}
assertEquals("[object global]",
String(exec_state.frame(0).evaluate("this").value()));
assertEquals("y", exec_state.frame(0).evaluate("y").value());
assertEquals("a", exec_state.frame(0).evaluate("a").value());
exec_state.frame(0).evaluate("a = 'A'");
assertThrows(() => exec_state.frame(0).evaluate("z"), ReferenceError);
}
f1();
assertEquals("A", a);
a = "a";
EndTest();
(function() {
BeginTest("Check that a context-allocated 'this' works")
function f2() {
var x = 1; // context allocate x
(() => x);
var y = "y";
......@@ -75,9 +105,80 @@ a = "a";
})(); // 2
})(); // 1
return y;
})();
};
// Uses the same listener delgate as for `f1`.
f2();
assertEquals("A", a);
EndTest();
BeginTest("Check that we don't get confused with nested scopes");
function f3() {
var x = 1; // context allocate x
(() => x);
(function() {
var x = 2; // stack allocate shadowing x
(function() {
{ // context allocate x in a nested scope
let x = 3;
(() => x);
}
debugger;
})();
})();
}
listener_delegate = function(exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("x").value());
}
f3();
EndTest();
BeginTest("Check that stack-allocated variable is unavailable");
function f4() {
let a = 1;
let b = 2;
let c = 3;
() => a + c; // a and c are context-allocated
return function g() {
let a = 2; // a is stack-allocated
return function h() {
b; // b is allocated onto f's context.
debugger;
}
}
}
listener_delegate = function(exec_state) {
assertEquals(2, exec_state.frame(0).evaluate("b").value());
assertEquals(3, exec_state.frame(0).evaluate("c").value())
assertThrows(() => exec_state.frame(0).evaluate("a").value());
};
(f4())()();
EndTest();
BeginTest("Check that block lists on the closure boundary work as expected");
function f5() {
let a = 1;
() => a; // a is context-allocated
return function g() {
let a = 2; // a is stack-allocated
{
let b = 3;
return function h() {
debugger;
}
}
}
}
listener_delegate = function(exec_state) {
assertThrows(() => exec_state.frame(0).evaluate("a").value());
};
(f5())()();
EndTest();
Debug.setListener(null);
assertNull(exception);
assertEquals(begin_test_count, break_count,
'one or more tests did not enter the debugger');
assertEquals(begin_test_count, end_test_count,
'one or more tests did not have its result checked');
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment