2007-11-10 Eric Seidel <eric@webkit.org>
[WebKit-https.git] / JavaScriptCore / kjs / nodes.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
5  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6  *  Copyright (C) 2007 Maks Orlovich
7  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Library General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Library General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Library General Public License
20  *  along with this library; see the file COPYING.LIB.  If not, write to
21  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301, USA.
23  *
24  */
25
26 #ifndef NODES_H_
27 #define NODES_H_
28
29 #include "Parser.h"
30 #include "internal.h"
31 #include "SymbolTable.h"
32 #include <wtf/ListRefPtr.h>
33 #include <wtf/OwnPtr.h>
34 #include <wtf/Vector.h>
35
36 #if PLATFORM(X86) && COMPILER(GCC)
37 #define KJS_FAST_CALL __attribute__((regparm(3)))
38 #else
39 #define KJS_FAST_CALL
40 #endif
41
42 #if COMPILER(GCC)
43 #define KJS_NO_INLINE __attribute__((noinline))
44 #else
45 #define KJS_NO_INLINE
46 #endif
47
48 namespace KJS {
49
50     class FuncDeclNode;
51     class PropertyListNode;
52     class SourceStream;
53     class VarDeclNode;
54
55     enum Operator {
56         OpEqual,
57         OpPlusEq,
58         OpMinusEq,
59         OpMultEq,
60         OpDivEq,
61         OpPlusPlus,
62         OpMinusMinus,
63         OpAndEq,
64         OpXOrEq,
65         OpOrEq,
66         OpModEq,
67         OpLShift,
68         OpRShift,
69         OpURShift,
70     };
71
72     enum Precedence {
73         PrecPrimary,
74         PrecMember,
75         PrecCall,
76         PrecLeftHandSide,
77         PrecPostfix,
78         PrecUnary,
79         PrecMultiplicitave,
80         PrecAdditive,
81         PrecShift,
82         PrecRelational,
83         PrecEquality,
84         PrecBitwiseAnd,
85         PrecBitwiseXor,
86         PrecBitwiseOr,
87         PrecLogicalAnd,
88         PrecLogicalOr,
89         PrecConditional,
90         PrecAssignment,
91         PrecExpression
92     };
93   
94   struct DeclarationStacks {
95       typedef Vector<Node*, 16> NodeStack;
96       typedef Vector<VarDeclNode*, 16> VarStack;
97       typedef Vector<FuncDeclNode*, 16> FunctionStack;
98       
99       DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
100         : exec(e)
101         , nodeStack(n)
102         , varStack(v)
103         , functionStack(f)
104       {
105       }
106
107       ExecState* exec;
108       NodeStack& nodeStack;
109       VarStack& varStack; 
110       FunctionStack& functionStack;
111   };
112
113   class Node : Noncopyable {
114   public:
115     Node() KJS_FAST_CALL;
116     Node(PlacementNewAdoptType) KJS_FAST_CALL { }
117     virtual ~Node();
118
119     UString toString() const KJS_FAST_CALL;
120     int lineNo() const KJS_FAST_CALL { return m_line; }
121     void ref() KJS_FAST_CALL;
122     void deref() KJS_FAST_CALL;
123     unsigned refcount() KJS_FAST_CALL;
124     static void clearNewNodes() KJS_FAST_CALL;
125
126     // Serialization.
127     virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
128     virtual Precedence precedence() const = 0;
129
130     // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
131     bool mayHaveDeclarations() const { return m_mayHaveDeclarations; }
132     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
133     
134     // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
135     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
136
137   protected:
138     Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
139     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
140     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
141
142     JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
143     JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
144     JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
145     JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
146     JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
147     JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
148     JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
149
150     JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
151
152     void handleException(ExecState*) KJS_FAST_CALL;
153     void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
154
155     Completion rethrowException(ExecState*) KJS_FAST_CALL;
156
157     int m_line : 28;
158     bool m_mayHaveDeclarations : 1;
159     unsigned m_expectedReturnType : 3; // JSType
160   };
161     
162     class ExpressionNode : public Node {
163     public:
164         ExpressionNode() KJS_FAST_CALL : Node() {}
165         ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
166             : Node(expectedReturn) {}
167         
168         // Special constructor for cases where we overwrite an object in place.
169         ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
170             : Node(PlacementNewAdopt) {}
171         
172         virtual bool isNumber() const KJS_FAST_CALL { return false; }
173         virtual bool isLocation() const KJS_FAST_CALL { return false; }
174         virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
175         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
176         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
177         
178         JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
179         
180         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
181         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
182         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
183
184         // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
185         virtual void optimizeForUnnecessaryResult() { }
186    };
187
188   class StatementNode : public Node {
189   public:
190     StatementNode() KJS_FAST_CALL;
191     void setLoc(int line0, int line1) KJS_FAST_CALL;
192     int firstLine() const KJS_FAST_CALL { return lineNo(); }
193     int lastLine() const KJS_FAST_CALL { return m_lastLine; }
194     bool hitStatement(ExecState*) KJS_FAST_CALL;
195     virtual Completion execute(ExecState *exec) KJS_FAST_CALL = 0;
196     void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
197     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
198   protected:
199     LabelStack ls;
200   private:
201     int m_lastLine;
202   };
203
204   class NullNode : public ExpressionNode {
205   public:
206     NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
207     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
208     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
209     virtual Precedence precedence() const { return PrecPrimary; }
210   };
211
212   class FalseNode : public ExpressionNode {
213   public:
214     FalseNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
215     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
216     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
217     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
218     virtual Precedence precedence() const { return PrecPrimary; }
219   };
220
221   class TrueNode : public ExpressionNode {
222   public:
223     TrueNode() KJS_FAST_CALL : ExpressionNode(BooleanType) {}
224     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
225     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
226     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
227     virtual Precedence precedence() const { return PrecPrimary; }
228   };
229
230   class NumberNode : public ExpressionNode {
231   public:
232     NumberNode(double v) KJS_FAST_CALL : ExpressionNode(NumberType), m_double(v) {}
233     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
234     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
235     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
236     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
237     virtual Precedence precedence() const { return PrecPrimary; }
238
239     virtual bool isNumber() const KJS_FAST_CALL { return true; }
240     double value() const KJS_FAST_CALL { return m_double; }
241     virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
242
243   protected:
244     double m_double;
245   };
246   
247   class ImmediateNumberNode : public NumberNode {
248   public:
249       ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL : NumberNode(d), m_value(v) { ASSERT(v == JSImmediate::from(d)); }
250       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
251       
252       virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
253   private:
254       JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
255   };
256
257   class StringNode : public ExpressionNode {
258   public:
259     StringNode(const UString* v) KJS_FAST_CALL : ExpressionNode(StringType), m_value(*v) {}
260     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
261     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
262     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
263     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
264     virtual Precedence precedence() const { return PrecPrimary; }
265
266   private:
267     UString m_value;
268   };
269
270   class RegExpNode : public ExpressionNode {
271   public:
272     RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL 
273       : m_pattern(pattern), m_flags(flags) { }
274     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
275     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
276     virtual Precedence precedence() const { return PrecPrimary; }
277   private:
278     UString m_pattern;
279     UString m_flags;
280   };
281
282   class ThisNode : public ExpressionNode {
283   public:
284     ThisNode() KJS_FAST_CALL {}
285     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
286     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
287     virtual Precedence precedence() const { return PrecPrimary; }
288  };
289
290   class ResolveNode : public ExpressionNode {
291   public:
292     ResolveNode(const Identifier &s) KJS_FAST_CALL 
293         : ident(s) 
294     { 
295     }
296
297     // Special constructor for cases where we overwrite an object in place.
298     ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
299         : ExpressionNode(PlacementNewAdopt)
300         , ident(PlacementNewAdopt)
301     {
302     }
303
304     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
305
306     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
307     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
308     virtual Precedence precedence() const { return PrecPrimary; }
309
310     virtual bool isLocation() const KJS_FAST_CALL { return true; }
311     virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
312     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
313
314   protected:
315     Identifier ident;
316     size_t index; // Used by LocalVarAccessNode.
317   };
318
319   class LocalVarAccessNode : public ResolveNode {
320   public:
321     // Overwrites a ResolveNode in place.
322     LocalVarAccessNode(size_t i) KJS_FAST_CALL
323         : ResolveNode(PlacementNewAdopt)
324     {
325         ASSERT(i != missingSymbolMarker());
326         index = i;
327     }
328     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
329     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
330     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
331   private:
332     ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
333   };
334
335   class ElementNode : public Node {
336   public:
337     ElementNode(int e, ExpressionNode* n) KJS_FAST_CALL : elision(e), node(n) { }
338     ElementNode(ElementNode* l, int e, ExpressionNode* n) KJS_FAST_CALL
339       : elision(e), node(n) { l->next = this; }
340     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
341     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
342     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
343
344     PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
345
346     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
347
348   private:
349     friend class ArrayNode;
350     ListRefPtr<ElementNode> next;
351     int elision;
352     RefPtr<ExpressionNode> node;
353   };
354
355   class ArrayNode : public ExpressionNode {
356   public:
357     ArrayNode(int e) KJS_FAST_CALL : elision(e), opt(true) { }
358     ArrayNode(ElementNode* ele) KJS_FAST_CALL
359       : element(ele), elision(0), opt(false) { }
360     ArrayNode(int eli, ElementNode* ele) KJS_FAST_CALL
361       : element(ele), elision(eli), opt(true) { }
362     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
363     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
364     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
365     virtual Precedence precedence() const { return PrecPrimary; }
366   private:
367     RefPtr<ElementNode> element;
368     int elision;
369     bool opt;
370   };
371
372   class PropertyNode : public Node {
373   public:
374     enum Type { Constant, Getter, Setter };
375     PropertyNode(const Identifier& n, ExpressionNode* a, Type t) KJS_FAST_CALL
376       : m_name(n), assign(a), type(t) { }
377     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
378     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
379     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
380
381     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
382     const Identifier& name() const { return m_name; }
383
384   private:
385     friend class PropertyListNode;
386     Identifier m_name;
387     RefPtr<ExpressionNode> assign;
388     Type type;
389   };
390   
391   class PropertyListNode : public Node {
392   public:
393     PropertyListNode(PropertyNode* n) KJS_FAST_CALL
394       : node(n) { }
395     PropertyListNode(PropertyNode* n, PropertyListNode* l) KJS_FAST_CALL
396       : node(n) { l->next = this; }
397     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
398     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
399     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
400
401     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
402     PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
403
404   private:
405     friend class ObjectLiteralNode;
406     RefPtr<PropertyNode> node;
407     ListRefPtr<PropertyListNode> next;
408   };
409
410   class ObjectLiteralNode : public ExpressionNode {
411   public:
412     ObjectLiteralNode() KJS_FAST_CALL { }
413     ObjectLiteralNode(PropertyListNode* l) KJS_FAST_CALL : list(l) { }
414     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
415     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
416     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
417     virtual Precedence precedence() const { return PrecPrimary; }
418   private:
419     RefPtr<PropertyListNode> list;
420   };
421
422   class BracketAccessorNode : public ExpressionNode {
423   public:
424     BracketAccessorNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
425     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
426     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
427     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
428     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
429     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
430     virtual Precedence precedence() const { return PrecMember; }
431
432     virtual bool isLocation() const KJS_FAST_CALL { return true; }
433     virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
434     ExpressionNode* base() KJS_FAST_CALL { return expr1.get(); }
435     ExpressionNode* subscript() KJS_FAST_CALL { return expr2.get(); }
436
437   private:
438     ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
439     RefPtr<ExpressionNode> expr1;
440     RefPtr<ExpressionNode> expr2;
441   };
442
443   class DotAccessorNode : public ExpressionNode {
444   public:
445     DotAccessorNode(ExpressionNode* e, const Identifier& s) KJS_FAST_CALL : expr(e), ident(s) { }
446     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
447     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
448     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
449     virtual Precedence precedence() const { return PrecMember; }
450
451     virtual bool isLocation() const KJS_FAST_CALL { return true; }
452     virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
453     ExpressionNode* base() const KJS_FAST_CALL { return expr.get(); }
454     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
455
456   private:
457     RefPtr<ExpressionNode> expr;
458     Identifier ident;
459   };
460
461   class ArgumentListNode : public Node {
462   public:
463     ArgumentListNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
464     ArgumentListNode(ArgumentListNode* l, ExpressionNode* e) KJS_FAST_CALL 
465       : expr(e) { l->next = this; }
466     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
467     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
468     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
469
470     void evaluateList(ExecState*, List&) KJS_FAST_CALL;
471     PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
472
473   private:
474     friend class ArgumentsNode;
475     ListRefPtr<ArgumentListNode> next;
476     RefPtr<ExpressionNode> expr;
477   };
478
479   class ArgumentsNode : public Node {
480   public:
481     ArgumentsNode() KJS_FAST_CALL { }
482     ArgumentsNode(ArgumentListNode* l) KJS_FAST_CALL
483       : listNode(l) { }
484     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
485     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
486     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
487
488     void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (listNode) listNode->evaluateList(exec, list); }
489
490   private:
491     RefPtr<ArgumentListNode> listNode;
492   };
493
494   class NewExprNode : public ExpressionNode {
495   public:
496     NewExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
497     NewExprNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
498     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
499     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
500     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
501     virtual Precedence precedence() const { return PrecLeftHandSide; }
502   private:
503     RefPtr<ExpressionNode> expr;
504     RefPtr<ArgumentsNode> args;
505   };
506
507   class FunctionCallValueNode : public ExpressionNode {
508   public:
509     FunctionCallValueNode(ExpressionNode* e, ArgumentsNode* a) KJS_FAST_CALL : expr(e), args(a) {}
510     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
511     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
512     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
513     virtual Precedence precedence() const { return PrecCall; }
514   private:
515     RefPtr<ExpressionNode> expr;
516     RefPtr<ArgumentsNode> args;
517   };
518
519   class FunctionCallResolveNode : public ExpressionNode {
520   public:
521     FunctionCallResolveNode(const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL
522         : ident(i)
523         , args(a)
524     {
525     }
526
527     FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
528         : ExpressionNode(PlacementNewAdopt)
529         , ident(PlacementNewAdopt)
530         , args(PlacementNewAdopt)
531     {
532     }
533
534     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
535     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
536     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
537     virtual Precedence precedence() const { return PrecCall; }
538
539   protected:
540     Identifier ident;
541     RefPtr<ArgumentsNode> args;
542     size_t index; // Used by LocalVarFunctionCallNode.
543   };
544
545   class LocalVarFunctionCallNode : public FunctionCallResolveNode {
546   public:
547     LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
548         : FunctionCallResolveNode(PlacementNewAdopt)
549     {
550         ASSERT(i != missingSymbolMarker());
551         index = i;
552     }
553
554     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
555   };
556
557   class FunctionCallBracketNode : public ExpressionNode {
558   public:
559     FunctionCallBracketNode(ExpressionNode* b, ExpressionNode* s, ArgumentsNode* a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
560     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
561     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
562     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
563     virtual Precedence precedence() const { return PrecCall; }
564   protected:
565     RefPtr<ExpressionNode> base;
566     RefPtr<ExpressionNode> subscript;
567     RefPtr<ArgumentsNode> args;
568   };
569
570   class FunctionCallDotNode : public ExpressionNode {
571   public:
572     FunctionCallDotNode(ExpressionNode* b, const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
573     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
574     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
575     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
576     virtual Precedence precedence() const { return PrecCall; }
577   protected:
578     RefPtr<ExpressionNode> base;
579     Identifier ident;
580     RefPtr<ArgumentsNode> args;
581   };
582
583   class PrePostResolveNode : public ExpressionNode {
584   public:
585     PrePostResolveNode(const Identifier& i) KJS_FAST_CALL : ExpressionNode(NumberType), m_ident(i) {}
586       
587     PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
588         : ExpressionNode(PlacementNewAdopt)
589         , m_ident(PlacementNewAdopt)
590     {
591     }
592       
593   protected:
594       Identifier m_ident;
595       size_t m_index; // Used by LocalVarPostfixNode.      
596   };
597     
598   class PostIncResolveNode : public PrePostResolveNode {
599   public:
600     PostIncResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
601
602     PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
603         : PrePostResolveNode(PlacementNewAdopt)
604     {
605     }
606
607     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
608     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
609     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
610     virtual Precedence precedence() const { return PrecPostfix; }
611     virtual void optimizeForUnnecessaryResult();
612
613   };
614
615   class PostIncLocalVarNode : public PostIncResolveNode {
616   public:
617     PostIncLocalVarNode(size_t i) KJS_FAST_CALL
618         : PostIncResolveNode(PlacementNewAdopt)
619     {
620         ASSERT(i != missingSymbolMarker());
621         m_index = i;
622     }
623
624     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
625     virtual void optimizeForUnnecessaryResult();
626   };
627
628   class PostDecResolveNode : public PrePostResolveNode {
629   public:
630     PostDecResolveNode(const Identifier& i) KJS_FAST_CALL : PrePostResolveNode(i) {}
631
632     PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
633         : PrePostResolveNode(PlacementNewAdopt)
634     {
635     }
636
637     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
638     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
639     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
640     virtual Precedence precedence() const { return PrecPostfix; }
641     virtual void optimizeForUnnecessaryResult();
642   };
643
644   class PostDecLocalVarNode : public PostDecResolveNode {
645   public:
646     PostDecLocalVarNode(size_t i) KJS_FAST_CALL
647         : PostDecResolveNode(PlacementNewAdopt)
648     {
649         ASSERT(i != missingSymbolMarker());
650         m_index = i;
651     }
652
653     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
654     virtual void optimizeForUnnecessaryResult();
655   };
656
657   class PostfixBracketNode : public ExpressionNode {
658   public:
659     PostfixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
660     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
661     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
662     virtual Precedence precedence() const { return PrecPostfix; }
663   protected:
664     virtual bool isIncrement() const = 0;
665     RefPtr<ExpressionNode> m_base;
666     RefPtr<ExpressionNode> m_subscript;
667   };
668
669   class PostIncBracketNode : public PostfixBracketNode {
670   public:
671     PostIncBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
672     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
673   protected:
674     virtual bool isIncrement() const { return true; }
675   };
676
677   class PostDecBracketNode : public PostfixBracketNode {
678   public:
679     PostDecBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : PostfixBracketNode(b, s) {}
680     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
681   protected:
682     virtual bool isIncrement() const { return false; }
683   };
684
685     class PostfixDotNode : public ExpressionNode {
686   public:
687     PostfixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
688     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
689     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
690     virtual Precedence precedence() const { return PrecPostfix; }
691   protected:
692     virtual bool isIncrement() const = 0;
693     RefPtr<ExpressionNode> m_base;
694     Identifier m_ident;
695   };
696
697   class PostIncDotNode : public PostfixDotNode {
698   public:
699     PostIncDotNode(ExpressionNode*  b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
700     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
701   protected:
702     virtual bool isIncrement() const { return true; }
703   };
704
705   class PostDecDotNode : public PostfixDotNode {
706   public:
707     PostDecDotNode(ExpressionNode*  b, const Identifier& i) KJS_FAST_CALL : PostfixDotNode(b, i) {}
708     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
709   protected:
710     virtual bool isIncrement() const { return false; }
711   };
712
713   class PostfixErrorNode : public ExpressionNode {
714   public:
715     PostfixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
716     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
717     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
718     virtual Precedence precedence() const { return PrecPostfix; }
719   private:
720     RefPtr<ExpressionNode> m_expr;
721     Operator m_oper;
722   };
723
724   class DeleteResolveNode : public ExpressionNode {
725   public:
726     DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
727     DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
728         : ExpressionNode(PlacementNewAdopt)
729         , m_ident(PlacementNewAdopt)
730     {
731     }
732
733     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
734     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
735     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
736     virtual Precedence precedence() const { return PrecUnary; }
737   private:
738     Identifier m_ident;
739   };
740
741   class LocalVarDeleteNode : public DeleteResolveNode {
742   public:
743     LocalVarDeleteNode() KJS_FAST_CALL
744         : DeleteResolveNode(PlacementNewAdopt)
745     {
746     }
747
748     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
749   };
750
751   class DeleteBracketNode : public ExpressionNode {
752   public:
753     DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
754     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
755     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
756     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
757     virtual Precedence precedence() const { return PrecUnary; }
758   private:
759     RefPtr<ExpressionNode> m_base;
760     RefPtr<ExpressionNode> m_subscript;
761   };
762
763   class DeleteDotNode : public ExpressionNode {
764   public:
765     DeleteDotNode(ExpressionNode* base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
766     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
767     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
768     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
769     virtual Precedence precedence() const { return PrecUnary; }
770   private:
771     RefPtr<ExpressionNode> m_base;
772     Identifier m_ident;
773   };
774
775   class DeleteValueNode : public ExpressionNode {
776   public:
777     DeleteValueNode(ExpressionNode* e) KJS_FAST_CALL : m_expr(e) {}
778     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
779     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
780     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
781     virtual Precedence precedence() const { return PrecUnary; }
782   private:
783     RefPtr<ExpressionNode> m_expr;
784   };
785
786   class VoidNode : public ExpressionNode {
787   public:
788     VoidNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
789     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
790     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
791     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
792     virtual Precedence precedence() const { return PrecUnary; }
793   private:
794     RefPtr<ExpressionNode> expr;
795   };
796
797   class TypeOfResolveNode : public ExpressionNode {
798   public:
799     TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL 
800         : ExpressionNode(StringType), m_ident(s) {}
801     
802     TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
803         : ExpressionNode(PlacementNewAdopt)
804         , m_ident(PlacementNewAdopt) 
805     {
806         m_expectedReturnType = StringType;
807     }
808
809     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
810     
811     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
812     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
813     virtual Precedence precedence() const { return PrecUnary; }
814
815     const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
816
817   protected:
818     Identifier m_ident;
819     size_t m_index; // Used by LocalTypeOfNode.
820   };
821     
822   class LocalVarTypeOfNode : public TypeOfResolveNode {
823   public:
824     LocalVarTypeOfNode(size_t i) KJS_FAST_CALL 
825         : TypeOfResolveNode(PlacementNewAdopt)
826     {
827         m_expectedReturnType = StringType;
828         ASSERT(i != missingSymbolMarker());
829         m_index = i;
830     }
831
832     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
833   };
834
835   class TypeOfValueNode : public ExpressionNode {
836   public:
837     TypeOfValueNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(StringType), m_expr(e) {}
838     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
839     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
840     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
841     virtual Precedence precedence() const { return PrecUnary; }
842   private:
843     RefPtr<ExpressionNode> m_expr;
844   };
845
846   class PreIncResolveNode : public PrePostResolveNode {
847   public:
848     PreIncResolveNode(const Identifier &s) KJS_FAST_CALL 
849         : PrePostResolveNode(s) 
850     { 
851     }
852     
853     PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
854         : PrePostResolveNode(PlacementNewAdopt)
855     {
856     }
857     
858     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
859
860     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
861     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
862     virtual Precedence precedence() const { return PrecUnary; }
863   };
864
865   class PreIncLocalVarNode : public PreIncResolveNode {
866   public:
867     PreIncLocalVarNode(size_t i) KJS_FAST_CALL 
868         : PreIncResolveNode(PlacementNewAdopt)
869     { 
870         ASSERT(i != missingSymbolMarker());
871         m_index = i;
872     }
873     
874     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
875   };
876   
877   class PreDecResolveNode : public PrePostResolveNode {
878   public:
879     PreDecResolveNode(const Identifier &s) KJS_FAST_CALL 
880         : PrePostResolveNode(s) 
881     { 
882     }
883     
884     PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
885         : PrePostResolveNode(PlacementNewAdopt)
886     {
887     }
888     
889     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
890
891     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
892     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
893     virtual Precedence precedence() const { return PrecUnary; }
894   };
895
896   class PreDecLocalVarNode : public PreDecResolveNode {
897   public:
898     PreDecLocalVarNode(size_t i) KJS_FAST_CALL 
899         : PreDecResolveNode(PlacementNewAdopt)
900     { 
901         ASSERT(i != missingSymbolMarker());
902         m_index = i;
903     }
904     
905     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
906   };
907   
908   class PrefixBracketNode : public ExpressionNode {
909   public:
910     PrefixBracketNode(ExpressionNode* b, ExpressionNode* s) KJS_FAST_CALL : m_base(b), m_subscript(s) {}
911     
912     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
913     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
914     virtual Precedence precedence() const { return PrecUnary; }
915   protected:
916     virtual bool isIncrement() const = 0;
917     RefPtr<ExpressionNode> m_base;
918     RefPtr<ExpressionNode> m_subscript;
919   };
920   
921   class PreIncBracketNode : public PrefixBracketNode {
922   public:
923     PreIncBracketNode(ExpressionNode*  b, ExpressionNode*  s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
924     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
925   protected:
926     bool isIncrement() const { return true; }
927   };
928   
929   class PreDecBracketNode : public PrefixBracketNode {
930   public:
931     PreDecBracketNode(ExpressionNode*  b, ExpressionNode*  s) KJS_FAST_CALL : PrefixBracketNode(b, s) {}
932     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
933   protected:
934     bool isIncrement() const { return false; }
935   };
936
937   class PrefixDotNode : public ExpressionNode {
938   public:
939     PrefixDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : m_base(b), m_ident(i) {}
940     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
941     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
942     virtual Precedence precedence() const { return PrecPostfix; }
943   protected:
944     virtual bool isIncrement() const = 0;
945     RefPtr<ExpressionNode> m_base;
946     Identifier m_ident;
947   };
948
949   class PreIncDotNode : public PrefixDotNode {
950   public:
951     PreIncDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
952     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
953   protected:
954     virtual bool isIncrement() const { return true; }
955   };
956
957   class PreDecDotNode : public PrefixDotNode {
958   public:
959     PreDecDotNode(ExpressionNode* b, const Identifier& i) KJS_FAST_CALL : PrefixDotNode(b, i) {}
960     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
961   protected:
962     virtual bool isIncrement() const { return false; }
963   };
964
965   class PrefixErrorNode : public ExpressionNode {
966   public:
967     PrefixErrorNode(ExpressionNode* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
968     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
969     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
970     virtual Precedence precedence() const { return PrecUnary; }
971   private:
972     RefPtr<ExpressionNode> m_expr;
973     Operator m_oper;
974   };
975
976   class UnaryPlusNode : public ExpressionNode {
977   public:
978     UnaryPlusNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), m_expr(e) {}
979     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
980     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
981     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
982     virtual Precedence precedence() const { return PrecUnary; }
983   private:
984     RefPtr<ExpressionNode> m_expr;
985   };
986
987   class NegateNode : public ExpressionNode {
988   public:
989     NegateNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
990     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
991     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
992     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
993     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
994     virtual Precedence precedence() const { return PrecUnary; }
995   private:
996     RefPtr<ExpressionNode> expr;
997   };
998
999   class BitwiseNotNode : public ExpressionNode {
1000   public:
1001     BitwiseNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(NumberType), expr(e) {}
1002     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1003     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1004     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1005     virtual Precedence precedence() const { return PrecUnary; }
1006   private:
1007     RefPtr<ExpressionNode> expr;
1008   };
1009
1010   class LogicalNotNode : public ExpressionNode {
1011   public:
1012     LogicalNotNode(ExpressionNode* e) KJS_FAST_CALL : ExpressionNode(BooleanType), expr(e) {}
1013     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1014     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1015     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1016     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1017     virtual Precedence precedence() const { return PrecUnary; }
1018   private:
1019     RefPtr<ExpressionNode> expr;
1020   };
1021   
1022   class MultNode : public ExpressionNode {
1023   public:
1024       MultNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1025       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1026       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1027       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1028       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1029       virtual Precedence precedence() const { return PrecMultiplicitave; }
1030   private:
1031       ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1032       RefPtr<ExpressionNode> term1;
1033       RefPtr<ExpressionNode> term2;
1034   };
1035   
1036   class DivNode : public ExpressionNode {
1037   public:
1038       DivNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1039       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1040       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1041       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1042       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1043       virtual Precedence precedence() const { return PrecMultiplicitave; }
1044   private:
1045       ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1046       RefPtr<ExpressionNode> term1;
1047       RefPtr<ExpressionNode> term2;
1048   };
1049   
1050   class ModNode : public ExpressionNode {
1051   public:
1052       ModNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1053       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1054       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1055       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1056       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1057       virtual Precedence precedence() const { return PrecMultiplicitave; }
1058   private:
1059       ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1060       RefPtr<ExpressionNode> term1;
1061       RefPtr<ExpressionNode> term2;
1062   };
1063
1064   class AddNode : public ExpressionNode {
1065   public:
1066     AddNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
1067     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1068     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1069     virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1070     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1071     virtual Precedence precedence() const { return PrecAdditive; }
1072   protected:
1073     AddNode(ExpressionNode* t1, ExpressionNode* t2, JSType expectedReturn) KJS_FAST_CALL : ExpressionNode(expectedReturn), term1(t1), term2(t2) {}
1074     RefPtr<ExpressionNode> term1;
1075     RefPtr<ExpressionNode> term2;
1076   };
1077
1078     class AddNumbersNode : public AddNode {
1079     public:
1080         AddNumbersNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, NumberType) {}
1081         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1082         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1083     private:
1084         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
1085     };
1086
1087     class AddStringLeftNode : public AddNode {
1088     public:
1089         AddStringLeftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1090         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1091     };
1092
1093     class AddStringRightNode : public AddNode {
1094     public:
1095         AddStringRightNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1096         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1097     };
1098
1099     class AddStringsNode : public AddNode {
1100     public:
1101         AddStringsNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : AddNode(t1, t2, StringType) {}
1102         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1103     };
1104
1105   class SubNode : public ExpressionNode {
1106   public:
1107       SubNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1108       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1109       virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1110       virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1111       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1112       virtual Precedence precedence() const { return PrecAdditive; }
1113   private:
1114       ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1115       RefPtr<ExpressionNode> term1;
1116       RefPtr<ExpressionNode> term2;
1117   };
1118
1119   class LeftShiftNode : public ExpressionNode {
1120   public:
1121     LeftShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1122       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1123     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1124     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1125     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1126     virtual Precedence precedence() const { return PrecShift; }
1127   private:
1128     RefPtr<ExpressionNode> term1;
1129     RefPtr<ExpressionNode> term2;
1130   };
1131
1132   class RightShiftNode : public ExpressionNode {
1133   public:
1134     RightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1135       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1136     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1137     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1138     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1139     virtual Precedence precedence() const { return PrecShift; }
1140   private:
1141     RefPtr<ExpressionNode> term1;
1142     RefPtr<ExpressionNode> term2;
1143   };
1144
1145   class UnsignedRightShiftNode : public ExpressionNode {
1146   public:
1147     UnsignedRightShiftNode(ExpressionNode* t1, ExpressionNode* t2) KJS_FAST_CALL
1148       : ExpressionNode(NumberType), term1(t1), term2(t2) {}
1149     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1150     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1151     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1152     virtual Precedence precedence() const { return PrecShift; }
1153   private:
1154     RefPtr<ExpressionNode> term1;
1155     RefPtr<ExpressionNode> term2;
1156   };
1157
1158   class LessNode : public ExpressionNode {
1159   public:
1160     LessNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1161       : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1162     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1163     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1164     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1165     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1166     virtual Precedence precedence() const { return PrecRelational; }
1167   protected:
1168     RefPtr<ExpressionNode> expr1;
1169     RefPtr<ExpressionNode> expr2;
1170   };
1171
1172     class LessNumbersNode : public LessNode {
1173     public:
1174         LessNumbersNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1175         : LessNode(e1, e2) {}
1176         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1177     };
1178
1179     class LessStringsNode : public LessNode {
1180     public:
1181         LessStringsNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1182         : LessNode(e1, e2) {}
1183         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1184     };
1185
1186   class GreaterNode : public ExpressionNode {
1187   public:
1188     GreaterNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1189       expr1(e1), expr2(e2) {}
1190     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1191     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1192     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1193     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1194     virtual Precedence precedence() const { return PrecRelational; }
1195   private:
1196     RefPtr<ExpressionNode> expr1;
1197     RefPtr<ExpressionNode> expr2;
1198   };
1199
1200   class LessEqNode : public ExpressionNode {
1201   public:
1202     LessEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1203       expr1(e1), expr2(e2) {}
1204     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1205     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1206     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1207     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1208     virtual Precedence precedence() const { return PrecRelational; }
1209   private:
1210     RefPtr<ExpressionNode> expr1;
1211     RefPtr<ExpressionNode> expr2;
1212   };
1213
1214   class GreaterEqNode : public ExpressionNode {
1215   public:
1216     GreaterEqNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1217       expr1(e1), expr2(e2) {}
1218     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1219     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1220     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1221     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1222     virtual Precedence precedence() const { return PrecRelational; }
1223   private:
1224     RefPtr<ExpressionNode> expr1;
1225     RefPtr<ExpressionNode> expr2;
1226   };
1227
1228     class InstanceOfNode : public ExpressionNode {
1229   public:
1230     InstanceOfNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1231         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1232     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1233     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1234     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1235     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1236     virtual Precedence precedence() const { return PrecRelational; }
1237   private:
1238     RefPtr<ExpressionNode> expr1;
1239     RefPtr<ExpressionNode> expr2;
1240   };
1241
1242     class InNode : public ExpressionNode {
1243   public:
1244     InNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1245       expr1(e1), expr2(e2) {}
1246     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1247     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1248     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1249     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1250     virtual Precedence precedence() const { return PrecRelational; }
1251   private:
1252     RefPtr<ExpressionNode> expr1;
1253     RefPtr<ExpressionNode> expr2;
1254   };
1255
1256     class EqualNode : public ExpressionNode {
1257   public:
1258     EqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1259         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1260     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1261     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1262     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1263     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1264     virtual Precedence precedence() const { return PrecEquality; }
1265   private:
1266     RefPtr<ExpressionNode> expr1;
1267     RefPtr<ExpressionNode> expr2;
1268   };
1269
1270     class NotEqualNode : public ExpressionNode {
1271   public:
1272     NotEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1273         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1274     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1275     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1276     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1277     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1278     virtual Precedence precedence() const { return PrecEquality; }
1279   private:
1280     RefPtr<ExpressionNode> expr1;
1281     RefPtr<ExpressionNode> expr2;
1282   };
1283
1284     class StrictEqualNode : public ExpressionNode {
1285   public:
1286     StrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1287         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1288     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1289     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1290     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1291     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1292     virtual Precedence precedence() const { return PrecEquality; }
1293   private:
1294     RefPtr<ExpressionNode> expr1;
1295     RefPtr<ExpressionNode> expr2;
1296   };
1297
1298     class NotStrictEqualNode : public ExpressionNode {
1299   public:
1300     NotStrictEqualNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1301         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1302     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1303     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1304     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1305     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1306     virtual Precedence precedence() const { return PrecEquality; }
1307   private:
1308     RefPtr<ExpressionNode> expr1;
1309     RefPtr<ExpressionNode> expr2;
1310   };
1311
1312     class BitAndNode : public ExpressionNode {
1313   public:
1314     BitAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1315         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1316     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1317     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1318     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1319     virtual Precedence precedence() const { return PrecBitwiseAnd; }
1320   private:
1321     RefPtr<ExpressionNode> expr1;
1322     RefPtr<ExpressionNode> expr2;
1323   };
1324
1325     class BitOrNode : public ExpressionNode {
1326   public:
1327     BitOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1328         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1329     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1330     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1331     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1332     virtual Precedence precedence() const { return PrecBitwiseOr; }
1333   private:
1334     RefPtr<ExpressionNode> expr1;
1335     RefPtr<ExpressionNode> expr2;
1336   };
1337
1338     class BitXOrNode : public ExpressionNode {
1339   public:
1340     BitXOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1341         : ExpressionNode(NumberType), expr1(e1), expr2(e2) {}
1342     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1343     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1344     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1345     virtual Precedence precedence() const { return PrecBitwiseXor; }
1346   private:
1347     RefPtr<ExpressionNode> expr1;
1348     RefPtr<ExpressionNode> expr2;
1349   };
1350
1351   /**
1352    * expr1 && expr2, expr1 || expr2
1353    */
1354     class LogicalAndNode : public ExpressionNode {
1355   public:
1356     LogicalAndNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1357         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1358     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1359     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1360     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1361     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1362     virtual Precedence precedence() const { return PrecLogicalAnd; }
1363   private:
1364     RefPtr<ExpressionNode> expr1;
1365     RefPtr<ExpressionNode> expr2;
1366   };
1367   
1368     class LogicalOrNode : public ExpressionNode {
1369   public:
1370     LogicalOrNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL
1371         : ExpressionNode(BooleanType), expr1(e1), expr2(e2) {}
1372     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1373     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1374     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1375     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1376     virtual Precedence precedence() const { return PrecLogicalOr; }
1377   private:
1378     RefPtr<ExpressionNode> expr1;
1379     RefPtr<ExpressionNode> expr2;
1380   };
1381
1382   /**
1383    * The ternary operator, "logical ? expr1 : expr2"
1384    */
1385     class ConditionalNode : public ExpressionNode {
1386   public:
1387     ConditionalNode(ExpressionNode*  l, ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL :
1388       logical(l), expr1(e1), expr2(e2) {}
1389     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1390     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1391     virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1392     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1393     virtual Precedence precedence() const { return PrecConditional; }
1394   private:
1395     RefPtr<ExpressionNode> logical;
1396     RefPtr<ExpressionNode> expr1;
1397     RefPtr<ExpressionNode> expr2;
1398   };
1399
1400     class ReadModifyResolveNode : public ExpressionNode {
1401   public:
1402     ReadModifyResolveNode(const Identifier &ident, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
1403       : m_ident(ident)
1404       , m_oper(oper)
1405       , m_right(right) 
1406       {
1407       }
1408
1409     ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
1410       : ExpressionNode(PlacementNewAdopt)
1411       , m_ident(PlacementNewAdopt) 
1412       , m_right(PlacementNewAdopt) 
1413     {
1414     }
1415
1416     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1417     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1418     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1419     virtual Precedence precedence() const { return PrecAssignment; }
1420   protected:
1421     Identifier m_ident;
1422     Operator m_oper;
1423     RefPtr<ExpressionNode> m_right;
1424     size_t m_index; // Used by ReadModifyLocalVarNode.
1425   };
1426
1427   class ReadModifyLocalVarNode : public ReadModifyResolveNode {
1428   public:
1429     ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL 
1430         : ReadModifyResolveNode(PlacementNewAdopt)
1431     { 
1432         ASSERT(i != missingSymbolMarker());
1433         m_index = i;
1434     }
1435     
1436     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1437   };
1438
1439     class AssignResolveNode : public ExpressionNode {
1440   public:
1441      AssignResolveNode(const Identifier &ident, ExpressionNode*  right) KJS_FAST_CALL
1442       : m_ident(ident)
1443       , m_right(right) 
1444       {
1445       }
1446
1447     AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
1448       : ExpressionNode(PlacementNewAdopt)
1449       , m_ident(PlacementNewAdopt) 
1450       , m_right(PlacementNewAdopt) 
1451     {
1452     }
1453
1454     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1455     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1456     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1457     virtual Precedence precedence() const { return PrecAssignment; }
1458   protected:
1459     Identifier m_ident;
1460     RefPtr<ExpressionNode> m_right;
1461     size_t m_index; // Used by ReadModifyLocalVarNode.
1462   };
1463
1464   class AssignLocalVarNode : public AssignResolveNode {
1465   public:
1466     AssignLocalVarNode(size_t i) KJS_FAST_CALL 
1467         : AssignResolveNode(PlacementNewAdopt)
1468     { 
1469         ASSERT(i != missingSymbolMarker());
1470         m_index = i;
1471     }
1472     
1473     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1474   };
1475
1476     class ReadModifyBracketNode : public ExpressionNode {
1477   public:
1478     ReadModifyBracketNode(ExpressionNode*  base, ExpressionNode*  subscript, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
1479       : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
1480     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1481     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1482     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1483     virtual Precedence precedence() const { return PrecAssignment; }
1484   protected:
1485     RefPtr<ExpressionNode> m_base;
1486     RefPtr<ExpressionNode> m_subscript;
1487     Operator m_oper;
1488     RefPtr<ExpressionNode> m_right;
1489   };
1490
1491     class AssignBracketNode : public ExpressionNode {
1492   public:
1493     AssignBracketNode(ExpressionNode*  base, ExpressionNode*  subscript, ExpressionNode*  right) KJS_FAST_CALL
1494       : m_base(base), m_subscript(subscript), m_right(right) {}
1495     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1496     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1497     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1498     virtual Precedence precedence() const { return PrecAssignment; }
1499   protected:
1500     RefPtr<ExpressionNode> m_base;
1501     RefPtr<ExpressionNode> m_subscript;
1502     RefPtr<ExpressionNode> m_right;
1503   };
1504
1505     class AssignDotNode : public ExpressionNode {
1506   public:
1507     AssignDotNode(ExpressionNode*  base, const Identifier& ident, ExpressionNode*  right) KJS_FAST_CALL
1508       : m_base(base), m_ident(ident), m_right(right) {}
1509     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1510     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1511     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1512     virtual Precedence precedence() const { return PrecAssignment; }
1513   protected:
1514     RefPtr<ExpressionNode> m_base;
1515     Identifier m_ident;
1516     RefPtr<ExpressionNode> m_right;
1517   };
1518
1519     class ReadModifyDotNode : public ExpressionNode {
1520   public:
1521     ReadModifyDotNode(ExpressionNode*  base, const Identifier& ident, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
1522       : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
1523     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1524     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1525     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1526     virtual Precedence precedence() const { return PrecAssignment; }
1527   protected:
1528     RefPtr<ExpressionNode> m_base;
1529     Identifier m_ident;
1530     Operator m_oper;
1531     RefPtr<ExpressionNode> m_right;
1532   };
1533
1534     class AssignErrorNode : public ExpressionNode {
1535   public:
1536     AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL
1537       : m_left(left), m_oper(oper), m_right(right) {}
1538     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1539     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1540     virtual Precedence precedence() const { return PrecAssignment; }
1541   protected:
1542     RefPtr<ExpressionNode> m_left;
1543     Operator m_oper;
1544     RefPtr<ExpressionNode> m_right;
1545   };
1546
1547     class CommaNode : public ExpressionNode {
1548   public:
1549     CommaNode(ExpressionNode* e1, ExpressionNode* e2) KJS_FAST_CALL : expr1(e1), expr2(e2)
1550     {
1551         e1->optimizeForUnnecessaryResult();
1552     }
1553     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1554     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1555     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1556     virtual Precedence precedence() const { return PrecExpression; }
1557   private:
1558     RefPtr<ExpressionNode> expr1;
1559     RefPtr<ExpressionNode> expr2;
1560   };
1561
1562     class AssignExprNode : public ExpressionNode {
1563   public:
1564     AssignExprNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1565     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1566     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1567     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1568     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1569   private:
1570     RefPtr<ExpressionNode> expr;
1571   };
1572
1573     class VarDeclNode : public ExpressionNode {
1574   public:
1575     enum Type { Variable, Constant };
1576     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) KJS_FAST_CALL;
1577     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1578     virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1579     void evaluateSingle(ExecState*) KJS_FAST_CALL;
1580     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1581     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1582     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1583     PassRefPtr<VarDeclNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1584
1585     Type varType;
1586     Identifier ident;
1587     ListRefPtr<VarDeclNode> next;
1588   private:
1589     void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
1590     RefPtr<AssignExprNode> init;
1591   };
1592
1593   class VarStatementNode : public StatementNode {
1594   public:
1595     VarStatementNode(VarDeclNode* l) KJS_FAST_CALL : next(l) { m_mayHaveDeclarations = true; }
1596     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1597     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1598     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1599     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1600   private:
1601     RefPtr<VarDeclNode> next;
1602   };
1603
1604   typedef Vector<RefPtr<StatementNode> > SourceElements;
1605
1606   class BlockNode : public StatementNode {
1607   public:
1608     BlockNode(SourceElements* children) KJS_FAST_CALL;
1609     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1610     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1611     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1612     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1613   protected:
1614     OwnPtr<SourceElements> m_children;
1615   };
1616
1617   class EmptyStatementNode : public StatementNode {
1618   public:
1619     EmptyStatementNode() KJS_FAST_CALL { } // debug
1620     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1621     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1622   };
1623
1624   class ExprStatementNode : public StatementNode {
1625   public:
1626     ExprStatementNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { }
1627     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1628     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1629     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1630   private:
1631     RefPtr<ExpressionNode> expr;
1632   };
1633
1634   class IfNode : public StatementNode {
1635   public:
1636     IfNode(ExpressionNode* e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
1637       : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
1638     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1639     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1640     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1641     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1642   private:
1643     RefPtr<ExpressionNode> expr;
1644     RefPtr<StatementNode> statement1;
1645     RefPtr<StatementNode> statement2;
1646   };
1647
1648   class DoWhileNode : public StatementNode {
1649   public:
1650     DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
1651     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1652     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1653     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1654     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1655   private:
1656     RefPtr<StatementNode> statement;
1657     RefPtr<ExpressionNode> expr;
1658   };
1659
1660   class WhileNode : public StatementNode {
1661   public:
1662     WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1663     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1664     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1665     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1666     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1667   private:
1668     RefPtr<ExpressionNode> expr;
1669     RefPtr<StatementNode> statement;
1670   };
1671
1672   class ForNode : public StatementNode {
1673   public:
1674     ForNode(ExpressionNode* e1, ExpressionNode* e2, ExpressionNode* e3, StatementNode* s) KJS_FAST_CALL :
1675       expr1(e1), expr2(e2), expr3(e3), statement(s)
1676     {
1677         m_mayHaveDeclarations = true; 
1678         if (expr1)
1679             expr1->optimizeForUnnecessaryResult();
1680         if (expr3)
1681             expr3->optimizeForUnnecessaryResult();
1682     }
1683
1684     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1685     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1686     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1687     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1688   private:
1689     RefPtr<ExpressionNode> expr1;
1690     RefPtr<ExpressionNode> expr2;
1691     RefPtr<ExpressionNode> expr3;
1692     RefPtr<StatementNode> statement;
1693   };
1694
1695   class ForInNode : public StatementNode {
1696   public:
1697     ForInNode(ExpressionNode*  l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1698     ForInNode(const Identifier &i, AssignExprNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1699     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1700     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1701     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1702     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1703   private:
1704     Identifier ident;
1705     RefPtr<AssignExprNode> init;
1706     RefPtr<ExpressionNode> lexpr;
1707     RefPtr<ExpressionNode> expr;
1708     RefPtr<VarDeclNode> varDecl;
1709     RefPtr<StatementNode> statement;
1710   };
1711
1712   class ContinueNode : public StatementNode {
1713   public:
1714     ContinueNode() KJS_FAST_CALL { }
1715     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1716     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1717     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1718   private:
1719     Identifier ident;
1720   };
1721
1722   class BreakNode : public StatementNode {
1723   public:
1724     BreakNode() KJS_FAST_CALL { }
1725     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1726     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1727     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1728   private:
1729     Identifier ident;
1730   };
1731
1732   class ReturnNode : public StatementNode {
1733   public:
1734     ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
1735     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1736     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1737     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1738   private:
1739     RefPtr<ExpressionNode> value;
1740   };
1741
1742   class WithNode : public StatementNode {
1743   public:
1744     WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1745     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1746     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1747     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1748     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1749   private:
1750     RefPtr<ExpressionNode> expr;
1751     RefPtr<StatementNode> statement;
1752   };
1753
1754   class LabelNode : public StatementNode {
1755   public:
1756     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
1757     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1758     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1759     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1760     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1761   private:
1762     Identifier label;
1763     RefPtr<StatementNode> statement;
1764   };
1765
1766   class ThrowNode : public StatementNode {
1767   public:
1768     ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1769     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1770     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1771     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1772   private:
1773     RefPtr<ExpressionNode> expr;
1774   };
1775
1776   class TryNode : public StatementNode {
1777   public:
1778     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1779       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
1780     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1781     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1782     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1783     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1784   private:
1785     RefPtr<StatementNode> tryBlock;
1786     Identifier exceptionIdent;
1787     RefPtr<StatementNode> catchBlock;
1788     RefPtr<StatementNode> finallyBlock;
1789   };
1790
1791     class ParameterNode : public Node {
1792   public:
1793     ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
1794     ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
1795       : id(i) { l->next = this; }
1796     Identifier ident() KJS_FAST_CALL { return id; }
1797     ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1798     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1799     PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1800     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1801   private:
1802     friend class FuncDeclNode;
1803     friend class FuncExprNode;
1804     Identifier id;
1805     ListRefPtr<ParameterNode> next;
1806   };
1807
1808   // inherited by ProgramNode
1809   class FunctionBodyNode : public BlockNode {
1810   public:
1811     FunctionBodyNode(SourceElements* children) KJS_FAST_CALL;
1812     int sourceId() KJS_FAST_CALL { return m_sourceId; }
1813     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
1814
1815     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1816     
1817     SymbolTable& symbolTable() { return m_symbolTable; }
1818
1819     void addParam(const Identifier& ident) KJS_FAST_CALL;
1820     size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
1821     Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos]; }
1822     UString paramString() const KJS_FAST_CALL;
1823     Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1824     ALWAYS_INLINE void processDeclarations(ExecState*);
1825     ALWAYS_INLINE void processDeclarationsForFunctionCode(ExecState*);
1826     ALWAYS_INLINE void processDeclarationsForProgramCode(ExecState*);
1827   private:
1828     UString m_sourceURL;
1829     int m_sourceId;
1830
1831     void initializeDeclarationStacks(ExecState*);
1832     bool m_initializedDeclarationStacks;
1833
1834     void initializeSymbolTable();
1835     bool m_initializedSymbolTable;
1836     
1837     void optimizeVariableAccess();
1838     bool m_optimizedResolveNodes;
1839     
1840     // Properties that will go into the ActivationImp's local storage. (Used for initializing the ActivationImp.)
1841     DeclarationStacks::VarStack m_varStack;
1842     DeclarationStacks::FunctionStack m_functionStack;
1843     Vector<Identifier> m_parameters;
1844
1845     // Mapping from property name -> local storage index. (Used once to transform the AST, and subsequently for residual slow case lookups.)
1846     SymbolTable m_symbolTable;
1847   };
1848
1849     class FuncExprNode : public ExpressionNode {
1850   public:
1851     FuncExprNode(const Identifier& i, FunctionBodyNode* b, ParameterNode* p = 0) KJS_FAST_CALL 
1852       : ident(i), param(p), body(b) { addParams(); }
1853     virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
1854     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1855     virtual Precedence precedence() const { return PrecMember; }
1856   private:
1857     void addParams() KJS_FAST_CALL;
1858     // Used for streamTo
1859     friend class PropertyNode;
1860     Identifier ident;
1861     RefPtr<ParameterNode> param;
1862     RefPtr<FunctionBodyNode> body;
1863   };
1864
1865   class FuncDeclNode : public StatementNode {
1866   public:
1867     FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
1868       : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
1869     FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
1870       : ident(i), param(p), body(b) { addParams(); m_mayHaveDeclarations = true; }
1871     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1872     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1873     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1874     ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
1875     Identifier ident;
1876   private:
1877     void addParams() KJS_FAST_CALL;
1878     RefPtr<ParameterNode> param;
1879     RefPtr<FunctionBodyNode> body;
1880   };
1881
1882     class CaseClauseNode : public Node {
1883   public:
1884       CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
1885       CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
1886       : expr(e), m_children(children) { m_mayHaveDeclarations = true; }
1887       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1888       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1889       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1890       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1891
1892       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1893       Completion evalStatements(ExecState*) KJS_FAST_CALL;
1894
1895   private:
1896       RefPtr<ExpressionNode> expr;
1897       OwnPtr<SourceElements> m_children;
1898   };
1899   
1900     class ClauseListNode : public Node {
1901   public:
1902       ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
1903       ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
1904       : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
1905       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1906       CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
1907       ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
1908       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1909       PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1910       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1911       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1912   private:
1913       friend class CaseBlockNode;
1914       RefPtr<CaseClauseNode> clause;
1915       ListRefPtr<ClauseListNode> next;
1916   };
1917   
1918     class CaseBlockNode : public Node {
1919   public:
1920       CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
1921       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1922       Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
1923       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1924       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1925       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1926   private:
1927       RefPtr<ClauseListNode> list1;
1928       RefPtr<CaseClauseNode> def;
1929       RefPtr<ClauseListNode> list2;
1930   };
1931   
1932   class SwitchNode : public StatementNode {
1933   public:
1934       SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
1935       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1936       virtual Completion execute(ExecState*) KJS_FAST_CALL;
1937       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1938       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1939   private:
1940       RefPtr<ExpressionNode> expr;
1941       RefPtr<CaseBlockNode> block;
1942   };
1943   
1944   class ProgramNode : public FunctionBodyNode {
1945   public:
1946     ProgramNode(SourceElements* children) KJS_FAST_CALL;
1947   };
1948
1949   struct ElementList {
1950       ElementNode* head;
1951       ElementNode* tail;
1952   };
1953
1954   struct PropertyList {
1955       PropertyListNode* head;
1956       PropertyListNode* tail;
1957   };
1958
1959   struct ArgumentList {
1960       ArgumentListNode* head;
1961       ArgumentListNode* tail;
1962   };
1963
1964   struct VarDeclList {
1965       VarDeclNode* head;
1966       VarDeclNode* tail;
1967   };
1968
1969   struct ParameterList {
1970       ParameterNode* head;
1971       ParameterNode* tail;
1972   };
1973
1974   struct ClauseList {
1975       ClauseListNode* head;
1976       ClauseListNode* tail;
1977   };
1978
1979 } // namespace
1980
1981 #endif