blob: 11ee212a64a3f68798e65690d35296c8e2928fcb [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Flags: --strong-mode --harmony-reflect
6// Flags: --allow-natives-syntax
7
8'use strict';
9
10
11function generateArguments(n, prefix) {
12 let a = [];
13 if (prefix) {
14 a.push(prefix);
15 }
16 for (let i = 0; i < n; i++) {
17 a.push(String(i));
18 }
19
20 return a.join(', ');
21}
22
23
24function generateParams(n, directive_in_body) {
25 let a = [];
26 for (let i = 0; i < n; i++) {
27 a[i] = `p${i}`;
28 }
29 return a.join(', ');
30}
31
32function generateParamsWithRest(n, directive_in_body) {
33 let a = [];
34 let i = 0;
35 for (; i < n; i++) {
36 a[i] = `p${i}`;
37 }
38 if (!directive_in_body) {
39 // If language mode directive occurs in body, rest parameters will trigger
40 // an early error regardless of language mode.
41 a.push(`...p${i}`);
42 }
43 return a.join(', ');
44}
45
46
47function generateSpread(n) {
48 return `...[${generateArguments(n)}]`;
49}
50
51
52(function FunctionCall() {
53 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
54 let defs = [
55 `'use strong'; function f(${generateParams(parameterCount)}) {}`,
56 `'use strong'; function f(${generateParamsWithRest(parameterCount)}) {}`,
57 `'use strong'; function* f(${generateParams(parameterCount)}) {}`,
58 `'use strong'; function* f(${generateParamsWithRest(parameterCount)}) {}`,
59 `'use strong'; let f = (${generateParams(parameterCount)}) => {}`,
60 `function f(${generateParams(parameterCount)}) { 'use strong'; }`,
61 `function* f(${generateParams(parameterCount)}) { 'use strong'; }`,
62 `let f = (${generateParams(parameterCount)}) => { 'use strong'; }`,
63 ];
64 for (let def of defs) {
65 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
66 let calls = [
67 `f(${generateArguments(argumentCount)})`,
68 `f(${generateSpread(argumentCount)})`,
69 `f.call(${generateArguments(argumentCount, 'undefined')})`,
70 `f.call(undefined, ${generateSpread(argumentCount)})`,
71 `f.apply(undefined, [${generateArguments(argumentCount)}])`,
72 `f.bind(undefined)(${generateArguments(argumentCount)})`,
73 `%_Call(f, ${generateArguments(argumentCount, 'undefined')})`,
74 `%Call(f, ${generateArguments(argumentCount, 'undefined')})`,
75 `%Apply(f, undefined, [${generateArguments(argumentCount)}], 0,
76 ${argumentCount})`,
77 ];
78
79 for (let call of calls) {
80 let code = `'use strict'; ${def}; ${call};`;
81 if (argumentCount < parameterCount) {
82 print(code);
83 assertThrows(code, TypeError);
84 } else {
85 assertDoesNotThrow(code);
86 }
87 }
88 }
89
90 let calls = [
91 `f.call()`,
92 `f.apply()`,
93 `f.apply(undefined)`,
94 ];
95 for (let call of calls) {
96 let code = `'use strict'; ${def}; ${call};`;
97 if (parameterCount > 0) {
98 assertThrows(code, TypeError);
99 } else {
100 assertDoesNotThrow(code);
101 }
102 }
103 }
104 }
105})();
106
107
108(function MethodCall() {
109 for (let genParams of [generateParams, generateParamsWithRest]) {
110 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
111 let defs = [
112 `let o = new class {
113 m(${genParams(parameterCount, true)}) { 'use strong'; }
114 }`,
115 `let o = new class {
116 *m(${genParams(parameterCount, true)}) { 'use strong'; }
117 }`,
118 `let o = { m(${genParams(parameterCount, true)}) { 'use strong'; } }`,
119 `let o = { *m(${genParams(parameterCount, true)}) { 'use strong'; } }`,
120 `'use strong';
121 let o = new class { m(${genParams(parameterCount)}) {} }`,
122 `'use strong';
123 let o = new class { *m(${genParams(parameterCount)}) {} }`,
124 `'use strong'; let o = { m(${genParams(parameterCount)}) {} }`,
125 `'use strong'; let o = { *m(${genParams(parameterCount)}) {} }`,
126 ];
127 for (let def of defs) {
128 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
129 let calls = [
130 `o.m(${generateArguments(argumentCount)})`,
131 `o.m(${generateSpread(argumentCount)})`,
132 `o.m.call(${generateArguments(argumentCount, 'o')})`,
133 `o.m.call(o, ${generateSpread(argumentCount)})`,
134 `o.m.apply(o, [${generateArguments(argumentCount)}])`,
135 `o.m.bind(o)(${generateArguments(argumentCount)})`,
136 `%_Call(o.m, ${generateArguments(argumentCount, 'o')})`,
137 `%Call(o.m, ${generateArguments(argumentCount, 'o')})`,
138 `%Apply(o.m, o, [${generateArguments(argumentCount)}], 0,
139 ${argumentCount})`,
140 ];
141
142 for (let call of calls) {
143 let code = `'use strict'; ${def}; ${call};`;
144 if (argumentCount < parameterCount) {
145 assertThrows(code, TypeError);
146 } else {
147 assertDoesNotThrow(code);
148 }
149 }
150 }
151
152 let calls = [
153 `o.m.call()`,
154 `o.m.apply()`,
155 `o.m.apply(o)`,
156 ];
157 for (let call of calls) {
158 let code = `'use strict'; ${def}; ${call};`;
159 if (parameterCount > 0) {
160 assertThrows(code, TypeError);
161 } else {
162 assertDoesNotThrow(code);
163 }
164 }
165 }
166 }
167 }
168})();
169
170
171(function Constructor() {
172 for (let genParams of [generateParams, generateParamsWithRest]) {
173 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
174 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
175 let defs = [
176 `'use strong';
177 class C { constructor(${genParams(parameterCount)}) {} }`,
178 ];
179 for (let def of defs) {
180 let calls = [
181 `new C(${generateArguments(argumentCount)})`,
182 `new C(${generateSpread(argumentCount)})`,
183 `Reflect.construct(C, [${generateArguments(argumentCount)}])`,
184 ];
185 for (let call of calls) {
186 let code = `${def}; ${call};`;
187 if (argumentCount < parameterCount) {
188 assertThrows(code, TypeError);
189 } else {
190 assertDoesNotThrow(code);
191 }
192 }
193 }
194 }
195 }
196 }
197})();
198
199
200(function DerivedConstructor() {
201 for (let genParams of [generateParams, generateParamsWithRest]) {
202 for (let genArgs of [generateArguments, generateSpread]) {
203 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
204 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
205 let defs = [
206 `'use strong';
207 class B {
208 constructor(${genParams(parameterCount)}) {}
209 }
210 class C extends B {
211 constructor() {
212 super(${genArgs(argumentCount)});
213 }
214 }`,
215 ];
216 for (let def of defs) {
217 let code = `${def}; new C();`;
218 if (argumentCount < parameterCount) {
219 assertThrows(code, TypeError);
220 } else {
221 assertDoesNotThrow(code);
222 }
223 }
224 }
225 }
226 }
227 }
228})();
229
230
231(function DerivedConstructorDefaultConstructorInDerivedClass() {
232 for (let genParams of [generateParams, generateParamsWithRest]) {
233 for (let genArgs of [generateArguments, generateSpread]) {
234 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
235 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
236 let defs = [
237 `'use strong';
238 class B {
239 constructor(${genParams(parameterCount)}) {}
240 }
241 class C extends B {}`,
242 ];
243 for (let def of defs) {
244 let code = `${def}; new C(${genArgs(argumentCount)})`;
245 if (argumentCount < parameterCount) {
246 assertThrows(code, TypeError);
247 } else {
248 assertDoesNotThrow(code);
249 }
250 }
251 }
252 }
253 }
254 }
255})();
256
257
258(function TestOptimized() {
259 function f(x, y) { 'use strong'; }
260
261 assertThrows(f, TypeError);
262 %OptimizeFunctionOnNextCall(f);
263 assertThrows(f, TypeError);
264
265 function g() {
266 f(1);
267 }
268 assertThrows(g, TypeError);
269 %OptimizeFunctionOnNextCall(g);
270 assertThrows(g, TypeError);
271
272 f(1, 2);
273 %OptimizeFunctionOnNextCall(f);
274 f(1, 2);
275})();
276
277
278(function TestOptimized2() {
279 'use strong';
280 function f(x, y) {}
281
282 assertThrows(f, TypeError);
283 %OptimizeFunctionOnNextCall(f);
284 assertThrows(f, TypeError);
285
286 function g() {
287 f(1);
288 }
289 assertThrows(g, TypeError);
290 %OptimizeFunctionOnNextCall(g);
291 assertThrows(g, TypeError);
292
293 f(1, 2);
294 %OptimizeFunctionOnNextCall(f);
295 f(1, 2);
296})();
297
298
299(function TestOptimized3() {
300 function f(x, y) {}
301 function g() {
302 'use strong';
303 f(1);
304 }
305
306 g();
307 %OptimizeFunctionOnNextCall(f);
308 g();
309})();
310
311
312(function ParametersSuper() {
313 for (let genArgs of [generateArguments, generateSpread]) {
314 for (let argumentCount = 0; argumentCount < 3; argumentCount++) {
315 for (let parameterCount = 0; parameterCount < 3; parameterCount++) {
316 let defs = [
317 `'use strict';
318 class B {
319 m(${generateParams(parameterCount)} ){ 'use strong' }
320 }`,
321 `'use strong'; class B { m(${generateParams(parameterCount)}) {} }`,
322 ];
323 for (let def of defs) {
324 let code = `${def};
325 class D extends B {
326 m() {
327 super.m(${genArgs(argumentCount)});
328 }
329 }
330 new D().m()`;
331 print('\n\n' + code);
332 if (argumentCount < parameterCount) {
333 assertThrows(code, TypeError);
334 } else {
335 assertDoesNotThrow(code);
336 }
337 }
338 }
339 }
340 }
341})();