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); })() \`); `);