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