function assert(b, m = "Bad!") { | |
if (!b) { | |
throw new Error(m); | |
} | |
} | |
function test(f, iters = 1000) { | |
for (let i = 0; i < iters; i++) | |
f(); | |
} | |
test(function() { | |
function fooProp() { return 'foo'; } | |
noInline(fooProp); | |
let shouldThrow = false; | |
class A { | |
get foo() { | |
if (shouldThrow) | |
throw new Error; | |
return 20; | |
} | |
get x() { return this._x; } | |
} | |
class B extends A { | |
constructor(x) { | |
super(); | |
this._x = x; | |
} | |
bar() { | |
this._x = super.foo; | |
} | |
baz() { | |
this._x = super[fooProp()]; | |
} | |
} | |
function foo(i) { | |
let b = new B(i); | |
noInline(b.__lookupGetter__('foo')); | |
let threw = false; | |
try { | |
b.bar(); | |
} catch(e) { | |
threw = true; | |
} | |
if (threw) | |
assert(b.x === i); | |
else | |
assert(b.x === 20); | |
} | |
function bar(i) { | |
let b = new B(i); | |
noInline(b.__lookupGetter__('foo')); | |
let threw = false; | |
try { | |
b.baz(); | |
} catch(e) { | |
threw = true; | |
} | |
if (threw) | |
assert(b.x === i); | |
else | |
assert(b.x === 20, "b.x " + b.x + " " + i); | |
} | |
noInline(bar); | |
for (let i = 0; i < 10000; i++) { | |
foo(i); | |
bar(i); | |
} | |
shouldThrow = true; | |
foo(23); | |
bar(24); | |
}, 1); | |
test(function() { | |
function fooProp() { return 'foo'; } | |
noInline(fooProp); | |
function func(i) { | |
if (shouldThrow) | |
throw new Error(); | |
return i; | |
} | |
noInline(func); | |
let shouldThrow = false; | |
class A { | |
set foo(x) { | |
this._x = x; | |
} | |
get x() { return this._x; } | |
} | |
class B extends A { | |
constructor(x) { | |
super(); | |
this._x = x; | |
} | |
bar(x) { | |
super.foo = func(x); | |
} | |
baz(x) { | |
super[fooProp()] = func(x); | |
} | |
} | |
function foo(i) { | |
let b = new B(i); | |
noInline(b.__lookupGetter__('foo')); | |
let threw = false; | |
try { | |
b.bar(i + 1); | |
} catch(e) { | |
threw = true; | |
} | |
if (threw) | |
assert(b.x === i); | |
else | |
assert(b.x === i + 1); | |
} | |
function bar(i) { | |
let b = new B(i); | |
noInline(b.__lookupGetter__('foo')); | |
let threw = false; | |
try { | |
b.baz(i + 1); | |
} catch(e) { | |
threw = true; | |
} | |
if (threw) | |
assert(b.x === i); | |
else | |
assert(b.x === i + 1); | |
} | |
noInline(bar); | |
for (let i = 0; i < 10000; i++) { | |
foo(i); | |
bar(i); | |
} | |
shouldThrow = true; | |
foo(23); | |
bar(24); | |
}, 1); |