summaryrefslogtreecommitdiffstats
path: root/js/src/jit-test/tests/debug/Frame-eval-29.js
blob: 73a3e735e0f75cd90d35f58f1d23a920b65344e0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
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");