views:

96

answers:

2

I have the following code sample to illustrate my point. When I load this in IE8 on Vista I get the error "Stack Overfow at line:16"

If I recurse using a top level function (outside of the testClass object) I can recurse millions of times without a stack overflow.

Why is this happening? Ultimately I just implemented a Function Que instead of using recursion, but just doesn't make sense to me, and I'd like to understand the cause.

-- code --

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN">
<html>
    <head>
        <title>Recusion Test</title>
        <body>
        </body>

        <script type="text/javascript">

            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    this.x--;
                    this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');
        </script>
    </head>
</html>
+7  A: 

There is no terminating condition for your recursive statement therefore it will run forever.

It appears that you want...


            function testClass() {
                this.x = 15;
                this.recurse = function() {
                    if (this.x--)
                        this.recurse();
                }
            }

            var wtf = new testClass();
                wtf.recurse();

            alert('done');
Dave
A: 

Ok, here's some more insight into the issue I was having. After going back and fixing what I thought was the problem with my application I was still having the issue. The part that made me pursue the issue was that if I recursed only 14 times it would complete successfully.

First, I was executing the original code in an HTA and not Internet Explorer. I'm writing a VIM based code editor similar to FCKEditor.

Second, the structure of my code is as follows:

-HTA

--EditorClass

---DivManagerClass

----KeyBindingClass

In my KeyBindingClass I had a codebase similar to the example provided (except it has a terminating condition)

In my KeyBindingClass I have a repeater property that would repeat the last keystrok N-times if a numeric modifier was pressed. For those that don't know pressing the keys '3' and 'x' in visual mode in vim will delete three characters.

Everything worked fine until I used a numeric modifier greater than 14.

I kept trying to reproduce this issue with a small test harness and couldn't. I was able to recurse up to 3000 in a basic test harness. So I started recreating the scenario as best I could. First I moved the call to the recurse method into another class/method. That limited my call stack to somewhere around 1600 (almost half the stack just vanished.)

Then I added jQuery to the mix and moved the call to the ParentClass.recurse method into a keybinding event inside the document.onready jquery handler. That reduced my callstack to about 1300.

Then I moved my code into an HTA which cut my call stack in half again! After mimicking my codebase as best I could and as quickly as I could I reached a callstack of about 515.

After doing some reasearch I have found the IE uses available memory space to determine callstack size. I'm guessing the HTA is a little more strict in that regard. I haven't figured out what other factor has limited my application to such a low callstack given the class structure, but it is definitely code structure that's the issue.

I can put my basic recursion test in a top level execution script tag and get about 1473 calls before reaching a stack overflow.

I can still use a function queue to fix my problem, but I just wanted others to know that A. I wouldn't post such a simple problem to Stack Overflow, and B. that your call stack limit can be vastly affected by the class structures surrounding functions, even though they aren't separate levels of what you'd traditionally consider a function stack.

Marcus Pope