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