summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/debug/Frame-eval-29.js
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/jit-test/tests/debug/Frame-eval-29.js')
-rw-r--r--js/src/jit-test/tests/debug/Frame-eval-29.js59
1 files changed, 59 insertions, 0 deletions
diff --git a/js/src/jit-test/tests/debug/Frame-eval-29.js b/js/src/jit-test/tests/debug/Frame-eval-29.js
new file mode 100644
index 000000000..73a3e735e
--- /dev/null
+++ b/js/src/jit-test/tests/debug/Frame-eval-29.js
@@ -0,0 +1,59 @@
+// Test reading and setting values on "hollow" debug scopes. In testGet and
+// testSet below, f and g *must* be called from a non-heavyweight lambda to
+// trigger the creation of the "hollow" debug scopes for the missing scopes.
+//
+// The reason is that a direct call to f or g that accesses a in testGet or
+// testSet's frame is actually recoverable. The Debugger can synthesize a scope
+// based on the frame. By contorting through a lambda, it becomes unsound to
+// synthesize a scope based on the lambda function's frame. Since f and g are
+// accessing a, which is itself free inside the lambda, the Debugger has no way
+// to tell if the on-stack testGet or testSet frame is the frame that *would
+// have* allocated a scope for the lambda, *had the lambda been heavyweight*.
+//
+// More concretely, if the inner lambda were returned from testGet and testSet,
+// then called from a different invocation of testGet or testSet, it becomes
+// obvious that it is incorrect to synthesize a scope based on the frame of
+// that different invocation.
+
+load(libdir + "evalInFrame.js");
+
+function f() {
+ // Eval one frame up. Nothing aliases a.
+ evalInFrame(1, "print(a)");
+}
+
+function g() {
+ evalInFrame(1, "a = 43");
+}
+
+function testGet() {
+ {
+ let a = 42;
+ (function () { f(); })();
+ }
+}
+
+function testSet() {
+ {
+ let a = 42;
+ (function () { g(); })();
+ }
+}
+
+var log = "";
+
+try {
+ testGet();
+} catch (e) {
+ // Throws due to a having been optimized out.
+ log += "g";
+}
+
+try {
+ testSet();
+} catch (e) {
+ // Throws due to a having been optimized out.
+ log += "s";
+}
+
+assertEq(log, "gs");