OLD | NEW |
| (Empty) |
1 // 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 | |
11 function 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 | |
24 function 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 | |
32 function 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 | |
47 function 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 `Reflect.apply(f, undefined, [${generateArguments(argumentCount)}])`, | |
76 ]; | |
77 | |
78 for (let call of calls) { | |
79 let code = `'use strict'; ${def}; ${call};`; | |
80 if (argumentCount < parameterCount) { | |
81 print(code); | |
82 assertThrows(code, TypeError); | |
83 } else { | |
84 assertDoesNotThrow(code); | |
85 } | |
86 } | |
87 } | |
88 | |
89 let calls = [ | |
90 `f.call()`, | |
91 `f.apply()`, | |
92 `f.apply(undefined)`, | |
93 ]; | |
94 for (let call of calls) { | |
95 let code = `'use strict'; ${def}; ${call};`; | |
96 if (parameterCount > 0) { | |
97 assertThrows(code, TypeError); | |
98 } else { | |
99 assertDoesNotThrow(code); | |
100 } | |
101 } | |
102 } | |
103 } | |
104 })(); | |
105 | |
106 | |
107 (function MethodCall() { | |
108 for (let genParams of [generateParams, generateParamsWithRest]) { | |
109 for (let parameterCount = 0; parameterCount < 3; parameterCount++) { | |
110 let defs = [ | |
111 `let o = new class { | |
112 m(${genParams(parameterCount, true)}) { 'use strong'; } | |
113 }`, | |
114 `let o = new class { | |
115 *m(${genParams(parameterCount, true)}) { 'use strong'; } | |
116 }`, | |
117 `let o = { m(${genParams(parameterCount, true)}) { 'use strong'; } }`, | |
118 `let o = { *m(${genParams(parameterCount, true)}) { 'use strong'; } }`, | |
119 `'use strong'; | |
120 let o = new class { m(${genParams(parameterCount)}) {} }`, | |
121 `'use strong'; | |
122 let o = new class { *m(${genParams(parameterCount)}) {} }`, | |
123 `'use strong'; let o = { m(${genParams(parameterCount)}) {} }`, | |
124 `'use strong'; let o = { *m(${genParams(parameterCount)}) {} }`, | |
125 ]; | |
126 for (let def of defs) { | |
127 for (let argumentCount = 0; argumentCount < 3; argumentCount++) { | |
128 let calls = [ | |
129 `o.m(${generateArguments(argumentCount)})`, | |
130 `o.m(${generateSpread(argumentCount)})`, | |
131 `o.m.call(${generateArguments(argumentCount, 'o')})`, | |
132 `o.m.call(o, ${generateSpread(argumentCount)})`, | |
133 `o.m.apply(o, [${generateArguments(argumentCount)}])`, | |
134 `o.m.bind(o)(${generateArguments(argumentCount)})`, | |
135 `%_Call(o.m, ${generateArguments(argumentCount, 'o')})`, | |
136 `%Call(o.m, ${generateArguments(argumentCount, 'o')})`, | |
137 `Reflect.apply(o.m, o, [${generateArguments(argumentCount)}])`, | |
138 ]; | |
139 | |
140 for (let call of calls) { | |
141 let code = `'use strict'; ${def}; ${call};`; | |
142 if (argumentCount < parameterCount) { | |
143 assertThrows(code, TypeError); | |
144 } else { | |
145 assertDoesNotThrow(code); | |
146 } | |
147 } | |
148 } | |
149 | |
150 let calls = [ | |
151 `o.m.call()`, | |
152 `o.m.apply()`, | |
153 `o.m.apply(o)`, | |
154 ]; | |
155 for (let call of calls) { | |
156 let code = `'use strict'; ${def}; ${call};`; | |
157 if (parameterCount > 0) { | |
158 assertThrows(code, TypeError); | |
159 } else { | |
160 assertDoesNotThrow(code); | |
161 } | |
162 } | |
163 } | |
164 } | |
165 } | |
166 })(); | |
167 | |
168 | |
169 (function Constructor() { | |
170 for (let genParams of [generateParams, generateParamsWithRest]) { | |
171 for (let argumentCount = 0; argumentCount < 3; argumentCount++) { | |
172 for (let parameterCount = 0; parameterCount < 3; parameterCount++) { | |
173 let defs = [ | |
174 `'use strong'; | |
175 class C { constructor(${genParams(parameterCount)}) {} }`, | |
176 ]; | |
177 for (let def of defs) { | |
178 let calls = [ | |
179 `new C(${generateArguments(argumentCount)})`, | |
180 `new C(${generateSpread(argumentCount)})`, | |
181 `Reflect.construct(C, [${generateArguments(argumentCount)}])`, | |
182 ]; | |
183 for (let call of calls) { | |
184 let code = `${def}; ${call};`; | |
185 if (argumentCount < parameterCount) { | |
186 assertThrows(code, TypeError); | |
187 } else { | |
188 assertDoesNotThrow(code); | |
189 } | |
190 } | |
191 } | |
192 } | |
193 } | |
194 } | |
195 })(); | |
196 | |
197 | |
198 (function DerivedConstructor() { | |
199 for (let genParams of [generateParams, generateParamsWithRest]) { | |
200 for (let genArgs of [generateArguments, generateSpread]) { | |
201 for (let argumentCount = 0; argumentCount < 3; argumentCount++) { | |
202 for (let parameterCount = 0; parameterCount < 3; parameterCount++) { | |
203 let defs = [ | |
204 `'use strong'; | |
205 class B { | |
206 constructor(${genParams(parameterCount)}) {} | |
207 } | |
208 class C extends B { | |
209 constructor() { | |
210 super(${genArgs(argumentCount)}); | |
211 } | |
212 }`, | |
213 ]; | |
214 for (let def of defs) { | |
215 let code = `${def}; new C();`; | |
216 if (argumentCount < parameterCount) { | |
217 assertThrows(code, TypeError); | |
218 } else { | |
219 assertDoesNotThrow(code); | |
220 } | |
221 } | |
222 } | |
223 } | |
224 } | |
225 } | |
226 })(); | |
227 | |
228 | |
229 (function DerivedConstructorDefaultConstructorInDerivedClass() { | |
230 for (let genParams of [generateParams, generateParamsWithRest]) { | |
231 for (let genArgs of [generateArguments, generateSpread]) { | |
232 for (let argumentCount = 0; argumentCount < 3; argumentCount++) { | |
233 for (let parameterCount = 0; parameterCount < 3; parameterCount++) { | |
234 let defs = [ | |
235 `'use strong'; | |
236 class B { | |
237 constructor(${genParams(parameterCount)}) {} | |
238 } | |
239 class C extends B {}`, | |
240 ]; | |
241 for (let def of defs) { | |
242 let code = `${def}; new C(${genArgs(argumentCount)})`; | |
243 if (argumentCount < parameterCount) { | |
244 assertThrows(code, TypeError); | |
245 } else { | |
246 assertDoesNotThrow(code); | |
247 } | |
248 } | |
249 } | |
250 } | |
251 } | |
252 } | |
253 })(); | |
254 | |
255 | |
256 (function TestOptimized() { | |
257 function f(x, y) { 'use strong'; } | |
258 | |
259 assertThrows(f, TypeError); | |
260 %OptimizeFunctionOnNextCall(f); | |
261 assertThrows(f, TypeError); | |
262 | |
263 function g() { | |
264 f(1); | |
265 } | |
266 assertThrows(g, TypeError); | |
267 %OptimizeFunctionOnNextCall(g); | |
268 assertThrows(g, TypeError); | |
269 | |
270 f(1, 2); | |
271 %OptimizeFunctionOnNextCall(f); | |
272 f(1, 2); | |
273 })(); | |
274 | |
275 | |
276 (function TestOptimized2() { | |
277 'use strong'; | |
278 function f(x, y) {} | |
279 | |
280 assertThrows(f, TypeError); | |
281 %OptimizeFunctionOnNextCall(f); | |
282 assertThrows(f, TypeError); | |
283 | |
284 function g() { | |
285 f(1); | |
286 } | |
287 assertThrows(g, TypeError); | |
288 %OptimizeFunctionOnNextCall(g); | |
289 assertThrows(g, TypeError); | |
290 | |
291 f(1, 2); | |
292 %OptimizeFunctionOnNextCall(f); | |
293 f(1, 2); | |
294 })(); | |
295 | |
296 | |
297 (function TestOptimized3() { | |
298 function f(x, y) {} | |
299 function g() { | |
300 'use strong'; | |
301 f(1); | |
302 } | |
303 | |
304 g(); | |
305 %OptimizeFunctionOnNextCall(f); | |
306 g(); | |
307 })(); | |
308 | |
309 | |
310 (function ParametersSuper() { | |
311 for (let genArgs of [generateArguments, generateSpread]) { | |
312 for (let argumentCount = 0; argumentCount < 3; argumentCount++) { | |
313 for (let parameterCount = 0; parameterCount < 3; parameterCount++) { | |
314 let defs = [ | |
315 `'use strict'; | |
316 class B { | |
317 m(${generateParams(parameterCount)} ){ 'use strong' } | |
318 }`, | |
319 `'use strong'; class B { m(${generateParams(parameterCount)}) {} }`, | |
320 ]; | |
321 for (let def of defs) { | |
322 let code = `${def}; | |
323 class D extends B { | |
324 m() { | |
325 super.m(${genArgs(argumentCount)}); | |
326 } | |
327 } | |
328 new D().m()`; | |
329 print('\n\n' + code); | |
330 if (argumentCount < parameterCount) { | |
331 assertThrows(code, TypeError); | |
332 } else { | |
333 assertDoesNotThrow(code); | |
334 } | |
335 } | |
336 } | |
337 } | |
338 } | |
339 })(); | |
OLD | NEW |