diff options
Diffstat (limited to 'js/src/frontend')
-rw-r--r-- | js/src/frontend/BytecodeCompiler.cpp | 2 | ||||
-rw-r--r-- | js/src/frontend/BytecodeEmitter.cpp | 23 | ||||
-rw-r--r-- | js/src/frontend/Parser.cpp | 54 | ||||
-rw-r--r-- | js/src/frontend/SharedContext.h | 4 |
4 files changed, 44 insertions, 39 deletions
diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index a1abbfeda..7760c4b2e 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -727,5 +727,5 @@ frontend::CompileStandaloneAsyncFunction(JSContext* cx, MutableHandleFunction fu BytecodeCompiler compiler(cx, cx->tempLifoAlloc(), options, srcBuf, emptyGlobalScope, TraceLogger_ParserCompileFunction); - return compiler.compileStandaloneFunction(fun, StarGenerator, AsyncFunction, parameterListEnd); + return compiler.compileStandaloneFunction(fun, NotGenerator, AsyncFunction, parameterListEnd); } diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 4dc4914dc..b8a9bdf7e 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -8443,7 +8443,8 @@ BytecodeEmitter::emitReturn(ParseNode* pn) if (!updateSourceCoordNotes(pn->pn_pos.begin)) return false; - if (sc->isFunctionBox() && sc->asFunctionBox()->isStarGenerator()) { + bool needsIteratorResult = sc->isFunctionBox() && sc->asFunctionBox()->needsIteratorResult(); + if (needsIteratorResult) { if (!emitPrepareIteratorResult()) return false; } @@ -8458,7 +8459,7 @@ BytecodeEmitter::emitReturn(ParseNode* pn) return false; } - if (sc->isFunctionBox() && sc->asFunctionBox()->isStarGenerator()) { + if (needsIteratorResult) { if (!emitFinishIteratorResult(true)) return false; } @@ -8530,7 +8531,8 @@ BytecodeEmitter::emitYield(ParseNode* pn) MOZ_ASSERT(sc->isFunctionBox()); if (pn->getOp() == JSOP_YIELD) { - if (sc->asFunctionBox()->isStarGenerator()) { + bool needsIteratorResult = sc->asFunctionBox()->needsIteratorResult(); + if (needsIteratorResult) { if (!emitPrepareIteratorResult()) return false; } @@ -8541,7 +8543,7 @@ BytecodeEmitter::emitYield(ParseNode* pn) if (!emit1(JSOP_UNDEFINED)) return false; } - if (sc->asFunctionBox()->isStarGenerator()) { + if (needsIteratorResult) { if (!emitFinishIteratorResult(false)) return false; } @@ -10319,14 +10321,19 @@ BytecodeEmitter::emitFunctionBody(ParseNode* funBody) if (funbox->needsFinalYield()) { // If we fall off the end of a generator, do a final yield. - if (funbox->isStarGenerator() && !emitPrepareIteratorResult()) - return false; + bool needsIteratorResult = funbox->needsIteratorResult(); + if (needsIteratorResult) { + if (!emitPrepareIteratorResult()) + return false; + } if (!emit1(JSOP_UNDEFINED)) return false; - if (funbox->isStarGenerator() && !emitFinishIteratorResult(true)) - return false; + if (needsIteratorResult) { + if (!emitFinishIteratorResult(true)) + return false; + } if (!emit1(JSOP_SETRVAL)) return false; diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 64b1f22c2..406d37725 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -2474,10 +2474,8 @@ Parser<SyntaxParseHandler>::finishFunction(bool isStandaloneFunction /* = false } static YieldHandling -GetYieldHandling(GeneratorKind generatorKind, FunctionAsyncKind asyncKind) +GetYieldHandling(GeneratorKind generatorKind) { - if (asyncKind == AsyncFunction) - return YieldIsName; if (generatorKind == NotGenerator) return YieldIsName; return YieldIsKeyword; @@ -2541,7 +2539,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun, return null(); funpc.setIsStandaloneFunctionBody(); - YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind); + YieldHandling yieldHandling = GetYieldHandling(generatorKind); AutoAwaitIsKeyword<FullParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction); if (!functionFormalParametersAndBody(InAllowed, yieldHandling, fn, Statement, parameterListEnd, /* isStandaloneFunction = */ true)) @@ -2699,7 +2697,7 @@ Parser<ParseHandler>::functionBody(InHandling inHandling, YieldHandling yieldHan switch (pc->generatorKind()) { case NotGenerator: - MOZ_ASSERT(pc->lastYieldOffset == startYieldOffset); + MOZ_ASSERT_IF(!pc->isAsync(), pc->lastYieldOffset == startYieldOffset); break; case LegacyGenerator: @@ -2715,8 +2713,8 @@ Parser<ParseHandler>::functionBody(InHandling inHandling, YieldHandling yieldHan break; case StarGenerator: - MOZ_ASSERT_IF(!pc->isAsync(), kind != Arrow); - MOZ_ASSERT_IF(!pc->isAsync(), type == StatementListBody); + MOZ_ASSERT(kind != Arrow); + MOZ_ASSERT(type == StatementListBody); break; } @@ -2761,9 +2759,9 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, #endif switch (kind) { case Expression: - flags = (generatorKind == NotGenerator + flags = (generatorKind == NotGenerator && asyncKind == SyncFunction ? JSFunction::INTERPRETED_LAMBDA - : JSFunction::INTERPRETED_LAMBDA_GENERATOR); + : JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC); break; case Arrow: flags = JSFunction::INTERPRETED_LAMBDA_ARROW; @@ -2771,9 +2769,9 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, break; case Method: MOZ_ASSERT(generatorKind == NotGenerator || generatorKind == StarGenerator); - flags = (generatorKind == NotGenerator + flags = (generatorKind == NotGenerator && asyncKind == SyncFunction ? JSFunction::INTERPRETED_METHOD - : JSFunction::INTERPRETED_METHOD_GENERATOR); + : JSFunction::INTERPRETED_METHOD_GENERATOR_OR_ASYNC); allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; case ClassConstructor: @@ -2799,9 +2797,9 @@ Parser<ParseHandler>::newFunction(HandleAtom atom, FunctionSyntaxKind kind, allocKind = gc::AllocKind::FUNCTION_EXTENDED; } #endif - flags = (generatorKind == NotGenerator + flags = (generatorKind == NotGenerator && asyncKind == SyncFunction ? JSFunction::INTERPRETED_NORMAL - : JSFunction::INTERPRETED_GENERATOR); + : JSFunction::INTERPRETED_GENERATOR_OR_ASYNC); } // We store the async wrapper in a slot for later access. @@ -3324,7 +3322,6 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand bool tryAnnexB /* = false */) { MOZ_ASSERT_IF(kind == Statement, funName); - MOZ_ASSERT_IF(asyncKind == AsyncFunction, generatorKind == StarGenerator); // When fully parsing a LazyScript, we do not fully reparse its inner // functions, which are also lazy. Instead, their free variables and @@ -3336,7 +3333,7 @@ Parser<ParseHandler>::functionDefinition(uint32_t toStringStart, Node pn, InHand } RootedObject proto(context); - if (generatorKind == StarGenerator) { + if (generatorKind == StarGenerator || asyncKind == AsyncFunction) { // If we are off the main thread, the generator meta-objects have // already been created by js::StartOffThreadParseScript, so cx will not // be necessary. @@ -3408,7 +3405,7 @@ Parser<FullParseHandler>::trySyntaxParseInnerFunction(ParseNode* pn, HandleFunct // parse to avoid the overhead of a lazy syntax-only parse. Although // the prediction may be incorrect, IIFEs are common enough that it // pays off for lots of code. - if (pn->isLikelyIIFE() && generatorKind == NotGenerator) + if (pn->isLikelyIIFE() && generatorKind == NotGenerator && asyncKind == SyncFunction) break; Parser<SyntaxParseHandler>* parser = handler.syntaxParser; @@ -3584,7 +3581,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict if (!tokenStream.peekTokenPos(&pn->pn_pos, modifier)) return null(); - YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind); + YieldHandling yieldHandling = GetYieldHandling(generatorKind); FunctionSyntaxKind syntaxKind = Statement; if (fun->isClassConstructor()) syntaxKind = ClassConstructor; @@ -3665,7 +3662,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, return false; uint32_t openedPos = 0; if (tt != TOK_LC) { - if ((funbox->isStarGenerator() && !funbox->isAsync()) || kind == Method || + if (funbox->isStarGenerator() || kind == Method || kind == GetterNoExpressionClosure || kind == SetterNoExpressionClosure || IsConstructorKind(kind)) { error(JSMSG_CURLY_BEFORE_BODY); @@ -3695,7 +3692,7 @@ Parser<ParseHandler>::functionFormalParametersAndBody(InHandling inHandling, // whether the arrow function is enclosed in a generator function or not. // Whereas the |yield| in the function body is always parsed as a name. // The same goes when parsing |await| in arrow functions. - YieldHandling bodyYieldHandling = GetYieldHandling(pc->generatorKind(), pc->asyncKind()); + YieldHandling bodyYieldHandling = GetYieldHandling(pc->generatorKind()); Node body; { AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, funbox->isAsync()); @@ -3786,7 +3783,7 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa if (!tokenStream.getToken(&tt)) return null(); - GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator; + GeneratorKind generatorKind = NotGenerator; if (tt == TOK_MUL) { if (asyncKind != SyncFunction) { error(JSMSG_ASYNC_GENERATOR); @@ -3817,7 +3814,7 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label); MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind())); - if (!pc->sc()->strict() && generatorKind == NotGenerator) { + if (!pc->sc()->strict() && generatorKind == NotGenerator && asyncKind == SyncFunction) { // In sloppy mode, try Annex B.3.3 semantics. If making an // additional 'var' binding of the same name does not throw an // early error, do so. This 'var' binding would be assigned @@ -3841,7 +3838,7 @@ Parser<ParseHandler>::functionStmt(uint32_t toStringStart, YieldHandling yieldHa if (!pn) return null(); - YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind); + YieldHandling newYieldHandling = GetYieldHandling(generatorKind); return functionDefinition(toStringStart, pn, InAllowed, newYieldHandling, name, Statement, generatorKind, asyncKind, tryAnnexB); } @@ -3854,7 +3851,7 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_FUNCTION)); AutoAwaitIsKeyword<ParseHandler> awaitIsKeyword(this, asyncKind == AsyncFunction); - GeneratorKind generatorKind = asyncKind == AsyncFunction ? StarGenerator : NotGenerator; + GeneratorKind generatorKind = NotGenerator; TokenKind tt; if (!tokenStream.getToken(&tt)) return null(); @@ -3869,7 +3866,7 @@ Parser<ParseHandler>::functionExpr(uint32_t toStringStart, InvokedPrediction inv return null(); } - YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind); + YieldHandling yieldHandling = GetYieldHandling(generatorKind); RootedPropertyName name(context); if (TokenKindIsPossibleIdentifier(tt)) { @@ -8187,7 +8184,6 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl uint32_t toStringStart = pos().begin; tokenStream.ungetToken(); - GeneratorKind generatorKind = NotGenerator; FunctionAsyncKind asyncKind = SyncFunction; if (next == TOK_ASYNC) { @@ -8200,7 +8196,6 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl if (nextSameLine == TOK_ARROW) { tokenStream.ungetToken(); } else { - generatorKind = StarGenerator; asyncKind = AsyncFunction; } } @@ -8210,7 +8205,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl return null(); Node arrowFunc = functionDefinition(toStringStart, pn, inHandling, yieldHandling, nullptr, - Arrow, generatorKind, asyncKind); + Arrow, NotGenerator, asyncKind); if (!arrowFunc) return null(); @@ -9950,8 +9945,7 @@ Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType prop MOZ_CRASH("Parser: methodDefinition: unexpected property type"); } - GeneratorKind generatorKind = (propType == PropertyType::GeneratorMethod || - propType == PropertyType::AsyncMethod) + GeneratorKind generatorKind = propType == PropertyType::GeneratorMethod ? StarGenerator : NotGenerator; @@ -9959,7 +9953,7 @@ Parser<ParseHandler>::methodDefinition(uint32_t toStringStart, PropertyType prop ? AsyncFunction : SyncFunction; - YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind); + YieldHandling yieldHandling = GetYieldHandling(generatorKind); Node pn = handler.newFunctionExpression(); if (!pn) diff --git a/js/src/frontend/SharedContext.h b/js/src/frontend/SharedContext.h index 5766c135a..2d478308e 100644 --- a/js/src/frontend/SharedContext.h +++ b/js/src/frontend/SharedContext.h @@ -552,6 +552,10 @@ class FunctionBox : public ObjectBox, public SharedContext return isStarGenerator() || isLegacyGenerator() || isAsync(); } + bool needsIteratorResult() const { + return isStarGenerator() || isAsync(); + } + bool isAsync() const { return asyncKind() == AsyncFunction; } bool isArrow() const { return function()->isArrow(); } |