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