• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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-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 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 g(n - 1);
61  }
62  function g(n){
63    if (n <= 0) {
64      return "bar";
65    }
66    return 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 g(n - 1, 42);  // Call with arguments adaptor.
83  }
84  function g(n){
85    if (n <= 0) {
86      return "bar";
87    }
88    return 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 f_bound(n - 1);
108  }
109  var f_bound = f0.bind({});
110  function f(n) {
111    return 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 g_bound(n - 1);
126  }
127  function g0(n){
128    if (n <= 0) {
129      return "bar";
130    }
131    return f_bound(n - 1);
132  }
133  var f_bound = f0.bind({});
134  var g_bound = g0.bind({});
135  function f(n) {
136    return 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})();
144