yield * broken for Firefox < 45 #274
Comments
Thanks for the in-depth analysis, @AnilRedshift! Rather than browser detection, I would prefer to detect this specific (mis)feature, and then polyfill I may be making a silly mistake, but I'm not able to reproduce the problem using your reproduction in the Regenerator sandbox in Firefox 44. What version of Regenerator are you using? Does other code have to run first to cause the problem to appear? |
Hmm, the repro is pretty consistent for us here. This is what I've been using to debug: It consists of just running regenerator --include-runtime and then hooking that up to a simple html file.
Using https://ftp.mozilla.org/pub/firefox/releases/44.0/Firefox-44.0.en-US.mac-x86_64.sdk.tar.bz2 to test. |
I'm also able to reproduce this in Firefox 42 with the above code, but not in the sandbox page, which is a little odd to me. There's nothing else loading in the test page other than the regenerator runtime. (I'm also running into this in a big way in one of my projects). Stepping through the code, I've noticed the following happening:
If I hack the function tryCatch(fn, obj, arg) {
try {
var newarg = fn.call(obj, arg);
if (newarg && newarg.value && newarg.value.hasOwnProperty('value')) {
newarg.done = newarg.value.done;
newarg.value = newarg.value.value;
}
return { type: "normal", arg: newarg };
} catch (err) {
return { type: "throw", arg: err };
}
} then things work as expected, but this is obviously just masking the problem, not getting to the root of it. Hope this is somehow helpful. I'd be glad to help further to get to the bottom of this however I can. |
For folks hitting this bug, this is the quick workaround we did in the meantime:
Running that script before including the babel-polyfill causes babel to polyfill all things related to symbols, including iterators. It's definitely a crude approach, but it is effective. |
A bit more info on this -- try running the browser tests (from
I should have a PR coming shortly with what appears to be a fix using specific (mis)feature-detection. I say "appears" because it makes the browser tests pass in FF 42, at least :) |
So this is a fun bug.
Try running this code through regenerator on FF 44 or below:
You'll note that the generator never reports
done
as true. Here are the notes from my investigation. I am not 100% of the reason because some of the macro code in gecko is not easy to parse.next()
working in order to iterate through the delegatewhere iteratorSymbol in this case is
Symbol.iterator
5. The scene is almost set.
wrap
uses theGenerator.prototype
to create its functions:So, putting it all together, this is what I believe happens:
Due to the bad Generator prototype, firefox decides that the code trying to get the iterator in
values()
is legacy and shoves it down the legacy iterator codepath. This means thatnext
will ALWAYS returndone: false
unless aStopIteration
exception is thrown.The current code does not do such a thing and therefore the generator never ends. It just keeps on going on my friends....
So: What's the fix? It looks like you have a few options:
next()
and related iterator methods for these builds of firefox (note that is what we chose to do to fix this bug)StopIteration
exception insteadtl;dr:
yield *
never worked on at the very least Firefox 44 and probably several builds earlier than that. It's a comedy of browser issues that you now get to work around. Thanks!The text was updated successfully, but these errors were encountered: