Bug 701620 - Use two different kinds for the + operator when used in unary and binary expressions, likewise for -. r=jorendorff
authorJeff Walden <jwalden@mit.edu>
Sat, 05 Nov 2011 12:20:22 -0700
changeset 81682 6ae5203fe3e158e5b343d36d438ac73583cb5294
parent 81681 9e33bed54f9afd107dd048f470111a96c34fce57
child 81683 1030be78cb5126ec2644fc23e9e8c9c54632edc1
push idunknown
push userunknown
push dateunknown
reviewersjorendorff
bugs701620
milestone11.0a1
Bug 701620 - Use two different kinds for the + operator when used in unary and binary expressions, likewise for -. r=jorendorff
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/FoldConstants.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.cpp
js/src/jsreflect.cpp
js/src/jsreflect.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -6531,20 +6531,18 @@ frontend::EmitTree(JSContext *cx, Byteco
                 tmp = GetJumpOffset(bce, pc);
                 CHECK_AND_SET_JUMP_OFFSET(cx, bce, pc, off - top);
                 *pc = pn->getOp();
                 top += tmp;
             } while ((pn2 = pn2->pn_next)->pn_next);
         }
         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:
       case PNK_STRICTEQ:
       case PNK_EQ:
       case PNK_STRICTNE:
       case PNK_NE:
       case PNK_LT:
@@ -6632,17 +6630,18 @@ frontend::EmitTree(JSContext *cx, Byteco
       case PNK_DEFXMLNS:
         JS_ASSERT(pn->isArity(PN_UNARY));
         /* FALL THROUGH */
 #endif
       case PNK_TYPEOF:
       case PNK_VOID:
       case PNK_NOT:
       case PNK_BITNOT:
-      unary_plusminus:
+      case PNK_POS:
+      case PNK_NEG:
       {
         /* Unary op, including unary +/-. */
         op = pn->getOp();
         pn2 = pn->pn_kid;
 
         JS_ASSERT(op != JSOP_XMLNAME);
         if (op == JSOP_TYPEOF && !pn2->isKind(PNK_NAME))
             op = JSOP_TYPEOFEXPR;
--- a/js/src/frontend/FoldConstants.cpp
+++ b/js/src/frontend/FoldConstants.cpp
@@ -678,19 +678,17 @@ js::FoldConstants(JSContext *cx, ParseNo
          * compiled from that same string.  += is special and so must be
          * handled below.
          */
         goto do_binary_op;
 
       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
              * this is a concatenation.  If any term is not a string or number
              * literal, we can't fold.
              */
             JS_ASSERT(pn->pn_count > 2);
             if (pn->pn_xflags & PNX_CANTFOLD)
@@ -762,20 +760,17 @@ js::FoldConstants(JSContext *cx, ParseNo
             tc->freeTree(pn1);
             tc->freeTree(pn2);
             break;
         }
 
         /* 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:
       case PNK_URSH:
       case PNK_DIV:
       case PNK_MOD:
       do_binary_op:
         if (pn->isArity(PN_LIST)) {
@@ -814,17 +809,18 @@ js::FoldConstants(JSContext *cx, ParseNo
             }
         }
         break;
 
       case PNK_TYPEOF:
       case PNK_VOID:
       case PNK_NOT:
       case PNK_BITNOT:
-      unary_plusminus:
+      case PNK_POS:
+      case PNK_NEG:
         if (pn1->isKind(PNK_NUMBER)) {
             jsdouble d;
 
             /* Operate on one numeric constant. */
             d = pn1->pn_dval;
             switch (pn->getOp()) {
               case JSOP_BITNOT:
                 d = ~js_DoubleToECMAInt32(d);
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -400,30 +400,30 @@ ParseNode::append(ParseNodeKind kind, JS
     JS_ASSERT(left->isKind(kind) && left->isOp(op) && (js_CodeSpec[op].format & JOF_LEFTASSOC));
 
     if (left->pn_arity != PN_LIST) {
         ParseNode *pn1 = left->pn_left, *pn2 = left->pn_right;
         left->setArity(PN_LIST);
         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))
                 left->pn_xflags |= PNX_CANTFOLD;
             if (pn2->isKind(PNK_STRING))
                 left->pn_xflags |= PNX_STRCAT;
             else if (!pn2->isKind(PNK_NUMBER))
                 left->pn_xflags |= PNX_CANTFOLD;
         }
     }
     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))
             left->pn_xflags |= PNX_CANTFOLD;
     }
 
     return left;
 }
