summaryrefslogtreecommitdiff
path: root/js
diff options
context:
space:
mode:
authorPale Moon <git-repo@palemoon.org>2017-01-08 03:52:56 +0100
committerPale Moon <git-repo@palemoon.org>2017-01-08 03:52:56 +0100
commit9db17223e55369c740b691a67819f97e58fa8a16 (patch)
tree181d65c827b1db89f8d5585192d42b65badfac48 /js
parenteba9f163fc8a52a0cf0975158937671cf275ecf9 (diff)
downloadpalemoon-gre-9db17223e55369c740b691a67819f97e58fa8a16.tar.gz
Remove support for non-standard let expressions, part 1: code.
Tag #773.
Diffstat (limited to 'js')
-rw-r--r--js/src/frontend/BytecodeEmitter.cpp39
-rw-r--r--js/src/frontend/FoldConstants.cpp1
-rw-r--r--js/src/frontend/FullParseHandler.h8
-rw-r--r--js/src/frontend/ParseNode.cpp1
-rw-r--r--js/src/frontend/ParseNode.h1
-rw-r--r--js/src/frontend/Parser.cpp138
-rw-r--r--js/src/frontend/Parser.h3
-rw-r--r--js/src/frontend/SyntaxParseHandler.h4
-rw-r--r--js/src/js.msg3
-rw-r--r--js/src/jsast.tbl1
-rw-r--r--js/src/jscompartment.h2
-rw-r--r--js/src/jsreflect.cpp36
-rw-r--r--js/src/vm/Xdr.h4
13 files changed, 45 insertions, 196 deletions
diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp
index 36b19240c..635e1e3e8 100644
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4788,41 +4788,14 @@ EmitIf(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pn)
}
/*
- * pnLet represents one of:
- *
- * let-expression: (let (x = y) EXPR)
- * let-statement: let (x = y) { ... }
- *
- * For a let-expression 'let (x = a, [y,z] = b) e', EmitLet produces:
- *
- * bytecode stackDepth srcnotes
- * evaluate a +1
- * evaluate b +1
- * dup +1
- * destructure y
- * pick 1
- * dup +1
- * destructure z
- * pick 1
- * pop -1
- * setlocal 2 -1
- * setlocal 1 -1
- * setlocal 0 -1
- * pushblockscope (if needed)
- * evaluate e +1
- * debugleaveblock
- * popblockscope (if needed)
- *
- * Note that, since pushblockscope simply changes fp->scopeChain and does not
- * otherwise touch the stack, evaluation of the let-var initializers must leave
- * the initial value in the let-var's future slot.
+ * pnLet represents a let-statement: let (x = y) { ... }
*/
/*
* Using MOZ_NEVER_INLINE in here is a workaround for llvm.org/pr14047. See
* the comment on EmitSwitch.
*/
MOZ_NEVER_INLINE static bool
-EmitLet(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pnLet)
+EmitLetBlock(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pnLet)
{
MOZ_ASSERT(pnLet->isArity(PN_BINARY));
ParseNode* varList = pnLet->pn_left;
@@ -6553,9 +6526,8 @@ EmitConditionalExpression(ExclusiveContext* cx, BytecodeEmitter* bce, Conditiona
* ignore the value pushed by the first branch. Execution will follow
* only one path, so we must decrement bce->stackDepth.
*
- * Failing to do this will foil code, such as let expression and block
- * code generation, which must use the stack depth to compute local
- * stack indexes correctly.
+ * Failing to do this will foil code, such as let block code generation,
+ * which must use the stack depth to compute local stack indexes correctly.
*/
MOZ_ASSERT(bce->stackDepth > 0);
bce->stackDepth--;
@@ -7193,8 +7165,7 @@ frontend::EmitTree(ExclusiveContext* cx, BytecodeEmitter* bce, ParseNode* pn)
break;
case PNK_LETBLOCK:
- case PNK_LETEXPR:
- ok = EmitLet(cx, bce, pn);
+ ok = EmitLetBlock(cx, bce, pn);
break;
case PNK_CONST:
diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp
index fdb369af5..1241be741 100644
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -392,7 +392,6 @@ ContainsHoistedDeclaration(ExclusiveContext* cx, ParseNode* node, bool* result)
case PNK_FALSE:
case PNK_NULL:
case PNK_THIS:
- case PNK_LETEXPR:
case PNK_ELISION:
case PNK_NUMBER:
case PNK_NEW:
diff --git a/js/src/frontend/FullParseHandler.h b/js/src/frontend/FullParseHandler.h
index d6d74f948..f6683ad3b 100644
--- a/js/src/frontend/FullParseHandler.h
+++ b/js/src/frontend/FullParseHandler.h
@@ -555,14 +555,6 @@ 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)
diff --git a/js/src/frontend/ParseNode.cpp b/js/src/frontend/ParseNode.cpp
index cd0b8b617..207b461a3 100644
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -258,7 +258,6 @@ PushNodeChildren(ParseNode* pn, NodeStack* stack)
case PNK_MODASSIGN:
// ...and a few others.
case PNK_ELEM:
- case PNK_LETEXPR:
case PNK_IMPORT_SPEC:
case PNK_EXPORT_SPEC:
case PNK_COLON:
diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h
index c091ab315..40658e173 100644
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -133,7 +133,6 @@ class UpvarCookie
F(LEXICALSCOPE) \
F(LET) \
F(LETBLOCK) \
- F(LETEXPR) \
F(IMPORT) \
F(IMPORT_SPEC_LIST) \
F(IMPORT_SPEC) \
diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp
index 7f0cbdb49..aab070b61 100644
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -2924,7 +2924,7 @@ Parser<ParseHandler>::reportRedeclaration(Node pn, Definition::Kind redeclKind,
}
/*
- * Define a lexical binding in a block, let-expression, or comprehension scope. pc
+ * Define a lexical binding in a block or comprehension scope. pc
* must already be in such a scope.
*
* Throw a SyntaxError if 'atom' is an invalid name. Otherwise create a
@@ -3613,13 +3613,13 @@ Parser<SyntaxParseHandler>::pushLetScope(HandleStaticBlockObject blockObj, StmtI
}
/*
- * Parse a let block statement or let expression (determined by 'letContext').
+ * Parse a let block statement.
* In both cases, bindings are not hoisted to the top of the enclosing block
* and thus must be carefully injected between variables() and the let body.
*/
template <typename ParseHandler>
typename ParseHandler::Node
-Parser<ParseHandler>::deprecatedLetBlockOrExpression(LetContext letContext)
+Parser<ParseHandler>::deprecatedLetBlock()
{
MOZ_ASSERT(tokenStream.isCurrentTokenType(TOK_LET));
@@ -3642,82 +3642,22 @@ Parser<ParseHandler>::deprecatedLetBlockOrExpression(LetContext letContext)
if (!block)
return null();
- bool needExprStmt = false;
- if (letContext == LetStatement) {
- bool matched;
- if (!tokenStream.matchToken(&matched, TOK_LC, TokenStream::Operand))
- return null();
- if (!matched) {
- /*
- * Strict mode eliminates a grammar ambiguity with unparenthesized
- * LetExpressions in an ExpressionStatement. If followed immediately
- * by an arguments list, it's ambiguous whether the let expression
- * is the callee or the call is inside the let expression body.
- *
- * function id(x) { return x; }
- * var x = "outer";
- * // Does this parse as
- * // (let (loc = "inner") id)(loc) // "outer"
- * // or as
- * // let (loc = "inner") (id(loc)) // "inner"
- * let (loc = "inner") id(loc);
- *
- * See bug 569464.
- */
- 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_LETEXPR node in a PNK_SEMI node so that we
- * pop the return value of the expression.
- */
- needExprStmt = true;
- letContext = LetExpression;
- }
- }
+ MUST_MATCH_TOKEN(TOK_LC, JSMSG_CURLY_BEFORE_LET);
+
+ Node expr = statements(yieldHandling);
+ if (!expr)
+ return null();
+ MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
+
+ addTelemetry(JSCompartment::DeprecatedLetBlock);
+ if (!report(ParseWarning, pc->sc->strict(), expr, JSMSG_DEPRECATED_LET_BLOCK))
+ return null();
- Node expr;
- if (letContext == LetStatement) {
- expr = statements();
- if (!expr)
- return null();
- MUST_MATCH_TOKEN(TOK_RC, JSMSG_CURLY_AFTER_LET);
-
- addTelemetry(JSCompartment::DeprecatedLetBlock);
- if (!report(ParseWarning, pc->sc->strict, expr, JSMSG_DEPRECATED_LET_BLOCK))
- return null();
- } else {
- MOZ_ASSERT(letContext == LetExpression);
- expr = assignExpr();
- if (!expr)
- return null();
-
- addTelemetry(JSCompartment::DeprecatedLetExpression);
- if (!report(ParseWarning, pc->sc->strict, expr, JSMSG_DEPRECATED_LET_EXPRESSION))
- return null();
- }
handler.setLexicalScopeBody(block, expr);
PopStatementPC(tokenStream, pc);
TokenPos letPos(begin, pos().end);
- if (letContext == LetExpression) {
- if (needExprStmt) {
- if (!MatchOrInsertSemicolon(tokenStream))
- return null();
- }
-
- Node letExpr = handler.newLetExpression(vars, block, letPos);
- if (!letExpr)
- return null();
-
- return needExprStmt ? handler.newExprStatement(letExpr, pos().end) : letExpr;
- }
-
return handler.newLetBlock(vars, block, letPos);
}
@@ -4101,23 +4041,17 @@ Parser<FullParseHandler>::letDeclarationOrBlock()
{
handler.disableSyntaxParser();
- /* Check for a let statement or let expression. */
+ /* Check for a let statement. */
TokenKind tt;
if (!tokenStream.peekToken(&tt))
return null();
if (tt == TOK_LP) {
- ParseNode* node = deprecatedLetBlockOrExpression(LetStatement);
+ ParseNode* node = deprecatedLetBlock();
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));
- }
-
+ MOZ_ASSERT(node->isKind(PNK_LETBLOCK));
+ MOZ_ASSERT(node->isArity(PN_BINARY));
return node;
}
@@ -4629,8 +4563,7 @@ Parser<FullParseHandler>::forStatement()
MUST_MATCH_TOKEN(TOK_LP, JSMSG_PAREN_AFTER_FOR);
/*
- * True if we have 'for (var/let/const ...)', except in the oddball case
- * where 'let' begins a let-expression in 'for (let (...) ...)'.
+ * True if we have 'for (var/let/const ...)'.
*/
bool isForDecl = false;
@@ -4669,18 +4602,12 @@ Parser<FullParseHandler>::forStatement()
handler.disableSyntaxParser();
bool constDecl = tt == TOK_CONST;
tokenStream.consumeKnownToken(tt);
- if (!tokenStream.peekToken(&tt))
+ isForDecl = true;
+ blockObj = StaticBlockObject::create(context);
+ if (!blockObj)
return null();
- if (tt == TOK_LP) {
- pn1 = deprecatedLetBlockOrExpression(LetExpression);
- } else {
- isForDecl = true;
- blockObj = StaticBlockObject::create(context);
- if (!blockObj)
- return null();
- pn1 = variables(constDecl ? PNK_CONST : PNK_LET, nullptr, blockObj,
- DontHoistVars);
- }
+ pn1 = variables(constDecl ? PNK_CONST : PNK_LET, nullptr, blockObj,
+ DontHoistVars);
} else {
pn1 = expr();
}
@@ -6695,9 +6622,7 @@ LegacyCompExprTransplanter::transplant(ParseNode* pn)
// The one remaining thing to patch up is the block scope depth. We need to
// compute the maximum block scope depth of a function, so we know how much
// space to reserve in the fixed part of a stack frame. Normally this is done
-// whenever we leave a statement, via AccumulateBlockScopeDepth. However if the
-// head has a let expression, we need to re-assign that depth to the tail of the
-// comprehension.
+// whenever we leave a statement, via AccumulateBlockScopeDepth.
//
// Thing is, we don't actually know what that depth is, because the only
// information we keep is the maximum nested depth within a statement, so we
@@ -6768,10 +6693,9 @@ Parser<FullParseHandler>::legacyComprehensionTail(ParseNode* bodyExpr, unsigned
* the comprehension's block scope. We allocate that id or one above it
* here, by calling PushLexicalScope.
*
- * In the case of a comprehension expression that has nested blocks
- * (e.g., let expressions), we will allocate a higher blockid but then
- * slide all blocks "to the right" to make room for the comprehension's
- * block scope.
+ * In the case of a comprehension expression that has nested blocks,
+ * we will allocate a higher blockid but then slide all blocks "to the
+ * right" to make room for the comprehension's block scope.
*/
adjust = pc->blockid();
pn = pushLexicalScope(&stmtInfo);
@@ -7804,9 +7728,10 @@ Parser<ParseHandler>::arrayInitializer()
*
* [i * j for (i in o) for (j in p) if (i != j)]
*
- * translates to roughly the following let expression:
+ * translates to roughly the following code:
*
- * let (array = new Array, i, j) {
+ * {
+ * let array = new Array, i, j;
* for (i in o) let {
* for (j in p)
* if (i != j)
@@ -8152,9 +8077,6 @@ Parser<ParseHandler>::primaryExpr(TokenKind tt, InvokedPrediction invoked)
case TOK_LC:
return objectLiteral();
- case TOK_LET:
- return deprecatedLetBlockOrExpression(LetExpression);
-
case TOK_LP: {
TokenKind next;
if (!tokenStream.peekToken(&next, TokenStream::Operand))
diff --git a/js/src/frontend/Parser.h b/js/src/frontend/Parser.h
index 6b23c4654..4723e764f 100644
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -325,7 +325,6 @@ struct BindData;
class CompExprTransplanter;
-enum LetContext { LetExpression, LetStatement };
enum VarContext { HoistVars, DontHoistVars };
enum FunctionType { Getter, Setter, Normal };
@@ -606,7 +605,7 @@ class Parser : private JS::AutoGCRooter, public StrictModeGetter
Node generatorComprehension(uint32_t begin);
bool argumentList(Node listNode, bool* isSpread);
- Node deprecatedLetBlockOrExpression(LetContext letContext);
+ Node deprecatedLetBlock();
Node destructuringExpr(BindData<ParseHandler>* data, TokenKind tt);
Node destructuringExprWithoutYield(BindData<ParseHandler>* data, TokenKind tt, unsigned msg);
diff --git a/js/src/frontend/SyntaxParseHandler.h b/js/src/frontend/SyntaxParseHandler.h
index 914ee23c4..8bb9985f4 100644
--- a/js/src/frontend/SyntaxParseHandler.h
+++ b/js/src/frontend/SyntaxParseHandler.h
@@ -250,10 +250,6 @@ 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;
}
diff --git a/js/src/js.msg b/js/src/js.msg
index 0fad821ed..47ed2e45e 100644
--- a/js/src/js.msg
+++ b/js/src/js.msg
@@ -219,6 +219,7 @@ MSG_DEF(JSMSG_CURLY_AFTER_LIST, 0, JSEXN_SYNTAXERR, "missing } after prop
MSG_DEF(JSMSG_CURLY_AFTER_TRY, 0, JSEXN_SYNTAXERR, "missing } after try block")
MSG_DEF(JSMSG_CURLY_BEFORE_BODY, 0, JSEXN_SYNTAXERR, "missing { before function body")
MSG_DEF(JSMSG_CURLY_BEFORE_CATCH, 0, JSEXN_SYNTAXERR, "missing { before catch block")
+MSG_DEF(JSMSG_CURLY_BEFORE_LET, 0, JSEXN_SYNTAXERR, "missing { before let block")
MSG_DEF(JSMSG_CURLY_BEFORE_FINALLY, 0, JSEXN_SYNTAXERR, "missing { before finally block")
MSG_DEF(JSMSG_CURLY_BEFORE_SWITCH, 0, JSEXN_SYNTAXERR, "missing { before switch body")
MSG_DEF(JSMSG_CURLY_BEFORE_TRY, 0, JSEXN_SYNTAXERR, "missing { before try block")
@@ -228,7 +229,6 @@ MSG_DEF(JSMSG_DECLARATION_AFTER_IMPORT,0, JSEXN_SYNTAXERR, "missing declaration
MSG_DEF(JSMSG_DEPRECATED_DELETE_OPERAND, 0, JSEXN_SYNTAXERR, "applying the 'delete' operator to an unqualified name is deprecated")
MSG_DEF(JSMSG_DEPRECATED_LET_BLOCK, 0, JSEXN_NONE, "JavaScript 1.7's let blocks are deprecated")
MSG_DEF(JSMSG_DEPRECATED_FOR_EACH, 0, JSEXN_NONE, "JavaScript 1.6's for-each-in loops are deprecated; consider using ES6 for-of instead")
-MSG_DEF(JSMSG_DEPRECATED_LET_EXPRESSION, 0, JSEXN_NONE, "JavaScript 1.7's let expressions are deprecated")
MSG_DEF(JSMSG_DEPRECATED_OCTAL, 0, JSEXN_SYNTAXERR, "octal literals and octal escape sequences are deprecated")
MSG_DEF(JSMSG_DEPRECATED_PRAGMA, 1, JSEXN_NONE, "Using //@ to indicate {0} pragmas is deprecated. Use //# instead")
MSG_DEF(JSMSG_DUPLICATE_FORMAL, 1, JSEXN_SYNTAXERR, "duplicate formal argument {0}")
@@ -295,7 +295,6 @@ MSG_DEF(JSMSG_SEMI_AFTER_FOR_COND, 0, JSEXN_SYNTAXERR, "missing ; after for-
MSG_DEF(JSMSG_SEMI_AFTER_FOR_INIT, 0, JSEXN_SYNTAXERR, "missing ; after for-loop initializer")
MSG_DEF(JSMSG_SEMI_BEFORE_STMNT, 0, JSEXN_SYNTAXERR, "missing ; before statement")
MSG_DEF(JSMSG_SOURCE_TOO_LONG, 0, JSEXN_RANGEERR, "source is too long")
-MSG_DEF(JSMSG_STRICT_CODE_LET_EXPR_STMT, 0, JSEXN_ERR, "strict mode code may not contain unparenthesized let expression statements")
MSG_DEF(JSMSG_STRICT_CODE_WITH, 0, JSEXN_SYNTAXERR, "strict mode code may not contain 'with' statements")
MSG_DEF(JSMSG_STRICT_FUNCTION_STATEMENT, 0, JSEXN_SYNTAXERR, "in strict mode code, functions may be declared only at top level or immediately within another function")
MSG_DEF(JSMSG_TEMPLSTR_UNTERM_EXPR, 0, JSEXN_SYNTAXERR, "missing } in template string")
diff --git a/js/src/jsast.tbl b/js/src/jsast.tbl
index 2bb89f636..286224fa0 100644
--- a/js/src/jsast.tbl
+++ b/js/src/jsast.tbl
@@ -37,7 +37,6 @@ ASTDEF(AST_THIS_EXPR, "ThisExpression", "thisExpress
ASTDEF(AST_COMP_EXPR, "ComprehensionExpression", "comprehensionExpression")
ASTDEF(AST_GENERATOR_EXPR, "GeneratorExpression", "generatorExpression")
ASTDEF(AST_YIELD_EXPR, "YieldExpression", "yieldExpression")
-ASTDEF(AST_LET_EXPR, "LetExpression", "letExpression")
ASTDEF(AST_EMPTY_STMT, "EmptyStatement", "emptyStatement")
ASTDEF(AST_BLOCK_STMT, "BlockStatement", "blockStatement")
diff --git a/js/src/jscompartment.h b/js/src/jscompartment.h
index 7623a0a66..dcf26c865 100644
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -546,7 +546,7 @@ struct JSCompartment
DeprecatedLegacyGenerator = 2, // JS 1.7+
DeprecatedExpressionClosure = 3, // Added in JS 1.8
DeprecatedLetBlock = 4, // Added in JS 1.7
- DeprecatedLetExpression = 5, // Added in JS 1.7
+ // No longer using 5 (was: let expressions)
DeprecatedNoSuchMethod = 6, // JS 1.7+
DeprecatedLanguageExtensionCount
};
diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp
index aa86fb0ce..1c7feeb18 100644
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -676,8 +676,6 @@ class NodeBuilder
bool generatorExpression(HandleValue body, NodeVector& blocks, HandleValue filter,
bool isLegacy, TokenPos* pos, MutableHandleValue dst);
- bool letExpression(NodeVector& head, HandleValue expr, TokenPos* pos, MutableHandleValue dst);
-
/*
* declarations
*/
@@ -1471,24 +1469,6 @@ NodeBuilder::generatorExpression(HandleValue body, NodeVector& blocks, HandleVal
}
bool
-NodeBuilder::letExpression(NodeVector& head, HandleValue expr, TokenPos* pos,
- MutableHandleValue dst)
-{
- RootedValue array(cx);
- if (!newArray(head, &array))
- return false;
-
- RootedValue cb(cx, callbacks[AST_LET_EXPR]);
- if (!cb.isNull())
- return callback(cb, array, expr, pos, dst);
-
- return newNode(AST_LET_EXPR, pos,
- "head", array,
- "body", expr,
- dst);
-}
-
-bool
NodeBuilder::letStatement(NodeVector& head, HandleValue stmt, TokenPos* pos, MutableHandleValue dst)
{
RootedValue array(cx);
@@ -1747,7 +1727,7 @@ class ASTSerializer
bool declaration(ParseNode* pn, MutableHandleValue dst);
bool variableDeclaration(ParseNode* pn, bool lexical, MutableHandleValue dst);
bool variableDeclarator(ParseNode* pn, MutableHandleValue dst);
- bool let(ParseNode* pn, bool expr, MutableHandleValue dst);
+ bool letBlock(ParseNode* pn, MutableHandleValue dst);
bool importDeclaration(ParseNode* pn, MutableHandleValue dst);
bool importSpecifier(ParseNode* pn, MutableHandleValue dst);
bool exportDeclaration(ParseNode* pn, MutableHandleValue dst);
@@ -2088,7 +2068,7 @@ ASTSerializer::variableDeclarator(ParseNode* pn, MutableHandleValue dst)
}
bool
-ASTSerializer::let(ParseNode* pn, bool expr, MutableHandleValue dst)
+ASTSerializer::letBlock(ParseNode* pn, MutableHandleValue dst)
{
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_left->pn_pos));
MOZ_ASSERT(pn->pn_pos.encloses(pn->pn_right->pn_pos));
@@ -2112,11 +2092,8 @@ ASTSerializer::let(ParseNode* pn, bool expr, MutableHandleValue dst)
}
RootedValue v(cx);
- return expr
- ? expression(letBody->pn_expr, &v) &&
- builder.letExpression(dtors, v, &pn->pn_pos, dst)
- : statement(letBody->pn_expr, &v) &&
- builder.letStatement(dtors, v, &pn->pn_pos, dst);
+ return statement(letBody->pn_expr, &v) &&
+ builder.letStatement(dtors, v, &pn->pn_pos, dst);
}
bool
@@ -2369,7 +2346,7 @@ ASTSerializer::statement(ParseNode* pn, MutableHandleValue dst)
return declaration(pn, dst);
case PNK_LETBLOCK:
- return let(pn, false, dst);
+ return letBlock(pn, dst);
case PNK_LET:
case PNK_CONST:
@@ -3046,9 +3023,6 @@ ASTSerializer::expression(ParseNode* pn, MutableHandleValue dst)
LOCAL_ASSERT(pn->pn_count == 1);
return comprehension(pn->pn_head, dst);
- case PNK_LETEXPR:
- return let(pn, true, dst);
-
default:
LOCAL_NOT_REACHED("unexpected expression type");
}
diff --git a/js/src/vm/Xdr.h b/js/src/vm/Xdr.h
index 4247a8aa9..8db07d385 100644
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -29,11 +29,11 @@ namespace js {
*
* https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
*/
-static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 247;
+static const uint32_t XDR_BYTECODE_VERSION_SUBTRAHEND = 248;
static const uint32_t XDR_BYTECODE_VERSION =
uint32_t(0xb973c0de - XDR_BYTECODE_VERSION_SUBTRAHEND);
-static_assert(JSErr_Limit == 369,
+static_assert(JSErr_Limit == 368,
"GREETINGS, POTENTIAL SUBTRAHEND INCREMENTER! If you added or "
"removed MSG_DEFs from js.msg, you should increment "
"XDR_BYTECODE_VERSION_SUBTRAHEND and update this assertion's "