diff options
Diffstat (limited to 'js/src/frontend/BytecodeEmitter.cpp')
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 77 |
1 files changed, 49 insertions, 28 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 6a6deed12f..77a480bff6 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -3175,10 +3175,11 @@ BytecodeEmitter::checkSideEffects(ParseNode* pn, bool* answer) *answer = true; return true; + case PNK_INITIALYIELD: case PNK_YIELD_STAR: case PNK_YIELD: case PNK_AWAIT: - MOZ_ASSERT(pn->isArity(PN_BINARY)); + MOZ_ASSERT(pn->isArity(PN_UNARY)); *answer = true; return true; @@ -8526,45 +8527,61 @@ BytecodeEmitter::emitReturn(ParseNode* pn) } bool +BytecodeEmitter::emitGetDotGenerator() +{ + NameLocation loc = *locationOfNameBoundInFunctionScope(cx->names().dotGenerator); + return emitGetNameAtLocation(cx->names().dotGenerator, loc); +} + +bool +BytecodeEmitter::emitInitialYield(ParseNode* pn) +{ + if (!emitTree(pn->pn_kid)) + return false; + + if (!emitYieldOp(JSOP_INITIALYIELD)) + return false; + + if (!emit1(JSOP_POP)) + return false; + + return true; +} + +bool BytecodeEmitter::emitYield(ParseNode* pn) { MOZ_ASSERT(sc->isFunctionBox()); + MOZ_ASSERT(pn->getOp() == JSOP_YIELD || pn->getOp() == JSOP_AWAIT); - if (pn->getOp() == JSOP_YIELD || pn->getOp() == JSOP_AWAIT) { - bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult(); - if (needsIteratorResult) { - if (!emitPrepareIteratorResult()) - return false; - } - if (pn->pn_left) { - if (!emitTree(pn->pn_left)) - return false; - } else { - if (!emit1(JSOP_UNDEFINED)) - return false; - } - if (needsIteratorResult) { - if (!emitFinishIteratorResult(false)) - return false; - } + bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult(); + if (needsIteratorResult) { + if (!emitPrepareIteratorResult()) + return false; + } + if (pn->pn_kid) { + if (!emitTree(pn->pn_kid)) + return false; } else { - MOZ_ASSERT(pn->getOp() == JSOP_INITIALYIELD); + if (!emit1(JSOP_UNDEFINED)) + return false; + } + if (needsIteratorResult) { + if (!emitFinishIteratorResult(false)) + return false; } - if (!emitTree(pn->pn_right)) + if (!emitGetDotGenerator()) return false; if (!emitYieldOp(pn->getOp())) return false; - if (pn->getOp() == JSOP_INITIALYIELD && !emit1(JSOP_POP)) - return false; - return true; } bool -BytecodeEmitter::emitYieldStar(ParseNode* iter, ParseNode* gen) +BytecodeEmitter::emitYieldStar(ParseNode* iter) { MOZ_ASSERT(sc->isFunctionBox()); MOZ_ASSERT(sc->asFunctionBox()->isStarGenerator()); @@ -8594,7 +8611,7 @@ BytecodeEmitter::emitYieldStar(ParseNode* iter, ParseNode* gen) MOZ_ASSERT(this->stackDepth == startDepth); // Load the generator object. - if (!emitTree(gen)) // ITER RESULT GENOBJ + if (!emitGetDotGenerator()) // ITER RESULT GENOBJ return false; // Yield RESULT as-is, without re-boxing. @@ -10338,8 +10355,7 @@ BytecodeEmitter::emitFunctionBody(ParseNode* funBody) if (!emit1(JSOP_SETRVAL)) return false; - NameLocation loc = *locationOfNameBoundInFunctionScope(cx->names().dotGenerator); - if (!emitGetNameAtLocation(cx->names().dotGenerator, loc)) + if (!emitGetDotGenerator()) return false; // No need to check for finally blocks, etc as in EmitReturn. @@ -10599,7 +10615,7 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage:: break; case PNK_YIELD_STAR: - if (!emitYieldStar(pn->pn_left, pn->pn_right)) + if (!emitYieldStar(pn->pn_kid)) return false; break; @@ -10608,6 +10624,11 @@ BytecodeEmitter::emitTree(ParseNode* pn, ValueUsage valueUsage /* = ValueUsage:: return false; break; + case PNK_INITIALYIELD: + if (!emitInitialYield(pn)) + return false; + break; + case PNK_YIELD: case PNK_AWAIT: if (!emitYield(pn)) |