0d07148d7011ada8ca6804a5ac8426187ec5ea22
[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     {
1581         e->optimizeForUnnecessaryResult();
1582     }
1583     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1584     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1585     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1586   private:
1587     RefPtr<ExpressionNode> expr;
1588   };
1589
1590   class IfNode : public StatementNode {
1591   public:
1592     IfNode(ExpressionNode* e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
1593       : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
1594     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1595     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1596     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1597     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1598   private:
1599     RefPtr<ExpressionNode> expr;
1600     RefPtr<StatementNode> statement1;
1601     RefPtr<StatementNode> statement2;
1602   };
1603
1604   class DoWhileNode : public StatementNode {
1605   public:
1606     DoWhileNode(StatementNode *s, ExpressionNode* e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
1607     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1608     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1609     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1610     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1611   private:
1612     RefPtr<StatementNode> statement;
1613     RefPtr<ExpressionNode> expr;
1614   };
1615
1616   class WhileNode : public StatementNode {
1617   public:
1618     WhileNode(ExpressionNode* e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1619     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1620     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1621     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1622     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1623   private:
1624     RefPtr<ExpressionNode> expr;
1625     RefPtr<StatementNode> statement;
1626   };
1627
1628   class ForNode : public StatementNode {
1629   public:
1630     ForNode(ExpressionNode* e1, ExpressionNode* e2, ExpressionNode* e3, StatementNode* s) KJS_FAST_CALL :
1631       expr1(e1), expr2(e2), expr3(e3), statement(s)
1632     {
1633         m_mayHaveDeclarations = true; 
1634         if (expr1)
1635             expr1->optimizeForUnnecessaryResult();
1636         if (expr3)
1637             expr3->optimizeForUnnecessaryResult();
1638     }
1639
1640     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1641     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1642     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1643     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1644   private:
1645     RefPtr<ExpressionNode> expr1;
1646     RefPtr<ExpressionNode> expr2;
1647     RefPtr<ExpressionNode> expr3;
1648     RefPtr<StatementNode> statement;
1649   };
1650
1651   class ForInNode : public StatementNode {
1652   public:
1653     ForInNode(ExpressionNode*  l, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1654     ForInNode(const Identifier &i, AssignExprNode *in, ExpressionNode* e, StatementNode *s) KJS_FAST_CALL;
1655     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1656     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1657     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1658     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1659   private:
1660     Identifier ident;
1661     RefPtr<AssignExprNode> init;
1662     RefPtr<ExpressionNode> lexpr;
1663     RefPtr<ExpressionNode> expr;
1664     RefPtr<VarDeclNode> varDecl;
1665     RefPtr<StatementNode> statement;
1666   };
1667
1668   class ContinueNode : public StatementNode {
1669   public:
1670     ContinueNode() KJS_FAST_CALL { }
1671     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1672     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1673     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1674   private:
1675     Identifier ident;
1676   };
1677
1678   class BreakNode : public StatementNode {
1679   public:
1680     BreakNode() KJS_FAST_CALL { }
1681     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1682     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1683     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1684   private:
1685     Identifier ident;
1686   };
1687
1688   class ReturnNode : public StatementNode {
1689   public:
1690     ReturnNode(ExpressionNode* v) KJS_FAST_CALL : value(v) {}
1691     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1692     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1693     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1694   private:
1695     RefPtr<ExpressionNode> value;
1696   };
1697
1698   class WithNode : public StatementNode {
1699   public:
1700     WithNode(ExpressionNode* e, StatementNode* s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1701     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1702     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1703     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1704     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1705   private:
1706     RefPtr<ExpressionNode> expr;
1707     RefPtr<StatementNode> statement;
1708   };
1709
1710   class LabelNode : public StatementNode {
1711   public:
1712     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
1713     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1714     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1715     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1716     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1717   private:
1718     Identifier label;
1719     RefPtr<StatementNode> statement;
1720   };
1721
1722   class ThrowNode : public StatementNode {
1723   public:
1724     ThrowNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) {}
1725     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1726     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1727     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1728   private:
1729     RefPtr<ExpressionNode> expr;
1730   };
1731
1732   class TryNode : public StatementNode {
1733   public:
1734     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1735       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
1736     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1737     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1738     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1739     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1740   private:
1741     RefPtr<StatementNode> tryBlock;
1742     Identifier exceptionIdent;
1743     RefPtr<StatementNode> catchBlock;
1744     RefPtr<StatementNode> finallyBlock;
1745   };
1746
1747     class ParameterNode : public Node {
1748   public:
1749     ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
1750     ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
1751       : id(i) { l->next = this; }
1752     Identifier ident() KJS_FAST_CALL { return id; }
1753     ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1754     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1755     PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1756     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1757   private:
1758     friend class FuncDeclNode;
1759     friend class FuncExprNode;
1760     Identifier id;
1761     ListRefPtr<ParameterNode> next;
1762   };
1763
1764   // inherited by ProgramNode
1765   class FunctionBodyNode : public BlockNode {
1766   public:
1767     FunctionBodyNode(SourceElements* children) KJS_FAST_CALL;
1768     int sourceId() KJS_FAST_CALL { return m_sourceId; }
1769     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
1770
1771     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1772     
1773     SymbolTable& symbolTable() { return m_symbolTable; }
1774
1775     void addParam(const Identifier& ident) KJS_FAST_CALL;
1776     size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
1777     Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos]; }
1778     UString paramString() const KJS_FAST_CALL;
1779     Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1780     ALWAYS_INLINE void processDeclarations(ExecState*);
1781     ALWAYS_INLINE void processDeclarationsForFunctionCode(ExecState*);
1782     ALWAYS_INLINE void processDeclarationsForProgramCode(ExecState*);
1783   private:
1784     UString m_sourceURL;
1785     int m_sourceId;
1786
1787     void initializeDeclarationStacks(ExecState*);
1788     bool m_initializedDeclarationStacks;
1789
1790     void initializeSymbolTable();
1791     bool m_initializedSymbolTable;
1792     
1793     void optimizeVariableAccess();
1794     bool m_optimizedResolveNodes;
1795     
1796     // Properties that will go into the ActivationImp's local storage. (Used for initializing the ActivationImp.)
1797     DeclarationStacks::VarStack m_varStack;
1798     DeclarationStacks::FunctionStack m_functionStack;
1799     Vector<Identifier> m_parameters;
1800
1801     // Mapping from property name -> local storage index. (Used once to transform the AST, and subsequently for residual slow case lookups.)
1802     SymbolTable m_symbolTable;
1803   };
1804
1805     class FuncExprNode : public ExpressionNode {
1806   public:
1807     FuncExprNode(const Identifier& i, FunctionBodyNode* b, ParameterNode* p = 0) KJS_FAST_CALL 
1808       : ident(i), param(p), body(b) { addParams(); }
1809     virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
1810     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1811     virtual Precedence precedence() const { return PrecMember; }
1812   private:
1813     void addParams() KJS_FAST_CALL;
1814     // Used for streamTo
1815     friend class PropertyNode;
1816     Identifier ident;
1817     RefPtr<ParameterNode> param;
1818     RefPtr<FunctionBodyNode> body;
1819   };
1820
1821   class FuncDeclNode : public StatementNode {
1822   public:
1823     FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
1824       : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
1825     FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
1826       : ident(i), param(p), body(b) { addParams(); m_mayHaveDeclarations = true; }
1827     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1828     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1829     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1830     ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
1831     Identifier ident;
1832   private:
1833     void addParams() KJS_FAST_CALL;
1834     RefPtr<ParameterNode> param;
1835     RefPtr<FunctionBodyNode> body;
1836   };
1837
1838     class CaseClauseNode : public Node {
1839   public:
1840       CaseClauseNode(ExpressionNode* e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
1841       CaseClauseNode(ExpressionNode* e, SourceElements* children) KJS_FAST_CALL
1842       : expr(e), m_children(children) { m_mayHaveDeclarations = true; }
1843       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1844       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1845       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1846       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1847
1848       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1849       Completion evalStatements(ExecState*) KJS_FAST_CALL;
1850
1851   private:
1852       RefPtr<ExpressionNode> expr;
1853       OwnPtr<SourceElements> m_children;
1854   };
1855   
1856     class ClauseListNode : public Node {
1857   public:
1858       ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
1859       ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
1860       : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
1861       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1862       CaseClauseNode* getClause() const KJS_FAST_CALL { return clause.get(); }
1863       ClauseListNode* getNext() const KJS_FAST_CALL { return next.get(); }
1864       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1865       PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1866       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1867       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1868   private:
1869       friend class CaseBlockNode;
1870       RefPtr<CaseClauseNode> clause;
1871       ListRefPtr<ClauseListNode> next;
1872   };
1873   
1874     class CaseBlockNode : public Node {
1875   public:
1876       CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
1877       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1878       Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
1879       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1880       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1881       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1882   private:
1883       RefPtr<ClauseListNode> list1;
1884       RefPtr<CaseClauseNode> def;
1885       RefPtr<ClauseListNode> list2;
1886   };
1887   
1888   class SwitchNode : public StatementNode {
1889   public:
1890       SwitchNode(ExpressionNode* e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
1891       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1892       virtual Completion execute(ExecState*) KJS_FAST_CALL;
1893       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1894       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1895   private:
1896       RefPtr<ExpressionNode> expr;
1897       RefPtr<CaseBlockNode> block;
1898   };
1899   
1900   class ProgramNode : public FunctionBodyNode {
1901   public:
1902     ProgramNode(SourceElements* children) KJS_FAST_CALL;
1903   };
1904
1905   struct ElementList {
1906       ElementNode* head;
1907       ElementNode* tail;
1908   };
1909
1910   struct PropertyList {
1911       PropertyListNode* head;
1912       PropertyListNode* tail;
1913   };
1914
1915   struct ArgumentList {
1916       ArgumentListNode* head;
1917       ArgumentListNode* tail;
1918   };
1919
1920   struct VarDeclList {
1921       VarDeclNode* head;
1922       VarDeclNode* tail;
1923   };
1924
1925   struct ParameterList {
1926       ParameterNode* head;
1927       ParameterNode* tail;
1928   };
1929
1930   struct ClauseList {
1931       ClauseListNode* head;
1932       ClauseListNode* tail;
1933   };
1934
1935 } // namespace
1936
1937 #endif