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

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

Issue 1917993004: [es8] Initial set of changes to support syntactic tail calls. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressing comments Created 4 years, 8 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
1 // Copyright 2016 the V8 project authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Flags: --allow-natives-syntax --harmony-tailcalls 5 // Flags: --allow-natives-syntax --harmony-explicit-tailcalls
6 "use strict";
7 6
8 Error.prepareStackTrace = (error,stack) => { 7 Error.prepareStackTrace = (error,stack) => {
9 error.strace = stack; 8 error.strace = stack;
10 return error.message + "\n at " + stack.join("\n at "); 9 return error.message + "\n at " + stack.join("\n at ");
11 } 10 }
12 11
13 12
14 function CheckStackTrace(expected) { 13 function CheckStackTrace(expected) {
15 var e = new Error(); 14 var e = new Error();
16 e.stack; // prepare stack trace 15 e.stack; // prepare stack trace
(...skipping 15 matching lines...) Expand all
32 } 31 }
33 32
34 33
35 // Tail call when caller does not have an arguments adaptor frame. 34 // Tail call when caller does not have an arguments adaptor frame.
36 (function() { 35 (function() {
37 // Caller and callee have same number of arguments. 36 // Caller and callee have same number of arguments.
38 function f1(a) { 37 function f1(a) {
39 CheckStackTrace([f1, test]); 38 CheckStackTrace([f1, test]);
40 return 10 + a; 39 return 10 + a;
41 } 40 }
42 function g1(a) { return f1(2); } 41 function g1(a) { return continue f1(2); }
43 42
44 // Caller has more arguments than callee. 43 // Caller has more arguments than callee.
45 function f2(a) { 44 function f2(a) {
46 CheckStackTrace([f2, test]); 45 CheckStackTrace([f2, test]);
47 return 10 + a; 46 return 10 + a;
48 } 47 }
49 function g2(a, b, c) { return f2(2); } 48 function g2(a, b, c) { return continue f2(2); }
50 49
51 // Caller has less arguments than callee. 50 // Caller has less arguments than callee.
52 function f3(a, b, c) { 51 function f3(a, b, c) {
53 CheckStackTrace([f3, test]); 52 CheckStackTrace([f3, test]);
54 return 10 + a + b + c; 53 return 10 + a + b + c;
55 } 54 }
56 function g3(a) { return f3(2, 3, 4); } 55 function g3(a) { return continue f3(2, 3, 4); }
57 56
58 // Callee has arguments adaptor frame. 57 // Callee has arguments adaptor frame.
59 function f4(a, b, c) { 58 function f4(a, b, c) {
60 CheckStackTrace([f4, test]); 59 CheckStackTrace([f4, test]);
61 return 10 + a; 60 return 10 + a;
62 } 61 }
63 function g4(a) { return f4(2); } 62 function g4(a) { return continue f4(2); }
64 63
65 function test() { 64 function test() {
66 assertEquals(12, g1(1)); 65 assertEquals(12, g1(1));
67 assertEquals(12, g2(1, 2, 3)); 66 assertEquals(12, g2(1, 2, 3));
68 assertEquals(19, g3(1)); 67 assertEquals(19, g3(1));
69 assertEquals(12, g4(1)); 68 assertEquals(12, g4(1));
70 } 69 }
71 test(); 70 test();
72 test(); 71 test();
73 %OptimizeFunctionOnNextCall(test); 72 %OptimizeFunctionOnNextCall(test);
74 test(); 73 test();
75 })(); 74 })();
76 75
77 76
78 // Tail call when caller has an arguments adaptor frame. 77 // Tail call when caller has an arguments adaptor frame.
79 (function() { 78 (function() {
80 // Caller and callee have same number of arguments. 79 // Caller and callee have same number of arguments.
81 function f1(a) { 80 function f1(a) {
82 CheckStackTrace([f1, test]); 81 CheckStackTrace([f1, test]);
83 return 10 + a; 82 return 10 + a;
84 } 83 }
85 function g1(a) { return f1(2); } 84 function g1(a) { return continue f1(2); }
86 85
87 // Caller has more arguments than callee. 86 // Caller has more arguments than callee.
88 function f2(a) { 87 function f2(a) {
89 CheckStackTrace([f2, test]); 88 CheckStackTrace([f2, test]);
90 return 10 + a; 89 return 10 + a;
91 } 90 }
92 function g2(a, b, c) { return f2(2); } 91 function g2(a, b, c) { return continue f2(2); }
93 92
94 // Caller has less arguments than callee. 93 // Caller has less arguments than callee.
95 function f3(a, b, c) { 94 function f3(a, b, c) {
96 CheckStackTrace([f3, test]); 95 CheckStackTrace([f3, test]);
97 return 10 + a + b + c; 96 return 10 + a + b + c;
98 } 97 }
99 function g3(a) { return f3(2, 3, 4); } 98 function g3(a) { return continue f3(2, 3, 4); }
100 99
101 // Callee has arguments adaptor frame. 100 // Callee has arguments adaptor frame.
102 function f4(a, b, c) { 101 function f4(a, b, c) {
103 CheckStackTrace([f4, test]); 102 CheckStackTrace([f4, test]);
104 return 10 + a; 103 return 10 + a;
105 } 104 }
106 function g4(a) { return f4(2); } 105 function g4(a) { return continue f4(2); }
107 106
108 function test() { 107 function test() {
109 assertEquals(12, g1()); 108 assertEquals(12, g1());
110 assertEquals(12, g2()); 109 assertEquals(12, g2());
111 assertEquals(19, g3()); 110 assertEquals(19, g3());
112 assertEquals(12, g4()); 111 assertEquals(12, g4());
113 } 112 }
114 test(); 113 test();
115 test(); 114 test();
116 %OptimizeFunctionOnNextCall(test); 115 %OptimizeFunctionOnNextCall(test);
117 test(); 116 test();
118 })(); 117 })();
119 118
120 119
121 // Tail call bound function when caller does not have an arguments 120 // Tail call bound function when caller does not have an arguments
122 // adaptor frame. 121 // adaptor frame.
123 (function() { 122 (function() {
124 // Caller and callee have same number of arguments. 123 // Caller and callee have same number of arguments.
125 function f1(a) { 124 function f1(a) {
126 assertEquals(153, this.a); 125 assertEquals(153, this.a);
127 CheckStackTrace([f1, test]); 126 CheckStackTrace([f1, test]);
128 return 10 + a; 127 return 10 + a;
129 } 128 }
130 var b1 = f1.bind({a: 153}); 129 var b1 = f1.bind({a: 153});
131 function g1(a) { return b1(2); } 130 function g1(a) { return continue b1(2); }
132 131
133 // Caller has more arguments than callee. 132 // Caller has more arguments than callee.
134 function f2(a) { 133 function f2(a) {
135 assertEquals(153, this.a); 134 assertEquals(153, this.a);
136 CheckStackTrace([f2, test]); 135 CheckStackTrace([f2, test]);
137 return 10 + a; 136 return 10 + a;
138 } 137 }
139 var b2 = f2.bind({a: 153}); 138 var b2 = f2.bind({a: 153});
140 function g2(a, b, c) { return b2(2); } 139 function g2(a, b, c) { return continue b2(2); }
141 140
142 // Caller has less arguments than callee. 141 // Caller has less arguments than callee.
143 function f3(a, b, c) { 142 function f3(a, b, c) {
144 assertEquals(153, this.a); 143 assertEquals(153, this.a);
145 CheckStackTrace([f3, test]); 144 CheckStackTrace([f3, test]);
146 return 10 + a + b + c; 145 return 10 + a + b + c;
147 } 146 }
148 var b3 = f3.bind({a: 153}); 147 var b3 = f3.bind({a: 153});
149 function g3(a) { return b3(2, 3, 4); } 148 function g3(a) { return continue b3(2, 3, 4); }
150 149
151 // Callee has arguments adaptor frame. 150 // Callee has arguments adaptor frame.
152 function f4(a, b, c) { 151 function f4(a, b, c) {
153 assertEquals(153, this.a); 152 assertEquals(153, this.a);
154 CheckStackTrace([f4, test]); 153 CheckStackTrace([f4, test]);
155 return 10 + a; 154 return 10 + a;
156 } 155 }
157 var b4 = f4.bind({a: 153}); 156 var b4 = f4.bind({a: 153});
158 function g4(a) { return b4(2); } 157 function g4(a) { return continue b4(2); }
159 158
160 function test() { 159 function test() {
161 assertEquals(12, g1(1)); 160 assertEquals(12, g1(1));
162 assertEquals(12, g2(1, 2, 3)); 161 assertEquals(12, g2(1, 2, 3));
163 assertEquals(19, g3(1)); 162 assertEquals(19, g3(1));
164 assertEquals(12, g4(1)); 163 assertEquals(12, g4(1));
165 } 164 }
166 test(); 165 test();
167 test(); 166 test();
168 %OptimizeFunctionOnNextCall(test); 167 %OptimizeFunctionOnNextCall(test);
169 test(); 168 test();
170 })(); 169 })();
171 170
172 171
173 // Tail call bound function when caller has an arguments adaptor frame. 172 // Tail call bound function when caller has an arguments adaptor frame.
174 (function() { 173 (function() {
175 // Caller and callee have same number of arguments. 174 // Caller and callee have same number of arguments.
176 function f1(a) { 175 function f1(a) {
177 assertEquals(153, this.a); 176 assertEquals(153, this.a);
178 CheckStackTrace([f1, test]); 177 CheckStackTrace([f1, test]);
179 return 10 + a; 178 return 10 + a;
180 } 179 }
181 var b1 = f1.bind({a: 153}); 180 var b1 = f1.bind({a: 153});
182 function g1(a) { return b1(2); } 181 function g1(a) { return continue b1(2); }
183 182
184 // Caller has more arguments than callee. 183 // Caller has more arguments than callee.
185 function f2(a) { 184 function f2(a) {
186 assertEquals(153, this.a); 185 assertEquals(153, this.a);
187 CheckStackTrace([f2, test]); 186 CheckStackTrace([f2, test]);
188 return 10 + a; 187 return 10 + a;
189 } 188 }
190 var b2 = f2.bind({a: 153}); 189 var b2 = f2.bind({a: 153});
191 function g2(a, b, c) { return b2(2); } 190 function g2(a, b, c) { return continue b2(2); }
192 191
193 // Caller has less arguments than callee. 192 // Caller has less arguments than callee.
194 function f3(a, b, c) { 193 function f3(a, b, c) {
195 assertEquals(153, this.a); 194 assertEquals(153, this.a);
196 CheckStackTrace([f3, test]); 195 CheckStackTrace([f3, test]);
197 return 10 + a + b + c; 196 return 10 + a + b + c;
198 } 197 }
199 var b3 = f3.bind({a: 153}); 198 var b3 = f3.bind({a: 153});
200 function g3(a) { return b3(2, 3, 4); } 199 function g3(a) { return continue b3(2, 3, 4); }
201 200
202 // Callee has arguments adaptor frame. 201 // Callee has arguments adaptor frame.
203 function f4(a, b, c) { 202 function f4(a, b, c) {
204 assertEquals(153, this.a); 203 assertEquals(153, this.a);
205 CheckStackTrace([f4, test]); 204 CheckStackTrace([f4, test]);
206 return 10 + a; 205 return 10 + a;
207 } 206 }
208 var b4 = f4.bind({a: 153}); 207 var b4 = f4.bind({a: 153});
209 function g4(a) { return b4(2); } 208 function g4(a) { return continue b4(2); }
210 209
211 function test() { 210 function test() {
212 assertEquals(12, g1()); 211 assertEquals(12, g1());
213 assertEquals(12, g2()); 212 assertEquals(12, g2());
214 assertEquals(19, g3()); 213 assertEquals(19, g3());
215 assertEquals(12, g4()); 214 assertEquals(12, g4());
216 } 215 }
217 test(); 216 test();
218 test(); 217 test();
219 %OptimizeFunctionOnNextCall(test); 218 %OptimizeFunctionOnNextCall(test);
220 test(); 219 test();
221 })(); 220 })();
222 221
223 222
224 // Tail calling via various expressions. 223 // Tail calling via various expressions.
225 (function() { 224 (function() {
226 function g1(a) { 225 function g1(a) {
227 return f([f, g1, test], false) || f([f, test], true); 226 return continue f([f, g1, test], false) || f([f, test], true);
228 } 227 }
229 228
230 function g2(a) { 229 function g2(a) {
231 return f([f, g2, test], true) && f([f, test], true); 230 return continue f([f, g2, test], true) && f([f, test], true);
232 } 231 }
233 232
234 function g3(a) { 233 function g3(a) {
235 return f([f, g3, test], 13), f([f, test], 153); 234 return continue f([f, g3, test], 13), f([f, test], 153);
236 } 235 }
237 236
238 function test() { 237 function test() {
239 assertEquals(true, g1()); 238 assertEquals(true, g1());
240 assertEquals(true, g2()); 239 assertEquals(true, g2());
241 assertEquals(153, g3()); 240 assertEquals(153, g3());
242 } 241 }
243 test(); 242 test();
244 test(); 243 test();
245 %OptimizeFunctionOnNextCall(test); 244 %OptimizeFunctionOnNextCall(test);
(...skipping 11 matching lines...) Expand all
257 f_153([f_153, tc1, test]); 256 f_153([f_153, tc1, test]);
258 } 257 }
259 } 258 }
260 259
261 function tc2(a) { 260 function tc2(a) {
262 try { 261 try {
263 f_153([f_153, tc2, test]); 262 f_153([f_153, tc2, test]);
264 throw new Error("boom"); 263 throw new Error("boom");
265 } catch(e) { 264 } catch(e) {
266 f_153([f_153, tc2, test]); 265 f_153([f_153, tc2, test]);
267 return f_153([f_153, test]); 266 return continue f_153([f_153, test]);
268 } 267 }
269 } 268 }
270 269
271 function tc3(a) { 270 function tc3(a) {
272 try { 271 try {
273 f_153([f_153, tc3, test]); 272 f_153([f_153, tc3, test]);
274 throw new Error("boom"); 273 throw new Error("boom");
275 } catch(e) { 274 } catch(e) {
276 f_153([f_153, tc3, test]); 275 f_153([f_153, tc3, test]);
277 } 276 }
278 f_153([f_153, tc3, test]); 277 f_153([f_153, tc3, test]);
279 return f_153([f_153, test]); 278 return continue f_153([f_153, test]);
280 } 279 }
281 280
282 function test() { 281 function test() {
283 assertEquals(153, tc1()); 282 assertEquals(153, tc1());
284 assertEquals(153, tc2()); 283 assertEquals(153, tc2());
285 assertEquals(153, tc3()); 284 assertEquals(153, tc3());
286 } 285 }
287 test(); 286 test();
288 test(); 287 test();
289 %OptimizeFunctionOnNextCall(test); 288 %OptimizeFunctionOnNextCall(test);
(...skipping 11 matching lines...) Expand all
301 f_153([f_153, tf1, test]); 300 f_153([f_153, tf1, test]);
302 } 301 }
303 } 302 }
304 303
305 function tf2(a) { 304 function tf2(a) {
306 try { 305 try {
307 f_153([f_153, tf2, test]); 306 f_153([f_153, tf2, test]);
308 throw new Error("boom"); 307 throw new Error("boom");
309 } finally { 308 } finally {
310 f_153([f_153, tf2, test]); 309 f_153([f_153, tf2, test]);
311 return f_153([f_153, test]); 310 return continue f_153([f_153, test]);
312 } 311 }
313 } 312 }
314 313
315 function tf3(a) { 314 function tf3(a) {
316 try { 315 try {
317 f_153([f_153, tf3, test]); 316 f_153([f_153, tf3, test]);
318 } finally { 317 } finally {
319 f_153([f_153, tf3, test]); 318 f_153([f_153, tf3, test]);
320 } 319 }
321 return f_153([f_153, test]); 320 return continue f_153([f_153, test]);
322 } 321 }
323 322
324 function test() { 323 function test() {
325 assertEquals(153, tf1()); 324 assertEquals(153, tf1());
326 assertEquals(153, tf2()); 325 assertEquals(153, tf2());
327 assertEquals(153, tf3()); 326 assertEquals(153, tf3());
328 } 327 }
329 test(); 328 test();
330 test(); 329 test();
331 %OptimizeFunctionOnNextCall(test); 330 %OptimizeFunctionOnNextCall(test);
(...skipping 26 matching lines...) Expand all
358 } 357 }
359 358
360 function tcf3(a) { 359 function tcf3(a) {
361 try { 360 try {
362 f_153([f_153, tcf3, test]); 361 f_153([f_153, tcf3, test]);
363 throw new Error("boom"); 362 throw new Error("boom");
364 } catch(e) { 363 } catch(e) {
365 f_153([f_153, tcf3, test]); 364 f_153([f_153, tcf3, test]);
366 } finally { 365 } finally {
367 f_153([f_153, tcf3, test]); 366 f_153([f_153, tcf3, test]);
368 return f_153([f_153, test]); 367 return continue f_153([f_153, test]);
369 } 368 }
370 } 369 }
371 370
372 function tcf4(a) { 371 function tcf4(a) {
373 try { 372 try {
374 f_153([f_153, tcf4, test]); 373 f_153([f_153, tcf4, test]);
375 throw new Error("boom"); 374 throw new Error("boom");
376 } catch(e) { 375 } catch(e) {
377 f_153([f_153, tcf4, test]); 376 f_153([f_153, tcf4, test]);
378 } finally { 377 } finally {
379 f_153([f_153, tcf4, test]); 378 f_153([f_153, tcf4, test]);
380 } 379 }
381 return f_153([f_153, test]); 380 return continue f_153([f_153, test]);
382 } 381 }
383 382
384 function test() { 383 function test() {
385 assertEquals(153, tcf1()); 384 assertEquals(153, tcf1());
386 assertEquals(153, tcf2()); 385 assertEquals(153, tcf2());
387 assertEquals(153, tcf3()); 386 assertEquals(153, tcf3());
388 assertEquals(153, tcf4()); 387 assertEquals(153, tcf4());
389 } 388 }
390 test(); 389 test();
391 test(); 390 test();
392 %OptimizeFunctionOnNextCall(test); 391 %OptimizeFunctionOnNextCall(test);
393 test(); 392 test();
394 })(); 393 })();
395 394
396 395
397 // Test tail calls from arrow functions. 396 // Test tail calls from arrow functions.
398 (function () { 397 (function () {
399 function g1(a) { 398 function g1(a) {
400 return (() => { return f_153([f_153, test]); })(); 399 return continue (() => { return continue f_153([f_153, test]); })();
401 } 400 }
402 401
403 function g2(a) { 402 function g2(a) {
404 return (() => f_153([f_153, test]))(); 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();
405 } 412 }
406 413
407 function test() { 414 function test() {
408 assertEquals(153, g1()); 415 assertEquals(153, g1());
409 assertEquals(153, g2()); 416 assertEquals(153, g2());
417 assertEquals(153, g3());
410 } 418 }
411 test(); 419 test();
412 test(); 420 test();
413 %OptimizeFunctionOnNextCall(test); 421 %OptimizeFunctionOnNextCall(test);
414 test(); 422 test();
415 })(); 423 })();
OLDNEW
« no previous file with comments | « test/message/syntactic-tail-call-in-try-try-catch-finally.out ('k') | test/mjsunit/es7/syntactic-tail-call-simple.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698