// 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]); })();