blob: ec7ade6673bee066a4c7ddf377e03f8b412acf9f [file] [log] [blame]
Ben Murdochc5610432016-08-08 18:44:38 +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-explicit-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 continue 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 continue f(n - 1, 42); // Call with arguments adaptor.
47 }
48 assertEquals("foo", f(1e5));
49 %OptimizeFunctionOnNextCall(f);
50 assertEquals("foo", f(1e5));
51})();
52
53
54(function() {
55 "use strict";
56 function f(n){
57 if (n <= 0) {
58 return "foo";
59 }
60 return continue g(n - 1);
61 }
62 function g(n){
63 if (n <= 0) {
64 return "bar";
65 }
66 return continue f(n - 1);
67 }
68 assertEquals("foo", f(1e5));
69 assertEquals("bar", f(1e5 + 1));
70 %OptimizeFunctionOnNextCall(f);
71 assertEquals("foo", f(1e5));
72 assertEquals("bar", f(1e5 + 1));
73})();
74
75
76(function() {
77 "use strict";
78 function f(n){
79 if (n <= 0) {
80 return "foo";
81 }
82 return continue g(n - 1, 42); // Call with arguments adaptor.
83 }
84 function g(n){
85 if (n <= 0) {
86 return "bar";
87 }
88 return continue f(n - 1, 42); // Call with arguments adaptor.
89 }
90 assertEquals("foo", f(1e5));
91 assertEquals("bar", f(1e5 + 1));
92 %OptimizeFunctionOnNextCall(f);
93 assertEquals("foo", f(1e5));
94 assertEquals("bar", f(1e5 + 1));
95})();
96
97
98//
99// Tail call bound functions.
100//
101(function() {
102 "use strict";
103 function f0(n) {
104 if (n <= 0) {
105 return "foo";
106 }
107 return continue f_bound(n - 1);
108 }
109 var f_bound = f0.bind({});
110 function f(n) {
111 return continue f_bound(n);
112 }
113 assertEquals("foo", f(1e5));
114 %OptimizeFunctionOnNextCall(f);
115 assertEquals("foo", f(1e5));
116})();
117
118
119(function() {
120 "use strict";
121 function f0(n){
122 if (n <= 0) {
123 return "foo";
124 }
125 return continue g_bound(n - 1);
126 }
127 function g0(n){
128 if (n <= 0) {
129 return "bar";
130 }
131 return continue f_bound(n - 1);
132 }
133 var f_bound = f0.bind({});
134 var g_bound = g0.bind({});
135 function f(n) {
136 return continue f_bound(n);
137 }
138 assertEquals("foo", f(1e5));
139 assertEquals("bar", f(1e5 + 1));
140 %OptimizeFunctionOnNextCall(f);
141 assertEquals("foo", f(1e5));
142 assertEquals("bar", f(1e5 + 1));
143})();