Hi,

A month ago, I wrote:

On Thu, 2012-02-09 at 17:49 +0100, Andy Wingo wrote:
> I'll refactor JSStaticScope into something that uses lazy tear-off.
[...]
> The block [of registers] reserved
> for block scopes will have as many registers as the maximum of (number
> of block scope-bound variables + block scope depth).

This is not something that can be computed easily at parse-time, because
variables can be declared anywhere within a block.  Computing the
maximum depth of block-scoped variables has to be a second pass over the
statements of a compilation unit.

As such it seems that the nicest way to do this is to add a Visitor
interface to parser/Nodes.h, as V8 does.  A patch to do this (after
separating scopenode and codenode) is attached.  But, it adds some 65 KB
to the compiled JSC library (from 4515336 to 4576472 bytes).  Is it too
much?

Or is it too architecture-astronaut-like?  We could refactor
BytecodeGenerator to use this visitor, if that were remotely useful.
But it's not in my plans, don't worry ;-)

Your thoughts are appreciated,

Andy
>From 0909b79b2602ae1558b00fa8ece5117a9ae6b025 Mon Sep 17 00:00:00 2001
From: Andy Wingo <[email protected]>
Date: Wed, 7 Mar 2012 18:05:01 +0100
Subject: [PATCH] nodevisitor

---
 Source/JavaScriptCore/parser/Nodes.cpp |    8 +
 Source/JavaScriptCore/parser/Nodes.h   |  241 ++++++++++++++++++++++++++++++++
 2 files changed, 249 insertions(+), 0 deletions(-)

