Bug 695752 - Part 1 - Give js::ParseNode a constructor. r=luke.
authorJason Orendorff <jorendorff@mozilla.com>
Wed, 19 Oct 2011 16:43:21 -0500
changeset 79635 7a5a2d0857bdc39f54013d712747652d85e4a5fe
parent 79634 959ff7fea1e8130affc569b617dac85967db20df
child 79636 7e5a4585d4658122de696a13601fd54eb9b92a72
push id506
push userclegnitto@mozilla.com
push dateWed, 09 Nov 2011 02:03:18 +0000
treeherdermozilla-aurora@63587fc7bb93 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersluke
bugs695752
milestone10.0a1
Bug 695752 - Part 1 - Give js::ParseNode a constructor. r=luke.
js/src/frontend/BytecodeGenerator.cpp
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
js/src/frontend/Parser.h
--- a/js/src/frontend/BytecodeGenerator.cpp
+++ b/js/src/frontend/BytecodeGenerator.cpp
@@ -3070,17 +3070,17 @@ EmitNameIncDec(JSContext *cx, ParseNode 
 
     return true;
 }
 
 static JSBool
 EmitElemOp(JSContext *cx, ParseNode *pn, JSOp op, CodeGenerator *cg)
 {
     ptrdiff_t top;
-    ParseNode *left, *right, *next, ltmp, rtmp;
+    ParseNode *left, *right, *next;
     int32_t slot;
 
     top = CG_OFFSET(cg);
     if (pn->isArity(PN_LIST)) {
         /* Left-associative operator chain to avoid too much recursion. */
         JS_ASSERT(pn->isOp(JSOP_GETELEM));
         JS_ASSERT(pn->pn_count >= 3);
         left = pn->pn_head;
@@ -3090,17 +3090,17 @@ EmitElemOp(JSContext *cx, ParseNode *pn,
 
         /*
          * Try to optimize arguments[0][j]... into JSOP_ARGSUB<0> followed by
          * one or more index expression and JSOP_GETELEM op pairs. If type
          * inference is enabled this is optimized separately.
          */
         if (left->isKind(TOK_NAME) && next->isKind(TOK_NUMBER)) {
             if (!BindNameToSlot(cx, cg, left))
-                return JS_FALSE;
+                return false;
             if (left->isOp(JSOP_ARGUMENTS) &&
                 JSDOUBLE_IS_INT32(next->pn_dval, &slot) &&
                 jsuint(slot) < JS_BIT(16) &&
                 !cx->typeInferenceEnabled() &&
                 (!cg->inStrictMode() ||
                  (!cg->mutatesParameter() && !cg->callsEval()))) {
                 /*
                  * arguments[i]() requires arguments object as "this".
@@ -3119,89 +3119,91 @@ EmitElemOp(JSContext *cx, ParseNode *pn,
          * one more index expression to emit.  Given arguments[0][j], we must
          * skip the while loop altogether, falling through to emit code for j
          * (in the subtree referenced by right), followed by the annotated op,
          * at the bottom of this function.
          */
         JS_ASSERT(next != right || pn->pn_count == 3);
         if (left == pn->pn_head) {
             if (!EmitTree(cx, cg, left))
-                return JS_FALSE;
+                return false;
         }
         while (next != right) {
             if (!EmitTree(cx, cg, next))
-                return JS_FALSE;
+                return false;
             if (NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
-                return JS_FALSE;
+                return false;
             if (!EmitElemOpBase(cx, cg, JSOP_GETELEM))
-                return JS_FALSE;
+                return false;
             next = next->pn_next;
         }
     } else {
         if (pn->isArity(PN_NAME)) {
             /*
              * Set left and right so pn appears to be a TOK_LB node, instead
              * of a TOK_DOT node.  See the TOK_FOR/IN case in EmitTree, and
              * EmitDestructuringOps nearer below.  In the destructuring case,
              * the base expression (pn_expr) of the name may be null, which
              * means we have to emit a JSOP_BINDNAME.
              */
             left = pn->maybeExpr();
             if (!left) {
-                left = &ltmp;
+                left = NullaryNode::create(cg);
+                if (!left)
+                    return false;
                 left->setKind(TOK_STRING);
                 left->setOp(JSOP_BINDNAME);
-                left->setArity(PN_NULLARY);
                 left->pn_pos = pn->pn_pos;
                 left->pn_atom = pn->pn_atom;
             }
-            right = &rtmp;
+            right = NullaryNode::create(cg);
+            if (!right)
+                return false;
             right->setKind(TOK_STRING);
             right->setOp(IsIdentifier(pn->pn_atom) ? JSOP_QNAMEPART : JSOP_STRING);
-            right->setArity(PN_NULLARY);
             right->pn_pos = pn->pn_pos;
             right->pn_atom = pn->pn_atom;
         } else {
             JS_ASSERT(pn->isArity(PN_BINARY));
             left = pn->pn_left;
             right = pn->pn_right;
         }
 
         /*
          * Try to optimize arguments[0] (e.g.) into JSOP_ARGSUB<0>. If type
          * inference is enabled this is optimized separately.
          */
         if (op == JSOP_GETELEM &&
             left->isKind(TOK_NAME) &&
             right->isKind(TOK_NUMBER)) {
             if (!BindNameToSlot(cx, cg, left))
-                return JS_FALSE;
+                return false;
             if (left->isOp(JSOP_ARGUMENTS) &&
                 JSDOUBLE_IS_INT32(right->pn_dval, &slot) &&
                 jsuint(slot) < JS_BIT(16) &&
                 !cx->typeInferenceEnabled() &&
                 (!cg->inStrictMode() ||
                  (!cg->mutatesParameter() && !cg->callsEval()))) {
                 left->pn_offset = right->pn_offset = top;
                 EMIT_UINT16_IMM_OP(JSOP_ARGSUB, (jsatomid)slot);
-                return JS_TRUE;
+                return true;
             }
         }
 
         if (!EmitTree(cx, cg, left))
-            return JS_FALSE;
+            return false;
     }
 
     /* The right side of the descendant operator is implicitly quoted. */
     JS_ASSERT(op != JSOP_DESCENDANTS || !right->isKind(TOK_STRING) ||
               right->isOp(JSOP_QNAMEPART));
     if (!EmitTree(cx, cg, right))
-        return JS_FALSE;
+        return false;
     if (NewSrcNote2(cx, cg, SRC_PCBASE, CG_OFFSET(cg) - top) < 0)
-        return JS_FALSE;
+        return false;
     return EmitElemOpBase(cx, cg, op);
 }
 
 static bool
 EmitElemIncDec(JSContext *cx, ParseNode *pn, JSOp op, CodeGenerator *cg)
 {
     if (pn) {
         if (!EmitElemOp(cx, pn, op, cg))
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -378,17 +378,17 @@ RecycleTree(ParseNode *pn, TreeContext *
  * cx's temporary arena.
  */
 ParseNode *
 NewOrRecycledNode(TreeContext *tc)
 {
     ParseNode *pn = tc->parser->nodeList;
     if (!pn) {
         JSContext *cx = tc->parser->context;
-        pn = cx->tempLifoAlloc().new_<ParseNode>();
+        pn = (ParseNode *) cx->tempLifoAlloc().alloc(sizeof (ParseNode));
         if (!pn)
             js_ReportOutOfMemory(cx);
     } else {
         tc->parser->nodeList = pn->pn_next;
     }
 
     if (pn) {
         pn->setUsed(false);
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -310,39 +310,59 @@ struct ParseNode {
     uint32              pn_type   : 16, /* TOK_* type, see frontend/TokenStream.h */
                         pn_op     : 8,  /* see JSOp enum and jsopcode.tbl */
                         pn_arity  : 5,  /* see ParseNodeArity enum */
                         pn_parens : 1,  /* this expr was enclosed in parens */
                         pn_used   : 1,  /* name node is on a use-chain */
                         pn_defn   : 1;  /* this node is a Definition */
 
   public:
+    ParseNode(TokenKind type, JSOp op, ParseNodeArity arity)
+      : pn_type(type), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
+        pn_offset(0), pn_next(NULL), pn_link(NULL)
+    {
+        pn_pos.begin.index = 0;
+        pn_pos.begin.lineno = 0;
+        pn_pos.end.index = 0;
+        pn_pos.end.lineno = 0;
+        memset(&pn_u, 0, sizeof pn_u);
+    }
+
+    ParseNode(TokenKind type, JSOp op, ParseNodeArity arity, const TokenPos &pos)
+      : pn_type(type), pn_op(op), pn_arity(arity), pn_parens(0), pn_used(0), pn_defn(0),
+        pn_pos(pos), pn_offset(0), pn_next(NULL), pn_link(NULL)
+    {
+        memset(&pn_u, 0, sizeof pn_u);
+    }
+
     JSOp getOp() const                     { return JSOp(pn_op); }
     void setOp(JSOp op)                    { pn_op = op; }
     bool isOp(JSOp op) const               { return getOp() == op; }
     TokenKind getKind() const              { return TokenKind(pn_type); }
     void setKind(TokenKind kind)           { pn_type = kind; }
     bool isKind(TokenKind kind) const      { return getKind() == kind; }
     ParseNodeArity getArity() const        { return ParseNodeArity(pn_arity); }
     bool isArity(ParseNodeArity a) const   { return getArity() == a; }
     void setArity(ParseNodeArity a)        { pn_arity = a; }
+
     /* Boolean attributes. */
     bool isInParens() const                { return pn_parens; }
     void setInParens(bool enabled)         { pn_parens = enabled; }
     bool isDefn() const                    { return pn_defn; }
     void setDefn(bool enabled)             { pn_defn = enabled; }
     bool isUsed() const                    { return pn_used; }
     void setUsed(bool enabled)             { pn_used = enabled; }
 
     TokenPos            pn_pos;         /* two 16-bit pairs here, for 64 bits */
     int32               pn_offset;      /* first generated bytecode offset */
     ParseNode           *pn_next;       /* intrinsic link in parent PN_LIST */
     ParseNode           *pn_link;       /* def/use link (alignment freebie);
                                            also links FunctionBox::methods
                                            lists of would-be |this| methods */
+
     union {
         struct {                        /* list of next-linked nodes */
             ParseNode   *head;          /* first node in list */
             ParseNode   **tail;         /* ptr to ptr to last node in list */
             uint32      count;          /* number of nodes in list */
             uint32      xflags:12,      /* extra flags, see below */
                         blockid:20;     /* see name variant below */
         } list;
@@ -419,33 +439,33 @@ struct ParseNode {
 #define pn_expr         pn_u.name.expr
 #define pn_lexdef       pn_u.name.lexdef
 #define pn_names        pn_u.nameset.defnMap
 #define pn_tree         pn_u.nameset.tree
 #define pn_dval         pn_u.dval
 #define pn_pitarget     pn_u.xmlpi.target
 #define pn_pidata       pn_u.xmlpi.data
 
-protected:
+  protected:
     void init(TokenKind type, JSOp op, ParseNodeArity arity) {
         pn_type = type;
         pn_op = op;
         pn_arity = arity;
         pn_parens = false;
         JS_ASSERT(!pn_used);
         JS_ASSERT(!pn_defn);
         pn_names.init();
         pn_next = pn_link = NULL;
     }
 
     static ParseNode *create(ParseNodeArity arity, TreeContext *tc);
     static ParseNode *create(ParseNodeArity arity, TokenKind type, JSOp op,
                              const TokenPos &pos, TreeContext *tc);
 
-public:
+  public:
     static ParseNode *newBinaryOrAppend(TokenKind tt, JSOp op, ParseNode *left, ParseNode *right,
                                         TreeContext *tc);
 
     static ParseNode *newTernary(TokenKind tt, JSOp op, ParseNode *kid1, ParseNode *kid2,
                                  ParseNode *kid3, TreeContext *tc);
 
     /*
      * The pn_expr and lexdef members are arms of an unsafe union. Unless you
--- a/js/src/frontend/Parser.h
+++ b/js/src/frontend/Parser.h
@@ -49,18 +49,16 @@
 #include "jspubtd.h"
 #include "jsatom.h"
 #include "jsscript.h"
 #include "jswin.h"
 
 #include "frontend/ParseMaps.h"
 #include "frontend/ParseNode.h"
 
-JS_BEGIN_EXTERN_C
-
 namespace js {
 
 struct GlobalScope {
     GlobalScope(JSContext *cx, JSObject *globalObj, CodeGenerator *cg)
       : globalObj(globalObj), cg(cg), defs(cx), names(cx)
     { }
 
     struct GlobalDef {
@@ -177,17 +175,17 @@ struct Parser : private AutoGCRooter
 
     void trace(JSTracer *trc);
 
     /*
      * Report a parse (compile) error.
      */
     inline bool reportErrorNumber(ParseNode *pn, uintN flags, uintN errorNumber, ...);
 
-private:
+  private:
     /*
      * JS parsers, from lowest to highest precedence.
      *
      * Each parser must be called during the dynamic scope of a TreeContext
      * object, pointed to by this->tc.
      *
      * Each returns a parse node tree or null on error.
      *
@@ -296,11 +294,9 @@ DefineArg(ParseNode *pn, JSAtom *atom, u
 
 } /* namespace js */
 
 /*
  * Convenience macro to access Parser.tokenStream as a pointer.
  */
 #define TS(p) (&(p)->tokenStream)
 
-JS_END_EXTERN_C
-
 #endif /* Parser_h__ */