mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-21 09:15:35 +00:00
Bug 1296814 - Move the Parser::checkFunctionDefinition call, out of Parser::functionDefinition, into its few Statement-related callers. r=anba
--HG-- extra : rebase_source : cfcaa227d7e1d9ae8e4c00313a986a40547f1771
This commit is contained in:
parent
e383cddaf8
commit
2fdbf4afb3
@ -667,9 +667,18 @@ class FullParseHandler
|
|||||||
ParseNode* pn);
|
ParseNode* pn);
|
||||||
inline void setLastFunctionFormalParameterDestructuring(ParseNode* funcpn, ParseNode* pn);
|
inline void setLastFunctionFormalParameterDestructuring(ParseNode* funcpn, ParseNode* pn);
|
||||||
|
|
||||||
ParseNode* newFunctionDefinition() {
|
ParseNode* newFunctionStatement() {
|
||||||
return new_<CodeNode>(PNK_FUNCTION, pos());
|
return new_<CodeNode>(PNK_FUNCTION, JSOP_NOP, pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ParseNode* newFunctionExpression() {
|
||||||
|
return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA, pos());
|
||||||
|
}
|
||||||
|
|
||||||
|
ParseNode* newArrowFunction() {
|
||||||
|
return new_<CodeNode>(PNK_FUNCTION, JSOP_LAMBDA_ARROW, pos());
|
||||||
|
}
|
||||||
|
|
||||||
bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) {
|
bool setComprehensionLambdaBody(ParseNode* pn, ParseNode* body) {
|
||||||
MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
|
MOZ_ASSERT(body->isKind(PNK_STATEMENTLIST));
|
||||||
ParseNode* paramsBody = newList(PNK_PARAMSBODY, body);
|
ParseNode* paramsBody = newList(PNK_PARAMSBODY, body);
|
||||||
@ -696,7 +705,7 @@ class FullParseHandler
|
|||||||
}
|
}
|
||||||
|
|
||||||
ParseNode* newModule() {
|
ParseNode* newModule() {
|
||||||
return new_<CodeNode>(PNK_MODULE, pos());
|
return new_<CodeNode>(PNK_MODULE, JSOP_NOP, pos());
|
||||||
}
|
}
|
||||||
|
|
||||||
ParseNode* newLexicalScope(LexicalScope::Data* bindings, ParseNode* body) {
|
ParseNode* newLexicalScope(LexicalScope::Data* bindings, ParseNode* body) {
|
||||||
|
@ -916,10 +916,14 @@ struct ListNode : public ParseNode
|
|||||||
|
|
||||||
struct CodeNode : public ParseNode
|
struct CodeNode : public ParseNode
|
||||||
{
|
{
|
||||||
CodeNode(ParseNodeKind kind, const TokenPos& pos)
|
CodeNode(ParseNodeKind kind, JSOp op, const TokenPos& pos)
|
||||||
: ParseNode(kind, JSOP_NOP, PN_CODE, pos)
|
: ParseNode(kind, op, PN_CODE, pos)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(kind == PNK_FUNCTION || kind == PNK_MODULE);
|
MOZ_ASSERT(kind == PNK_FUNCTION || kind == PNK_MODULE);
|
||||||
|
MOZ_ASSERT_IF(kind == PNK_MODULE, op == JSOP_NOP);
|
||||||
|
MOZ_ASSERT(op == JSOP_NOP || // statement, module
|
||||||
|
op == JSOP_LAMBDA_ARROW || // arrow function
|
||||||
|
op == JSOP_LAMBDA); // expression, method, comprehension, accessor, &c.
|
||||||
MOZ_ASSERT(!pn_body);
|
MOZ_ASSERT(!pn_body);
|
||||||
MOZ_ASSERT(!pn_objbox);
|
MOZ_ASSERT(!pn_objbox);
|
||||||
}
|
}
|
||||||
|
@ -2293,7 +2293,7 @@ Parser<FullParseHandler>::standaloneFunctionBody(HandleFunction fun,
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(checkOptionsCalled);
|
MOZ_ASSERT(checkOptionsCalled);
|
||||||
|
|
||||||
Node fn = handler.newFunctionDefinition();
|
Node fn = handler.newFunctionStatement();
|
||||||
if (!fn)
|
if (!fn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@ -2971,60 +2971,54 @@ Parser<ParseHandler>::functionArguments(YieldHandling yieldHandling, FunctionSyn
|
|||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
bool
|
bool
|
||||||
Parser<ParseHandler>::checkFunctionDefinition(HandleAtom funAtom, Node pn, FunctionSyntaxKind kind,
|
Parser<ParseHandler>::checkFunctionDefinition(HandlePropertyName funName, Node pn,
|
||||||
GeneratorKind generatorKind, bool* tryAnnexB)
|
GeneratorKind generatorKind, bool* tryAnnexB)
|
||||||
{
|
{
|
||||||
if (kind == Statement) {
|
TokenPos pos = handler.getPosition(pn);
|
||||||
TokenPos pos = handler.getPosition(pn);
|
|
||||||
RootedPropertyName funName(context, funAtom->asPropertyName());
|
|
||||||
|
|
||||||
// In sloppy mode, Annex B.3.2 allows labelled function
|
// In sloppy mode, Annex B.3.2 allows labelled function
|
||||||
// declarations. Otherwise it is a parse error.
|
// declarations. Otherwise it is a parse error.
|
||||||
ParseContext::Statement* declaredInStmt = pc->innermostStatement();
|
ParseContext::Statement* declaredInStmt = pc->innermostStatement();
|
||||||
if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
|
if (declaredInStmt && declaredInStmt->kind() == StatementKind::Label) {
|
||||||
MOZ_ASSERT(!pc->sc()->strict(),
|
MOZ_ASSERT(!pc->sc()->strict(),
|
||||||
"labeled functions shouldn't be parsed in strict mode");
|
"labeled functions shouldn't be parsed in strict mode");
|
||||||
|
|
||||||
// Find the innermost non-label statement. Report an error if it's
|
// Find the innermost non-label statement. Report an error if it's
|
||||||
// unbraced: functions can't appear in it. Otherwise the statement
|
// unbraced: functions can't appear in it. Otherwise the statement
|
||||||
// (or its absence) determines the scope the function's bound in.
|
// (or its absence) determines the scope the function's bound in.
|
||||||
while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label)
|
while (declaredInStmt && declaredInStmt->kind() == StatementKind::Label)
|
||||||
declaredInStmt = declaredInStmt->enclosing();
|
declaredInStmt = declaredInStmt->enclosing();
|
||||||
|
|
||||||
if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
|
if (declaredInStmt && !StatementKindIsBraced(declaredInStmt->kind())) {
|
||||||
reportWithOffset(ParseError, false, pos.begin, JSMSG_SLOPPY_FUNCTION_LABEL);
|
reportWithOffset(ParseError, false, pos.begin, JSMSG_SLOPPY_FUNCTION_LABEL);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (declaredInStmt) {
|
||||||
|
MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
|
||||||
|
MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
|
||||||
|
|
||||||
|
if (!pc->sc()->strict() && generatorKind == NotGenerator) {
|
||||||
|
// Under 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
|
||||||
|
// the function object when its declaration is reached, not at
|
||||||
|
// the start of the block.
|
||||||
|
|
||||||
|
if (!tryDeclareVarForAnnexBLexicalFunction(funName, tryAnnexB))
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (declaredInStmt) {
|
if (!noteDeclaredName(funName, DeclarationKind::LexicalFunction, pos))
|
||||||
MOZ_ASSERT(declaredInStmt->kind() != StatementKind::Label);
|
return false;
|
||||||
MOZ_ASSERT(StatementKindIsBraced(declaredInStmt->kind()));
|
|
||||||
|
|
||||||
if (!pc->sc()->strict() && generatorKind == NotGenerator) {
|
|
||||||
// Under 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
|
|
||||||
// the function object when its declaration is reached, not at
|
|
||||||
// the start of the block.
|
|
||||||
|
|
||||||
if (!tryDeclareVarForAnnexBLexicalFunction(funName, tryAnnexB))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!noteDeclaredName(funName, DeclarationKind::LexicalFunction, pos))
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
if (!noteDeclaredName(funName, DeclarationKind::BodyLevelFunction, pos))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Body-level functions in modules are always closed over.
|
|
||||||
if (pc->atModuleLevel())
|
|
||||||
pc->varScope().lookupDeclaredName(funName)->value()->setClosedOver();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
// A function expression does not introduce any binding.
|
if (!noteDeclaredName(funName, DeclarationKind::BodyLevelFunction, pos))
|
||||||
handler.setOp(pn, kind == Arrow ? JSOP_LAMBDA_ARROW : JSOP_LAMBDA);
|
return false;
|
||||||
|
|
||||||
|
// Body-level functions in modules are always closed over.
|
||||||
|
if (pc->atModuleLevel())
|
||||||
|
pc->varScope().lookupDeclaredName(funName)->value()->setClosedOver();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -3152,16 +3146,12 @@ typename ParseHandler::Node
|
|||||||
Parser<ParseHandler>::functionDefinition(Node pn, InHandling inHandling,
|
Parser<ParseHandler>::functionDefinition(Node pn, InHandling inHandling,
|
||||||
YieldHandling yieldHandling, HandleAtom funName,
|
YieldHandling yieldHandling, HandleAtom funName,
|
||||||
FunctionSyntaxKind kind,
|
FunctionSyntaxKind kind,
|
||||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind)
|
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||||
|
bool tryAnnexB /* = false */)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(kind == Statement, funName);
|
MOZ_ASSERT_IF(kind == Statement, funName);
|
||||||
MOZ_ASSERT_IF(asyncKind == AsyncFunction, generatorKind == StarGenerator);
|
MOZ_ASSERT_IF(asyncKind == AsyncFunction, generatorKind == StarGenerator);
|
||||||
|
|
||||||
// Note the declared name and check for early errors.
|
|
||||||
bool tryAnnexB = false;
|
|
||||||
if (!checkFunctionDefinition(funName, pn, kind, generatorKind, &tryAnnexB))
|
|
||||||
return null();
|
|
||||||
|
|
||||||
// When fully parsing a LazyScript, we do not fully reparse its inner
|
// When fully parsing a LazyScript, we do not fully reparse its inner
|
||||||
// functions, which are also lazy. Instead, their free variables and
|
// functions, which are also lazy. Instead, their free variables and
|
||||||
// source extents are recorded and may be skipped.
|
// source extents are recorded and may be skipped.
|
||||||
@ -3388,7 +3378,7 @@ Parser<FullParseHandler>::standaloneLazyFunction(HandleFunction fun, bool strict
|
|||||||
{
|
{
|
||||||
MOZ_ASSERT(checkOptionsCalled);
|
MOZ_ASSERT(checkOptionsCalled);
|
||||||
|
|
||||||
Node pn = handler.newFunctionDefinition();
|
Node pn = handler.newFunctionStatement();
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@ -3590,13 +3580,18 @@ Parser<ParseHandler>::functionStmt(YieldHandling yieldHandling, DefaultHandling
|
|||||||
return null();
|
return null();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node pn = handler.newFunctionDefinition();
|
Node pn = handler.newFunctionStatement();
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
// Note the declared name and check for early errors.
|
||||||
|
bool tryAnnexB = false;
|
||||||
|
if (!checkFunctionDefinition(name, pn, generatorKind, &tryAnnexB))
|
||||||
|
return null();
|
||||||
|
|
||||||
YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind);
|
YieldHandling newYieldHandling = GetYieldHandling(generatorKind, asyncKind);
|
||||||
return functionDefinition(pn, InAllowed, newYieldHandling, name, Statement, generatorKind,
|
return functionDefinition(pn, InAllowed, newYieldHandling, name, Statement, generatorKind,
|
||||||
asyncKind);
|
asyncKind, tryAnnexB);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename ParseHandler>
|
template <typename ParseHandler>
|
||||||
@ -3632,7 +3627,7 @@ Parser<ParseHandler>::functionExpr(InvokedPrediction invoked, FunctionAsyncKind
|
|||||||
tokenStream.ungetToken();
|
tokenStream.ungetToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
Node pn = handler.newFunctionDefinition();
|
Node pn = handler.newFunctionExpression();
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@ -6523,31 +6518,6 @@ JSOpFromPropertyType(PropertyType propType)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static FunctionSyntaxKind
|
|
||||||
FunctionSyntaxKindFromPropertyType(PropertyType propType)
|
|
||||||
{
|
|
||||||
switch (propType) {
|
|
||||||
case PropertyType::Getter:
|
|
||||||
return Getter;
|
|
||||||
case PropertyType::GetterNoExpressionClosure:
|
|
||||||
return GetterNoExpressionClosure;
|
|
||||||
case PropertyType::Setter:
|
|
||||||
return Setter;
|
|
||||||
case PropertyType::SetterNoExpressionClosure:
|
|
||||||
return SetterNoExpressionClosure;
|
|
||||||
case PropertyType::Method:
|
|
||||||
case PropertyType::GeneratorMethod:
|
|
||||||
case PropertyType::AsyncMethod:
|
|
||||||
return Method;
|
|
||||||
case PropertyType::Constructor:
|
|
||||||
return ClassConstructor;
|
|
||||||
case PropertyType::DerivedConstructor:
|
|
||||||
return DerivedClassConstructor;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("unexpected property type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static GeneratorKind
|
static GeneratorKind
|
||||||
GeneratorKindFromPropertyType(PropertyType propType)
|
GeneratorKindFromPropertyType(PropertyType propType)
|
||||||
{
|
{
|
||||||
@ -7726,7 +7696,7 @@ Parser<ParseHandler>::assignExpr(InHandling inHandling, YieldHandling yieldHandl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Node pn = handler.newFunctionDefinition();
|
Node pn = handler.newArrowFunction();
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
@ -8069,10 +8039,9 @@ template <typename ParseHandler>
|
|||||||
typename ParseHandler::Node
|
typename ParseHandler::Node
|
||||||
Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin)
|
Parser<ParseHandler>::generatorComprehensionLambda(unsigned begin)
|
||||||
{
|
{
|
||||||
Node genfn = handler.newFunctionDefinition();
|
Node genfn = handler.newFunctionExpression();
|
||||||
if (!genfn)
|
if (!genfn)
|
||||||
return null();
|
return null();
|
||||||
handler.setOp(genfn, JSOP_LAMBDA);
|
|
||||||
|
|
||||||
ParseContext* outerpc = pc;
|
ParseContext* outerpc = pc;
|
||||||
|
|
||||||
@ -9356,12 +9325,47 @@ template <typename ParseHandler>
|
|||||||
typename ParseHandler::Node
|
typename ParseHandler::Node
|
||||||
Parser<ParseHandler>::methodDefinition(PropertyType propType, HandleAtom funName)
|
Parser<ParseHandler>::methodDefinition(PropertyType propType, HandleAtom funName)
|
||||||
{
|
{
|
||||||
FunctionSyntaxKind kind = FunctionSyntaxKindFromPropertyType(propType);
|
FunctionSyntaxKind kind;
|
||||||
|
switch (propType) {
|
||||||
|
case PropertyType::Getter:
|
||||||
|
kind = Getter;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::GetterNoExpressionClosure:
|
||||||
|
kind = GetterNoExpressionClosure;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::Setter:
|
||||||
|
kind = Setter;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::SetterNoExpressionClosure:
|
||||||
|
kind = SetterNoExpressionClosure;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::Method:
|
||||||
|
case PropertyType::GeneratorMethod:
|
||||||
|
case PropertyType::AsyncMethod:
|
||||||
|
kind = Method;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::Constructor:
|
||||||
|
kind = ClassConstructor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PropertyType::DerivedConstructor:
|
||||||
|
kind = DerivedClassConstructor;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("unexpected property type");
|
||||||
|
}
|
||||||
|
|
||||||
GeneratorKind generatorKind = GeneratorKindFromPropertyType(propType);
|
GeneratorKind generatorKind = GeneratorKindFromPropertyType(propType);
|
||||||
FunctionAsyncKind asyncKind = AsyncKindFromPropertyType(propType);
|
FunctionAsyncKind asyncKind = AsyncKindFromPropertyType(propType);
|
||||||
YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind);
|
YieldHandling yieldHandling = GetYieldHandling(generatorKind, asyncKind);
|
||||||
|
|
||||||
Node pn = handler.newFunctionDefinition();
|
Node pn = handler.newFunctionExpression();
|
||||||
if (!pn)
|
if (!pn)
|
||||||
return null();
|
return null();
|
||||||
|
|
||||||
|
@ -1256,7 +1256,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
|
|||||||
|
|
||||||
Node functionDefinition(Node func, InHandling inHandling, YieldHandling yieldHandling,
|
Node functionDefinition(Node func, InHandling inHandling, YieldHandling yieldHandling,
|
||||||
HandleAtom name, FunctionSyntaxKind kind,
|
HandleAtom name, FunctionSyntaxKind kind,
|
||||||
GeneratorKind generatorKind, FunctionAsyncKind asyncKind);
|
GeneratorKind generatorKind, FunctionAsyncKind asyncKind,
|
||||||
|
bool tryAnnexB = false);
|
||||||
|
|
||||||
// Parse a function body. Pass StatementListBody if the body is a list of
|
// Parse a function body. Pass StatementListBody if the body is a list of
|
||||||
// statements; pass ExpressionBody if the body is a single expression.
|
// statements; pass ExpressionBody if the body is a single expression.
|
||||||
@ -1342,8 +1343,8 @@ class Parser final : private JS::AutoGCRooter, public StrictModeGetter
|
|||||||
Node newDotGeneratorName();
|
Node newDotGeneratorName();
|
||||||
bool declareDotGeneratorName();
|
bool declareDotGeneratorName();
|
||||||
|
|
||||||
bool checkFunctionDefinition(HandleAtom funAtom, Node pn, FunctionSyntaxKind kind,
|
bool checkFunctionDefinition(HandlePropertyName funName, Node pn, GeneratorKind generatorKind,
|
||||||
GeneratorKind generatorKind, bool* tryAnnexB);
|
bool* tryAnnexB);
|
||||||
bool skipLazyInnerFunction(Node pn, FunctionSyntaxKind kind, bool tryAnnexB);
|
bool skipLazyInnerFunction(Node pn, FunctionSyntaxKind kind, bool tryAnnexB);
|
||||||
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
|
bool innerFunction(Node pn, ParseContext* outerpc, HandleFunction fun,
|
||||||
InHandling inHandling, YieldHandling yieldHandling,
|
InHandling inHandling, YieldHandling yieldHandling,
|
||||||
|
@ -344,7 +344,11 @@ class SyntaxParseHandler
|
|||||||
Node catchGuard, Node catchBody) { return true; }
|
Node catchGuard, Node catchBody) { return true; }
|
||||||
|
|
||||||
MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(Node funcpn, Node pn) { return true; }
|
MOZ_MUST_USE bool setLastFunctionFormalParameterDefault(Node funcpn, Node pn) { return true; }
|
||||||
Node newFunctionDefinition() { return NodeFunctionDefinition; }
|
|
||||||
|
Node newFunctionStatement() { return NodeFunctionDefinition; }
|
||||||
|
Node newFunctionExpression() { return NodeFunctionDefinition; }
|
||||||
|
Node newArrowFunction() { return NodeFunctionDefinition; }
|
||||||
|
|
||||||
bool setComprehensionLambdaBody(Node pn, Node body) { return true; }
|
bool setComprehensionLambdaBody(Node pn, Node body) { return true; }
|
||||||
void setFunctionFormalParametersAndBody(Node pn, Node kid) {}
|
void setFunctionFormalParametersAndBody(Node pn, Node kid) {}
|
||||||
void setFunctionBody(Node pn, Node kid) {}
|
void setFunctionBody(Node pn, Node kid) {}
|
||||||
|
@ -7060,7 +7060,7 @@ ParseFunction(ModuleValidator& m, ParseNode** fnOut, unsigned* line)
|
|||||||
if (!name)
|
if (!name)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
ParseNode* fn = m.parser().handler.newFunctionDefinition();
|
ParseNode* fn = m.parser().handler.newFunctionStatement();
|
||||||
if (!fn)
|
if (!fn)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user