mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1130811 - Split out of PNK_LET (used for let declarations, deprecated let blocks, and deprecated let expressions) additional PNK_LETBLOCK and PNK_LETEXPR kinds. r=shu
--HG-- extra : rebase_source : 0d628316044cafddf2b0ee890219c02b879dffc4
This commit is contained in:
parent
b09b675f9f
commit
3e0f48699f
@ -7202,12 +7202,14 @@ frontend::EmitTree(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
|
||||
ok = EmitLexicalScope(cx, bce, pn);
|
||||
break;
|
||||
|
||||
case PNK_LET:
|
||||
case PNK_LETBLOCK:
|
||||
case PNK_LETEXPR:
|
||||
ok = EmitLet(cx, bce, pn);
|
||||
break;
|
||||
|
||||
case PNK_CONST:
|
||||
MOZ_ASSERT_IF(pn->isKind(PNK_CONST), !pn->isArity(PN_BINARY));
|
||||
ok = pn->isArity(PN_BINARY)
|
||||
? EmitLet(cx, bce, pn)
|
||||
: EmitVariables(cx, bce, pn, InitializeVars);
|
||||
case PNK_LET:
|
||||
ok = EmitVariables(cx, bce, pn, InitializeVars);
|
||||
break;
|
||||
|
||||
case PNK_IMPORT:
|
||||
|
@ -540,6 +540,22 @@ class FullParseHandler
|
||||
block->pn_expr = body;
|
||||
}
|
||||
|
||||
ParseNode *newLetExpression(ParseNode *vars, ParseNode *block, const TokenPos &pos) {
|
||||
ParseNode *letExpr = newBinary(PNK_LETEXPR, vars, block);
|
||||
if (!letExpr)
|
||||
return nullptr;
|
||||
letExpr->pn_pos = pos;
|
||||
return letExpr;
|
||||
}
|
||||
|
||||
ParseNode *newLetBlock(ParseNode *vars, ParseNode *block, const TokenPos &pos) {
|
||||
ParseNode *letBlock = newBinary(PNK_LETBLOCK, vars, block);
|
||||
if (!letBlock)
|
||||
return nullptr;
|
||||
letBlock->pn_pos = pos;
|
||||
return letBlock;
|
||||
}
|
||||
|
||||
ParseNode *newAssignment(ParseNodeKind kind, ParseNode *lhs, ParseNode *rhs,
|
||||
ParseContext<FullParseHandler> *pc, JSOp op)
|
||||
{
|
||||
|
@ -131,6 +131,8 @@ class UpvarCookie
|
||||
F(ARRAYPUSH) \
|
||||
F(LEXICALSCOPE) \
|
||||
F(LET) \
|
||||
F(LETBLOCK) \
|
||||
F(LETEXPR) \
|
||||
F(IMPORT) \
|
||||
F(IMPORT_SPEC_LIST) \
|
||||
F(IMPORT_SPEC) \
|
||||
|
@ -3622,7 +3622,7 @@ Parser<SyntaxParseHandler>::pushLetScope(HandleStaticBlockObject blockObj, StmtI
|
||||
*/
|
||||
template <typename ParseHandler>
|
||||
typename ParseHandler::Node
|
||||
Parser<ParseHandler>::letBlock(LetContext letContext)
|
||||
Parser<ParseHandler>::deprecatedLetBlockOrExpression(LetContext letContext)
|
||||
{
|
||||
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LET));
|
||||
|
||||
@ -3645,11 +3645,6 @@ Parser<ParseHandler>::letBlock(LetContext letContext)
|
||||
if (!block)
|
||||
return null();
|
||||
|
||||
Node pnlet = handler.newBinary(PNK_LET, vars, block);
|
||||
if (!pnlet)
|
||||
return null();
|
||||
handler.setBeginPosition(pnlet, begin);
|
||||
|
||||
bool needExprStmt = false;
|
||||
if (letContext == LetStatement) {
|
||||
bool matched;
|
||||
@ -3672,16 +3667,16 @@ Parser<ParseHandler>::letBlock(LetContext letContext)
|
||||
*
|
||||
* See bug 569464.
|
||||
*/
|
||||
if (!report(ParseStrictError, pc->sc->strict, pnlet,
|
||||
JSMSG_STRICT_CODE_LET_EXPR_STMT))
|
||||
if (!reportWithOffset(ParseStrictError, pc->sc->strict, begin,
|
||||
JSMSG_STRICT_CODE_LET_EXPR_STMT))
|
||||
{
|
||||
return null();
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is really an expression in let statement guise, then we
|
||||
* need to wrap the PNK_LET node in a PNK_SEMI node so that we pop
|
||||
* the return value of the expression.
|
||||
* need to wrap the PNK_LETEXPR node in a PNK_SEMI node so that we
|
||||
* pop the return value of the expression.
|
||||
*/
|
||||
needExprStmt = true;
|
||||
letContext = LetExpression;
|
||||
@ -3711,14 +3706,22 @@ Parser<ParseHandler>::letBlock(LetContext letContext)
|
||||
handler.setLexicalScopeBody(block, expr);
|
||||
PopStatementPC(tokenStream, pc);
|
||||
|
||||
handler.setEndPosition(pnlet, pos().end);
|
||||
TokenPos letPos(begin, pos().end);
|
||||
|
||||
if (needExprStmt) {
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
if (letContext == LetExpression) {
|
||||
if (needExprStmt) {
|
||||
if (!MatchOrInsertSemicolon(tokenStream))
|
||||
return null();
|
||||
}
|
||||
|
||||
Node letExpr = handler.newLetExpression(vars, block, letPos);
|
||||
if (!letExpr)
|
||||
return null();
|
||||
return handler.newExprStatement(pnlet, pos().end);
|
||||
|
||||
return needExprStmt ? handler.newExprStatement(letExpr, pos().end) : letExpr;
|
||||
}
|
||||
return pnlet;
|
||||
|
||||
return handler.newLetBlock(vars, block, letPos);
|
||||
}
|
||||
|
||||
template <typename ParseHandler>
|
||||
@ -4097,27 +4100,44 @@ Parser<SyntaxParseHandler>::lexicalDeclaration(bool)
|
||||
|
||||
template <>
|
||||
ParseNode *
|
||||
Parser<FullParseHandler>::letStatement()
|
||||
Parser<FullParseHandler>::letDeclarationOrBlock()
|
||||
{
|
||||
handler.disableSyntaxParser();
|
||||
|
||||
/* Check for a let statement or let expression. */
|
||||
ParseNode *pn;
|
||||
TokenKind tt;
|
||||
if (!tokenStream.peekToken(&tt))
|
||||
return null();
|
||||
if (tt == TOK_LP) {
|
||||
pn = letBlock(LetStatement);
|
||||
MOZ_ASSERT_IF(pn, pn->isKind(PNK_LET) || pn->isKind(PNK_SEMI));
|
||||
} else {
|
||||
pn = lexicalDeclaration(/* isConst = */ false);
|
||||
ParseNode *node = deprecatedLetBlockOrExpression(LetStatement);
|
||||
if (!node)
|
||||
return nullptr;
|
||||
|
||||
if (node->isKind(PNK_LETBLOCK)) {
|
||||
MOZ_ASSERT(node->isArity(PN_BINARY));
|
||||
} else {
|
||||
MOZ_ASSERT(node->isKind(PNK_SEMI));
|
||||
MOZ_ASSERT(node->pn_kid->isKind(PNK_LETEXPR));
|
||||
MOZ_ASSERT(node->pn_kid->isArity(PN_BINARY));
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
return pn;
|
||||
|
||||
ParseNode *decl = lexicalDeclaration(/* isConst = */ false);
|
||||
if (!decl)
|
||||
return nullptr;
|
||||
|
||||
// let-declarations at global scope are currently treated as plain old var.
|
||||
// See bug 589199.
|
||||
MOZ_ASSERT(decl->isKind(PNK_LET) || decl->isKind(PNK_VAR));
|
||||
MOZ_ASSERT(decl->isArity(PN_LIST));
|
||||
return decl;
|
||||
}
|
||||
|
||||
template <>
|
||||
SyntaxParseHandler::Node
|
||||
Parser<SyntaxParseHandler>::letStatement()
|
||||
Parser<SyntaxParseHandler>::letDeclarationOrBlock()
|
||||
{
|
||||
JS_ALWAYS_FALSE(abortIfSyntaxParser());
|
||||
return SyntaxParseHandler::NodeFailure;
|
||||
@ -4655,7 +4675,7 @@ Parser<FullParseHandler>::forStatement()
|
||||
if (!tokenStream.peekToken(&tt))
|
||||
return null();
|
||||
if (tt == TOK_LP) {
|
||||
pn1 = letBlock(LetExpression);
|
||||
pn1 = deprecatedLetBlockOrExpression(LetExpression);
|
||||
} else {
|
||||
isForDecl = true;
|
||||
blockObj = StaticBlockObject::create(context);
|
||||
@ -4928,11 +4948,7 @@ Parser<FullParseHandler>::forStatement()
|
||||
if (forLetImpliedBlock) {
|
||||
forLetImpliedBlock->pn_expr = forLoop;
|
||||
forLetImpliedBlock->pn_pos = forLoop->pn_pos;
|
||||
ParseNode *let = handler.newBinary(PNK_LET, forLetDecl, forLetImpliedBlock);
|
||||
if (!let)
|
||||
return null();
|
||||
let->pn_pos = forLoop->pn_pos;
|
||||
return let;
|
||||
return handler.newLetBlock(forLetDecl, forLetImpliedBlock, forLoop->pn_pos);
|
||||
}
|
||||
return forLoop;
|
||||
}
|
||||
@ -5812,7 +5828,7 @@ Parser<ParseHandler>::statement(bool canHaveDirectives)
|
||||
}
|
||||
|
||||
case TOK_LET:
|
||||
return letStatement();
|
||||
return letDeclarationOrBlock();
|
||||
case TOK_IMPORT:
|
||||
return importDeclaration();
|
||||
case TOK_EXPORT:
|
||||
@ -8129,7 +8145,7 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt, InvokedPrediction invoked)
|
||||
return objectLiteral();
|
||||
|
||||
case TOK_LET:
|
||||
return letBlock(LetExpression);
|
||||
return deprecatedLetBlockOrExpression(LetExpression);
|
||||
|
||||
case TOK_LP: {
|
||||
TokenKind next;
|
||||
|
@ -557,7 +557,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node debuggerStatement();
|
||||
|
||||
Node lexicalDeclaration(bool isConst);
|
||||
Node letStatement();
|
||||
Node letDeclarationOrBlock();
|
||||
Node importDeclaration();
|
||||
Node exportDeclaration();
|
||||
Node expressionStatement(InvokedPrediction invoked = PredictUninvoked);
|
||||
@ -614,7 +614,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
|
||||
Node generatorComprehension(uint32_t begin);
|
||||
|
||||
bool argumentList(Node listNode, bool *isSpread);
|
||||
Node letBlock(LetContext letContext);
|
||||
Node deprecatedLetBlockOrExpression(LetContext letContext);
|
||||
Node destructuringExpr(BindData<ParseHandler> *data, TokenKind tt);
|
||||
Node destructuringExprWithoutYield(BindData<ParseHandler> *data, TokenKind tt, unsigned msg);
|
||||
|
||||
|
@ -246,6 +246,14 @@ class SyntaxParseHandler
|
||||
Node newLexicalScope(ObjectBox *blockbox) { return NodeGeneric; }
|
||||
void setLexicalScopeBody(Node block, Node body) {}
|
||||
|
||||
Node newLetExpression(Node vars, Node block, const TokenPos &pos) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
Node newLetBlock(Node vars, Node block, const TokenPos &pos) {
|
||||
return NodeGeneric;
|
||||
}
|
||||
|
||||
bool finishInitializerAssignment(Node pn, Node init, JSOp op) { return true; }
|
||||
|
||||
void setBeginPosition(Node pn, Node oth) {}
|
||||
|
@ -2367,11 +2367,12 @@ ASTSerializer::statement(ParseNode *pn, MutableHandleValue dst)
|
||||
case PNK_GLOBALCONST:
|
||||
return declaration(pn, dst);
|
||||
|
||||
case PNK_LETBLOCK:
|
||||
return let(pn, false, dst);
|
||||
|
||||
case PNK_LET:
|
||||
case PNK_CONST:
|
||||
return pn->isArity(PN_BINARY)
|
||||
? let(pn, false, dst)
|
||||
: declaration(pn, dst);
|
||||
return declaration(pn, dst);
|
||||
|
||||
case PNK_IMPORT:
|
||||
return importDeclaration(pn, dst);
|
||||
@ -3067,7 +3068,7 @@ ASTSerializer::expression(ParseNode *pn, MutableHandleValue dst)
|
||||
LOCAL_ASSERT(pn->pn_count == 1);
|
||||
return comprehension(pn->pn_head, dst);
|
||||
|
||||
case PNK_LET:
|
||||
case PNK_LETEXPR:
|
||||
return let(pn, true, dst);
|
||||
|
||||
default:
|
||||
|
Loading…
Reference in New Issue
Block a user