blob: faf9404f07542b014db5a289517c70c0210ae800 [file] [log] [blame]
// 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]);
})();