369 lines
10 KiB
JavaScript
369 lines
10 KiB
JavaScript
|
// Copyright 2015 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: --strong-mode --harmony-arrow-functions --harmony-reflect
|
||
|
// Flags: --harmony-spreadcalls --allow-natives-syntax
|
||
|
|
||
|
'use strict';
|
||
|
|
||
|
|
||
|
function generateArguments(n, prefix) {
|
||
|
let a = [];
|
||
|
if (prefix) {
|
||
|
a.push(prefix);
|
||
|
}
|
||
|
for (let i = 0; i < n; i++) {
|
||
|
a.push(String(i));
|
||
|
}
|
||
|
|
||
|
return a.join(', ');
|
||
|
}
|
||
|
|
||
|
|
||
|
function generateParams(n) {
|
||
|
let a = [];
|
||
|
for (let i = 0; i < n; i++) {
|
||
|
a[i] = `p${i}`;
|
||
|
}
|
||
|
return a.join(', ');
|
||
|
}
|
||
|
|
||
|
|
||
|
function generateSpread(n) {
|
||
|
return `...[${generateArguments(n)}]`;
|
||
|
}
|
||
|
|
||
|
|
||
|
(function FunctionCall() {
|
||
|
for (let parameter_count = 0; parameter_count < 3; parameter_count++) {
|
||
|
let defs = [
|
||
|
`'use strong'; function f(${generateParams(parameter_count)}) {}`,
|
||
|
`'use strong'; function* f(${generateParams(parameter_count)}) {}`,
|
||
|
`'use strong'; let f = (${generateParams(parameter_count)}) => {}`,
|
||
|
`function f(${generateParams(parameter_count)}) { 'use strong'; }`,
|
||
|
`function* f(${generateParams(parameter_count)}) { 'use strong'; }`,
|
||
|
`let f = (${generateParams(parameter_count)}) => { 'use strong'; }`,
|
||
|
];
|
||
|
for (let def of defs) {
|
||
|
for (let argument_count = 0; argument_count < 3; argument_count++) {
|
||
|
let calls = [
|
||
|
`f(${generateArguments(argument_count)})`,
|
||
|
`f(${generateSpread(argument_count)})`,
|
||
|
`f.call(${generateArguments(argument_count, 'undefined')})`,
|
||
|
`f.call(undefined, ${generateSpread(argument_count)})`,
|
||
|
`f.apply(undefined, [${generateArguments(argument_count)}])`,
|
||
|
`f.bind(undefined)(${generateArguments(argument_count)})`,
|
||
|
`%_CallFunction(${generateArguments(argument_count, 'undefined')},
|
||
|
f)`,
|
||
|
`%Call(${generateArguments(argument_count, 'undefined')}, f)`,
|
||
|
`%Apply(f, undefined, [${generateArguments(argument_count)}], 0,
|
||
|
${argument_count})`,
|
||
|
];
|
||
|
|
||
|
for (let call of calls) {
|
||
|
let code = `'use strict'; ${def}; ${call};`;
|
||
|
if (argument_count < parameter_count) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let calls = [
|
||
|
`f.call()`,
|
||
|
`f.apply()`,
|
||
|
`f.apply(undefined)`,
|
||
|
];
|
||
|
for (let call of calls) {
|
||
|
let code = `'use strict'; ${def}; ${call};`;
|
||
|
if (parameter_count > 0) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function MethodCall() {
|
||
|
for (let parameter_count = 0; parameter_count < 3; parameter_count++) {
|
||
|
let defs = [
|
||
|
`let o = new class {
|
||
|
m(${generateParams(parameter_count)}) { 'use strong'; }
|
||
|
}`,
|
||
|
`let o = new class {
|
||
|
*m(${generateParams(parameter_count)}) { 'use strong'; }
|
||
|
}`,
|
||
|
`let o = { m(${generateParams(parameter_count)}) { 'use strong'; } }`,
|
||
|
`let o = { *m(${generateParams(parameter_count)}) { 'use strong'; } }`,
|
||
|
`'use strong';
|
||
|
let o = new class { m(${generateParams(parameter_count)}) {} }`,
|
||
|
`'use strong';
|
||
|
let o = new class { *m(${generateParams(parameter_count)}) {} }`,
|
||
|
`'use strong'; let o = { m(${generateParams(parameter_count)}) {} }`,
|
||
|
`'use strong'; let o = { *m(${generateParams(parameter_count)}) {} }`,
|
||
|
];
|
||
|
for (let def of defs) {
|
||
|
for (let argument_count = 0; argument_count < 3; argument_count++) {
|
||
|
let calls = [
|
||
|
`o.m(${generateArguments(argument_count)})`,
|
||
|
`o.m(${generateSpread(argument_count)})`,
|
||
|
`o.m.call(${generateArguments(argument_count, 'o')})`,
|
||
|
`o.m.call(o, ${generateSpread(argument_count)})`,
|
||
|
`o.m.apply(o, [${generateArguments(argument_count)}])`,
|
||
|
`o.m.bind(o)(${generateArguments(argument_count)})`,
|
||
|
`%_CallFunction(${generateArguments(argument_count, 'o')}, o.m)`,
|
||
|
`%Call(${generateArguments(argument_count, 'o')}, o.m)`,
|
||
|
`%Apply(o.m, o, [${generateArguments(argument_count)}], 0,
|
||
|
${argument_count})`,
|
||
|
];
|
||
|
|
||
|
for (let call of calls) {
|
||
|
let code = `'use strict'; ${def}; ${call};`;
|
||
|
if (argument_count < parameter_count) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
let calls = [
|
||
|
`o.m.call()`,
|
||
|
`o.m.apply()`,
|
||
|
`o.m.apply(o)`,
|
||
|
];
|
||
|
for (let call of calls) {
|
||
|
let code = `'use strict'; ${def}; ${call};`;
|
||
|
if (parameter_count > 0) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function Constructor() {
|
||
|
for (let argument_count = 0; argument_count < 3; argument_count++) {
|
||
|
for (let parameter_count = 0; parameter_count < 3; parameter_count++) {
|
||
|
let defs = [
|
||
|
`'use strong';
|
||
|
class C { constructor(${generateParams(parameter_count)}) {} }`,
|
||
|
`'use strict';
|
||
|
class C {
|
||
|
constructor(${generateParams(parameter_count)}) { 'use strong'; }
|
||
|
}`,
|
||
|
];
|
||
|
for (let def of defs) {
|
||
|
let calls = [
|
||
|
`new C(${generateArguments(argument_count)})`,
|
||
|
`new C(${generateSpread(argument_count)})`,
|
||
|
`Reflect.construct(C, [${generateArguments(argument_count)}])`,
|
||
|
];
|
||
|
for (let call of calls) {
|
||
|
let code = `${def}; ${call};`;
|
||
|
if (argument_count < parameter_count) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function DerivedConstructor() {
|
||
|
for (let genArgs of [generateArguments, generateSpread]) {
|
||
|
for (let argument_count = 0; argument_count < 3; argument_count++) {
|
||
|
for (let parameter_count = 0; parameter_count < 3; parameter_count++) {
|
||
|
let defs = [
|
||
|
`'use strong';
|
||
|
class B {
|
||
|
constructor(${generateParams(parameter_count)}) {}
|
||
|
}
|
||
|
class C extends B {
|
||
|
constructor() {
|
||
|
super(${genArgs(argument_count)});
|
||
|
}
|
||
|
}`,
|
||
|
`'use strict';
|
||
|
class B {
|
||
|
constructor(${generateParams(parameter_count)}) { 'use strong'; }
|
||
|
}
|
||
|
class C extends B {
|
||
|
constructor() {
|
||
|
super(${genArgs(argument_count)});
|
||
|
}
|
||
|
}`,
|
||
|
];
|
||
|
for (let def of defs) {
|
||
|
let code = `${def}; new C();`;
|
||
|
if (argument_count < parameter_count) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function DerivedConstructorDefaultConstructorInDerivedClass() {
|
||
|
for (let genArgs of [generateArguments, generateSpread]) {
|
||
|
for (let argument_count = 0; argument_count < 3; argument_count++) {
|
||
|
for (let parameter_count = 0; parameter_count < 3; parameter_count++) {
|
||
|
let defs = [
|
||
|
`'use strong';
|
||
|
class B {
|
||
|
constructor(${generateParams(parameter_count)}) {}
|
||
|
}
|
||
|
class C extends B {}`,
|
||
|
`'use strict';
|
||
|
class B {
|
||
|
constructor(${generateParams(parameter_count)}) { 'use strong'; }
|
||
|
}
|
||
|
class C extends B {}`,
|
||
|
];
|
||
|
for (let def of defs) {
|
||
|
let code = `${def}; new C(${genArgs(argument_count)})`;
|
||
|
if (argument_count < parameter_count) {
|
||
|
assertThrows(code, TypeError);
|
||
|
} else {
|
||
|
assertDoesNotThrow(code);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function TestOptimized() {
|
||
|
function f(x, y) { 'use strong'; }
|
||
|
|
||
|
assertThrows(f, TypeError);
|
||
|
%OptimizeFunctionOnNextCall(f);
|
||
|
assertThrows(f, TypeError);
|
||
|
|
||
|
function g() {
|
||
|
f(1);
|
||
|
}
|
||
|
assertThrows(g, TypeError);
|
||
|
%OptimizeFunctionOnNextCall(g);
|
||
|
assertThrows(g, TypeError);
|
||
|
|
||
|
f(1, 2);
|
||
|
%OptimizeFunctionOnNextCall(f);
|
||
|
f(1, 2);
|
||
|
})();
|
||
|
|
||
|
|
||
|
(function TestOptimized2() {
|
||
|
'use strong';
|
||
|
function f(x, y) {}
|
||
|
|
||
|
assertThrows(f, TypeError);
|
||
|
%OptimizeFunctionOnNextCall(f);
|
||
|
assertThrows(f, TypeError);
|
||
|
|
||
|
function g() {
|
||
|
f(1);
|
||
|
}
|
||
|
assertThrows(g, TypeError);
|
||
|
%OptimizeFunctionOnNextCall(g);
|
||
|
assertThrows(g, TypeError);
|
||
|
|
||
|
f(1, 2);
|
||
|
%OptimizeFunctionOnNextCall(f);
|
||
|
f(1, 2);
|
||
|
})();
|
||
|
|
||
|
|
||
|
// https://code.google.com/p/v8/issues/detail?id=4077
|
||
|
// (function NoParametersSuper() {
|
||
|
// 'use strong';
|
||
|
//
|
||
|
// class B {
|
||
|
// m() {}
|
||
|
// }
|
||
|
// class D extends B {
|
||
|
// m0() { super.m(); }
|
||
|
// m1() { super.m(1); }
|
||
|
// s0() { super.m(); }
|
||
|
// s1() { super.m(1); }
|
||
|
// }
|
||
|
//
|
||
|
// new D().m0();
|
||
|
// new D().m1();
|
||
|
//
|
||
|
// new D().s0();
|
||
|
// new D().s1();
|
||
|
// })();
|
||
|
|
||
|
|
||
|
// https://code.google.com/p/v8/issues/detail?id=4077
|
||
|
// (function OneParamentSuper() {
|
||
|
// 'use strong';
|
||
|
//
|
||
|
// class B {
|
||
|
// m(x) {}
|
||
|
// }
|
||
|
// class D extends B {
|
||
|
// m0() { super.m(); }
|
||
|
// m1() { super.m(1); }
|
||
|
// m2() { super.m(1, 2); }
|
||
|
// s0() { super.m(...[]); }
|
||
|
// s1() { super.m(...[1]); }
|
||
|
// s2() { super.m(...[1, 2]); }
|
||
|
// }
|
||
|
//
|
||
|
// assertThrows(function() { new D().m0(); }, TypeError);
|
||
|
// new D().m1();
|
||
|
// new D().m2();
|
||
|
//
|
||
|
// assertThrows(function() { new D().s0(); }, TypeError);
|
||
|
// new D().s1();
|
||
|
// new D().s2();
|
||
|
// })();
|
||
|
|
||
|
|
||
|
// https://code.google.com/p/v8/issues/detail?id=4077
|
||
|
// (function TwoParametersSuper() {
|
||
|
// 'use strong';
|
||
|
//
|
||
|
// class B {
|
||
|
// m(x, y) {}
|
||
|
// }
|
||
|
// class D extends B {
|
||
|
// m0() { super.m(); }
|
||
|
// m1() { super.m(1); }
|
||
|
// m2() { super.m(1, 2); }
|
||
|
// m3() { super.m(1, 2, 3); }
|
||
|
// s0() { super.m(...[]); }
|
||
|
// s1() { super.m(...[1]); }
|
||
|
// s2() { super.m(...[1, 2]); }
|
||
|
// s3() { super.m(...[1, 2, 3]); }
|
||
|
// }
|
||
|
//
|
||
|
// assertThrows(function() { new D().m0(); }, TypeError);
|
||
|
// assertThrows(function() { new D().m1(); }, TypeError);
|
||
|
// new D().m2();
|
||
|
// new D().m3();
|
||
|
//
|
||
|
// assertThrows(function() { new D().s0(); }, TypeError);
|
||
|
// assertThrows(function() { new D().s1(); }, TypeError);
|
||
|
// new D().s2();
|
||
|
// new D().s3();
|
||
|
// })();
|