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