2008-08-06 Cameron Zwarich <cwzwarich@webkit.org>
[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 "Error.h"
30 #include "JSString.h"
31 #include "LabelStack.h"
32 #include "Opcode.h"
33 #include "RegisterID.h"
34 #include "SourceRange.h"
35 #include "SymbolTable.h"
36 #include "regexp.h"
37 #include <wtf/ListRefPtr.h>
38 #include <wtf/MathExtras.h>
39 #include <wtf/OwnPtr.h>
40 #include <wtf/UnusedParam.h>
41 #include <wtf/Vector.h>
42
43 #if PLATFORM(X86) && COMPILER(GCC)
44 #define KJS_FAST_CALL __attribute__((regparm(3)))
45 #else
46 #define KJS_FAST_CALL
47 #endif
48
49 namespace KJS {
50
51     class CodeBlock;
52     class CodeGenerator;
53     class FuncDeclNode;
54     class Node;
55     class EvalCodeBlock;
56     class ProgramCodeBlock;
57     class PropertyListNode;
58     class SourceStream;
59
60     enum Operator {
61         OpEqual,
62         OpPlusEq,
63         OpMinusEq,
64         OpMultEq,
65         OpDivEq,
66         OpPlusPlus,
67         OpMinusMinus,
68         OpAndEq,
69         OpXOrEq,
70         OpOrEq,
71         OpModEq,
72         OpLShift,
73         OpRShift,
74         OpURShift
75     };
76     
77     enum LogicalOperator {
78         OpLogicalAnd,
79         OpLogicalOr
80     };
81
82     enum Precedence {
83         PrecPrimary,
84         PrecMember,
85         PrecCall,
86         PrecLeftHandSide,
87         PrecPostfix,
88         PrecUnary,
89         PrecMultiplicative,
90         PrecAdditive,
91         PrecShift,
92         PrecRelational,
93         PrecEquality,
94         PrecBitwiseAnd,
95         PrecBitwiseXor,
96         PrecBitwiseOr,
97         PrecLogicalAnd,
98         PrecLogicalOr,
99         PrecConditional,
100         PrecAssignment,
101         PrecExpression
102     };
103
104     struct DeclarationStacks {
105         typedef Vector<Node*, 16> NodeStack;
106         enum { IsConstant = 1, HasInitializer = 2 } VarAttrs;
107         typedef Vector<std::pair<Identifier, unsigned>, 16> VarStack;
108         typedef Vector<RefPtr<FuncDeclNode>, 16> FunctionStack;
109
110         DeclarationStacks(ExecState* e, NodeStack& n, VarStack& v, FunctionStack& f)
111             : exec(e)
112             , nodeStack(n)
113             , varStack(v)
114             , functionStack(f)
115         {
116         }
117
118         ExecState* exec;
119         NodeStack& nodeStack;
120         VarStack& varStack;
121         FunctionStack& functionStack;
122     };
123
124     struct SwitchInfo {
125         enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
126         uint32_t opcodeOffset;
127         SwitchType switchType;
128     };
129
130     class ParserRefCounted : Noncopyable {
131     protected:
132         ParserRefCounted(JSGlobalData*) KJS_FAST_CALL;
133
134         JSGlobalData* m_globalData;
135
136     public:
137         void ref() KJS_FAST_CALL;
138         void deref() KJS_FAST_CALL;
139         bool hasOneRef() KJS_FAST_CALL;
140
141         static void deleteNewObjects(JSGlobalData*) KJS_FAST_CALL;
142
143         virtual ~ParserRefCounted();
144     };
145
146     class Node : public ParserRefCounted {
147     public:
148         typedef DeclarationStacks::NodeStack NodeStack;
149         typedef DeclarationStacks::VarStack VarStack;
150         typedef DeclarationStacks::FunctionStack FunctionStack;
151
152         Node(JSGlobalData*) KJS_FAST_CALL;
153
154         /*
155             Return value: The register holding the production's value.
156                      dst: An optional parameter specifying the most efficient
157                           destination at which to store the production's value.
158                           The callee must honor dst.
159
160             dst provides for a crude form of copy propagation. For example,
161
162             x = 1
163
164             becomes
165             
166             load r[x], 1
167             
168             instead of 
169
170             load r0, 1
171             mov r[x], r0
172             
173             because the assignment node, "x =", passes r[x] as dst to the number
174             node, "1".
175         */
176         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) KJS_FAST_CALL 
177         {
178             ASSERT_WITH_MESSAGE(0, "Don't know how to generate code for:\n%s\n", toString().ascii());
179             UNUSED_PARAM(dst); 
180             return 0; 
181         } // FIXME: Make this pure virtual.
182
183         UString toString() const KJS_FAST_CALL;
184         int lineNo() const { return m_line; }
185
186         virtual bool isReturnNode() const KJS_FAST_CALL { return false; }
187
188         // Serialization.
189         virtual void streamTo(SourceStream&) const KJS_FAST_CALL = 0;
190         virtual Precedence precedence() const = 0;
191         virtual bool needsParensIfLeftmost() const { return false; }
192         
193     protected:
194         Node(JSGlobalData*, JSType) KJS_FAST_CALL; // used by ExpressionNode
195
196         int m_line : 28;
197         unsigned m_expectedReturnType : 3; // JSType
198     };
199
200     class ExpressionNode : public Node {
201     public:
202         ExpressionNode(JSGlobalData* globalData) KJS_FAST_CALL : Node(globalData) {}
203         ExpressionNode(JSGlobalData* globalData, JSType expectedReturn) KJS_FAST_CALL
204             : Node(globalData, expectedReturn)
205         {
206         }
207
208         virtual bool isNumber() const KJS_FAST_CALL { return false; }
209         virtual bool isString() const KJS_FAST_CALL { return false; }
210         virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return false; }        
211         virtual bool isLocation() const KJS_FAST_CALL { return false; }
212         virtual bool isResolveNode() const KJS_FAST_CALL { return false; }
213         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return false; }
214         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return false; }
215
216         JSType expectedReturnType() const KJS_FAST_CALL { return static_cast<JSType>(m_expectedReturnType); }
217
218         // This needs to be in public in order to compile using GCC 3.x 
219         typedef enum { EvalOperator, FunctionCall } CallerType;
220     };
221
222     class StatementNode : public Node {
223     public:
224         StatementNode(JSGlobalData*) KJS_FAST_CALL;
225         void setLoc(int line0, int line1) KJS_FAST_CALL;
226         int firstLine() const KJS_FAST_CALL { return lineNo(); }
227         int lastLine() const KJS_FAST_CALL { return m_lastLine; }
228
229         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_labelStack.push(ident); }
230         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
231         virtual bool isEmptyStatement() const KJS_FAST_CALL { return false; }
232
233     protected:
234         LabelStack m_labelStack;
235
236     private:
237         int m_lastLine;
238     };
239
240     class NullNode : public ExpressionNode {
241     public:
242         NullNode(JSGlobalData* globalData) KJS_FAST_CALL
243             : ExpressionNode(globalData, NullType)
244         {
245         }
246
247         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
248
249         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
250         virtual Precedence precedence() const { return PrecPrimary; }
251     };
252
253     class BooleanNode : public ExpressionNode {
254     public:
255         BooleanNode(JSGlobalData* globalData, bool value) KJS_FAST_CALL
256             : ExpressionNode(globalData, BooleanType)
257             , m_value(value)
258         {
259         }
260
261         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
262
263         virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
264         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
265         virtual Precedence precedence() const { return PrecPrimary; }
266
267     protected:
268         bool m_value;
269     };
270
271     class NumberNode : public ExpressionNode {
272     public:
273         NumberNode(JSGlobalData* globalData, double v) KJS_FAST_CALL
274             : ExpressionNode(globalData, NumberType)
275             , m_double(v)
276         {
277         }
278
279         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
280
281         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
282         virtual Precedence precedence() const { return signbit(m_double) ? PrecUnary : PrecPrimary; }
283
284         virtual bool isNumber() const KJS_FAST_CALL { return true; }
285         virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
286         double value() const KJS_FAST_CALL { return m_double; }
287         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; }
288
289     protected:
290         double m_double;
291     };
292
293     class ImmediateNumberNode : public NumberNode {
294     public:
295         ImmediateNumberNode(JSGlobalData* globalData, JSValue* v, double d) KJS_FAST_CALL
296             : NumberNode(globalData, d)
297             , m_value(v)
298         {
299             ASSERT(v == JSImmediate::from(d));
300         }
301
302         virtual void setValue(double d) KJS_FAST_CALL { m_double = d; m_value = JSImmediate::from(d); ASSERT(m_value); }
303
304     private:
305         JSValue* m_value; // This is never a JSCell, only JSImmediate, thus no ProtectedPtr
306     };
307
308     class StringNode : public ExpressionNode {
309     public:
310         StringNode(JSGlobalData* globalData, const UString* v) KJS_FAST_CALL
311             : ExpressionNode(globalData, StringType)
312             , m_value(*v)
313         {
314         }
315
316         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
317         
318         virtual bool isString() const KJS_FAST_CALL { return true; }
319         UString& value() { return m_value; }
320         virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL { return true; }
321         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
322         virtual Precedence precedence() const { return PrecPrimary; }
323
324     private:
325         UString m_value;
326     };
327     
328     class ThrowableExpressionData {
329     public:
330         ThrowableExpressionData()
331             : m_divot(static_cast<uint32_t>(-1))
332             , m_startOffset(static_cast<uint16_t>(-1))
333             , m_endOffset(static_cast<uint16_t>(-1))
334         {
335         }
336         
337         ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
338             : m_divot(divot)
339             , m_startOffset(startOffset)
340             , m_endOffset(endOffset)
341         {
342         }
343         
344         void setExceptionSourceRange(unsigned divot, unsigned startOffset, unsigned endOffset)
345         {
346             m_divot = divot;
347             m_startOffset = startOffset;
348             m_endOffset = endOffset;
349         }
350
351         uint32_t divot() const { return m_divot; }
352         uint16_t startOffset() const { return m_startOffset; }
353         uint16_t endOffset() const { return m_endOffset; }
354
355     protected:
356         RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg);
357         RegisterID* emitThrowError(CodeGenerator&, ErrorType, const char* msg, const Identifier&);
358         uint32_t m_divot;
359         uint16_t m_startOffset;
360         uint16_t m_endOffset;
361     };
362
363     class ThrowableSubExpressionData : public ThrowableExpressionData {
364     public:
365         ThrowableSubExpressionData()
366             : ThrowableExpressionData()
367             , m_subexpressionDivotOffset(0)
368             , m_subexpressionEndOffset(0)
369         {
370         }
371
372         ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
373             : ThrowableExpressionData(divot, startOffset, endOffset)
374             , m_subexpressionDivotOffset(0)
375             , m_subexpressionEndOffset(0)
376         {
377         }
378
379         void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
380             ASSERT(subexpressionDivot <= m_divot);
381             if ((m_divot - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
382                 return;
383             m_subexpressionDivotOffset = m_divot - subexpressionDivot;
384             m_subexpressionEndOffset = subexpressionOffset;
385         }
386
387     protected:
388         uint16_t m_subexpressionDivotOffset;
389         uint16_t m_subexpressionEndOffset;
390     };
391     
392     class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
393     public:
394         ThrowablePrefixedSubExpressionData()
395             : ThrowableExpressionData()
396             , m_subexpressionDivotOffset(0)
397             , m_subexpressionStartOffset(0)
398         {
399         }
400
401         ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
402             : ThrowableExpressionData(divot, startOffset, endOffset)
403             , m_subexpressionDivotOffset(0)
404             , m_subexpressionStartOffset(0)
405         {
406         }
407
408         void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset) {
409             ASSERT(subexpressionDivot >= m_divot);
410             if ((subexpressionDivot - m_divot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
411                 return;
412             m_subexpressionDivotOffset = subexpressionDivot - m_divot;
413             m_subexpressionStartOffset = subexpressionOffset;
414         }
415
416     protected:
417         uint16_t m_subexpressionDivotOffset;
418         uint16_t m_subexpressionStartOffset;
419     };
420
421     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
422     public:
423         RegExpNode(JSGlobalData* globalData, const UString& pattern, const UString& flags) KJS_FAST_CALL
424             : ExpressionNode(globalData)
425             , m_regExp(RegExp::create(pattern, flags))
426         {
427         }
428
429         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
430
431         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
432         virtual Precedence precedence() const { return PrecPrimary; }
433
434     private:
435         RefPtr<RegExp> m_regExp;
436     };
437
438     class ThisNode : public ExpressionNode {
439     public:
440         ThisNode(JSGlobalData* globalData) KJS_FAST_CALL
441             : ExpressionNode(globalData)
442         {
443         }
444
445         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
446
447         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
448         virtual Precedence precedence() const { return PrecPrimary; }
449     };
450
451     class ResolveNode : public ExpressionNode {
452     public:
453         ResolveNode(JSGlobalData* globalData, const Identifier& ident, int startOffset) KJS_FAST_CALL
454             : ExpressionNode(globalData)
455             , m_ident(ident)
456             , m_startOffset(startOffset)
457         {
458         }
459
460         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
461
462         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
463         virtual Precedence precedence() const { return PrecPrimary; }
464
465         virtual bool isPure(CodeGenerator&) const KJS_FAST_CALL;
466         virtual bool isLocation() const KJS_FAST_CALL { return true; }
467         virtual bool isResolveNode() const KJS_FAST_CALL { return true; }
468         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
469
470     protected:
471         Identifier m_ident;
472         int32_t m_startOffset;
473         
474     };
475
476     class ElementNode : public Node {
477     public:
478         ElementNode(JSGlobalData* globalData, int elision, ExpressionNode* node) KJS_FAST_CALL
479             : Node(globalData)
480             , m_elision(elision)
481             , m_node(node)
482         {
483         }
484
485         ElementNode(JSGlobalData* globalData, ElementNode* l, int elision, ExpressionNode* node) KJS_FAST_CALL
486             : Node(globalData)
487             , m_elision(elision)
488             , m_node(node)
489         {
490             l->m_next = this;
491         }
492
493         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
494         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
495
496         int elision() const { return m_elision; }
497         ExpressionNode* value() { return m_node.get(); }
498
499         ElementNode* next() { return m_next.get(); }
500         PassRefPtr<ElementNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
501
502     private:
503         ListRefPtr<ElementNode> m_next;
504         int m_elision;
505         RefPtr<ExpressionNode> m_node;
506     };
507
508     class ArrayNode : public ExpressionNode {
509     public:
510         ArrayNode(JSGlobalData* globalData, int elision) KJS_FAST_CALL
511             : ExpressionNode(globalData)
512             , m_elision(elision)
513             , m_optional(true)
514         {
515         }
516
517         ArrayNode(JSGlobalData* globalData, ElementNode* element) KJS_FAST_CALL
518             : ExpressionNode(globalData)
519             , m_element(element)
520             , m_elision(0)
521             , m_optional(false)
522         {
523         }
524
525         ArrayNode(JSGlobalData* globalData, int elision, ElementNode* element) KJS_FAST_CALL
526             : ExpressionNode(globalData)
527             , m_element(element)
528             , m_elision(elision)
529             , m_optional(true)
530         {
531         }
532
533         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
534
535         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
536         virtual Precedence precedence() const { return PrecPrimary; }
537
538     private:
539         RefPtr<ElementNode> m_element;
540         int m_elision;
541         bool m_optional;
542     };
543
544     class PropertyNode : public Node {
545     public:
546         enum Type { Constant, Getter, Setter };
547
548         PropertyNode(JSGlobalData* globalData, const Identifier& name, ExpressionNode* assign, Type type) KJS_FAST_CALL
549             : Node(globalData)
550             , m_name(name)
551             , m_assign(assign)
552             , m_type(type)
553         {
554         }
555
556         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
557         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
558
559         const Identifier& name() const { return m_name; }
560
561     private:
562         friend class PropertyListNode;
563         Identifier m_name;
564         RefPtr<ExpressionNode> m_assign;
565         Type m_type;
566     };
567
568     class PropertyListNode : public Node {
569     public:
570         PropertyListNode(JSGlobalData* globalData, PropertyNode* node) KJS_FAST_CALL
571             : Node(globalData)
572             , m_node(node)
573         {
574         }
575
576         PropertyListNode(JSGlobalData* globalData, PropertyNode* node, PropertyListNode* list) KJS_FAST_CALL
577             : Node(globalData)
578             , m_node(node)
579         {
580             list->m_next = this;
581         }
582
583         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
584         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
585         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
586
587         PassRefPtr<PropertyListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
588
589     private:
590         friend class ObjectLiteralNode;
591         RefPtr<PropertyNode> m_node;
592         ListRefPtr<PropertyListNode> m_next;
593     };
594
595     class ObjectLiteralNode : public ExpressionNode {
596     public:
597         ObjectLiteralNode(JSGlobalData* globalData) KJS_FAST_CALL
598             : ExpressionNode(globalData)
599         {
600         }
601
602         ObjectLiteralNode(JSGlobalData* globalData, PropertyListNode* list) KJS_FAST_CALL
603             : ExpressionNode(globalData)
604             , m_list(list)
605         {
606         }
607
608         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
609         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
610         virtual Precedence precedence() const { return PrecPrimary; }
611         virtual bool needsParensIfLeftmost() const { return true; }
612
613     private:
614         RefPtr<PropertyListNode> m_list;
615     };
616     
617     class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
618     public:
619         BracketAccessorNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments) KJS_FAST_CALL
620             : ExpressionNode(globalData)
621             , m_base(base)
622             , m_subscript(subscript)
623             , m_subscriptHasAssignments(subscriptHasAssignments)
624         {
625         }
626
627         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
628
629         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
630         virtual Precedence precedence() const { return PrecMember; }
631
632         virtual bool isLocation() const KJS_FAST_CALL { return true; }
633         virtual bool isBracketAccessorNode() const KJS_FAST_CALL { return true; }
634         ExpressionNode* base() KJS_FAST_CALL { return m_base.get(); }
635         ExpressionNode* subscript() KJS_FAST_CALL { return m_subscript.get(); }
636
637     private:
638         RefPtr<ExpressionNode> m_base;
639         RefPtr<ExpressionNode> m_subscript;
640         bool m_subscriptHasAssignments;
641     };
642
643     class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
644     public:
645         DotAccessorNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident) KJS_FAST_CALL
646             : ExpressionNode(globalData)
647             , m_base(base)
648             , m_ident(ident)
649         {
650         }
651
652         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
653         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
654         virtual Precedence precedence() const { return PrecMember; }
655
656         virtual bool isLocation() const KJS_FAST_CALL { return true; }
657         virtual bool isDotAccessorNode() const KJS_FAST_CALL { return true; }
658         ExpressionNode* base() const KJS_FAST_CALL { return m_base.get(); }
659         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
660
661     private:
662         RefPtr<ExpressionNode> m_base;
663         Identifier m_ident;
664     };
665
666     class ArgumentListNode : public Node {
667     public:
668         ArgumentListNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
669             : Node(globalData)
670             , m_expr(expr)
671         {
672         }
673
674         ArgumentListNode(JSGlobalData* globalData, ArgumentListNode* listNode, ExpressionNode* expr) KJS_FAST_CALL
675             : Node(globalData)
676             , m_expr(expr)
677         {
678             listNode->m_next = this;
679         }
680
681         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
682         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
683         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
684
685         PassRefPtr<ArgumentListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
686
687         ListRefPtr<ArgumentListNode> m_next;
688         RefPtr<ExpressionNode> m_expr;
689     };
690
691     class ArgumentsNode : public Node {
692     public:
693         ArgumentsNode(JSGlobalData* globalData) KJS_FAST_CALL
694             : Node(globalData)
695         {
696         }
697
698         ArgumentsNode(JSGlobalData* globalData, ArgumentListNode* listNode) KJS_FAST_CALL
699             : Node(globalData)
700             , m_listNode(listNode)
701         {
702         }
703
704         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
705         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
706
707         RefPtr<ArgumentListNode> m_listNode;
708     };
709
710     class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
711     public:
712         NewExprNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
713             : ExpressionNode(globalData)
714             , m_expr(expr)
715         {
716         }
717
718         NewExprNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args) KJS_FAST_CALL
719             : ExpressionNode(globalData)
720             , m_expr(expr)
721             , m_args(args)
722         {
723         }
724
725         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
726
727         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
728         virtual Precedence precedence() const { return PrecLeftHandSide; }
729
730     private:
731         RefPtr<ExpressionNode> m_expr;
732         RefPtr<ArgumentsNode> m_args;
733     };
734
735     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
736     public:
737         EvalFunctionCallNode(JSGlobalData* globalData, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
738             : ExpressionNode(globalData)
739             , ThrowableExpressionData(divot, startOffset, endOffset)
740             , m_args(args)
741         {
742         }
743
744         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
745         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
746         virtual Precedence precedence() const { return PrecCall; }
747
748     private:
749         RefPtr<ArgumentsNode> m_args;
750     };
751
752     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
753     public:
754         FunctionCallValueNode(JSGlobalData* globalData, ExpressionNode* expr, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
755             : ExpressionNode(globalData)
756             , ThrowableExpressionData(divot, startOffset, endOffset)
757             , m_expr(expr)
758             , m_args(args)
759         {
760         }
761
762         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
763         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
764         virtual Precedence precedence() const { return PrecCall; }
765
766     private:
767         RefPtr<ExpressionNode> m_expr;
768         RefPtr<ArgumentsNode> m_args;
769     };
770
771     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
772     public:
773         FunctionCallResolveNode(JSGlobalData* globalData, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
774             : ExpressionNode(globalData)
775             , ThrowableExpressionData(divot, startOffset, endOffset)
776             , m_ident(ident)
777             , m_args(args)
778         {
779         }
780
781         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
782
783         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
784         virtual Precedence precedence() const { return PrecCall; }
785
786     protected:
787         Identifier m_ident;
788         RefPtr<ArgumentsNode> m_args;
789         size_t m_index; // Used by LocalVarFunctionCallNode.
790         size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
791     };
792     
793     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
794     public:
795         FunctionCallBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
796             : ExpressionNode(globalData)
797             , ThrowableSubExpressionData(divot, startOffset, endOffset)
798             , m_base(base)
799             , m_subscript(subscript)
800             , m_args(args)
801         {
802         }
803
804         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
805         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
806         virtual Precedence precedence() const { return PrecCall; }
807
808     protected:
809         RefPtr<ExpressionNode> m_base;
810         RefPtr<ExpressionNode> m_subscript;
811         RefPtr<ArgumentsNode> m_args;
812     };
813
814     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
815     public:
816         FunctionCallDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ArgumentsNode* args, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
817             : ExpressionNode(globalData)
818             , ThrowableSubExpressionData(divot, startOffset, endOffset)
819             , m_base(base)
820             , m_ident(ident)
821             , m_args(args)
822         {
823         }
824
825         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
826         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
827         virtual Precedence precedence() const { return PrecCall; }
828
829     private:
830         RefPtr<ExpressionNode> m_base;
831         Identifier m_ident;
832         RefPtr<ArgumentsNode> m_args;
833     };
834
835     class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
836     public:
837         PrePostResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
838             : ExpressionNode(globalData, NumberType)
839             , ThrowableExpressionData(divot, startOffset, endOffset)
840             , m_ident(ident)
841         {
842         }
843
844     protected:
845         Identifier m_ident;
846     };
847
848     class PostfixResolveNode : public PrePostResolveNode {
849     public:
850         PostfixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
851             : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
852             , m_operator(oper)
853         {
854         }
855
856         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
857         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
858         virtual Precedence precedence() const { return PrecPostfix; }
859
860     protected:
861         Operator m_operator;
862     };
863
864     class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
865     public:
866         PostfixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
867             : ExpressionNode(globalData)
868             , ThrowableSubExpressionData(divot, startOffset, endOffset)
869             , m_base(base)
870             , m_subscript(subscript)
871             , m_operator(oper)
872         {
873         }
874
875         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
876         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
877         virtual Precedence precedence() const { return PrecPostfix; }
878
879     protected:
880         RefPtr<ExpressionNode> m_base;
881         RefPtr<ExpressionNode> m_subscript;
882         Operator m_operator;
883     };
884
885     class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
886     public:
887         PostfixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
888             : ExpressionNode(globalData)
889             , ThrowableSubExpressionData(divot, startOffset, endOffset)
890             , m_base(base)
891             , m_ident(ident)
892             , m_operator(oper)
893         {
894         }
895
896         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
897         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
898         virtual Precedence precedence() const { return PrecPostfix; }
899
900     protected:
901         RefPtr<ExpressionNode> m_base;
902         Identifier m_ident;
903         Operator m_operator;
904     };
905
906     class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
907     public:
908         PostfixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
909             : ExpressionNode(globalData)
910             , ThrowableSubExpressionData(divot, startOffset, endOffset)
911             , m_expr(expr)
912             , m_operator(oper)
913         {
914         }
915
916         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
917         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
918         virtual Precedence precedence() const { return PrecPostfix; }
919
920     private:
921         RefPtr<ExpressionNode> m_expr;
922         Operator m_operator;
923     };
924
925     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
926     public:
927         DeleteResolveNode(JSGlobalData* globalData, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
928             : ExpressionNode(globalData)
929             , ThrowableExpressionData(divot, startOffset, endOffset)
930             , m_ident(ident)
931         {
932         }
933
934         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
935
936         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
937         virtual Precedence precedence() const { return PrecUnary; }
938
939     private:
940         Identifier m_ident;
941     };
942
943     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
944     public:
945         DeleteBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
946             : ExpressionNode(globalData)
947             , ThrowableExpressionData(divot, startOffset, endOffset)
948             , m_base(base)
949             , m_subscript(subscript)
950         {
951         }
952
953         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
954
955         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
956         virtual Precedence precedence() const { return PrecUnary; }
957
958     private:
959         RefPtr<ExpressionNode> m_base;
960         RefPtr<ExpressionNode> m_subscript;
961     };
962
963     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
964     public:
965         DeleteDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
966             : ExpressionNode(globalData)
967             , ThrowableExpressionData(divot, startOffset, endOffset)
968             , m_base(base)
969             , m_ident(ident)
970         {
971         }
972
973         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
974
975         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
976         virtual Precedence precedence() const { return PrecUnary; }
977
978     private:
979         RefPtr<ExpressionNode> m_base;
980         Identifier m_ident;
981     };
982
983     class DeleteValueNode : public ExpressionNode {
984     public:
985         DeleteValueNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
986             : ExpressionNode(globalData)
987             , m_expr(expr)
988         {
989         }
990
991         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
992
993         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
994         virtual Precedence precedence() const { return PrecUnary; }
995
996     private:
997         RefPtr<ExpressionNode> m_expr;
998     };
999
1000     class VoidNode : public ExpressionNode {
1001     public:
1002         VoidNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1003             : ExpressionNode(globalData)
1004             , m_expr(expr)
1005         {
1006         }
1007
1008         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1009
1010         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1011         virtual Precedence precedence() const { return PrecUnary; }
1012
1013     private:
1014         RefPtr<ExpressionNode> m_expr;
1015     };
1016
1017     class TypeOfResolveNode : public ExpressionNode {
1018     public:
1019         TypeOfResolveNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL
1020             : ExpressionNode(globalData, StringType)
1021             , m_ident(ident)
1022         {
1023         }
1024
1025         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1026
1027         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1028         virtual Precedence precedence() const { return PrecUnary; }
1029
1030         const Identifier& identifier() const KJS_FAST_CALL { return m_ident; }
1031
1032     protected:
1033         Identifier m_ident;
1034         size_t m_index; // Used by LocalTypeOfNode.
1035     };
1036
1037     class TypeOfValueNode : public ExpressionNode {
1038     public:
1039         TypeOfValueNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1040             : ExpressionNode(globalData, StringType)
1041             , m_expr(expr)
1042         {
1043         }
1044
1045         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1046
1047         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1048         virtual Precedence precedence() const { return PrecUnary; }
1049
1050     private:
1051         RefPtr<ExpressionNode> m_expr;
1052     };
1053
1054     class PrefixResolveNode : public PrePostResolveNode {
1055     public:
1056         PrefixResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1057             : PrePostResolveNode(globalData, ident, divot, startOffset, endOffset)
1058             , m_operator(oper)
1059         {
1060         }
1061
1062         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1063
1064         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1065         virtual Precedence precedence() const { return PrecUnary; }
1066
1067     protected:
1068         Operator m_operator;
1069     };
1070
1071     class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
1072     public:
1073         PrefixBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1074             : ExpressionNode(globalData)
1075             , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
1076             , m_base(base)
1077             , m_subscript(subscript)
1078             , m_operator(oper)
1079         {
1080         }
1081
1082         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1083         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1084         virtual Precedence precedence() const { return PrecUnary; }
1085
1086     protected:
1087         RefPtr<ExpressionNode> m_base;
1088         RefPtr<ExpressionNode> m_subscript;
1089         Operator m_operator;
1090     };
1091
1092     class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
1093     public:
1094         PrefixDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1095             : ExpressionNode(globalData)
1096             , ThrowablePrefixedSubExpressionData(divot, startOffset, endOffset)
1097             , m_base(base)
1098             , m_ident(ident)
1099             , m_operator(oper)
1100         {
1101         }
1102
1103         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1104         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1105         virtual Precedence precedence() const { return PrecPostfix; }
1106
1107     protected:
1108         RefPtr<ExpressionNode> m_base;
1109         Identifier m_ident;
1110         Operator m_operator;
1111     };
1112
1113     class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
1114     public:
1115         PrefixErrorNode(JSGlobalData* globalData, ExpressionNode* expr, Operator oper, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1116             : ExpressionNode(globalData)
1117             , ThrowableExpressionData(divot, startOffset, endOffset)
1118             , m_expr(expr)
1119             , m_operator(oper)
1120         {
1121         }
1122
1123         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1124         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1125         virtual Precedence precedence() const { return PrecUnary; }
1126
1127     private:
1128         RefPtr<ExpressionNode> m_expr;
1129         Operator m_operator;
1130     };
1131
1132     class UnaryOpNode : public ExpressionNode {
1133     public:
1134         UnaryOpNode(JSGlobalData* globalData, ExpressionNode* expr)
1135             : ExpressionNode(globalData)
1136             , m_expr(expr)
1137         {
1138         }
1139
1140         UnaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* expr)
1141             : ExpressionNode(globalData, type)
1142             , m_expr(expr)
1143         {
1144         }
1145
1146         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1147         virtual OpcodeID opcode() const KJS_FAST_CALL = 0;
1148
1149     protected:
1150         RefPtr<ExpressionNode> m_expr;
1151     };
1152
1153     class UnaryPlusNode : public UnaryOpNode {
1154     public:
1155         UnaryPlusNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1156             : UnaryOpNode(globalData, NumberType, expr)
1157         {
1158         }
1159
1160         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_to_jsnumber; }
1161         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1162         virtual Precedence precedence() const { return PrecUnary; }
1163     };
1164
1165     class NegateNode : public UnaryOpNode {
1166     public:
1167         NegateNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1168             : UnaryOpNode(globalData, NumberType, expr)
1169         {
1170         }
1171
1172         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_negate; }
1173         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1174         virtual Precedence precedence() const { return PrecUnary; }
1175     };
1176
1177     class BitwiseNotNode : public UnaryOpNode {
1178     public:
1179         BitwiseNotNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1180             : UnaryOpNode(globalData, NumberType, expr)
1181         {
1182         }
1183
1184         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_bitnot; }
1185         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1186         virtual Precedence precedence() const { return PrecUnary; }
1187     };
1188
1189     class LogicalNotNode : public UnaryOpNode {
1190     public:
1191         LogicalNotNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1192             : UnaryOpNode(globalData, BooleanType, expr)
1193         {
1194         }
1195
1196         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_not; }
1197         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1198         virtual Precedence precedence() const { return PrecUnary; }
1199     };
1200
1201     class BinaryOpNode : public ExpressionNode {
1202     public:
1203         BinaryOpNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments)
1204             : ExpressionNode(globalData)
1205             , m_term1(term1)
1206             , m_term2(term2)
1207             , m_rightHasAssignments(rightHasAssignments)
1208         {
1209         }
1210
1211         BinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments)
1212             : ExpressionNode(globalData, type)
1213             , m_term1(term1)
1214             , m_term2(term2)
1215             , m_rightHasAssignments(rightHasAssignments)
1216         {
1217         }
1218
1219         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1220         virtual OpcodeID opcode() const KJS_FAST_CALL = 0;
1221
1222     protected:
1223         RefPtr<ExpressionNode> m_term1;
1224         RefPtr<ExpressionNode> m_term2;
1225         bool m_rightHasAssignments;
1226     };
1227
1228     class ReverseBinaryOpNode : public ExpressionNode {
1229     public:
1230         ReverseBinaryOpNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments)
1231             : ExpressionNode(globalData)
1232             , m_term1(term1)
1233             , m_term2(term2)
1234             , m_rightHasAssignments(rightHasAssignments)
1235         {
1236         }
1237
1238         ReverseBinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments)
1239             : ExpressionNode(globalData, type)
1240             , m_term1(term1)
1241             , m_term2(term2)
1242             , m_rightHasAssignments(rightHasAssignments)
1243         {
1244         }
1245
1246         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1247         virtual OpcodeID opcode() const KJS_FAST_CALL = 0;
1248
1249     protected:
1250         RefPtr<ExpressionNode> m_term1;
1251         RefPtr<ExpressionNode> m_term2;
1252         bool m_rightHasAssignments;
1253     };
1254
1255     class MultNode : public BinaryOpNode {
1256     public:
1257         MultNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1258             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1259         {
1260         }
1261
1262         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_mul; }
1263         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1264         virtual Precedence precedence() const { return PrecMultiplicative; }
1265     };
1266
1267     class DivNode : public BinaryOpNode {
1268     public:
1269         DivNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1270             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1271         {
1272         }
1273
1274         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_div; }
1275         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1276         virtual Precedence precedence() const { return PrecMultiplicative; }
1277     };
1278
1279     class ModNode : public BinaryOpNode {
1280     public:
1281         ModNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1282             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1283         {
1284         }
1285
1286         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_mod; }
1287         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1288         virtual Precedence precedence() const { return PrecMultiplicative; }
1289     };
1290
1291     class AddNode : public BinaryOpNode {
1292     public:
1293         AddNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1294             : BinaryOpNode(globalData, term1, term2, rightHasAssignments)
1295         {
1296         }
1297
1298         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_add; }
1299         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1300         virtual Precedence precedence() const { return PrecAdditive; }
1301     };
1302
1303     class SubNode : public BinaryOpNode {
1304     public:
1305         SubNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1306             : BinaryOpNode(globalData, term1, term2, rightHasAssignments)
1307         {
1308         }
1309
1310         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_sub; }
1311         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1312         virtual Precedence precedence() const { return PrecAdditive; }
1313     };
1314
1315     class LeftShiftNode : public BinaryOpNode {
1316     public:
1317         LeftShiftNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1318             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1319         {
1320         }
1321
1322         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_lshift; }
1323         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1324         virtual Precedence precedence() const { return PrecShift; }
1325     };
1326
1327     class RightShiftNode : public BinaryOpNode {
1328     public:
1329         RightShiftNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1330             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1331         {
1332         }
1333
1334         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_rshift; }
1335         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1336         virtual Precedence precedence() const { return PrecShift; }
1337     };
1338
1339     class UnsignedRightShiftNode : public BinaryOpNode {
1340     public:
1341         UnsignedRightShiftNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1342             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1343         {
1344         }
1345
1346         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_urshift; }
1347         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1348         virtual Precedence precedence() const { return PrecShift; }
1349     };
1350
1351     class LessNode : public BinaryOpNode {
1352     public:
1353         LessNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1354             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1355         {
1356         }
1357
1358         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_less; }
1359         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1360         virtual Precedence precedence() const { return PrecRelational; }
1361     };
1362
1363     class GreaterNode : public ReverseBinaryOpNode {
1364     public:
1365         GreaterNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1366             : ReverseBinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1367         {
1368         }
1369
1370         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_less; }
1371         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1372         virtual Precedence precedence() const { return PrecRelational; }
1373     };
1374
1375     class LessEqNode : public BinaryOpNode {
1376     public:
1377         LessEqNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1378             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1379         {
1380         }
1381
1382         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_lesseq; }
1383         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1384         virtual Precedence precedence() const { return PrecRelational; }
1385     };
1386
1387     class GreaterEqNode : public ReverseBinaryOpNode {
1388     public:
1389         GreaterEqNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1390             : ReverseBinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1391         {
1392         }
1393
1394         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_lesseq; }
1395         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1396         virtual Precedence precedence() const { return PrecRelational; }
1397     };
1398
1399     class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
1400     public:
1401         ThrowableBinaryOpNode(JSGlobalData* globalData, JSType type, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1402             : BinaryOpNode(globalData, type, term1, term2, rightHasAssignments)
1403         {
1404         }
1405         ThrowableBinaryOpNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1406             : BinaryOpNode(globalData, term1, term2, rightHasAssignments)
1407         {
1408         }
1409         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1410     };
1411     
1412     class InstanceOfNode : public ThrowableBinaryOpNode {
1413     public:
1414         InstanceOfNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1415             : ThrowableBinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1416         {
1417         }
1418
1419         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_instanceof; }
1420         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1421         virtual Precedence precedence() const { return PrecRelational; }
1422     };
1423
1424     class InNode : public ThrowableBinaryOpNode {
1425     public:
1426         InNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1427             : ThrowableBinaryOpNode(globalData, term1, term2, rightHasAssignments)
1428         {
1429         }
1430
1431         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_in; }
1432         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1433         virtual Precedence precedence() const { return PrecRelational; }
1434     };
1435
1436     class EqualNode : public BinaryOpNode {
1437     public:
1438         EqualNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1439             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1440         {
1441         }
1442
1443         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_eq; }
1444         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1445         virtual Precedence precedence() const { return PrecEquality; }
1446     };
1447
1448     class NotEqualNode : public BinaryOpNode {
1449     public:
1450         NotEqualNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1451             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1452         {
1453         }
1454
1455         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_neq; }
1456         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1457         virtual Precedence precedence() const { return PrecEquality; }
1458     };
1459
1460     class StrictEqualNode : public BinaryOpNode {
1461     public:
1462         StrictEqualNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1463             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1464         {
1465         }
1466
1467         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_stricteq; }
1468         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1469         virtual Precedence precedence() const { return PrecEquality; }
1470     };
1471
1472     class NotStrictEqualNode : public BinaryOpNode {
1473     public:
1474         NotStrictEqualNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1475             : BinaryOpNode(globalData, BooleanType, term1, term2, rightHasAssignments)
1476         {
1477         }
1478
1479         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_nstricteq; }
1480         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1481         virtual Precedence precedence() const { return PrecEquality; }
1482     };
1483
1484     class BitAndNode : public BinaryOpNode {
1485     public:
1486         BitAndNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1487             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1488         {
1489         }
1490
1491         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_bitand; }
1492         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1493         virtual Precedence precedence() const { return PrecBitwiseAnd; }
1494     };
1495
1496     class BitOrNode : public BinaryOpNode {
1497     public:
1498         BitOrNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1499             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1500         {
1501         }
1502
1503         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_bitor; }
1504         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1505         virtual Precedence precedence() const { return PrecBitwiseOr; }
1506     };
1507
1508     class BitXOrNode : public BinaryOpNode {
1509     public:
1510         BitXOrNode(JSGlobalData* globalData, ExpressionNode* term1, ExpressionNode* term2, bool rightHasAssignments) KJS_FAST_CALL
1511             : BinaryOpNode(globalData, NumberType, term1, term2, rightHasAssignments)
1512         {
1513         }
1514
1515         virtual OpcodeID opcode() const KJS_FAST_CALL { return op_bitxor; }
1516         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1517         virtual Precedence precedence() const { return PrecBitwiseXor; }
1518     };
1519
1520     /**
1521      * m_expr1 && m_expr2, m_expr1 || m_expr2
1522      */
1523     class LogicalOpNode : public ExpressionNode {
1524     public:
1525         LogicalOpNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator oper) KJS_FAST_CALL
1526             : ExpressionNode(globalData, BooleanType)
1527             , m_expr1(expr1)
1528             , m_expr2(expr2)
1529             , m_operator(oper)
1530         {
1531         }
1532
1533         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1534         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1535         virtual Precedence precedence() const { return (m_operator == OpLogicalAnd) ? PrecLogicalAnd : PrecLogicalOr; }
1536
1537     private:
1538         RefPtr<ExpressionNode> m_expr1;
1539         RefPtr<ExpressionNode> m_expr2;
1540         LogicalOperator m_operator;
1541     };
1542
1543     /**
1544      * The ternary operator, "m_logical ? m_expr1 : m_expr2"
1545      */
1546     class ConditionalNode : public ExpressionNode {
1547     public:
1548         ConditionalNode(JSGlobalData* globalData, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1549             : ExpressionNode(globalData)
1550             , m_logical(logical)
1551             , m_expr1(expr1)
1552             , m_expr2(expr2)
1553         {
1554         }
1555
1556         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1557         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1558         virtual Precedence precedence() const { return PrecConditional; }
1559
1560     private:
1561         RefPtr<ExpressionNode> m_logical;
1562         RefPtr<ExpressionNode> m_expr1;
1563         RefPtr<ExpressionNode> m_expr2;
1564     };
1565
1566     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
1567     public:
1568         ReadModifyResolveNode(JSGlobalData* globalData, const Identifier& ident, Operator oper, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1569             : ExpressionNode(globalData)
1570             , ThrowableExpressionData(divot, startOffset, endOffset)
1571             , m_ident(ident)
1572             , m_right(right)
1573             , m_operator(oper)
1574             , m_rightHasAssignments(rightHasAssignments)
1575         {
1576         }
1577
1578         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1579
1580         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1581         virtual Precedence precedence() const { return PrecAssignment; }
1582
1583     protected:
1584         Identifier m_ident;
1585         RefPtr<ExpressionNode> m_right;
1586         size_t m_index; // Used by ReadModifyLocalVarNode.
1587         Operator m_operator : 31;
1588         bool m_rightHasAssignments : 1;
1589     };
1590
1591     class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1592     public:
1593         AssignResolveNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments) KJS_FAST_CALL
1594             : ExpressionNode(globalData)
1595             , m_ident(ident)
1596             , m_right(right)
1597             , m_rightHasAssignments(rightHasAssignments)
1598         {
1599         }
1600
1601         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1602
1603         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1604         virtual Precedence precedence() const { return PrecAssignment; }
1605
1606     protected:
1607         Identifier m_ident;
1608         RefPtr<ExpressionNode> m_right;
1609         size_t m_index; // Used by ReadModifyLocalVarNode.
1610         bool m_rightHasAssignments;
1611     };
1612
1613     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1614     public:
1615         ReadModifyBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, Operator oper, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1616             : ExpressionNode(globalData)
1617             , ThrowableSubExpressionData(divot, startOffset, endOffset)
1618             , m_base(base)
1619             , m_subscript(subscript)
1620             , m_right(right)
1621             , m_operator(oper)
1622             , m_subscriptHasAssignments(subscriptHasAssignments)
1623             , m_rightHasAssignments(rightHasAssignments)
1624         {
1625         }
1626
1627         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1628
1629         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1630         virtual Precedence precedence() const { return PrecAssignment; }
1631
1632     protected:
1633         RefPtr<ExpressionNode> m_base;
1634         RefPtr<ExpressionNode> m_subscript;
1635         RefPtr<ExpressionNode> m_right;
1636         Operator m_operator : 30;
1637         bool m_subscriptHasAssignments : 1;
1638         bool m_rightHasAssignments : 1;
1639     };
1640
1641     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1642     public:
1643         AssignBracketNode(JSGlobalData* globalData, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1644             : ExpressionNode(globalData)
1645             , ThrowableExpressionData(divot, startOffset, endOffset)
1646             , m_base(base)
1647             , m_subscript(subscript)
1648             , m_right(right)
1649             , m_subscriptHasAssignments(subscriptHasAssignments)
1650             , m_rightHasAssignments(rightHasAssignments)
1651         {
1652         }
1653
1654         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1655
1656         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1657         virtual Precedence precedence() const { return PrecAssignment; }
1658
1659     protected:
1660         RefPtr<ExpressionNode> m_base;
1661         RefPtr<ExpressionNode> m_subscript;
1662         RefPtr<ExpressionNode> m_right;
1663         bool m_subscriptHasAssignments : 1;
1664         bool m_rightHasAssignments : 1;
1665     };
1666
1667     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1668     public:
1669         AssignDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1670             : ExpressionNode(globalData)
1671             , ThrowableExpressionData(divot, startOffset, endOffset)
1672             , m_base(base)
1673             , m_ident(ident)
1674             , m_right(right)
1675             , m_rightHasAssignments(rightHasAssignments)
1676         {
1677         }
1678
1679         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1680         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1681         virtual Precedence precedence() const { return PrecAssignment; }
1682
1683     protected:
1684         RefPtr<ExpressionNode> m_base;
1685         Identifier m_ident;
1686         RefPtr<ExpressionNode> m_right;
1687         bool m_rightHasAssignments;
1688     };
1689
1690     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1691     public:
1692         ReadModifyDotNode(JSGlobalData* globalData, ExpressionNode* base, const Identifier& ident, Operator oper, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1693             : ExpressionNode(globalData)
1694             , ThrowableSubExpressionData(divot, startOffset, endOffset)
1695             , m_base(base)
1696             , m_ident(ident)
1697             , m_right(right)
1698             , m_operator(oper)
1699             , m_rightHasAssignments(rightHasAssignments)
1700         {
1701         }
1702
1703         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1704
1705         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1706         virtual Precedence precedence() const { return PrecAssignment; }
1707
1708     protected:
1709         RefPtr<ExpressionNode> m_base;
1710         Identifier m_ident;
1711         RefPtr<ExpressionNode> m_right;
1712         Operator m_operator : 31;
1713         bool m_rightHasAssignments : 1;
1714     };
1715
1716     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1717     public:
1718         AssignErrorNode(JSGlobalData* globalData, ExpressionNode* left, Operator oper, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset) KJS_FAST_CALL
1719             : ExpressionNode(globalData)
1720             , ThrowableExpressionData(divot, startOffset, endOffset)
1721             , m_left(left)
1722             , m_operator(oper)
1723             , m_right(right)
1724         {
1725         }
1726
1727         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1728         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1729         virtual Precedence precedence() const { return PrecAssignment; }
1730
1731     protected:
1732         RefPtr<ExpressionNode> m_left;
1733         Operator m_operator;
1734         RefPtr<ExpressionNode> m_right;
1735     };
1736
1737     class CommaNode : public ExpressionNode {
1738     public:
1739         CommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1740             : ExpressionNode(globalData)
1741             , m_expr1(expr1)
1742             , m_expr2(expr2)
1743         {
1744         }
1745
1746         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1747         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1748         virtual Precedence precedence() const { return PrecExpression; }
1749
1750     private:
1751         RefPtr<ExpressionNode> m_expr1;
1752         RefPtr<ExpressionNode> m_expr2;
1753     };
1754     
1755     class VarDeclCommaNode : public CommaNode {
1756     public:
1757         VarDeclCommaNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2) KJS_FAST_CALL
1758             : CommaNode(globalData, expr1, expr2)
1759         {
1760         }
1761         virtual Precedence precedence() const { return PrecAssignment; }
1762     };
1763
1764     class ConstDeclNode : public ExpressionNode {
1765     public:
1766         ConstDeclNode(JSGlobalData* globalData, const Identifier& ident, ExpressionNode* in) KJS_FAST_CALL;
1767
1768         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1769         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
1770         PassRefPtr<ConstDeclNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
1771
1772         Identifier m_ident;
1773         ListRefPtr<ConstDeclNode> m_next;
1774         RefPtr<ExpressionNode> m_init;
1775         
1776         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1777         virtual RegisterID* emitCodeSingle(CodeGenerator&) KJS_FAST_CALL;
1778     };
1779
1780     class ConstStatementNode : public StatementNode {
1781     public:
1782         ConstStatementNode(JSGlobalData* globalData, ConstDeclNode* next) KJS_FAST_CALL
1783             : StatementNode(globalData)
1784             , m_next(next)
1785         {
1786         }
1787
1788         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1789         
1790         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1791
1792     private:
1793         RefPtr<ConstDeclNode> m_next;
1794     };
1795
1796     typedef Vector<RefPtr<StatementNode> > StatementVector;
1797
1798     class SourceElements : public ParserRefCounted {
1799     public:
1800         SourceElements(JSGlobalData* globalData) : ParserRefCounted(globalData) {}
1801
1802         void append(PassRefPtr<StatementNode>);
1803         void releaseContentsIntoVector(StatementVector& destination)
1804         {
1805             ASSERT(destination.isEmpty());
1806             m_statements.swap(destination);
1807         }
1808
1809     private:
1810         StatementVector m_statements;
1811     };
1812
1813     class BlockNode : public StatementNode {
1814     public:
1815         BlockNode(JSGlobalData*, SourceElements* children) KJS_FAST_CALL;
1816
1817         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1818         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1819
1820         StatementVector& children() { return m_children; }
1821
1822     protected:
1823         StatementVector m_children;
1824     };
1825
1826     class EmptyStatementNode : public StatementNode {
1827     public:
1828         EmptyStatementNode(JSGlobalData* globalData) KJS_FAST_CALL // debug
1829             : StatementNode(globalData)
1830         {
1831         }
1832
1833         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1834
1835         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1836         virtual bool isEmptyStatement() const KJS_FAST_CALL { return true; }
1837     };
1838     
1839     class DebuggerStatementNode : public StatementNode {
1840     public:
1841         DebuggerStatementNode(JSGlobalData* globalData) KJS_FAST_CALL
1842             : StatementNode(globalData)
1843         {
1844         }
1845         
1846         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1847
1848         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1849     };
1850
1851     class ExprStatementNode : public StatementNode {
1852     public:
1853         ExprStatementNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1854             : StatementNode(globalData)
1855             , m_expr(expr)
1856         {
1857         }
1858
1859         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1860         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1861
1862     private:
1863         RefPtr<ExpressionNode> m_expr;
1864     };
1865
1866     class VarStatementNode : public StatementNode {
1867     public:
1868         VarStatementNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
1869             : StatementNode(globalData)
1870             , m_expr(expr)
1871         {
1872         }
1873         
1874         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1875
1876         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1877
1878     private:
1879         RefPtr<ExpressionNode> m_expr;
1880     };
1881
1882     class IfNode : public StatementNode {
1883     public:
1884         IfNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock) KJS_FAST_CALL
1885             : StatementNode(globalData)
1886             , m_condition(condition)
1887             , m_ifBlock(ifBlock)
1888         {
1889         }
1890
1891         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1892         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1893
1894     protected:
1895         RefPtr<ExpressionNode> m_condition;
1896         RefPtr<StatementNode> m_ifBlock;
1897     };
1898
1899     class IfElseNode : public IfNode {
1900     public:
1901         IfElseNode(JSGlobalData* globalData, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock) KJS_FAST_CALL
1902             : IfNode(globalData, condition, ifBlock)
1903             , m_elseBlock(elseBlock)
1904         {
1905         }
1906
1907         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1908         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1909
1910     private:
1911         RefPtr<StatementNode> m_elseBlock;
1912     };
1913
1914     class DoWhileNode : public StatementNode {
1915     public:
1916         DoWhileNode(JSGlobalData* globalData, StatementNode* statement, ExpressionNode* expr) KJS_FAST_CALL
1917             : StatementNode(globalData)
1918             , m_statement(statement)
1919             , m_expr(expr)
1920         {
1921         }
1922
1923         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1924         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1925
1926     private:
1927         RefPtr<StatementNode> m_statement;
1928         RefPtr<ExpressionNode> m_expr;
1929     };
1930
1931     class WhileNode : public StatementNode {
1932     public:
1933         WhileNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement) KJS_FAST_CALL
1934             : StatementNode(globalData)
1935             , m_expr(expr)
1936             , m_statement(statement)
1937         {
1938         }
1939
1940         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1941         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1942
1943     private:
1944         RefPtr<ExpressionNode> m_expr;
1945         RefPtr<StatementNode> m_statement;
1946     };
1947
1948     class ForNode : public StatementNode {
1949     public:
1950         ForNode(JSGlobalData* globalData, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl) KJS_FAST_CALL
1951             : StatementNode(globalData)
1952             , m_expr1(expr1)
1953             , m_expr2(expr2)
1954             , m_expr3(expr3)
1955             , m_statement(statement)
1956             , m_expr1WasVarDecl(expr1 && expr1WasVarDecl)
1957         {
1958             ASSERT(statement);
1959         }
1960
1961         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1962         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1963
1964     private:
1965         RefPtr<ExpressionNode> m_expr1;
1966         RefPtr<ExpressionNode> m_expr2;
1967         RefPtr<ExpressionNode> m_expr3;
1968         RefPtr<StatementNode> m_statement;
1969         bool m_expr1WasVarDecl;
1970     };
1971
1972     class ForInNode : public StatementNode, public ThrowableExpressionData {
1973     public:
1974         ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*) KJS_FAST_CALL;
1975         ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset) KJS_FAST_CALL;
1976         
1977         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
1978         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
1979
1980     private:
1981         Identifier m_ident;
1982         RefPtr<ExpressionNode> m_init;
1983         RefPtr<ExpressionNode> m_lexpr;
1984         RefPtr<ExpressionNode> m_expr;
1985         RefPtr<StatementNode> m_statement;
1986         bool m_identIsVarDecl;
1987     };
1988
1989     class ContinueNode : public StatementNode, public ThrowableExpressionData {
1990     public:
1991         ContinueNode(JSGlobalData* globalData) KJS_FAST_CALL
1992             : StatementNode(globalData)
1993         {
1994         }
1995
1996         ContinueNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL
1997             : StatementNode(globalData)
1998             , m_ident(ident)
1999         {
2000         }
2001         
2002         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2003         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2004
2005     private:
2006         Identifier m_ident;
2007     };
2008
2009     class BreakNode : public StatementNode, public ThrowableExpressionData {
2010     public:
2011         BreakNode(JSGlobalData* globalData) KJS_FAST_CALL
2012             : StatementNode(globalData)
2013         {
2014         }
2015
2016         BreakNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL
2017             : StatementNode(globalData)
2018             , m_ident(ident)
2019         {
2020         }
2021         
2022         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2023         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2024
2025     private:
2026         Identifier m_ident;
2027     };
2028
2029     class ReturnNode : public StatementNode, public ThrowableExpressionData {
2030     public:
2031         ReturnNode(JSGlobalData* globalData, ExpressionNode* value) KJS_FAST_CALL
2032             : StatementNode(globalData)
2033             , m_value(value)
2034         {
2035         }
2036
2037         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2038         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2039         virtual bool isReturnNode() const KJS_FAST_CALL { return true; }
2040
2041     private:
2042         RefPtr<ExpressionNode> m_value;
2043     };
2044
2045     class WithNode : public StatementNode {
2046     public:
2047         WithNode(JSGlobalData* globalData, ExpressionNode* expr, StatementNode* statement, uint32_t divot, uint32_t expressionLength) KJS_FAST_CALL
2048             : StatementNode(globalData)
2049             , m_expr(expr)
2050             , m_statement(statement)
2051             , m_divot(divot)
2052             , m_expressionLength(expressionLength)
2053         {
2054         }
2055
2056         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2057         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2058
2059     private:
2060         RefPtr<ExpressionNode> m_expr;
2061         RefPtr<StatementNode> m_statement;
2062         uint32_t m_divot;
2063         uint32_t m_expressionLength;
2064     };
2065
2066     class LabelNode : public StatementNode, public ThrowableExpressionData {
2067     public:
2068         LabelNode(JSGlobalData* globalData, const Identifier& label, StatementNode* statement) KJS_FAST_CALL
2069             : StatementNode(globalData)
2070             , m_label(label)
2071             , m_statement(statement)
2072         {
2073         }
2074
2075         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2076         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2077         virtual void pushLabel(const Identifier& ident) KJS_FAST_CALL { m_statement->pushLabel(ident); }
2078
2079     private:
2080         Identifier m_label;
2081         RefPtr<StatementNode> m_statement;
2082     };
2083
2084     class ThrowNode : public StatementNode, public ThrowableExpressionData {
2085     public:
2086         ThrowNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
2087             : StatementNode(globalData)
2088             , m_expr(expr)
2089         {
2090         }
2091
2092         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2093         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2094
2095     private:
2096         RefPtr<ExpressionNode> m_expr;
2097     };
2098
2099     class TryNode : public StatementNode {
2100     public:
2101         TryNode(JSGlobalData* globalData, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock) KJS_FAST_CALL
2102             : StatementNode(globalData)
2103             , m_tryBlock(tryBlock)
2104             , m_exceptionIdent(exceptionIdent)
2105             , m_catchBlock(catchBlock)
2106             , m_finallyBlock(finallyBlock)
2107         {
2108         }
2109
2110         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2111
2112         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* dst = 0) KJS_FAST_CALL;
2113
2114     private:
2115         RefPtr<StatementNode> m_tryBlock;
2116         Identifier m_exceptionIdent;
2117         RefPtr<StatementNode> m_catchBlock;
2118         RefPtr<StatementNode> m_finallyBlock;
2119     };
2120
2121     class ParameterNode : public Node {
2122     public:
2123         ParameterNode(JSGlobalData* globalData, const Identifier& ident) KJS_FAST_CALL
2124             : Node(globalData)
2125             , m_ident(ident)
2126         {
2127         }
2128
2129         ParameterNode(JSGlobalData* globalData, ParameterNode* l, const Identifier& ident) KJS_FAST_CALL
2130             : Node(globalData)
2131             , m_ident(ident)
2132         {
2133             l->m_next = this;
2134         }
2135
2136         Identifier ident() KJS_FAST_CALL { return m_ident; }
2137         ParameterNode *nextParam() KJS_FAST_CALL { return m_next.get(); }
2138         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2139         PassRefPtr<ParameterNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2140         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2141
2142     private:
2143         friend class FuncDeclNode;
2144         friend class FuncExprNode;
2145         Identifier m_ident;
2146         ListRefPtr<ParameterNode> m_next;
2147     };
2148
2149     class ScopeNode : public BlockNode {
2150     public:
2151         ScopeNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2152
2153         int sourceId() const KJS_FAST_CALL { return m_sourceId; }
2154         const UString& sourceURL() const KJS_FAST_CALL { return m_sourceURL; }
2155         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2156         
2157         bool usesEval() const { return m_usesEval; }
2158         bool needsClosure() const { return m_needsClosure; }
2159         
2160         VarStack& varStack() { return m_varStack; }
2161         FunctionStack& functionStack() { return m_functionStack; }
2162
2163         int neededConstants()
2164         {
2165             // We may need 3 more constants than the count given by the parser,
2166             // because of the various uses of jsUndefined() and the 1.0 / -1.0
2167             // that are emitted for a preincrement or predecrement on a constant
2168             // local variable. 
2169             return m_numConstants + 3;
2170         }
2171
2172     protected:
2173         VarStack m_varStack;
2174         FunctionStack m_functionStack;
2175
2176     private:
2177         UString m_sourceURL;
2178         int m_sourceId;
2179         bool m_usesEval;
2180         bool m_needsClosure;
2181         int m_numConstants;
2182     };
2183
2184     class ProgramNode : public ScopeNode {
2185     public:
2186         static ProgramNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2187
2188         ProgramCodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL
2189         {
2190             if (!m_code)
2191                 generateCode(scopeChain);
2192             return *m_code;
2193         }
2194
2195     private:
2196         ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2197
2198         void generateCode(ScopeChainNode*) KJS_FAST_CALL;
2199         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2200
2201         Vector<size_t> m_varIndexes; // Storage indexes belonging to the nodes in m_varStack. (Recorded to avoid double lookup.)
2202         Vector<size_t> m_functionIndexes; // Storage indexes belonging to the nodes in m_functionStack. (Recorded to avoid double lookup.)
2203
2204         RefPtr<SourceProvider> m_sourceProvider;
2205
2206         OwnPtr<ProgramCodeBlock> m_code;
2207     };
2208
2209     class EvalNode : public ScopeNode {
2210     public:
2211         static EvalNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2212
2213         EvalCodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL
2214         {
2215             if (!m_code)
2216                 generateCode(scopeChain);
2217             return *m_code;
2218         }
2219
2220     private:
2221         EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2222
2223         void generateCode(ScopeChainNode*) KJS_FAST_CALL;
2224         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2225         
2226         RefPtr<SourceProvider> m_sourceProvider;
2227
2228         OwnPtr<EvalCodeBlock> m_code;
2229     };
2230
2231     class FunctionBodyNode : public ScopeNode {
2232     public:
2233         static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, SourceProvider*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2234         static FunctionBodyNode* create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2235
2236         Vector<Identifier>& parameters() KJS_FAST_CALL { return m_parameters; }
2237         UString paramString() const KJS_FAST_CALL;
2238
2239         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2240         
2241         SymbolTable& symbolTable() { return m_symbolTable; } // FIXME: Remove this
2242         
2243         CodeBlock& byteCode(ScopeChainNode* scopeChain) KJS_FAST_CALL
2244         {
2245             ASSERT(scopeChain);
2246             if (!m_code)
2247                 generateCode(scopeChain);
2248             return *m_code;
2249         }
2250
2251         CodeBlock& generatedByteCode() KJS_FAST_CALL
2252         {
2253             ASSERT(m_code);
2254             return *m_code;
2255         }
2256
2257         void mark();
2258
2259         void setSource(const SourceRange& source) { m_source = source; } 
2260         UString toSourceString() const KJS_FAST_CALL { return UString("{") + m_source.toString() + UString("}"); }
2261     protected:
2262         FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, bool usesEval, bool needsClosure, int numConstants) KJS_FAST_CALL;
2263
2264     private:
2265         void generateCode(ScopeChainNode*) KJS_FAST_CALL;
2266         
2267         Vector<Identifier> m_parameters;
2268         SymbolTable m_symbolTable;
2269         OwnPtr<CodeBlock> m_code;
2270         SourceRange m_source;
2271     };
2272
2273     class FuncExprNode : public ExpressionNode {
2274     public:
2275         FuncExprNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceRange& source, ParameterNode* parameter = 0) KJS_FAST_CALL
2276             : ExpressionNode(globalData)
2277             , m_ident(ident)
2278             , m_parameter(parameter)
2279             , m_body(body)
2280         {
2281             addParams();
2282             m_body->setSource(source);
2283         }
2284
2285         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2286         JSFunction* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
2287         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2288         virtual Precedence precedence() const { return PrecMember; }
2289         virtual bool needsParensIfLeftmost() const { return true; }
2290
2291         FunctionBodyNode* body() { return m_body.get(); }
2292
2293     private:
2294         void addParams() KJS_FAST_CALL;
2295
2296         // Used for streamTo
2297         friend class PropertyNode;
2298         Identifier m_ident;
2299         RefPtr<ParameterNode> m_parameter;
2300         RefPtr<FunctionBodyNode> m_body;
2301     };
2302
2303     class FuncDeclNode : public StatementNode {
2304     public:
2305         FuncDeclNode(JSGlobalData* globalData, const Identifier& ident, FunctionBodyNode* body, const SourceRange& source, ParameterNode* parameter = 0) KJS_FAST_CALL
2306             : StatementNode(globalData)
2307             , m_ident(ident)
2308             , m_parameter(parameter)
2309             , m_body(body)
2310         {
2311             addParams();
2312             m_body->setSource(source);
2313         }
2314
2315         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2316
2317         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2318         JSFunction* makeFunction(ExecState*, ScopeChainNode*) KJS_FAST_CALL;
2319
2320         Identifier m_ident;
2321
2322         FunctionBodyNode* body() { return m_body.get(); }
2323
2324     private:
2325         void addParams() KJS_FAST_CALL;
2326
2327         RefPtr<ParameterNode> m_parameter;
2328         RefPtr<FunctionBodyNode> m_body;
2329     };
2330
2331     class CaseClauseNode : public Node {
2332     public:
2333         CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr) KJS_FAST_CALL
2334             : Node(globalData)
2335             , m_expr(expr)
2336         {
2337         }
2338
2339         CaseClauseNode(JSGlobalData* globalData, ExpressionNode* expr, SourceElements* children) KJS_FAST_CALL
2340             : Node(globalData)
2341             , m_expr(expr)
2342         {
2343             if (children)
2344                 children->releaseContentsIntoVector(m_children);
2345         }
2346
2347         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2348         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2349
2350         ExpressionNode* expr() const { return m_expr.get(); }
2351         StatementVector& children() { return m_children; }
2352
2353     private:
2354         RefPtr<ExpressionNode> m_expr;
2355         StatementVector m_children;
2356     };
2357
2358     class ClauseListNode : public Node {
2359     public:
2360         ClauseListNode(JSGlobalData* globalData, CaseClauseNode* clause) KJS_FAST_CALL
2361             : Node(globalData)
2362             , m_clause(clause)
2363         {
2364         }
2365
2366         ClauseListNode(JSGlobalData* globalData, ClauseListNode* clauseList, CaseClauseNode* clause) KJS_FAST_CALL
2367             : Node(globalData)
2368             , m_clause(clause)
2369         {
2370             clauseList->m_next = this;
2371         }
2372
2373         CaseClauseNode* getClause() const KJS_FAST_CALL { return m_clause.get(); }
2374         ClauseListNode* getNext() const KJS_FAST_CALL { return m_next.get(); }
2375         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2376         PassRefPtr<ClauseListNode> releaseNext() KJS_FAST_CALL { return m_next.release(); }
2377         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2378
2379     private:
2380         friend class CaseBlockNode;
2381         RefPtr<CaseClauseNode> m_clause;
2382         ListRefPtr<ClauseListNode> m_next;
2383     };
2384
2385     class CaseBlockNode : public Node {
2386     public:
2387         CaseBlockNode(JSGlobalData* globalData, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2) KJS_FAST_CALL
2388             : Node(globalData)
2389             , m_list1(list1)
2390             , m_defaultClause(defaultClause)
2391             , m_list2(list2)
2392         {
2393         }
2394
2395         RegisterID* emitCodeForBlock(CodeGenerator&, RegisterID* input, RegisterID* dst = 0) KJS_FAST_CALL;
2396
2397         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2398         virtual Precedence precedence() const { ASSERT_NOT_REACHED(); return PrecExpression; }
2399
2400     private:
2401         SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
2402         RefPtr<ClauseListNode> m_list1;
2403         RefPtr<CaseClauseNode> m_defaultClause;
2404         RefPtr<ClauseListNode> m_list2;
2405     };
2406
2407     class SwitchNode : public StatementNode {
2408     public:
2409         SwitchNode(JSGlobalData* globalData, ExpressionNode* expr, CaseBlockNode* block) KJS_FAST_CALL
2410             : StatementNode(globalData)
2411             , m_expr(expr)
2412             , m_block(block)
2413         {
2414         }
2415
2416         virtual RegisterID* emitCode(CodeGenerator&, RegisterID* = 0) KJS_FAST_CALL;
2417
2418         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2419
2420     private:
2421         RefPtr<ExpressionNode> m_expr;
2422         RefPtr<CaseBlockNode> m_block;
2423     };
2424
2425     class BreakpointCheckStatement : public StatementNode {
2426     public:
2427         BreakpointCheckStatement(JSGlobalData*, PassRefPtr<StatementNode>) KJS_FAST_CALL;
2428
2429         virtual void streamTo(SourceStream&) const KJS_FAST_CALL;
2430
2431     private:
2432         RefPtr<StatementNode> m_statement;
2433     };
2434
2435     struct ElementList {
2436         ElementNode* head;
2437         ElementNode* tail;
2438     };
2439
2440     struct PropertyList {
2441         PropertyListNode* head;
2442         PropertyListNode* tail;
2443     };
2444
2445     struct ArgumentList {
2446         ArgumentListNode* head;
2447         ArgumentListNode* tail;
2448     };
2449
2450     struct ConstDeclList {
2451         ConstDeclNode* head;
2452         ConstDeclNode* tail;
2453     };
2454
2455     struct ParameterList {
2456         ParameterNode* head;
2457         ParameterNode* tail;
2458     };
2459
2460     struct ClauseList {
2461         ClauseListNode* head;
2462         ClauseListNode* tail;
2463     };
2464
2465 } // namespace KJS
2466
2467 #endif // NODES_H_