Separating all of the simple binary expression nodes into multiple classes
[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) KJS_FAST_CALL : term1(t1), term2(t2) {}
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   };
659   
660   class DivNode : public Node {
661   public:
662       DivNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
663       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
664       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
665   private:
666       RefPtr<Node> term1;
667       RefPtr<Node> term2;
668   };
669   
670   class ModNode : public Node {
671   public:
672       ModNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
673       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
674       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
675   private:
676       RefPtr<Node> term1;
677       RefPtr<Node> term2;
678   };
679
680   class AddNode : public Node {
681   public:
682     AddNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
683     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
684     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
685   private:
686     RefPtr<Node> term1;
687     RefPtr<Node> term2;
688   };
689   
690   class SubNode : public Node {
691   public:
692       SubNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
693       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
694       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
695   private:
696       RefPtr<Node> term1;
697       RefPtr<Node> term2;
698   };
699
700   class LeftShiftNode : public Node {
701   public:
702     LeftShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
703       : term1(t1), term2(t2) {}
704     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
705     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
706   private:
707     RefPtr<Node> term1;
708     RefPtr<Node> term2;
709   };
710
711   class RightShiftNode : public Node {
712   public:
713     RightShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
714       : term1(t1), term2(t2) {}
715     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
716     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
717   private:
718     RefPtr<Node> term1;
719     RefPtr<Node> term2;
720   };
721
722   class UnsignedRightShiftNode : public Node {
723   public:
724     UnsignedRightShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
725       : term1(t1), term2(t2) {}
726     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
727     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
728   private:
729     RefPtr<Node> term1;
730     RefPtr<Node> term2;
731   };
732
733   class LessNode : public Node {
734   public:
735     LessNode(Node *e1, Node *e2) KJS_FAST_CALL :
736       expr1(e1), expr2(e2) {}
737     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
738     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
739   private:
740     RefPtr<Node> expr1;
741     RefPtr<Node> expr2;
742   };
743
744   class GreaterNode : public Node {
745   public:
746     GreaterNode(Node *e1, Node *e2) KJS_FAST_CALL :
747       expr1(e1), expr2(e2) {}
748     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
749     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
750   private:
751     RefPtr<Node> expr1;
752     RefPtr<Node> expr2;
753   };
754
755   class LessEqNode : public Node {
756   public:
757     LessEqNode(Node *e1, Node *e2) KJS_FAST_CALL :
758       expr1(e1), expr2(e2) {}
759     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
760     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
761   private:
762     RefPtr<Node> expr1;
763     RefPtr<Node> expr2;
764   };
765
766   class GreaterEqNode : public Node {
767   public:
768     GreaterEqNode(Node *e1, Node *e2) KJS_FAST_CALL :
769       expr1(e1), expr2(e2) {}
770     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
771     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
772   private:
773     RefPtr<Node> expr1;
774     RefPtr<Node> expr2;
775   };
776
777   class InstanceOfNode : public Node {
778   public:
779     InstanceOfNode(Node *e1, Node *e2) KJS_FAST_CALL :
780       expr1(e1), expr2(e2) {}
781     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
782     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
783   private:
784     RefPtr<Node> expr1;
785     RefPtr<Node> expr2;
786   };
787
788   class InNode : public Node {
789   public:
790     InNode(Node *e1, Node *e2) KJS_FAST_CALL :
791       expr1(e1), expr2(e2) {}
792     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
793     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
794   private:
795     RefPtr<Node> expr1;
796     RefPtr<Node> expr2;
797   };
798
799   class EqualNode : public Node {
800   public:
801     EqualNode(Node *e1, Node *e2) KJS_FAST_CALL
802       : 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 NotEqualNode : public Node {
811   public:
812     NotEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
813       : expr1(e1), expr2(e2) {}
814     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
815     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
816   private:
817     RefPtr<Node> expr1;
818     RefPtr<Node> expr2;
819   };
820
821   class StrictEqualNode : public Node {
822   public:
823     StrictEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
824       : expr1(e1), expr2(e2) {}
825     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
826     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
827   private:
828     RefPtr<Node> expr1;
829     RefPtr<Node> expr2;
830   };
831
832   class NotStrictEqualNode : public Node {
833   public:
834     NotStrictEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
835       : expr1(e1), expr2(e2) {}
836     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
837     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
838   private:
839     RefPtr<Node> expr1;
840     RefPtr<Node> expr2;
841   };
842
843   class BitAndNode : public Node {
844   public:
845     BitAndNode(Node *e1, Node *e2) KJS_FAST_CALL :
846       expr1(e1), expr2(e2) {}
847     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
848     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
849   private:
850     RefPtr<Node> expr1;
851     RefPtr<Node> expr2;
852   };
853
854   class BitOrNode : public Node {
855   public:
856     BitOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
857       expr1(e1), expr2(e2) {}
858     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
859     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
860   private:
861     RefPtr<Node> expr1;
862     RefPtr<Node> expr2;
863   };
864
865   class BitXOrNode : public Node {
866   public:
867     BitXOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
868       expr1(e1), expr2(e2) {}
869     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
870     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
871   private:
872     RefPtr<Node> expr1;
873     RefPtr<Node> expr2;
874   };
875
876   /**
877    * expr1 && expr2, expr1 || expr2
878    */
879   class LogicalAndNode : public Node {
880   public:
881     LogicalAndNode(Node *e1, Node *e2) KJS_FAST_CALL :
882       expr1(e1), expr2(e2) {}
883     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
884     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
885   private:
886     RefPtr<Node> expr1;
887     RefPtr<Node> expr2;
888   };
889   
890   class LogicalOrNode : public Node {
891   public:
892     LogicalOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
893       expr1(e1), expr2(e2) {}
894     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
895     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
896   private:
897     RefPtr<Node> expr1;
898     RefPtr<Node> expr2;
899   };
900
901   /**
902    * The ternary operator, "logical ? expr1 : expr2"
903    */
904   class ConditionalNode : public Node {
905   public:
906     ConditionalNode(Node *l, Node *e1, Node *e2) KJS_FAST_CALL :
907       logical(l), expr1(e1), expr2(e2) {}
908     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
909     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
910   private:
911     RefPtr<Node> logical;
912     RefPtr<Node> expr1;
913     RefPtr<Node> expr2;
914   };
915
916   class AssignResolveNode : public Node {
917   public:
918     AssignResolveNode(const Identifier &ident, Operator oper, Node *right) KJS_FAST_CALL
919       : m_ident(ident), m_oper(oper), m_right(right) {}
920     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
921     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
922   protected:
923     Identifier m_ident;
924     Operator m_oper;
925     RefPtr<Node> m_right;
926   };
927
928   class AssignBracketNode : public Node {
929   public:
930     AssignBracketNode(Node *base, Node *subscript, Operator oper, Node *right) KJS_FAST_CALL
931       : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
932     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
933     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
934   protected:
935     RefPtr<Node> m_base;
936     RefPtr<Node> m_subscript;
937     Operator m_oper;
938     RefPtr<Node> m_right;
939   };
940
941   class AssignDotNode : public Node {
942   public:
943     AssignDotNode(Node *base, const Identifier& ident, Operator oper, Node *right) KJS_FAST_CALL
944       : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
945     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
946     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
947   protected:
948     RefPtr<Node> m_base;
949     Identifier m_ident;
950     Operator m_oper;
951     RefPtr<Node> m_right;
952   };
953
954   class AssignErrorNode : public Node {
955   public:
956     AssignErrorNode(Node* left, Operator oper, Node* right) KJS_FAST_CALL
957       : m_left(left), m_oper(oper), m_right(right) {}
958     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
959     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
960   protected:
961     RefPtr<Node> m_left;
962     Operator m_oper;
963     RefPtr<Node> m_right;
964   };
965
966   class CommaNode : public Node {
967   public:
968     CommaNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
969     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
970     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
971   private:
972     RefPtr<Node> expr1;
973     RefPtr<Node> expr2;
974   };
975
976   class AssignExprNode : public Node {
977   public:
978     AssignExprNode(Node *e) KJS_FAST_CALL : expr(e) {}
979     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
980     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
981   private:
982     RefPtr<Node> expr;
983   };
984
985   class VarDeclNode: public Node {
986   public:
987     enum Type { Variable, Constant };
988     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) KJS_FAST_CALL;
989     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
990     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
991     ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL;
992     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
993   private:
994     JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
995     Type varType;
996     Identifier ident;
997     RefPtr<AssignExprNode> init;
998   };
999
1000   class VarDeclListNode : public Node {
1001   public:
1002     // list pointer is tail of a circular list, cracked in the ForNode/VarStatementNode ctor
1003     VarDeclListNode(VarDeclNode *v) KJS_FAST_CALL : next(this), var(v) { Parser::noteNodeCycle(this); m_mayHaveDeclarations = true; }
1004     VarDeclListNode(VarDeclListNode *l, VarDeclNode *v) KJS_FAST_CALL
1005       : next(l->next), var(v) { l->next = this; m_mayHaveDeclarations = true; }
1006     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1007     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1008     PassRefPtr<VarDeclListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1009     virtual void breakCycle() KJS_FAST_CALL;
1010     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1011   private:
1012     friend class ForNode;
1013     friend class VarStatementNode;
1014     ListRefPtr<VarDeclListNode> next;
1015     RefPtr<VarDeclNode> var;
1016   };
1017
1018   class VarStatementNode : public StatementNode {
1019   public:
1020     VarStatementNode(VarDeclListNode *l) KJS_FAST_CALL : next(l->next.release()) { Parser::removeNodeCycle(next.get()); m_mayHaveDeclarations = true; }
1021     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1022     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1023     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1024   private:
1025     RefPtr<VarDeclListNode> next;
1026   };
1027
1028   class BlockNode : public StatementNode {
1029   public:
1030     BlockNode(SourceElementsNode *s) KJS_FAST_CALL;
1031     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1032     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1033     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1034   protected:
1035     RefPtr<SourceElementsNode> source;
1036   };
1037
1038   class EmptyStatementNode : public StatementNode {
1039   public:
1040     EmptyStatementNode() KJS_FAST_CALL { } // debug
1041     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1042     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1043   };
1044
1045   class ExprStatementNode : public StatementNode {
1046   public:
1047     ExprStatementNode(Node *e) KJS_FAST_CALL : expr(e) { }
1048     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1049     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1050   private:
1051     RefPtr<Node> expr;
1052   };
1053
1054   class IfNode : public StatementNode {
1055   public:
1056     IfNode(Node *e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
1057       : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
1058     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1059     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1060     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1061   private:
1062     RefPtr<Node> expr;
1063     RefPtr<StatementNode> statement1;
1064     RefPtr<StatementNode> statement2;
1065   };
1066
1067   class DoWhileNode : public StatementNode {
1068   public:
1069     DoWhileNode(StatementNode *s, Node *e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
1070     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1071     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1072     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1073   private:
1074     RefPtr<StatementNode> statement;
1075     RefPtr<Node> expr;
1076   };
1077
1078   class WhileNode : public StatementNode {
1079   public:
1080     WhileNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1081     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1082     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1083     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1084   private:
1085     RefPtr<Node> expr;
1086     RefPtr<StatementNode> statement;
1087   };
1088
1089   class ForNode : public StatementNode {
1090   public:
1091     ForNode(Node *e1, Node *e2, Node *e3, StatementNode *s) KJS_FAST_CALL :
1092       expr1(e1), expr2(e2), expr3(e3), statement(s) { m_mayHaveDeclarations = true; }
1093     ForNode(VarDeclListNode *e1, Node *e2, Node *e3, StatementNode *s) KJS_FAST_CALL :
1094       expr1(e1->next.release()), expr2(e2), expr3(e3), statement(s) { Parser::removeNodeCycle(expr1.get()); 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   private:
1099     RefPtr<Node> expr1;
1100     RefPtr<Node> expr2;
1101     RefPtr<Node> expr3;
1102     RefPtr<StatementNode> statement;
1103   };
1104
1105   class ForInNode : public StatementNode {
1106   public:
1107     ForInNode(Node *l, Node *e, StatementNode *s) KJS_FAST_CALL;
1108     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s) KJS_FAST_CALL;
1109     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1110     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1111     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1112   private:
1113     Identifier ident;
1114     RefPtr<AssignExprNode> init;
1115     RefPtr<Node> lexpr;
1116     RefPtr<Node> expr;
1117     RefPtr<VarDeclNode> varDecl;
1118     RefPtr<StatementNode> statement;
1119   };
1120
1121   class ContinueNode : public StatementNode {
1122   public:
1123     ContinueNode() KJS_FAST_CALL { }
1124     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1125     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1126     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1127   private:
1128     Identifier ident;
1129   };
1130
1131   class BreakNode : public StatementNode {
1132   public:
1133     BreakNode() KJS_FAST_CALL { }
1134     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1135     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1136     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1137   private:
1138     Identifier ident;
1139   };
1140
1141   class ReturnNode : public StatementNode {
1142   public:
1143     ReturnNode(Node *v) KJS_FAST_CALL : value(v) {}
1144     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1145     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1146   private:
1147     RefPtr<Node> value;
1148   };
1149
1150   class WithNode : public StatementNode {
1151   public:
1152     WithNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1153     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1154     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1155     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1156   private:
1157     RefPtr<Node> expr;
1158     RefPtr<StatementNode> statement;
1159   };
1160
1161   class LabelNode : public StatementNode {
1162   public:
1163     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
1164     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1165     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1166     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1167   private:
1168     Identifier label;
1169     RefPtr<StatementNode> statement;
1170   };
1171
1172   class ThrowNode : public StatementNode {
1173   public:
1174     ThrowNode(Node *e) KJS_FAST_CALL : expr(e) {}
1175     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1176     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1177   private:
1178     RefPtr<Node> expr;
1179   };
1180
1181   class TryNode : public StatementNode {
1182   public:
1183     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1184       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
1185     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1186     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1187     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1188   private:
1189     RefPtr<StatementNode> tryBlock;
1190     Identifier exceptionIdent;
1191     RefPtr<StatementNode> catchBlock;
1192     RefPtr<StatementNode> finallyBlock;
1193   };
1194
1195   class ParameterNode : public Node {
1196   public:
1197     // list pointer is tail of a circular list, cracked in the FuncDeclNode/FuncExprNode ctor
1198     ParameterNode(const Identifier &i) KJS_FAST_CALL : id(i), next(this) { Parser::noteNodeCycle(this); }
1199     ParameterNode(ParameterNode *next, const Identifier &i) KJS_FAST_CALL
1200       : id(i), next(next->next) { next->next = this; }
1201     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1202     Identifier ident() KJS_FAST_CALL { return id; }
1203     ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1204     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1205     PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1206     virtual void breakCycle() KJS_FAST_CALL;
1207   private:
1208     friend class FuncDeclNode;
1209     friend class FuncExprNode;
1210     Identifier id;
1211     ListRefPtr<ParameterNode> next;
1212   };
1213
1214   // inherited by ProgramNode
1215   class FunctionBodyNode : public BlockNode {
1216   public:
1217     FunctionBodyNode(SourceElementsNode *) KJS_FAST_CALL;
1218     int sourceId() KJS_FAST_CALL { return m_sourceId; }
1219     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
1220
1221     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1222
1223     void addParam(const Identifier& ident) KJS_FAST_CALL;
1224     size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
1225     Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos]; }
1226     UString paramString() const KJS_FAST_CALL;
1227     Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1228     ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
1229   private:
1230     UString m_sourceURL;
1231     int m_sourceId;
1232     Vector<Identifier> m_parameters;
1233
1234     void initializeDeclarationStacks();
1235     bool m_initializedDeclarationStacks;
1236     DeclarationStacks::VarStack m_varStack;
1237     DeclarationStacks::FunctionStack m_functionStack;
1238   };
1239
1240   class FuncExprNode : public Node {
1241   public:
1242     FuncExprNode(const Identifier &i, FunctionBodyNode *b, ParameterNode *p = 0) KJS_FAST_CALL 
1243       : ident(i), param(p ? p->next.release() : 0), body(b) { if (p) { Parser::removeNodeCycle(param.get()); } addParams(); }
1244     virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
1245     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1246   private:
1247     void addParams() KJS_FAST_CALL;
1248     // Used for streamTo
1249     friend class PropertyNode;
1250     Identifier ident;
1251     RefPtr<ParameterNode> param;
1252     RefPtr<FunctionBodyNode> body;
1253   };
1254
1255   class FuncDeclNode : public StatementNode {
1256   public:
1257     FuncDeclNode(const Identifier &i, FunctionBodyNode *b) KJS_FAST_CALL
1258       : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
1259     FuncDeclNode(const Identifier &i, ParameterNode *p, FunctionBodyNode *b) KJS_FAST_CALL
1260       : ident(i), param(p->next.release()), body(b) { Parser::removeNodeCycle(param.get()); addParams(); m_mayHaveDeclarations = true; }
1261     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1262     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1263     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1264     ALWAYS_INLINE void processDeclaration(ExecState*) KJS_FAST_CALL;
1265   private:
1266     void addParams() KJS_FAST_CALL;
1267     Identifier ident;
1268     RefPtr<ParameterNode> param;
1269     RefPtr<FunctionBodyNode> body;
1270   };
1271
1272   // A linked list of source element nodes
1273   class SourceElementsNode : public StatementNode {
1274   public:
1275     static int count;
1276     // list pointer is tail of a circular list, cracked in the BlockNode (or subclass) ctor
1277     SourceElementsNode(StatementNode*) KJS_FAST_CALL;
1278     SourceElementsNode(SourceElementsNode *s1, StatementNode *s2) KJS_FAST_CALL;
1279     
1280     Completion execute(ExecState*) KJS_FAST_CALL;
1281     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1282     PassRefPtr<SourceElementsNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1283     virtual void breakCycle() KJS_FAST_CALL;
1284     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1285   private:
1286     friend class BlockNode;
1287     friend class CaseClauseNode;
1288     RefPtr<StatementNode> node;
1289     ListRefPtr<SourceElementsNode> next;
1290   };
1291
1292   class CaseClauseNode : public Node {
1293   public:
1294       CaseClauseNode(Node *e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
1295       CaseClauseNode(Node *e, SourceElementsNode *s) KJS_FAST_CALL
1296       : expr(e), source(s->next.release()) { Parser::removeNodeCycle(source.get()); m_mayHaveDeclarations = true; }
1297       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1298       Completion evalStatements(ExecState*) KJS_FAST_CALL;
1299       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1300       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1301   private:
1302       RefPtr<Node> expr;
1303       RefPtr<SourceElementsNode> source;
1304   };
1305   
1306   class ClauseListNode : public Node {
1307   public:
1308       // list pointer is tail of a circular list, cracked in the CaseBlockNode ctor
1309       ClauseListNode(CaseClauseNode *c) KJS_FAST_CALL : clause(c), next(this) { Parser::noteNodeCycle(this); m_mayHaveDeclarations = true; }
1310       ClauseListNode(ClauseListNode *n, CaseClauseNode *c) KJS_FAST_CALL
1311       : clause(c), next(n->next) { n->next = this; m_mayHaveDeclarations = true; }
1312       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1313       CaseClauseNode *getClause() const KJS_FAST_CALL { return clause.get(); }
1314       ClauseListNode *getNext() const KJS_FAST_CALL { return next.get(); }
1315       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1316       PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1317       virtual void breakCycle() KJS_FAST_CALL;
1318       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1319   private:
1320       friend class CaseBlockNode;
1321       RefPtr<CaseClauseNode> clause;
1322       ListRefPtr<ClauseListNode> next;
1323   };
1324   
1325   class CaseBlockNode : public Node {
1326   public:
1327       CaseBlockNode(ClauseListNode *l1, CaseClauseNode *d, ClauseListNode *l2) KJS_FAST_CALL;
1328       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1329       Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
1330       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1331       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1332   private:
1333       RefPtr<ClauseListNode> list1;
1334       RefPtr<CaseClauseNode> def;
1335       RefPtr<ClauseListNode> list2;
1336   };
1337   
1338   class SwitchNode : public StatementNode {
1339   public:
1340       SwitchNode(Node *e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
1341       virtual Completion execute(ExecState*) KJS_FAST_CALL;
1342       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1343       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1344   private:
1345       RefPtr<Node> expr;
1346       RefPtr<CaseBlockNode> block;
1347   };
1348   
1349   class ProgramNode : public FunctionBodyNode {
1350   public:
1351     ProgramNode(SourceElementsNode *s) KJS_FAST_CALL;
1352   };
1353
1354 } // namespace
1355
1356 #endif