| // Copyright 2014 the V8 project authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Flags: --allow-natives-syntax |
| |
| (function TestDefaultConstructorNoCrash() { |
| // Regression test for https://code.google.com/p/v8/issues/detail?id=3661 |
| class C {} |
| assertThrows(function () {C();}, TypeError); |
| assertThrows(function () {C(1);}, TypeError); |
| assertTrue(new C() instanceof C); |
| assertTrue(new C(1) instanceof C); |
| })(); |
| |
| |
| (function TestConstructorCall(){ |
| var realmIndex = Realm.create(); |
| var otherTypeError = Realm.eval(realmIndex, "TypeError"); |
| var A = Realm.eval(realmIndex, '"use strict"; class A {}; A'); |
| var instance = new A(); |
| var constructor = instance.constructor; |
| var otherTypeError = Realm.eval(realmIndex, 'TypeError'); |
| if (otherTypeError === TypeError) { |
| throw Error('Should not happen!'); |
| } |
| |
| // ES6 9.2.1[[Call]] throws a TypeError in the caller context/Realm when the |
| // called function is a classConstructor |
| assertThrows(function() { Realm.eval(realmIndex, "A()") }, otherTypeError); |
| assertThrows(function() { instance.constructor() }, TypeError); |
| assertThrows(function() { A() }, TypeError); |
| |
| // ES6 9.3.1 call() first activates the callee context before invoking the |
| // method. The TypeError from the constructor is thus thrown in the other |
| // Realm. |
| assertThrows(function() { Realm.eval(realmIndex, "A.call()") }, |
| otherTypeError); |
| assertThrows(function() { constructor.call() }, otherTypeError); |
| assertThrows(function() { A.call() }, otherTypeError); |
| })(); |
| |
| |
| (function TestConstructorCallOptimized() { |
| class A { }; |
| |
| function invoke_constructor() { A() } |
| function call_constructor() { A.call() } |
| function apply_constructor() { A.apply() } |
| %PrepareFunctionForOptimization(invoke_constructor); |
| %PrepareFunctionForOptimization(call_constructor); |
| %PrepareFunctionForOptimization(apply_constructor); |
| |
| for (var i=0; i<3; i++) { |
| assertThrows(invoke_constructor); |
| assertThrows(call_constructor); |
| assertThrows(apply_constructor); |
| } |
| // Make sure we still check for class constructors when calling optimized |
| // code. |
| %OptimizeFunctionOnNextCall(invoke_constructor); |
| assertThrows(invoke_constructor); |
| %OptimizeFunctionOnNextCall(call_constructor); |
| assertThrows(call_constructor); |
| %OptimizeFunctionOnNextCall(apply_constructor); |
| assertThrows(apply_constructor); |
| })(); |
| |
| |
| (function TestDefaultConstructor() { |
| var calls = 0; |
| class Base { |
| constructor() { |
| calls++; |
| } |
| } |
| class Derived extends Base {} |
| var object = new Derived; |
| assertEquals(1, calls); |
| |
| calls = 0; |
| assertThrows(function() { Derived(); }, TypeError); |
| assertEquals(0, calls); |
| })(); |
| |
| |
| (function TestDefaultConstructorArguments() { |
| var args, self; |
| class Base { |
| constructor() { |
| self = this; |
| args = arguments; |
| } |
| } |
| class Derived extends Base {} |
| |
| new Derived; |
| assertEquals(0, args.length); |
| |
| new Derived(0, 1, 2); |
| assertEquals(3, args.length); |
| assertTrue(self instanceof Derived); |
| |
| var arr = new Array(100); |
| var obj = {}; |
| assertThrows(function() {Derived.apply(obj, arr);}, TypeError); |
| })(); |
| |
| |
| (function TestDefaultConstructorArguments2() { |
| var args; |
| class Base { |
| constructor(x, y) { |
| args = arguments; |
| } |
| } |
| class Derived extends Base {} |
| |
| new Derived; |
| assertEquals(0, args.length); |
| |
| new Derived(1); |
| assertEquals(1, args.length); |
| assertEquals(1, args[0]); |
| |
| new Derived(1, 2, 3); |
| assertEquals(3, args.length); |
| assertEquals(1, args[0]); |
| assertEquals(2, args[1]); |
| assertEquals(3, args[2]); |
| })(); |