Bug 1528409 - Part 1: Autogenerate the dispatch code in ParseNode::dump(). r=khyperia
authorJason Orendorff <jorendorff@mozilla.com>
Tue, 26 Feb 2019 18:37:33 +0000
changeset 519120 d56678e5ee519c006e32a3f00c0889154da1648d
parent 519119 db866e98d64e31f40dc49815125412afdb11c59d
child 519121 b70102d25a47d2edca9f28c31db8a0103ff009a4
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 1: Autogenerate the dispatch code in ParseNode::dump(). r=khyperia Differential Revision: https://phabricator.services.mozilla.com/D20035
js/src/frontend/ParseNode.cpp
js/src/frontend/ParseNode.h
--- a/js/src/frontend/ParseNode.cpp
+++ b/js/src/frontend/ParseNode.cpp
@@ -133,61 +133,29 @@ void ParseNode::dump(GenericPrinter& out
 }
 
 void ParseNode::dump() {
   js::Fprinter out(stderr);
   dump(out);
 }
 
 void ParseNode::dump(GenericPrinter& out, int indent) {
-  switch (getArity()) {
-    case PN_NULLARY:
-      as<NullaryNode>().dump(out);
-      return;
-    case PN_UNARY:
-      as<UnaryNode>().dump(out, indent);
-      return;
-    case PN_BINARY:
-      as<BinaryNode>().dump(out, indent);
-      return;
-    case PN_TERNARY:
-      as<TernaryNode>().dump(out, indent);
-      return;
-    case PN_FUNCTION:
-      as<FunctionNode>().dump(out, indent);
-      return;
-    case PN_MODULE:
-      as<ModuleNode>().dump(out, indent);
-      return;
-    case PN_LIST:
-      as<ListNode>().dump(out, indent);
-      return;
-    case PN_NAME:
-      as<NameNode>().dump(out, indent);
-      return;
-    case PN_NUMBER:
-      as<NumericLiteral>().dump(out, indent);
-      return;
-    case PN_BIGINT:
-      as<BigIntLiteral>().dump(out, indent);
-      return;
-    case PN_REGEXP:
-      as<RegExpLiteral>().dump(out, indent);
-      return;
-    case PN_LOOP:
-      as<LoopControlStatement>().dump(out, indent);
-      return;
-    case PN_SCOPE:
-      as<LexicalScopeNode>().dump(out, indent);
-      return;
+  switch (getKind()) {
+#  define DUMP(K, T)                 \
+    case ParseNodeKind::K:           \
+      as<T>().dumpImpl(out, indent); \
+      break;
+    FOR_EACH_PARSE_NODE_KIND(DUMP)
+#  undef DUMP
+    default:
+      out.printf("#<BAD NODE %p, kind=%u>", (void*)this, unsigned(getKind()));
   }
-  out.printf("#<BAD NODE %p, kind=%u>", (void*)this, unsigned(getKind()));
 }
 
-void NullaryNode::dump(GenericPrinter& out) {
+void NullaryNode::dumpImpl(GenericPrinter& out, int indent) {
   switch (getKind()) {
     case ParseNodeKind::TrueExpr:
       out.put("#true");
       break;
     case ParseNodeKind::FalseExpr:
       out.put("#false");
       break;
     case ParseNodeKind::NullExpr:
@@ -197,56 +165,56 @@ void NullaryNode::dump(GenericPrinter& o
       out.put("#undefined");
       break;
 
     default:
       out.printf("(%s)", parseNodeNames[size_t(getKind())]);
   }
 }
 
-void NumericLiteral::dump(GenericPrinter& out, int indent) {
+void NumericLiteral::dumpImpl(GenericPrinter& out, int indent) {
   ToCStringBuf cbuf;
   const char* cstr = NumberToCString(nullptr, &cbuf, value());
   if (!IsFinite(value())) {
     out.put("#");
   }
   if (cstr) {
     out.printf("%s", cstr);
   } else {
     out.printf("%g", value());
   }
 }
 
-void BigIntLiteral::dump(GenericPrinter& out, int indent) {
+void BigIntLiteral::dumpImpl(GenericPrinter& out, int indent) {
   out.printf("(%s)", parseNodeNames[size_t(getKind())]);
 }
 
-void RegExpLiteral::dump(GenericPrinter& out, int indent) {
+void RegExpLiteral::dumpImpl(GenericPrinter& out, int indent) {
   out.printf("(%s)", parseNodeNames[size_t(getKind())]);
 }
 
-void LoopControlStatement::dump(GenericPrinter& out, int indent) {
+void LoopControlStatement::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s", name);
   if (label()) {
     out.printf(" ");
     label()->dumpCharsNoNewline(out);
   }
   out.printf(")");
 }
 
-void UnaryNode::dump(GenericPrinter& out, int indent) {
+void UnaryNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(kid(), out, indent);
   out.printf(")");
 }
 
-void BinaryNode::dump(GenericPrinter& out, int indent) {
+void BinaryNode::dumpImpl(GenericPrinter& out, int indent) {
   if (isKind(ParseNodeKind::DotExpr)) {
     out.put("(.");
 
     DumpParseTree(right(), out, indent + 2);
 
     out.putChar(' ');
     if (as<PropertyAccess>().isSuper()) {
       out.put("super");
@@ -262,45 +230,45 @@ void BinaryNode::dump(GenericPrinter& ou
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(left(), out, indent);
   IndentNewLine(out, indent);
   DumpParseTree(right(), out, indent);
   out.printf(")");
 }
 
-void TernaryNode::dump(GenericPrinter& out, int indent) {
+void TernaryNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(kid1(), out, indent);
   IndentNewLine(out, indent);
   DumpParseTree(kid2(), out, indent);
   IndentNewLine(out, indent);
   DumpParseTree(kid3(), out, indent);
   out.printf(")");
 }
 
-void FunctionNode::dump(GenericPrinter& out, int indent) {
+void FunctionNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(body(), out, indent);
   out.printf(")");
 }
 
-void ModuleNode::dump(GenericPrinter& out, int indent) {
+void ModuleNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s ", name);
   indent += strlen(name) + 2;
   DumpParseTree(body(), out, indent);
   out.printf(")");
 }
 
-void ListNode::dump(GenericPrinter& out, int indent) {
+void ListNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s [", name);
   if (ParseNode* listHead = head()) {
     indent += strlen(name) + 3;
     DumpParseTree(listHead, out, indent);
     for (ParseNode* item : contentsFrom(listHead->pn_next)) {
       IndentNewLine(out, indent);
       DumpParseTree(item, out, indent);
@@ -322,17 +290,17 @@ static void DumpName(GenericPrinter& out
     } else if (c <= 255) {
       out.printf("\\x%02x", unsigned(c));
     } else {
       out.printf("\\u%04x", unsigned(c));
     }
   }
 }
 
-void NameNode::dump(GenericPrinter& out, int indent) {
+void NameNode::dumpImpl(GenericPrinter& out, int indent) {
   switch (getKind()) {
     case ParseNodeKind::StringExpr:
     case ParseNodeKind::TemplateStringExpr:
     case ParseNodeKind::ObjectPropertyName:
       atom()->dumpCharsNoNewline(out);
       return;
 
     case ParseNodeKind::Name:
@@ -375,17 +343,17 @@ void NameNode::dump(GenericPrinter& out,
       indent += strlen(name) + 2;
       DumpParseTree(initializer(), out, indent);
       out.printf(")");
       return;
     }
   }
 }
 
-void LexicalScopeNode::dump(GenericPrinter& out, int indent) {
+void LexicalScopeNode::dumpImpl(GenericPrinter& out, int indent) {
   const char* name = parseNodeNames[size_t(getKind())];
   out.printf("(%s [", name);
   int nameIndent = indent + strlen(name) + 3;
   if (!isEmptyScope()) {
     LexicalScope::Data* bindings = scopeBindings();
     for (uint32_t i = 0; i < bindings->length; i++) {
       JSAtom* name = bindings->trailingNames[i].name();
       JS::AutoCheckCannotGC nogc;
--- a/js/src/frontend/ParseNode.h
+++ b/js/src/frontend/ParseNode.h
@@ -787,17 +787,17 @@ class NullaryNode : public ParseNode {
   static constexpr ParseNodeArity arity() { return PN_NULLARY; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 };
 
 class NameNode : public ParseNode {
   JSAtom* atom_;         /* lexical name or label atom */
   ParseNode* initOrStmt; /* var initializer, argument default, or label
                             statement target */
 
@@ -824,17 +824,17 @@ class NameNode : public ParseNode {
       if (!visitor.visit(initOrStmt)) {
         return false;
       }
     }
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   JSAtom* atom() const { return atom_; }
 
   PropertyName* name() const {
     MOZ_ASSERT(isKind(ParseNodeKind::Name));
     return atom()->asPropertyName();
   }
@@ -870,17 +870,17 @@ class UnaryNode : public ParseNode {
       if (!visitor.visit(kid_)) {
         return false;
       }
     }
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   ParseNode* kid() const { return kid_; }
 
   /* Return true if this node appears in a Directive Prologue. */
   bool isDirectivePrologueMember() const { return prologue; }
 
   void setIsDirectivePrologueMember() { prologue = true; }
@@ -945,17 +945,17 @@ class BinaryNode : public ParseNode {
       if (!visitor.visit(right_)) {
         return false;
       }
     }
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   ParseNode* left() const { return left_; }
 
   ParseNode* right() const { return right_; }
 
   // Methods used by FoldConstants.cpp.
   // callers are responsible for keeping the list consistent.
@@ -1045,17 +1045,17 @@ class TernaryNode : public ParseNode {
       if (!visitor.visit(kid3_)) {
         return false;
       }
     }
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   ParseNode* kid1() const { return kid1_; }
 
   ParseNode* kid2() const { return kid2_; }
 
   ParseNode* kid3() const { return kid3_; }
 
@@ -1152,17 +1152,17 @@ class ListNode : public ParseNode {
         ReplaceNode(listp, pn);
       }
     }
     unsafeReplaceTail(listp);
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   ParseNode* head() const { return head_; }
 
   ParseNode** tail() const { return tail_; }
 
   uint32_t count() const { return count_; }
 
@@ -1437,17 +1437,17 @@ class FunctionNode : public ParseNode {
       if (!visitor.visit(body_)) {
         return false;
       }
     }
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   FunctionBox* funbox() const { return funbox_; }
 
   ListNode* body() const { return body_ ? &body_->as<ListNode>() : nullptr; }
 
   void setFunbox(FunctionBox* funbox) { funbox_ = funbox; }
 
@@ -1479,17 +1479,17 @@ class ModuleNode : public ParseNode {
   static constexpr ParseNodeArity arity() { return PN_MODULE; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return visitor.visit(body_);
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   ListNode* body() const { return &body_->as<ListNode>(); }
 
   void setBody(ListNode* body) { body_ = body; }
 };
 
 class NumericLiteral : public ParseNode {
@@ -1511,17 +1511,17 @@ class NumericLiteral : public ParseNode 
   static constexpr ParseNodeArity arity() { return PN_NUMBER; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   double value() const { return value_; }
 
   DecimalPoint decimalPoint() const { return decimalPoint_; }
 
   void setValue(double v) { value_ = v; }
 
@@ -1544,17 +1544,17 @@ class BigIntLiteral : public ParseNode {
   static constexpr ParseNodeArity arity() { return PN_BIGINT; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return true;
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   BigIntBox* box() const { return box_; }
 };
 
 class LexicalScopeNode : public ParseNode {
   LexicalScope::Data* bindings;
   ParseNode* body;
@@ -1574,17 +1574,17 @@ class LexicalScopeNode : public ParseNod
   static constexpr ParseNodeArity arity() { return PN_SCOPE; }
 
   template <typename Visitor>
   bool accept(Visitor& visitor) {
     return visitor.visit(body);
   }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  void dumpImpl(GenericPrinter& out, int indent);
 #endif
 
   Handle<LexicalScope::Data*> scopeBindings() const {
     MOZ_ASSERT(!isEmptyScope());
     // Bindings' GC safety depend on the presence of an AutoKeepAtoms that
     // the rest of the frontend also depends on.
     return Handle<LexicalScope::Data*>::fromMarkedLocation(&bindings);
   }
@@ -1649,17 +1649,17 @@ class LoopControlStatement : public Pars
     MOZ_ASSERT(is<LoopControlStatement>());
   }
 
  public:
   /* Label associated with this break/continue statement, if any. */
   PropertyName* label() const { return label_; }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  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;
@@ -1823,17 +1823,17 @@ class RegExpLiteral : public ParseNode {
  public:
   RegExpLiteral(ObjectBox* reobj, const TokenPos& pos)
       : ParseNode(ParseNodeKind::RegExpExpr, JSOP_REGEXP, pos),
         objbox_(reobj) {}
 
   ObjectBox* objbox() const { return objbox_; }
 
 #ifdef DEBUG
-  void dump(GenericPrinter& out, int indent);
+  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;
   }