Bug 1528409 - Part 2: Rename ParseNodeArity to ParseNode::TypeCode. r=khyperia
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 26 Feb 2019 18:37:53 +0000
changeset 519121 b70102d25a47d2edca9f28c31db8a0103ff009a4
parent 519120 d56678e5ee519c006e32a3f00c0889154da1648d
child 519122 6d6bbd91a4ee61702a6141101e9cae7177fac06b
push id10862
push userffxbld-merge
push dateMon, 11 Mar 2019 13:01:11 +0000
treeherdermozilla-beta@a2e7f5c935da [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskhyperia
bugs1528409
milestone67.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1528409 - Part 2: Rename ParseNodeArity to ParseNode::TypeCode. r=khyperia Many ParseNodeArity constants are never really used; this patch removes them. Differential Revision: https://phabricator.services.mozilla.com/D20036
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -93,20 +93,20 @@ ParseNode* ParseNode::appendOrCreateList
   if (!list) {
     return nullptr;
   }
 
   list->append(right);
   return list;
 }
 
-const ParseNodeArity js::frontend::ParseNodeKindArity[] = {
-#define ARITY(_name, type) type::arity(),
-    FOR_EACH_PARSE_NODE_KIND(ARITY)
-#undef ARITY
+const ParseNode::TypeCode ParseNode::typeCodeTable[] = {
+#define TYPE_CODE(_name, type) type::classTypeCode(),
+    FOR_EACH_PARSE_NODE_KIND(TYPE_CODE)
+#undef TYPE_CODE
 };
 
 #ifdef DEBUG
 
 static const char* const parseNodeNames[] = {
 #  define STRINGIFY(name, _type) #  name,
     FOR_EACH_PARSE_NODE_KIND(STRINGIFY)
 #  undef STRINGIFY
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -521,31 +521,16 @@ inline bool IsTypeofKind(ParseNodeKind k
  *   scopeBindings: scope bindings
  *   scopeBody: scope body
  * Generator (NullaryNode)
  * InitialYield (UnaryNode)
  *   kid: generator object
  * YieldExpr, YieldStarExpr, AwaitExpr (UnaryNode)
  *   kid: expr or null
  */
-enum ParseNodeArity {
-  PN_NULLARY,  /* 0 kids */
-  PN_UNARY,    /* one kid, plus a couple of scalars */
-  PN_BINARY,   /* two kids, plus a couple of scalars */
-  PN_TERNARY,  /* three kids */
-  PN_FUNCTION, /* function definition node */
-  PN_MODULE,   /* module node */
-  PN_LIST,     /* generic singly linked list */
-  PN_NAME,     /* name, label, string */
-  PN_NUMBER,   /* numeric literal */
-  PN_BIGINT,   /* BigInt literal */
-  PN_REGEXP,   /* regexp literal */
-  PN_LOOP,     /* loop control (break/continue) */
-  PN_SCOPE     /* lexical scope */
-};
 
 // FIXME: Remove `*Type` (bug 1489008)
 #define FOR_EACH_PARSENODE_SUBCLASS(MACRO)                                   \
   MACRO(BinaryNode, BinaryNodeType, asBinary)                                \
   MACRO(AssignmentNode, AssignmentNodeType, asAssignment)                    \
   MACRO(CaseClause, CaseClauseType, asCaseClause)                            \
   MACRO(ClassMethod, ClassMethodType, asClassMethod)                         \
   MACRO(ClassField, ClassFieldType, asClassField)                            \
@@ -590,19 +575,16 @@ enum ParseNodeArity {
                                                                              \
   MACRO(UnaryNode, UnaryNodeType, asUnary)                                   \
   MACRO(ThisLiteral, ThisLiteralType, asThisLiteral)
 
 #define DECLARE_CLASS(typeName, longTypeName, asMethodName) class typeName;
 FOR_EACH_PARSENODE_SUBCLASS(DECLARE_CLASS)
 #undef DECLARE_CLASS
 
-// ParseNodeKindArity[size_t(pnk)] is the arity of a ParseNode of kind pnk.
-extern const ParseNodeArity ParseNodeKindArity[];
-
 enum class FunctionSyntaxKind {
   // A non-arrow function expression.
   Expression,
 
   // A named function appearing as a Statement.
   Statement,
 
   Arrow,
@@ -666,20 +648,35 @@ class ParseNode {
   bool isOp(JSOp op) const { return getOp() == op; }
 
   ParseNodeKind getKind() const {
     MOZ_ASSERT(pn_type < ParseNodeKind::Limit);
     return pn_type;
   }
   bool isKind(ParseNodeKind kind) const { return getKind() == kind; }
 
-  ParseNodeArity getArity() const {
-    return ParseNodeKindArity[size_t(getKind())];
-  }
-  bool isArity(ParseNodeArity a) const { return getArity() == a; }
+ protected:
+  // Used to implement test() on a few ParseNodes efficiently.
+  // (This enum doesn't fully reflect the ParseNode class hierarchy,
+  // so don't use it for anything else.)
+  enum class TypeCode : uint8_t {
+    Nullary,
+    Unary,
+    Binary,
+    Ternary,
+    List,
+    Name,
+    Other
+  };
+
+  // typeCodeTable[size_t(pnk)] is the type code of a ParseNode of kind pnk.
+  static const TypeCode typeCodeTable[];
+
+ public:
+  TypeCode typeCode() const { return typeCodeTable[size_t(getKind())]; }
 
   bool isBinaryOperation() const {
     ParseNodeKind kind = getKind();
     return ParseNodeKind::BinOpFirst <= kind &&
            kind <= ParseNodeKind::BinOpLast;
   }
   inline bool isName(PropertyName* name) const;
 
@@ -777,19 +774,21 @@ class NullaryNode : public ParseNode {
     MOZ_ASSERT(is<NullaryNode>());
   }
 
   NullaryNode(ParseNodeKind kind, JSOp op, const TokenPos& pos)
       : ParseNode(kind, op, pos) {
     MOZ_ASSERT(is<NullaryNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_NULLARY); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::Nullary;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_NULLARY; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Nullary; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
@@ -809,19 +808,21 @@ class NameNode : public ParseNode {
   }
 
  public:
   NameNode(ParseNodeKind kind, JSOp op, JSAtom* atom, const TokenPos& pos)
       : ParseNode(kind, op, pos), atom_(atom), initOrStmt(nullptr) {
     MOZ_ASSERT(is<NameNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_NAME); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::Name;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_NAME; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Name; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     if (initOrStmt) {
       if (!visitor.visit(initOrStmt)) {
         return false;
       }
     }
@@ -855,19 +856,21 @@ class UnaryNode : public ParseNode {
   bool prologue; /* directive prologue member */
 
  public:
   UnaryNode(ParseNodeKind kind, const TokenPos& pos, ParseNode* kid)
       : ParseNode(kind, JSOP_NOP, pos), kid_(kid), prologue(false) {
     MOZ_ASSERT(is<UnaryNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_UNARY); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::Unary;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_UNARY; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Unary; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     if (kid_) {
       if (!visitor.visit(kid_)) {
         return false;
       }
     }
@@ -925,19 +928,21 @@ class BinaryNode : public ParseNode {
 
   BinaryNode(ParseNodeKind kind, JSOp op, ParseNode* left, ParseNode* right)
       : ParseNode(kind, op, TokenPos::box(left->pn_pos, right->pn_pos)),
         left_(left),
         right_(right) {
     MOZ_ASSERT(is<BinaryNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_BINARY); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::Binary;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_BINARY; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Binary; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     if (left_) {
       if (!visitor.visit(left_)) {
         return false;
       }
     }
@@ -1020,19 +1025,21 @@ class TernaryNode : public ParseNode {
                              (kid3 ? kid3 : kid2 ? kid2 : kid1)->pn_pos.end)) {}
 
   TernaryNode(ParseNodeKind kind, ParseNode* kid1, ParseNode* kid2,
               ParseNode* kid3, const TokenPos& pos)
       : ParseNode(kind, JSOP_NOP, pos), kid1_(kid1), kid2_(kid2), kid3_(kid3) {
     MOZ_ASSERT(is<TernaryNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_TERNARY); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::Ternary;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_TERNARY; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Ternary; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     if (kid1_) {
       if (!visitor.visit(kid1_)) {
         return false;
       }
     }
@@ -1129,19 +1136,21 @@ class ListNode : public ParseNode {
     if (kid->pn_pos.begin < pn_pos.begin) {
       pn_pos.begin = kid->pn_pos.begin;
     }
     pn_pos.end = kid->pn_pos.end;
 
     MOZ_ASSERT(is<ListNode>());
   }
 
-  static bool test(const ParseNode& node) { return node.isArity(PN_LIST); }
+  static bool test(const ParseNode& node) {
+    return node.typeCode() == TypeCode::List;
+  }
 
-  static constexpr ParseNodeArity arity() { return PN_LIST; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::List; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     ParseNode** listp = &head_;
     for (; *listp; listp = &(*listp)->pn_next) {
       // Don't use PN*& because we want to check if it changed, so we can use
       // ReplaceNode
       ParseNode* pn = *listp;
@@ -1418,22 +1427,20 @@ class FunctionNode : public ParseNode {
         body_(nullptr),
         syntaxKind_(syntaxKind) {
     MOZ_ASSERT(!body_);
     MOZ_ASSERT(!funbox_);
     MOZ_ASSERT(is<FunctionNode>());
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Function);
-    MOZ_ASSERT_IF(match, node.isArity(PN_FUNCTION));
-    return match;
+    return node.isKind(ParseNodeKind::Function);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_FUNCTION; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     // Note: body is null for lazily-parsed functions.
     if (body_) {
       if (!visitor.visit(body_)) {
         return false;
       }
@@ -1466,22 +1473,20 @@ class ModuleNode : public ParseNode {
  public:
   explicit ModuleNode(const TokenPos& pos)
       : ParseNode(ParseNodeKind::Module, JSOP_NOP, pos), body_(nullptr) {
     MOZ_ASSERT(!body_);
     MOZ_ASSERT(is<ModuleNode>());
   }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::Module);
-    MOZ_ASSERT_IF(match, node.isArity(PN_MODULE));
-    return match;
+    return node.isKind(ParseNodeKind::Module);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_MODULE; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return visitor.visit(body_);
   }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
@@ -1498,22 +1503,20 @@ class NumericLiteral : public ParseNode 
 
  public:
   NumericLiteral(double value, DecimalPoint decimalPoint, const TokenPos& pos)
       : ParseNode(ParseNodeKind::NumberExpr, JSOP_NOP, pos),
         value_(value),
         decimalPoint_(decimalPoint) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::NumberExpr);
-    MOZ_ASSERT_IF(match, node.isArity(PN_NUMBER));
-    return match;
+    return node.isKind(ParseNodeKind::NumberExpr);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_NUMBER; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
@@ -1531,22 +1534,20 @@ class NumericLiteral : public ParseNode 
 class BigIntLiteral : public ParseNode {
   BigIntBox* box_;
 
  public:
   BigIntLiteral(BigIntBox* bibox, const TokenPos& pos)
       : ParseNode(ParseNodeKind::BigIntExpr, JSOP_NOP, pos), box_(bibox) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::BigIntExpr);
-    MOZ_ASSERT_IF(match, node.isArity(PN_BIGINT));
-    return match;
+    return node.isKind(ParseNodeKind::BigIntExpr);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_BIGINT; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
@@ -1561,22 +1562,20 @@ class LexicalScopeNode : public ParseNod
 
  public:
   LexicalScopeNode(LexicalScope::Data* bindings, ParseNode* body)
       : ParseNode(ParseNodeKind::LexicalScope, JSOP_NOP, body->pn_pos),
         bindings(bindings),
         body(body) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::LexicalScope);
-    MOZ_ASSERT_IF(match, node.isArity(PN_SCOPE));
-    return match;
+    return node.isKind(ParseNodeKind::LexicalScope);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_SCOPE; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return visitor.visit(body);
   }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
@@ -1602,20 +1601,17 @@ class LabeledStatement : public NameNode
       : NameNode(ParseNodeKind::LabelStmt, JSOP_NOP, label, stmt,
                  TokenPos(begin, stmt->pn_pos.end)) {}
 
   PropertyName* label() const { return atom()->asPropertyName(); }
 
   ParseNode* statement() const { return initializer(); }
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::LabelStmt);
-    MOZ_ASSERT_IF(match, node.isArity(PN_NAME));
-    MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
-    return match;
+    return node.isKind(ParseNodeKind::LabelStmt);
   }
 };
 
 // Inside a switch statement, a CaseClause is a case-label and the subsequent
 // statements. The same node type is used for DefaultClauses. The only
 // difference is that their caseExpression() is null.
 class CaseClause : public BinaryNode {
  public:
@@ -1653,24 +1649,21 @@ class LoopControlStatement : public Pars
   /* Label associated with this break/continue statement, if any. */
   PropertyName* label() const { return label_; }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::BreakStmt) ||
-                 node.isKind(ParseNodeKind::ContinueStmt);
-    MOZ_ASSERT_IF(match, node.isArity(PN_LOOP));
-    MOZ_ASSERT_IF(match, node.isOp(JSOP_NOP));
-    return match;
+    return node.isKind(ParseNodeKind::BreakStmt) ||
+           node.isKind(ParseNodeKind::ContinueStmt);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_LOOP; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 };
 
 class BreakStatement : public LoopControlStatement {
@@ -1827,23 +1820,20 @@ class RegExpLiteral : public ParseNode {
 
   ObjectBox* objbox() const { return objbox_; }
 
 #ifdef DEBUG
   void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::RegExpExpr);
-    MOZ_ASSERT_IF(match, node.isArity(PN_REGEXP));
-    MOZ_ASSERT_IF(match, node.isOp(JSOP_REGEXP));
-    return match;
+    return node.isKind(ParseNodeKind::RegExpExpr);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_REGEXP; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 };
 
 class PropertyAccess : public BinaryNode {
@@ -1964,22 +1954,20 @@ class ClassField : public BinaryNode {
   ClassField(ParseNode* name, ParseNode* initializer)
       : BinaryNode(ParseNodeKind::ClassField, JSOP_NOP,
                    initializer == nullptr
                        ? name->pn_pos
                        : TokenPos::box(name->pn_pos, initializer->pn_pos),
                    name, initializer) {}
 
   static bool test(const ParseNode& node) {
-    bool match = node.isKind(ParseNodeKind::ClassField);
-    MOZ_ASSERT_IF(match, node.isArity(PN_BINARY));
-    return match;
+    return node.isKind(ParseNodeKind::ClassField);
   }
 
-  static constexpr ParseNodeArity arity() { return PN_BINARY; }
+  static constexpr TypeCode classTypeCode() { return TypeCode::Other; }
 
   ParseNode& name() const { return *left(); }
 
   bool hasInitializer() const { return right() != nullptr; }
 
   FunctionNode& initializer() const { return right()->as<FunctionNode>(); }
 };