@@ -432,29 +432,29 @@ ParseNode *
 ParseNode::newBinaryOrAppend(ParseNodeKind kind, JSOp op, ParseNode *left, ParseNode *right,
                              TreeContext *tc)
 {
     if (!left || !right)
         return NULL;
 
     /*
      * 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)
     {
         left->pn_dval += right->pn_dval;
         left->pn_pos.end = right->pn_pos.end;
         tc->freeTree(right);
         return left;
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -63,18 +63,20 @@ enum ParseNodeKind {
     PNK_COMMA,
     PNK_HOOK,
     PNK_COLON,
     PNK_OR,
     PNK_AND,
     PNK_BITOR,
     PNK_BITXOR,
     PNK_BITAND,
-    PNK_PLUS,
-    PNK_MINUS,
+    PNK_POS,
+    PNK_NEG,
+    PNK_ADD,
+    PNK_SUB,
     PNK_STAR,
     PNK_DIV,
     PNK_MOD,
     PNK_INC,
     PNK_DEC,
     PNK_DOT,
     PNK_LB,
     PNK_RB,
@@ -316,29 +318,30 @@ enum ParseNodeKind {
  * PNK_STRICTNE
  * PNK_LT,      binary      pn_left: left-assoc REL expr, pn_right: SH expr
  * PNK_LE,
  * PNK_GT,
  * PNK_GE
  * 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,
  * PNK_BITNOT
  * PNK_INC,     unary       pn_kid: MEMBER expr
  * PNK_DEC
  * PNK_NEW      list        pn_head: list of ctor, arg1, arg2, ... argN
  *                          pn_count: 1 + N (where N is number of args)
@@ -706,18 +709,18 @@ struct ParseNode {
                                            still valid, but this use no longer
                                            optimizable via an upvar opcode */
 #define PND_CLOSED      0x800           /* variable is closed over */
 
 /* Flags to propagate from uses to definition. */
 #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 */
 #define PNX_ENDCOMMA    0x10            /* array literal has comma at end */
 #define PNX_XMLROOT     0x20            /* top-most node in XML literal tree */
 #define PNX_GROUPINIT   0x40            /* var [a, b] = [c, d]; unit list */
 #define PNX_NEEDBRACES  0x80            /* braces necessary due to closure */
 #define PNX_FUNCDEFS   0x100            /* contains top-level function statements */
--- a/js/src/frontend/Parser.cpp
+++ b/js/src/frontend/Parser.cpp
@@ -4376,17 +4376,17 @@ BEGIN_EXPR_PARSER(mulExpr1)
 END_EXPR_PARSER(mulExpr1)
 
 BEGIN_EXPR_PARSER(addExpr1)
 {
     ParseNode *pn = mulExpr1i();
     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;
 }
 END_EXPR_PARSER(addExpr1)
 
 inline ParseNodeKind
 ShiftTokenToParseNodeKind(const Token &token)
@@ -4777,19 +4777,19 @@ Parser::unaryExpr()
         return unaryOpExpr(PNK_TYPEOF, JSOP_TYPEOF);
       case TOK_VOID:
         return unaryOpExpr(PNK_VOID, JSOP_VOID);
       case TOK_NOT:
         return unaryOpExpr(PNK_NOT, JSOP_NOT);
       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:
         pn = UnaryNode::create((tt == TOK_INC) ? PNK_INC : PNK_DEC, tc);
         if (!pn)
             return NULL;
         pn2 = memberExpr(JS_TRUE);
         if (!pn2)
--- a/js/src/jsreflect.cpp
+++ b/js/src/jsreflect.cpp
@@ -1775,20 +1775,20 @@ ASTSerializer::binop(ParseNodeKind kind,
       case PNK_EQ:
         return BINOP_EQ;
       case PNK_NE:
         return BINOP_NE;
       case PNK_STRICTEQ:
         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:
         return BINOP_DIV;
       case PNK_MOD:
         return BINOP_MOD;
       case PNK_BITOR:
         return BINOP_BITOR;
@@ -2449,21 +2449,18 @@ ASTSerializer::expression(ParseNode *pn,
         LOCAL_ASSERT(op > AOP_ERR && op < AOP_LIMIT);
 
         Value lhs, rhs;
         return pattern(pn->pn_left, NULL, &lhs) &&
                expression(pn->pn_right, &rhs) &&
                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:
       case PNK_NE:
       case PNK_LT:
       case PNK_LE:
       case PNK_GT:
       case PNK_GE:
@@ -2490,17 +2487,18 @@ ASTSerializer::expression(ParseNode *pn,
         }
         return leftAssociate(pn, dst);
 
       case PNK_DELETE:
       case PNK_TYPEOF:
       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);
 
         Value expr;
         return expression(pn->pn_kid, &expr) &&
                builder.unaryExpression(op, expr, &pn->pn_pos, dst);
       }
 
--- a/js/src/jsreflect.h
+++ b/js/src/jsreflect.h
@@ -76,17 +76,17 @@ enum BinaryOperator {
 
     /* eq */
     BINOP_EQ = 0, BINOP_NE, BINOP_STRICTEQ, BINOP_STRICTNE,
     /* rel */
     BINOP_LT, BINOP_LE, BINOP_GT, BINOP_GE,
     /* 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 */
     BINOP_IN, BINOP_INSTANCEOF,
     /* xml */
     BINOP_DBLDOT,
 
     BINOP_LIMIT