blob: 79cdaefbcee5185533ab8747e2b218aaa462ab80 [file] [log] [blame]
function truth() {
return true;
}
noInline(truth);
function assert(cond) {
if (!cond)
throw new Error("broke assertion");
}
noInline(assert);
function shouldThrowTDZ(func) {
var hasThrown = false;
try {
func();
} catch(e) {
if (e.name.indexOf("ReferenceError") !== -1)
hasThrown = true;
}
assert(hasThrown);
}
noInline(shouldThrowTDZ);
// Tests
const NUM_LOOPS = 1000;
;(function() {
function foo() {
delete x;
const x = 20;
}
function bar() {
delete x;
const x = 20;
function capX() { return x; }
}
for (var i = 0; i < NUM_LOOPS; i++) {
shouldThrowTDZ(foo);
shouldThrowTDZ(bar);
}
})();
;(function() {
function foo() {
var hadError = false;
try {
x;
} catch(e) {
hadError = true;
}
assert(hadError);
if (truth()) {
// This eval is enterpreted as follows:
// eval("var x; x = 20");
// We first assign undefined to the "var x".
// Then, we interperet an assignment expression
// into the resolved variable x. x resolves to the lexical "const x;"
// Look at ECMA section 13.3.2.4 of the ES6 spec:
// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-variable-statement-runtime-semantics-evaluation
// And also look at section 8.3.1 ResolveBinding:
// http://www.ecma-international.org/ecma-262/6.0/index.html#sec-resolvebinding
const x = 40;
let threw = false;
try {
eval("var x = 20;");
} catch(e) {
if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1)
threw = true;
}
assert(threw);
assert(x === 40);
}
assert(x === undefined);
}
function bar() {
var hadError = false;
try {
x;
} catch(e) {
hadError = true;
}
assert(hadError);
if (truth()) {
const x = 40;
function capX() { return x; }
let threw = false;
try {
eval("var x = 20;");
} catch(e) {
if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1)
threw = true;
}
assert(threw);
assert(x === 40);
}
assert(x === undefined);
}
function baz() {
if (truth()) {
const x = 40;
eval("const x = 20; assert(x === 20);");
assert(x === 40);
}
if (truth()) {
const x = 40;
function capX() { return x; }
eval("const x = 20; assert(x === 20);");
assert(x === 40);
}
}
function baz() {
// Test eval() caching.
const x = 20;
const evalString = "x;";
assert(eval(evalString) === 20);
if (truth()) {
const y = 60;
assert(eval(evalString) === 20);
assert(y === 60);
if (truth()) {
const y = 50, z = 70, x = 40;
assert(eval(evalString) === 40);
assert(y === 50 && z === 70);
}
}
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
bar();
baz();
}
})();