4

JavaScript (browser): I want to find out how deep the stack is. Basically, I want to know how many lines would be printed if I would call console.trace(). But I don't want to call console.trace() (and then count lines in the console window), I just want to 'have' that number of lines in a variable which I can then store to get some kind of performance statistics. Here is an example.

function StackTest(limit){
    this.inc = -1;
    this.limit = limit;
}
StackTest.prototype.test = function(n){
    //console.log(n);
    if (n>this.limit){
        console.trace();
        return [n, this.inc];
    }
    this.inc += 2;
    return this.test(n + this.inc);
}
test899 = new StackTest(899);
document.body.innerHTML = test899.test(0);

Above dummy code sums up odd numbers (which generates the sequence of square numbers), until the sum exceeds a given limit, here 899. So, we compute 1 + 3 + 5 + ... + 59 = 900; 900 is the first square exceeding our limit of 899.

The stack depth (for the innermost return) is 30 (as we summed up 30 numbers, namely the odd numbers below 60), and console.trace() will print out 30 lines (to be more exact, 30 lines referring to the last line of our test function)

I want this 30, but I don't want to call console.trace(). Neither do I want to modify my code and put in manual counters. Neither do I want anything specific to the dummy example (like depth = (1+this.inc)/2 or depth=Math.ceil(Math.sqrt(this.limit))); I want a generic way to get the 30 programmatically.

Is that possible?

I should mention: One thing which does not work: generating (not throwing, just creating) an Error with e = new Error('blah'), then doing e.stack, then doing .split('\n') on that to see how many lines there are. The reason this does not work is that the Error stack is 'cut down' to only the topmost couple of lines/frames of the 'real' stack. If there would be something like e.fullStack, that would give me what I want. If error objects as the above have the information I want, then I was unable to find it there.

UPDATE

one more thing which does not work: Error.captureStackTrace, taken from accepted answer to this question. It's 'cut down' also, and therefore, this really shouldn't be the accepted answer!!!

CLARIFICATION

What I'm doing is analyzing/comparing various performance measures of various algorithms. Among the performance measures are run time, space requirements, and stack depth (which is, kind of, a special case of 'space requirements'). The measures are graphed with the problem size on the horizontal axis, and run time etc vertically. To be able to construct graphs like this, obviously, it helps to have functions which do programmatically what otherwise would be done via debugger / console tools.

Please, please spare me with dull lectures about how I allegedly advocate some weirdo programming style, and other far-fetched assumptions on how I write code, just to construct an hallucinated argument for why I "don't need" and/or "shouldn't want" what I'm asking for. More angry rant (very optional)

If you have a rational argument against the existence of the feature, such as security concerns, different story, obviously.

11
  • one more thing which does not work: using the 'old-fashioned' arguments.callee.caller thing in a loop. If the same function occurs twice in the stack trace, you'll get the exact same function (===) again in your chain, rather than some object representing the function (and the different arguments). Thus, if you're doing a while loop until .caller.caller.caller.caller.... gives null, that will give you an infinite loop. Commented Jul 7, 2020 at 6:02
  • 1
    I don't think there's a way. That's a thing that your code can't and shouldn't have access to (functions shouldn't rely on what have called them)... You'll have to stick to counters.
    – FZs
    Commented Jul 7, 2020 at 6:05
  • related: stackoverflow.com/questions/147891/… Commented Jul 7, 2020 at 6:13
  • related: stackoverflow.com/questions/591857/… Commented Jul 7, 2020 at 6:13
  • 1
    I agree with those. However, I still don't think there's a way. (and I assume new Error().stack and alike exist to allow providing meaningful information to the developer, not to be used by the program after applying crazy regexes on them...)
    – FZs
    Commented Jul 7, 2020 at 17:10

0