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