| 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); |