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.
 
 
 
 
 
 

92 lines
1.7 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.
*/
/*===
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);
/*===
50
Error
===*/
/* 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
print(tail_eval(0, 50));
} catch (e) {
print(e.name, e.message);
}
try {
// this should probably not
print(tail_eval(0, 100000));
} catch (e) {
print(e.name);
}