diff --git a/Source/JavaScriptCore/parser/Nodes.cpp b/Source/JavaScriptCore/parser/Nodes.cpp
index 5e95a6d..00fbd1d 100644
--- a/Source/JavaScriptCore/parser/Nodes.cpp
+++ b/Source/JavaScriptCore/parser/Nodes.cpp
@@ -50,6 +50,14 @@ using namespace WTF;
 namespace JSC {
 
 
+// ------------------------------ Visitors --------------------------------
+
+#define DEFINE_ACCEPT(name) \
+    void name::accept(NodeVisitor *visitor) { visitor->visit##name(this); }
+FOR_EACH_CONCRETE_NODE_TYPE(DEFINE_ACCEPT)
+#undef DEFINE_ACCEPT
+
+
 // ------------------------------ StatementNode --------------------------------
 
 void StatementNode::setLoc(int firstLine, int lastLine)
diff --git a/Source/JavaScriptCore/parser/Nodes.h b/Source/JavaScriptCore/parser/Nodes.h
index cc1e591..7e0297d 100644
--- a/Source/JavaScriptCore/parser/Nodes.h
+++ b/Source/JavaScriptCore/parser/Nodes.h
@@ -72,6 +72,124 @@ namespace JSC {
     const ScopeFlags ShadowsArgumentsFlag = 1 << 13;
     const ScopeFlags AllScopeUsesFlags = UsesEvalFlag | UsesArgumentsFlag | UsesWithFlag | UsesCatchFlag | UsesThisFlag | ShadowsArgumentsFlag;
     
+// Statements and expressions.
+#define FOR_EACH_CONCRETE_NODE_TYPE(M) \
+    M(NullNode)                        \
+    M(BooleanNode)                     \
+    M(NumberNode)                      \
+    M(StringNode)                      \
+    M(RegExpNode)                      \
+    M(ThisNode)                        \
+    M(ResolveNode)                     \
+    M(ElementNode)                     \
+    M(ArrayNode)                       \
+    M(PropertyNode)                    \
+    M(PropertyListNode)                \
+    M(ObjectLiteralNode)               \
+    M(BracketAccessorNode)             \
+    M(DotAccessorNode)                 \
+    M(ArgumentListNode)                \
+    M(ArgumentsNode)                   \
+    M(NewExprNode)                     \
+    M(EvalFunctionCallNode)            \
+    M(FunctionCallValueNode)           \
+    M(FunctionCallResolveNode)         \
+    M(FunctionCallBracketNode)         \
+    M(FunctionCallDotNode)             \
+    M(CallFunctionCallDotNode)         \
+    M(ApplyFunctionCallDotNode)        \
+    M(PostfixResolveNode)              \
+    M(PostfixBracketNode)              \
+    M(PostfixDotNode)                  \
+    M(PostfixErrorNode)                \
+    M(DeleteResolveNode)               \
+    M(DeleteBracketNode)               \
+    M(DeleteDotNode)                   \
+    M(DeleteValueNode)                 \
+    M(VoidNode)                        \
+    M(TypeOfResolveNode)               \
+    M(TypeOfValueNode)                 \
+    M(PrefixResolveNode)               \
+    M(PrefixBracketNode)               \
+    M(PrefixDotNode)                   \
+    M(PrefixErrorNode)                 \
+    M(UnaryPlusNode)                   \
+    M(NegateNode)                      \
+    M(BitwiseNotNode)                  \
+    M(LogicalNotNode)                  \
+    M(MultNode)                        \
+    M(DivNode)                         \
+    M(ModNode)                         \
+    M(AddNode)                         \
+    M(SubNode)                         \
+    M(LeftShiftNode)                   \
+    M(RightShiftNode)                  \
+    M(UnsignedRightShiftNode)          \
+    M(LessNode)                        \
+    M(GreaterNode)                     \
+    M(LessEqNode)                      \
+    M(GreaterEqNode)                   \
+    M(InstanceOfNode)                  \
+    M(InNode)                          \
+    M(EqualNode)                       \
+    M(NotEqualNode)                    \
+    M(StrictEqualNode)                 \
+    M(NotStrictEqualNode)              \
+    M(BitAndNode)                      \
+    M(BitOrNode)                       \
+    M(BitXOrNode)                      \
+    M(LogicalOpNode)                   \
+    M(ConditionalNode)                 \
+    M(ReadModifyResolveNode)           \
+    M(AssignResolveNode)               \
+    M(ReadModifyBracketNode)           \
+    M(AssignBracketNode)               \
+    M(AssignDotNode)                   \
+    M(ReadModifyDotNode)               \
+    M(AssignErrorNode)                 \
+    M(CommaNode)                       \
+    M(ConstDeclNode)                   \
+    M(ConstStatementNode)              \
+    M(BlockNode)                       \
+    M(EmptyStatementNode)              \
+    M(DebuggerStatementNode)           \
+    M(ExprStatementNode)               \
+    M(VarStatementNode)                \
+    M(IfNode)                          \
+    M(IfElseNode)                      \
+    M(DoWhileNode)                     \
+    M(WhileNode)                       \
+    M(ForNode)                         \
+    M(ForInNode)                       \
+    M(ContinueNode)                    \
+    M(BreakNode)                       \
+    M(ReturnNode)                      \
+    M(WithNode)                        \
+    M(LabelNode)                       \
+    M(ThrowNode)                       \
+    M(TryNode)                         \
+    M(ProgramNode)                     \
+    M(EvalNode)                        \
+    M(FunctionBodyNode)                \
+    M(FuncExprNode)                    \
+    M(FuncDeclNode)                    \
+    M(CaseClauseNode)                  \
+    M(ClauseListNode)                  \
+    M(CaseBlockNode)                   \
+    M(SwitchNode)
+
+    enum NodeType {
+#define DECLARE_ENUM(name) name##Type,
+FOR_EACH_CONCRETE_NODE_TYPE(DECLARE_ENUM)
+#undef DECLARE_ENUM
+    };
+
+    class NodeVisitor;
+
+#define DECLARE_NODE_TYPE(name) \
+    virtual NodeType nodeType() { return name##Type; } \
+    virtual void accept(NodeVisitor *)
+
     enum Operator {
         OpEqual,
         OpPlusEq,
@@ -147,6 +265,8 @@ namespace JSC {
     public:
         virtual ~Node() { }
 
+        virtual void accept(NodeVisitor *) const { ASSERT_NOT_REACHED(); }
+
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
 
         int lineNo() const { return m_lineNumber; }
@@ -207,6 +327,7 @@ namespace JSC {
     class NullNode : public ExpressionNode {
     public:
         NullNode(int);
+        DECLARE_NODE_TYPE(NullNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -217,6 +338,7 @@ namespace JSC {
     class BooleanNode : public ExpressionNode {
     public:
         BooleanNode(int, bool value);
+        DECLARE_NODE_TYPE(BooleanNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -229,6 +351,7 @@ namespace JSC {
     class NumberNode : public ExpressionNode {
     public:
         NumberNode(int, double value);
+        DECLARE_NODE_TYPE(NumberNode);
 
         double value() const { return m_value; }
         void setValue(double value) { m_value = value; }
@@ -245,6 +368,7 @@ namespace JSC {
     class StringNode : public ExpressionNode {
     public:
         StringNode(int, const Identifier&);
+        DECLARE_NODE_TYPE(StringNode);
 
         const Identifier& value() { return m_value; }
 
@@ -355,6 +479,7 @@ namespace JSC {
     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         RegExpNode(int, const Identifier& pattern, const Identifier& flags);
+        DECLARE_NODE_TYPE(RegExpNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -366,6 +491,7 @@ namespace JSC {
     class ThisNode : public ExpressionNode {
     public:
         ThisNode(int);
+        DECLARE_NODE_TYPE(ThisNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -374,6 +500,7 @@ namespace JSC {
     class ResolveNode : public ExpressionNode {
     public:
         ResolveNode(int, const Identifier&, int startOffset);
+        DECLARE_NODE_TYPE(ResolveNode);
 
         const Identifier& identifier() const { return m_ident; }
 
@@ -392,6 +519,7 @@ namespace JSC {
     public:
         ElementNode(int elision, ExpressionNode*);
         ElementNode(ElementNode*, int elision, ExpressionNode*);
+        DECLARE_NODE_TYPE(ElementNode);
 
         int elision() const { return m_elision; }
         ExpressionNode* value() { return m_node; }
@@ -408,6 +536,7 @@ namespace JSC {
         ArrayNode(int, int elision);
         ArrayNode(int, ElementNode*);
         ArrayNode(int, int elision, ElementNode*);
+        DECLARE_NODE_TYPE(ArrayNode);
 
         ArgumentListNode* toArgumentList(JSGlobalData*, int) const;
 
@@ -427,6 +556,7 @@ namespace JSC {
 
         PropertyNode(JSGlobalData*, const Identifier&, ExpressionNode*, Type);
         PropertyNode(JSGlobalData*, double, ExpressionNode*, Type);
+        DECLARE_NODE_TYPE(PropertyNode);
 
         const Identifier& name() const { return m_name; }
         Type type() const { return m_type; }
@@ -442,6 +572,7 @@ namespace JSC {
     public:
         PropertyListNode(int, PropertyNode*);
         PropertyListNode(int, PropertyNode*, PropertyListNode*);
+        DECLARE_NODE_TYPE(PropertyListNode);
 
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
 
@@ -454,6 +585,7 @@ namespace JSC {
     public:
         ObjectLiteralNode(int);
         ObjectLiteralNode(int, PropertyListNode*);
+        DECLARE_NODE_TYPE(ObjectLiteralNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -464,6 +596,7 @@ namespace JSC {
     class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         BracketAccessorNode(int, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
+        DECLARE_NODE_TYPE(BracketAccessorNode);
 
         ExpressionNode* base() const { return m_base; }
         ExpressionNode* subscript() const { return m_subscript; }
@@ -482,6 +615,7 @@ namespace JSC {
     class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         DotAccessorNode(int, ExpressionNode* base, const Identifier&);
+        DECLARE_NODE_TYPE(DotAccessorNode);
 
         ExpressionNode* base() const { return m_base; }
         const Identifier& identifier() const { return m_ident; }
@@ -500,6 +634,7 @@ namespace JSC {
     public:
         ArgumentListNode(int, ExpressionNode*);
         ArgumentListNode(int, ArgumentListNode*, ExpressionNode*);
+        DECLARE_NODE_TYPE(ArgumentListNode);
 
         ArgumentListNode* m_next;
         ExpressionNode* m_expr;
@@ -512,6 +647,7 @@ namespace JSC {
     public:
         ArgumentsNode();
         ArgumentsNode(ArgumentListNode*);
+        DECLARE_NODE_TYPE(ArgumentsNode);
 
         ArgumentListNode* m_listNode;
     };
@@ -520,6 +656,7 @@ namespace JSC {
     public:
         NewExprNode(int, ExpressionNode*);
         NewExprNode(int, ExpressionNode*, ArgumentsNode*);
+        DECLARE_NODE_TYPE(NewExprNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -531,6 +668,7 @@ namespace JSC {
     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         EvalFunctionCallNode(int, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(EvalFunctionCallNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -541,6 +679,7 @@ namespace JSC {
     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         FunctionCallValueNode(int, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(FunctionCallValueNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -552,6 +691,7 @@ namespace JSC {
     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         FunctionCallResolveNode(int, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(FunctionCallResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -565,6 +705,7 @@ namespace JSC {
     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         FunctionCallBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(FunctionCallBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -577,6 +718,7 @@ namespace JSC {
     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         FunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(FunctionCallDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -590,6 +732,7 @@ namespace JSC {
     class CallFunctionCallDotNode : public FunctionCallDotNode {
     public:
         CallFunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(CallFunctionCallDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -598,6 +741,7 @@ namespace JSC {
     class ApplyFunctionCallDotNode : public FunctionCallDotNode {
     public:
         ApplyFunctionCallDotNode(int, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(ApplyFunctionCallDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -614,6 +758,7 @@ namespace JSC {
     class PostfixResolveNode : public PrePostResolveNode {
     public:
         PostfixResolveNode(int, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PostfixResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -624,6 +769,7 @@ namespace JSC {
     class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         PostfixBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PostfixBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -636,6 +782,7 @@ namespace JSC {
     class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         PostfixDotNode(int, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PostfixDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -648,6 +795,7 @@ namespace JSC {
     class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         PostfixErrorNode(int, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PostfixErrorNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -659,6 +807,7 @@ namespace JSC {
     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         DeleteResolveNode(int, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(DeleteResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -669,6 +818,7 @@ namespace JSC {
     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         DeleteBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(DeleteBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -680,6 +830,7 @@ namespace JSC {
     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         DeleteDotNode(int, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(DeleteDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -691,6 +842,7 @@ namespace JSC {
     class DeleteValueNode : public ExpressionNode {
     public:
         DeleteValueNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(DeleteValueNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -701,6 +853,7 @@ namespace JSC {
     class VoidNode : public ExpressionNode {
     public:
         VoidNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(VoidNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -711,6 +864,7 @@ namespace JSC {
     class TypeOfResolveNode : public ExpressionNode {
     public:
         TypeOfResolveNode(int, const Identifier&);
+        DECLARE_NODE_TYPE(TypeOfResolveNode);
 
         const Identifier& identifier() const { return m_ident; }
 
@@ -723,6 +877,7 @@ namespace JSC {
     class TypeOfValueNode : public ExpressionNode {
     public:
         TypeOfValueNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(TypeOfValueNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -733,6 +888,7 @@ namespace JSC {
     class PrefixResolveNode : public PrePostResolveNode {
     public:
         PrefixResolveNode(int, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PrefixResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -743,6 +899,7 @@ namespace JSC {
     class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
         PrefixBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PrefixBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -755,6 +912,7 @@ namespace JSC {
     class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
     public:
         PrefixDotNode(int, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PrefixDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -767,6 +925,7 @@ namespace JSC {
     class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         PrefixErrorNode(int, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(PrefixErrorNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -795,6 +954,7 @@ namespace JSC {
     class UnaryPlusNode : public UnaryOpNode {
     public:
         UnaryPlusNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(UnaryPlusNode);
 
     private:
         virtual ExpressionNode* stripUnaryPlus() { return expr(); }
@@ -803,11 +963,13 @@ namespace JSC {
     class NegateNode : public UnaryOpNode {
     public:
         NegateNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(NegateNode);
     };
 
     class BitwiseNotNode : public ExpressionNode {
     public:
         BitwiseNotNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(BitwiseNotNode);
 
     protected:
         ExpressionNode* expr() { return m_expr; }
@@ -822,6 +984,7 @@ namespace JSC {
     class LogicalNotNode : public UnaryOpNode {
     public:
         LogicalNotNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(LogicalNotNode);
     private:
         void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
         virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
@@ -855,21 +1018,25 @@ namespace JSC {
     class MultNode : public BinaryOpNode {
     public:
         MultNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(MultNode);
     };
 
     class DivNode : public BinaryOpNode {
     public:
         DivNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(DivNode);
     };
 
     class ModNode : public BinaryOpNode {
     public:
         ModNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(ModNode);
     };
 
     class AddNode : public BinaryOpNode {
     public:
         AddNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(AddNode);
 
         virtual bool isAdd() const { return true; }
     };
@@ -877,6 +1044,7 @@ namespace JSC {
     class SubNode : public BinaryOpNode {
     public:
         SubNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(SubNode);
 
         virtual bool isSubtract() const { return true; }
     };
@@ -884,36 +1052,43 @@ namespace JSC {
     class LeftShiftNode : public BinaryOpNode {
     public:
         LeftShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(LeftShiftNode);
     };
 
     class RightShiftNode : public BinaryOpNode {
     public:
         RightShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(RightShiftNode);
     };
 
     class UnsignedRightShiftNode : public BinaryOpNode {
     public:
         UnsignedRightShiftNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(UnsignedRightShiftNode);
     };
 
     class LessNode : public BinaryOpNode {
     public:
         LessNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(LessNode);
     };
 
     class GreaterNode : public BinaryOpNode {
     public:
         GreaterNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(GreaterNode);
     };
 
     class LessEqNode : public BinaryOpNode {
     public:
         LessEqNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(LessEqNode);
     };
 
     class GreaterEqNode : public BinaryOpNode {
     public:
         GreaterEqNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(GreaterEqNode);
     };
 
     class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
@@ -928,6 +1103,7 @@ namespace JSC {
     class InstanceOfNode : public ThrowableBinaryOpNode {
     public:
         InstanceOfNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(InstanceOfNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -936,11 +1112,13 @@ namespace JSC {
     class InNode : public ThrowableBinaryOpNode {
     public:
         InNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(InNode);
     };
 
     class EqualNode : public BinaryOpNode {
     public:
         EqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(EqualNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -949,11 +1127,13 @@ namespace JSC {
     class NotEqualNode : public BinaryOpNode {
     public:
         NotEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(NotEqualNode);
     };
 
     class StrictEqualNode : public BinaryOpNode {
     public:
         StrictEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(StrictEqualNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -962,27 +1142,32 @@ namespace JSC {
     class NotStrictEqualNode : public BinaryOpNode {
     public:
         NotStrictEqualNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(NotStrictEqualNode);
     };
 
     class BitAndNode : public BinaryOpNode {
     public:
         BitAndNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(BitAndNode);
     };
 
     class BitOrNode : public BinaryOpNode {
     public:
         BitOrNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(BitOrNode);
     };
 
     class BitXOrNode : public BinaryOpNode {
     public:
         BitXOrNode(int, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(BitXOrNode);
     };
 
     // m_expr1 && m_expr2, m_expr1 || m_expr2
     class LogicalOpNode : public ExpressionNode {
     public:
         LogicalOpNode(int, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
+        DECLARE_NODE_TYPE(LogicalOpNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -998,6 +1183,7 @@ namespace JSC {
     class ConditionalNode : public ExpressionNode {
     public:
         ConditionalNode(int, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
+        DECLARE_NODE_TYPE(ConditionalNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1010,6 +1196,7 @@ namespace JSC {
     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         ReadModifyResolveNode(int, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(ReadModifyResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1024,6 +1211,7 @@ namespace JSC {
     class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         AssignResolveNode(int, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
+        DECLARE_NODE_TYPE(AssignResolveNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1037,6 +1225,7 @@ namespace JSC {
     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         ReadModifyBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(ReadModifyBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1052,6 +1241,7 @@ namespace JSC {
     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         AssignBracketNode(int, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(AssignBracketNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1066,6 +1256,7 @@ namespace JSC {
     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         AssignDotNode(int, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(AssignDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1079,6 +1270,7 @@ namespace JSC {
     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
     public:
         ReadModifyDotNode(int, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(ReadModifyDotNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1093,6 +1285,7 @@ namespace JSC {
     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
     public:
         AssignErrorNode(int, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
+        DECLARE_NODE_TYPE(AssignErrorNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1107,6 +1300,7 @@ namespace JSC {
     class CommaNode : public ExpressionNode, public ParserArenaDeletable {
     public:
         CommaNode(int, ExpressionNode* expr1, ExpressionNode* expr2);
+        DECLARE_NODE_TYPE(CommaNode);
 
         using ParserArenaDeletable::operator new;
 
@@ -1122,6 +1316,7 @@ namespace JSC {
     class ConstDeclNode : public ExpressionNode {
     public:
         ConstDeclNode(int, const Identifier&, ExpressionNode*);
+        DECLARE_NODE_TYPE(ConstDeclNode);
 
         bool hasInitializer() const { return m_init; }
         const Identifier& ident() { return m_ident; }
@@ -1142,6 +1337,9 @@ namespace JSC {
     class ConstStatementNode : public StatementNode {
     public:
         ConstStatementNode(int, ConstDeclNode* next);
+        DECLARE_NODE_TYPE(ConstStatementNode);
+
+        virtual void computeMaximumScopeDepth(int& scopeDepth, int& variableDepth) const { }
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1167,6 +1365,7 @@ namespace JSC {
     class BlockNode : public StatementNode {
     public:
         BlockNode(int, SourceElements* = 0);
+        DECLARE_NODE_TYPE(BlockNode);
 
         StatementNode* singleStatement() const;
         StatementNode* lastStatement() const;
@@ -1182,6 +1381,7 @@ namespace JSC {
     class EmptyStatementNode : public StatementNode {
     public:
         EmptyStatementNode(int);
+        DECLARE_NODE_TYPE(EmptyStatementNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1192,6 +1392,7 @@ namespace JSC {
     class DebuggerStatementNode : public StatementNode {
     public:
         DebuggerStatementNode(int);
+        DECLARE_NODE_TYPE(DebuggerStatementNode);
         
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1200,6 +1401,7 @@ namespace JSC {
     class ExprStatementNode : public StatementNode {
     public:
         ExprStatementNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(ExprStatementNode);
 
         ExpressionNode* expr() const { return m_expr; }
 
@@ -1214,6 +1416,7 @@ namespace JSC {
     class VarStatementNode : public StatementNode {
     public:
         VarStatementNode(int, ExpressionNode*);        
+        DECLARE_NODE_TYPE(VarStatementNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1224,6 +1427,7 @@ namespace JSC {
     class IfNode : public StatementNode {
     public:
         IfNode(int, ExpressionNode* condition, StatementNode* ifBlock);
+        DECLARE_NODE_TYPE(IfNode);
 
     protected:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1235,6 +1439,7 @@ namespace JSC {
     class IfElseNode : public IfNode {
     public:
         IfElseNode(int, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
+        DECLARE_NODE_TYPE(IfElseNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1245,6 +1450,7 @@ namespace JSC {
     class DoWhileNode : public StatementNode {
     public:
         DoWhileNode(int, StatementNode*, ExpressionNode*);
+        DECLARE_NODE_TYPE(DoWhileNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1256,6 +1462,7 @@ namespace JSC {
     class WhileNode : public StatementNode {
     public:
         WhileNode(int, ExpressionNode*, StatementNode*);
+        DECLARE_NODE_TYPE(WhileNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1267,6 +1474,7 @@ namespace JSC {
     class ForNode : public StatementNode {
     public:
         ForNode(int, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, bool expr1WasVarDecl);
+        DECLARE_NODE_TYPE(ForNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1282,6 +1490,7 @@ namespace JSC {
     public:
         ForInNode(JSGlobalData*, int, ExpressionNode*, ExpressionNode*, StatementNode*);
         ForInNode(JSGlobalData*, int, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
+        DECLARE_NODE_TYPE(ForInNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1298,6 +1507,7 @@ namespace JSC {
     public:
         ContinueNode(JSGlobalData*, int);
         ContinueNode(int, const Identifier&);
+        DECLARE_NODE_TYPE(ContinueNode);
         
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1309,6 +1519,7 @@ namespace JSC {
     public:
         BreakNode(JSGlobalData*, int);
         BreakNode(int, const Identifier&);
+        DECLARE_NODE_TYPE(BreakNode);
         
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1319,6 +1530,7 @@ namespace JSC {
     class ReturnNode : public StatementNode, public ThrowableExpressionData {
     public:
         ReturnNode(int, ExpressionNode* value);
+        DECLARE_NODE_TYPE(ReturnNode);
 
         ExpressionNode* value() { return m_value; }
 
@@ -1333,6 +1545,7 @@ namespace JSC {
     class WithNode : public StatementNode {
     public:
         WithNode(int, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
+        DECLARE_NODE_TYPE(WithNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1346,6 +1559,7 @@ namespace JSC {
     class LabelNode : public StatementNode, public ThrowableExpressionData {
     public:
         LabelNode(int, const Identifier& name, StatementNode*);
+        DECLARE_NODE_TYPE(LabelNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1357,6 +1571,7 @@ namespace JSC {
     class ThrowNode : public StatementNode, public ThrowableExpressionData {
     public:
         ThrowNode(int, ExpressionNode*);
+        DECLARE_NODE_TYPE(ThrowNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1367,6 +1582,7 @@ namespace JSC {
     class TryNode : public StatementNode {
     public:
         TryNode(int, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
+        DECLARE_NODE_TYPE(TryNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1477,6 +1693,8 @@ namespace JSC {
 
         static const bool scopeIsFunction = false;
 
+        DECLARE_NODE_TYPE(ProgramNode);
+
     private:
         ProgramNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
 
@@ -1490,6 +1708,8 @@ namespace JSC {
 
         static const bool scopeIsFunction = false;
 
+        DECLARE_NODE_TYPE(EvalNode);
+
     private:
         EvalNode(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
 
@@ -1511,6 +1731,8 @@ namespace JSC {
         static FunctionBodyNode* create(JSGlobalData*, int, ScopeFlags);
         static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, int, SourceElements*, VarStack*, FunctionStack*, IdentifierSet&, const SourceCode&, ScopeFlags, int numConstants);
 
+        DECLARE_NODE_TYPE(FunctionBodyNode);
+
         FunctionParameters* parameters() const { return m_parameters.get(); }
         size_t parameterCount() const { return m_parameters->size(); }
 
@@ -1537,6 +1759,7 @@ namespace JSC {
     class FuncExprNode : public ExpressionNode {
     public:
         FuncExprNode(int, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+        DECLARE_NODE_TYPE(FuncExprNode);
 
         FunctionBodyNode* body() { return m_body; }
 
@@ -1551,6 +1774,7 @@ namespace JSC {
     class FuncDeclNode : public StatementNode {
     public:
         FuncDeclNode(int, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
+        DECLARE_NODE_TYPE(FuncDeclNode);
 
         FunctionBodyNode* body() { return m_body; }
 
@@ -1563,6 +1787,7 @@ namespace JSC {
     class CaseClauseNode : public ParserArenaFreeable {
     public:
         CaseClauseNode(ExpressionNode*, SourceElements* = 0);
+        DECLARE_NODE_TYPE(CaseClauseNode);
 
         ExpressionNode* expr() const { return m_expr; }
 
@@ -1577,6 +1802,7 @@ namespace JSC {
     public:
         ClauseListNode(CaseClauseNode*);
         ClauseListNode(ClauseListNode*, CaseClauseNode*);
+        DECLARE_NODE_TYPE(ClauseListNode);
 
         CaseClauseNode* getClause() const { return m_clause; }
         ClauseListNode* getNext() const { return m_next; }
@@ -1589,6 +1815,7 @@ namespace JSC {
     class CaseBlockNode : public ParserArenaFreeable {
     public:
         CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
+        DECLARE_NODE_TYPE(CaseBlockNode);
 
         RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
 
@@ -1602,6 +1829,7 @@ namespace JSC {
     class SwitchNode : public StatementNode {
     public:
         SwitchNode(int, ExpressionNode*, CaseBlockNode*);
+        DECLARE_NODE_TYPE(SwitchNode);
 
     private:
         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
@@ -1640,6 +1868,19 @@ namespace JSC {
         ClauseListNode* tail;
     };
 
+#undef DECLARE_NODE_TYPE
+
+    class NodeVisitor
+    {
+    public:
+        NodeVisitor() {}
+        virtual ~NodeVisitor() {}
+
+#define DECLARE_VISIT(name) virtual void visit##name(name *) = 0;
+FOR_EACH_CONCRETE_NODE_TYPE(DECLARE_VISIT)
+#undef DECLARE_VISIT
+    };
+
 } // namespace JSC
 
 #endif // Nodes_h
-- 
1.7.9.1

_______________________________________________
squirrelfish-dev mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/squirrelfish-dev

Reply via email to