Bug 701620 - Use two different kinds for the + operator when used in unary and binary expressions, likewise for -. r=jorendorff

--HG--
extra : rebase_source : ae4b6490a658893b51a069ac40151ca63fff0055
This commit is contained in:
Jeff Walden 2011-11-05 12:20:22 -07:00
parent 04598ac634
commit 1f0255090e
7 changed files with 36 additions and 40 deletions

View File

@ -6536,10 +6536,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
}
break;
case PNK_PLUS:
case PNK_MINUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
case PNK_ADD:
case PNK_SUB:
case PNK_BITOR:
case PNK_BITXOR:
case PNK_BITAND:
@ -6637,7 +6635,8 @@ frontend::EmitTree(JSContext *cx, BytecodeEmitter *bce, ParseNode *pn)
case PNK_VOID:
case PNK_NOT:
case PNK_BITNOT:
unary_plusminus:
case PNK_POS:
case PNK_NEG:
{
/* Unary op, including unary +/-. */
op = pn->getOp();

View File

@ -683,9 +683,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
case PNK_ADDASSIGN:
JS_ASSERT(pn->isOp(JSOP_ADD));
/* FALL THROUGH */
case PNK_PLUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
case PNK_ADD:
if (pn->isArity(PN_LIST)) {
/*
* Any string literal term with all others number or string means
@ -767,10 +765,7 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
/* Can't concatenate string literals, let's try numbers. */
goto do_binary_op;
case PNK_MINUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
/* FALL THROUGH */
case PNK_SUB:
case PNK_STAR:
case PNK_LSH:
case PNK_RSH:
@ -819,7 +814,8 @@ js::FoldConstants(JSContext *cx, ParseNode *pn, TreeContext *tc, bool inCond)
case PNK_VOID:
case PNK_NOT:
case PNK_BITNOT:
unary_plusminus:
case PNK_POS:
case PNK_NEG:
if (pn1->isKind(PNK_NUMBER)) {
jsdouble d;

View File

@ -405,7 +405,7 @@ ParseNode::append(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right
left->pn_parens = false;
left->initList(pn1);
left->append(pn2);
if (kind == PNK_PLUS) {
if (kind == PNK_ADD) {
if (pn1->isKind(PNK_STRING))
left->pn_xflags |= PNX_STRCAT;
else if (!pn1->isKind(PNK_NUMBER))
@ -418,7 +418,7 @@ ParseNode::append(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right
}
left->append(right);
left->pn_pos.end = right->pn_pos.end;
if (kind == PNK_PLUS) {
if (kind == PNK_ADD) {
if (right->isKind(PNK_STRING))
left->pn_xflags |= PNX_STRCAT;
else if (!right->isKind(PNK_NUMBER))
@ -437,19 +437,19 @@ ParseNode::newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, Parse
/*
* Flatten a left-associative (left-heavy) tree of a given operator into
* a list, to reduce js_FoldConstants and js_EmitTree recursion.
* a list to reduce js::FoldConstants and js::frontend::EmitTree recursion.
*/
if (left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC))
return append(kind, op, left, right);
/*
* Fold constant addition immediately, to conserve node space and, what's
* more, so js_FoldConstants never sees mixed addition and concatenation
* more, so js::FoldConstants never sees mixed addition and concatenation
* operations with more than one leading non-string operand in a PN_LIST
* generated for expressions such as 1 + 2 + "pt" (which should evaluate
* to "3pt", not "12pt").
*/
if (kind == PNK_PLUS &&
if (kind == PNK_ADD &&
left->isKind(PNK_NUMBER) &&
right->isKind(PNK_NUMBER) &&
tc->parser->foldConstants)

View File

@ -68,8 +68,10 @@ enum ParseNodeKind {
PNK_BITOR,
PNK_BITXOR,
PNK_BITAND,
PNK_PLUS,
PNK_MINUS,
PNK_POS,
PNK_NEG,
PNK_ADD,
PNK_SUB,
PNK_STAR,
PNK_DIV,
PNK_MOD,
@ -321,19 +323,20 @@ enum ParseNodeKind {
* PNK_LSH, binary pn_left: left-assoc SH expr, pn_right: ADD expr
* PNK_RSH,
* PNK_URSH
* PNK_PLUS, binary pn_left: left-assoc ADD expr, pn_right: MUL expr
* pn_xflags: if a left-associated binary PNK_PLUS
* PNK_ADD binary pn_left: left-assoc ADD expr, pn_right: MUL expr
* pn_xflags: if a left-associated binary PNK_ADD
* tree has been flattened into a list (see above
* under <Expressions>), pn_xflags will contain
* PNX_STRCAT if at least one list element is a
* string literal (PNK_STRING); if such a list has
* any non-string, non-number term, pn_xflags will
* contain PNX_CANTFOLD.
* pn_
* PNK_MINUS pn_op: JSOP_ADD, JSOP_SUB
* PNK_SUB binary pn_left: left-assoc SH expr, pn_right: ADD expr
* PNK_STAR, binary pn_left: left-assoc MUL expr, pn_right: UNARY expr
* PNK_DIV, pn_op: JSOP_MUL, JSOP_DIV, JSOP_MOD
* PNK_MOD
* PNK_POS, unary pn_kid: UNARY expr
* PNK_NEG
* PNK_TYPEOF, unary pn_kid: UNARY expr
* PNK_VOID,
* PNK_NOT,
@ -711,8 +714,8 @@ struct ParseNode {
#define PND_USE2DEF_FLAGS (PND_ASSIGNED | PND_FUNARG | PND_CLOSED)
/* PN_LIST pn_xflags bits. */
#define PNX_STRCAT 0x01 /* PNK_PLUS list has string term */
#define PNX_CANTFOLD 0x02 /* PNK_PLUS list has unfoldable term */
#define PNX_STRCAT 0x01 /* PNK_ADD list has string term */
#define PNX_CANTFOLD 0x02 /* PNK_ADD list has unfoldable term */
#define PNX_POPVAR 0x04 /* PNK_VAR last result needs popping */
#define PNX_FORINVAR 0x08 /* PNK_VAR is left kid of PNK_IN node,
which is left kid of PNK_FOR */

View File

@ -4381,7 +4381,7 @@ BEGIN_EXPR_PARSER(addExpr1)
while (pn && tokenStream.isCurrentTokenType(TOK_PLUS, TOK_MINUS)) {
TokenKind tt = tokenStream.currentToken().type;
JSOp op = (tt == TOK_PLUS) ? JSOP_ADD : JSOP_SUB;
ParseNodeKind kind = (tt == TOK_PLUS) ? PNK_PLUS : PNK_MINUS;
ParseNodeKind kind = (tt == TOK_PLUS) ? PNK_ADD : PNK_SUB;
pn = ParseNode::newBinaryOrAppend(kind, op, pn, mulExpr1n(), tc);
}
return pn;
@ -4782,9 +4782,9 @@ Parser::unaryExpr()
case TOK_BITNOT:
return unaryOpExpr(PNK_BITNOT, JSOP_BITNOT);
case TOK_PLUS:
return unaryOpExpr(PNK_PLUS, JSOP_POS);
return unaryOpExpr(PNK_POS, JSOP_POS);
case TOK_MINUS:
return unaryOpExpr(PNK_MINUS, JSOP_NEG);
return unaryOpExpr(PNK_NEG, JSOP_NEG);
case TOK_INC:
case TOK_DEC:

View File

@ -1780,10 +1780,10 @@ ASTSerializer::binop(ParseNodeKind kind, JSOp op)
return BINOP_STRICTEQ;
case PNK_STRICTNE:
return BINOP_STRICTNE;
case PNK_PLUS:
return BINOP_PLUS;
case PNK_MINUS:
return BINOP_MINUS;
case PNK_ADD:
return BINOP_ADD;
case PNK_SUB:
return BINOP_SUB;
case PNK_STAR:
return BINOP_STAR;
case PNK_DIV:
@ -2454,11 +2454,8 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
builder.assignmentExpression(op, lhs, rhs, &pn->pn_pos, dst);
}
case PNK_PLUS:
case PNK_MINUS:
if (pn->isArity(PN_UNARY))
goto unary_plusminus;
/* FALL THROUGH */
case PNK_ADD:
case PNK_SUB:
case PNK_STRICTEQ:
case PNK_EQ:
case PNK_STRICTNE:
@ -2495,7 +2492,8 @@ ASTSerializer::expression(ParseNode *pn, Value *dst)
case PNK_VOID:
case PNK_NOT:
case PNK_BITNOT:
unary_plusminus: {
case PNK_POS:
case PNK_NEG: {
UnaryOperator op = unop(pn->getKind(), pn->getOp());
LOCAL_ASSERT(op > UNOP_ERR && op < UNOP_LIMIT);

View File

@ -81,7 +81,7 @@ enum BinaryOperator {
/* shift */
BINOP_LSH, BINOP_RSH, BINOP_URSH,
/* arithmetic */
BINOP_PLUS, BINOP_MINUS, BINOP_STAR, BINOP_DIV, BINOP_MOD,
BINOP_ADD, BINOP_SUB, BINOP_STAR, BINOP_DIV, BINOP_MOD,
/* binary */
BINOP_BITOR, BINOP_BITXOR, BINOP_BITAND,
/* misc */