Standardizing out-of-memory and stack-depth-exceeded errors?
On Mar 22, 2011, at 9:07 AM, Joshua Bell wrote:
Formally describing the behavior of these runtime boundaries may be outside the scope of ECMA-262,
It's also extremely hard to do well and fairly across all JS host environments (tiny devices up to beefy servers).
Compiler writers will have to cope. Harmony includes proper tail calls now, so that will help.
and some browsers choose not to expose this condition to scripts at all and simply terminate the presumably misbehaving script with appropriate user feedback. And in scenarios where the code is trusted the desired behavior may be to let the process exhaust resources and let the operating system terminate the process. But given the increase in "compile to JavaScript" scenarios where the source language may have other exception handling mechanisms it seems like this might be something to aim for convergence on, at least within sandboxed environments. Any browser vendor interest? Would discussion belong in this working group or WHATWG or ... ?
This is the list for discussion about ECMAScript language design and implementation (where strongly coupled to design) issues, so it's a fair topic.
My two cents: I don't think we'll be standardizing anything here for a long while, if ever. It's up to implementors, depending on device capabilities and competition, to do their best.
On Tue, Mar 22, 2011 at 12:07 PM, Joshua Bell <josh at lindenlab.com> wrote:
I was noodling with a (toy) compiler-to-JS for a (dead) language that supports error handlers for two boundary conditions - stack depth exceeded & out of memory - and noticed that the relevant behavior in JS is not standard across browsers. Has there been any discussion around standardization of errors thrown when limits of the script execution environment are hit? (Searching the archives didn't yield hits, but my search-fu may be weak today.)
From briefly testing the boxes on my desk:
stack depth: function a() { return a() + 1; } a();
- IE9: Error, message: 'Out of stack space'
- Firefox 4: InternalError, message: 'too much recursion'
- Safari 5: RangeError, message 'Maximum call stack size exceeded'
- Chrome 10: RangeError, message: 'Maximum call stack size exceeded', type: 'stack_overflow'
- Opera 11: Error, message: 'Maximum recursion depth exceeded'
RangeError makes most sense here, imo. It does after all "indicates a numeric value has exceeded the allowable range" (15.11.6.2) even if this "numeric value" is something internal. Standardizing (or agreeing upon) RangeError across implementations wouldn't solve much of course, since it could be RangeError caused any of the other cases where RangeError occurs. Parsing message for "stack" or "recursion" would help, but that's just ugly and fragile.
Firefox's InternalError looks like something non-standard. I wonder why they don't just throw Error.
[...]
On Mar 23, 2011, at 1:06 AM, Juriy Zaytsev wrote:
On Tue, Mar 22, 2011 at 12:07 PM, Joshua Bell <josh at lindenlab.com> wrote: I was noodling with a (toy) compiler-to-JS for a (dead) language that supports error handlers for two boundary conditions - stack depth exceeded & out of memory - and noticed that the relevant behavior in JS is not standard across browsers. Has there been any discussion around standardization of errors thrown when limits of the script execution environment are hit? (Searching the archives didn't yield hits, but my search-fu may be weak today.)
From briefly testing the boxes on my desk:
stack depth: function a() { return a() + 1; } a();
- IE9: Error, message: 'Out of stack space'
- Firefox 4: InternalError, message: 'too much recursion'
- Safari 5: RangeError, message 'Maximum call stack size exceeded'
- Chrome 10: RangeError, message: 'Maximum call stack size exceeded', type: 'stack_overflow'
- Opera 11: Error, message: 'Maximum recursion depth exceeded'
RangeError makes most sense here, imo. It does after all "indicates a numeric value has exceeded the allowable range" (15.11.6.2) even if this "numeric value" is something internal. Standardizing (or agreeing upon) RangeError across implementations wouldn't solve much of course, since it could be RangeError caused any of the other cases where RangeError occurs. Parsing message for "stack" or "recursion" would help, but that's just ugly and fragile.
Disagree. RangeError might rather be called ValueError based on how it is used. There is no over "value" in a recursively deep program, e.g. Ack(4,5) given
function Ack(m, n) { if (m == 0) return n + 1; if (n == 0) return Ack(m - 1, 1); return Ack(m - 1, Ack(m, n - 1)); }
that can be cited by the error message. Think about the developer's point of view. Which argument is to blame? Or is Ackermann's function to blame? The engine won't know.
Firefox's InternalError looks like something non-standard. I wonder why they don't just throw Error.
This is all non-standard! There is no normative spec.
Picking odd-Firefox-out when the other browsers split into pairs and disagree between Error and RangeError just confirms that. It does not argue that we should jump on one of two bandwagons.
This is a minor point, but I am strongly against RangeError being used for an internal recursion limit that may be OS-dependent.
On 3/22/11, Joshua Bell <josh at lindenlab.com> wrote:
I was noodling with a (toy) compiler-to-JS for a (dead) language that supports error handlers for two boundary conditions - stack depth exceeded & out of memory - and noticed that the relevant behavior in JS is not standard across browsers. Has there been any discussion around standardization of errors thrown when limits of the script execution environment are hit? (Searching the archives didn't yield hits, but my search-fu may be weak today.)
From briefly testing the boxes on my desk:
stack depth: function a() { return a() + 1; } a();
- IE9: Error, message: 'Out of stack space'
- Firefox 4: InternalError, message: 'too much recursion'
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
But FWIW, new InternalError instanceof Error
is true.
- Safari 5: RangeError, message 'Maximum call stack size exceeded'
- Chrome 10: RangeError, message: 'Maximum call stack size exceeded', type: 'stack_overflow'
Agree with Brendan. Seems strange.
The infinite recursion could be detected and reported early. Where does that happen? Does any engine report early for infinite recursion?
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
Necessary to permit instanceof testing, no?
The infinite recursion could be detected and reported early. Where does that happen? Does any engine report early for infinite recursion?
No engine in all of computer science does so.
en.wikipedia.org/wiki/Halting_problem
Mike
On Mar 23, 2011, at 6:21 PM, Garrett Smith wrote:
The infinite recursion could be detected and reported early. Where does that happen? Does any engine report early for infinite recursion?
Non-trivial infinite recursion can't be detected early, and it's the non-trivial cases that people miss in basic testing. Potential infinite recursion can also be trivially detected, however more or less any recursive algorithm is potentially "infinitely recursing" so i suspect such a warning would be seen as unhelpful noise.
On Wed, Mar 23, 2011 at 6:25 PM, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
The infinite recursion could be detected and reported early. Where does that happen? Does any engine report early for infinite recursion?
No engine in all of computer science does so.
but the halting problem is solvable for finite machines. it's only unsolvable for infinite machines.
On 3/23/11, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
Necessary to permit instanceof testing, no?
The infinite recursion could be detected and reported early. Where does that happen? Does any engine report early for infinite recursion?
No; instanceof uses [[HasInstance]] which compares the Function's prototype property to the each objet in the object's prototype chain. If there is a match, the result is true. Otherwise, the result is false.
Bad quoting made it confusing, but I was (am) right. Edited as intended below: On 3/23/11, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
On 3/23/11, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
Necessary to permit instanceof testing, no? [...]
On Wed, Mar 23, 2011 at 8:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
Bad quoting made it confusing, but I was (am) right. Edited as intended below: On 3/23/11, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
On 3/23/11, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
Necessary to permit instanceof testing, no? [...]
No; instanceof uses [[HasInstance]] which compares the Function's prototype property to the each objet in the object's prototype chain. If there is a match, the result is true. Otherwise, the result is false.
I mean that you need the constructor exposed to test instanceof for InternalError.
Mike
On 3/23/11, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 8:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
Bad quoting made it confusing, but I was (am) right. Edited as intended below: On 3/23/11, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
On 3/23/11, Mike Shaver <mike.shaver at gmail.com> wrote:
On Wed, Mar 23, 2011 at 6:21 PM, Garrett Smith <dhtmlkitchen at gmail.com> wrote:
javascript: alert(new InternalError("Got on tha inside, bitch!"));
Hrm. seems odd to expose the constructor publicly.
Necessary to permit instanceof testing, no? [...]
No; instanceof uses [[HasInstance]] which compares the Function's prototype property to the each objet in the object's prototype chain. If there is a match, the result is true. Otherwise, the result is false.
I mean that you need the constructor exposed to test instanceof for InternalError.
FOr what?
I was noodling with a (toy) compiler-to-JS for a (dead) language that supports error handlers for two boundary conditions - stack depth exceeded & out of memory - and noticed that the relevant behavior in JS is not standard across browsers. Has there been any discussion around standardization of errors thrown when limits of the script execution environment are hit? (Searching the archives didn't yield hits, but my search-fu may be weak today.)
stack depth: function a() { return a() + 1; } a();
memory limit: var s = 'x'; while(true) { s = s + s; }
(That "memory" test is much weaker than the stack depth test as the browser may simply be limiting the size strings or of one particular allocation.)
Formally describing the behavior of these runtime boundaries may be outside the scope of ECMA-262, and some browsers choose not to expose this condition to scripts at all and simply terminate the presumably misbehaving script with appropriate user feedback. And in scenarios where the code is trusted the desired behavior may be to let the process exhaust resources and let the operating system terminate the process. But given the increase in "compile to JavaScript" scenarios where the source language may have other exception handling mechanisms it seems like this might be something to aim for convergence on, at least within sandboxed environments. Any browser vendor interest? Would discussion belong in this working group or WHATWG or ... ?