blob: e5c6d23426fd9d3cd05b837da577bde8f09b6525 [file] [log] [blame]
"use strict";
function truth() {
return true;
}
noInline(truth);
function assert(cond) {
if (!cond)
throw new Error("broke assertion");
}
noInline(assert);
const NUM_LOOPS = 1000;
const SHORT_LOOPS = 100;
function shouldThrowTDZ(func) {
var hasThrown = false;
try {
func();
} catch(e) {
if (e.name.indexOf("ReferenceError") !== -1)
hasThrown = true;
}
assert(hasThrown);
}
noInline(shouldThrowTDZ);
;(function () {
var arr = [];
for (let i = 0; i < 10; i++) {
arr.push(function () { return i; })
}
for (let j = 0; j < arr.length; j++) {
assert(arr[j]() === j);
}
let f = "fff";
let counter = 0;
for (let f of arr) {
assert(f() === counter++);
}
assert(f === "fff");
let numLoops = 0;
for (let f of arr) {
numLoops++;
let f = function () { return "f"; }
assert(f() === "f");
}
assert(numLoops === arr.length);
assert(f === "fff");
})();
;(function() {
function foo() {
var obj = {hello:1, world:2};
obj["bar"] = 3;
let p = 20;
assert(p === 20);
for (let p in obj) {
assert(p === "hello" || p === "world" || p === "bar");
}
assert(p === 20);
}
function bar() {
var obj = {hello:1, world:2};
obj["bar"] = 3;
let props = [];
let p = 20;
for (let p in obj) {
props.push(function foo() { return p; });
let outerP = p;
if (truth()) {
let p = 100;
assert(p === 100);
assert(p !== outerP);
assert(outerP === "hello" || outerP === "world" || outerP === "bar");
}
assert(p === outerP);
}
assert(p === 20);
let seenProps = {};
for (let f of props) {
let p = f();
assert(p === "hello" || p === "world" || p === "bar");
seenProps[p] = true;
}
assert(seenProps["hello"] === true);
assert(seenProps["world"] === true);
assert(seenProps["bar"] === true);
assert(p === 20);
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
bar();
}
})();
;(function() {
function foo() {
let counter = 0;
for (let idx = 0; idx < 20; idx++) {
assert(idx === counter++);
continue;
}
shouldThrowTDZ(function() { return idx; });
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
}
})();
;(function() {
function foo() {
for (let idx = 0; !truth(); idx++) { }
shouldThrowTDZ(function() { return idx; }); // Just plain old reference error here.
}
function bar() {
for (let j = 0; j < 20; j++) {
if (j === 1)
break;
else
continue;
}
shouldThrowTDZ(function() { return j; });
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
bar();
}
})();
;(function() {
function foo() {
var obj = {hello:1, world:2};
let p = 20;
var arr = []
for (let p in obj) {
arr.push(function capP() { return p; });
assert(p === "hello" || p === "world");
}
assert(arr[0]() === "hello" || arr[0]() === "world");
assert(arr[1]() === "hello" || arr[1]() === "world");
assert(arr[1]() !== arr[0]());
assert(p === 20);
}
function bar() {
var obj = {a:1, b:2, c:3, d:4, e:4};
obj["f"] = 5;
let funcs = [];
for (let p in obj) {
funcs.push(function capP() { return p; });
}
let counter = 0;
for (let p in obj) {
assert(funcs[counter]() === p);
counter++;
}
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
bar();
}
})();
;(function() {
function foo() {
let arr = [0, 1, 2, 3, 4, 5];
let funcs = [];
for (let x of arr) {
funcs.push(function() { return x; });
}
for (let i = 0; i < arr.length; ++i) {
assert(funcs[i]() === i);
}
}
for (var i = 0; i < NUM_LOOPS; i++) {
foo();
}
})();
;(function() {
function foo() {
let thing = {};
for (let thing = thing; !thing; ) {}
}
for (var i = 0; i < NUM_LOOPS; i++) {
shouldThrowTDZ(foo);
}
})();
;(function() {
function foo() {
let thing = {};
for (let thing = eval("thing"); !truth(); ) {}
}
for (var i = 0; i < SHORT_LOOPS; i++) {
shouldThrowTDZ(foo);
}
})();
;(function() {
function foo() {
let thing = {};
for (let thing in thing) {}
}
function bar() {
let thing = {hello: "world"}
for (let thing in thing) {}
}
function baz() {
let thing = {};
for (let thing in eval("thing")) {}
}
function bag() {
let thing = {hello: "world"}
for (let thing in eval("thing")) {}
}
for (var i = 0; i < SHORT_LOOPS; i++) {
shouldThrowTDZ(foo);
shouldThrowTDZ(bar);
shouldThrowTDZ(baz);
shouldThrowTDZ(bag);
}
})();
;(function() {
function foo() {
let thing = ["hello"];
for (let thing in thing) {}
}
function bar() {
let thing = [];
for (let thing in thing) {}
}
function baz() {
let thing = {hello: "world"};
for (let thing in thing) {}
}
function bag() {
let empty = {};
for (let thing in empty) {}
return thing;
}
function hat() {
let notEmpty = {foo: "bar"};
for (let thing in notEmpty) {
break;
}
return thing;
}
function cap() {
let notEmpty = {foo: "bar"};
for (let thing in notEmpty) {
continue;
}
return thing;
}
for (var i = 0; i < NUM_LOOPS; i++) {
shouldThrowTDZ(foo);
shouldThrowTDZ(bar);
shouldThrowTDZ(baz);
shouldThrowTDZ(bag);
shouldThrowTDZ(hat);
shouldThrowTDZ(cap);
}
})();
;(function() {
function foo() {
let thing = ["hello"];
for (let thing of thing) {}
}
function bar() {
let thing = [];
for (let thing of thing) {}
}
function baz() {
let thing = ["world"]
for (let thing of thing) {}
}
function bag() {
let empty = [];
for (let thing of empty) {}
return thing;
}
function hat() {
let notEmpty = ["hello", "world"];
for (let thing of notEmpty) {
break;
}
return thing;
}
function tap() {
let notEmpty = [10, 20];
for (let thing of notEmpty) { }
return thing;
}
function cap() {
let notEmpty = [10, 20];
for (let thing of notEmpty) {
continue;
}
return thing;
}
function pap() {
let notEmpty = [10, 20];
for (let thing of notEmpty) {
}
return thing;
}
for (var i = 0; i < SHORT_LOOPS; i++) {
shouldThrowTDZ(foo);
shouldThrowTDZ(bar);
shouldThrowTDZ(baz);
shouldThrowTDZ(bag);
shouldThrowTDZ(hat);
shouldThrowTDZ(tap);
shouldThrowTDZ(cap);
shouldThrowTDZ(pap);
}
})();
;(function() {
function foo() {
let x = 0;
let arr = [];
for (let x of (x=2, obj)) { x; }
}
function bar() {
let x = 0;
let obj = {};
for (let x in (x=2, obj)) { x; }
}
for (var i = 0; i < SHORT_LOOPS; i++) {
shouldThrowTDZ(foo);
shouldThrowTDZ(bar);
}
})();
;(function() {
let factorial = null;
function test() {
for (let factorial = function(x){ return x > 1 ? x * factorial(x - 1) : 1; }; true; ) { return factorial(5); }
}
assert(test() === 120);
})();
;(function() {
function test() {
for (let factorial = function(x){ return x > 1 ? x * factorial(x - 1) : 1; }; true; ) { return factorial(5); }
}
assert(test() === 120);
})();