syntactic-tail-call-simple.js 2.71 KB
Newer Older
1 2 3 4 5 6
// 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-explicit-tailcalls --stack-size=100

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
//
// 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) });
})();


23 24 25 26
//
// Tail call normal functions.
//
(function() {
27
  "use strict";
28 29 30 31 32 33 34 35 36 37 38 39 40
  function f(n) {
    if (n <= 0) {
      return "foo";
    }
    return continue f(n - 1);
  }
  assertEquals("foo", f(1e5));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
})();


(function() {
41
  "use strict";
42 43 44 45 46 47 48 49 50 51 52 53 54
  function f(n) {
    if (n <= 0) {
      return  "foo";
    }
    return continue f(n - 1, 42);  // Call with arguments adaptor.
  }
  assertEquals("foo", f(1e5));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
})();


(function() {
55
  "use strict";
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
  function f(n){
    if (n <= 0) {
      return "foo";
    }
    return continue g(n - 1);
  }
  function g(n){
    if (n <= 0) {
      return "bar";
    }
    return continue f(n - 1);
  }
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
})();


(function() {
77
  "use strict";
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
  function f(n){
    if (n <= 0) {
      return "foo";
    }
    return continue g(n - 1, 42);  // Call with arguments adaptor.
  }
  function g(n){
    if (n <= 0) {
      return "bar";
    }
    return continue f(n - 1, 42);  // Call with arguments adaptor.
  }
  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() {
102
  "use strict";
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
  function f0(n) {
    if (n <= 0) {
      return "foo";
    }
    return continue f_bound(n - 1);
  }
  var f_bound = f0.bind({});
  function f(n) {
    return continue f_bound(n);
  }
  assertEquals("foo", f(1e5));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
})();


(function() {
120
  "use strict";
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  function f0(n){
    if (n <= 0) {
      return "foo";
    }
    return continue g_bound(n - 1);
  }
  function g0(n){
    if (n <= 0) {
      return "bar";
    }
    return continue f_bound(n - 1);
  }
  var f_bound = f0.bind({});
  var g_bound = g0.bind({});
  function f(n) {
    return continue f_bound(n);
  }
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
  %OptimizeFunctionOnNextCall(f);
  assertEquals("foo", f(1e5));
  assertEquals("bar", f(1e5 + 1));
})();