whatwg / html

HTML Standard
https://html.spec.whatwg.org/multipage/
Other
8.09k stars 2.66k forks source link

"Abort a running script" doesn't abort function invocations #8421

Open andreubotella opened 1 year ago

andreubotella commented 1 year ago

"Abort a running script" is defined in terms of stopping invocations of TC39 operations to evaluate a (classic or module) script, but the way it is defined it doesn't allow killing an invocation of a JS function. Likewise, "run a classic script" and "run a module script" handle script abortions, but WebIDL's "call a user object's operation", and "invoke" and "construct" a callback function don't.

Everywhere that deals with killing script execution in the HTML spec (the section on "user agents may impose resource limitations" after the "abort a running script" definition, as well as worker and worklet termination) use "abort a running script", which means an endless loop like this could not be stopped:

setTimeout(() => {
  while (true) {}
}, 0);
domenic commented 1 year ago

doesn't allow killing an invocation of a JS function

This seems false? The prose is pretty clear: "cease immediately", "emptying the JavaScript execution context stack", etc.

It doesn't say "cease immediately unless you are in the middle of a function". Or "cease immediately after you finish the next TC39 operation". It says "immediately cease".

andreubotella commented 1 year ago

The spec says that it's the ScriptEvaluation or Source Text Module Record Evaluate invocations that have to cease immediately, not any script execution started through other means. And I'm reading "emptying the JavaScript execution context stack" as being the way through which they must cease immediately.

bathos commented 1 year ago

It does makes it sound like the AOs must be on the (hypothetical) stack for the emptying-of-the-stack to occur cause it’s seemingly written as a cause and effect chain, not a list of independent actions to take.

However it doesn’t seem to be the definition of aborting a script in itself, is it? It describes consequences (“This causes...”) but doesn’t claim to be exhaustive & doesn’t say how those things “happen”. There’s a sentence further on though which does seem more like a “definition” to me — just one whose ambiguity is likely intentional:

~> If scripting is disabled while a script is executing, the script should be terminated immediately.~

I copypasted the wrong line and now have no idea what I’d thought was a better sentence, so ignore that lol. The very first one, maybe?

Right now ECMA-262 doesn’t really allow for this to occur. Like, it’s not just missing from ES, it’s “impossible” as a consequence of ES’s own semantics I think(?) This seems to be why the section opens with “Although the JavaScript specification does not account for this possibility.” There are more related issues linked to from that one which color in the picture more.

The changes needed are nuts and bolts things squarely inside the ES “jurisdiction,” e.g. it’d touch the real scary stuff (well, to me I mean) related to memory model invariants I suspect & till ES’s own semantics permit termination to occur, it seems short & sweet on the HTML side is probably a safer stopgap than attempted precision that’s known to be wrong underneath.

I agree that the highlighted sentence (whether meant to be definitional or not) is confusing.

andreubotella commented 1 year ago

Right now ECMA-262 doesn’t really allow for this to occur. Like, it’s not just missing from ES, it’s “impossible” as a consequence of ES’s own semantics I think(?) This seems to be why the section opens with “Although the JavaScript specification does not account for this possibility.” There are more related issues linked to from that one which color in the picture more.

The changes needed are nuts and bolts things squarely inside the ES “jurisdiction,” e.g. it’d touch the real scary stuff (well, to me I mean) related to memory model invariants I suspect & till ES’s own semantics permit termination to occur, it seems short & sweet on the HTML side is probably a safer stopgap than attempted precision that’s known to be wrong underneath.

True, but the UA-level (rather than JS engine-level) semantics of aborting script execution during a WebIDL callback invocation are also not defined at all, and this would indeed fall on the HTML / WebIDL side to define. I suppose this can't be done fully until TC39 specifies aborting scripts, but some progress in defining the semantics could still be made before that.