"use strict"; 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 below =========== const NUM_LOOPS = 1000; ;(function() { function foo() { const x = 40; const {y} = {y: 50}, [z] = [60]; assert(x === 40); assert(y === 50); assert(z === 60); } function bar() { const x = 40; const {y} = {y: 50}, [z] = [60]; function capture() { return x + y + z; } assert(x === 40); assert(y === 50); assert(z === 60); assert(capture() === 150); if (truth()) { const x = "x"; assert(x === "x"); if (truth()) { let x = 100; const y = 200; assert(x === 100); assert(y === 200); x = 10; assert(x === 10); } assert(x === "x"); } assert(x === 40); } function baz() { let y = 10; function sideEffects() { y = 20; } const x = 10; try { x = sideEffects(); } catch(e) {} assert(y === 20); assert(x === 10); try { x = y = 30; } catch(e) {} assert(y === 30); assert(x === 10); } function taz() { let y = 10; let z; function sideEffects() { y = 20; return ["hello", "world"]; } const x = 10; try { [z, x] = sideEffects(); } catch(e) {} assert(y === 20); assert(x === 10); assert(z === "hello"); } function jaz() { const x = "x"; function capX() { return x; } assert(x === "x"); assert(capX() === "x"); if (truth()) { let y = 40; let capY = function() { return y; } assert(x === "x"); assert(capX() === "x"); } assert(x === "x"); assert(capX() === "x"); } for (var i = 0; i < NUM_LOOPS; i++) { foo(); bar(); baz(); jaz(); } })(); ;(function() { function foo() { const x = 40; x = 30; } function bar() { const x = 40; function capX() { return x; } x = 30; } function baz() { const x = 40; assert(x === 40); function bad() { x = 10; } bad(); } function jaz() { const x = 40; assert(x === 40); function bad() { eval("x = 10"); } bad(); } function faz() { const x = 40; assert(x === 40); eval("x = 10"); } function raz() { const x = 40; assert(x === 40); ;({x} = {x: 20}); } function taz() { const x = 40; function capX() { return x; } assert(capX() === 40); ;({x} = {x: 20}); } function paz() { const x = 20; const y = x = 20; } for (var i = 0; i < NUM_LOOPS; i++) { shouldThrowInvalidConstAssignment(foo); shouldThrowInvalidConstAssignment(bar); shouldThrowInvalidConstAssignment(baz); shouldThrowInvalidConstAssignment(jaz); shouldThrowInvalidConstAssignment(faz); shouldThrowInvalidConstAssignment(raz); shouldThrowInvalidConstAssignment(taz); shouldThrowInvalidConstAssignment(paz); } })(); ;(function() { function foo() { const x = 40; eval("x = 30;"); } function bar() { const x = 20; x += 20; } function baz() { const x = 20; x -= 20; } function taz() { const x = 20; shouldThrowInvalidConstAssignment(function() { x = 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x += 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x -= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x *= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x /= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x >>= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x <<= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x ^= 20; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x++; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { x--; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { ++x; }); assert(x === 20); shouldThrowInvalidConstAssignment(function() { --x; }); assert(x === 20); } function jaz() { const x = 20; let threw = false; try { x = 20; } catch(e) { threw = true} assert(threw); threw = false; try { x += 20; } catch(e) { threw = true} assert(threw); threw = false; try { x -= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x *= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x /= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x >>= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x <<= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x ^= 20; } catch(e) { threw = true} assert(threw); threw = false; try { x++; } catch(e) { threw = true} assert(threw); threw = false; try { x--; } catch(e) { threw = true} assert(threw); threw = false; try { ++x; } catch(e) { threw = true} assert(threw); threw = false; try { --x; } catch(e) { threw = true}; assert(threw); } for (var i = 0; i < NUM_LOOPS; i++) { shouldThrowInvalidConstAssignment(foo); shouldThrowInvalidConstAssignment(bar); shouldThrowInvalidConstAssignment(baz); taz(); jaz(); } })();