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, 2009 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 "JITCode.h"
31#include "Opcode.h"
32#include "ParserArena.h"
33#include "ResultType.h"
34#include "SourceCode.h"
35#include "SymbolTable.h"
36#include <wtf/MathExtras.h>
37
38namespace JSC {
39
40    class ArgumentListNode;
41    class BytecodeGenerator;
42    class FunctionBodyNode;
43    class Label;
44    class PropertyListNode;
45    class ReadModifyResolveNode;
46    class RegisterID;
47    class ScopeChainNode;
48    class ScopeNode;
49
50    typedef unsigned CodeFeatures;
51
52    const CodeFeatures NoFeatures = 0;
53    const CodeFeatures EvalFeature = 1 << 0;
54    const CodeFeatures ClosureFeature = 1 << 1;
55    const CodeFeatures AssignFeature = 1 << 2;
56    const CodeFeatures ArgumentsFeature = 1 << 3;
57    const CodeFeatures WithFeature = 1 << 4;
58    const CodeFeatures CatchFeature = 1 << 5;
59    const CodeFeatures ThisFeature = 1 << 6;
60    const CodeFeatures AllFeatures = EvalFeature | ClosureFeature | AssignFeature | ArgumentsFeature | WithFeature | CatchFeature | ThisFeature;
61
62    enum Operator {
63        OpEqual,
64        OpPlusEq,
65        OpMinusEq,
66        OpMultEq,
67        OpDivEq,
68        OpPlusPlus,
69        OpMinusMinus,
70        OpAndEq,
71        OpXOrEq,
72        OpOrEq,
73        OpModEq,
74        OpLShift,
75        OpRShift,
76        OpURShift
77    };
78
79    enum LogicalOperator {
80        OpLogicalAnd,
81        OpLogicalOr
82    };
83
84    namespace DeclarationStacks {
85        enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
86        typedef Vector<std::pair<const Identifier*, unsigned> > VarStack;
87        typedef Vector<FunctionBodyNode*> FunctionStack;
88    }
89
90    struct SwitchInfo {
91        enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
92        uint32_t bytecodeOffset;
93        SwitchType switchType;
94    };
95
96    class ParserArenaFreeable {
97    public:
98        // ParserArenaFreeable objects are are freed when the arena is deleted.
99        // Destructors are not called. Clients must not call delete on such objects.
100        void* operator new(size_t, JSGlobalData*);
101    };
102
103    class ParserArenaDeletable {
104    public:
105        virtual ~ParserArenaDeletable() { }
106
107        // ParserArenaDeletable objects are deleted when the arena is deleted.
108        // Clients must not call delete directly on such objects.
109        void* operator new(size_t, JSGlobalData*);
110    };
111
112    class ParserArenaRefCounted : public RefCounted<ParserArenaRefCounted> {
113    protected:
114        ParserArenaRefCounted(JSGlobalData*);
115
116    public:
117        virtual ~ParserArenaRefCounted()
118        {
119            ASSERT(deletionHasBegun());
120        }
121    };
122
123    class Node : public ParserArenaFreeable {
124    protected:
125        Node(JSGlobalData*);
126
127    public:
128        virtual ~Node() { }
129
130        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
131
132        int lineNo() const { return m_line; }
133
134    protected:
135        int m_line;
136    };
137
138    class ExpressionNode : public Node {
139    protected:
140        ExpressionNode(JSGlobalData*, ResultType = ResultType::unknownType());
141
142    public:
143        virtual bool isNumber() const { return false; }
144        virtual bool isString() const { return false; }
145        virtual bool isNull() const { return false; }
146        virtual bool isPure(BytecodeGenerator&) const { return false; }
147        virtual bool isLocation() const { return false; }
148        virtual bool isResolveNode() const { return false; }
149        virtual bool isBracketAccessorNode() const { return false; }
150        virtual bool isDotAccessorNode() const { return false; }
151        virtual bool isFuncExprNode() const { return false; }
152        virtual bool isCommaNode() const { return false; }
153        virtual bool isSimpleArray() const { return false; }
154        virtual bool isAdd() const { return false; }
155        virtual bool hasConditionContextCodegen() const { return false; }
156
157        virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, bool) { ASSERT_NOT_REACHED(); }
158
159        virtual ExpressionNode* stripUnaryPlus() { return this; }
160
161        ResultType resultDescriptor() const { return m_resultType; }
162
163    private:
164        ResultType m_resultType;
165    };
166
167    class StatementNode : public Node {
168    protected:
169        StatementNode(JSGlobalData*);
170
171    public:
172        void setLoc(int firstLine, int lastLine);
173        int firstLine() const { return lineNo(); }
174        int lastLine() const { return m_lastLine; }
175
176        virtual bool isEmptyStatement() const { return false; }
177        virtual bool isReturnNode() const { return false; }
178        virtual bool isExprStatement() const { return false; }
179
180        virtual bool isBlock() const { return false; }
181
182    private:
183        int m_lastLine;
184    };
185
186    class NullNode : public ExpressionNode {
187    public:
188        NullNode(JSGlobalData*);
189
190    private:
191        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
192
193        virtual bool isNull() const { return true; }
194    };
195
196    class BooleanNode : public ExpressionNode {
197    public:
198        BooleanNode(JSGlobalData*, bool value);
199
200    private:
201        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
202
203        virtual bool isPure(BytecodeGenerator&) const { return true; }
204
205        bool m_value;
206    };
207
208    class NumberNode : public ExpressionNode {
209    public:
210        NumberNode(JSGlobalData*, double value);
211
212        double value() const { return m_value; }
213        void setValue(double value) { m_value = value; }
214
215    private:
216        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
217
218        virtual bool isNumber() const { return true; }
219        virtual bool isPure(BytecodeGenerator&) const { return true; }
220
221        double m_value;
222    };
223
224    class StringNode : public ExpressionNode {
225    public:
226        StringNode(JSGlobalData*, const Identifier&);
227
228        const Identifier& value() { return m_value; }
229
230    private:
231        virtual bool isPure(BytecodeGenerator&) const { return true; }
232
233        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
234
235        virtual bool isString() const { return true; }
236
237        const Identifier& m_value;
238    };
239
240    class ThrowableExpressionData {
241    public:
242        ThrowableExpressionData()
243            : m_divot(static_cast<uint32_t>(-1))
244            , m_startOffset(static_cast<uint16_t>(-1))
245            , m_endOffset(static_cast<uint16_t>(-1))
246        {
247        }
248
249        ThrowableExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
250            : m_divot(divot)
251            , m_startOffset(startOffset)
252            , m_endOffset(endOffset)
253        {
254        }
255
256        void setExceptionSourceCode(unsigned divot, unsigned startOffset, unsigned endOffset)
257        {
258            m_divot = divot;
259            m_startOffset = startOffset;
260            m_endOffset = endOffset;
261        }
262
263        uint32_t divot() const { return m_divot; }
264        uint16_t startOffset() const { return m_startOffset; }
265        uint16_t endOffset() const { return m_endOffset; }
266
267    protected:
268        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message);
269        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const UString&);
270        RegisterID* emitThrowError(BytecodeGenerator&, ErrorType, const char* message, const Identifier&);
271
272    private:
273        uint32_t m_divot;
274        uint16_t m_startOffset;
275        uint16_t m_endOffset;
276    };
277
278    class ThrowableSubExpressionData : public ThrowableExpressionData {
279    public:
280        ThrowableSubExpressionData()
281            : m_subexpressionDivotOffset(0)
282            , m_subexpressionEndOffset(0)
283        {
284        }
285
286        ThrowableSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
287            : ThrowableExpressionData(divot, startOffset, endOffset)
288            , m_subexpressionDivotOffset(0)
289            , m_subexpressionEndOffset(0)
290        {
291        }
292
293        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
294        {
295            ASSERT(subexpressionDivot <= divot());
296            if ((divot() - subexpressionDivot) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
297                return;
298            m_subexpressionDivotOffset = divot() - subexpressionDivot;
299            m_subexpressionEndOffset = subexpressionOffset;
300        }
301
302    protected:
303        uint16_t m_subexpressionDivotOffset;
304        uint16_t m_subexpressionEndOffset;
305    };
306
307    class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
308    public:
309        ThrowablePrefixedSubExpressionData()
310            : m_subexpressionDivotOffset(0)
311            , m_subexpressionStartOffset(0)
312        {
313        }
314
315        ThrowablePrefixedSubExpressionData(unsigned divot, unsigned startOffset, unsigned endOffset)
316            : ThrowableExpressionData(divot, startOffset, endOffset)
317            , m_subexpressionDivotOffset(0)
318            , m_subexpressionStartOffset(0)
319        {
320        }
321
322        void setSubexpressionInfo(uint32_t subexpressionDivot, uint16_t subexpressionOffset)
323        {
324            ASSERT(subexpressionDivot >= divot());
325            if ((subexpressionDivot - divot()) & ~0xFFFF) // Overflow means we can't do this safely, so just point at the primary divot
326                return;
327            m_subexpressionDivotOffset = subexpressionDivot - divot();
328            m_subexpressionStartOffset = subexpressionOffset;
329        }
330
331    protected:
332        uint16_t m_subexpressionDivotOffset;
333        uint16_t m_subexpressionStartOffset;
334    };
335
336    class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
337    public:
338        RegExpNode(JSGlobalData*, const Identifier& pattern, const Identifier& flags);
339
340    private:
341        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
342
343        const Identifier& m_pattern;
344        const Identifier& m_flags;
345    };
346
347    class ThisNode : public ExpressionNode {
348    public:
349        ThisNode(JSGlobalData*);
350
351    private:
352        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
353    };
354
355    class ResolveNode : public ExpressionNode {
356    public:
357        ResolveNode(JSGlobalData*, const Identifier&, int startOffset);
358
359        const Identifier& identifier() const { return m_ident; }
360
361    private:
362        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
363
364        virtual bool isPure(BytecodeGenerator&) const ;
365        virtual bool isLocation() const { return true; }
366        virtual bool isResolveNode() const { return true; }
367
368        const Identifier& m_ident;
369        int32_t m_startOffset;
370    };
371
372    class ElementNode : public ParserArenaFreeable {
373    public:
374        ElementNode(JSGlobalData*, int elision, ExpressionNode*);
375        ElementNode(JSGlobalData*, ElementNode*, int elision, ExpressionNode*);
376
377        int elision() const { return m_elision; }
378        ExpressionNode* value() { return m_node; }
379        ElementNode* next() { return m_next; }
380
381    private:
382        ElementNode* m_next;
383        int m_elision;
384        ExpressionNode* m_node;
385    };
386
387    class ArrayNode : public ExpressionNode {
388    public:
389        ArrayNode(JSGlobalData*, int elision);
390        ArrayNode(JSGlobalData*, ElementNode*);
391        ArrayNode(JSGlobalData*, int elision, ElementNode*);
392
393        ArgumentListNode* toArgumentList(JSGlobalData*) const;
394
395    private:
396        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
397
398        virtual bool isSimpleArray() const ;
399
400        ElementNode* m_element;
401        int m_elision;
402        bool m_optional;
403    };
404
405    class PropertyNode : public ParserArenaFreeable {
406    public:
407        enum Type { Constant, Getter, Setter };
408
409        PropertyNode(JSGlobalData*, const Identifier& name, ExpressionNode* value, Type);
410        PropertyNode(JSGlobalData*, double name, ExpressionNode* value, Type);
411
412        const Identifier& name() const { return m_name; }
413
414    private:
415        friend class PropertyListNode;
416        const Identifier& m_name;
417        ExpressionNode* m_assign;
418        Type m_type;
419    };
420
421    class PropertyListNode : public Node {
422    public:
423        PropertyListNode(JSGlobalData*, PropertyNode*);
424        PropertyListNode(JSGlobalData*, PropertyNode*, PropertyListNode*);
425
426        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
427
428    private:
429        PropertyNode* m_node;
430        PropertyListNode* m_next;
431    };
432
433    class ObjectLiteralNode : public ExpressionNode {
434    public:
435        ObjectLiteralNode(JSGlobalData*);
436        ObjectLiteralNode(JSGlobalData*, PropertyListNode*);
437
438    private:
439        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
440
441        PropertyListNode* m_list;
442    };
443
444    class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
445    public:
446        BracketAccessorNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
447
448        ExpressionNode* base() const { return m_base; }
449        ExpressionNode* subscript() const { return m_subscript; }
450
451    private:
452        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
453
454        virtual bool isLocation() const { return true; }
455        virtual bool isBracketAccessorNode() const { return true; }
456
457        ExpressionNode* m_base;
458        ExpressionNode* m_subscript;
459        bool m_subscriptHasAssignments;
460    };
461
462    class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
463    public:
464        DotAccessorNode(JSGlobalData*, ExpressionNode* base, const Identifier&);
465
466        ExpressionNode* base() const { return m_base; }
467        const Identifier& identifier() const { return m_ident; }
468
469    private:
470        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
471
472        virtual bool isLocation() const { return true; }
473        virtual bool isDotAccessorNode() const { return true; }
474
475        ExpressionNode* m_base;
476        const Identifier& m_ident;
477    };
478
479    class ArgumentListNode : public Node {
480    public:
481        ArgumentListNode(JSGlobalData*, ExpressionNode*);
482        ArgumentListNode(JSGlobalData*, ArgumentListNode*, ExpressionNode*);
483
484        ArgumentListNode* m_next;
485        ExpressionNode* m_expr;
486
487    private:
488        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
489    };
490
491    class ArgumentsNode : public ParserArenaFreeable {
492    public:
493        ArgumentsNode(JSGlobalData*);
494        ArgumentsNode(JSGlobalData*, ArgumentListNode*);
495
496        ArgumentListNode* m_listNode;
497    };
498
499    class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
500    public:
501        NewExprNode(JSGlobalData*, ExpressionNode*);
502        NewExprNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*);
503
504    private:
505        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
506
507        ExpressionNode* m_expr;
508        ArgumentsNode* m_args;
509    };
510
511    class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
512    public:
513        EvalFunctionCallNode(JSGlobalData*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
514
515    private:
516        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
517
518        ArgumentsNode* m_args;
519    };
520
521    class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
522    public:
523        FunctionCallValueNode(JSGlobalData*, ExpressionNode*, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
524
525    private:
526        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
527
528        ExpressionNode* m_expr;
529        ArgumentsNode* m_args;
530    };
531
532    class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
533    public:
534        FunctionCallResolveNode(JSGlobalData*, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
535
536    private:
537        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
538
539        const Identifier& m_ident;
540        ArgumentsNode* m_args;
541        size_t m_index; // Used by LocalVarFunctionCallNode.
542        size_t m_scopeDepth; // Used by ScopedVarFunctionCallNode and NonLocalVarFunctionCallNode
543    };
544
545    class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
546    public:
547        FunctionCallBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
548
549    private:
550        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
551
552        ExpressionNode* m_base;
553        ExpressionNode* m_subscript;
554        ArgumentsNode* m_args;
555    };
556
557    class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
558    public:
559        FunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
560
561    private:
562        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
563
564    protected:
565        ExpressionNode* m_base;
566        const Identifier& m_ident;
567        ArgumentsNode* m_args;
568    };
569
570    class CallFunctionCallDotNode : public FunctionCallDotNode {
571    public:
572        CallFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
573
574    private:
575        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
576    };
577
578    class ApplyFunctionCallDotNode : public FunctionCallDotNode {
579    public:
580        ApplyFunctionCallDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ArgumentsNode*, unsigned divot, unsigned startOffset, unsigned endOffset);
581
582    private:
583        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
584    };
585
586    class PrePostResolveNode : public ExpressionNode, public ThrowableExpressionData {
587    public:
588        PrePostResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
589
590    protected:
591        const Identifier& m_ident;
592    };
593
594    class PostfixResolveNode : public PrePostResolveNode {
595    public:
596        PostfixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
597
598    private:
599        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
600
601        Operator m_operator;
602    };
603
604    class PostfixBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
605    public:
606        PostfixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
607
608    private:
609        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
610
611        ExpressionNode* m_base;
612        ExpressionNode* m_subscript;
613        Operator m_operator;
614    };
615
616    class PostfixDotNode : public ExpressionNode, public ThrowableSubExpressionData {
617    public:
618        PostfixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
619
620    private:
621        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
622
623        ExpressionNode* m_base;
624        const Identifier& m_ident;
625        Operator m_operator;
626    };
627
628    class PostfixErrorNode : public ExpressionNode, public ThrowableSubExpressionData {
629    public:
630        PostfixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
631
632    private:
633        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
634
635        ExpressionNode* m_expr;
636        Operator m_operator;
637    };
638
639    class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
640    public:
641        DeleteResolveNode(JSGlobalData*, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
642
643    private:
644        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
645
646        const Identifier& m_ident;
647    };
648
649    class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
650    public:
651        DeleteBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, unsigned divot, unsigned startOffset, unsigned endOffset);
652
653    private:
654        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
655
656        ExpressionNode* m_base;
657        ExpressionNode* m_subscript;
658    };
659
660    class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
661    public:
662        DeleteDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, unsigned divot, unsigned startOffset, unsigned endOffset);
663
664    private:
665        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
666
667        ExpressionNode* m_base;
668        const Identifier& m_ident;
669    };
670
671    class DeleteValueNode : public ExpressionNode {
672    public:
673        DeleteValueNode(JSGlobalData*, ExpressionNode*);
674
675    private:
676        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
677
678        ExpressionNode* m_expr;
679    };
680
681    class VoidNode : public ExpressionNode {
682    public:
683        VoidNode(JSGlobalData*, ExpressionNode*);
684
685    private:
686        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
687
688        ExpressionNode* m_expr;
689    };
690
691    class TypeOfResolveNode : public ExpressionNode {
692    public:
693        TypeOfResolveNode(JSGlobalData*, const Identifier&);
694
695        const Identifier& identifier() const { return m_ident; }
696
697    private:
698        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
699
700        const Identifier& m_ident;
701    };
702
703    class TypeOfValueNode : public ExpressionNode {
704    public:
705        TypeOfValueNode(JSGlobalData*, ExpressionNode*);
706
707    private:
708        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
709
710        ExpressionNode* m_expr;
711    };
712
713    class PrefixResolveNode : public PrePostResolveNode {
714    public:
715        PrefixResolveNode(JSGlobalData*, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
716
717    private:
718        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
719
720        Operator m_operator;
721    };
722
723    class PrefixBracketNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
724    public:
725        PrefixBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
726
727    private:
728        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
729
730        ExpressionNode* m_base;
731        ExpressionNode* m_subscript;
732        Operator m_operator;
733    };
734
735    class PrefixDotNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
736    public:
737        PrefixDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
738
739    private:
740        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
741
742        ExpressionNode* m_base;
743        const Identifier& m_ident;
744        Operator m_operator;
745    };
746
747    class PrefixErrorNode : public ExpressionNode, public ThrowableExpressionData {
748    public:
749        PrefixErrorNode(JSGlobalData*, ExpressionNode*, Operator, unsigned divot, unsigned startOffset, unsigned endOffset);
750
751    private:
752        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
753
754        ExpressionNode* m_expr;
755        Operator m_operator;
756    };
757
758    class UnaryOpNode : public ExpressionNode {
759    public:
760        UnaryOpNode(JSGlobalData*, ResultType, ExpressionNode*, OpcodeID);
761
762    protected:
763        ExpressionNode* expr() { return m_expr; }
764        const ExpressionNode* expr() const { return m_expr; }
765
766    private:
767        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
768
769        OpcodeID opcodeID() const { return m_opcodeID; }
770
771        ExpressionNode* m_expr;
772        OpcodeID m_opcodeID;
773    };
774
775    class UnaryPlusNode : public UnaryOpNode {
776    public:
777        UnaryPlusNode(JSGlobalData*, ExpressionNode*);
778
779    private:
780        virtual ExpressionNode* stripUnaryPlus() { return expr(); }
781    };
782
783    class NegateNode : public UnaryOpNode {
784    public:
785        NegateNode(JSGlobalData*, ExpressionNode*);
786    };
787
788    class BitwiseNotNode : public UnaryOpNode {
789    public:
790        BitwiseNotNode(JSGlobalData*, ExpressionNode*);
791    };
792
793    class LogicalNotNode : public UnaryOpNode {
794    public:
795        LogicalNotNode(JSGlobalData*, ExpressionNode*);
796    private:
797        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
798        virtual bool hasConditionContextCodegen() const { return expr()->hasConditionContextCodegen(); }
799    };
800
801    class BinaryOpNode : public ExpressionNode {
802    public:
803        BinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
804        BinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
805
806        RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
807
808    private:
809        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
810
811    protected:
812        OpcodeID opcodeID() const { return m_opcodeID; }
813
814    protected:
815        ExpressionNode* m_expr1;
816        ExpressionNode* m_expr2;
817    private:
818        OpcodeID m_opcodeID;
819    protected:
820        bool m_rightHasAssignments;
821    };
822
823    class ReverseBinaryOpNode : public BinaryOpNode {
824    public:
825        ReverseBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
826        ReverseBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
827
828        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
829    };
830
831    class MultNode : public BinaryOpNode {
832    public:
833        MultNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
834    };
835
836    class DivNode : public BinaryOpNode {
837    public:
838        DivNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
839    };
840
841    class ModNode : public BinaryOpNode {
842    public:
843        ModNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
844    };
845
846    class AddNode : public BinaryOpNode {
847    public:
848        AddNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
849
850        virtual bool isAdd() const { return true; }
851    };
852
853    class SubNode : public BinaryOpNode {
854    public:
855        SubNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
856    };
857
858    class LeftShiftNode : public BinaryOpNode {
859    public:
860        LeftShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
861    };
862
863    class RightShiftNode : public BinaryOpNode {
864    public:
865        RightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
866    };
867
868    class UnsignedRightShiftNode : public BinaryOpNode {
869    public:
870        UnsignedRightShiftNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
871    };
872
873    class LessNode : public BinaryOpNode {
874    public:
875        LessNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
876    };
877
878    class GreaterNode : public ReverseBinaryOpNode {
879    public:
880        GreaterNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
881    };
882
883    class LessEqNode : public BinaryOpNode {
884    public:
885        LessEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
886    };
887
888    class GreaterEqNode : public ReverseBinaryOpNode {
889    public:
890        GreaterEqNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
891    };
892
893    class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
894    public:
895        ThrowableBinaryOpNode(JSGlobalData*, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
896        ThrowableBinaryOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
897
898    private:
899        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
900    };
901
902    class InstanceOfNode : public ThrowableBinaryOpNode {
903    public:
904        InstanceOfNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
905
906    private:
907        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
908    };
909
910    class InNode : public ThrowableBinaryOpNode {
911    public:
912        InNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
913    };
914
915    class EqualNode : public BinaryOpNode {
916    public:
917        EqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
918
919    private:
920        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
921    };
922
923    class NotEqualNode : public BinaryOpNode {
924    public:
925        NotEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
926    };
927
928    class StrictEqualNode : public BinaryOpNode {
929    public:
930        StrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
931
932    private:
933        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
934    };
935
936    class NotStrictEqualNode : public BinaryOpNode {
937    public:
938        NotStrictEqualNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
939    };
940
941    class BitAndNode : public BinaryOpNode {
942    public:
943        BitAndNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
944    };
945
946    class BitOrNode : public BinaryOpNode {
947    public:
948        BitOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
949    };
950
951    class BitXOrNode : public BinaryOpNode {
952    public:
953        BitXOrNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
954    };
955
956    // m_expr1 && m_expr2, m_expr1 || m_expr2
957    class LogicalOpNode : public ExpressionNode {
958    public:
959        LogicalOpNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
960
961    private:
962        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
963        void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, bool fallThroughMeansTrue);
964        virtual bool hasConditionContextCodegen() const { return true; }
965
966        ExpressionNode* m_expr1;
967        ExpressionNode* m_expr2;
968        LogicalOperator m_operator;
969    };
970
971    // The ternary operator, "m_logical ? m_expr1 : m_expr2"
972    class ConditionalNode : public ExpressionNode {
973    public:
974        ConditionalNode(JSGlobalData*, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
975
976    private:
977        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
978
979        ExpressionNode* m_logical;
980        ExpressionNode* m_expr1;
981        ExpressionNode* m_expr2;
982    };
983
984    class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
985    public:
986        ReadModifyResolveNode(JSGlobalData*, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
987
988    private:
989        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
990
991        const Identifier& m_ident;
992        ExpressionNode* m_right;
993        size_t m_index; // Used by ReadModifyLocalVarNode.
994        Operator m_operator;
995        bool m_rightHasAssignments;
996    };
997
998    class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
999    public:
1000        AssignResolveNode(JSGlobalData*, const Identifier&, ExpressionNode* right, bool rightHasAssignments);
1001
1002    private:
1003        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1004
1005        const Identifier& m_ident;
1006        ExpressionNode* m_right;
1007        size_t m_index; // Used by ReadModifyLocalVarNode.
1008        bool m_rightHasAssignments;
1009    };
1010
1011    class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1012    public:
1013        ReadModifyBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1014
1015    private:
1016        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1017
1018        ExpressionNode* m_base;
1019        ExpressionNode* m_subscript;
1020        ExpressionNode* m_right;
1021        Operator m_operator : 30;
1022        bool m_subscriptHasAssignments : 1;
1023        bool m_rightHasAssignments : 1;
1024    };
1025
1026    class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1027    public:
1028        AssignBracketNode(JSGlobalData*, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1029
1030    private:
1031        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1032
1033        ExpressionNode* m_base;
1034        ExpressionNode* m_subscript;
1035        ExpressionNode* m_right;
1036        bool m_subscriptHasAssignments : 1;
1037        bool m_rightHasAssignments : 1;
1038    };
1039
1040    class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1041    public:
1042        AssignDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1043
1044    private:
1045        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1046
1047        ExpressionNode* m_base;
1048        const Identifier& m_ident;
1049        ExpressionNode* m_right;
1050        bool m_rightHasAssignments;
1051    };
1052
1053    class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1054    public:
1055        ReadModifyDotNode(JSGlobalData*, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, unsigned divot, unsigned startOffset, unsigned endOffset);
1056
1057    private:
1058        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1059
1060        ExpressionNode* m_base;
1061        const Identifier& m_ident;
1062        ExpressionNode* m_right;
1063        Operator m_operator : 31;
1064        bool m_rightHasAssignments : 1;
1065    };
1066
1067    class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1068    public:
1069        AssignErrorNode(JSGlobalData*, ExpressionNode* left, Operator, ExpressionNode* right, unsigned divot, unsigned startOffset, unsigned endOffset);
1070
1071    private:
1072        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1073
1074        ExpressionNode* m_left;
1075        Operator m_operator;
1076        ExpressionNode* m_right;
1077    };
1078
1079    typedef Vector<ExpressionNode*, 8> ExpressionVector;
1080
1081    class CommaNode : public ExpressionNode, public ParserArenaDeletable {
1082    public:
1083        CommaNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2);
1084
1085        using ParserArenaDeletable::operator new;
1086
1087        void append(ExpressionNode* expr) { m_expressions.append(expr); }
1088
1089    private:
1090        virtual bool isCommaNode() const { return true; }
1091        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1092
1093        ExpressionVector m_expressions;
1094    };
1095
1096    class ConstDeclNode : public ExpressionNode {
1097    public:
1098        ConstDeclNode(JSGlobalData*, const Identifier&, ExpressionNode*);
1099
1100        bool hasInitializer() const { return m_init; }
1101        const Identifier& ident() { return m_ident; }
1102
1103    private:
1104        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1105        virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1106
1107        const Identifier& m_ident;
1108
1109    public:
1110        ConstDeclNode* m_next;
1111
1112    private:
1113        ExpressionNode* m_init;
1114    };
1115
1116    class ConstStatementNode : public StatementNode {
1117    public:
1118        ConstStatementNode(JSGlobalData*, ConstDeclNode* next);
1119
1120    private:
1121        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1122
1123        ConstDeclNode* m_next;
1124    };
1125
1126    class SourceElements : public ParserArenaDeletable {
1127    public:
1128        SourceElements(JSGlobalData*);
1129
1130        void append(StatementNode*);
1131
1132        StatementNode* singleStatement() const;
1133        StatementNode* lastStatement() const;
1134
1135        void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1136
1137    private:
1138        Vector<StatementNode*> m_statements;
1139    };
1140
1141    class BlockNode : public StatementNode {
1142    public:
1143        BlockNode(JSGlobalData*, SourceElements* = 0);
1144
1145        StatementNode* lastStatement() const;
1146
1147    private:
1148        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1149
1150        virtual bool isBlock() const { return true; }
1151
1152        SourceElements* m_statements;
1153    };
1154
1155    class EmptyStatementNode : public StatementNode {
1156    public:
1157        EmptyStatementNode(JSGlobalData*);
1158
1159    private:
1160        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1161
1162        virtual bool isEmptyStatement() const { return true; }
1163    };
1164
1165    class DebuggerStatementNode : public StatementNode {
1166    public:
1167        DebuggerStatementNode(JSGlobalData*);
1168
1169    private:
1170        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1171    };
1172
1173    class ExprStatementNode : public StatementNode {
1174    public:
1175        ExprStatementNode(JSGlobalData*, ExpressionNode*);
1176
1177        ExpressionNode* expr() const { return m_expr; }
1178
1179    private:
1180        virtual bool isExprStatement() const { return true; }
1181
1182        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1183
1184        ExpressionNode* m_expr;
1185    };
1186
1187    class VarStatementNode : public StatementNode {
1188    public:
1189        VarStatementNode(JSGlobalData*, ExpressionNode*);
1190
1191    private:
1192        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1193
1194        ExpressionNode* m_expr;
1195    };
1196
1197    class IfNode : public StatementNode {
1198    public:
1199        IfNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock);
1200
1201    protected:
1202        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1203
1204        ExpressionNode* m_condition;
1205        StatementNode* m_ifBlock;
1206    };
1207
1208    class IfElseNode : public IfNode {
1209    public:
1210        IfElseNode(JSGlobalData*, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1211
1212    private:
1213        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1214
1215        StatementNode* m_elseBlock;
1216    };
1217
1218    class DoWhileNode : public StatementNode {
1219    public:
1220        DoWhileNode(JSGlobalData*, StatementNode* statement, ExpressionNode*);
1221
1222    private:
1223        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1224
1225        StatementNode* m_statement;
1226        ExpressionNode* m_expr;
1227    };
1228
1229    class WhileNode : public StatementNode {
1230    public:
1231        WhileNode(JSGlobalData*, ExpressionNode*, StatementNode* statement);
1232
1233    private:
1234        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1235
1236        ExpressionNode* m_expr;
1237        StatementNode* m_statement;
1238    };
1239
1240    class ForNode : public StatementNode {
1241    public:
1242        ForNode(JSGlobalData*, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode* statement, bool expr1WasVarDecl);
1243
1244    private:
1245        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1246
1247        ExpressionNode* m_expr1;
1248        ExpressionNode* m_expr2;
1249        ExpressionNode* m_expr3;
1250        StatementNode* m_statement;
1251        bool m_expr1WasVarDecl;
1252    };
1253
1254    class ForInNode : public StatementNode, public ThrowableExpressionData {
1255    public:
1256        ForInNode(JSGlobalData*, ExpressionNode*, ExpressionNode*, StatementNode*);
1257        ForInNode(JSGlobalData*, const Identifier&, ExpressionNode*, ExpressionNode*, StatementNode*, int divot, int startOffset, int endOffset);
1258
1259    private:
1260        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1261
1262        const Identifier& m_ident;
1263        ExpressionNode* m_init;
1264        ExpressionNode* m_lexpr;
1265        ExpressionNode* m_expr;
1266        StatementNode* m_statement;
1267        bool m_identIsVarDecl;
1268    };
1269
1270    class ContinueNode : public StatementNode, public ThrowableExpressionData {
1271    public:
1272        ContinueNode(JSGlobalData*);
1273        ContinueNode(JSGlobalData*, const Identifier&);
1274
1275    private:
1276        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1277
1278        const Identifier& m_ident;
1279    };
1280
1281    class BreakNode : public StatementNode, public ThrowableExpressionData {
1282    public:
1283        BreakNode(JSGlobalData*);
1284        BreakNode(JSGlobalData*, const Identifier&);
1285
1286    private:
1287        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1288
1289        const Identifier& m_ident;
1290    };
1291
1292    class ReturnNode : public StatementNode, public ThrowableExpressionData {
1293    public:
1294        ReturnNode(JSGlobalData*, ExpressionNode* value);
1295
1296    private:
1297        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1298
1299        virtual bool isReturnNode() const { return true; }
1300
1301        ExpressionNode* m_value;
1302    };
1303
1304    class WithNode : public StatementNode {
1305    public:
1306        WithNode(JSGlobalData*, ExpressionNode*, StatementNode*, uint32_t divot, uint32_t expressionLength);
1307
1308    private:
1309        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1310
1311        ExpressionNode* m_expr;
1312        StatementNode* m_statement;
1313        uint32_t m_divot;
1314        uint32_t m_expressionLength;
1315    };
1316
1317    class LabelNode : public StatementNode, public ThrowableExpressionData {
1318    public:
1319        LabelNode(JSGlobalData*, const Identifier& name, StatementNode*);
1320
1321    private:
1322        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1323
1324        const Identifier& m_name;
1325        StatementNode* m_statement;
1326    };
1327
1328    class ThrowNode : public StatementNode, public ThrowableExpressionData {
1329    public:
1330        ThrowNode(JSGlobalData*, ExpressionNode*);
1331
1332    private:
1333        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1334
1335        ExpressionNode* m_expr;
1336    };
1337
1338    class TryNode : public StatementNode {
1339    public:
1340        TryNode(JSGlobalData*, StatementNode* tryBlock, const Identifier& exceptionIdent, bool catchHasEval, StatementNode* catchBlock, StatementNode* finallyBlock);
1341
1342    private:
1343        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1344
1345        StatementNode* m_tryBlock;
1346        const Identifier& m_exceptionIdent;
1347        StatementNode* m_catchBlock;
1348        StatementNode* m_finallyBlock;
1349        bool m_catchHasEval;
1350    };
1351
1352    class ParameterNode : public ParserArenaFreeable {
1353    public:
1354        ParameterNode(JSGlobalData*, const Identifier&);
1355        ParameterNode(JSGlobalData*, ParameterNode*, const Identifier&);
1356
1357        const Identifier& ident() const { return m_ident; }
1358        ParameterNode* nextParam() const { return m_next; }
1359
1360    private:
1361        const Identifier& m_ident;
1362        ParameterNode* m_next;
1363    };
1364
1365    struct ScopeNodeData : FastAllocBase {
1366        typedef DeclarationStacks::VarStack VarStack;
1367        typedef DeclarationStacks::FunctionStack FunctionStack;
1368
1369        ScopeNodeData(ParserArena&, SourceElements*, VarStack*, FunctionStack*, int numConstants);
1370
1371        ParserArena m_arena;
1372        VarStack m_varStack;
1373        FunctionStack m_functionStack;
1374        int m_numConstants;
1375        SourceElements* m_statements;
1376    };
1377
1378    class ScopeNode : public StatementNode, public ParserArenaRefCounted {
1379    public:
1380        typedef DeclarationStacks::VarStack VarStack;
1381        typedef DeclarationStacks::FunctionStack FunctionStack;
1382
1383        ScopeNode(JSGlobalData*);
1384        ScopeNode(JSGlobalData*, const SourceCode&, SourceElements*, VarStack*, FunctionStack*, CodeFeatures, int numConstants);
1385
1386        using ParserArenaRefCounted::operator new;
1387
1388        void adoptData(std::auto_ptr<ScopeNodeData> data)
1389        {
1390            ASSERT(!data->m_arena.contains(this));
1391            ASSERT(!m_data);
1392            m_data.adopt(data);
1393        }
1394        ScopeNodeData* data() const { return m_data.get(); }
1395        void destroyData() { m_data.clear(); }
1396
1397        const SourceCode& source() const { return m_source; }
1398        const UString& sourceURL() const { return m_source.provider()->url(); }
1399        intptr_t sourceID() const { return m_source.provider()->asID(); }
1400
1401        void setFeatures(CodeFeatures features) { m_features = features; }
1402        CodeFeatures features() { return m_features; }
1403
1404        bool usesEval() const { return m_features & EvalFeature; }
1405        bool usesArguments() const { return m_features & ArgumentsFeature; }
1406        void setUsesArguments() { m_features |= ArgumentsFeature; }
1407        bool usesThis() const { return m_features & ThisFeature; }
1408        bool needsActivation() const { return m_features & (EvalFeature | ClosureFeature | WithFeature | CatchFeature); }
1409
1410        VarStack& varStack() { ASSERT(m_data); return m_data->m_varStack; }
1411        FunctionStack& functionStack() { ASSERT(m_data); return m_data->m_functionStack; }
1412
1413        int neededConstants()
1414        {
1415            ASSERT(m_data);
1416            // We may need 2 more constants than the count given by the parser,
1417            // because of the various uses of jsUndefined() and jsNull().
1418            return m_data->m_numConstants + 2;
1419        }
1420
1421        StatementNode* singleStatement() const;
1422
1423        void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1424
1425    protected:
1426        void setSource(const SourceCode& source) { m_source = source; }
1427
1428    private:
1429        OwnPtr<ScopeNodeData> m_data;
1430        CodeFeatures m_features;
1431        SourceCode m_source;
1432    };
1433
1434    class ProgramNode : public ScopeNode {
1435    public:
1436        static PassRefPtr<ProgramNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1437
1438        static const bool scopeIsFunction = false;
1439
1440    private:
1441        ProgramNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1442
1443        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1444    };
1445
1446    class EvalNode : public ScopeNode {
1447    public:
1448        static PassRefPtr<EvalNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1449
1450        static const bool scopeIsFunction = false;
1451
1452    private:
1453        EvalNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1454
1455        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1456    };
1457
1458    class FunctionParameters : public Vector<Identifier>, public RefCounted<FunctionParameters> {
1459    public:
1460        static PassRefPtr<FunctionParameters> create(ParameterNode* firstParameter) { return adoptRef(new FunctionParameters(firstParameter)); }
1461
1462    private:
1463        FunctionParameters(ParameterNode*);
1464    };
1465
1466    class FunctionBodyNode : public ScopeNode {
1467    public:
1468        static FunctionBodyNode* create(JSGlobalData*);
1469        static PassRefPtr<FunctionBodyNode> create(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1470
1471        FunctionParameters* parameters() const { return m_parameters.get(); }
1472        size_t parameterCount() const { return m_parameters->size(); }
1473
1474        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1475
1476        void finishParsing(const SourceCode&, ParameterNode*, const Identifier&);
1477        void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&);
1478
1479        const Identifier& ident() { return m_ident; }
1480
1481        static const bool scopeIsFunction = true;
1482
1483    private:
1484        FunctionBodyNode(JSGlobalData*);
1485        FunctionBodyNode(JSGlobalData*, SourceElements*, VarStack*, FunctionStack*, const SourceCode&, CodeFeatures, int numConstants);
1486
1487        Identifier m_ident;
1488        RefPtr<FunctionParameters> m_parameters;
1489    };
1490
1491    class FuncExprNode : public ExpressionNode {
1492    public:
1493        FuncExprNode(JSGlobalData*, const Identifier&, FunctionBodyNode* body, const SourceCode& source, ParameterNode* parameter = 0);
1494
1495        FunctionBodyNode* body() { return m_body; }
1496
1497    private:
1498        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1499
1500        virtual bool isFuncExprNode() const { return true; }
1501
1502        FunctionBodyNode* m_body;
1503    };
1504
1505    class FuncDeclNode : public StatementNode {
1506    public:
1507        FuncDeclNode(JSGlobalData*, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1508
1509        FunctionBodyNode* body() { return m_body; }
1510
1511    private:
1512        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1513
1514        FunctionBodyNode* m_body;
1515    };
1516
1517    class CaseClauseNode : public ParserArenaFreeable {
1518    public:
1519        CaseClauseNode(JSGlobalData*, ExpressionNode*, SourceElements* = 0);
1520
1521        ExpressionNode* expr() const { return m_expr; }
1522
1523        void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1524
1525    private:
1526        ExpressionNode* m_expr;
1527        SourceElements* m_statements;
1528    };
1529
1530    class ClauseListNode : public ParserArenaFreeable {
1531    public:
1532        ClauseListNode(JSGlobalData*, CaseClauseNode*);
1533        ClauseListNode(JSGlobalData*, ClauseListNode*, CaseClauseNode*);
1534
1535        CaseClauseNode* getClause() const { return m_clause; }
1536        ClauseListNode* getNext() const { return m_next; }
1537
1538    private:
1539        CaseClauseNode* m_clause;
1540        ClauseListNode* m_next;
1541    };
1542
1543    class CaseBlockNode : public ParserArenaFreeable {
1544    public:
1545        CaseBlockNode(JSGlobalData*, ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1546
1547        RegisterID* emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
1548
1549    private:
1550        SwitchInfo::SwitchType tryOptimizedSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1551        ClauseListNode* m_list1;
1552        CaseClauseNode* m_defaultClause;
1553        ClauseListNode* m_list2;
1554    };
1555
1556    class SwitchNode : public StatementNode {
1557    public:
1558        SwitchNode(JSGlobalData*, ExpressionNode*, CaseBlockNode*);
1559
1560    private:
1561        virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0);
1562
1563        ExpressionNode* m_expr;
1564        CaseBlockNode* m_block;
1565    };
1566
1567    struct ElementList {
1568        ElementNode* head;
1569        ElementNode* tail;
1570    };
1571
1572    struct PropertyList {
1573        PropertyListNode* head;
1574        PropertyListNode* tail;
1575    };
1576
1577    struct ArgumentList {
1578        ArgumentListNode* head;
1579        ArgumentListNode* tail;
1580    };
1581
1582    struct ConstDeclList {
1583        ConstDeclNode* head;
1584        ConstDeclNode* tail;
1585    };
1586
1587    struct ParameterList {
1588        ParameterNode* head;
1589        ParameterNode* tail;
1590    };
1591
1592    struct ClauseList {
1593        ClauseListNode* head;
1594        ClauseListNode* tail;
1595    };
1596
1597} // namespace JSC
1598
1599#endif // Nodes_h
1600