webengine/osswebengine/JavaScriptCore/kjs/nodes.h
changeset 0 dd21522fd290
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 // -*- c-basic-offset: 2 -*-
       
     2 /*
       
     3  *  This file is part of the KDE libraries
       
     4  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
       
     5  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
       
     6  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
       
     7  *
       
     8  *  This library is free software; you can redistribute it and/or
       
     9  *  modify it under the terms of the GNU Library General Public
       
    10  *  License as published by the Free Software Foundation; either
       
    11  *  version 2 of the License, or (at your option) any later version.
       
    12  *
       
    13  *  This library is distributed in the hope that it will be useful,
       
    14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    16  *  Library General Public License for more details.
       
    17  *
       
    18  *  You should have received a copy of the GNU Library General Public License
       
    19  *  along with this library; see the file COPYING.LIB.  If not, write to
       
    20  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
       
    21  *  Boston, MA 02110-1301, USA.
       
    22  *
       
    23  */
       
    24 
       
    25 #ifndef NODES_H_
       
    26 #define NODES_H_
       
    27 
       
    28 #include "Parser.h"
       
    29 #include "internal.h"
       
    30 #include <wtf/ListRefPtr.h>
       
    31 #include <wtf/Vector.h>
       
    32 
       
    33 #if PLATFORM(X86) && COMPILER(GCC)
       
    34 #define KJS_FAST_CALL __attribute__((regparm(3)))
       
    35 #else
       
    36 #define KJS_FAST_CALL
       
    37 #endif
       
    38 
       
    39 #if COMPILER(GCC)
       
    40 #define KJS_NO_INLINE __attribute__((noinline))
       
    41 #else
       
    42 #define KJS_NO_INLINE
       
    43 #endif
       
    44 
       
    45 namespace KJS {
       
    46 
       
    47   class ProgramNode;
       
    48   class PropertyNameNode;
       
    49   class PropertyListNode;
       
    50   class RegExp;
       
    51   class SourceElementsNode;
       
    52   class SourceStream;
       
    53 
       
    54   enum Operator { OpEqual,
       
    55                   OpEqEq,
       
    56                   OpNotEq,
       
    57                   OpStrEq,
       
    58                   OpStrNEq,
       
    59                   OpPlusEq,
       
    60                   OpMinusEq,
       
    61                   OpMultEq,
       
    62                   OpDivEq,
       
    63                   OpPlusPlus,
       
    64                   OpMinusMinus,
       
    65                   OpLess,
       
    66                   OpLessEq,
       
    67                   OpGreater,
       
    68                   OpGreaterEq,
       
    69                   OpAndEq,
       
    70                   OpXOrEq,
       
    71                   OpOrEq,
       
    72                   OpModEq,
       
    73                   OpAnd,
       
    74                   OpOr,
       
    75                   OpBitAnd,
       
    76                   OpBitXOr,
       
    77                   OpBitOr,
       
    78                   OpLShift,
       
    79                   OpRShift,
       
    80                   OpURShift,
       
    81                   OpIn,
       
    82                   OpInstanceOf
       
    83   };
       
    84 
       
    85   class Node {
       
    86   public:
       
    87     Node() KJS_FAST_CALL;
       
    88     virtual ~Node();
       
    89 
       
    90     virtual JSValue *evaluate(ExecState *exec) KJS_FAST_CALL = 0;
       
    91     UString toString() const KJS_FAST_CALL;
       
    92     virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
       
    93     virtual void processVarDecls(ExecState*) KJS_FAST_CALL {}
       
    94     int lineNo() const KJS_FAST_CALL { return m_line; }
       
    95 
       
    96     void ref() KJS_FAST_CALL;
       
    97     void deref() KJS_FAST_CALL;
       
    98     unsigned refcount() KJS_FAST_CALL;
       
    99     static void clearNewNodes() KJS_FAST_CALL;
       
   100 
       
   101     virtual Node *nodeInsideAllParens() KJS_FAST_CALL;
       
   102 
       
   103     virtual bool isLocation() const KJS_FAST_CALL { return false; }
       
   104     virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
       
   105     virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
       
   106     virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
       
   107     virtual bool isGroupNode() const KJS_FAST_CALL { return false; }
       
   108 
       
   109     virtual void breakCycle() KJS_FAST_CALL { }
       
   110 
       
   111   protected:
       
   112     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
       
   113     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
       
   114 
       
   115     JSValue *throwError(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
       
   116     JSValue* throwError(ExecState *, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
       
   117     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *) KJS_FAST_CALL;
       
   118     JSValue *throwError(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
       
   119     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, const Identifier &) KJS_FAST_CALL;
       
   120     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, Node *) KJS_FAST_CALL;
       
   121     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, const Identifier &) KJS_FAST_CALL;
       
   122 
       
   123     JSValue *throwUndefinedVariableError(ExecState *, const Identifier &) KJS_FAST_CALL;
       
   124 
       
   125     void handleException(ExecState*) KJS_FAST_CALL;
       
   126     void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
       
   127 
       
   128     int m_line;
       
   129   private:
       
   130     // disallow assignment
       
   131     Node& operator=(const Node&) KJS_FAST_CALL;
       
   132     Node(const Node &other) KJS_FAST_CALL;
       
   133   };
       
   134 
       
   135   class StatementNode : public Node {
       
   136   public:
       
   137     StatementNode() KJS_FAST_CALL;
       
   138     void setLoc(int line0, int line1) KJS_FAST_CALL;
       
   139     int firstLine() const KJS_FAST_CALL { return lineNo(); }
       
   140     int lastLine() const KJS_FAST_CALL { return m_lastLine; }
       
   141     bool hitStatement(ExecState*) KJS_FAST_CALL;
       
   142     virtual Completion execute(ExecState *exec) KJS_FAST_CALL = 0;
       
   143     void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
       
   144     virtual void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
   145   protected:
       
   146     LabelStack ls;
       
   147   private:
       
   148     JSValue *evaluate(ExecState*) KJS_FAST_CALL { return jsUndefined(); }
       
   149     int m_lastLine;
       
   150   };
       
   151 
       
   152   class NullNode : public Node {
       
   153   public:
       
   154     NullNode() KJS_FAST_CALL {}
       
   155     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   156     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   157   };
       
   158 
       
   159   class BooleanNode : public Node {
       
   160   public:
       
   161     BooleanNode(bool v) KJS_FAST_CALL : value(v) {}
       
   162     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   163     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   164   private:
       
   165     bool value;
       
   166   };
       
   167 
       
   168   class NumberNode : public Node {
       
   169   public:
       
   170     NumberNode(double v) KJS_FAST_CALL : value(v) {}
       
   171     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   172     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   173   private:
       
   174     double value;
       
   175   };
       
   176 
       
   177   class StringNode : public Node {
       
   178   public:
       
   179     StringNode(const UString *v) KJS_FAST_CALL { value = *v; }
       
   180     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   181     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   182   private:
       
   183     UString value;
       
   184   };
       
   185 
       
   186   class RegExpNode : public Node {
       
   187   public:
       
   188     RegExpNode(const UString &p, const UString &f) KJS_FAST_CALL 
       
   189       : pattern(p), flags(f) { }
       
   190     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   191     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   192   private:
       
   193     UString pattern, flags;
       
   194   };
       
   195 
       
   196   class ThisNode : public Node {
       
   197   public:
       
   198     ThisNode() KJS_FAST_CALL {}
       
   199     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   200     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   201   };
       
   202 
       
   203   class ResolveNode : public Node {
       
   204   public:
       
   205     ResolveNode(const Identifier &s) KJS_FAST_CALL : ident(s) { }
       
   206     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   207     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   208 
       
   209     virtual bool isLocation() const KJS_FAST_CALL { return true; }
       
   210     virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
       
   211     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
       
   212 
       
   213   private:
       
   214     Identifier ident;
       
   215   };
       
   216 
       
   217   class GroupNode : public Node {
       
   218   public:
       
   219     GroupNode(Node *g) KJS_FAST_CALL : group(g) { }
       
   220     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   221     virtual Node *nodeInsideAllParens() KJS_FAST_CALL;
       
   222     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   223     virtual bool isGroupNode() const KJS_FAST_CALL { return true; }
       
   224   private:
       
   225     RefPtr<Node> group;
       
   226   };
       
   227 
       
   228   class ElementNode : public Node {
       
   229   public:
       
   230     // list pointer is tail of a circular list, cracked in the ArrayNode ctor
       
   231     ElementNode(int e, Node *n) KJS_FAST_CALL : next(this), elision(e), node(n) { Parser::noteNodeCycle(this); }
       
   232     ElementNode(ElementNode *l, int e, Node *n) KJS_FAST_CALL
       
   233       : next(l->next), elision(e), node(n) { l->next = this; }
       
   234     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   235     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   236     PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
   237     virtual void breakCycle() KJS_FAST_CALL;
       
   238   private:
       
   239     friend class ArrayNode;
       
   240     ListRefPtr<ElementNode> next;
       
   241     int elision;
       
   242     RefPtr<Node> node;
       
   243   };
       
   244 
       
   245   class ArrayNode : public Node {
       
   246   public:
       
   247     ArrayNode(int e) KJS_FAST_CALL : elision(e), opt(true) { }
       
   248     ArrayNode(ElementNode *ele) KJS_FAST_CALL
       
   249       : element(ele->next.release()), elision(0), opt(false) { Parser::removeNodeCycle(element.get()); }
       
   250     ArrayNode(int eli, ElementNode *ele) KJS_FAST_CALL
       
   251       : element(ele->next.release()), elision(eli), opt(true) { Parser::removeNodeCycle(element.get()); }
       
   252     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   253     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   254   private:
       
   255     RefPtr<ElementNode> element;
       
   256     int elision;
       
   257     bool opt;
       
   258   };
       
   259 
       
   260   class PropertyNameNode : public Node {
       
   261   public:
       
   262     PropertyNameNode(double d) KJS_FAST_CALL : numeric(d) { }
       
   263     PropertyNameNode(const Identifier &s) KJS_FAST_CALL : str(s) { }
       
   264     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   265     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   266   private:
       
   267     double numeric;
       
   268     Identifier str;
       
   269   };
       
   270   
       
   271   class PropertyNode : public Node {
       
   272   public:
       
   273     enum Type { Constant, Getter, Setter };
       
   274     PropertyNode(PropertyNameNode *n, Node *a, Type t) KJS_FAST_CALL
       
   275       : name(n), assign(a), type(t) { }
       
   276     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   277     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   278     friend class PropertyListNode;
       
   279   private:
       
   280     RefPtr<PropertyNameNode> name;
       
   281     RefPtr<Node> assign;
       
   282     Type type;
       
   283   };
       
   284   
       
   285   class PropertyListNode : public Node {
       
   286   public:
       
   287     // list pointer is tail of a circular list, cracked in the ObjectLiteralNode ctor
       
   288     PropertyListNode(PropertyNode *n) KJS_FAST_CALL
       
   289       : node(n), next(this) { Parser::noteNodeCycle(this); }
       
   290     PropertyListNode(PropertyNode *n, PropertyListNode *l) KJS_FAST_CALL
       
   291       : node(n), next(l->next) { l->next = this; }
       
   292     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   293     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   294     PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
   295     virtual void breakCycle() KJS_FAST_CALL;
       
   296   private:
       
   297     friend class ObjectLiteralNode;
       
   298     RefPtr<PropertyNode> node;
       
   299     ListRefPtr<PropertyListNode> next;
       
   300   };
       
   301 
       
   302   class ObjectLiteralNode : public Node {
       
   303   public:
       
   304     ObjectLiteralNode() KJS_FAST_CALL { }
       
   305     ObjectLiteralNode(PropertyListNode *l) KJS_FAST_CALL : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
       
   306     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   307     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   308   private:
       
   309     RefPtr<PropertyListNode> list;
       
   310   };
       
   311 
       
   312   class BracketAccessorNode : public Node {
       
   313   public:
       
   314     BracketAccessorNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
       
   315     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   316     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   317 
       
   318     virtual bool isLocation() const KJS_FAST_CALL { return true; }
       
   319     virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
       
   320     Node *base() KJS_FAST_CALL { return expr1.get(); }
       
   321     Node *subscript() KJS_FAST_CALL { return expr2.get(); }
       
   322 
       
   323   private:
       
   324     RefPtr<Node> expr1;
       
   325     RefPtr<Node> expr2;
       
   326   };
       
   327 
       
   328   class DotAccessorNode : public Node {
       
   329   public:
       
   330     DotAccessorNode(Node *e, const Identifier &s) KJS_FAST_CALL : expr(e), ident(s) { }
       
   331     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   332     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   333 
       
   334     virtual bool isLocation() const KJS_FAST_CALL { return true; }
       
   335     virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
       
   336     Node *base() const KJS_FAST_CALL { return expr.get(); }
       
   337     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
       
   338 
       
   339   private:
       
   340     RefPtr<Node> expr;
       
   341     Identifier ident;
       
   342   };
       
   343 
       
   344   class ArgumentListNode : public Node {
       
   345   public:
       
   346     // list pointer is tail of a circular list, cracked in the ArgumentsNode ctor
       
   347     ArgumentListNode(Node *e) KJS_FAST_CALL : next(this), expr(e) { Parser::noteNodeCycle(this); }
       
   348     ArgumentListNode(ArgumentListNode *l, Node *e) KJS_FAST_CALL 
       
   349       : next(l->next), expr(e) { l->next = this; }
       
   350     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   351     List evaluateList(ExecState*) KJS_FAST_CALL;
       
   352     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   353     PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
   354     virtual void breakCycle() KJS_FAST_CALL;
       
   355   private:
       
   356     friend class ArgumentsNode;
       
   357     ListRefPtr<ArgumentListNode> next;
       
   358     RefPtr<Node> expr;
       
   359   };
       
   360 
       
   361   class ArgumentsNode : public Node {
       
   362   public:
       
   363     ArgumentsNode() KJS_FAST_CALL { }
       
   364     ArgumentsNode(ArgumentListNode *l) KJS_FAST_CALL
       
   365       : list(l->next.release()) { Parser::removeNodeCycle(list.get()); }
       
   366     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   367     List evaluateList(ExecState *exec) KJS_FAST_CALL { return list ? list->evaluateList(exec) : List(); }
       
   368     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   369   private:
       
   370     RefPtr<ArgumentListNode> list;
       
   371   };
       
   372 
       
   373   class NewExprNode : public Node {
       
   374   public:
       
   375     NewExprNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   376     NewExprNode(Node *e, ArgumentsNode *a) KJS_FAST_CALL : expr(e), args(a) {}
       
   377     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   378     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   379   private:
       
   380     RefPtr<Node> expr;
       
   381     RefPtr<ArgumentsNode> args;
       
   382   };
       
   383 
       
   384   class FunctionCallValueNode : public Node {
       
   385   public:
       
   386     FunctionCallValueNode(Node *e, ArgumentsNode *a) KJS_FAST_CALL : expr(e), args(a) {}
       
   387     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   388     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   389   private:
       
   390     RefPtr<Node> expr;
       
   391     RefPtr<ArgumentsNode> args;
       
   392   };
       
   393 
       
   394   class FunctionCallResolveNode : public Node {
       
   395   public:
       
   396     FunctionCallResolveNode(const Identifier& i, ArgumentsNode *a) KJS_FAST_CALL : ident(i), args(a) {}
       
   397     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   398     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   399   private:
       
   400     Identifier ident;
       
   401     RefPtr<ArgumentsNode> args;
       
   402   };
       
   403 
       
   404   class FunctionCallBracketNode : public Node {
       
   405   public:
       
   406     FunctionCallBracketNode(Node *b, Node *s, ArgumentsNode *a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
       
   407     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   408     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   409   protected:
       
   410     RefPtr<Node> base;
       
   411     RefPtr<Node> subscript;
       
   412     RefPtr<ArgumentsNode> args;
       
   413   };
       
   414 
       
   415   class FunctionCallParenBracketNode : public FunctionCallBracketNode {
       
   416   public:
       
   417     FunctionCallParenBracketNode(Node *b, Node *s, ArgumentsNode *a) KJS_FAST_CALL : FunctionCallBracketNode(b, s, a) {}
       
   418     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   419   };
       
   420 
       
   421   class FunctionCallDotNode : public Node {
       
   422   public:
       
   423     FunctionCallDotNode(Node *b, const Identifier &i, ArgumentsNode *a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
       
   424     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   425     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   426   protected:
       
   427     RefPtr<Node> base;
       
   428     Identifier ident;
       
   429     RefPtr<ArgumentsNode> args;
       
   430   };
       
   431 
       
   432   class FunctionCallParenDotNode : public FunctionCallDotNode {
       
   433   public:
       
   434     FunctionCallParenDotNode(Node *b, const Identifier &i, ArgumentsNode *a) KJS_FAST_CALL : FunctionCallDotNode(b, i, a) {}
       
   435     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   436   };
       
   437 
       
   438   class PostfixResolveNode : public Node {
       
   439   public:
       
   440     PostfixResolveNode(const Identifier& i, Operator o) KJS_FAST_CALL : m_ident(i), m_oper(o) {}
       
   441     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   442     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   443   private:
       
   444     Identifier m_ident;
       
   445     Operator m_oper;
       
   446   };
       
   447 
       
   448   class PostfixBracketNode : public Node {
       
   449   public:
       
   450     PostfixBracketNode(Node *b, Node *s, Operator o) KJS_FAST_CALL : m_base(b), m_subscript(s), m_oper(o) {}
       
   451     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   452     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   453   private:
       
   454     RefPtr<Node> m_base;
       
   455     RefPtr<Node> m_subscript;
       
   456     Operator m_oper;
       
   457   };
       
   458 
       
   459   class PostfixDotNode : public Node {
       
   460   public:
       
   461     PostfixDotNode(Node *b, const Identifier& i, Operator o) KJS_FAST_CALL : m_base(b), m_ident(i), m_oper(o) {}
       
   462     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   463     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   464   private:
       
   465     RefPtr<Node> m_base;
       
   466     Identifier m_ident;
       
   467     Operator m_oper;
       
   468   };
       
   469 
       
   470   class PostfixErrorNode : public Node {
       
   471   public:
       
   472     PostfixErrorNode(Node* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
       
   473     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   474     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   475   private:
       
   476     RefPtr<Node> m_expr;
       
   477     Operator m_oper;
       
   478   };
       
   479 
       
   480   class DeleteResolveNode : public Node {
       
   481   public:
       
   482     DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
       
   483     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   484     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   485   private:
       
   486     Identifier m_ident;
       
   487   };
       
   488 
       
   489   class DeleteBracketNode : public Node {
       
   490   public:
       
   491     DeleteBracketNode(Node *base, Node *subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
       
   492     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   493     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   494   private:
       
   495     RefPtr<Node> m_base;
       
   496     RefPtr<Node> m_subscript;
       
   497   };
       
   498 
       
   499   class DeleteDotNode : public Node {
       
   500   public:
       
   501     DeleteDotNode(Node *base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
       
   502     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   503     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   504   private:
       
   505     RefPtr<Node> m_base;
       
   506     Identifier m_ident;
       
   507   };
       
   508 
       
   509   class DeleteValueNode : public Node {
       
   510   public:
       
   511     DeleteValueNode(Node *e) KJS_FAST_CALL : m_expr(e) {}
       
   512     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   513     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   514   private:
       
   515     RefPtr<Node> m_expr;
       
   516   };
       
   517 
       
   518   class VoidNode : public Node {
       
   519   public:
       
   520     VoidNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   521     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   522     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   523   private:
       
   524     RefPtr<Node> expr;
       
   525   };
       
   526 
       
   527   class TypeOfResolveNode : public Node {
       
   528   public:
       
   529     TypeOfResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
       
   530     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   531     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   532   private:
       
   533     Identifier m_ident;
       
   534   };
       
   535 
       
   536   class TypeOfValueNode : public Node {
       
   537   public:
       
   538     TypeOfValueNode(Node *e) KJS_FAST_CALL : m_expr(e) {}
       
   539     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   540     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   541   private:
       
   542     RefPtr<Node> m_expr;
       
   543   };
       
   544 
       
   545   class PrefixResolveNode : public Node {
       
   546   public:
       
   547     PrefixResolveNode(const Identifier& i, Operator o) KJS_FAST_CALL : m_ident(i), m_oper(o) {}
       
   548     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   549     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   550   private:
       
   551     Identifier m_ident;
       
   552     Operator m_oper;
       
   553   };
       
   554 
       
   555   class PrefixBracketNode : public Node {
       
   556   public:
       
   557     PrefixBracketNode(Node *b, Node *s, Operator o) KJS_FAST_CALL : m_base(b), m_subscript(s), m_oper(o) {}
       
   558     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   559     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   560   private:
       
   561     RefPtr<Node> m_base;
       
   562     RefPtr<Node> m_subscript;
       
   563     Operator m_oper;
       
   564   };
       
   565 
       
   566   class PrefixDotNode : public Node {
       
   567   public:
       
   568     PrefixDotNode(Node *b, const Identifier& i, Operator o) KJS_FAST_CALL : m_base(b), m_ident(i), m_oper(o) {}
       
   569     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   570     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   571   private:
       
   572     RefPtr<Node> m_base;
       
   573     Identifier m_ident;
       
   574     Operator m_oper;
       
   575   };
       
   576 
       
   577   class PrefixErrorNode : public Node {
       
   578   public:
       
   579     PrefixErrorNode(Node* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
       
   580     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   581     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   582   private:
       
   583     RefPtr<Node> m_expr;
       
   584     Operator m_oper;
       
   585   };
       
   586 
       
   587   class UnaryPlusNode : public Node {
       
   588   public:
       
   589     UnaryPlusNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   590     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   591     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   592   private:
       
   593     RefPtr<Node> expr;
       
   594   };
       
   595 
       
   596   class NegateNode : public Node {
       
   597   public:
       
   598     NegateNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   599     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   600     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   601   private:
       
   602     RefPtr<Node> expr;
       
   603   };
       
   604 
       
   605   class BitwiseNotNode : public Node {
       
   606   public:
       
   607     BitwiseNotNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   608     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   609     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   610   private:
       
   611     RefPtr<Node> expr;
       
   612   };
       
   613 
       
   614   class LogicalNotNode : public Node {
       
   615   public:
       
   616     LogicalNotNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   617     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   618     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   619   private:
       
   620     RefPtr<Node> expr;
       
   621   };
       
   622 
       
   623   class MultNode : public Node {
       
   624   public:
       
   625     MultNode(Node *t1, Node *t2, char op) KJS_FAST_CALL : term1(t1), term2(t2), oper(op) {}
       
   626     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   627     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   628   private:
       
   629     RefPtr<Node> term1;
       
   630     RefPtr<Node> term2;
       
   631     char oper;
       
   632   };
       
   633 
       
   634   class AddNode : public Node {
       
   635   public:
       
   636     AddNode(Node *t1, Node *t2, char op) KJS_FAST_CALL : term1(t1), term2(t2), oper(op) {}
       
   637     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   638     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   639   private:
       
   640     RefPtr<Node> term1;
       
   641     RefPtr<Node> term2;
       
   642     char oper;
       
   643   };
       
   644 
       
   645   class ShiftNode : public Node {
       
   646   public:
       
   647     ShiftNode(Node *t1, Operator o, Node *t2) KJS_FAST_CALL
       
   648       : term1(t1), term2(t2), oper(o) {}
       
   649     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   650     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   651   private:
       
   652     RefPtr<Node> term1;
       
   653     RefPtr<Node> term2;
       
   654     Operator oper;
       
   655   };
       
   656 
       
   657   class RelationalNode : public Node {
       
   658   public:
       
   659     RelationalNode(Node *e1, Operator o, Node *e2) KJS_FAST_CALL :
       
   660       expr1(e1), expr2(e2), oper(o) {}
       
   661     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   662     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   663   private:
       
   664     RefPtr<Node> expr1;
       
   665     RefPtr<Node> expr2;
       
   666     Operator oper;
       
   667   };
       
   668 
       
   669   class EqualNode : public Node {
       
   670   public:
       
   671     EqualNode(Node *e1, Operator o, Node *e2) KJS_FAST_CALL
       
   672       : expr1(e1), expr2(e2), oper(o) {}
       
   673     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   674     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   675   private:
       
   676     RefPtr<Node> expr1;
       
   677     RefPtr<Node> expr2;
       
   678     Operator oper;
       
   679   };
       
   680 
       
   681   class BitOperNode : public Node {
       
   682   public:
       
   683     BitOperNode(Node *e1, Operator o, Node *e2) KJS_FAST_CALL :
       
   684       expr1(e1), expr2(e2), oper(o) {}
       
   685     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   686     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   687   private:
       
   688     RefPtr<Node> expr1;
       
   689     RefPtr<Node> expr2;
       
   690     Operator oper;
       
   691   };
       
   692 
       
   693   /**
       
   694    * expr1 && expr2, expr1 || expr2
       
   695    */
       
   696   class BinaryLogicalNode : public Node {
       
   697   public:
       
   698     BinaryLogicalNode(Node *e1, Operator o, Node *e2) KJS_FAST_CALL :
       
   699       expr1(e1), expr2(e2), oper(o) {}
       
   700     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   701     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   702   private:
       
   703     RefPtr<Node> expr1;
       
   704     RefPtr<Node> expr2;
       
   705     Operator oper;
       
   706   };
       
   707 
       
   708   /**
       
   709    * The ternary operator, "logical ? expr1 : expr2"
       
   710    */
       
   711   class ConditionalNode : public Node {
       
   712   public:
       
   713     ConditionalNode(Node *l, Node *e1, Node *e2) KJS_FAST_CALL :
       
   714       logical(l), expr1(e1), expr2(e2) {}
       
   715     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   716     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   717   private:
       
   718     RefPtr<Node> logical;
       
   719     RefPtr<Node> expr1;
       
   720     RefPtr<Node> expr2;
       
   721   };
       
   722 
       
   723   class AssignResolveNode : public Node {
       
   724   public:
       
   725     AssignResolveNode(const Identifier &ident, Operator oper, Node *right) KJS_FAST_CALL
       
   726       : m_ident(ident), m_oper(oper), m_right(right) {}
       
   727     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   728     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   729   protected:
       
   730     Identifier m_ident;
       
   731     Operator m_oper;
       
   732     RefPtr<Node> m_right;
       
   733   };
       
   734 
       
   735   class AssignBracketNode : public Node {
       
   736   public:
       
   737     AssignBracketNode(Node *base, Node *subscript, Operator oper, Node *right) KJS_FAST_CALL
       
   738       : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
       
   739     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   740     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   741   protected:
       
   742     RefPtr<Node> m_base;
       
   743     RefPtr<Node> m_subscript;
       
   744     Operator m_oper;
       
   745     RefPtr<Node> m_right;
       
   746   };
       
   747 
       
   748   class AssignDotNode : public Node {
       
   749   public:
       
   750     AssignDotNode(Node *base, const Identifier& ident, Operator oper, Node *right) KJS_FAST_CALL
       
   751       : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
       
   752     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   753     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   754   protected:
       
   755     RefPtr<Node> m_base;
       
   756     Identifier m_ident;
       
   757     Operator m_oper;
       
   758     RefPtr<Node> m_right;
       
   759   };
       
   760 
       
   761   class AssignErrorNode : public Node {
       
   762   public:
       
   763     AssignErrorNode(Node* left, Operator oper, Node* right) KJS_FAST_CALL
       
   764       : m_left(left), m_oper(oper), m_right(right) {}
       
   765     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   766     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   767   protected:
       
   768     RefPtr<Node> m_left;
       
   769     Operator m_oper;
       
   770     RefPtr<Node> m_right;
       
   771   };
       
   772 
       
   773   class CommaNode : public Node {
       
   774   public:
       
   775     CommaNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
       
   776     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   777     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   778   private:
       
   779     RefPtr<Node> expr1;
       
   780     RefPtr<Node> expr2;
       
   781   };
       
   782 
       
   783   class AssignExprNode : public Node {
       
   784   public:
       
   785     AssignExprNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   786     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   787     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   788   private:
       
   789     RefPtr<Node> expr;
       
   790   };
       
   791 
       
   792   class VarDeclNode: public Node {
       
   793   public:
       
   794     enum Type { Variable, Constant };
       
   795     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) KJS_FAST_CALL;
       
   796     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   797     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   798     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   799   private:
       
   800     JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
       
   801     Type varType;
       
   802     Identifier ident;
       
   803     RefPtr<AssignExprNode> init;
       
   804   };
       
   805 
       
   806   class VarDeclListNode : public Node {
       
   807   public:
       
   808     // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
       
   809     VarDeclListNode(VarDeclNode *v) KJS_FAST_CALL : next(this), var(v) { Parser::noteNodeCycle(this); }
       
   810     VarDeclListNode(VarDeclListNode *l, VarDeclNode *v) KJS_FAST_CALL
       
   811       : next(l->next), var(v) { l->next = this; }
       
   812     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
   813     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   814     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   815     PassRefPtr<VarDeclListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
   816     virtual void breakCycle() KJS_FAST_CALL;
       
   817   private:
       
   818     friend class ForNode;
       
   819     friend class VarStatementNode;
       
   820     ListRefPtr<VarDeclListNode> next;
       
   821     RefPtr<VarDeclNode> var;
       
   822   };
       
   823 
       
   824   class VarStatementNode : public StatementNode {
       
   825   public:
       
   826     VarStatementNode(VarDeclListNode *l) KJS_FAST_CALL : next(l->next.release()) { Parser::removeNodeCycle(next.get()); }
       
   827     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   828     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   829     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   830   private:
       
   831     RefPtr<VarDeclListNode> next;
       
   832   };
       
   833 
       
   834   class BlockNode : public StatementNode {
       
   835   public:
       
   836     BlockNode(SourceElementsNode *s) KJS_FAST_CALL;
       
   837     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   838     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   839     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   840   protected:
       
   841     RefPtr<SourceElementsNode> source;
       
   842   };
       
   843 
       
   844   class EmptyStatementNode : public StatementNode {
       
   845   public:
       
   846     EmptyStatementNode() KJS_FAST_CALL { } // debug
       
   847     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   848     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   849   };
       
   850 
       
   851   class ExprStatementNode : public StatementNode {
       
   852   public:
       
   853     ExprStatementNode(Node *e) KJS_FAST_CALL : expr(e) { }
       
   854     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   855     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   856   private:
       
   857     RefPtr<Node> expr;
       
   858   };
       
   859 
       
   860   class IfNode : public StatementNode {
       
   861   public:
       
   862     IfNode(Node *e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
       
   863       : expr(e), statement1(s1), statement2(s2) {}
       
   864     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   865     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   866     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   867   private:
       
   868     RefPtr<Node> expr;
       
   869     RefPtr<StatementNode> statement1;
       
   870     RefPtr<StatementNode> statement2;
       
   871   };
       
   872 
       
   873   class DoWhileNode : public StatementNode {
       
   874   public:
       
   875     DoWhileNode(StatementNode *s, Node *e) KJS_FAST_CALL : statement(s), expr(e) {}
       
   876     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   877     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   878     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   879   private:
       
   880     RefPtr<StatementNode> statement;
       
   881     RefPtr<Node> expr;
       
   882   };
       
   883 
       
   884   class WhileNode : public StatementNode {
       
   885   public:
       
   886     WhileNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) {}
       
   887     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   888     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   889     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   890   private:
       
   891     RefPtr<Node> expr;
       
   892     RefPtr<StatementNode> statement;
       
   893   };
       
   894 
       
   895   class ForNode : public StatementNode {
       
   896   public:
       
   897     ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) KJS_FAST_CALL :
       
   898       expr1(e1), expr2(e2), expr3(e3), statement(s) {}
       
   899     ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) KJS_FAST_CALL :
       
   900       expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s) { Parser::removeNodeCycle(expr1.get()); }
       
   901     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   902     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   903     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   904   private:
       
   905     RefPtr<Node> expr1;
       
   906     RefPtr<Node> expr2;
       
   907     RefPtr<Node> expr3;
       
   908     RefPtr<StatementNode> statement;
       
   909   };
       
   910 
       
   911   class ForInNode : public StatementNode {
       
   912   public:
       
   913     ForInNode(Node *l, Node *e, StatementNode *s) KJS_FAST_CALL;
       
   914     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s) KJS_FAST_CALL;
       
   915     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   916     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   917     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   918   private:
       
   919     Identifier ident;
       
   920     RefPtr<AssignExprNode> init;
       
   921     RefPtr<Node> lexpr;
       
   922     RefPtr<Node> expr;
       
   923     RefPtr<VarDeclNode> varDecl;
       
   924     RefPtr<StatementNode> statement;
       
   925   };
       
   926 
       
   927   class ContinueNode : public StatementNode {
       
   928   public:
       
   929     ContinueNode() KJS_FAST_CALL { }
       
   930     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
       
   931     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   932     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   933   private:
       
   934     Identifier ident;
       
   935   };
       
   936 
       
   937   class BreakNode : public StatementNode {
       
   938   public:
       
   939     BreakNode() KJS_FAST_CALL { }
       
   940     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
       
   941     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   942     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   943   private:
       
   944     Identifier ident;
       
   945   };
       
   946 
       
   947   class ReturnNode : public StatementNode {
       
   948   public:
       
   949     ReturnNode(Node *v) KJS_FAST_CALL : value(v) {}
       
   950     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   951     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   952   private:
       
   953     RefPtr<Node> value;
       
   954   };
       
   955 
       
   956   class WithNode : public StatementNode {
       
   957   public:
       
   958     WithNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) {}
       
   959     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   960     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   961     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   962   private:
       
   963     RefPtr<Node> expr;
       
   964     RefPtr<StatementNode> statement;
       
   965   };
       
   966 
       
   967   class LabelNode : public StatementNode {
       
   968   public:
       
   969     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { }
       
   970     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   971     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   972     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   973   private:
       
   974     Identifier label;
       
   975     RefPtr<StatementNode> statement;
       
   976   };
       
   977 
       
   978   class ThrowNode : public StatementNode {
       
   979   public:
       
   980     ThrowNode(Node *e) KJS_FAST_CALL : expr(e) {}
       
   981     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   982     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   983   private:
       
   984     RefPtr<Node> expr;
       
   985   };
       
   986 
       
   987   class TryNode : public StatementNode {
       
   988   public:
       
   989     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
       
   990       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { }
       
   991     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
   992     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
   993     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
   994   private:
       
   995     RefPtr<StatementNode> tryBlock;
       
   996     Identifier exceptionIdent;
       
   997     RefPtr<StatementNode> catchBlock;
       
   998     RefPtr<StatementNode> finallyBlock;
       
   999   };
       
  1000 
       
  1001   class ParameterNode : public Node {
       
  1002   public:
       
  1003     // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
       
  1004     ParameterNode(const Identifier &i) KJS_FAST_CALL : id(i), next(this) { Parser::noteNodeCycle(this); }
       
  1005     ParameterNode(ParameterNode *next, const Identifier &i) KJS_FAST_CALL
       
  1006       : id(i), next(next->next) { next->next = this; }
       
  1007     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
  1008     Identifier ident() KJS_FAST_CALL { return id; }
       
  1009     ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
       
  1010     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1011     PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
  1012     virtual void breakCycle() KJS_FAST_CALL;
       
  1013   private:
       
  1014     friend class FuncDeclNode;
       
  1015     friend class FuncExprNode;
       
  1016     Identifier id;
       
  1017     ListRefPtr<ParameterNode> next;
       
  1018   };
       
  1019 
       
  1020   class Parameter {
       
  1021   public:
       
  1022     Parameter() KJS_FAST_CALL { }
       
  1023     Parameter(const Identifier& n) KJS_FAST_CALL : name(n) { }
       
  1024     Identifier name;
       
  1025   };
       
  1026 
       
  1027   // inherited by ProgramNode
       
  1028   class FunctionBodyNode : public BlockNode {
       
  1029   public:
       
  1030     FunctionBodyNode(SourceElementsNode *) KJS_FAST_CALL;
       
  1031     virtual void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1032     int sourceId() KJS_FAST_CALL { return m_sourceId; }
       
  1033     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
       
  1034 
       
  1035     void addParam(const Identifier& ident) KJS_FAST_CALL;
       
  1036     size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
       
  1037     Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos].name; }
       
  1038     UString paramString() const KJS_FAST_CALL;
       
  1039     Vector<Parameter>& parameters() KJS_FAST_CALL { return m_parameters; }
       
  1040   private:
       
  1041     UString m_sourceURL;
       
  1042     int m_sourceId;
       
  1043     Vector<Parameter> m_parameters;
       
  1044   };
       
  1045 
       
  1046   class FuncExprNode : public Node {
       
  1047   public:
       
  1048     FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = 0) KJS_FAST_CALL 
       
  1049       : ident(i), param(p ? p->next.release() : 0), body(b) { if (p) { Parser::removeNodeCycle(param.get()); } addParams(); }
       
  1050     virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
       
  1051     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1052   private:
       
  1053     void addParams() KJS_FAST_CALL;
       
  1054     // Used for streamTo
       
  1055     friend class PropertyNode;
       
  1056     Identifier ident;
       
  1057     RefPtr<ParameterNode> param;
       
  1058     RefPtr<FunctionBodyNode> body;
       
  1059   };
       
  1060 
       
  1061   class FuncDeclNode : public StatementNode {
       
  1062   public:
       
  1063     FuncDeclNode(const Identifier &i, FunctionBodyNode *b) KJS_FAST_CALL
       
  1064       : ident(i), body(b) { addParams(); }
       
  1065     FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b) KJS_FAST_CALL
       
  1066       : ident(i), param(p->next.release()), body(b) { Parser::removeNodeCycle(param.get()); addParams(); }
       
  1067     virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
  1068     virtual void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1069     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1070   private:
       
  1071     void addParams() KJS_FAST_CALL;
       
  1072     Identifier ident;
       
  1073     RefPtr<ParameterNode> param;
       
  1074     RefPtr<FunctionBodyNode> body;
       
  1075   };
       
  1076 
       
  1077   // A linked list of source element nodes
       
  1078   class SourceElementsNode : public StatementNode {
       
  1079   public:
       
  1080     static int count;
       
  1081     // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
       
  1082     SourceElementsNode(StatementNode*) KJS_FAST_CALL;
       
  1083     SourceElementsNode(SourceElementsNode *s1, StatementNode *s2) KJS_FAST_CALL;
       
  1084     
       
  1085     Completion execute(ExecState*) KJS_FAST_CALL;
       
  1086     void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1087     virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
  1088     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1089     PassRefPtr<SourceElementsNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
  1090     virtual void breakCycle() KJS_FAST_CALL;
       
  1091   private:
       
  1092     friend class BlockNode;
       
  1093     friend class CaseClauseNode;
       
  1094     RefPtr<StatementNode> node;
       
  1095     ListRefPtr<SourceElementsNode> next;
       
  1096   };
       
  1097 
       
  1098   class CaseClauseNode : public Node {
       
  1099   public:
       
  1100       CaseClauseNode(Node *e) KJS_FAST_CALL : expr(e) { }
       
  1101       CaseClauseNode(Node *e, SourceElementsNode *s) KJS_FAST_CALL
       
  1102       : expr(e), source(s->next.release()) { Parser::removeNodeCycle(source.get()); }
       
  1103       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
  1104       Completion evalStatements(ExecState*) KJS_FAST_CALL;
       
  1105       void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1106       virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
  1107       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1108   private:
       
  1109       RefPtr<Node> expr;
       
  1110       RefPtr<SourceElementsNode> source;
       
  1111   };
       
  1112   
       
  1113   class ClauseListNode : public Node {
       
  1114   public:
       
  1115       // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
       
  1116       ClauseListNode(CaseClauseNode *c) KJS_FAST_CALL : clause(c), next(this) { Parser::noteNodeCycle(this); }
       
  1117       ClauseListNode(ClauseListNode *n, CaseClauseNode *c) KJS_FAST_CALL
       
  1118       : clause(c), next(n->next) { n->next = this; }
       
  1119       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
  1120       CaseClauseNode *getClause() const KJS_FAST_CALL { return clause.get(); }
       
  1121       ClauseListNode *getNext() const KJS_FAST_CALL { return next.get(); }
       
  1122       virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
  1123       void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1124       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1125       PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
       
  1126       virtual void breakCycle() KJS_FAST_CALL;
       
  1127   private:
       
  1128       friend class CaseBlockNode;
       
  1129       RefPtr<CaseClauseNode> clause;
       
  1130       ListRefPtr<ClauseListNode> next;
       
  1131   };
       
  1132   
       
  1133   class CaseBlockNode : public Node {
       
  1134   public:
       
  1135       CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2) KJS_FAST_CALL;
       
  1136       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
       
  1137       Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
       
  1138       virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
  1139       void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1140       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1141   private:
       
  1142       RefPtr<ClauseListNode> list1;
       
  1143       RefPtr<CaseClauseNode> def;
       
  1144       RefPtr<ClauseListNode> list2;
       
  1145   };
       
  1146   
       
  1147   class SwitchNode : public StatementNode {
       
  1148   public:
       
  1149       SwitchNode(Node *e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { }
       
  1150       virtual Completion execute(ExecState*) KJS_FAST_CALL;
       
  1151       virtual void processVarDecls(ExecState*) KJS_FAST_CALL;
       
  1152       virtual void processFuncDecl(ExecState*) KJS_FAST_CALL;
       
  1153       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
       
  1154   private:
       
  1155       RefPtr<Node> expr;
       
  1156       RefPtr<CaseBlockNode> block;
       
  1157   };
       
  1158   
       
  1159   class ProgramNode : public FunctionBodyNode {
       
  1160   public:
       
  1161     ProgramNode(SourceElementsNode *s) KJS_FAST_CALL;
       
  1162   };
       
  1163 
       
  1164 } // namespace
       
  1165 
       
  1166 #endif