53053095bf7b7dacec1cc6a7895fd53dfc9048ef
[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  *
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/Vector.h>
34
35 #if PLATFORM(X86) && COMPILER(GCC)
36 #define KJS_FAST_CALL __attribute__((regparm(3)))
37 #else
38 #define KJS_FAST_CALL
39 #endif
40
41 #if COMPILER(GCC)
42 #define KJS_NO_INLINE __attribute__((noinline))
43 #else
44 #define KJS_NO_INLINE
45 #endif
46
47 namespace KJS {
48
49     class FuncDeclNode;
50     class PropertyListNode;
51     class SourceElementsNode;
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 {
114   public:
115     Node() KJS_FAST_CALL;
116     Node(PlacementNewAdoptType) KJS_FAST_CALL { }
117     virtual ~Node();
118
119     virtual JSValue *evaluate(ExecState *exec) KJS_FAST_CALL = 0;
120     UString toString() const KJS_FAST_CALL;
121     int lineNo() const KJS_FAST_CALL { return m_line; }
122     void ref() KJS_FAST_CALL;
123     void deref() KJS_FAST_CALL;
124     unsigned refcount() KJS_FAST_CALL;
125     static void clearNewNodes() KJS_FAST_CALL;
126
127     virtual bool isNumber() const KJS_FAST_CALL { return false; }
128     virtual bool isImmediateValue() const KJS_FAST_CALL { return false; }
129     virtual bool isLocation() const KJS_FAST_CALL { return false; }
130     virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
131     virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
132     virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
133
134     // Serialization.
135     virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
136     virtual Precedence precedence() const = 0;
137
138     // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
139     bool mayHaveDeclarations() const { return m_mayHaveDeclarations; }
140     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL { ASSERT_NOT_REACHED(); }
141     
142     // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
143     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL { }
144
145   protected:
146     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
147     Completion createErrorCompletion(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
148
149     JSValue *throwError(ExecState *, ErrorType, const char *msg) KJS_FAST_CALL;
150     JSValue* throwError(ExecState *, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
151     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *) KJS_FAST_CALL;
152     JSValue *throwError(ExecState *, ErrorType, const char *msg, const Identifier &) KJS_FAST_CALL;
153     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, const Identifier &) KJS_FAST_CALL;
154     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, Node *) KJS_FAST_CALL;
155     JSValue *throwError(ExecState *, ErrorType, const char *msg, JSValue *, Node *, const Identifier &) KJS_FAST_CALL;
156
157     JSValue *throwUndefinedVariableError(ExecState *, const Identifier &) KJS_FAST_CALL;
158
159     void handleException(ExecState*) KJS_FAST_CALL;
160     void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
161
162     Completion rethrowException(ExecState*) KJS_FAST_CALL;
163
164     int m_line : 31;
165     bool m_mayHaveDeclarations : 1;
166   private:
167     // disallow assignment
168     Node& operator=(const Node&) KJS_FAST_CALL;
169     Node(const Node &other) KJS_FAST_CALL;
170   };
171
172   class StatementNode : public Node {
173   public:
174     StatementNode() KJS_FAST_CALL;
175     void setLoc(int line0, int line1) KJS_FAST_CALL;
176     int firstLine() const KJS_FAST_CALL { return lineNo(); }
177     int lastLine() const KJS_FAST_CALL { return m_lastLine; }
178     bool hitStatement(ExecState*) KJS_FAST_CALL;
179     virtual Completion execute(ExecState *exec) KJS_FAST_CALL = 0;
180     void pushLabel(const Identifier &id) KJS_FAST_CALL { ls.push(id); }
181     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
182   protected:
183     LabelStack ls;
184   private:
185     JSValue *evaluate(ExecState*) KJS_FAST_CALL { return jsUndefined(); }
186     int m_lastLine;
187   };
188
189   class NullNode : public Node {
190   public:
191     NullNode() KJS_FAST_CALL {}
192     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
193     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
194     virtual Precedence precedence() const { return PrecPrimary; }
195   };
196
197   class BooleanNode : public Node {
198   public:
199     BooleanNode(bool v) KJS_FAST_CALL : value(v) {}
200     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
201     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
202     virtual Precedence precedence() const { return PrecPrimary; }
203   private:
204     bool value;
205   };
206
207   class NumberNode : public Node {
208   public:
209     NumberNode(double v) KJS_FAST_CALL : val(v) {}
210     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
211     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
212     virtual Precedence precedence() const { return PrecPrimary; }
213
214     virtual bool isNumber() const KJS_FAST_CALL { return true; }
215     double value() const KJS_FAST_CALL { return val; }
216     void setValue(double v) KJS_FAST_CALL { val = v; }
217   private:
218     double val;
219   };
220   
221   class ImmediateNumberNode : public Node {
222   public:
223       ImmediateNumberNode(JSValue* v) KJS_FAST_CALL : m_value(v) {}
224       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
225       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
226       virtual Precedence precedence() const { return PrecPrimary; }
227       
228       virtual bool isImmediateValue() const KJS_FAST_CALL { return true; }
229       double value() const KJS_FAST_CALL { return JSImmediate::toDouble(m_value); }
230       void setValue(double v) KJS_FAST_CALL { m_value = JSImmediate::fromDouble(v); ASSERT(m_value); }
231   private:
232       JSValue* m_value;
233   };
234
235   class StringNode : public Node {
236   public:
237     StringNode(const UString *v) KJS_FAST_CALL { value = *v; }
238     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
239     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
240     virtual Precedence precedence() const { return PrecPrimary; }
241   private:
242     UString value;
243   };
244
245   class RegExpNode : public Node {
246   public:
247     RegExpNode(const UString &p, const UString &f) KJS_FAST_CALL 
248       : pattern(p), flags(f) { }
249     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
250     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
251     virtual Precedence precedence() const { return PrecPrimary; }
252   private:
253     UString pattern, flags;
254   };
255
256   class ThisNode : public Node {
257   public:
258     ThisNode() KJS_FAST_CALL {}
259     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
260     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
261     virtual Precedence precedence() const { return PrecPrimary; }
262  };
263
264   class ResolveNode : public Node {
265   public:
266     ResolveNode(const Identifier &s) KJS_FAST_CALL 
267         : ident(s) 
268     { 
269     }
270
271     // Special constructor for cases where we overwrite an object in place.
272     ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
273         : Node(PlacementNewAdopt)
274         , ident(PlacementNewAdopt) 
275     {
276     }
277
278     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
279
280     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
281     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
282     virtual Precedence precedence() const { return PrecPrimary; }
283
284     virtual bool isLocation() const KJS_FAST_CALL { return true; }
285     virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
286     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
287
288   protected:
289     Identifier ident;
290     size_t index; // Used by LocalVarAccessNode.
291   };
292
293   class LocalVarAccessNode : public ResolveNode {
294   public:
295     // Overwrites a ResolveNode in place.
296     LocalVarAccessNode(size_t i) KJS_FAST_CALL
297         : ResolveNode(PlacementNewAdopt)
298     {
299         ASSERT(i != missingSymbolMarker());
300         index = i;
301     }
302     virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
303   };
304
305   class ElementNode : public Node {
306   public:
307     ElementNode(int e, Node* n) KJS_FAST_CALL : elision(e), node(n) { }
308     ElementNode(ElementNode* l, int e, Node* n) KJS_FAST_CALL
309       : elision(e), node(n) { l->next = this; }
310     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
311     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
312     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
313     PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return next.release(); }
314     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
315   private:
316     friend class ArrayNode;
317     ListRefPtr<ElementNode> next;
318     int elision;
319     RefPtr<Node> node;
320   };
321
322   class ArrayNode : public Node {
323   public:
324     ArrayNode(int e) KJS_FAST_CALL : elision(e), opt(true) { }
325     ArrayNode(ElementNode* ele) KJS_FAST_CALL
326       : element(ele), elision(0), opt(false) { }
327     ArrayNode(int eli, ElementNode* ele) KJS_FAST_CALL
328       : element(ele), elision(eli), opt(true) { }
329     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
330     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
331     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
332     virtual Precedence precedence() const { return PrecPrimary; }
333   private:
334     RefPtr<ElementNode> element;
335     int elision;
336     bool opt;
337   };
338
339   class PropertyNode : public Node {
340   public:
341     enum Type { Constant, Getter, Setter };
342     PropertyNode(const Identifier& n, Node *a, Type t) KJS_FAST_CALL
343       : m_name(n), assign(a), type(t) { }
344     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
345     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
346     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
347     friend class PropertyListNode;
348     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
349     const Identifier& name() const { return m_name; }
350   private:
351     Identifier m_name;
352     RefPtr<Node> assign;
353     Type type;
354   };
355   
356   class PropertyListNode : public Node {
357   public:
358     PropertyListNode(PropertyNode* n) KJS_FAST_CALL
359       : node(n) { }
360     PropertyListNode(PropertyNode* n, PropertyListNode* l) KJS_FAST_CALL
361       : node(n) { l->next = this; }
362     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
363     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
364     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
365     PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
366     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
367   private:
368     friend class ObjectLiteralNode;
369     RefPtr<PropertyNode> node;
370     ListRefPtr<PropertyListNode> next;
371   };
372
373   class ObjectLiteralNode : public Node {
374   public:
375     ObjectLiteralNode() KJS_FAST_CALL { }
376     ObjectLiteralNode(PropertyListNode* l) KJS_FAST_CALL : list(l) { }
377     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
378     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
379     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
380     virtual Precedence precedence() const { return PrecPrimary; }
381   private:
382     RefPtr<PropertyListNode> list;
383   };
384
385   class BracketAccessorNode : public Node {
386   public:
387     BracketAccessorNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
388     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
389     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
390     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
391     virtual Precedence precedence() const { return PrecMember; }
392
393     virtual bool isLocation() const KJS_FAST_CALL { return true; }
394     virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
395     Node *base() KJS_FAST_CALL { return expr1.get(); }
396     Node *subscript() KJS_FAST_CALL { return expr2.get(); }
397
398   private:
399     RefPtr<Node> expr1;
400     RefPtr<Node> expr2;
401   };
402
403   class DotAccessorNode : public Node {
404   public:
405     DotAccessorNode(Node *e, const Identifier &s) KJS_FAST_CALL : expr(e), ident(s) { }
406     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
407     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
408     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
409     virtual Precedence precedence() const { return PrecMember; }
410
411     virtual bool isLocation() const KJS_FAST_CALL { return true; }
412     virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
413     Node *base() const KJS_FAST_CALL { return expr.get(); }
414     const Identifier& identifier() const KJS_FAST_CALL { return ident; }
415
416   private:
417     RefPtr<Node> expr;
418     Identifier ident;
419   };
420
421   class ArgumentListNode : public Node {
422   public:
423     ArgumentListNode(Node* e) KJS_FAST_CALL : expr(e) { }
424     ArgumentListNode(ArgumentListNode* l, Node* e) KJS_FAST_CALL 
425       : expr(e) { l->next = this; }
426     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
427     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
428     List evaluateList(ExecState*) KJS_FAST_CALL;
429     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
430     PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
431     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
432   private:
433     friend class ArgumentsNode;
434     ListRefPtr<ArgumentListNode> next;
435     RefPtr<Node> expr;
436   };
437
438   class ArgumentsNode : public Node {
439   public:
440     ArgumentsNode() KJS_FAST_CALL { }
441     ArgumentsNode(ArgumentListNode* l) KJS_FAST_CALL
442       : list(l) { }
443     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
444     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
445     List evaluateList(ExecState *exec) KJS_FAST_CALL { return list ? list->evaluateList(exec) : List(); }
446     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
447     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
448   private:
449     RefPtr<ArgumentListNode> list;
450   };
451
452   class NewExprNode : public Node {
453   public:
454     NewExprNode(Node *e) KJS_FAST_CALL : expr(e) {}
455     NewExprNode(Node *e, ArgumentsNode *a) KJS_FAST_CALL : expr(e), args(a) {}
456     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
457     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
458     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
459     virtual Precedence precedence() const { return PrecLeftHandSide; }
460   private:
461     RefPtr<Node> expr;
462     RefPtr<ArgumentsNode> args;
463   };
464
465   class FunctionCallValueNode : public Node {
466   public:
467     FunctionCallValueNode(Node *e, ArgumentsNode *a) KJS_FAST_CALL : expr(e), args(a) {}
468     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
469     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
470     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
471     virtual Precedence precedence() const { return PrecCall; }
472   private:
473     RefPtr<Node> expr;
474     RefPtr<ArgumentsNode> args;
475   };
476
477   class FunctionCallResolveNode : public Node {
478   public:
479     FunctionCallResolveNode(const Identifier& i, ArgumentsNode* a) KJS_FAST_CALL
480         : ident(i)
481         , args(a)
482     {
483     }
484
485     FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
486         : Node(PlacementNewAdopt)
487         , ident(PlacementNewAdopt)
488         , args(PlacementNewAdopt)
489     {
490     }
491
492     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
493     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
494     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
495     virtual Precedence precedence() const { return PrecCall; }
496
497   protected:
498     Identifier ident;
499     RefPtr<ArgumentsNode> args;
500     size_t index; // Used by LocalVarFunctionCallNode.
501   };
502
503   class LocalVarFunctionCallNode : public FunctionCallResolveNode {
504   public:
505     LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
506         : FunctionCallResolveNode(PlacementNewAdopt)
507     {
508         ASSERT(i != missingSymbolMarker());
509         index = i;
510     }
511
512     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
513   };
514
515   class FunctionCallBracketNode : public Node {
516   public:
517     FunctionCallBracketNode(Node *b, Node *s, ArgumentsNode *a) KJS_FAST_CALL : base(b), subscript(s), args(a) {}
518     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
519     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
520     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
521     virtual Precedence precedence() const { return PrecCall; }
522   protected:
523     RefPtr<Node> base;
524     RefPtr<Node> subscript;
525     RefPtr<ArgumentsNode> args;
526   };
527
528   class FunctionCallDotNode : public Node {
529   public:
530     FunctionCallDotNode(Node *b, const Identifier &i, ArgumentsNode *a) KJS_FAST_CALL : base(b), ident(i), args(a) {}
531     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
532     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
533     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
534     virtual Precedence precedence() const { return PrecCall; }
535   protected:
536     RefPtr<Node> base;
537     Identifier ident;
538     RefPtr<ArgumentsNode> args;
539   };
540
541   class PostfixResolveNode : public Node {
542   public:
543     PostfixResolveNode(const Identifier& i, Operator o) KJS_FAST_CALL : m_ident(i), m_oper(o) {}
544
545     PostfixResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
546         : Node(PlacementNewAdopt)
547         , m_ident(PlacementNewAdopt)
548     {
549     }
550
551     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
552     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
553     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
554     virtual Precedence precedence() const { return PrecPostfix; }
555
556   protected:
557     Identifier m_ident;
558     Operator m_oper;
559     size_t index; // Used by LocalVarPostfixNode.
560   };
561
562   class LocalVarPostfixNode : public PostfixResolveNode {
563   public:
564     LocalVarPostfixNode(size_t i) KJS_FAST_CALL
565         : PostfixResolveNode(PlacementNewAdopt)
566     {
567         ASSERT(i != missingSymbolMarker());
568         index = i;
569     }
570
571     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
572   };
573
574   class PostfixBracketNode : public Node {
575   public:
576     PostfixBracketNode(Node *b, Node *s, Operator o) KJS_FAST_CALL : m_base(b), m_subscript(s), m_oper(o) {}
577     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
578     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
579     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
580     virtual Precedence precedence() const { return PrecPostfix; }
581   private:
582     RefPtr<Node> m_base;
583     RefPtr<Node> m_subscript;
584     Operator m_oper;
585   };
586
587   class PostfixDotNode : public Node {
588   public:
589     PostfixDotNode(Node *b, const Identifier& i, Operator o) KJS_FAST_CALL : m_base(b), m_ident(i), m_oper(o) {}
590     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
591     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
592     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
593     virtual Precedence precedence() const { return PrecPostfix; }
594   private:
595     RefPtr<Node> m_base;
596     Identifier m_ident;
597     Operator m_oper;
598   };
599
600   class PostfixErrorNode : public Node {
601   public:
602     PostfixErrorNode(Node* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
603     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
604     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
605     virtual Precedence precedence() const { return PrecPostfix; }
606   private:
607     RefPtr<Node> m_expr;
608     Operator m_oper;
609   };
610
611   class DeleteResolveNode : public Node {
612   public:
613     DeleteResolveNode(const Identifier& i) KJS_FAST_CALL : m_ident(i) {}
614     DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
615         : Node(PlacementNewAdopt)
616         , m_ident(PlacementNewAdopt)
617     {
618     }
619
620     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
621     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
622     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
623     virtual Precedence precedence() const { return PrecUnary; }
624   private:
625     Identifier m_ident;
626   };
627
628   class LocalVarDeleteNode : public DeleteResolveNode {
629   public:
630     LocalVarDeleteNode() KJS_FAST_CALL
631         : DeleteResolveNode(PlacementNewAdopt)
632     {
633     }
634
635     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
636   };
637
638   class DeleteBracketNode : public Node {
639   public:
640     DeleteBracketNode(Node *base, Node *subscript) KJS_FAST_CALL : m_base(base), m_subscript(subscript) {}
641     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
642     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
643     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
644     virtual Precedence precedence() const { return PrecUnary; }
645   private:
646     RefPtr<Node> m_base;
647     RefPtr<Node> m_subscript;
648   };
649
650   class DeleteDotNode : public Node {
651   public:
652     DeleteDotNode(Node *base, const Identifier& i) KJS_FAST_CALL : m_base(base), m_ident(i) {}
653     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
654     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
655     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
656     virtual Precedence precedence() const { return PrecUnary; }
657   private:
658     RefPtr<Node> m_base;
659     Identifier m_ident;
660   };
661
662   class DeleteValueNode : public Node {
663   public:
664     DeleteValueNode(Node *e) KJS_FAST_CALL : m_expr(e) {}
665     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
666     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
667     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
668     virtual Precedence precedence() const { return PrecUnary; }
669   private:
670     RefPtr<Node> m_expr;
671   };
672
673   class VoidNode : public Node {
674   public:
675     VoidNode(Node *e) KJS_FAST_CALL : expr(e) {}
676     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
677     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
678     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
679     virtual Precedence precedence() const { return PrecUnary; }
680   private:
681     RefPtr<Node> expr;
682   };
683
684   class TypeOfResolveNode : public Node {
685   public:
686     TypeOfResolveNode(const Identifier &s) KJS_FAST_CALL 
687         : m_ident(s) 
688     { 
689     }
690     
691     TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
692         : Node(PlacementNewAdopt)
693         , m_ident(PlacementNewAdopt) 
694     {
695     }
696
697     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
698     
699     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
700     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
701     virtual Precedence precedence() const { return PrecUnary; }
702
703     const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
704
705   protected:
706     Identifier m_ident;
707     size_t m_index; // Used by LocalTypeOfNode.
708   };
709     
710   class LocalTypeOfAccessNode : public TypeOfResolveNode {
711   public:
712     LocalTypeOfAccessNode(size_t i) KJS_FAST_CALL 
713         : TypeOfResolveNode(PlacementNewAdopt)
714     { 
715         ASSERT(i != missingSymbolMarker());
716         m_index = i;
717     }
718
719     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
720   };
721
722   class TypeOfValueNode : public Node {
723   public:
724     TypeOfValueNode(Node *e) KJS_FAST_CALL : m_expr(e) {}
725     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
726     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
727     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
728     virtual Precedence precedence() const { return PrecUnary; }
729   private:
730     RefPtr<Node> m_expr;
731   };
732
733   class PrefixResolveNode : public Node {
734   public:
735     PrefixResolveNode(const Identifier &s, Operator o) KJS_FAST_CALL 
736         : m_ident(s) 
737         , m_oper(o) 
738     { 
739     }
740     
741     PrefixResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
742         : Node(PlacementNewAdopt)
743         , m_ident(PlacementNewAdopt) 
744         , m_oper(m_oper) 
745     {
746     }
747     
748     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
749
750     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
751     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
752     virtual Precedence precedence() const { return PrecUnary; }
753
754   protected:
755     Identifier m_ident;
756     Operator m_oper;
757     size_t m_index;
758   };
759
760   class PrefixLocalAccessNode : public PrefixResolveNode {
761   public:
762     PrefixLocalAccessNode(size_t i) KJS_FAST_CALL 
763         : PrefixResolveNode(PlacementNewAdopt)
764     { 
765         ASSERT(i != missingSymbolMarker());
766         m_index = i;
767     }
768     
769     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
770   };
771
772   class PrefixBracketNode : public Node {
773   public:
774     PrefixBracketNode(Node *b, Node *s, Operator o) KJS_FAST_CALL : m_base(b), m_subscript(s), m_oper(o) {}
775     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
776     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
777     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
778     virtual Precedence precedence() const { return PrecUnary; }
779   private:
780     RefPtr<Node> m_base;
781     RefPtr<Node> m_subscript;
782     Operator m_oper;
783   };
784
785   class PrefixDotNode : public Node {
786   public:
787     PrefixDotNode(Node *b, const Identifier& i, Operator o) KJS_FAST_CALL : m_base(b), m_ident(i), m_oper(o) {}
788     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
789     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
790     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
791     virtual Precedence precedence() const { return PrecUnary; }
792   private:
793     RefPtr<Node> m_base;
794     Identifier m_ident;
795     Operator m_oper;
796   };
797
798   class PrefixErrorNode : public Node {
799   public:
800     PrefixErrorNode(Node* e, Operator o) KJS_FAST_CALL : m_expr(e), m_oper(o) {}
801     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
802     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
803     virtual Precedence precedence() const { return PrecUnary; }
804   private:
805     RefPtr<Node> m_expr;
806     Operator m_oper;
807   };
808
809   class UnaryPlusNode : public Node {
810   public:
811     UnaryPlusNode(Node *e) KJS_FAST_CALL : expr(e) {}
812     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
813     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
814     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
815     virtual Precedence precedence() const { return PrecUnary; }
816   private:
817     RefPtr<Node> expr;
818   };
819
820   class NegateNode : public Node {
821   public:
822     NegateNode(Node *e) KJS_FAST_CALL : expr(e) {}
823     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
824     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
825     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
826     virtual Precedence precedence() const { return PrecUnary; }
827   private:
828     RefPtr<Node> expr;
829   };
830
831   class BitwiseNotNode : public Node {
832   public:
833     BitwiseNotNode(Node *e) KJS_FAST_CALL : expr(e) {}
834     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
835     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
836     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
837     virtual Precedence precedence() const { return PrecUnary; }
838   private:
839     RefPtr<Node> expr;
840   };
841
842   class LogicalNotNode : public Node {
843   public:
844     LogicalNotNode(Node *e) KJS_FAST_CALL : expr(e) {}
845     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
846     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
847     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
848     virtual Precedence precedence() const { return PrecUnary; }
849   private:
850     RefPtr<Node> expr;
851   };
852   
853   class MultNode : public Node {
854   public:
855       MultNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
856       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
857       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
858       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
859       virtual Precedence precedence() const { return PrecMultiplicitave; }
860   private:
861       RefPtr<Node> term1;
862       RefPtr<Node> term2;
863   };
864   
865   class DivNode : public Node {
866   public:
867       DivNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
868       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
869       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
870       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
871       virtual Precedence precedence() const { return PrecMultiplicitave; }
872   private:
873       RefPtr<Node> term1;
874       RefPtr<Node> term2;
875   };
876   
877   class ModNode : public Node {
878   public:
879       ModNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
880       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
881       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
882       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
883       virtual Precedence precedence() const { return PrecMultiplicitave; }
884   private:
885       RefPtr<Node> term1;
886       RefPtr<Node> term2;
887   };
888
889   class AddNode : public Node {
890   public:
891     AddNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
892     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
893     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
894     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
895       virtual Precedence precedence() const { return PrecAdditive; }
896   private:
897     RefPtr<Node> term1;
898     RefPtr<Node> term2;
899   };
900   
901   class SubNode : public Node {
902   public:
903       SubNode(Node *t1, Node *t2) KJS_FAST_CALL : term1(t1), term2(t2) {}
904       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
905       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
906       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
907       virtual Precedence precedence() const { return PrecAdditive; }
908   private:
909       RefPtr<Node> term1;
910       RefPtr<Node> term2;
911   };
912
913   class LeftShiftNode : public Node {
914   public:
915     LeftShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
916       : term1(t1), term2(t2) {}
917     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
918     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
919     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
920     virtual Precedence precedence() const { return PrecShift; }
921   private:
922     RefPtr<Node> term1;
923     RefPtr<Node> term2;
924   };
925
926   class RightShiftNode : public Node {
927   public:
928     RightShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
929       : term1(t1), term2(t2) {}
930     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
931     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
932     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
933     virtual Precedence precedence() const { return PrecShift; }
934   private:
935     RefPtr<Node> term1;
936     RefPtr<Node> term2;
937   };
938
939   class UnsignedRightShiftNode : public Node {
940   public:
941     UnsignedRightShiftNode(Node *t1, Node *t2) KJS_FAST_CALL
942       : term1(t1), term2(t2) {}
943     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
944     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
945     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
946     virtual Precedence precedence() const { return PrecShift; }
947   private:
948     RefPtr<Node> term1;
949     RefPtr<Node> term2;
950   };
951
952   class LessNode : public Node {
953   public:
954     LessNode(Node *e1, Node *e2) KJS_FAST_CALL :
955       expr1(e1), expr2(e2) {}
956     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
957     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
958     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
959     virtual Precedence precedence() const { return PrecRelational; }
960   private:
961     RefPtr<Node> expr1;
962     RefPtr<Node> expr2;
963   };
964
965   class GreaterNode : public Node {
966   public:
967     GreaterNode(Node *e1, Node *e2) KJS_FAST_CALL :
968       expr1(e1), expr2(e2) {}
969     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
970     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
971     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
972     virtual Precedence precedence() const { return PrecRelational; }
973   private:
974     RefPtr<Node> expr1;
975     RefPtr<Node> expr2;
976   };
977
978   class LessEqNode : public Node {
979   public:
980     LessEqNode(Node *e1, Node *e2) KJS_FAST_CALL :
981       expr1(e1), expr2(e2) {}
982     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
983     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
984     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
985     virtual Precedence precedence() const { return PrecRelational; }
986   private:
987     RefPtr<Node> expr1;
988     RefPtr<Node> expr2;
989   };
990
991   class GreaterEqNode : public Node {
992   public:
993     GreaterEqNode(Node *e1, Node *e2) KJS_FAST_CALL :
994       expr1(e1), expr2(e2) {}
995     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
996     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
997     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
998     virtual Precedence precedence() const { return PrecRelational; }
999   private:
1000     RefPtr<Node> expr1;
1001     RefPtr<Node> expr2;
1002   };
1003
1004   class InstanceOfNode : public Node {
1005   public:
1006     InstanceOfNode(Node *e1, Node *e2) KJS_FAST_CALL :
1007       expr1(e1), expr2(e2) {}
1008     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1009     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1010     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1011     virtual Precedence precedence() const { return PrecRelational; }
1012   private:
1013     RefPtr<Node> expr1;
1014     RefPtr<Node> expr2;
1015   };
1016
1017   class InNode : public Node {
1018   public:
1019     InNode(Node *e1, Node *e2) KJS_FAST_CALL :
1020       expr1(e1), expr2(e2) {}
1021     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1022     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1023     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1024     virtual Precedence precedence() const { return PrecRelational; }
1025   private:
1026     RefPtr<Node> expr1;
1027     RefPtr<Node> expr2;
1028   };
1029
1030   class EqualNode : public Node {
1031   public:
1032     EqualNode(Node *e1, Node *e2) KJS_FAST_CALL
1033       : expr1(e1), expr2(e2) {}
1034     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1035     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1036     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1037     virtual Precedence precedence() const { return PrecEquality; }
1038   private:
1039     RefPtr<Node> expr1;
1040     RefPtr<Node> expr2;
1041   };
1042
1043   class NotEqualNode : public Node {
1044   public:
1045     NotEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
1046       : expr1(e1), expr2(e2) {}
1047     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1048     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1049     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1050     virtual Precedence precedence() const { return PrecEquality; }
1051   private:
1052     RefPtr<Node> expr1;
1053     RefPtr<Node> expr2;
1054   };
1055
1056   class StrictEqualNode : public Node {
1057   public:
1058     StrictEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
1059       : expr1(e1), expr2(e2) {}
1060     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1061     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1062     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1063     virtual Precedence precedence() const { return PrecEquality; }
1064   private:
1065     RefPtr<Node> expr1;
1066     RefPtr<Node> expr2;
1067   };
1068
1069   class NotStrictEqualNode : public Node {
1070   public:
1071     NotStrictEqualNode(Node *e1, Node *e2) KJS_FAST_CALL
1072       : expr1(e1), expr2(e2) {}
1073     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1074     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1075     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1076     virtual Precedence precedence() const { return PrecEquality; }
1077   private:
1078     RefPtr<Node> expr1;
1079     RefPtr<Node> expr2;
1080   };
1081
1082   class BitAndNode : public Node {
1083   public:
1084     BitAndNode(Node *e1, Node *e2) KJS_FAST_CALL :
1085       expr1(e1), expr2(e2) {}
1086     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1087     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1088     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1089     virtual Precedence precedence() const { return PrecBitwiseAnd; }
1090   private:
1091     RefPtr<Node> expr1;
1092     RefPtr<Node> expr2;
1093   };
1094
1095   class BitOrNode : public Node {
1096   public:
1097     BitOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
1098       expr1(e1), expr2(e2) {}
1099     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1100     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1101     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1102     virtual Precedence precedence() const { return PrecBitwiseOr; }
1103   private:
1104     RefPtr<Node> expr1;
1105     RefPtr<Node> expr2;
1106   };
1107
1108   class BitXOrNode : public Node {
1109   public:
1110     BitXOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
1111       expr1(e1), expr2(e2) {}
1112     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1113     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1114     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1115     virtual Precedence precedence() const { return PrecBitwiseXor; }
1116   private:
1117     RefPtr<Node> expr1;
1118     RefPtr<Node> expr2;
1119   };
1120
1121   /**
1122    * expr1 && expr2, expr1 || expr2
1123    */
1124   class LogicalAndNode : public Node {
1125   public:
1126     LogicalAndNode(Node *e1, Node *e2) KJS_FAST_CALL :
1127       expr1(e1), expr2(e2) {}
1128     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1129     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1130     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1131     virtual Precedence precedence() const { return PrecLogicalAnd; }
1132   private:
1133     RefPtr<Node> expr1;
1134     RefPtr<Node> expr2;
1135   };
1136   
1137   class LogicalOrNode : public Node {
1138   public:
1139     LogicalOrNode(Node *e1, Node *e2) KJS_FAST_CALL :
1140       expr1(e1), expr2(e2) {}
1141     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1142     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1143     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1144     virtual Precedence precedence() const { return PrecLogicalOr; }
1145   private:
1146     RefPtr<Node> expr1;
1147     RefPtr<Node> expr2;
1148   };
1149
1150   /**
1151    * The ternary operator, "logical ? expr1 : expr2"
1152    */
1153   class ConditionalNode : public Node {
1154   public:
1155     ConditionalNode(Node *l, Node *e1, Node *e2) KJS_FAST_CALL :
1156       logical(l), expr1(e1), expr2(e2) {}
1157     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1158     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1159     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1160     virtual Precedence precedence() const { return PrecConditional; }
1161   private:
1162     RefPtr<Node> logical;
1163     RefPtr<Node> expr1;
1164     RefPtr<Node> expr2;
1165   };
1166
1167   class AssignResolveNode : public Node {
1168   public:
1169     AssignResolveNode(const Identifier &ident, Operator oper, Node *right) KJS_FAST_CALL
1170       : m_ident(ident)
1171       , m_oper(oper)
1172       , m_right(right) 
1173       {
1174       }
1175
1176     AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL 
1177       : Node(PlacementNewAdopt)
1178       , m_ident(PlacementNewAdopt) 
1179       , m_oper(m_oper) 
1180       , m_right(PlacementNewAdopt) 
1181     {
1182     }
1183
1184     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1185     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1186     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1187     virtual Precedence precedence() const { return PrecAssignment; }
1188   protected:
1189     Identifier m_ident;
1190     Operator m_oper;
1191     RefPtr<Node> m_right;
1192     size_t m_index;
1193   };
1194
1195   class AssignLocalAccessNode : public AssignResolveNode {
1196   public:
1197     AssignLocalAccessNode(size_t i) KJS_FAST_CALL 
1198         : AssignResolveNode(PlacementNewAdopt)
1199     { 
1200         ASSERT(i != missingSymbolMarker());
1201         m_index = i;
1202     }
1203     
1204     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1205   };
1206
1207   class AssignBracketNode : public Node {
1208   public:
1209     AssignBracketNode(Node *base, Node *subscript, Operator oper, Node *right) KJS_FAST_CALL
1210       : m_base(base), m_subscript(subscript), m_oper(oper), m_right(right) {}
1211     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1212     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1213     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1214     virtual Precedence precedence() const { return PrecAssignment; }
1215   protected:
1216     RefPtr<Node> m_base;
1217     RefPtr<Node> m_subscript;
1218     Operator m_oper;
1219     RefPtr<Node> m_right;
1220   };
1221
1222   class AssignDotNode : public Node {
1223   public:
1224     AssignDotNode(Node *base, const Identifier& ident, Operator oper, Node *right) KJS_FAST_CALL
1225       : m_base(base), m_ident(ident), m_oper(oper), m_right(right) {}
1226     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1227     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1228     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1229     virtual Precedence precedence() const { return PrecAssignment; }
1230   protected:
1231     RefPtr<Node> m_base;
1232     Identifier m_ident;
1233     Operator m_oper;
1234     RefPtr<Node> m_right;
1235   };
1236
1237   class AssignErrorNode : public Node {
1238   public:
1239     AssignErrorNode(Node* left, Operator oper, Node* right) KJS_FAST_CALL
1240       : m_left(left), m_oper(oper), m_right(right) {}
1241     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1242     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1243     virtual Precedence precedence() const { return PrecAssignment; }
1244   protected:
1245     RefPtr<Node> m_left;
1246     Operator m_oper;
1247     RefPtr<Node> m_right;
1248   };
1249
1250   class CommaNode : public Node {
1251   public:
1252     CommaNode(Node *e1, Node *e2) KJS_FAST_CALL : expr1(e1), expr2(e2) {}
1253     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1254     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1255     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1256     virtual Precedence precedence() const { return PrecExpression; }
1257   private:
1258     RefPtr<Node> expr1;
1259     RefPtr<Node> expr2;
1260   };
1261
1262   class AssignExprNode : public Node {
1263   public:
1264     AssignExprNode(Node *e) KJS_FAST_CALL : expr(e) {}
1265     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1266     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1267     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1268     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1269   private:
1270     RefPtr<Node> expr;
1271   };
1272
1273   class VarDeclNode : public Node {
1274   public:
1275     enum Type { Variable, Constant };
1276     VarDeclNode(const Identifier &id, AssignExprNode *in, Type t) KJS_FAST_CALL;
1277     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1278     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1279     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1280     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1281     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1282     Type varType;
1283     Identifier ident;
1284   private:
1285     JSValue* handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL KJS_NO_INLINE;
1286     RefPtr<AssignExprNode> init;
1287   };
1288
1289   class VarDeclListNode : public Node {
1290   public:
1291     VarDeclListNode(VarDeclNode* v) KJS_FAST_CALL : var(v) { m_mayHaveDeclarations = true; }
1292     VarDeclListNode(VarDeclListNode* l, VarDeclNode* v) KJS_FAST_CALL
1293       : var(v) { l->next = this; m_mayHaveDeclarations = true; }
1294     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1295     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1296     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1297     PassRefPtr<VarDeclListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1298     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1299     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1300   private:
1301     friend class ForNode;
1302     friend class VarStatementNode;
1303     ListRefPtr<VarDeclListNode> next;
1304     RefPtr<VarDeclNode> var;
1305   };
1306
1307   class VarStatementNode : public StatementNode {
1308   public:
1309     VarStatementNode(VarDeclListNode* l) KJS_FAST_CALL : next(l) { m_mayHaveDeclarations = true; }
1310     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1311     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1312     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1313     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1314   private:
1315     RefPtr<VarDeclListNode> next;
1316   };
1317
1318   class BlockNode : public StatementNode {
1319   public:
1320     BlockNode(SourceElementsNode *s) KJS_FAST_CALL;
1321     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1322     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1323     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1324     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1325   protected:
1326     RefPtr<SourceElementsNode> source;
1327   };
1328
1329   class EmptyStatementNode : public StatementNode {
1330   public:
1331     EmptyStatementNode() KJS_FAST_CALL { } // debug
1332     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1333     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1334   };
1335
1336   class ExprStatementNode : public StatementNode {
1337   public:
1338     ExprStatementNode(Node *e) KJS_FAST_CALL : expr(e) { }
1339     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1340     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1341     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1342   private:
1343     RefPtr<Node> expr;
1344   };
1345
1346   class IfNode : public StatementNode {
1347   public:
1348     IfNode(Node *e, StatementNode *s1, StatementNode *s2) KJS_FAST_CALL
1349       : expr(e), statement1(s1), statement2(s2) { m_mayHaveDeclarations = statement1->mayHaveDeclarations() || (statement2 && statement2->mayHaveDeclarations()); }
1350     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1351     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1352     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1353     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1354   private:
1355     RefPtr<Node> expr;
1356     RefPtr<StatementNode> statement1;
1357     RefPtr<StatementNode> statement2;
1358   };
1359
1360   class DoWhileNode : public StatementNode {
1361   public:
1362     DoWhileNode(StatementNode *s, Node *e) KJS_FAST_CALL : statement(s), expr(e) { m_mayHaveDeclarations = true; }
1363     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1364     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1365     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1366     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1367   private:
1368     RefPtr<StatementNode> statement;
1369     RefPtr<Node> expr;
1370   };
1371
1372   class WhileNode : public StatementNode {
1373   public:
1374     WhileNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1375     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1376     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1377     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1378     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1379   private:
1380     RefPtr<Node> expr;
1381     RefPtr<StatementNode> statement;
1382   };
1383
1384   class ForNode : public StatementNode {
1385   public:
1386     ForNode(Node* e1, Node* e2, Node* e3, StatementNode* s) KJS_FAST_CALL :
1387       expr1(e1), expr2(e2), expr3(e3), statement(s) { m_mayHaveDeclarations = true; }
1388     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1389     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1390     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1391     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1392   private:
1393     RefPtr<Node> expr1;
1394     RefPtr<Node> expr2;
1395     RefPtr<Node> expr3;
1396     RefPtr<StatementNode> statement;
1397   };
1398
1399   class ForInNode : public StatementNode {
1400   public:
1401     ForInNode(Node *l, Node *e, StatementNode *s) KJS_FAST_CALL;
1402     ForInNode(const Identifier &i, AssignExprNode *in, Node *e, StatementNode *s) KJS_FAST_CALL;
1403     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1404     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1405     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1406     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1407   private:
1408     Identifier ident;
1409     RefPtr<AssignExprNode> init;
1410     RefPtr<Node> lexpr;
1411     RefPtr<Node> expr;
1412     RefPtr<VarDeclNode> varDecl;
1413     RefPtr<StatementNode> statement;
1414   };
1415
1416   class ContinueNode : public StatementNode {
1417   public:
1418     ContinueNode() KJS_FAST_CALL { }
1419     ContinueNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1420     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1421     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1422   private:
1423     Identifier ident;
1424   };
1425
1426   class BreakNode : public StatementNode {
1427   public:
1428     BreakNode() KJS_FAST_CALL { }
1429     BreakNode(const Identifier &i) KJS_FAST_CALL : ident(i) { }
1430     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1431     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1432   private:
1433     Identifier ident;
1434   };
1435
1436   class ReturnNode : public StatementNode {
1437   public:
1438     ReturnNode(Node *v) KJS_FAST_CALL : value(v) {}
1439     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1440     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1441     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1442   private:
1443     RefPtr<Node> value;
1444   };
1445
1446   class WithNode : public StatementNode {
1447   public:
1448     WithNode(Node *e, StatementNode *s) KJS_FAST_CALL : expr(e), statement(s) { m_mayHaveDeclarations = true; }
1449     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1450     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1451     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1452     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1453   private:
1454     RefPtr<Node> expr;
1455     RefPtr<StatementNode> statement;
1456   };
1457
1458   class LabelNode : public StatementNode {
1459   public:
1460     LabelNode(const Identifier &l, StatementNode *s) KJS_FAST_CALL : label(l), statement(s) { m_mayHaveDeclarations = true; }
1461     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1462     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1463     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1464     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1465   private:
1466     Identifier label;
1467     RefPtr<StatementNode> statement;
1468   };
1469
1470   class ThrowNode : public StatementNode {
1471   public:
1472     ThrowNode(Node *e) KJS_FAST_CALL : expr(e) {}
1473     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1474     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1475     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1476   private:
1477     RefPtr<Node> expr;
1478   };
1479
1480   class TryNode : public StatementNode {
1481   public:
1482     TryNode(StatementNode *b, const Identifier &e, StatementNode *c, StatementNode *f) KJS_FAST_CALL
1483       : tryBlock(b), exceptionIdent(e), catchBlock(c), finallyBlock(f) { m_mayHaveDeclarations = true; }
1484     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1485     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1486     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1487     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1488   private:
1489     RefPtr<StatementNode> tryBlock;
1490     Identifier exceptionIdent;
1491     RefPtr<StatementNode> catchBlock;
1492     RefPtr<StatementNode> finallyBlock;
1493   };
1494
1495   class ParameterNode : public Node {
1496   public:
1497     ParameterNode(const Identifier& i) KJS_FAST_CALL : id(i) { }
1498     ParameterNode(ParameterNode* l, const Identifier& i) KJS_FAST_CALL
1499       : id(i) { l->next = this; }
1500     JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1501     Identifier ident() KJS_FAST_CALL { return id; }
1502     ParameterNode *nextParam() KJS_FAST_CALL { return next.get(); }
1503     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1504     PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1505     virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1506   private:
1507     friend class FuncDeclNode;
1508     friend class FuncExprNode;
1509     Identifier id;
1510     ListRefPtr<ParameterNode> next;
1511   };
1512
1513   // inherited by ProgramNode
1514   class FunctionBodyNode : public BlockNode {
1515   public:
1516     FunctionBodyNode(SourceElementsNode *) KJS_FAST_CALL;
1517     int sourceId() KJS_FAST_CALL { return m_sourceId; }
1518     const UString& sourceURL() KJS_FAST_CALL { return m_sourceURL; }
1519
1520     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1521     
1522     SymbolTable& symbolTable() { return m_symbolTable; }
1523
1524     void addParam(const Identifier& ident) KJS_FAST_CALL;
1525     size_t numParams() const KJS_FAST_CALL { return m_parameters.size(); }
1526     Identifier paramName(size_t pos) const KJS_FAST_CALL { return m_parameters[pos]; }
1527     UString paramString() const KJS_FAST_CALL;
1528     Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
1529     ALWAYS_INLINE void processDeclarations(ExecState*);
1530     ALWAYS_INLINE void processDeclarationsForFunctionCode(ExecState*);
1531     ALWAYS_INLINE void processDeclarationsForProgramCode(ExecState*);
1532   private:
1533     UString m_sourceURL;
1534     int m_sourceId;
1535
1536     void initializeDeclarationStacks(ExecState*);
1537     bool m_initializedDeclarationStacks;
1538
1539     void initializeSymbolTable();
1540     bool m_initializedSymbolTable;
1541     
1542     void optimizeVariableAccess();
1543     bool m_optimizedResolveNodes;
1544     
1545     // Properties that will go into the ActivationImp's local storage. (Used for initializing the ActivationImp.)
1546     DeclarationStacks::VarStack m_varStack;
1547     DeclarationStacks::FunctionStack m_functionStack;
1548     Vector<Identifier> m_parameters;
1549
1550     // Mapping from property name -> local storage index. (Used once to transform the AST, and subsequently for residual slow case lookups.)
1551     SymbolTable m_symbolTable;
1552   };
1553
1554   class FuncExprNode : public Node {
1555   public:
1556     FuncExprNode(const Identifier& i, FunctionBodyNode* b, ParameterNode* p = 0) KJS_FAST_CALL 
1557       : ident(i), param(p), body(b) { addParams(); }
1558     virtual JSValue *evaluate(ExecState*) KJS_FAST_CALL;
1559     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1560     virtual Precedence precedence() const { return PrecMember; }
1561   private:
1562     void addParams() KJS_FAST_CALL;
1563     // Used for streamTo
1564     friend class PropertyNode;
1565     Identifier ident;
1566     RefPtr<ParameterNode> param;
1567     RefPtr<FunctionBodyNode> body;
1568   };
1569
1570   class FuncDeclNode : public StatementNode {
1571   public:
1572     FuncDeclNode(const Identifier& i, FunctionBodyNode* b) KJS_FAST_CALL
1573       : ident(i), body(b) { addParams(); m_mayHaveDeclarations = true; }
1574     FuncDeclNode(const Identifier& i, ParameterNode* p, FunctionBodyNode* b) KJS_FAST_CALL
1575       : ident(i), param(p), body(b) { addParams(); m_mayHaveDeclarations = true; }
1576     virtual Completion execute(ExecState*) KJS_FAST_CALL;
1577     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1578     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1579     ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
1580     Identifier ident;
1581   private:
1582     void addParams() KJS_FAST_CALL;
1583     RefPtr<ParameterNode> param;
1584     RefPtr<FunctionBodyNode> body;
1585   };
1586
1587   // A linked list of source element nodes
1588   class SourceElementsNode : public StatementNode {
1589   public:
1590     static int count;
1591     SourceElementsNode(StatementNode*) KJS_FAST_CALL;
1592     SourceElementsNode(SourceElementsNode*, StatementNode*) KJS_FAST_CALL;
1593     
1594     virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1595     Completion execute(ExecState*) KJS_FAST_CALL;
1596     virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1597     PassRefPtr<SourceElementsNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1598     virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1599   private:
1600     friend class BlockNode;
1601     friend class CaseClauseNode;
1602     RefPtr<StatementNode> node;
1603     ListRefPtr<SourceElementsNode> next;
1604   };
1605
1606   class CaseClauseNode : public Node {
1607   public:
1608       CaseClauseNode(Node *e) KJS_FAST_CALL : expr(e) { m_mayHaveDeclarations = true; }
1609       CaseClauseNode(Node *e, SourceElementsNode *s) KJS_FAST_CALL
1610       : expr(e), source(s) { m_mayHaveDeclarations = true; }
1611       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1612       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1613       Completion evalStatements(ExecState*) KJS_FAST_CALL;
1614       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1615       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1616       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1617   private:
1618       RefPtr<Node> expr;
1619       RefPtr<SourceElementsNode> source;
1620   };
1621   
1622   class ClauseListNode : public Node {
1623   public:
1624       ClauseListNode(CaseClauseNode* c) KJS_FAST_CALL : clause(c) { m_mayHaveDeclarations = true; }
1625       ClauseListNode(ClauseListNode* n, CaseClauseNode* c) KJS_FAST_CALL
1626       : clause(c) { n->next = this; m_mayHaveDeclarations = true; }
1627       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1628       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1629       CaseClauseNode *getClause() const KJS_FAST_CALL { return clause.get(); }
1630       ClauseListNode *getNext() const KJS_FAST_CALL { return next.get(); }
1631       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1632       PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return next.release(); }
1633       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1634       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1635   private:
1636       friend class CaseBlockNode;
1637       RefPtr<CaseClauseNode> clause;
1638       ListRefPtr<ClauseListNode> next;
1639   };
1640   
1641   class CaseBlockNode : public Node {
1642   public:
1643       CaseBlockNode(ClauseListNode* l1, CaseClauseNode* d, ClauseListNode* l2) KJS_FAST_CALL;
1644       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1645       JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1646       Completion evalBlock(ExecState *exec, JSValue *input) KJS_FAST_CALL;
1647       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1648       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1649       virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1650   private:
1651       RefPtr<ClauseListNode> list1;
1652       RefPtr<CaseClauseNode> def;
1653       RefPtr<ClauseListNode> list2;
1654   };
1655   
1656   class SwitchNode : public StatementNode {
1657   public:
1658       SwitchNode(Node *e, CaseBlockNode *b) KJS_FAST_CALL : expr(e), block(b) { m_mayHaveDeclarations = true; }
1659       virtual void optimizeVariableAccess(FunctionBodyNode*, DeclarationStacks::NodeStack&) KJS_FAST_CALL;
1660       virtual Completion execute(ExecState*) KJS_FAST_CALL;
1661       virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1662       virtual void getDeclarations(DeclarationStacks&) KJS_FAST_CALL;
1663   private:
1664       RefPtr<Node> expr;
1665       RefPtr<CaseBlockNode> block;
1666   };
1667   
1668   class ProgramNode : public FunctionBodyNode {
1669   public:
1670     ProgramNode(SourceElementsNode* s) KJS_FAST_CALL;
1671   };
1672
1673 } // namespace
1674
1675 #endif