You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

102 lines
1.9 KiB

/*
* Tail recursion is not a guaranteed property of a compliant
* implementation. In fact neither Rhino nor V8 seems to have it.
* Since we do, test that it works.
*/
/*---
{
"custom": true,
"comment": "breaks with DUK_OPT_FUNC_NONSTD_CALLER_PROPERTY"
}
---*/
/*===
1000000
===*/
/* Very basic case */
function sum1(a, b) {
if (b == 0) {
return a;
}
return sum1(a + 1, b - 1);
}
try {
print(sum1(0, 1000000));
} catch (e) {
print(e.name);
}
/*===
1000000
1000000
===*/
/* The return expression may contain preceding stuff as long as its evaluation
* ends with a "call + return" pair with nothing in the middle. Here we test
* that a comma expression works (although this is not that important as such).
*/
var count = 0;
function commaop() {
count++;
}
function sum2(a, b) {
if (b == 0) {
return a;
}
return commaop(), sum2(a + 1, b - 1);
}
try {
print(sum2(0, 1000000));
} catch (e) {
print(e.name);
}
print(count);
/*===
25
RangeError
===*/
/* FIXME: Change limit errors to RangeError? */
/* Since both tail calls and eval calls are handled by control flags of the
* CALL instruction, it's worth testing that if both happen at the same time,
* things work as expected.
*
* The call target to a combined eval+tail call is a native function, so no
* tail calling actually takes place. This test just ensures that the calling
* process still works correctly and fulfills eval semantics.
*/
function tail_eval(a,b) {
if (b == 0) {
return a;
}
return eval("tail_eval(a + 1, b - 1)");
}
try {
// This should fit in callstack even without tailcalls.
// C recursion limit is now 60, and each tail_eval()
// level requires two C calls (one for eval, one for
// bytecode executor)
print(tail_eval(0, 25));
} catch (e) {
print(e.name);
}
try {
// this should probably not
print(tail_eval(0, 100000));
} catch (e) {
print(e.name);
}