diff --git a/examples/demo/fibonacci_memo.js b/examples/demo/fibonacci_memo.js index 9dbd1f4..300a514 100644 --- a/examples/demo/fibonacci_memo.js +++ b/examples/demo/fibonacci_memo.js @@ -10,4 +10,4 @@ const result = fibonacci(621); const end = performance.now(); console.log(`fibonacci(621) = ${result}`); -console.log(`Time: ${(end - start).toFixed(2)} ms`); +console.log(`Time: ${(end - start).toFixed(4)} ms (${((end - start) * 1000).toFixed(2)} µs)`); diff --git a/examples/demo/fibonacci_tco.js b/examples/demo/fibonacci_tco.js index e8d77e3..d99c523 100644 --- a/examples/demo/fibonacci_tco.js +++ b/examples/demo/fibonacci_tco.js @@ -8,4 +8,4 @@ const result = fib(30); const end = performance.now(); console.log(`fibonacci(30) = ${result}`); -console.log(`Time: ${(end - start).toFixed(2)} ms`); +console.log(`Time: ${(end - start).toFixed(4)} ms (${((end - start) * 1000).toFixed(2)} µs)`); diff --git a/src/ant.c b/src/ant.c index bfb1251..dc6937e 100644 --- a/src/ant.c +++ b/src/ant.c @@ -7222,6 +7222,7 @@ jsval_t call_js_internal( tc_args = js->tc.args; js->tc.args = NULL; tc_argc = js->tc.argc; + tc_iter = true; continue; } diff --git a/tests/test_tco_zeroarg.js b/tests/test_tco_zeroarg.js new file mode 100644 index 0000000..026e6b5 --- /dev/null +++ b/tests/test_tco_zeroarg.js @@ -0,0 +1,23 @@ +// Test: verify zero-arg tail call actually uses TCO by going deep enough to +// guarantee a stack overflow without it. + +// Pure zero-arg self-recursion with no parameters at all +let n = 0; +function go() { + n++; + if (n >= 1000000) return 'ok'; + return go(); +} +const r = go(); +console.log('result:', r, 'n:', n); +if (r !== 'ok') { console.log('FAIL'); process.exit(1); } + +// Zero-arg mutual recursion +let m = 0; +function a() { m++; if (m >= 1000000) return m; return b(); } +function b() { m++; if (m >= 1000000) return m; return a(); } +const r2 = a(); +console.log('mutual result:', r2); +if (r2 !== 1000000) { console.log('FAIL'); process.exit(1); } + +console.log('PASS');