OLD | NEW |
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-tailcalls |
6 "use strict"; | 6 "use strict"; |
7 | 7 |
8 Error.prepareStackTrace = (e,s) => s; | 8 Error.prepareStackTrace = (e,s) => s; |
9 | 9 |
10 function CheckStackTrace(expected) { | 10 function CheckStackTrace(expected) { |
11 var stack = (new Error()).stack; | 11 var stack = (new Error()).stack; |
12 assertEquals("CheckStackTrace", stack[0].getFunctionName()); | 12 assertEquals("CheckStackTrace", stack[0].getFunctionName()); |
13 for (var i = 0; i < expected.length; i++) { | 13 for (var i = 0; i < expected.length; i++) { |
14 assertEquals(expected[i].name, stack[i + 1].getFunctionName()); | 14 assertEquals(expected[i].name, stack[i + 1].getFunctionName()); |
15 } | 15 } |
16 } | 16 } |
17 | 17 |
| 18 function f(expected_call_stack, a, b) { |
| 19 CheckStackTrace(expected_call_stack); |
| 20 return a; |
| 21 } |
| 22 |
| 23 function f_153(expected_call_stack, a) { |
| 24 CheckStackTrace(expected_call_stack); |
| 25 return 153; |
| 26 } |
| 27 |
18 | 28 |
19 // Tail call when caller does not have an arguments adaptor frame. | 29 // Tail call when caller does not have an arguments adaptor frame. |
20 (function test() { | 30 (function test() { |
21 // Caller and callee have same number of arguments. | 31 // Caller and callee have same number of arguments. |
22 function f1(a) { | 32 function f1(a) { |
23 CheckStackTrace([f1, test]); | 33 CheckStackTrace([f1, test]); |
24 return 10 + a; | 34 return 10 + a; |
25 } | 35 } |
26 function g1(a) { return f1(2); } | 36 function g1(a) { return f1(2); } |
27 assertEquals(12, g1(1)); | 37 assertEquals(12, g1(1)); |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 // Callee has arguments adaptor frame. | 178 // Callee has arguments adaptor frame. |
169 function f4(a, b, c) { | 179 function f4(a, b, c) { |
170 assertEquals(153, this.a); | 180 assertEquals(153, this.a); |
171 CheckStackTrace([f4, test]); | 181 CheckStackTrace([f4, test]); |
172 return 10 + a; | 182 return 10 + a; |
173 } | 183 } |
174 var b4 = f4.bind({a: 153}); | 184 var b4 = f4.bind({a: 153}); |
175 function g4(a) { return b4(2); } | 185 function g4(a) { return b4(2); } |
176 assertEquals(12, g4()); | 186 assertEquals(12, g4()); |
177 })(); | 187 })(); |
| 188 |
| 189 |
| 190 // Tail calling via various expressions. |
| 191 (function test() { |
| 192 function g1(a) { |
| 193 return f([f, g1, test], false) || f([f, test], true); |
| 194 } |
| 195 assertEquals(true, g1()); |
| 196 |
| 197 function g2(a) { |
| 198 return f([f, g2, test], true) && f([f, test], true); |
| 199 } |
| 200 assertEquals(true, g2()); |
| 201 |
| 202 function g3(a) { |
| 203 return f([f, g3, test], 13), f([f, test], 153); |
| 204 } |
| 205 assertEquals(153, g3()); |
| 206 })(); |
| 207 |
| 208 |
| 209 // Test tail calls from try-catch-finally constructs. |
| 210 (function test() { |
| 211 // |
| 212 // try-catch |
| 213 // |
| 214 function tc1(a) { |
| 215 try { |
| 216 f_153([f_153, tc1, test]); |
| 217 return f_153([f_153, tc1, test]); |
| 218 } catch(e) { |
| 219 f_153([f_153, tc1, test]); |
| 220 } |
| 221 } |
| 222 assertEquals(153, tc1()); |
| 223 |
| 224 function tc2(a) { |
| 225 try { |
| 226 f_153([f_153, tc2, test]); |
| 227 throw new Error("boom"); |
| 228 } catch(e) { |
| 229 f_153([f_153, tc2, test]); |
| 230 return f_153([f_153, test]); |
| 231 } |
| 232 } |
| 233 assertEquals(153, tc2()); |
| 234 |
| 235 function tc3(a) { |
| 236 try { |
| 237 f_153([f_153, tc3, test]); |
| 238 throw new Error("boom"); |
| 239 } catch(e) { |
| 240 f_153([f_153, tc3, test]); |
| 241 } |
| 242 f_153([f_153, tc3, test]); |
| 243 return f_153([f_153, test]); |
| 244 } |
| 245 assertEquals(153, tc3()); |
| 246 |
| 247 // |
| 248 // try-finally |
| 249 // |
| 250 function tf1(a) { |
| 251 try { |
| 252 f_153([f_153, tf1, test]); |
| 253 return f_153([f_153, tf1, test]); |
| 254 } finally { |
| 255 f_153([f_153, tf1, test]); |
| 256 } |
| 257 } |
| 258 assertEquals(153, tf1()); |
| 259 |
| 260 function tf2(a) { |
| 261 try { |
| 262 f_153([f_153, tf2, test]); |
| 263 throw new Error("boom"); |
| 264 } finally { |
| 265 f_153([f_153, tf2, test]); |
| 266 return f_153([f_153, test]); |
| 267 } |
| 268 } |
| 269 assertEquals(153, tf2()); |
| 270 |
| 271 function tf3(a) { |
| 272 try { |
| 273 f_153([f_153, tf3, test]); |
| 274 } finally { |
| 275 f_153([f_153, tf3, test]); |
| 276 } |
| 277 return f_153([f_153, test]); |
| 278 } |
| 279 assertEquals(153, tf3()); |
| 280 |
| 281 // |
| 282 // try-catch-finally |
| 283 // |
| 284 function tcf1(a) { |
| 285 try { |
| 286 f_153([f_153, tcf1, test]); |
| 287 return f_153([f_153, tcf1, test]); |
| 288 } catch(e) { |
| 289 } finally { |
| 290 f_153([f_153, tcf1, test]); |
| 291 } |
| 292 } |
| 293 assertEquals(153, tcf1()); |
| 294 |
| 295 function tcf2(a) { |
| 296 try { |
| 297 f_153([f_153, tcf2, test]); |
| 298 throw new Error("boom"); |
| 299 } catch(e) { |
| 300 f_153([f_153, tcf2, test]); |
| 301 return f_153([f_153, tcf2, test]); |
| 302 } finally { |
| 303 f_153([f_153, tcf2, test]); |
| 304 } |
| 305 } |
| 306 assertEquals(153, tcf2()); |
| 307 |
| 308 function tcf3(a) { |
| 309 try { |
| 310 f_153([f_153, tcf3, test]); |
| 311 throw new Error("boom"); |
| 312 } catch(e) { |
| 313 f_153([f_153, tcf3, test]); |
| 314 } finally { |
| 315 f_153([f_153, tcf3, test]); |
| 316 return f_153([f_153, test]); |
| 317 } |
| 318 } |
| 319 assertEquals(153, tcf3()); |
| 320 |
| 321 function tcf4(a) { |
| 322 try { |
| 323 f_153([f_153, tcf4, test]); |
| 324 throw new Error("boom"); |
| 325 } catch(e) { |
| 326 f_153([f_153, tcf4, test]); |
| 327 } finally { |
| 328 f_153([f_153, tcf4, test]); |
| 329 } |
| 330 return f_153([f_153, test]); |
| 331 } |
| 332 assertEquals(153, tcf4()); |
| 333 })(); |
OLD | NEW |