Reviewed by Darin.
[WebKit-https.git] / JavaScriptCore / kjs / nodes.h
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