Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(74)

Side by Side Diff: test/mjsunit/es7/syntactic-tail-call.js

Issue 1928203002: [es8] More spec compliant syntactic tail calls implementation. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Moar tests Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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: --allow-natives-syntax --harmony-explicit-tailcalls
6
7 Error.prepareStackTrace = (error,stack) => {
8 error.strace = stack;
9 return error.message + "\n at " + stack.join("\n at ");
10 }
11
12
13 function CheckStackTrace(expected) {
14 var e = new Error();
15 e.stack; // prepare stack trace
16 var stack = e.strace;
17 assertEquals("CheckStackTrace", stack[0].getFunctionName());
18 for (var i = 0; i < expected.length; i++) {
19 assertEquals(expected[i].name, stack[i + 1].getFunctionName());
20 }
21 }
22
23 function f(expected_call_stack, a, b) {
24 CheckStackTrace(expected_call_stack);
25 return a;
26 }
27
28 function f_153(expected_call_stack, a) {
29 CheckStackTrace(expected_call_stack);
30 return 153;
31 }
32
33
34 // Tail call when caller does not have an arguments adaptor frame.
35 (function() {
36 // Caller and callee have same number of arguments.
37 function f1(a) {
38 CheckStackTrace([f1, test]);
39 return 10 + a;
40 }
41 function g1(a) { return continue f1(2); }
42
43 // Caller has more arguments than callee.
44 function f2(a) {
45 CheckStackTrace([f2, test]);
46 return 10 + a;
47 }
48 function g2(a, b, c) { return continue f2(2); }
49
50 // Caller has less arguments than callee.
51 function f3(a, b, c) {
52 CheckStackTrace([f3, test]);
53 return 10 + a + b + c;
54 }
55 function g3(a) { return continue f3(2, 3, 4); }
56
57 // Callee has arguments adaptor frame.
58 function f4(a, b, c) {
59 CheckStackTrace([f4, test]);
60 return 10 + a;
61 }
62 function g4(a) { return continue f4(2); }
63
64 function test() {
65 assertEquals(12, g1(1));
66 assertEquals(12, g2(1, 2, 3));
67 assertEquals(19, g3(1));
68 assertEquals(12, g4(1));
69 }
70 test();
71 test();
72 %OptimizeFunctionOnNextCall(test);
73 test();
74 })();
75
76
77 // Tail call when caller has an arguments adaptor frame.
78 (function() {
79 // Caller and callee have same number of arguments.
80 function f1(a) {
81 CheckStackTrace([f1, test]);
82 return 10 + a;
83 }
84 function g1(a) { return continue f1(2); }
85
86 // Caller has more arguments than callee.
87 function f2(a) {
88 CheckStackTrace([f2, test]);
89 return 10 + a;
90 }
91 function g2(a, b, c) { return continue f2(2); }
92
93 // Caller has less arguments than callee.
94 function f3(a, b, c) {
95 CheckStackTrace([f3, test]);
96 return 10 + a + b + c;
97 }
98 function g3(a) { return continue f3(2, 3, 4); }
99
100 // Callee has arguments adaptor frame.
101 function f4(a, b, c) {
102 CheckStackTrace([f4, test]);
103 return 10 + a;
104 }
105 function g4(a) { return continue f4(2); }
106
107 function test() {
108 assertEquals(12, g1());
109 assertEquals(12, g2());
110 assertEquals(19, g3());
111 assertEquals(12, g4());
112 }
113 test();
114 test();
115 %OptimizeFunctionOnNextCall(test);
116 test();
117 })();
118
119
120 // Tail call bound function when caller does not have an arguments
121 // adaptor frame.
122 (function() {
123 // Caller and callee have same number of arguments.
124 function f1(a) {
125 assertEquals(153, this.a);
126 CheckStackTrace([f1, test]);
127 return 10 + a;
128 }
129 var b1 = f1.bind({a: 153});
130 function g1(a) { return continue b1(2); }
131
132 // Caller has more arguments than callee.
133 function f2(a) {
134 assertEquals(153, this.a);
135 CheckStackTrace([f2, test]);
136 return 10 + a;
137 }
138 var b2 = f2.bind({a: 153});
139 function g2(a, b, c) { return continue b2(2); }
140
141 // Caller has less arguments than callee.
142 function f3(a, b, c) {
143 assertEquals(153, this.a);
144 CheckStackTrace([f3, test]);
145 return 10 + a + b + c;
146 }
147 var b3 = f3.bind({a: 153});
148 function g3(a) { return continue b3(2, 3, 4); }
149
150 // Callee has arguments adaptor frame.
151 function f4(a, b, c) {
152 assertEquals(153, this.a);
153 CheckStackTrace([f4, test]);
154 return 10 + a;
155 }
156 var b4 = f4.bind({a: 153});
157 function g4(a) { return continue b4(2); }
158
159 function test() {
160 assertEquals(12, g1(1));
161 assertEquals(12, g2(1, 2, 3));
162 assertEquals(19, g3(1));
163 assertEquals(12, g4(1));
164 }
165 test();
166 test();
167 %OptimizeFunctionOnNextCall(test);
168 test();
169 })();
170
171
172 // Tail call bound function when caller has an arguments adaptor frame.
173 (function() {
174 // Caller and callee have same number of arguments.
175 function f1(a) {
176 assertEquals(153, this.a);
177 CheckStackTrace([f1, test]);
178 return 10 + a;
179 }
180 var b1 = f1.bind({a: 153});
181 function g1(a) { return continue b1(2); }
182
183 // Caller has more arguments than callee.
184 function f2(a) {
185 assertEquals(153, this.a);
186 CheckStackTrace([f2, test]);
187 return 10 + a;
188 }
189 var b2 = f2.bind({a: 153});
190 function g2(a, b, c) { return continue b2(2); }
191
192 // Caller has less arguments than callee.
193 function f3(a, b, c) {
194 assertEquals(153, this.a);
195 CheckStackTrace([f3, test]);
196 return 10 + a + b + c;
197 }
198 var b3 = f3.bind({a: 153});
199 function g3(a) { return continue b3(2, 3, 4); }
200
201 // Callee has arguments adaptor frame.
202 function f4(a, b, c) {
203 assertEquals(153, this.a);
204 CheckStackTrace([f4, test]);
205 return 10 + a;
206 }
207 var b4 = f4.bind({a: 153});
208 function g4(a) { return continue b4(2); }
209
210 function test() {
211 assertEquals(12, g1());
212 assertEquals(12, g2());
213 assertEquals(19, g3());
214 assertEquals(12, g4());
215 }
216 test();
217 test();
218 %OptimizeFunctionOnNextCall(test);
219 test();
220 })();
221
222
223 // Tail calling via various expressions.
224 (function() {
225 function g1(a) {
226 return continue f([f, g1, test], false) || f([f, test], true);
227 }
228
229 function g2(a) {
230 return continue f([f, g2, test], true) && f([f, test], true);
231 }
232
233 function g3(a) {
234 return continue f([f, g3, test], 13), f([f, test], 153);
235 }
236
237 function test() {
238 assertEquals(true, g1());
239 assertEquals(true, g2());
240 assertEquals(153, g3());
241 }
242 test();
243 test();
244 %OptimizeFunctionOnNextCall(test);
245 test();
246 })();
247
248
249 // Test tail calls from try-catch constructs.
250 (function() {
251 function tc1(a) {
252 try {
253 f_153([f_153, tc1, test]);
254 return f_153([f_153, tc1, test]);
255 } catch(e) {
256 f_153([f_153, tc1, test]);
257 }
258 }
259
260 function tc2(a) {
261 try {
262 f_153([f_153, tc2, test]);
263 throw new Error("boom");
264 } catch(e) {
265 f_153([f_153, tc2, test]);
266 return continue f_153([f_153, test]);
267 }
268 }
269
270 function tc3(a) {
271 try {
272 f_153([f_153, tc3, test]);
273 throw new Error("boom");
274 } catch(e) {
275 f_153([f_153, tc3, test]);
276 }
277 f_153([f_153, tc3, test]);
278 return continue f_153([f_153, test]);
279 }
280
281 function test() {
282 assertEquals(153, tc1());
283 assertEquals(153, tc2());
284 assertEquals(153, tc3());
285 }
286 test();
287 test();
288 %OptimizeFunctionOnNextCall(test);
289 test();
290 })();
291
292
293 // Test tail calls from try-finally constructs.
294 (function() {
295 function tf1(a) {
296 try {
297 f_153([f_153, tf1, test]);
298 return f_153([f_153, tf1, test]);
299 } finally {
300 f_153([f_153, tf1, test]);
301 }
302 }
303
304 function tf2(a) {
305 try {
306 f_153([f_153, tf2, test]);
307 throw new Error("boom");
308 } finally {
309 f_153([f_153, tf2, test]);
310 return continue f_153([f_153, test]);
311 }
312 }
313
314 function tf3(a) {
315 try {
316 f_153([f_153, tf3, test]);
317 } finally {
318 f_153([f_153, tf3, test]);
319 }
320 return continue f_153([f_153, test]);
321 }
322
323 function test() {
324 assertEquals(153, tf1());
325 assertEquals(153, tf2());
326 assertEquals(153, tf3());
327 }
328 test();
329 test();
330 %OptimizeFunctionOnNextCall(test);
331 test();
332 })();
333
334
335 // Test tail calls from try-catch-finally constructs.
336 (function() {
337 function tcf1(a) {
338 try {
339 f_153([f_153, tcf1, test]);
340 return f_153([f_153, tcf1, test]);
341 } catch(e) {
342 } finally {
343 f_153([f_153, tcf1, test]);
344 }
345 }
346
347 function tcf2(a) {
348 try {
349 f_153([f_153, tcf2, test]);
350 throw new Error("boom");
351 } catch(e) {
352 f_153([f_153, tcf2, test]);
353 return f_153([f_153, tcf2, test]);
354 } finally {
355 f_153([f_153, tcf2, test]);
356 }
357 }
358
359 function tcf3(a) {
360 try {
361 f_153([f_153, tcf3, test]);
362 throw new Error("boom");
363 } catch(e) {
364 f_153([f_153, tcf3, test]);
365 } finally {
366 f_153([f_153, tcf3, test]);
367 return continue f_153([f_153, test]);
368 }
369 }
370
371 function tcf4(a) {
372 try {
373 f_153([f_153, tcf4, test]);
374 throw new Error("boom");
375 } catch(e) {
376 f_153([f_153, tcf4, test]);
377 } finally {
378 f_153([f_153, tcf4, test]);
379 }
380 return continue f_153([f_153, test]);
381 }
382
383 function test() {
384 assertEquals(153, tcf1());
385 assertEquals(153, tcf2());
386 assertEquals(153, tcf3());
387 assertEquals(153, tcf4());
388 }
389 test();
390 test();
391 %OptimizeFunctionOnNextCall(test);
392 test();
393 })();
394
395
396 // Test tail calls from arrow functions.
397 (function () {
398 function g1(a) {
399 return continue (() => { return continue f_153([f_153, test]); })();
400 }
401
402 function g2(a) {
403 return continue (() => continue f_153([f_153, test]))();
404 }
405
406 function g3(a) {
407 var closure = () => continue f([f, closure, test], true)
408 ? f_153([f_153, test])
409 : f_153([f_153, test]);
410
411 return continue closure();
412 }
413
414 function test() {
415 assertEquals(153, g1());
416 assertEquals(153, g2());
417 assertEquals(153, g3());
418 }
419 test();
420 test();
421 %OptimizeFunctionOnNextCall(test);
422 test();
423 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698