From 3c5ca419bcd9d8f31c34f7c93389e8d876106592 Mon Sep 17 00:00:00 2001 From: Jeff Walden Date: Fri, 11 Nov 2011 18:05:43 -0800 Subject: [PATCH] Bug 701620 - Split up PNK_LC into PNK_STATEMENTLIST and PNK_XMLCURLYEXPR. r=jorendorff --HG-- extra : rebase_source : 4d781725639c6c94da53fd33fcfcedf221634a35 --- js/src/frontend/BytecodeEmitter.cpp | 39 ++++++++++++++-------------- js/src/frontend/FoldConstants.cpp | 2 +- js/src/frontend/ParseNode.h | 38 +++++++++++++++------------ js/src/frontend/Parser.cpp | 26 +++++++++---------- js/src/frontend/SemanticAnalysis.cpp | 2 +- js/src/jsreflect.cpp | 15 ++++++----- 6 files changed, 65 insertions(+), 57 deletions(-) diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 9b0d53337cf..d5d1b474a47 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1454,7 +1454,8 @@ EmitTraceOp(JSContext *cx, BytecodeEmitter *bce, ParseNode *nextpn) * instruction. nextpn is often a block, in which case the next * instruction typically comes from the first statement inside. */ - if (nextpn->isKind(PNK_LC) && nextpn->isArity(PN_LIST) && nextpn->pn_head) + JS_ASSERT_IF(nextpn->isKind(PNK_STATEMENTLIST), nextpn->isArity(PN_LIST)); + if (nextpn->isKind(PNK_STATEMENTLIST) && nextpn->pn_head) nextpn = nextpn->pn_head; if (!UpdateLineNumberNotes(cx, bce, nextpn->pn_pos.begin.lineno)) return -1; @@ -3345,7 +3346,7 @@ EmitSwitch(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) #if !JS_HAS_BLOCK_SCOPE PushStatement(bce, &stmtInfo, STMT_SWITCH, top); #else - if (pn2->isKind(PNK_LC)) { + if (pn2->isKind(PNK_STATEMENTLIST)) { PushStatement(bce, &stmtInfo, STMT_SWITCH, top); } else { /* Re-push the switch's statement info record. */ @@ -5319,7 +5320,7 @@ EmitXMLTag(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) JS_ASSERT(pn->pn_count != 0); ParseNode *pn2 = pn->pn_head; - if (pn2->isKind(PNK_LC) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) + if (pn2->isKind(PNK_XMLCURLYEXPR) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) return false; if (!EmitTree(cx, bce, pn2)) return false; @@ -5328,11 +5329,11 @@ EmitXMLTag(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) uint32 i; for (pn2 = pn2->pn_next, i = 0; pn2; pn2 = pn2->pn_next, i++) { - if (pn2->isKind(PNK_LC) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) + if (pn2->isKind(PNK_XMLCURLYEXPR) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) return false; if (!EmitTree(cx, bce, pn2)) return false; - if ((i & 1) && pn2->isKind(PNK_LC)) { + if ((i & 1) && pn2->isKind(PNK_XMLCURLYEXPR)) { if (Emit1(cx, bce, JSOP_TOATTRVAL) < 0) return false; } @@ -5788,7 +5789,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) /* * This second pass is needed to emit JSOP_NOP with a source note * for the already-emitted function definition prolog opcode. See - * comments in the PNK_LC case. + * comments in the PNK_STATEMENTLIST case. */ JS_ASSERT(pn->isOp(JSOP_NOP)); JS_ASSERT(bce->inFunction()); @@ -6176,18 +6177,18 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) break; #endif - case PNK_LC: - { #if JS_HAS_XML_SUPPORT - if (pn->isArity(PN_UNARY)) { - if (!EmitTree(cx, bce, pn->pn_kid)) - return JS_FALSE; - if (Emit1(cx, bce, pn->getOp()) < 0) - return JS_FALSE; - break; - } + case PNK_XMLCURLYEXPR: + JS_ASSERT(pn->isArity(PN_UNARY)); + if (!EmitTree(cx, bce, pn->pn_kid)) + return JS_FALSE; + if (Emit1(cx, bce, pn->getOp()) < 0) + return JS_FALSE; + break; #endif + case PNK_STATEMENTLIST: + { JS_ASSERT(pn->isArity(PN_LIST)); noteIndex = -1; @@ -6355,9 +6356,9 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) return JS_FALSE; pn2 = pn->expr(); - noteType = (pn2->isKind(PNK_LC) || + noteType = (pn2->isKind(PNK_STATEMENTLIST) || (pn2->isKind(PNK_LEXICALSCOPE) && - pn2->expr()->isKind(PNK_LC))) + pn2->expr()->isKind(PNK_STATEMENTLIST))) ? SRC_LABELBRACE : SRC_LABEL; noteIndex = NewSrcNote2(cx, bce, noteType, ptrdiff_t(index)); @@ -7291,7 +7292,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) } for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { - if (pn2->isKind(PNK_LC) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) + if (pn2->isKind(PNK_XMLCURLYEXPR) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) return JS_FALSE; if (!EmitTree(cx, bce, pn2)) return JS_FALSE; @@ -7330,7 +7331,7 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn) if (pn->isArity(PN_LIST)) { JS_ASSERT(pn->pn_count != 0); for (pn2 = pn->pn_head; pn2; pn2 = pn2->pn_next) { - if (pn2->isKind(PNK_LC) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) + if (pn2->isKind(PNK_XMLCURLYEXPR) && Emit1(cx, bce, JSOP_STARTXMLEXPR) < 0) return JS_FALSE; if (!EmitTree(cx, bce, pn2)) return JS_FALSE; diff --git a/js/src/frontend/FoldConstants.cpp b/js/src/frontend/FoldConstants.cpp index 0b56ddb4076..f50fd1dafc5 100644 --- a/js/src/frontend/FoldConstants.cpp +++ b/js/src/frontend/FoldConstants.cpp @@ -594,7 +594,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond) * NB: pn must be a PNK_IF as PNK_HOOK can never have a null kid * or an empty statement for a child. */ - pn->setKind(PNK_LC); + pn->setKind(PNK_STATEMENTLIST); pn->setArity(PN_LIST); pn->makeEmpty(); } diff --git a/js/src/frontend/ParseNode.h b/js/src/frontend/ParseNode.h index f3b9944e800..dcb6eb900bd 100644 --- a/js/src/frontend/ParseNode.h +++ b/js/src/frontend/ParseNode.h @@ -80,7 +80,8 @@ enum ParseNodeKind { PNK_DOT, PNK_LB, PNK_RB, - PNK_LC, + PNK_STATEMENTLIST, + PNK_XMLCURLYEXPR, PNK_RC, PNK_LP, PNK_RP, @@ -205,30 +206,33 @@ enum ParseNodeKind { * create the function object at parse (not emit) * time to specialize arg and var bytecodes early. * pn_body: PNK_UPVARS if the function's source body - * depends on outer names, else PNK_ARGSBODY - * if formal parameters, else PNK_LC node for - * function body statements, else PNK_RETURN - * for expression closure, else PNK_SEQ for - * expression closure with destructured - * formal parameters + * depends on outer names, + * PNK_ARGSBODY if formal parameters, + * PNK_STATEMENTLIST node for function body + * statements, + * PNK_RETURN for expression closure, or + * PNK_SEQ for expression closure with + * destructured formal parameters * pn_cookie: static level and var index for function * pn_dflags: PND_* definition/use flags (see below) * pn_blockid: block id number - * PNK_ARGSBODY list list of formal parameters followed by PNK_LC node - * for function body statements as final element + * PNK_ARGSBODY list list of formal parameters followed by + * PNK_STATEMENTLIST node for function body + * statements as final element * pn_count: 1 + number of formal parameters * PNK_UPVARS nameset pn_names: lexical dependencies (js::Definitions) * defined in enclosing scopes, or ultimately not * defined (free variables, either global property * references or reference errors). - * pn_tree: PNK_ARGSBODY or PNK_LC node + * pn_tree: PNK_ARGSBODY or PNK_STATEMENTLIST node * * - * PNK_LC list pn_head: list of pn_count statements + * PNK_STATEMENTLIST list pn_head: list of pn_count statements * PNK_IF ternary pn_kid1: cond, pn_kid2: then, pn_kid3: else or null. * In body of a comprehension or desugared generator * expression, pn_kid2 is PNK_YIELD, PNK_ARRAYPUSH, - * or (if the push was optimized away) empty PNK_LC. + * or (if the push was optimized away) empty + * PNK_STATEMENTLIST. * PNK_SWITCH binary pn_left: discriminant * pn_right: list of PNK_CASE nodes, with at most one * PNK_DEFAULT node, or if there are let bindings @@ -236,9 +240,11 @@ enum ParseNodeKind { * PNK_LEXICALSCOPE node that contains the list of * PNK_CASE nodes. * PNK_CASE, binary pn_left: case expr - * pn_right: PNK_LC node for this case's statements + * pn_right: PNK_STATEMENTLIST node for this case's + * statements * PNK_DEFAULT binary pn_left: null - * pn_right: PNK_LC node for this default's statements + * pn_right: PNK_STATEMENTLIST node for this default's + * statements * pn_val: constant value if lookup or table switch * PNK_WHILE binary pn_left: cond, pn_right: body * PNK_DOWHILE binary pn_left: body, pn_right: cond @@ -417,7 +423,7 @@ enum ParseNodeKind { * PNK_XMLPI nullary pn_pitarget: XML processing instruction target * pn_pidata: XML PI data, or null if no data * PNK_XMLTEXT nullary pn_atom: marked-up text, or null if empty string - * PNK_LC unary {expr} in XML tag or content; pn_kid is expr + * PNK_XMLCURLYEXPR unary {expr} in XML tag or content; pn_kid is expr * * So an XML tag with no {expr} and three attributes is a list with the form: * @@ -432,7 +438,7 @@ enum ParseNodeKind { * ((name1 {expr1}) (name2 {expr2} name3) {expr3}) * * where () bracket a list with elements separated by spaces, and {expr} is a - * PNK_LC unary node with expr as its kid. + * PNK_XMLCURLYEXPR unary node with expr as its kid. * * Thus, the attribute name/value pairs occupy successive odd and even list * locations, where pn_head is the PNK_XMLNAME node at list location 0. The diff --git a/js/src/frontend/Parser.cpp b/js/src/frontend/Parser.cpp index 26cea1eea37..c7ec97f7ab8 100644 --- a/js/src/frontend/Parser.cpp +++ b/js/src/frontend/Parser.cpp @@ -261,7 +261,7 @@ GenerateBlockIdForStmtNode(ParseNode *pn, TreeContext *tc) { JS_ASSERT(tc->topStmt); JS_ASSERT(STMT_MAYBE_SCOPE(tc->topStmt)); - JS_ASSERT(pn->isKind(PNK_LC) || pn->isKind(PNK_LEXICALSCOPE)); + JS_ASSERT(pn->isKind(PNK_STATEMENTLIST) || pn->isKind(PNK_LEXICALSCOPE)); if (!GenerateBlockId(tc, tc->topStmt->blockid)) return false; pn->pn_blockid = tc->topStmt->blockid; @@ -321,7 +321,7 @@ HasFinalReturn(ParseNode *pn) uintN rv, rv2, hasDefault; switch (pn->getKind()) { - case PNK_LC: + case PNK_STATEMENTLIST: if (!pn->pn_head) return ENDS_IN_OTHER; return HasFinalReturn(pn->last()); @@ -368,7 +368,7 @@ HasFinalReturn(ParseNode *pn) if (pn2->isKind(PNK_DEFAULT)) hasDefault = ENDS_IN_RETURN; pn3 = pn2->pn_right; - JS_ASSERT(pn3->isKind(PNK_LC)); + JS_ASSERT(pn3->isKind(PNK_STATEMENTLIST)); if (pn3->pn_head) { rv2 = HasFinalReturn(pn3->last()); if (rv2 == ENDS_IN_OTHER && pn2->pn_next) @@ -1771,7 +1771,7 @@ Parser::statements() JS_CHECK_RECURSION(context, return NULL); - ParseNode *pn = ListNode::create(PNK_LC, tc); + ParseNode *pn = ListNode::create(PNK_STATEMENTLIST, tc); if (!pn) return NULL; pn->makeEmpty(); @@ -2951,7 +2951,7 @@ Parser::switchStatement() PushStatement(tc, &stmtInfo, STMT_SWITCH, -1); /* pn2 is a list of case nodes. The default case has pn_left == NULL */ - ParseNode *pn2 = ListNode::create(PNK_LC, tc); + ParseNode *pn2 = ListNode::create(PNK_STATEMENTLIST, tc); if (!pn2) return NULL; pn2->makeEmpty(); @@ -3003,7 +3003,7 @@ Parser::switchStatement() MUST_MATCH_TOKEN(TOK_COLON, JSMSG_COLON_AFTER_CASE); - ParseNode *pn4 = ListNode::create(PNK_LC, tc); + ParseNode *pn4 = ListNode::create(PNK_STATEMENTLIST, tc); if (!pn4) return NULL; pn4->makeEmpty(); @@ -3757,7 +3757,7 @@ Parser::expressionStatement() /* Normalize empty statement to empty block for the decompiler. */ if (pn->isKind(PNK_SEMI) && !pn->pn_kid) { - pn->setKind(PNK_LC); + pn->setKind(PNK_STATEMENTLIST); pn->setArity(PN_LIST); pn->makeEmpty(); } @@ -6038,7 +6038,7 @@ Parser::xmlExpr(JSBool inTag) JS_ASSERT(!tc->inStrictMode()); JS_ASSERT(tokenStream.currentToken().type == TOK_LC); - ParseNode *pn = UnaryNode::create(PNK_LC, tc); + ParseNode *pn = UnaryNode::create(PNK_XMLCURLYEXPR, tc); if (!pn) return NULL; @@ -6083,7 +6083,7 @@ Parser::atomNode(ParseNodeKind kind, JSOp op) * Return a PN_LIST, PN_UNARY, or PN_NULLARY according as XMLNameExpr produces * a list of names and/or expressions, a single expression, or a single name. * If PN_LIST or PN_NULLARY, getKind() will be PNK_XMLNAME. Otherwise if - * PN_UNARY, getKind() will be PNK_LC. + * PN_UNARY, getKind() will be PNK_XMLCURLYEXPR. */ ParseNode * Parser::xmlNameExpr() @@ -6135,7 +6135,7 @@ Parser::xmlNameExpr() */ #define XML_FOLDABLE(pn) ((pn)->isArity(PN_LIST) \ ? ((pn)->pn_xflags & PNX_CANTFOLD) == 0 \ - : !(pn)->isKind(PNK_LC)) + : !(pn)->isKind(PNK_XMLCURLYEXPR)) /* * Parse the productions: @@ -6152,7 +6152,7 @@ Parser::xmlNameExpr() * If PN_LIST or PN_NULLARY, getKind() will be PNK_XMLNAME for the case where * XMLTagContent: XMLNameExpr. If getKind() is not PNK_XMLNAME but getArity() * is PN_LIST, getKind() will be tagkind. If PN_UNARY, getKind() will be - * PNK_LC and we parsed exactly one expression. + * PNK_XMLCURLYEXPR and we parsed exactly one expression. */ ParseNode * Parser::xmlTagContent(ParseNodeKind tagkind, JSAtom **namep) @@ -6333,7 +6333,7 @@ Parser::xmlElementOrList(JSBool allowList) freeTree(pn); pn = pn2; } else { - JS_ASSERT(pn2->isKind(PNK_XMLNAME) || pn2->isKind(PNK_LC)); + JS_ASSERT(pn2->isKind(PNK_XMLNAME) || pn2->isKind(PNK_XMLCURLYEXPR)); pn->initList(pn2); if (!XML_FOLDABLE(pn2)) pn->pn_xflags |= PNX_CANTFOLD; @@ -6395,7 +6395,7 @@ Parser::xmlElementOrList(JSBool allowList) } /* Make a TOK_XMLETAGO list with pn2 as its single child. */ - JS_ASSERT(pn2->isKind(PNK_XMLNAME) || pn2->isKind(PNK_LC)); + JS_ASSERT(pn2->isKind(PNK_XMLNAME) || pn2->isKind(PNK_XMLCURLYEXPR)); list = ListNode::create(PNK_XMLETAGO, tc); if (!list) return NULL; diff --git a/js/src/frontend/SemanticAnalysis.cpp b/js/src/frontend/SemanticAnalysis.cpp index 03eabc26bcd..25437bcfa12 100644 --- a/js/src/frontend/SemanticAnalysis.cpp +++ b/js/src/frontend/SemanticAnalysis.cpp @@ -533,7 +533,7 @@ ConsiderUnbranding(FunctionBox *funbox) pn2 = pn2->pn_tree; if (pn2->isKind(PNK_ARGSBODY)) pn2 = pn2->last(); - if (!pn2->isKind(PNK_LC)) + if (!pn2->isKind(PNK_STATEMENTLIST)) returnsExpr = true; } #endif diff --git a/js/src/jsreflect.cpp b/js/src/jsreflect.cpp index a56e9caeb87..de4cc9fc40b 100644 --- a/js/src/jsreflect.cpp +++ b/js/src/jsreflect.cpp @@ -1810,7 +1810,8 @@ ASTSerializer::binop(ParseNodeKind kind, JSOp op) bool ASTSerializer::statements(ParseNode *pn, NodeVector &elts) { - JS_ASSERT(pn->isKind(PNK_LC) && pn->isArity(PN_LIST)); + JS_ASSERT(pn->isKind(PNK_STATEMENTLIST)); + JS_ASSERT(pn->isArity(PN_LIST)); if (!elts.reserve(pn->pn_count)) return false; @@ -1860,7 +1861,7 @@ ASTSerializer::xmls(ParseNode *pn, NodeVector &elts) bool ASTSerializer::blockStatement(ParseNode *pn, Value *dst) { - JS_ASSERT(pn->isKind(PNK_LC)); + JS_ASSERT(pn->isKind(PNK_STATEMENTLIST)); NodeVector stmts(cx); return statements(pn, stmts) && @@ -2111,11 +2112,11 @@ ASTSerializer::statement(ParseNode *pn, Value *dst) builder.letStatement(dtors, stmt, &pn->pn_pos, dst); } - if (!pn->isKind(PNK_LC)) + if (!pn->isKind(PNK_STATEMENTLIST)) return statement(pn, dst); /* FALL THROUGH */ - case PNK_LC: + case PNK_STATEMENTLIST: return blockStatement(pn, dst); case PNK_IF: @@ -2337,7 +2338,7 @@ ASTSerializer::comprehension(ParseNode *pn, Value *dst) if (!optExpression(next->pn_kid1, &filter)) return false; next = next->pn_kid2; - } else if (next->isKind(PNK_LC) && next->pn_count == 0) { + } else if (next->isKind(PNK_STATEMENTLIST) && next->pn_count == 0) { /* FoldConstants optimized away the push. */ NodeVector empty(cx); return builder.arrayExpression(empty, &pn->pn_pos, dst); @@ -2714,7 +2715,7 @@ ASTSerializer::xml(ParseNode *pn, Value *dst) JS_CHECK_RECURSION(cx, return false); switch (pn->getKind()) { #ifdef JS_HAS_XML_SUPPORT - case PNK_LC: + case PNK_XMLCURLYEXPR: { Value expr; return expression(pn->pn_kid, &expr) && @@ -3049,7 +3050,7 @@ ASTSerializer::functionArgsAndBody(ParseNode *pn, NodeVector &args, Value *body) expression(pnstart->pn_kid, body); } - case PNK_LC: /* statement closure */ + case PNK_STATEMENTLIST: /* statement closure */ { ParseNode *pnstart = (pnbody->pn_xflags & PNX_DESTRUCT) ? pnbody->pn_head->pn_next