Optimise multi-scope function call resolution
[WebKit-https.git] / JavaScriptCore / kjs / nodes.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
5  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6  *  Copyright (C) 2007 Maks Orlovich
7  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Library General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Library General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Library General Public License
20  *  along with this library; see the file COPYING.LIB.  If not, write to
21  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301, USA.
23  *
24  */
25
26 #ifndef NODES_H_
27 #define NODES_H_
28
29 #include "internal.h"
30 #include "regexp.h"
31 #include "SymbolTable.h"
32 #include <wtf/ListRefPtr.h>
33 #include <wtf/MathExtras.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 namespace KJS {
44
45     class ArgumentsNode;
46     class ConstDeclNode;
47     class FuncDeclNode;
48     class Node;
49     class PropertyListNode;
50     class SourceStream;
51
52     enum Operator {
53         OpEqual,
54         OpPlusEq,
55         OpMinusEq,
56         OpMultEq,
57         OpDivEq,
58         OpPlusPlus,
59         OpMinusMinus,
60         OpAndEq,
61         OpXOrEq,
62         OpOrEq,
63         OpModEq,
64         OpLShift,
65         OpRShift,
66         OpURShift,
67     };
68
69     enum Precedence {
70         PrecPrimary,
71         PrecMember,
72         PrecCall,
73         PrecLeftHandSide,
74         PrecPostfix,
75         PrecUnary,
76         PrecMultiplicitave,
77         PrecAdditive,
78         PrecShift,
79         PrecRelational,
80         PrecEquality,
81         PrecBitwiseAnd,
82         PrecBitwiseXor,
83         PrecBitwiseOr,
84         PrecLogicalAnd,
85         PrecLogicalOr,
86         PrecConditional,
87         PrecAssignment,
88         PrecExpression
89     };
90
91     struct DeclarationStacks {
92         typedef Vector<Node*, 16> NodeStack;
93         enum { IsConstant = 1, HasInitializer = 2 } VarAttrs;
94         typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
95         typedef Vector<FuncDeclNode*, 16> FunctionStack;
96
97         DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
98             : exec(e)
99             , nodeStack(n)
100             , varStack(v)
101             , functionStack(f)
102         {
103         }
104
105         ExecState* exec;
106         NodeStack& nodeStack;
107         VarStack& varStack;
108         FunctionStack& functionStack;
109     };
110
111     class ParserRefCounted : Noncopyable {
112     protected:
113         ParserRefCounted() KJS_FAST_CALL;
114         ParserRefCounted(PlacementNewAdoptType) KJS_FAST_CALL
115         {
116         }
117
118     public:
119         void ref() KJS_FAST_CALL;
120         void deref() KJS_FAST_CALL;
121         unsigned refcount() KJS_FAST_CALL;
122
123         static void deleteNewObjects() KJS_FAST_CALL;
124
125         virtual ~ParserRefCounted();
126     };
127
128     class Node : public ParserRefCounted {
129     public:
130         typedef DeclarationStacks::NodeStack NodeStack;
131         typedef DeclarationStacks::VarStack VarStack;
132         typedef DeclarationStacks::FunctionStack FunctionStack;
133
134         Node() KJS_FAST_CALL;
135         Node(PlacementNewAdoptType placementAdopt) KJS_FAST_CALL
136             : ParserRefCounted(placementAdopt)
137         {
138         }
139
140         UString toString() const KJS_FAST_CALL;
141         int lineNo() const KJS_FAST_CALL { return m_line; }
142
143         // Serialization.
144         virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
145         virtual Precedence precedence() const = 0;
146         virtual bool needsParensIfLeftmost() const { return false; }
147
148         // Used for iterative, depth-first traversal of the node tree. Does not cross function call boundaries.
149         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL { }
150
151     protected:
152         Node(JSType) KJS_FAST_CALL; // used by ExpressionNode
153
154         // for use in execute()
155         JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
156         JSValue* setErrorCompletion(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
157
158         // for use in evaluate()
159         JSValue* throwError(ExecState*, ErrorType, const char* msg) KJS_FAST_CALL;
160         JSValue* throwError(ExecState*, ErrorType, const char* msg, const char*) KJS_FAST_CALL;
161         JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*) KJS_FAST_CALL;
162         JSValue* throwError(ExecState*, ErrorType, const char* msg, const Identifier&) KJS_FAST_CALL;
163         JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, const Identifier&) KJS_FAST_CALL;
164         JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, Node*) KJS_FAST_CALL;
165         JSValue* throwError(ExecState*, ErrorType, const char* msg, JSValue*, Node*, const Identifier&) KJS_FAST_CALL;
166
167         JSValue* throwUndefinedVariableError(ExecState*, const Identifier&) KJS_FAST_CALL;
168
169         void handleException(ExecState*) KJS_FAST_CALL;
170         void handleException(ExecState*, JSValue*) KJS_FAST_CALL;
171
172         // for use in execute()
173         JSValue* rethrowException(ExecState*) KJS_FAST_CALL;
174
175         int m_line : 28;
176         unsigned m_expectedReturnType : 3; // JSType
177     };
178
179     class ExpressionNode : public Node {
180     public:
181         ExpressionNode() KJS_FAST_CALL : Node() {}
182         ExpressionNode(JSType expectedReturn) KJS_FAST_CALL
183             : Node(expectedReturn)
184         {
185         }
186
187         // Special constructor for cases where we overwrite an object in place.
188         ExpressionNode(PlacementNewAdoptType) KJS_FAST_CALL
189             : Node(PlacementNewAdopt)
190         {
191         }
192
193         virtual bool isNumber() const KJS_FAST_CALL { return false; }
194         virtual bool isLocation() const KJS_FAST_CALL { return false; }
195         virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
196         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
197         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
198
199         JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
200
201         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL = 0;
202         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
203         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
204         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
205         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
206
207         // Used to optimize those nodes that do extra work when returning a result, even if the result has no semantic relevance
208         virtual void optimizeForUnnecessaryResult() { }
209
210     protected:
211         typedef enum { EvalOperator, FunctionCall } CallerType;
212         template <CallerType, bool> inline JSValue* resolveAndCall(ExecState*, const Identifier&, ArgumentsNode*, size_t = 0);
213     };
214
215     class StatementNode : public Node {
216     public:
217         StatementNode() KJS_FAST_CALL;
218         void setLoc(int line0, int line1) KJS_FAST_CALL;
219         int firstLine() const KJS_FAST_CALL { return lineNo(); }
220         int lastLine() const KJS_FAST_CALL { return m_lastLine; }
221         virtual JSValue* execute(ExecState *exec) KJS_FAST_CALL = 0;
222         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
223         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
224         virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
225
226     protected:
227         LabelStack m_labelStack;
228
229     private:
230         int m_lastLine;
231     };
232
233     class NullNode : public ExpressionNode {
234     public:
235         NullNode() KJS_FAST_CALL : ExpressionNode(NullType) {}
236         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
237         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
238         virtual Precedence precedence() const { return PrecPrimary; }
239     };
240
241     class FalseNode : public ExpressionNode {
242     public:
243         FalseNode() KJS_FAST_CALL
244             : ExpressionNode(BooleanType)
245         {
246         }
247
248         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
249         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return false; }
250         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
251         virtual Precedence precedence() const { return PrecPrimary; }
252     };
253
254     class TrueNode : public ExpressionNode {
255     public:
256         TrueNode() KJS_FAST_CALL
257             : ExpressionNode(BooleanType)
258         {
259         }
260
261         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
262         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL { return true; }
263         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
264         virtual Precedence precedence() const { return PrecPrimary; }
265     };
266
267     class PlaceholderTrueNode : public TrueNode {
268     public:
269         // Like TrueNode, but does not serialize as "true".
270         PlaceholderTrueNode() KJS_FAST_CALL
271             : TrueNode()
272         {
273         }
274
275         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
276     };
277
278     class NumberNode : public ExpressionNode {
279     public:
280         NumberNode(double v) KJS_FAST_CALL
281             : ExpressionNode(NumberType)
282             , m_double(v)
283         {
284         }
285
286         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
287         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
288         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
289         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
290         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
291         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
292         virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
293
294         virtual bool isNumber() const KJS_FAST_CALL { return true; }
295         double value() const KJS_FAST_CALL { return m_double; }
296         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
297
298     protected:
299         double m_double;
300     };
301
302     class ImmediateNumberNode : public NumberNode {
303     public:
304         ImmediateNumberNode(JSValue* v, double d) KJS_FAST_CALL
305             : NumberNode(d)
306             , m_value(v)
307         {
308             ASSERT(v == JSImmediate::from(d));
309         }
310
311         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
312         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
313         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
314
315         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
316
317     private:
318         JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
319     };
320
321     class StringNode : public ExpressionNode {
322     public:
323         StringNode(const UString* v) KJS_FAST_CALL
324             : ExpressionNode(StringType)
325             , m_value(*v)
326         {
327         }
328
329         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
330         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
331         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
332         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
333         virtual Precedence precedence() const { return PrecPrimary; }
334
335     private:
336         UString m_value;
337     };
338
339     class RegExpNode : public ExpressionNode {
340     public:
341         RegExpNode(const UString& pattern, const UString& flags) KJS_FAST_CALL
342             : m_regExp(RegExp::create(pattern, flags))
343         {
344         }
345
346         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
347         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
348         virtual Precedence precedence() const { return PrecPrimary; }
349
350     private:
351         RefPtr<RegExp> m_regExp;
352     };
353
354     class ThisNode : public ExpressionNode {
355     public:
356         ThisNode() KJS_FAST_CALL
357         {
358         }
359
360         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
361         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
362         virtual Precedence precedence() const { return PrecPrimary; }
363     };
364
365     class ResolveNode : public ExpressionNode {
366     public:
367         ResolveNode(const Identifier& ident) KJS_FAST_CALL
368             : m_ident(ident)
369         {
370         }
371
372         // Special constructor for cases where we overwrite an object in place.
373         ResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
374             : ExpressionNode(PlacementNewAdopt)
375             , m_ident(PlacementNewAdopt)
376         {
377         }
378
379         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
380
381         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
382         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
383         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
384         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
385         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
386         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
387         virtual Precedence precedence() const { return PrecPrimary; }
388
389         virtual bool isLocation() const KJS_FAST_CALL { return true; }
390         virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
391         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
392
393     protected:
394         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
395         Identifier m_ident;
396         size_t m_index; // Used by LocalVarAccessNode and ScopedVarAccessNode.
397         size_t m_scopeDepth; // Used by ScopedVarAccessNode
398     };
399
400     class LocalVarAccessNode : public ResolveNode {
401     public:
402         // Overwrites a ResolveNode in place.
403         LocalVarAccessNode(size_t i) KJS_FAST_CALL
404             : ResolveNode(PlacementNewAdopt)
405         {
406             ASSERT(i != missingSymbolMarker());
407             m_index = i;
408         }
409
410         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
411         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
412         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
413         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
414         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
415
416     private:
417         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
418     };
419     
420     class ScopedVarAccessNode : public ResolveNode {
421     public:
422         // Overwrites a ResolveNode in place.
423         ScopedVarAccessNode(size_t i, size_t scopeDepth) KJS_FAST_CALL
424         : ResolveNode(PlacementNewAdopt)
425         {
426             ASSERT(i != missingSymbolMarker());
427             m_index = i;
428             m_scopeDepth = scopeDepth;
429         }
430         
431         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
432         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
433         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
434         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
435         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
436         
437     private:
438         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
439     };
440     
441     class NonLocalVarAccessNode : public ResolveNode {
442     public:
443         // Overwrites a ResolveNode in place.
444         NonLocalVarAccessNode(size_t scopeDepth) KJS_FAST_CALL
445         : ResolveNode(PlacementNewAdopt)
446         {
447             ASSERT(scopeDepth != 0);
448             m_scopeDepth = scopeDepth;
449         }
450         
451         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
452         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
453         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
454         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
455         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
456         
457     private:
458         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
459     };
460
461     class ElementNode : public Node {
462     public:
463         ElementNode(int elision, ExpressionNode* node) KJS_FAST_CALL
464             : m_elision(elision)
465             , m_node(node)
466         {
467         }
468
469         ElementNode(ElementNode* l, int elision, ExpressionNode* node) KJS_FAST_CALL
470             : m_elision(elision)
471             , m_node(node)
472         {
473             l->m_next = this;
474         }
475
476         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
477         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
478         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
479
480         PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
481
482         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
483
484     private:
485         friend class ArrayNode;
486         ListRefPtr<ElementNode> m_next;
487         int m_elision;
488         RefPtr<ExpressionNode> m_node;
489     };
490
491     class ArrayNode : public ExpressionNode {
492     public:
493         ArrayNode(int elision) KJS_FAST_CALL
494             : m_elision(elision)
495             , m_optional(true)
496         {
497         }
498
499         ArrayNode(ElementNode* element) KJS_FAST_CALL
500             : m_element(element)
501             , m_elision(0)
502             , m_optional(false)
503         {
504         }
505
506         ArrayNode(int elision, ElementNode* element) KJS_FAST_CALL
507             : m_element(element)
508             , m_elision(elision)
509             , m_optional(true)
510         {
511         }
512
513         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
514         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
515         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
516         virtual Precedence precedence() const { return PrecPrimary; }
517
518     private:
519         RefPtr<ElementNode> m_element;
520         int m_elision;
521         bool m_optional;
522     };
523
524     class PropertyNode : public Node {
525     public:
526         enum Type { Constant, Getter, Setter };
527
528         PropertyNode(const Identifier& name, ExpressionNode* assign, Type type) KJS_FAST_CALL
529             : m_name(name)
530             , m_assign(assign)
531             , m_type(type)
532         {
533         }
534
535         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
536         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
537         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
538
539         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
540         const Identifier& name() const { return m_name; }
541
542     private:
543         friend class PropertyListNode;
544         Identifier m_name;
545         RefPtr<ExpressionNode> m_assign;
546         Type m_type;
547     };
548
549     class PropertyListNode : public Node {
550     public:
551         PropertyListNode(PropertyNode* node) KJS_FAST_CALL
552             : m_node(node)
553         {
554         }
555
556         PropertyListNode(PropertyNode* node, PropertyListNode* list) KJS_FAST_CALL
557             : m_node(node)
558         {
559             list->m_next = this;
560         }
561
562         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
563         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
564         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
565
566         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
567         PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
568
569     private:
570         friend class ObjectLiteralNode;
571         RefPtr<PropertyNode> m_node;
572         ListRefPtr<PropertyListNode> m_next;
573     };
574
575     class ObjectLiteralNode : public ExpressionNode {
576     public:
577         ObjectLiteralNode() KJS_FAST_CALL
578         {
579         }
580
581         ObjectLiteralNode(PropertyListNode* list) KJS_FAST_CALL
582             : m_list(list)
583         {
584         }
585
586         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
587         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
588         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
589         virtual Precedence precedence() const { return PrecPrimary; }
590         virtual bool needsParensIfLeftmost() const { return true; }
591
592     private:
593         RefPtr<PropertyListNode> m_list;
594     };
595
596     class BracketAccessorNode : public ExpressionNode {
597     public:
598         BracketAccessorNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
599             : m_base(base)
600             , m_subscript(subscript)
601         {
602         }
603
604         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
605         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
606         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
607         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
608         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
609         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
610         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
611         virtual Precedence precedence() const { return PrecMember; }
612
613         virtual bool isLocation() const KJS_FAST_CALL { return true; }
614         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
615         ExpressionNode* base() KJS_FAST_CALL { return m_base.get(); }
616         ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); }
617
618     private:
619         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
620
621         RefPtr<ExpressionNode> m_base;
622         RefPtr<ExpressionNode> m_subscript;
623     };
624
625     class DotAccessorNode : public ExpressionNode {
626     public:
627         DotAccessorNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
628             : m_base(base)
629             , m_ident(ident)
630         {
631         }
632
633         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
634         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
635         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
636         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
637         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
638         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
639         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
640         virtual Precedence precedence() const { return PrecMember; }
641
642         virtual bool isLocation() const KJS_FAST_CALL { return true; }
643         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
644         ExpressionNode* base() const KJS_FAST_CALL { return m_base.get(); }
645         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
646
647     private:
648         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
649
650         RefPtr<ExpressionNode> m_base;
651         Identifier m_ident;
652     };
653
654     class ArgumentListNode : public Node {
655     public:
656         ArgumentListNode(ExpressionNode* expr) KJS_FAST_CALL
657             : m_expr(expr)
658         {
659         }
660
661         ArgumentListNode(ArgumentListNode* listNode, ExpressionNode* expr) KJS_FAST_CALL
662             : m_expr(expr)
663         {
664             listNode->m_next = this;
665         }
666
667         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
668         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
669         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
670
671         void evaluateList(ExecState*, List&) KJS_FAST_CALL;
672         PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
673
674     private:
675         friend class ArgumentsNode;
676         ListRefPtr<ArgumentListNode> m_next;
677         RefPtr<ExpressionNode> m_expr;
678     };
679
680     class ArgumentsNode : public Node {
681     public:
682         ArgumentsNode() KJS_FAST_CALL
683         {
684         }
685
686         ArgumentsNode(ArgumentListNode* listNode) KJS_FAST_CALL
687             : m_listNode(listNode)
688         {
689         }
690
691         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
692         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
693         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
694
695         void evaluateList(ExecState* exec, List& list) KJS_FAST_CALL { if (m_listNode) m_listNode->evaluateList(exec, list); }
696
697     private:
698         RefPtr<ArgumentListNode> m_listNode;
699     };
700
701     class NewExprNode : public ExpressionNode {
702     public:
703         NewExprNode(ExpressionNode* expr) KJS_FAST_CALL
704             : m_expr(expr)
705         {
706         }
707
708         NewExprNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL
709             : m_expr(expr)
710             , m_args(args)
711         {
712         }
713
714         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
715         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
716         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
717         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
718         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
719         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
720         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
721         virtual Precedence precedence() const { return PrecLeftHandSide; }
722
723     private:
724         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
725
726         RefPtr<ExpressionNode> m_expr;
727         RefPtr<ArgumentsNode> m_args;
728     };
729
730     class EvalFunctionCallNode : public ExpressionNode {
731     public:
732         EvalFunctionCallNode(ArgumentsNode* args) KJS_FAST_CALL
733             : m_args(args)
734         {
735         }
736
737         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
738         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
739         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
740         virtual Precedence precedence() const { return PrecCall; }
741
742     private:
743         RefPtr<ArgumentsNode> m_args;
744     };
745
746     class FunctionCallValueNode : public ExpressionNode {
747     public:
748         FunctionCallValueNode(ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL
749             : m_expr(expr)
750             , m_args(args)
751         {
752         }
753
754         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
755         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
756         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
757         virtual Precedence precedence() const { return PrecCall; }
758
759     private:
760         RefPtr<ExpressionNode> m_expr;
761         RefPtr<ArgumentsNode> m_args;
762     };
763
764     class FunctionCallResolveNode : public ExpressionNode {
765     public:
766         FunctionCallResolveNode(const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL
767             : m_ident(ident)
768             , m_args(args)
769         {
770         }
771
772         FunctionCallResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
773             : ExpressionNode(PlacementNewAdopt)
774             , m_ident(PlacementNewAdopt)
775             , m_args(PlacementNewAdopt)
776         {
777         }
778
779         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
780         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
781         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
782         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
783         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
784         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
785         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
786         virtual Precedence precedence() const { return PrecCall; }
787
788     protected:
789         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
790
791         Identifier m_ident;
792         RefPtr<ArgumentsNode> m_args;
793         size_t m_index; // Used by LocalVarFunctionCallNode.
794         size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
795     };
796     
797     class LocalVarFunctionCallNode : public FunctionCallResolveNode {
798     public:
799         LocalVarFunctionCallNode(size_t i) KJS_FAST_CALL
800             : FunctionCallResolveNode(PlacementNewAdopt)
801         {
802             ASSERT(i != missingSymbolMarker());
803             m_index = i;
804         }
805         
806         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
807         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
808         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
809         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
810         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
811         
812     private:
813         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
814     };
815     
816     class ScopedVarFunctionCallNode : public FunctionCallResolveNode {
817     public:
818         ScopedVarFunctionCallNode(size_t i, size_t depth) KJS_FAST_CALL
819             : FunctionCallResolveNode(PlacementNewAdopt)
820         {
821             ASSERT(i != missingSymbolMarker());
822             m_index = i;
823             m_scopeDepth = depth;
824         }
825         
826         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
827         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
828         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
829         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
830         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
831         
832     private:
833         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
834     };
835     
836     class NonLocalVarFunctionCallNode : public FunctionCallResolveNode {
837     public:
838         NonLocalVarFunctionCallNode(size_t depth) KJS_FAST_CALL
839             : FunctionCallResolveNode(PlacementNewAdopt)
840         {
841             m_scopeDepth = depth;
842         }
843         
844         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
845         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
846         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
847         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
848         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
849         
850     private:
851         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
852     };
853
854     class FunctionCallBracketNode : public ExpressionNode {
855     public:
856         FunctionCallBracketNode(ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args) KJS_FAST_CALL
857             : m_base(base)
858             , m_subscript(subscript)
859             , m_args(args)
860         {
861         }
862
863         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
864         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
865         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
866         virtual Precedence precedence() const { return PrecCall; }
867
868     protected:
869         RefPtr<ExpressionNode> m_base;
870         RefPtr<ExpressionNode> m_subscript;
871         RefPtr<ArgumentsNode> m_args;
872     };
873
874     class FunctionCallDotNode : public ExpressionNode {
875     public:
876         FunctionCallDotNode(ExpressionNode* base, const Identifier& ident, ArgumentsNode* args) KJS_FAST_CALL
877             : m_base(base)
878             , m_ident(ident)
879             , m_args(args)
880         {
881         }
882
883         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
884         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
885         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
886         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
887         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
888         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
889         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
890         virtual Precedence precedence() const { return PrecCall; }
891
892     private:
893         ALWAYS_INLINE JSValue* inlineEvaluate(ExecState*);
894
895         RefPtr<ExpressionNode> m_base;
896         Identifier m_ident;
897         RefPtr<ArgumentsNode> m_args;
898     };
899
900     class PrePostResolveNode : public ExpressionNode {
901     public:
902         PrePostResolveNode(const Identifier& ident) KJS_FAST_CALL
903             : ExpressionNode(NumberType)
904             , m_ident(ident)
905         {
906         }
907
908         PrePostResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
909             : ExpressionNode(PlacementNewAdopt)
910             , m_ident(PlacementNewAdopt)
911         {
912         }
913
914     protected:
915         Identifier m_ident;
916         size_t m_index; // Used by LocalVarPostfixNode.
917     };
918
919     class PostIncResolveNode : public PrePostResolveNode {
920     public:
921         PostIncResolveNode(const Identifier& ident) KJS_FAST_CALL
922             : PrePostResolveNode(ident)
923         {
924         }
925
926         PostIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
927             : PrePostResolveNode(PlacementNewAdopt)
928         {
929         }
930
931         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
932         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
933         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
934         virtual Precedence precedence() const { return PrecPostfix; }
935         virtual void optimizeForUnnecessaryResult();
936     };
937
938     class PostIncLocalVarNode : public PostIncResolveNode {
939     public:
940         PostIncLocalVarNode(size_t i) KJS_FAST_CALL
941             : PostIncResolveNode(PlacementNewAdopt)
942         {
943             ASSERT(i != missingSymbolMarker());
944             m_index = i;
945         }
946
947         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
948         virtual void optimizeForUnnecessaryResult();
949     };
950
951     class PostIncConstNode : public PostIncResolveNode {
952     public:
953         PostIncConstNode(size_t i) KJS_FAST_CALL
954             : PostIncResolveNode(PlacementNewAdopt)
955         {
956             ASSERT(i != missingSymbolMarker());
957             m_index = i;
958         }
959
960         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
961     };
962
963     class PostDecResolveNode : public PrePostResolveNode {
964     public:
965         PostDecResolveNode(const Identifier& ident) KJS_FAST_CALL
966             : PrePostResolveNode(ident)
967         {
968         }
969
970         PostDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
971             : PrePostResolveNode(PlacementNewAdopt)
972         {
973         }
974
975         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
976         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
977         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
978         virtual Precedence precedence() const { return PrecPostfix; }
979         virtual void optimizeForUnnecessaryResult();
980     };
981
982     class PostDecLocalVarNode : public PostDecResolveNode {
983     public:
984         PostDecLocalVarNode(size_t i) KJS_FAST_CALL
985             : PostDecResolveNode(PlacementNewAdopt)
986         {
987             ASSERT(i != missingSymbolMarker());
988             m_index = i;
989         }
990
991         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
992         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
993         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
994         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
995         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
996         virtual void optimizeForUnnecessaryResult();
997
998     private:
999         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1000     };
1001
1002     class PostDecConstNode : public PostDecResolveNode {
1003     public:
1004         PostDecConstNode(size_t i) KJS_FAST_CALL
1005             : PostDecResolveNode(PlacementNewAdopt)
1006         {
1007             ASSERT(i != missingSymbolMarker());
1008             m_index = i;
1009         }
1010
1011         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1012     };
1013
1014     class PostfixBracketNode : public ExpressionNode {
1015     public:
1016         PostfixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1017             : m_base(base)
1018             , m_subscript(subscript)
1019         {
1020         }
1021
1022         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1023         virtual Precedence precedence() const { return PrecPostfix; }
1024
1025     protected:
1026         RefPtr<ExpressionNode> m_base;
1027         RefPtr<ExpressionNode> m_subscript;
1028     };
1029
1030     class PostIncBracketNode : public PostfixBracketNode {
1031     public:
1032         PostIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1033             : PostfixBracketNode(base, subscript)
1034         {
1035         }
1036
1037         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1038         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1039     };
1040
1041     class PostDecBracketNode : public PostfixBracketNode {
1042     public:
1043         PostDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1044             : PostfixBracketNode(base, subscript)
1045         {
1046         }
1047
1048         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1049         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1050     };
1051
1052     class PostfixDotNode : public ExpressionNode {
1053     public:
1054         PostfixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1055             : m_base(base)
1056             , m_ident(ident)
1057         {
1058         }
1059
1060         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1061         virtual Precedence precedence() const { return PrecPostfix; }
1062
1063     protected:
1064         RefPtr<ExpressionNode> m_base;
1065         Identifier m_ident;
1066     };
1067
1068     class PostIncDotNode : public PostfixDotNode {
1069     public:
1070         PostIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1071             : PostfixDotNode(base, ident)
1072         {
1073         }
1074
1075         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1076         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1077     };
1078
1079     class PostDecDotNode : public PostfixDotNode {
1080     public:
1081         PostDecDotNode(ExpressionNode*  base, const Identifier& ident) KJS_FAST_CALL
1082             : PostfixDotNode(base, ident)
1083         {
1084         }
1085
1086         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1087         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1088     };
1089
1090     class PostfixErrorNode : public ExpressionNode {
1091     public:
1092         PostfixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL
1093             : m_expr(expr)
1094             , m_operator(oper)
1095         {
1096         }
1097
1098         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1099         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1100         virtual Precedence precedence() const { return PrecPostfix; }
1101
1102     private:
1103         RefPtr<ExpressionNode> m_expr;
1104         Operator m_operator;
1105     };
1106
1107     class DeleteResolveNode : public ExpressionNode {
1108     public:
1109         DeleteResolveNode(const Identifier& ident) KJS_FAST_CALL
1110             : m_ident(ident)
1111         {
1112         }
1113
1114         DeleteResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1115             : ExpressionNode(PlacementNewAdopt)
1116             , m_ident(PlacementNewAdopt)
1117         {
1118         }
1119
1120         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1121         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1122         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1123         virtual Precedence precedence() const { return PrecUnary; }
1124
1125     private:
1126         Identifier m_ident;
1127     };
1128
1129     class LocalVarDeleteNode : public DeleteResolveNode {
1130     public:
1131         LocalVarDeleteNode() KJS_FAST_CALL
1132             : DeleteResolveNode(PlacementNewAdopt)
1133         {
1134         }
1135
1136         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1137     };
1138
1139     class DeleteBracketNode : public ExpressionNode {
1140     public:
1141         DeleteBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1142             : m_base(base)
1143             , m_subscript(subscript)
1144         {
1145         }
1146
1147         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1148         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1149         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1150         virtual Precedence precedence() const { return PrecUnary; }
1151
1152     private:
1153         RefPtr<ExpressionNode> m_base;
1154         RefPtr<ExpressionNode> m_subscript;
1155     };
1156
1157     class DeleteDotNode : public ExpressionNode {
1158     public:
1159         DeleteDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1160             : m_base(base)
1161             , m_ident(ident)
1162         {
1163         }
1164
1165         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1166         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1167         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1168         virtual Precedence precedence() const { return PrecUnary; }
1169
1170     private:
1171         RefPtr<ExpressionNode> m_base;
1172         Identifier m_ident;
1173     };
1174
1175     class DeleteValueNode : public ExpressionNode {
1176     public:
1177         DeleteValueNode(ExpressionNode* expr) KJS_FAST_CALL
1178             : m_expr(expr)
1179         {
1180         }
1181
1182         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1183         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1184         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1185         virtual Precedence precedence() const { return PrecUnary; }
1186
1187     private:
1188         RefPtr<ExpressionNode> m_expr;
1189     };
1190
1191     class VoidNode : public ExpressionNode {
1192     public:
1193         VoidNode(ExpressionNode* expr) KJS_FAST_CALL
1194             : m_expr(expr)
1195         {
1196         }
1197
1198         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1199         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1200         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1201         virtual Precedence precedence() const { return PrecUnary; }
1202
1203     private:
1204         RefPtr<ExpressionNode> m_expr;
1205     };
1206
1207     class TypeOfResolveNode : public ExpressionNode {
1208     public:
1209         TypeOfResolveNode(const Identifier& ident) KJS_FAST_CALL
1210             : ExpressionNode(StringType)
1211             , m_ident(ident)
1212         {
1213         }
1214
1215         TypeOfResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1216             : ExpressionNode(PlacementNewAdopt)
1217             , m_ident(PlacementNewAdopt)
1218         {
1219             m_expectedReturnType = StringType;
1220         }
1221
1222         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1223
1224         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1225         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1226         virtual Precedence precedence() const { return PrecUnary; }
1227
1228         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
1229
1230     protected:
1231         Identifier m_ident;
1232         size_t m_index; // Used by LocalTypeOfNode.
1233     };
1234
1235     class LocalVarTypeOfNode : public TypeOfResolveNode {
1236     public:
1237         LocalVarTypeOfNode(size_t i) KJS_FAST_CALL
1238             : TypeOfResolveNode(PlacementNewAdopt)
1239         {
1240             m_expectedReturnType = StringType;
1241             ASSERT(i != missingSymbolMarker());
1242             m_index = i;
1243         }
1244
1245         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1246     };
1247
1248     class TypeOfValueNode : public ExpressionNode {
1249     public:
1250         TypeOfValueNode(ExpressionNode* expr) KJS_FAST_CALL
1251             : ExpressionNode(StringType)
1252             , m_expr(expr)
1253         {
1254         }
1255
1256         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1257         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1258         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1259         virtual Precedence precedence() const { return PrecUnary; }
1260
1261     private:
1262         RefPtr<ExpressionNode> m_expr;
1263     };
1264
1265     class PreIncResolveNode : public PrePostResolveNode {
1266     public:
1267         PreIncResolveNode(const Identifier& ident) KJS_FAST_CALL
1268             : PrePostResolveNode(ident)
1269         {
1270         }
1271
1272         PreIncResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1273             : PrePostResolveNode(PlacementNewAdopt)
1274         {
1275         }
1276
1277         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1278
1279         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1280         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1281         virtual Precedence precedence() const { return PrecUnary; }
1282     };
1283
1284     class PreIncLocalVarNode : public PreIncResolveNode {
1285     public:
1286         PreIncLocalVarNode(size_t i) KJS_FAST_CALL
1287             : PreIncResolveNode(PlacementNewAdopt)
1288         {
1289             ASSERT(i != missingSymbolMarker());
1290             m_index = i;
1291         }
1292
1293         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1294     };
1295
1296     class PreIncConstNode : public PreIncResolveNode {
1297     public:
1298         PreIncConstNode(size_t i) KJS_FAST_CALL
1299             : PreIncResolveNode(PlacementNewAdopt)
1300         {
1301             ASSERT(i != missingSymbolMarker());
1302             m_index = i;
1303         }
1304
1305         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1306     };
1307
1308     class PreDecResolveNode : public PrePostResolveNode {
1309     public:
1310         PreDecResolveNode(const Identifier& ident) KJS_FAST_CALL
1311             : PrePostResolveNode(ident)
1312         {
1313         }
1314
1315         PreDecResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
1316             : PrePostResolveNode(PlacementNewAdopt)
1317         {
1318         }
1319
1320         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1321
1322         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1323         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1324         virtual Precedence precedence() const { return PrecUnary; }
1325     };
1326
1327     class PreDecLocalVarNode : public PreDecResolveNode {
1328     public:
1329         PreDecLocalVarNode(size_t i) KJS_FAST_CALL
1330             : PreDecResolveNode(PlacementNewAdopt)
1331         {
1332             ASSERT(i != missingSymbolMarker());
1333             m_index = i;
1334         }
1335
1336         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1337     };
1338
1339     class PreDecConstNode : public PreDecResolveNode {
1340     public:
1341         PreDecConstNode(size_t i) KJS_FAST_CALL
1342             : PreDecResolveNode(PlacementNewAdopt)
1343         {
1344             ASSERT(i != missingSymbolMarker());
1345             m_index = i;
1346         }
1347
1348         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1349     };
1350
1351     class PrefixBracketNode : public ExpressionNode {
1352     public:
1353         PrefixBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1354             : m_base(base)
1355             , m_subscript(subscript)
1356         {
1357         }
1358
1359         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1360         virtual Precedence precedence() const { return PrecUnary; }
1361
1362     protected:
1363         RefPtr<ExpressionNode> m_base;
1364         RefPtr<ExpressionNode> m_subscript;
1365     };
1366
1367     class PreIncBracketNode : public PrefixBracketNode {
1368     public:
1369         PreIncBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1370             : PrefixBracketNode(base, subscript)
1371         {
1372         }
1373
1374         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1375         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1376     };
1377
1378     class PreDecBracketNode : public PrefixBracketNode {
1379     public:
1380         PreDecBracketNode(ExpressionNode* base, ExpressionNode* subscript) KJS_FAST_CALL
1381             : PrefixBracketNode(base, subscript)
1382         {
1383         }
1384
1385         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1386         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1387     };
1388
1389     class PrefixDotNode : public ExpressionNode {
1390     public:
1391         PrefixDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1392             : m_base(base)
1393             , m_ident(ident)
1394         {
1395         }
1396
1397         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1398         virtual Precedence precedence() const { return PrecPostfix; }
1399
1400     protected:
1401         RefPtr<ExpressionNode> m_base;
1402         Identifier m_ident;
1403     };
1404
1405     class PreIncDotNode : public PrefixDotNode {
1406     public:
1407         PreIncDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1408             : PrefixDotNode(base, ident)
1409         {
1410         }
1411
1412         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1413         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1414     };
1415
1416     class PreDecDotNode : public PrefixDotNode {
1417     public:
1418         PreDecDotNode(ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
1419             : PrefixDotNode(base, ident)
1420         {
1421         }
1422
1423         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1424         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1425     };
1426
1427     class PrefixErrorNode : public ExpressionNode {
1428     public:
1429         PrefixErrorNode(ExpressionNode* expr, Operator oper) KJS_FAST_CALL
1430             : m_expr(expr)
1431             , m_operator(oper)
1432         {
1433         }
1434
1435         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1436         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1437         virtual Precedence precedence() const { return PrecUnary; }
1438
1439     private:
1440         RefPtr<ExpressionNode> m_expr;
1441         Operator m_operator;
1442     };
1443
1444     class UnaryPlusNode : public ExpressionNode {
1445     public:
1446         UnaryPlusNode(ExpressionNode* expr) KJS_FAST_CALL
1447             : ExpressionNode(NumberType)
1448             , m_expr(expr)
1449         {
1450         }
1451
1452         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1453         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1454         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1455         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1456         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1457         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1458         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1459         virtual Precedence precedence() const { return PrecUnary; }
1460
1461     private:
1462         RefPtr<ExpressionNode> m_expr;
1463     };
1464
1465     class NegateNode : public ExpressionNode {
1466     public:
1467         NegateNode(ExpressionNode* expr) KJS_FAST_CALL
1468             : ExpressionNode(NumberType)
1469             , m_expr(expr)
1470         {
1471         }
1472
1473         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1474         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1475         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1476         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1477         virtual Precedence precedence() const { return PrecUnary; }
1478
1479     private:
1480         RefPtr<ExpressionNode> m_expr;
1481     };
1482
1483     class BitwiseNotNode : public ExpressionNode {
1484     public:
1485         BitwiseNotNode(ExpressionNode* expr) KJS_FAST_CALL
1486             : ExpressionNode(NumberType)
1487             , m_expr(expr)
1488         {
1489         }
1490
1491         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1492         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1493         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1494         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1495         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1496         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1497         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1498         virtual Precedence precedence() const { return PrecUnary; }
1499
1500     private:
1501         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1502
1503         RefPtr<ExpressionNode> m_expr;
1504     };
1505
1506     class LogicalNotNode : public ExpressionNode {
1507     public:
1508         LogicalNotNode(ExpressionNode* expr) KJS_FAST_CALL
1509             : ExpressionNode(BooleanType)
1510             , m_expr(expr)
1511         {
1512         }
1513
1514         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1515         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1516         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1517         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1518         virtual Precedence precedence() const { return PrecUnary; }
1519
1520     private:
1521         RefPtr<ExpressionNode> m_expr;
1522     };
1523
1524     class MultNode : public ExpressionNode {
1525     public:
1526         MultNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1527             : ExpressionNode(NumberType)
1528             , m_term1(term1)
1529             , m_term2(term2)
1530         {
1531         }
1532
1533         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1534         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1535         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1536         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1537         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1538         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1539         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1540         virtual Precedence precedence() const { return PrecMultiplicitave; }
1541
1542     private:
1543         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1544
1545         RefPtr<ExpressionNode> m_term1;
1546         RefPtr<ExpressionNode> m_term2;
1547     };
1548
1549     class DivNode : public ExpressionNode {
1550     public:
1551         DivNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1552             : ExpressionNode(NumberType)
1553             , m_term1(term1)
1554             , m_term2(term2)
1555         {
1556         }
1557
1558         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1559         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1560         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1561         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1562         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1563         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1564         virtual Precedence precedence() const { return PrecMultiplicitave; }
1565
1566     private:
1567         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1568
1569         RefPtr<ExpressionNode> m_term1;
1570         RefPtr<ExpressionNode> m_term2;
1571     };
1572
1573     class ModNode : public ExpressionNode {
1574     public:
1575         ModNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1576             : ExpressionNode(NumberType)
1577             , m_term1(term1)
1578             , m_term2(term2)
1579         {
1580         }
1581
1582         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1583         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1584         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1585         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1586         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1587         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1588         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1589         virtual Precedence precedence() const { return PrecMultiplicitave; }
1590
1591     private:
1592         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1593
1594         RefPtr<ExpressionNode> m_term1;
1595         RefPtr<ExpressionNode> m_term2;
1596     };
1597
1598     class AddNode : public ExpressionNode {
1599     public:
1600         AddNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1601             : m_term1(term1)
1602             , m_term2(term2)
1603         {
1604         }
1605
1606         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1607         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1608         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1609         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1610         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1611         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1612         virtual Precedence precedence() const { return PrecAdditive; }
1613
1614     protected:
1615         AddNode(ExpressionNode* term1, ExpressionNode* term2, JSType expectedReturn) KJS_FAST_CALL
1616             : ExpressionNode(expectedReturn)
1617             , m_term1(term1)
1618             , m_term2(term2)
1619         {
1620         }
1621
1622         RefPtr<ExpressionNode> m_term1;
1623         RefPtr<ExpressionNode> m_term2;
1624
1625     private:
1626         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1627     };
1628
1629     class AddNumbersNode : public AddNode {
1630     public:
1631         AddNumbersNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1632             : AddNode(term1, term2, NumberType)
1633         {
1634         }
1635
1636         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1637         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1638         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1639         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1640
1641     private:
1642         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*) KJS_FAST_CALL;
1643     };
1644
1645     class AddStringLeftNode : public AddNode {
1646     public:
1647         AddStringLeftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1648             : AddNode(term1, term2, StringType)
1649         {
1650         }
1651
1652         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1653     };
1654
1655     class AddStringRightNode : public AddNode {
1656     public:
1657         AddStringRightNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1658             : AddNode(term1, term2, StringType)
1659         {
1660         }
1661
1662         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1663     };
1664
1665     class AddStringsNode : public AddNode {
1666     public:
1667         AddStringsNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1668             : AddNode(term1, term2, StringType)
1669         {
1670         }
1671
1672         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1673     };
1674
1675     class SubNode : public ExpressionNode {
1676     public:
1677         SubNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1678             : ExpressionNode(NumberType)
1679             , m_term1(term1)
1680             , m_term2(term2)
1681         {
1682         }
1683
1684         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1685         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1686         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1687         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1688         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1689         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1690         virtual Precedence precedence() const { return PrecAdditive; }
1691
1692     private:
1693         ALWAYS_INLINE double inlineEvaluateToNumber(ExecState*);
1694
1695         RefPtr<ExpressionNode> m_term1;
1696         RefPtr<ExpressionNode> m_term2;
1697     };
1698
1699     class LeftShiftNode : public ExpressionNode {
1700     public:
1701         LeftShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1702             : ExpressionNode(NumberType)
1703             , m_term1(term1)
1704             , m_term2(term2)
1705         {
1706         }
1707
1708         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1709         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1710         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1711         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1712         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1713         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1714         virtual Precedence precedence() const { return PrecShift; }
1715
1716     private:
1717         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1718
1719         RefPtr<ExpressionNode> m_term1;
1720         RefPtr<ExpressionNode> m_term2;
1721     };
1722
1723     class RightShiftNode : public ExpressionNode {
1724     public:
1725         RightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1726             : ExpressionNode(NumberType)
1727             , m_term1(term1)
1728             , m_term2(term2)
1729         {
1730         }
1731
1732         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1733         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1734         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1735         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1736         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1737         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1738         virtual Precedence precedence() const { return PrecShift; }
1739
1740     private:
1741         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
1742
1743         RefPtr<ExpressionNode> m_term1;
1744         RefPtr<ExpressionNode> m_term2;
1745     };
1746
1747     class UnsignedRightShiftNode : public ExpressionNode {
1748     public:
1749         UnsignedRightShiftNode(ExpressionNode* term1, ExpressionNode* term2) KJS_FAST_CALL
1750             : ExpressionNode(NumberType)
1751             , m_term1(term1)
1752             , m_term2(term2)
1753         {
1754         }
1755
1756         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1757         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1758         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
1759         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
1760         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
1761         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1762         virtual Precedence precedence() const { return PrecShift; }
1763     private:
1764         ALWAYS_INLINE uint32_t inlineEvaluateToUInt32(ExecState*);
1765
1766         RefPtr<ExpressionNode> m_term1;
1767         RefPtr<ExpressionNode> m_term2;
1768     };
1769
1770     class LessNode : public ExpressionNode {
1771     public:
1772         LessNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1773             : ExpressionNode(BooleanType)
1774             , m_expr1(expr1)
1775             , m_expr2(expr2)
1776         {
1777         }
1778
1779         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1780         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1781         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1782         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1783         virtual Precedence precedence() const { return PrecRelational; }
1784
1785     private:
1786         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1787
1788     protected:
1789         RefPtr<ExpressionNode> m_expr1;
1790         RefPtr<ExpressionNode> m_expr2;
1791     };
1792
1793     class LessNumbersNode : public LessNode {
1794     public:
1795         LessNumbersNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1796             : LessNode(expr1, expr2)
1797         {
1798         }
1799
1800         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1801         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1802
1803     private:
1804         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1805     };
1806
1807     class LessStringsNode : public LessNode {
1808     public:
1809         LessStringsNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1810             : LessNode(expr1, expr2)
1811         {
1812         }
1813
1814         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1815         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1816
1817     private:
1818         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1819     };
1820
1821     class GreaterNode : public ExpressionNode {
1822     public:
1823         GreaterNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1824             : m_expr1(expr1)
1825             , m_expr2(expr2)
1826         {
1827         }
1828
1829         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1830         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1831         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1832         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1833         virtual Precedence precedence() const { return PrecRelational; }
1834
1835     private:
1836         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1837
1838         RefPtr<ExpressionNode> m_expr1;
1839         RefPtr<ExpressionNode> m_expr2;
1840     };
1841
1842     class LessEqNode : public ExpressionNode {
1843     public:
1844         LessEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1845             : m_expr1(expr1)
1846             , m_expr2(expr2)
1847         {
1848         }
1849
1850         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1851         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1852         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1853         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1854         virtual Precedence precedence() const { return PrecRelational; }
1855
1856     private:
1857         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1858
1859         RefPtr<ExpressionNode> m_expr1;
1860         RefPtr<ExpressionNode> m_expr2;
1861     };
1862
1863     class GreaterEqNode : public ExpressionNode {
1864     public:
1865         GreaterEqNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1866             : m_expr1(expr1)
1867             , m_expr2(expr2)
1868         {
1869         }
1870
1871         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1872         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1873         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1874         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1875         virtual Precedence precedence() const { return PrecRelational; }
1876
1877     private:
1878         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1879
1880         RefPtr<ExpressionNode> m_expr1;
1881         RefPtr<ExpressionNode> m_expr2;
1882     };
1883
1884     class InstanceOfNode : public ExpressionNode {
1885     public:
1886         InstanceOfNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1887             : ExpressionNode(BooleanType)
1888             , m_expr1(expr1)
1889             , m_expr2(expr2)
1890         {
1891         }
1892
1893         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1894         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1895         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1896         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1897         virtual Precedence precedence() const { return PrecRelational; }
1898
1899     private:
1900         RefPtr<ExpressionNode> m_expr1;
1901         RefPtr<ExpressionNode> m_expr2;
1902     };
1903
1904     class InNode : public ExpressionNode {
1905     public:
1906         InNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1907             : m_expr1(expr1)
1908             , m_expr2(expr2)
1909         {
1910         }
1911
1912         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1913         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1914         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1915         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1916         virtual Precedence precedence() const { return PrecRelational; }
1917
1918     private:
1919         RefPtr<ExpressionNode> m_expr1;
1920         RefPtr<ExpressionNode> m_expr2;
1921     };
1922
1923     class EqualNode : public ExpressionNode {
1924     public:
1925         EqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1926             : ExpressionNode(BooleanType)
1927             , m_expr1(expr1)
1928             , m_expr2(expr2)
1929         {
1930         }
1931
1932         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1933         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1934         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1935         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1936         virtual Precedence precedence() const { return PrecEquality; }
1937
1938     private:
1939         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1940
1941         RefPtr<ExpressionNode> m_expr1;
1942         RefPtr<ExpressionNode> m_expr2;
1943     };
1944
1945     class NotEqualNode : public ExpressionNode {
1946     public:
1947         NotEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1948             : ExpressionNode(BooleanType)
1949             , m_expr1(expr1)
1950             , m_expr2(expr2)
1951         {
1952         }
1953
1954         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1955         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1956         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1957         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1958         virtual Precedence precedence() const { return PrecEquality; }
1959
1960     private:
1961         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1962
1963         RefPtr<ExpressionNode> m_expr1;
1964         RefPtr<ExpressionNode> m_expr2;
1965     };
1966
1967     class StrictEqualNode : public ExpressionNode {
1968     public:
1969         StrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1970             : ExpressionNode(BooleanType)
1971             , m_expr1(expr1)
1972             , m_expr2(expr2)
1973         {
1974         }
1975
1976         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1977         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
1978         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
1979         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1980         virtual Precedence precedence() const { return PrecEquality; }
1981
1982     private:
1983         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
1984
1985         RefPtr<ExpressionNode> m_expr1;
1986         RefPtr<ExpressionNode> m_expr2;
1987     };
1988
1989     class NotStrictEqualNode : public ExpressionNode {
1990     public:
1991         NotStrictEqualNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1992             : ExpressionNode(BooleanType)
1993             , m_expr1(expr1)
1994             , m_expr2(expr2)
1995         {
1996         }
1997
1998         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
1999         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2000         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2001         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2002         virtual Precedence precedence() const { return PrecEquality; }
2003
2004     private:
2005         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2006
2007         RefPtr<ExpressionNode> m_expr1;
2008         RefPtr<ExpressionNode> m_expr2;
2009     };
2010
2011     class BitAndNode : public ExpressionNode {
2012     public:
2013         BitAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2014             : ExpressionNode(NumberType)
2015             , m_expr1(expr1)
2016             , m_expr2(expr2)
2017         {
2018         }
2019
2020         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2021         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2022         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2023         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2024         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2025         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2026         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2027         virtual Precedence precedence() const { return PrecBitwiseAnd; }
2028
2029     private:
2030         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2031
2032         RefPtr<ExpressionNode> m_expr1;
2033         RefPtr<ExpressionNode> m_expr2;
2034     };
2035
2036     class BitOrNode : public ExpressionNode {
2037     public:
2038         BitOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2039             : ExpressionNode(NumberType)
2040             , m_expr1(expr1)
2041             , m_expr2(expr2)
2042         {
2043         }
2044
2045         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2046         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2047         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2048         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2049         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2050         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2051         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2052         virtual Precedence precedence() const { return PrecBitwiseOr; }
2053
2054     private:
2055         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2056
2057         RefPtr<ExpressionNode> m_expr1;
2058         RefPtr<ExpressionNode> m_expr2;
2059     };
2060
2061     class BitXOrNode : public ExpressionNode {
2062     public:
2063         BitXOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2064             : ExpressionNode(NumberType)
2065             , m_expr1(expr1)
2066             , m_expr2(expr2)
2067         {
2068         }
2069
2070         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2071         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2072         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2073         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2074         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2075         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2076         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2077         virtual Precedence precedence() const { return PrecBitwiseXor; }
2078
2079     private:
2080         ALWAYS_INLINE int32_t inlineEvaluateToInt32(ExecState*);
2081
2082         RefPtr<ExpressionNode> m_expr1;
2083         RefPtr<ExpressionNode> m_expr2;
2084     };
2085
2086     /**
2087      * m_expr1 && m_expr2, m_expr1 || m_expr2
2088      */
2089     class LogicalAndNode : public ExpressionNode {
2090     public:
2091         LogicalAndNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2092             : ExpressionNode(BooleanType)
2093             , m_expr1(expr1)
2094             , m_expr2(expr2)
2095         {
2096         }
2097
2098         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2099         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2100         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2101         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2102         virtual Precedence precedence() const { return PrecLogicalAnd; }
2103
2104     private:
2105         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2106
2107         RefPtr<ExpressionNode> m_expr1;
2108         RefPtr<ExpressionNode> m_expr2;
2109     };
2110
2111     class LogicalOrNode : public ExpressionNode {
2112     public:
2113         LogicalOrNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2114             : ExpressionNode(BooleanType)
2115             , m_expr1(expr1)
2116             , m_expr2(expr2)
2117         {
2118         }
2119
2120         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2121         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2122         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2123         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2124         virtual Precedence precedence() const { return PrecLogicalOr; }
2125
2126     private:
2127         ALWAYS_INLINE bool inlineEvaluateToBoolean(ExecState*);
2128
2129         RefPtr<ExpressionNode> m_expr1;
2130         RefPtr<ExpressionNode> m_expr2;
2131     };
2132
2133     /**
2134      * The ternary operator, "m_logical ? m_expr1 : m_expr2"
2135      */
2136     class ConditionalNode : public ExpressionNode {
2137     public:
2138         ConditionalNode(ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2139             : m_logical(logical)
2140             , m_expr1(expr1)
2141             , m_expr2(expr2)
2142         {
2143         }
2144
2145         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2146         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2147         virtual bool evaluateToBoolean(ExecState*) KJS_FAST_CALL;
2148         virtual double evaluateToNumber(ExecState*) KJS_FAST_CALL;
2149         virtual int32_t evaluateToInt32(ExecState*) KJS_FAST_CALL;
2150         virtual uint32_t evaluateToUInt32(ExecState*) KJS_FAST_CALL;
2151         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2152         virtual Precedence precedence() const { return PrecConditional; }
2153
2154     private:
2155         RefPtr<ExpressionNode> m_logical;
2156         RefPtr<ExpressionNode> m_expr1;
2157         RefPtr<ExpressionNode> m_expr2;
2158     };
2159
2160     class ReadModifyResolveNode : public ExpressionNode {
2161     public:
2162         ReadModifyResolveNode(const Identifier& ident, Operator oper, ExpressionNode*  right) KJS_FAST_CALL
2163             : m_ident(ident)
2164             , m_operator(oper)
2165             , m_right(right)
2166         {
2167         }
2168
2169         ReadModifyResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
2170             : ExpressionNode(PlacementNewAdopt)
2171             , m_ident(PlacementNewAdopt)
2172             , m_right(PlacementNewAdopt)
2173         {
2174         }
2175
2176         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2177         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2178         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2179         virtual Precedence precedence() const { return PrecAssignment; }
2180
2181     protected:
2182         Identifier m_ident;
2183         Operator m_operator;
2184         RefPtr<ExpressionNode> m_right;
2185         size_t m_index; // Used by ReadModifyLocalVarNode.
2186     };
2187
2188     class ReadModifyLocalVarNode : public ReadModifyResolveNode {
2189     public:
2190         ReadModifyLocalVarNode(size_t i) KJS_FAST_CALL
2191             : ReadModifyResolveNode(PlacementNewAdopt)
2192         {
2193             ASSERT(i != missingSymbolMarker());
2194             m_index = i;
2195         }
2196
2197         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2198     };
2199
2200     class ReadModifyConstNode : public ReadModifyResolveNode {
2201     public:
2202         ReadModifyConstNode(size_t i) KJS_FAST_CALL
2203             : ReadModifyResolveNode(PlacementNewAdopt)
2204         {
2205             ASSERT(i != missingSymbolMarker());
2206             m_index = i;
2207         }
2208
2209         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2210     };
2211
2212     class AssignResolveNode : public ExpressionNode {
2213     public:
2214         AssignResolveNode(const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
2215             : m_ident(ident)
2216             , m_right(right)
2217         {
2218         }
2219
2220         AssignResolveNode(PlacementNewAdoptType) KJS_FAST_CALL
2221             : ExpressionNode(PlacementNewAdopt)
2222             , m_ident(PlacementNewAdopt)
2223             , m_right(PlacementNewAdopt)
2224         {
2225         }
2226
2227         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2228         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2229         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2230         virtual Precedence precedence() const { return PrecAssignment; }
2231
2232     protected:
2233         Identifier m_ident;
2234         RefPtr<ExpressionNode> m_right;
2235         size_t m_index; // Used by ReadModifyLocalVarNode.
2236     };
2237
2238     class AssignLocalVarNode : public AssignResolveNode {
2239     public:
2240         AssignLocalVarNode(size_t i) KJS_FAST_CALL
2241             : AssignResolveNode(PlacementNewAdopt)
2242         {
2243             ASSERT(i != missingSymbolMarker());
2244             m_index = i;
2245         }
2246
2247         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2248     };
2249
2250     class AssignConstNode : public AssignResolveNode {
2251     public:
2252         AssignConstNode() KJS_FAST_CALL
2253             : AssignResolveNode(PlacementNewAdopt)
2254         {
2255         }
2256
2257         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2258     };
2259
2260     class ReadModifyBracketNode : public ExpressionNode {
2261     public:
2262         ReadModifyBracketNode(ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2263             : m_base(base)
2264             , m_subscript(subscript)
2265             , m_operator(oper)
2266             , m_right(right)
2267         {
2268         }
2269
2270         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2271         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2272         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2273         virtual Precedence precedence() const { return PrecAssignment; }
2274
2275     protected:
2276         RefPtr<ExpressionNode> m_base;
2277         RefPtr<ExpressionNode> m_subscript;
2278         Operator m_operator;
2279         RefPtr<ExpressionNode> m_right;
2280     };
2281
2282     class AssignBracketNode : public ExpressionNode {
2283     public:
2284         AssignBracketNode(ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right) KJS_FAST_CALL
2285             : m_base(base)
2286             , m_subscript(subscript)
2287             , m_right(right)
2288         {
2289         }
2290
2291         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2292         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2293         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2294         virtual Precedence precedence() const { return PrecAssignment; }
2295
2296     protected:
2297         RefPtr<ExpressionNode> m_base;
2298         RefPtr<ExpressionNode> m_subscript;
2299         RefPtr<ExpressionNode> m_right;
2300     };
2301
2302     class AssignDotNode : public ExpressionNode {
2303     public:
2304         AssignDotNode(ExpressionNode* base, const Identifier& ident, ExpressionNode* right) KJS_FAST_CALL
2305             : m_base(base)
2306             , m_ident(ident)
2307             , m_right(right)
2308         {
2309         }
2310
2311         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2312         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2313         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2314         virtual Precedence precedence() const { return PrecAssignment; }
2315
2316     protected:
2317         RefPtr<ExpressionNode> m_base;
2318         Identifier m_ident;
2319         RefPtr<ExpressionNode> m_right;
2320     };
2321
2322     class ReadModifyDotNode : public ExpressionNode {
2323     public:
2324         ReadModifyDotNode(ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2325             : m_base(base)
2326             , m_ident(ident)
2327             , m_operator(oper)
2328             , m_right(right)
2329         {
2330         }
2331
2332         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2333         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2334         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2335         virtual Precedence precedence() const { return PrecAssignment; }
2336
2337     protected:
2338         RefPtr<ExpressionNode> m_base;
2339         Identifier m_ident;
2340         Operator m_operator;
2341         RefPtr<ExpressionNode> m_right;
2342     };
2343
2344     class AssignErrorNode : public ExpressionNode {
2345     public:
2346         AssignErrorNode(ExpressionNode* left, Operator oper, ExpressionNode* right) KJS_FAST_CALL
2347             : m_left(left)
2348             , m_operator(oper)
2349             , m_right(right)
2350         {
2351         }
2352
2353         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2354         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2355         virtual Precedence precedence() const { return PrecAssignment; }
2356
2357     protected:
2358         RefPtr<ExpressionNode> m_left;
2359         Operator m_operator;
2360         RefPtr<ExpressionNode> m_right;
2361     };
2362
2363     class CommaNode : public ExpressionNode {
2364     public:
2365         CommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2366             : m_expr1(expr1)
2367             , m_expr2(expr2)
2368         {
2369             m_expr1->optimizeForUnnecessaryResult();
2370         }
2371
2372         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2373         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2374         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2375         virtual Precedence precedence() const { return PrecExpression; }
2376
2377     private:
2378         RefPtr<ExpressionNode> m_expr1;
2379         RefPtr<ExpressionNode> m_expr2;
2380     };
2381     
2382     class VarDeclCommaNode : public CommaNode {
2383     public:
2384         VarDeclCommaNode(ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
2385             : CommaNode(expr1, expr2)
2386         {
2387         }
2388         virtual Precedence precedence() const { return PrecAssignment; }
2389     };
2390
2391     class ConstDeclNode : public ExpressionNode {
2392     public:
2393         ConstDeclNode(const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;
2394
2395         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2396         virtual KJS::JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2397         void evaluateSingle(ExecState*) KJS_FAST_CALL;
2398         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2399         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2400         PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2401
2402         Identifier m_ident;
2403         ListRefPtr<ConstDeclNode> m_next;
2404         RefPtr<ExpressionNode> m_init;
2405
2406     private:
2407         void handleSlowCase(ExecState*, const ScopeChain&, JSValue*) KJS_FAST_CALL NEVER_INLINE;
2408     };
2409
2410     class ConstStatementNode : public StatementNode {
2411     public:
2412         ConstStatementNode(ConstDeclNode* next) KJS_FAST_CALL
2413             : m_next(next)
2414         {
2415         }
2416
2417         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2418         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2419         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2420
2421     private:
2422         RefPtr<ConstDeclNode> m_next;
2423     };
2424
2425     typedef Vector<RefPtr<StatementNode> > StatementVector;
2426
2427     class SourceElements : public ParserRefCounted {
2428     public:
2429         void append(PassRefPtr<StatementNode>);
2430         void releaseContentsIntoVector(StatementVector& destination)
2431         {
2432             ASSERT(destination.isEmpty());
2433             m_statements.swap(destination);
2434         }
2435
2436     private:
2437         StatementVector m_statements;
2438     };
2439
2440     class BlockNode : public StatementNode {
2441     public:
2442         BlockNode(SourceElements* children) KJS_FAST_CALL;
2443
2444         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2445         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2446         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2447
2448     protected:
2449         StatementVector m_children;
2450     };
2451
2452     class EmptyStatementNode : public StatementNode {
2453     public:
2454         EmptyStatementNode() KJS_FAST_CALL // debug
2455         {
2456         }
2457
2458         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2459         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2460         virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
2461     };
2462
2463     class ExprStatementNode : public StatementNode {
2464     public:
2465         ExprStatementNode(ExpressionNode* expr) KJS_FAST_CALL
2466             : m_expr(expr)
2467         {
2468         }
2469
2470         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2471         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2472         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2473
2474     private:
2475         RefPtr<ExpressionNode> m_expr;
2476     };
2477
2478     class VarStatementNode : public StatementNode {
2479     public:
2480         VarStatementNode(ExpressionNode* expr) KJS_FAST_CALL
2481             : m_expr(expr)
2482         {
2483         }
2484
2485         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2486         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2487         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2488
2489     private:
2490         RefPtr<ExpressionNode> m_expr;
2491     };
2492
2493     class IfNode : public StatementNode {
2494     public:
2495         IfNode(ExpressionNode* condition, StatementNode* ifBlock) KJS_FAST_CALL
2496             : m_condition(condition)
2497             , m_ifBlock(ifBlock)
2498         {
2499         }
2500
2501         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2502         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2503         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2504
2505     protected:
2506         RefPtr<ExpressionNode> m_condition;
2507         RefPtr<StatementNode> m_ifBlock;
2508     };
2509
2510     class IfElseNode : public IfNode {
2511     public:
2512         IfElseNode(ExpressionNode* condtion, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL
2513             : IfNode(condtion, ifBlock)
2514             , m_elseBlock(elseBlock)
2515         {
2516         }
2517
2518         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2519         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2520         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2521
2522     private:
2523         RefPtr<StatementNode> m_elseBlock;
2524     };
2525
2526     class DoWhileNode : public StatementNode {
2527     public:
2528         DoWhileNode(StatementNode* statement, ExpressionNode* expr) KJS_FAST_CALL
2529             : m_statement(statement)
2530             , m_expr(expr)
2531         {
2532         }
2533
2534         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2535         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2536         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2537
2538     private:
2539         RefPtr<StatementNode> m_statement;
2540         RefPtr<ExpressionNode> m_expr;
2541     };
2542
2543     class WhileNode : public StatementNode {
2544     public:
2545         WhileNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL
2546             : m_expr(expr)
2547             , m_statement(statement)
2548         {
2549         }
2550
2551         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2552         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2553         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2554
2555     private:
2556         RefPtr<ExpressionNode> m_expr;
2557         RefPtr<StatementNode> m_statement;
2558     };
2559
2560     class ForNode : public StatementNode {
2561     public:
2562         ForNode(ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL
2563             : m_expr1(expr1 ? expr1 : new PlaceholderTrueNode)
2564             , m_expr2(expr2 ? expr2 : new PlaceholderTrueNode)
2565             , m_expr3(expr3 ? expr3 : new PlaceholderTrueNode)
2566             , m_statement(statement)
2567             , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
2568         {
2569             ASSERT(m_expr1);
2570             ASSERT(m_expr2);
2571             ASSERT(m_expr3);
2572             ASSERT(statement);
2573
2574             m_expr1->optimizeForUnnecessaryResult();
2575             m_expr3->optimizeForUnnecessaryResult();
2576         }
2577
2578         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2579         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2580         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2581
2582     private:
2583         RefPtr<ExpressionNode> m_expr1;
2584         RefPtr<ExpressionNode> m_expr2;
2585         RefPtr<ExpressionNode> m_expr3;
2586         RefPtr<StatementNode> m_statement;
2587         bool m_expr1WasVarDecl;
2588     };
2589
2590     class ForInNode : public StatementNode {
2591     public:
2592         ForInNode(ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
2593         ForInNode(const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
2594
2595         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2596         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2597         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2598
2599     private:
2600         Identifier m_ident;
2601         RefPtr<ExpressionNode> m_init;
2602         RefPtr<ExpressionNode> m_lexpr;
2603         RefPtr<ExpressionNode> m_expr;
2604         RefPtr<StatementNode> m_statement;
2605         bool m_identIsVarDecl;
2606     };
2607
2608     class ContinueNode : public StatementNode {
2609     public:
2610         ContinueNode() KJS_FAST_CALL
2611         {
2612         }
2613
2614         ContinueNode(const Identifier& ident) KJS_FAST_CALL
2615             : m_ident(ident)
2616         {
2617         }
2618
2619         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2620         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2621
2622     private:
2623         Identifier m_ident;
2624     };
2625
2626     class BreakNode : public StatementNode {
2627     public:
2628         BreakNode() KJS_FAST_CALL
2629         {
2630         }
2631
2632         BreakNode(const Identifier& ident) KJS_FAST_CALL
2633             : m_ident(ident)
2634         {
2635         }
2636
2637         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2638         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2639
2640     private:
2641         Identifier m_ident;
2642     };
2643
2644     class ReturnNode : public StatementNode {
2645     public:
2646         ReturnNode(ExpressionNode* value) KJS_FAST_CALL
2647             : m_value(value)
2648         {
2649         }
2650
2651         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2652         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2653         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2654
2655     private:
2656         RefPtr<ExpressionNode> m_value;
2657     };
2658
2659     class WithNode : public StatementNode {
2660     public:
2661         WithNode(ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL
2662             : m_expr(expr)
2663             , m_statement(statement)
2664         {
2665         }
2666
2667         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2668         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2669         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2670
2671     private:
2672         RefPtr<ExpressionNode> m_expr;
2673         RefPtr<StatementNode> m_statement;
2674     };
2675
2676     class LabelNode : public StatementNode {
2677     public:
2678         LabelNode(const Identifier& label, StatementNode* statement) KJS_FAST_CALL
2679             : m_label(label)
2680             , m_statement(statement)
2681         {
2682         }
2683
2684         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2685         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2686         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2687         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); }
2688
2689     private:
2690         Identifier m_label;
2691         RefPtr<StatementNode> m_statement;
2692     };
2693
2694     class ThrowNode : public StatementNode {
2695     public:
2696         ThrowNode(ExpressionNode* expr) KJS_FAST_CALL
2697             : m_expr(expr)
2698         {
2699         }
2700
2701         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2702         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2703         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2704
2705     private:
2706         RefPtr<ExpressionNode> m_expr;
2707     };
2708
2709     class TryNode : public StatementNode {
2710     public:
2711         TryNode(StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) KJS_FAST_CALL
2712             : m_tryBlock(tryBlock)
2713             , m_exceptionIdent(exceptionIdent)
2714             , m_catchBlock(catchBlock)
2715             , m_finallyBlock(finallyBlock)
2716         {
2717         }
2718
2719         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2720         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2721         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2722
2723     private:
2724         RefPtr<StatementNode> m_tryBlock;
2725         Identifier m_exceptionIdent;
2726         RefPtr<StatementNode> m_catchBlock;
2727         RefPtr<StatementNode> m_finallyBlock;
2728     };
2729
2730     class ParameterNode : public Node {
2731     public:
2732         ParameterNode(const Identifier& ident) KJS_FAST_CALL
2733             : m_ident(ident)
2734         {
2735         }
2736
2737         ParameterNode(ParameterNode* l, const Identifier& ident) KJS_FAST_CALL
2738             : m_ident(ident)
2739         {
2740             l->m_next = this;
2741         }
2742
2743         Identifier ident() KJS_FAST_CALL { return m_ident; }
2744         ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); }
2745         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2746         PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2747         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2748
2749     private:
2750         friend class FuncDeclNode;
2751         friend class FuncExprNode;
2752         Identifier m_ident;
2753         ListRefPtr<ParameterNode> m_next;
2754     };
2755
2756     class ScopeNode : public BlockNode {
2757     public:
2758         ScopeNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2759
2760         int sourceId() const KJS_FAST_CALL { return m_sourceId; }
2761         const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
2762         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2763         
2764         bool usesEval() const { return m_usesEval; }
2765         bool needsClosure() const { return m_needsClosure; }
2766         
2767     protected:
2768         void optimizeVariableAccess(ExecState*) KJS_FAST_CALL;
2769
2770         VarStack m_varStack;
2771         FunctionStack m_functionStack;
2772     private:
2773         UString m_sourceURL;
2774         int m_sourceId;
2775         bool m_usesEval;
2776         bool m_needsClosure;
2777     };
2778
2779     class ProgramNode : public ScopeNode {
2780     public:
2781         static ProgramNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2782
2783         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2784
2785     private:
2786         ProgramNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2787
2788         void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
2789         ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2790
2791         Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
2792         Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
2793     };
2794
2795     class EvalNode : public ScopeNode {
2796     public:
2797         static EvalNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2798
2799         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2800
2801     private:
2802         EvalNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2803
2804         ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2805     };
2806
2807     class FunctionBodyNode : public ScopeNode {
2808     public:
2809         static FunctionBodyNode* create(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2810
2811         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2812
2813         SymbolTable& symbolTable() KJS_FAST_CALL { return m_symbolTable; }
2814
2815         Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
2816         UString paramString() const KJS_FAST_CALL;
2817
2818     protected:
2819         FunctionBodyNode(SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure) KJS_FAST_CALL;
2820
2821     private:
2822         void initializeSymbolTable(ExecState*) KJS_FAST_CALL;
2823         ALWAYS_INLINE void processDeclarations(ExecState*) KJS_FAST_CALL;
2824
2825         bool m_initialized;
2826         Vector<Identifier> m_parameters;
2827         SymbolTable m_symbolTable;
2828     };
2829
2830     class FuncExprNode : public ExpressionNode {
2831     public:
2832         FuncExprNode(const Identifier& ident, FunctionBodyNode* body, ParameterNode* parameter = 0) KJS_FAST_CALL
2833             : m_ident(ident)
2834             , m_parameter(parameter)
2835             , m_body(body)
2836         {
2837             addParams();
2838         }
2839
2840         virtual JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2841         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2842         virtual Precedence precedence() const { return PrecMember; }
2843         virtual bool needsParensIfLeftmost() const { return true; }
2844
2845     private:
2846         void addParams() KJS_FAST_CALL;
2847
2848         // Used for streamTo
2849         friend class PropertyNode;
2850         Identifier m_ident;
2851         RefPtr<ParameterNode> m_parameter;
2852         RefPtr<FunctionBodyNode> m_body;
2853     };
2854
2855     class FuncDeclNode : public StatementNode {
2856     public:
2857         FuncDeclNode(const Identifier& ident, FunctionBodyNode* body) KJS_FAST_CALL
2858             : m_ident(ident)
2859             , m_body(body)
2860         {
2861             addParams();
2862         }
2863
2864         FuncDeclNode(const Identifier& ident, ParameterNode* parameter, FunctionBodyNode* body) KJS_FAST_CALL
2865             : m_ident(ident)
2866             , m_parameter(parameter)
2867             , m_body(body)
2868         {
2869             addParams();
2870         }
2871
2872         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2873         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2874         ALWAYS_INLINE FunctionImp* makeFunction(ExecState*) KJS_FAST_CALL;
2875
2876         Identifier m_ident;
2877
2878     private:
2879         void addParams() KJS_FAST_CALL;
2880
2881         RefPtr<ParameterNode> m_parameter;
2882         RefPtr<FunctionBodyNode> m_body;
2883     };
2884
2885     class CaseClauseNode : public Node {
2886     public:
2887         CaseClauseNode(ExpressionNode* expr) KJS_FAST_CALL
2888             : m_expr(expr)
2889         {
2890         }
2891
2892         CaseClauseNode(ExpressionNode* expr, SourceElements* children) KJS_FAST_CALL
2893             : m_expr(expr)
2894         {
2895             if (children)
2896                 children->releaseContentsIntoVector(m_children);
2897         }
2898
2899         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2900         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2901         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2902
2903         JSValue* evaluate(ExecState*) KJS_FAST_CALL;
2904         JSValue* executeStatements(ExecState*) KJS_FAST_CALL;
2905
2906     private:
2907         RefPtr<ExpressionNode> m_expr;
2908         StatementVector m_children;
2909     };
2910
2911     class ClauseListNode : public Node {
2912     public:
2913         ClauseListNode(CaseClauseNode* clause) KJS_FAST_CALL
2914             : m_clause(clause)
2915         {
2916         }
2917
2918         ClauseListNode(ClauseListNode* clauseList, CaseClauseNode* clause) KJS_FAST_CALL
2919             : m_clause(clause)
2920         {
2921             clauseList->m_next = this;
2922         }
2923
2924         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2925         CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
2926         ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
2927         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2928         PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2929         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2930
2931     private:
2932         friend class CaseBlockNode;
2933         RefPtr<CaseClauseNode> m_clause;
2934         ListRefPtr<ClauseListNode> m_next;
2935     };
2936
2937     class CaseBlockNode : public Node {
2938     public:
2939         CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL;
2940
2941         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2942         JSValue* executeBlock(ExecState*, JSValue *input) KJS_FAST_CALL;
2943         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2944         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2945
2946     private:
2947         RefPtr<ClauseListNode> m_list1;
2948         RefPtr<CaseClauseNode> m_defaultClause;
2949         RefPtr<ClauseListNode> m_list2;
2950     };
2951
2952     class SwitchNode : public StatementNode {
2953     public:
2954         SwitchNode(ExpressionNode* expr, CaseBlockNode* block) KJS_FAST_CALL
2955             : m_expr(expr)
2956             , m_block(block)
2957         {
2958         }
2959
2960         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2961         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2962         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2963
2964     private:
2965         RefPtr<ExpressionNode> m_expr;
2966         RefPtr<CaseBlockNode> m_block;
2967     };
2968
2969     class BreakpointCheckStatement : public StatementNode {
2970     public:
2971         BreakpointCheckStatement(PassRefPtr<StatementNode>) KJS_FAST_CALL;
2972
2973         virtual JSValue* execute(ExecState*) KJS_FAST_CALL;
2974         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2975         virtual void optimizeVariableAccess(ExecState*, const SymbolTable&, const LocalStorage&, NodeStack&) KJS_FAST_CALL;
2976
2977     private:
2978         RefPtr<StatementNode> m_statement;
2979     };
2980
2981     struct ElementList {
2982         ElementNode* head;
2983         ElementNode* tail;
2984     };
2985
2986     struct PropertyList {
2987         PropertyListNode* head;
2988         PropertyListNode* tail;
2989     };
2990
2991     struct ArgumentList {
2992         ArgumentListNode* head;
2993         ArgumentListNode* tail;
2994     };
2995
2996     struct ConstDeclList {
2997         ConstDeclNode* head;
2998         ConstDeclNode* tail;
2999     };
3000
3001     struct ParameterList {
3002         ParameterNode* head;
3003         ParameterNode* tail;
3004     };
3005
3006     struct ClauseList {
3007         ClauseListNode* head;
3008         ClauseListNode* tail;
3009     };
3010
3011 } // namespace KJS
3012
3013 #endif // NODES_H_