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