summaryrefslogtreecommitdiff
path: root/js/src/frontend/BytecodeEmitter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'js/src/frontend/BytecodeEmitter.cpp')
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp77
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))