function truth() { | |
return true; | |
} | |
noInline(truth); | |
function assert(cond) { | |
if (!cond) | |
throw new Error("broke assertion"); | |
} | |
noInline(assert); | |
function shouldThrowInvalidConstAssignment(f) { | |
var threw = false; | |
try { | |
f(); | |
} catch(e) { | |
if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1) | |
threw = true; | |
} | |
assert(threw); | |
} | |
noInline(shouldThrowInvalidConstAssignment); | |
// Tests | |
const NUM_LOOPS = 100; | |
;(function() { | |
function foo() { | |
const x = 40; | |
with ({x : 100}) { | |
assert(x === 100); | |
} | |
with ({y : 100}) { | |
assert(x === 40); | |
} | |
} | |
noInline(foo); | |
function bar() { | |
const x = 40; | |
function capX() { return x; } | |
with ({x : 100}) { | |
if (truth()) { | |
const x = 50; | |
const capX = function() { return x; } | |
assert(x === 50); | |
assert(capX() === x); | |
} | |
assert(x === 100); | |
assert(capX() === 40); | |
} | |
with ({y : 100}) { | |
if (truth()) { | |
const x = 50; | |
const capX = function() { return x; } | |
assert(x === 50); | |
assert(capX() === x); | |
} | |
assert(x === 40); | |
assert(capX() === 40); | |
} | |
} | |
noInline(bar); | |
function baz() { | |
const x = 40; | |
function capX() { return x; } | |
with ({x : 100}) { | |
if (truth()) { | |
const x = 50; | |
assert(x === 50); | |
} | |
assert(x === 100); | |
assert(capX() === 40); | |
} | |
with ({y : 100}) { | |
if (truth()) { | |
const x = 50; | |
assert(x === 50); | |
} | |
assert(x === 40); | |
assert(capX() === 40); | |
} | |
} | |
noInline(baz); | |
for (let i = 0; i < NUM_LOOPS; i++) { | |
foo(); | |
bar(); | |
baz(); | |
} | |
})(); | |
;(function() { | |
function foo() { | |
const x = 40; | |
with ({x : 100}) { | |
assert(x === 100); | |
x = 20; | |
assert(x === 20); | |
} | |
assert(x === 40); | |
with ({y : 100}) { | |
assert(x === 40); | |
x = 100; | |
} | |
} | |
for (let i = 0; i < NUM_LOOPS; ++i) { | |
shouldThrowInvalidConstAssignment(foo); | |
} | |
})(); |