8db991a042
Each time a constructor is being called without new operator, a TypeError is thrown. The TypeError should be the realm's one according to 10.2.1.5.b. Refs: https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist Refs: https://github.com/tc39/ecma262/pull/2216 Bug: v8:11530 Change-Id: Iff10a78e96fb547fe2062c86b9f93a30d2a8be20 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3056830 Reviewed-by: Marja Hölttä <marja@chromium.org> Commit-Queue: Marja Hölttä <marja@chromium.org> Cr-Commit-Position: refs/heads/master@{#76002}
133 lines
3.7 KiB
JavaScript
133 lines
3.7 KiB
JavaScript
// 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!');
|
|
}
|
|
|
|
// https://tc39.es/ecma262/#sec-ecmascript-function-objects-call-thisargument-argumentslist
|
|
// 10.2.1 [[Call]] throws a TypeError created in callee context with F's
|
|
// associated Realm Record when the called function is a classConstructor
|
|
assertThrows(function() { Realm.eval(realmIndex, "A()") }, otherTypeError);
|
|
assertThrows(function() { instance.constructor() }, otherTypeError);
|
|
assertThrows(function() { A() }, otherTypeError);
|
|
|
|
// 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]);
|
|
})();
|