• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
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})();
342