mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-09 09:18:42 +09:00
Issue #2173 - Introduce FunctionNode::syntaxKind instead of JSOPs
This moves some "implementation details" to later in the emitter,
and also keeps syntax information available for later use.
Based-on: 1518391/{3+4}
This commit is contained in:
parent
0dac791851
commit
0132ae2101
6 changed files with 138 additions and 133 deletions
|
|
@ -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(),
|
||||
|
|
|
|||
|
|
@ -722,16 +722,8 @@ FOR_EACH_PARSENODE_SUBCLASS(DECLARE_AS)
|
|||
pn->setDirectRHSAnonFunction(true);
|
||||
}
|
||||
|
||||
FunctionNodeType newFunctionStatement() {
|
||||
return new_<FunctionNode>(JSOP_NOP, pos());
|
||||
}
|
||||
|
||||
FunctionNodeType newFunctionExpression() {
|
||||
return new_<FunctionNode>(JSOP_LAMBDA, pos());
|
||||
}
|
||||
|
||||
FunctionNodeType newArrowFunction() {
|
||||
return new_<FunctionNode>(JSOP_LAMBDA_ARROW, pos());
|
||||
FunctionNodeType newFunction(FunctionSyntaxKind syntaxKind) {
|
||||
return new_<FunctionNode>(syntaxKind, pos());
|
||||
}
|
||||
|
||||
bool setComprehensionLambdaBody(FunctionNodeType funNode, ListNodeType body) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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<ParseContext::ClassStatement>();
|
||||
MOZ_ASSERT(stmt);
|
||||
stmt->constructorBox = this;
|
||||
|
||||
if (kind == DerivedClassConstructor) {
|
||||
if (kind == FunctionSyntaxKind::DerivedClassConstructor) {
|
||||
setDerivedClassConstructor();
|
||||
allowSuperCall_ = true;
|
||||
needsThisTDZChecks_ = true;
|
||||
|
|
@ -2547,7 +2547,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
tokenStream.ungetToken();
|
||||
}
|
||||
|
||||
FunctionNodeType funNode = handler.newFunctionStatement();
|
||||
FunctionNodeType funNode = handler.newFunction(FunctionSyntaxKind::Statement);
|
||||
if (!funNode)
|
||||
return null();
|
||||
|
||||
|
|
@ -2569,7 +2569,7 @@ Parser<FullParseHandler>::standaloneFunction(HandleFunction fun,
|
|||
|
||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind);
|
||||
AutoAwaitIsKeyword<FullParseHandler> 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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<FullParseHandler>::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<ParseHandler>::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<FullParseHandler>::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<FullParseHandler>::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<ParseHandler>::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<ParseHandler> awaitIsKeyword(this, asyncOrArrowInAsync);
|
||||
if (!functionArguments(yieldHandling, kind, funNode))
|
||||
return false;
|
||||
|
|
@ -3671,7 +3676,7 @@ Parser<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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 <typename ParseHandler>
|
||||
|
|
@ -3903,15 +3911,15 @@ Parser<ParseHandler>::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<ParseHandler>::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>
|
|||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin)
|
||||
{
|
||||
FunctionNodeType genfn = handler.newFunctionExpression();
|
||||
FunctionNodeType genfn = handler.newFunction(FunctionSyntaxKind::Expression);
|
||||
if (!genfn)
|
||||
return null();
|
||||
|
||||
|
|
@ -8807,7 +8815,7 @@ Parser<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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<ParseHandler>::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 <typename ParseHandler>
|
||||
|
|
|
|||
|
|
@ -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) {}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue