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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
|
function bytecode(f) {
if (typeof disassemble !== "function")
return "unavailable";
var d = disassemble(f);
return d.slice(d.indexOf("main:"), d.indexOf("\n\n"));
}
function hasGname(f, v, hasIt = true) {
// Do a try-catch that prints the full stack, so we can tell
// _which_ part of this test failed.
try {
var b = bytecode(f);
if (b != "unavailable") {
assertEq(b.includes(`GetGName "${v}"`), hasIt);
assertEq(b.includes(`GetName "${v}"`), !hasIt);
}
} catch (e) {
print(e.stack);
throw e;
}
}
var x = "outer";
var nonLazyGlobal = newGlobal({ disableLazyParsing: true });
nonLazyGlobal.eval(bytecode.toString());
nonLazyGlobal.eval(hasGname.toString());
nonLazyGlobal.x = x;
nonLazyGlobal.evaluate(`
{
let x = "inner";
eval("function g() { assertEq(x, 'inner');} g()");
eval("function g2() { (function nest() { assertEq(x, 'inner'); })(); } g2()");
}
eval(\`
function g3() {
assertEq(x, 'outer');
}
g3();
hasGname(g3, 'x');
\`);
eval(\`
function g4() {
function nest() { assertEq(x, 'outer'); }
nest();
return nest;
}
hasGname(g4(), 'x');
\`);
`);
{
let x = "inner";
eval("function h() { assertEq(x, 'inner');} h()");
eval("function h2() { (function nest() { assertEq(x, 'inner'); })(); } h2()");
}
// GNAME optimizations should work through lazy parsing.
eval(`
function h3() {
assertEq(x, 'outer');
}
h3();
hasGname(h3, 'x', true);
`);
eval(`
function h4() {
function nest() { assertEq(x, 'outer'); }
nest();
return nest;
}
hasGname(h4(), 'x', true);
`);
nonLazyGlobal.evaluate(`
with ({}) {
let x = "inner";
eval("function i() { assertEq(x, 'inner');} i()");
eval("function i2() { (function nest() { assertEq(x, 'inner'); })(); } i2()");
}
`);
with ({}) {
let x = "inner";
eval("function j() { assertEq(x, 'inner');} j()");
eval("function j2() { (function nest() { assertEq(x, 'inner'); })(); } j2()");
}
nonLazyGlobal.evaluate(`
(function () {
var x = "inner";
eval("function k() { assertEq(x, 'inner');} k()");
eval("function k2() { (function nest() { assertEq(x, 'inner'); })(); } k2()");
})();
`);
(function () {
let x = "inner";
eval("function l() { assertEq(x, 'inner');} l()");
eval("function l2() { (function nest() { assertEq(x, 'inner'); })(); } l2()");
})();
var y1 = 5;
eval(`
'use strict';
var y1 = 6;
assertEq(y1, 6);
(function() { assertEq(y1, 6); })()
`);
assertEq(y1, 5);
eval(`
'use strict';
var y2 = 6;
assertEq(y2, 6);
(function() { assertEq(y2, 6); })()
`);
nonLazyGlobal.evaluate(`
var y3 = 5;
eval(\`
'use strict';
var y3 = 6;
assertEq(y3, 6);
(function() { assertEq(y3, 6); })()
\`);
assertEq(y3, 5);
eval(\`
'use strict';
var y4 = 6;
assertEq(y4, 6);
(function() { assertEq(y4, 6); })()
\`);
`);
|