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