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