Exceptional exits from generators

Jason Orendorff jason.orendorff at gmail.com
Tue Apr 15 14:16:45 PDT 2014

On Tue, Apr 8, 2014 at 7:47 AM, Andy Wingo <wingo at igalia.com> wrote:
>   iter.next() // => { value: undefined, done: true }
> I find this very strange.  I would have expected an exception of the
> kind "generator is already running", as indeed we entered the running
> state but never moved out of that state.

I get what you said about there being an extra try-catch in the
continuation. That's certainly true. And very likely no user will ever
care how ES behaves in this case—if a generator throws, you're not
meant to call back into it.

On the other hand it seems more ECMAScript-like for the execution of
the generator to be considered "done" when an exception is thrown out
of it. The spec has terminology like "abrupt completion" that takes
that viewpoint for granted.

How expensive does that try-catch need to be? In straightforward
implementations, the cost should be a single branch, well-predicted as
long as exceptions are rare. Implementations with "zero-cost"
exception handling would avoid that; I think you can even retain the
tail-call opportunity ("tail-resume"?) in .next() and .throw().

> If it is removed we could also consider removing the
> suspendedStart->completed state change on Generator.prototype.throw.
> If that were done we could remove the suspendedStart state entirely;
> dead spec elimination ;)

I don't think we can eliminate the test for "suspendedStart". That
would mean plowing ahead with the rest of the algorithm, right? But
the generator's [[GeneratorContext]] slot holds undefined; we can't
resume it. It would be consistent with your idea to replace the
suspendedStart->completed state change with suspendedStart->executing.

Anyway—let's not remove suspendedStart unless we really mean to remove
the special state that new generators start in. The purpose of
[[GeneratorState]] is partly expository.


More information about the es-discuss mailing list