diff --git a/js/src/jit-test/tests/basic/bug885648.js b/js/src/jit-test/tests/basic/bug885648.js new file mode 100644 index 00000000000..60816962cae --- /dev/null +++ b/js/src/jit-test/tests/basic/bug885648.js @@ -0,0 +1,9 @@ +gczeal(4,1); +var iterable = {persistedProp: 17}; +iterable.__iterator__ = function() { + yield ["foo", 2]; + yield ["bar", 3]; +}; +var it = Iterator(iterable); +assertEq(it.next().toString(), "foo,2"); +assertEq(it.next().toString(), "bar,3"); diff --git a/js/src/jsiter.cpp b/js/src/jsiter.cpp index b2101a2c830..18f088c43d1 100644 --- a/js/src/jsiter.cpp +++ b/js/src/jsiter.cpp @@ -1418,11 +1418,6 @@ GeneratorState::pushInterpreterFrame(JSContext *cx, FrameGuard *) * or else some kind of epoch scheme would have to be used. */ GeneratorWriteBarrierPre(cx, gen_); - - /* - * Don't change the state until after the frame is successfully pushed - * or else we might fail to scan some generator values. - */ gen_->state = futureState_; gen_->fp->clearSuspended(); @@ -1561,9 +1556,12 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, HandleObject obj, if (gen->state == JSGEN_OPEN) { /* * Store the argument to send as the result of the yield - * expression. + * expression. The generator stack is not barriered, so we need + * write barriers here. */ + HeapValue::writeBarrierPre(gen->regs.sp[-1]); gen->regs.sp[-1] = arg; + HeapValue::writeBarrierPost(cx->runtime(), gen->regs.sp[-1], &gen->regs.sp[-1]); } futureState = JSGEN_RUNNING; break;