diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 5adbf9f066..6e52fbad77 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -5735,7 +5735,7 @@ BytecodeEmitter::emitFunction(FunctionNode* funNode, bool needsProto) /* Non-hoisted functions simply emit their respective op. */ if (!funNode->functionIsHoisted()) { /* JSOP_LAMBDA_ARROW is always preceded by a new.target */ - MOZ_ASSERT(fun->isArrow() == (funNode->getOp() == JSOP_LAMBDA_ARROW)); + MOZ_ASSERT(fun->isArrow() == (funNode->syntaxKind() == FunctionSyntaxKind::Arrow)); if (funbox->isAsync()) { MOZ_ASSERT(!needsProto); return emitAsyncWrapper(index, funbox->needsHomeObject(), fun->isArrow(), @@ -5753,13 +5753,16 @@ BytecodeEmitter::emitFunction(FunctionNode* funNode, bool needsProto) } if (needsProto) { - MOZ_ASSERT(funNode->getOp() == JSOP_LAMBDA); + MOZ_ASSERT(funNode->syntaxKind() == FunctionSyntaxKind::DerivedClassConstructor); return emitIndex32(JSOP_FUNWITHPROTO, index); } // This is a FunctionExpression, ArrowFunctionExpression, or class // constructor. Emit the single instruction (without location info). - return emitIndex32(funNode->getOp(), index); + JSOp op = funNode->syntaxKind() == FunctionSyntaxKind::Arrow + ? JSOP_LAMBDA_ARROW + : JSOP_LAMBDA; + return emitIndex32(op, index); } MOZ_ASSERT(!needsProto); @@ -5787,7 +5790,7 @@ BytecodeEmitter::emitFunction(FunctionNode* funNode, bool needsProto) return false; } else { MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext()); - MOZ_ASSERT(funNode->getOp() == JSOP_NOP); + MOZ_ASSERT(funNode->syntaxKind() == FunctionSyntaxKind::Statement); switchToPrologue(); if (funbox->isAsync()) { if (!emitAsyncWrapper(index, fun->isMethod(), fun->isArrow(), diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h index 8af543fc45..ab01fa83ef 100644 --- a/js/src/frontend/FullParseHandler.h +++ b/js/src/frontend/FullParseHandler.h @@ -722,16 +722,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) pn->setDirectRHSAnonFunction(true); } - FunctionNodeType newFunctionStatement() { - return new_(JSOP_NOP, pos()); - } - - FunctionNodeType newFunctionExpression() { - return new_(JSOP_LAMBDA, pos()); - } - - FunctionNodeType newArrowFunction() { - return new_(JSOP_LAMBDA_ARROW, pos()); + FunctionNodeType newFunction(FunctionSyntaxKind syntaxKind) { + return new_(syntaxKind, pos()); } bool setComprehensionLambdaBody(FunctionNodeType funNode, ListNodeType body) { diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index a31e9d3731..50fe44074a 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -227,6 +227,7 @@ IsTypeofKind(ParseNodeKind kind) * time to specialize arg and var bytecodes early. * body: PNK_PARAMSBODY or null for lazily-parsed function, ordinarily; * PNK_LEXICALSCOPE for implicit function in genexpr + * syntaxKind: the syntax of the function * PNK_PARAMSBODY (ListNode) * head: list of formal parameters with * * Name node with non-empty name for SingleNameBinding without @@ -606,6 +607,49 @@ class typeName; FOR_EACH_PARSENODE_SUBCLASS(DECLARE_CLASS) #undef DECLARE_CLASS +enum class FunctionSyntaxKind +{ + Expression, // A non-arrow function expression. + Statement, // A named function appearing as a Statement. + Arrow, + Method, + ClassConstructor, + DerivedClassConstructor, + Getter, + GetterNoExpressionClosure, // Deprecated syntax: get a() this._a; (bug 1203742) + Setter, + SetterNoExpressionClosure // Deprecated syntax: set a(x) this._a = x; +}; + +static inline bool +IsConstructorKind(FunctionSyntaxKind kind) +{ + return kind == FunctionSyntaxKind::ClassConstructor || + kind == FunctionSyntaxKind::DerivedClassConstructor; +} + +static inline bool +IsGetterKind(FunctionSyntaxKind kind) +{ + return kind == FunctionSyntaxKind::Getter || + kind == FunctionSyntaxKind::GetterNoExpressionClosure; +} + +static inline bool +IsSetterKind(FunctionSyntaxKind kind) +{ + return kind == FunctionSyntaxKind::Setter || + kind == FunctionSyntaxKind::SetterNoExpressionClosure; +} + +static inline bool +IsMethodDefinitionKind(FunctionSyntaxKind kind) +{ + return kind == FunctionSyntaxKind::Method || + IsConstructorKind(kind) || + IsGetterKind(kind) || IsSetterKind(kind); +} + class ParseNode { uint16_t pn_type; /* PNK_* type */ @@ -738,6 +782,7 @@ class ParseNode friend class FunctionNode; FunctionBox* funbox; ParseNode* body; + FunctionSyntaxKind syntaxKind; } function; struct { private: @@ -1427,14 +1472,12 @@ ParseNode::isForLoopDeclaration() const class FunctionNode : public ParseNode { public: - FunctionNode(JSOp op, const TokenPos& pos) - : ParseNode(PNK_FUNCTION, op, PN_FUNCTION, pos) + FunctionNode(FunctionSyntaxKind syntaxKind, const TokenPos& pos) + : ParseNode(PNK_FUNCTION, JSOP_NOP, PN_FUNCTION, pos) { - MOZ_ASSERT(op == JSOP_NOP || // statement, module - op == JSOP_LAMBDA_ARROW || // arrow function - op == JSOP_LAMBDA); // expression, method, comprehension, accessor, &c. MOZ_ASSERT(!pn_u.function.body); MOZ_ASSERT(!pn_u.function.funbox); + pn_u.function.syntaxKind = syntaxKind; } static bool test(const ParseNode& node) { @@ -1468,11 +1511,10 @@ class FunctionNode : public ParseNode return &pn_u.function.body; } + FunctionSyntaxKind syntaxKind() const { return pn_u.function.syntaxKind; } + bool functionIsHoisted() const { - MOZ_ASSERT(isOp(JSOP_LAMBDA) || // lambda - isOp(JSOP_LAMBDA_ARROW) || // arrow function - isOp(JSOP_NOP)); // body-level function stmt in global code - return isOp(JSOP_NOP); + return syntaxKind() == FunctionSyntaxKind::Statement; } }; @@ -2247,45 +2289,6 @@ enum ParseReportKind ParseStrictError }; -enum FunctionSyntaxKind -{ - Expression, - Statement, - Arrow, - Method, - ClassConstructor, - DerivedClassConstructor, - Getter, - GetterNoExpressionClosure, - Setter, - SetterNoExpressionClosure -}; - -static inline bool -IsConstructorKind(FunctionSyntaxKind kind) -{ - return kind == ClassConstructor || kind == DerivedClassConstructor; -} - -static inline bool -IsGetterKind(FunctionSyntaxKind kind) -{ - return kind == Getter || kind == GetterNoExpressionClosure; -} - -static inline bool -IsSetterKind(FunctionSyntaxKind kind) -{ - return kind == Setter || kind == SetterNoExpressionClosure; -} - -static inline bool -IsMethodDefinitionKind(FunctionSyntaxKind kind) -{ - return kind == Method || IsConstructorKind(kind) || - IsGetterKind(kind) || IsSetterKind(kind); -} - static inline ParseNode* FunctionFormalParametersList(ParseNode* fn, unsigned* numFormals) { diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index e40e583745..1f92256a33 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -560,12 +560,12 @@ FunctionBox::initWithEnclosingParseContext(ParseContext* enclosing, FunctionSynt allowNewTarget_ = true; allowSuperProperty_ = fun->allowSuperProperty(); - if (kind == ClassConstructor || kind == DerivedClassConstructor) { + if (IsConstructorKind(kind)) { auto stmt = enclosing->findInnermostStatement(); MOZ_ASSERT(stmt); stmt->constructorBox = this; - if (kind == DerivedClassConstructor) { + if (kind == FunctionSyntaxKind::DerivedClassConstructor) { setDerivedClassConstructor(); allowSuperCall_ = true; needsThisTDZChecks_ = true; @@ -2547,7 +2547,7 @@ Parser::standaloneFunction(HandleFunction fun, tokenStream.ungetToken(); } - FunctionNodeType funNode = handler.newFunctionStatement(); + FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Statement); if (!funNode) return null(); @@ -2569,7 +2569,7 @@ Parser::standaloneFunction(HandleFunction fun, YieldHandling yieldHandling = GetYieldHandling(generatorKind); AutoAwaitIsKeyword awaitIsKeyword(this, asyncKind == AsyncFunction); - if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, Statement, + if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, FunctionSyntaxKind::Statement, parameterListEnd, /* isStandaloneFunction = */ true)) { return null(); @@ -2734,16 +2734,16 @@ Parser::functionBody(InHandling inHandling, YieldHandling yieldHan MOZ_ASSERT(pc->lastYieldOffset != startYieldOffset); // These should throw while parsing the yield expression. - MOZ_ASSERT(kind != Arrow); + MOZ_ASSERT(kind != FunctionSyntaxKind::Arrow); MOZ_ASSERT(!IsGetterKind(kind)); MOZ_ASSERT(!IsSetterKind(kind)); MOZ_ASSERT(!IsConstructorKind(kind)); - MOZ_ASSERT(kind != Method); + MOZ_ASSERT(kind != FunctionSyntaxKind::Method); MOZ_ASSERT(type != ExpressionBody); break; case StarGenerator: - MOZ_ASSERT(kind != Arrow); + MOZ_ASSERT(kind != FunctionSyntaxKind::Arrow); MOZ_ASSERT(type == StatementListBody); break; } @@ -2762,7 +2762,7 @@ Parser::functionBody(InHandling inHandling, YieldHandling yieldHan // Declare the 'arguments' and 'this' bindings if necessary before // finishing up the scope so these special bindings get marked as closed // over if necessary. Arrow functions don't have these bindings. - if (kind != Arrow) { + if (kind != FunctionSyntaxKind::Arrow) { if (!declareFunctionArgumentsObject()) return null(); if (!declareFunctionThis()) @@ -2778,7 +2778,7 @@ Parser::newFunction(HandleAtom atom, FunctionSyntaxKind kind, GeneratorKind generatorKind, FunctionAsyncKind asyncKind, HandleObject proto) { - MOZ_ASSERT_IF(kind == Statement, atom != nullptr); + MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, atom != nullptr); RootedFunction fun(context); @@ -2788,39 +2788,39 @@ Parser::newFunction(HandleAtom atom, FunctionSyntaxKind kind, bool isGlobalSelfHostedBuiltin = false; #endif switch (kind) { - case Expression: + case FunctionSyntaxKind::Expression: flags = (generatorKind == NotGenerator && asyncKind == SyncFunction ? JSFunction::INTERPRETED_LAMBDA : JSFunction::INTERPRETED_LAMBDA_GENERATOR_OR_ASYNC); break; - case Arrow: + case FunctionSyntaxKind::Arrow: flags = JSFunction::INTERPRETED_LAMBDA_ARROW; allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; - case Method: + case FunctionSyntaxKind::Method: MOZ_ASSERT(generatorKind == NotGenerator || generatorKind == StarGenerator); flags = (generatorKind == NotGenerator && asyncKind == SyncFunction ? JSFunction::INTERPRETED_METHOD : JSFunction::INTERPRETED_METHOD_GENERATOR_OR_ASYNC); allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; - case ClassConstructor: - case DerivedClassConstructor: + case FunctionSyntaxKind::ClassConstructor: + case FunctionSyntaxKind::DerivedClassConstructor: flags = JSFunction::INTERPRETED_CLASS_CONSTRUCTOR; allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; - case Getter: - case GetterNoExpressionClosure: + case FunctionSyntaxKind::Getter: + case FunctionSyntaxKind::GetterNoExpressionClosure: flags = JSFunction::INTERPRETED_GETTER; allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; - case Setter: - case SetterNoExpressionClosure: + case FunctionSyntaxKind::Setter: + case FunctionSyntaxKind::SetterNoExpressionClosure: flags = JSFunction::INTERPRETED_SETTER; allocKind = gc::AllocKind::FUNCTION_EXTENDED; break; default: - MOZ_ASSERT(kind == Statement); + MOZ_ASSERT(kind == FunctionSyntaxKind::Statement); #ifdef DEBUG if (options().selfHostingMode && !pc->isFunctionBox()) { isGlobalSelfHostedBuiltin = true; @@ -2989,7 +2989,7 @@ Parser::functionArguments(YieldHandling yieldHandling, FunctionSyn // async a => 1 // ^ TokenStream::Modifier argModifier = TokenStream::Operand; - if (kind == Arrow) { + if (kind == FunctionSyntaxKind::Arrow) { TokenKind tt; // In async function, the first token after `async` is already gotten // with TokenStream::None. @@ -3008,7 +3008,7 @@ Parser::functionArguments(YieldHandling yieldHandling, FunctionSyn if (!tokenStream.getToken(&tt, firstTokenModifier)) return false; if (tt != TOK_LP) { - error(kind == Arrow ? JSMSG_BAD_ARROW_ARGS : JSMSG_PAREN_BEFORE_FORMAL); + error(kind == FunctionSyntaxKind::Arrow ? JSMSG_BAD_ARROW_ARGS : JSMSG_PAREN_BEFORE_FORMAL); return false; } @@ -3036,7 +3036,9 @@ Parser::functionArguments(YieldHandling yieldHandling, FunctionSyn bool hasRest = false; bool hasDefault = false; bool duplicatedParam = false; - bool disallowDuplicateParams = kind == Arrow || kind == Method || kind == ClassConstructor; + bool disallowDuplicateParams = kind == FunctionSyntaxKind::Arrow || + kind == FunctionSyntaxKind::Method || + kind == FunctionSyntaxKind::ClassConstructor; AtomVector& positionalFormals = pc->positionalFormalParameterNames(); if (IsGetterKind(kind)) { @@ -3257,7 +3259,7 @@ Parser::skipLazyInnerFunction(FunctionNode* funNode, uint32_t // Only expression closure can be Statement kind. // If we remove expression closure, we can remove isExprBody flag from // LazyScript and JSScript. - if (kind == Statement && funbox->isExprBody()) { + if (kind == FunctionSyntaxKind::Statement && funbox->isExprBody()) { if (!matchOrInsertSemicolonAfterExpression()) return false; } @@ -3351,7 +3353,7 @@ Parser::functionDefinition(uint32_t toStringStart, FunctionNodeTyp GeneratorKind generatorKind, FunctionAsyncKind asyncKind, bool tryAnnexB /* = false */) { - MOZ_ASSERT_IF(kind == Statement, funName); + MOZ_ASSERT_IF(kind == FunctionSyntaxKind::Statement, funName); // When fully parsing a LazyScript, we do not fully reparse its inner // functions, which are also lazy. Instead, their free variables and @@ -3586,7 +3588,20 @@ Parser::standaloneLazyFunction(HandleFunction fun, bool strict { MOZ_ASSERT(checkOptionsCalled); - FunctionNodeType funNode = handler.newFunctionStatement(); + FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement; + if (fun->isClassConstructor()) { + syntaxKind = FunctionSyntaxKind::ClassConstructor; + } else if (fun->isMethod()) { + syntaxKind = FunctionSyntaxKind::Method; + } else if (fun->isGetter()) { + syntaxKind = FunctionSyntaxKind::Getter; + } else if (fun->isSetter()) { + syntaxKind = FunctionSyntaxKind::Setter; + } else if (fun->isArrow()) { + syntaxKind = FunctionSyntaxKind::Arrow; + } + + FunctionNodeType funNode = handler.newFunction(syntaxKind); if (!funNode) return null(); @@ -3613,17 +3628,6 @@ Parser::standaloneLazyFunction(HandleFunction fun, bool strict return null(); YieldHandling yieldHandling = GetYieldHandling(generatorKind); - FunctionSyntaxKind syntaxKind = Statement; - if (fun->isClassConstructor()) - syntaxKind = ClassConstructor; - else if (fun->isMethod()) - syntaxKind = Method; - else if (fun->isGetter()) - syntaxKind = Getter; - else if (fun->isSetter()) - syntaxKind = Setter; - else if (fun->isArrow()) - syntaxKind = Arrow; if (!functionFormalParametersAndBody(InAllowed, yieldHandling, funNode, syntaxKind)) { MOZ_ASSERT(directives == newDirectives); @@ -3656,7 +3660,8 @@ Parser::functionFormalParametersAndBody(InHandling inHandling, // See below for an explanation why arrow function parameters and arrow // function bodies are parsed with different yield/await settings. { - bool asyncOrArrowInAsync = funbox->isAsync() || (kind == Arrow && awaitIsKeyword()); + bool asyncOrArrowInAsync = funbox->isAsync() || + (kind == FunctionSyntaxKind::Arrow && awaitIsKeyword()); AutoAwaitIsKeyword awaitIsKeyword(this, asyncOrArrowInAsync); if (!functionArguments(yieldHandling, kind, funNode)) return false; @@ -3671,7 +3676,7 @@ Parser::functionFormalParametersAndBody(InHandling inHandling, pc->functionScope().useAsVarScope(pc); } - if (kind == Arrow) { + if (kind == FunctionSyntaxKind::Arrow) { bool matched; if (!tokenStream.matchToken(&matched, TOK_ARROW)) return false; @@ -3695,14 +3700,15 @@ Parser::functionFormalParametersAndBody(InHandling inHandling, return false; uint32_t openedPos = 0; if (tt != TOK_LC) { - if (funbox->isStarGenerator() || kind == Method || - kind == GetterNoExpressionClosure || kind == SetterNoExpressionClosure || + if (funbox->isStarGenerator() || kind == FunctionSyntaxKind::Method || + kind == FunctionSyntaxKind::GetterNoExpressionClosure || + kind == FunctionSyntaxKind::SetterNoExpressionClosure || IsConstructorKind(kind)) { error(JSMSG_CURLY_BEFORE_BODY); return false; } - if (kind != Arrow) { + if (kind != FunctionSyntaxKind::Arrow) { #if JS_HAS_EXPR_CLOSURES if (!warnOnceAboutExprClosure()) return false; @@ -3734,10 +3740,11 @@ Parser::functionFormalParametersAndBody(InHandling inHandling, return false; } - if ((kind == Statement || kind == Expression) && fun->explicitName()) { + if ((kind == FunctionSyntaxKind::Statement || + kind == FunctionSyntaxKind::Expression) && fun->explicitName()) { RootedPropertyName propertyName(context, fun->explicitName()->asPropertyName()); YieldHandling nameYieldHandling; - if (kind == Expression) { + if (kind == FunctionSyntaxKind::Expression) { // Named lambda has binding inside it. nameYieldHandling = bodyYieldHandling; } else { @@ -3765,12 +3772,12 @@ Parser::functionFormalParametersAndBody(InHandling inHandling, funbox->setEnd(pos().end); } else { #if !JS_HAS_EXPR_CLOSURES - MOZ_ASSERT(kind == Arrow); + MOZ_ASSERT(kind == FunctionSyntaxKind::Arrow); #endif if (tokenStream.hadError()) return false; funbox->setEnd(pos().end); - if (kind == Statement && !matchOrInsertSemicolonAfterExpression()) + if (kind == FunctionSyntaxKind::Statement && !matchOrInsertSemicolonAfterExpression()) return false; } @@ -3864,13 +3871,14 @@ Parser::functionStmt(uint32_t toStringStart, YieldHandling yieldHa return null(); } - FunctionNodeType funNode = handler.newFunctionStatement(); + FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Statement); if (!funNode) return null(); YieldHandling newYieldHandling = GetYieldHandling(generatorKind); return functionDefinition(toStringStart, funNode, InAllowed, newYieldHandling, - name, Statement, generatorKind, asyncKind, tryAnnexB); + name, FunctionSyntaxKind::Statement, generatorKind, + asyncKind, tryAnnexB); } template @@ -3903,15 +3911,15 @@ Parser::functionExpr(uint32_t toStringStart, InvokedPrediction inv tokenStream.ungetToken(); } - FunctionNodeType funNode = handler.newFunctionExpression(); + FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Expression); if (!funNode) return null(); if (invoked) funNode = handler.setLikelyIIFE(funNode); - return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, name, Expression, - generatorKind, asyncKind); + return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, name, + FunctionSyntaxKind::Expression, generatorKind, asyncKind); } /* @@ -8395,12 +8403,12 @@ Parser::assignExpr(InHandling inHandling, YieldHandling yieldHandl } } - FunctionNodeType funNode = handler.newArrowFunction(); + FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Arrow); if (!funNode) return null(); Node arrowFunc = functionDefinition(toStringStart, funNode, inHandling, yieldHandling, nullptr, - Arrow, NotGenerator, asyncKind); + FunctionSyntaxKind::Arrow, NotGenerator, asyncKind); if (!arrowFunc) return null(); @@ -8792,7 +8800,7 @@ template typename ParseHandler::Node Parser::generatorComprehensionLambda(unsigned begin) { - FunctionNodeType genfn = handler.newFunctionExpression(); + FunctionNodeType genfn = handler.newFunction(FunctionSyntaxKind::Expression); if (!genfn) return null(); @@ -8807,7 +8815,7 @@ Parser::generatorComprehensionLambda(unsigned begin) if (!proto) return null(); - RootedFunction fun(context, newFunction(/* atom = */ nullptr, Expression, + RootedFunction fun(context, newFunction(/* atom = */ nullptr, FunctionSyntaxKind::Expression, StarGenerator, SyncFunction, proto)); if (!fun) return null(); @@ -8819,7 +8827,7 @@ Parser::generatorComprehensionLambda(unsigned begin) if (!genFunbox) return null(); genFunbox->isGenexpLambda = true; - genFunbox->initWithEnclosingParseContext(outerpc, Expression); + genFunbox->initWithEnclosingParseContext(outerpc, FunctionSyntaxKind::Expression); ParseContext genpc(this, genFunbox, /* newDirectives = */ nullptr); if (!genpc.init()) @@ -10316,37 +10324,37 @@ typename ParseHandler::FunctionNodeType Parser::methodDefinition(uint32_t toStringStart, PropertyType propType, HandleAtom funName) { - FunctionSyntaxKind kind; + FunctionSyntaxKind syntaxKind; switch (propType) { case PropertyType::Getter: - kind = Getter; + syntaxKind = FunctionSyntaxKind::Getter; break; case PropertyType::GetterNoExpressionClosure: - kind = GetterNoExpressionClosure; + syntaxKind = FunctionSyntaxKind::GetterNoExpressionClosure; break; case PropertyType::Setter: - kind = Setter; + syntaxKind = FunctionSyntaxKind::Setter; break; case PropertyType::SetterNoExpressionClosure: - kind = SetterNoExpressionClosure; + syntaxKind = FunctionSyntaxKind::SetterNoExpressionClosure; break; case PropertyType::Method: case PropertyType::GeneratorMethod: case PropertyType::AsyncMethod: case PropertyType::AsyncGeneratorMethod: - kind = Method; + syntaxKind = FunctionSyntaxKind::Method; break; case PropertyType::Constructor: - kind = ClassConstructor; + syntaxKind = FunctionSyntaxKind::ClassConstructor; break; case PropertyType::DerivedConstructor: - kind = DerivedClassConstructor; + syntaxKind = FunctionSyntaxKind::DerivedClassConstructor; break; default: @@ -10365,12 +10373,12 @@ Parser::methodDefinition(uint32_t toStringStart, PropertyType prop YieldHandling yieldHandling = GetYieldHandling(generatorKind); - FunctionNodeType funNode = handler.newFunctionExpression(); + FunctionNodeType funNode = handler.newFunction(syntaxKind); if (!funNode) return null(); return functionDefinition(toStringStart, funNode, InAllowed, yieldHandling, funName, - kind, generatorKind, asyncKind); + syntaxKind, generatorKind, asyncKind); } template diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h index a8a8cf49f3..f3591e22ba 100644 --- a/js/src/frontend/SyntaxParseHandler.h +++ b/js/src/frontend/SyntaxParseHandler.h @@ -411,9 +411,7 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS) void checkAndSetIsDirectRHSAnonFunction(Node pn) {} - FunctionNodeType newFunctionStatement() { return NodeFunctionDefinition; } - FunctionNodeType newFunctionExpression() { return NodeFunctionDefinition; } - FunctionNodeType newArrowFunction() { return NodeFunctionDefinition; } + FunctionNodeType newFunction(FunctionSyntaxKind syntaxKind) { return NodeFunctionDefinition; } bool setComprehensionLambdaBody(FunctionNodeType funNode, ListNodeType body) { return true; } void setFunctionFormalParametersAndBody(FunctionNodeType funNode, ListNodeType paramsBody) {} diff --git a/js/src/wasm/AsmJS.cpp b/js/src/wasm/AsmJS.cpp index f139316952..98fcff4203 100644 --- a/js/src/wasm/AsmJS.cpp +++ b/js/src/wasm/AsmJS.cpp @@ -7044,7 +7044,8 @@ ParseFunction(ModuleValidator& m, FunctionNode** funNodeOut, unsigned* line) if (!name) return false; - FunctionNode* funNode = m.parser().handler.newFunctionStatement(); + FunctionSyntaxKind syntaxKind = FunctionSyntaxKind::Statement; + FunctionNode* funNode = m.parser().handler.newFunction(syntaxKind); if (!funNode) return false; @@ -7058,14 +7059,14 @@ ParseFunction(ModuleValidator& m, FunctionNode** funNodeOut, unsigned* line) SyncFunction, /* tryAnnexB = */ false); if (!funbox) return false; - funbox->initWithEnclosingParseContext(outerpc, frontend::Statement); + funbox->initWithEnclosingParseContext(outerpc, syntaxKind); Directives newDirectives = directives; ParseContext funpc(&m.parser(), funbox, &newDirectives); if (!funpc.init()) return false; - if (!m.parser().functionFormalParametersAndBody(InAllowed, YieldIsName, funNode, Statement)) { + if (!m.parser().functionFormalParametersAndBody(InAllowed, YieldIsName, funNode, syntaxKind)) { if (tokenStream.hadError() || directives == newDirectives) return false;