blob: d2890b0212d92044dd0099cdd4f24859d505dc98 [file] [log] [blame]
Ben Murdoch097c5b22016-05-18 11:27:45 +01001// 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-tailcalls --stack-size=100
6
7//
8// Tail calls work only in strict mode.
9//
10(function() {
11 function f(n) {
12 if (n <= 0) {
13 return "foo";
14 }
15 return f(n - 1);
16 }
17 assertThrows(()=>{ f(1e5) });
18 %OptimizeFunctionOnNextCall(f);
19 assertThrows(()=>{ f(1e5) });
20})();
21
22
23//
24// Tail call normal functions.
25//
26(function() {
27 "use strict";
28 function f(n) {
29 if (n <= 0) {
30 return "foo";
31 }
32 return f(n - 1);
33 }
34 assertEquals("foo", f(1e5));
35 %OptimizeFunctionOnNextCall(f);
36 assertEquals("foo", f(1e5));
37})();
38
39
40(function() {
41 "use strict";
42 function f(n){
43 if (n <= 0) {
44 return "foo";
45 }
46 return g(n - 1);
47 }
48 function g(n){
49 if (n <= 0) {
50 return "bar";
51 }
52 return f(n - 1);
53 }
54 assertEquals("foo", f(1e5));
55 assertEquals("bar", f(1e5 + 1));
56 %OptimizeFunctionOnNextCall(f);
57 assertEquals("foo", f(1e5));
58 assertEquals("bar", f(1e5 + 1));
59})();
60
61
62//
63// Tail call bound functions.
64//
65(function() {
66 "use strict";
67 function f0(n) {
68 if (n <= 0) {
69 return "foo";
70 }
71 return f_bound(n - 1);
72 }
73 var f_bound = f0.bind({});
74 function f(n) {
75 return f_bound(n);
76 }
77 assertEquals("foo", f(1e5));
78 %OptimizeFunctionOnNextCall(f);
79 assertEquals("foo", f(1e5));
80})();
81
82
83(function() {
84 "use strict";
85 function f0(n){
86 if (n <= 0) {
87 return "foo";
88 }
89 return g_bound(n - 1);
90 }
91 function g0(n){
92 if (n <= 0) {
93 return "bar";
94 }
95 return f_bound(n - 1);
96 }
97 var f_bound = f0.bind({});
98 var g_bound = g0.bind({});
99 function f(n) {
100 return f_bound(n);
101 }
102 assertEquals("foo", f(1e5));
103 assertEquals("bar", f(1e5 + 1));
104 %OptimizeFunctionOnNextCall(f);
105 assertEquals("foo", f(1e5));
106 assertEquals("bar", f(1e5 + 1));
107})();