summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/es6/tail-call-simple.js
blob: d2890b0212d92044dd0099cdd4f24859d505dc98 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Copyright 2016 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax --harmony-tailcalls --stack-size=100

//
// Tail calls work only in strict mode.
//
(function() {
  function f(n) {
    if (n <= 0) {
      return  "foo";
    }
    return f(n - 1);
  }
  assertThrows(()=>{ f(1e5) });
  %OptimizeFunctionOnNextCall(f);
  assertThrows(()=>{ f(1e5) });
})();


//
// Tail call normal functions.
//
(function() {
  "use strict";
  function f(n) {
    if (n <= 0) {
      return  "foo";
    }
    return f(n - 1);
  }
  assertEquals("foo", f(1e5));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
})();


(function() {
  "use strict";
  function f(n){
    if (n <= 0) {
      return "foo";
    }
    return g(n - 1);
  }
  function g(n){
    if (n <= 0) {
      return "bar";
    }
    return f(n - 1);
  }
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
})();


//
// Tail call bound functions.
//
(function() {
  "use strict";
  function f0(n) {
    if (n <= 0) {
      return "foo";
    }
    return f_bound(n - 1);
  }
  var f_bound = f0.bind({});
  function f(n) {
    return f_bound(n);
  }
  assertEquals("foo", f(1e5));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
})();


(function() {
  "use strict";
  function f0(n){
    if (n <= 0) {
      return "foo";
    }
    return g_bound(n - 1);
  }
  function g0(n){
    if (n <= 0) {
      return "bar";
    }
    return f_bound(n - 1);
  }
  var f_bound = f0.bind({});
  var g_bound = g0.bind({});
  function f(n) {
    return f_bound(n);
  }
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
})();