A recursive algorithm does not *close back* *on* itself, it *calls forward*
*to* itself. Hence the requirement of a stack for recursion, but not for
iteration.
OK, let's us set the grounds first: iterations, recursions, finite
loops, infinite loops etc. these are all top level mental constructs
used in the programming to distinguish certain types of top level
coding. On the engine level itself there is the stack, its size and
respectively certain amount of RET values it may store in LIFO schema.
Respectively the engine itself doesn't care what RETs are these:
function F0001 calling F0002,... calling F1000 - or the same function
F calling itself 1000 times. It is all the same by the allocation
demands. So in order do not switch onto Assembly language yet being
technically correct let's say that each engine has some limit of
nested calls where the chain goes from the initial Global RET point
and up to the currently executed function. This limit is the same for
the regular nested calls and for recursions as well because again on
the lower level it is all the same. So coming back to OP's question
his real question was: "How many nested control flow transfers are
allowed in the most prominent ECMAScript implementations?"
The answer is that they are still rather generous for the regular
coding. Even Safari with its lesser than 500 RET positions doesn't put
some real life limits on coding. When did anyone really needed 500 or
more different functions making nested call chain at once? I mean,
com'on now, guys...
At the same time these limits may hit noticeably recursion based code,
especially one based on infinite loops where the loop's break
determined by some condition check and not by a fixed amount of
iterations.
The other thing is that, as I said, the engine doesn't have a "stack
for regulars", a "stack for recursions" etc. It is all the same
program stack and it nearly never completely empty at runtime, so your
recursion depth tests - if done from the language itself - are going
to the top of whatever is already stored in the stack. This is why
such tests will always differ a bit circa +/-10 depending on the
structure of your test and on additional scripts already running by
the engine. So in order to get _true_ stack size one should to read
the engine specs or to query stack from outside from a C program.
I played a bit with the original test I posted so now you can run it
on any browser without manually changing every time the work-on-denial
value.
It also reminded me that JScript 5.6 had a severe stack vulnerability
bug in the original IE6 back in 2001 that allowed to do whatever you
want with the visitor's computer using specially crafted stack
overflow script. The Microsoft was in such secret panic that time that
they suggested to their corporate customers to "upgrade" from MSDN
from JScript 5.6 to JScript 5.1
I see that the current JScript 5.6 for IE6 has a quick-n-dirty
vulnerability fix for that - so it just shuts down the window being
under attack. An often question in this group is how to close the
original browser window. Here is the Astalavista way for IE6
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en_US">
<head>
<meta http-equiv="Content-type"
content="text/html; charset=iso-8859-1">
<title>Stack depth measuring</title>
<script type="text/javascript">
var fun = new Array(4000);
function test() {
for (var i=0; i<fun.length; i++) {
fun
= new Function('i', ''.concat(
'i++; try {fun(i);}',
'catch(e) {window.alert(',
'e.message.concat("\\n","max allowed: ",i));}'
)
);
}
fun[fun.length-1] = new Function('window.alert(\'OK\');');
eval(fun[0](0));
}
</script>
</head>
<body>
<p>No content</p>
</body>
</html>