Chromium Code Reviews| Index: test/mjsunit/strong/function-arity.js |
| diff --git a/test/mjsunit/strong/function-arity.js b/test/mjsunit/strong/function-arity.js |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1a237625da1abc568843423de042e337b714e768 |
| --- /dev/null |
| +++ b/test/mjsunit/strong/function-arity.js |
| @@ -0,0 +1,359 @@ |
| +// 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 --harmony-spreadcalls --allow-natives-syntax |
|
rossberg
2015/05/11 15:39:28
Nit: line length
arv (Not doing code reviews)
2015/05/11 16:54:02
Done.
I fixed this but I guess I undid too much a
|
| + |
| +'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); |
| +})(); |
| + |
| + |
| +(function TestOptimized2() { |
| + 'use strong'; |
| + function f(x, y) {} |
|
rossberg
2015/05/11 15:39:28
It's also worth testing the case where the callee
arv (Not doing code reviews)
2015/05/11 16:54:02
Done.
rossberg
2015/05/12 06:02:16
Sorry for the misunderstanding, I meant the case w
|
| + |
| + assertThrows(f, TypeError); |
| + %OptimizeFunctionOnNextCall(f); |
| + assertThrows(f, TypeError); |
| + |
| + function g() { |
| + f(1); |
| + } |
| + assertThrows(g, TypeError); |
| + %OptimizeFunctionOnNextCall(g); |
| + assertThrows(g, TypeError); |
| +})(); |
| + |
| + |
| +// 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(); |
| +// })(); |