Adjust the ranges of basic block statements in JSC's control flow profiler to be...
[WebKit-https.git] / Source / JavaScriptCore / parser / Nodes.h
1 /*
2  *  Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3  *  Copyright (C) 2001 Peter Kelly (pmk@post.com)
4  *  Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013 Apple Inc. All rights reserved.
5  *  Copyright (C) 2007 Cameron Zwarich (cwzwarich@uwaterloo.ca)
6  *  Copyright (C) 2007 Maks Orlovich
7  *  Copyright (C) 2007 Eric Seidel <eric@webkit.org>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Library General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Library General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Library General Public License
20  *  along with this library; see the file COPYING.LIB.  If not, write to
21  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  *  Boston, MA 02110-1301, USA.
23  *
24  */
25
26 #ifndef Nodes_h
27 #define Nodes_h
28
29 #include "Error.h"
30 #include "JITCode.h"
31 #include "Opcode.h"
32 #include "ParserArena.h"
33 #include "ParserTokens.h"
34 #include "ResultType.h"
35 #include "SourceCode.h"
36 #include "SymbolTable.h"
37 #include <wtf/MathExtras.h>
38
39 namespace JSC {
40
41     class ArgumentListNode;
42     class BytecodeGenerator;
43     class FunctionBodyNode;
44     class Label;
45     class PropertyListNode;
46     class ReadModifyResolveNode;
47     class RegisterID;
48     class JSScope;
49     class ScopeNode;
50
51     enum Operator {
52         OpEqual,
53         OpPlusEq,
54         OpMinusEq,
55         OpMultEq,
56         OpDivEq,
57         OpPlusPlus,
58         OpMinusMinus,
59         OpAndEq,
60         OpXOrEq,
61         OpOrEq,
62         OpModEq,
63         OpLShift,
64         OpRShift,
65         OpURShift
66     };
67     
68     enum LogicalOperator {
69         OpLogicalAnd,
70         OpLogicalOr
71     };
72
73     enum FallThroughMode {
74         FallThroughMeansTrue = 0,
75         FallThroughMeansFalse = 1
76     };
77     inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
78
79     typedef HashSet<RefPtr<StringImpl>, IdentifierRepHash> IdentifierSet;
80
81     namespace DeclarationStacks {
82         enum VarAttrs { IsConstant = 1, HasInitializer = 2 };
83         typedef Vector<std::pair<Identifier, unsigned>> VarStack;
84         typedef Vector<FunctionBodyNode*> FunctionStack;
85     }
86
87     struct SwitchInfo {
88         enum SwitchType { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
89         uint32_t bytecodeOffset;
90         SwitchType switchType;
91     };
92
93     class ParserArenaFreeable {
94     public:
95         // ParserArenaFreeable objects are are freed when the arena is deleted.
96         // Destructors are not called. Clients must not call delete on such objects.
97         void* operator new(size_t, ParserArena&);
98     };
99
100     class ParserArenaDeletable {
101     public:
102         virtual ~ParserArenaDeletable() { }
103
104         // ParserArenaDeletable objects are deleted when the arena is deleted.
105         // Clients must not call delete directly on such objects.
106         void* operator new(size_t, ParserArena&);
107     };
108
109     class ParserArenaRoot {
110         WTF_MAKE_FAST_ALLOCATED;
111     protected:
112         ParserArenaRoot(ParserArena&);
113
114     public:
115         ParserArena& parserArena() { return m_arena; }
116         virtual ~ParserArenaRoot() { }
117
118     protected:
119         ParserArena m_arena;
120     };
121
122     class Node : public ParserArenaFreeable {
123     protected:
124         Node(const JSTokenLocation&);
125
126     public:
127         virtual ~Node() { }
128
129         int lineNo() const { return m_position.line; }
130         int startOffset() const { return m_position.offset; }
131         int endOffset() const { return m_endOffset; }
132         int lineStartOffset() const { return m_position.lineStartOffset; }
133         const JSTextPosition& position() const { return m_position; }
134         void setEndOffset(int offset) { m_endOffset = offset; }
135         void setStartOffset(int offset) { m_position.offset = offset; }
136
137     protected:
138         JSTextPosition m_position;
139         int m_endOffset;
140     };
141
142     class ExpressionNode : public Node {
143     protected:
144         ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
145
146     public:
147         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
148
149         virtual bool isNumber() const { return false; }
150         virtual bool isString() const { return false; }
151         virtual bool isNull() const { return false; }
152         virtual bool isPure(BytecodeGenerator&) const { return false; }        
153         virtual bool isConstant() const { return false; }
154         virtual bool isLocation() const { return false; }
155         virtual bool isAssignmentLocation() const { return isLocation(); }
156         virtual bool isResolveNode() const { return false; }
157         virtual bool isBracketAccessorNode() const { return false; }
158         virtual bool isDotAccessorNode() const { return false; }
159         virtual bool isDeconstructionNode() const { return false; }
160         virtual bool isFuncExprNode() const { return false; }
161         virtual bool isCommaNode() const { return false; }
162         virtual bool isSimpleArray() const { return false; }
163         virtual bool isAdd() const { return false; }
164         virtual bool isSubtract() const { return false; }
165         virtual bool isBoolean() const { return false; }
166         virtual bool isSpreadExpression() const { return false; }
167
168         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label*, Label*, FallThroughMode);
169
170         virtual ExpressionNode* stripUnaryPlus() { return this; }
171
172         ResultType resultDescriptor() const { return m_resultType; }
173
174     private:
175         ResultType m_resultType;
176     };
177
178     class StatementNode : public Node {
179     protected:
180         StatementNode(const JSTokenLocation&);
181
182     public:
183         virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
184
185         void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
186         unsigned firstLine() const { return lineNo(); }
187         unsigned lastLine() const { return m_lastLine; }
188
189         StatementNode* next() { return m_next; }
190         void setNext(StatementNode* next) { m_next = next; }
191
192         virtual bool isEmptyStatement() const { return false; }
193         virtual bool isReturnNode() const { return false; }
194         virtual bool isExprStatement() const { return false; }
195         virtual bool isBreak() const { return false; }
196         virtual bool isContinue() const { return false; }
197         virtual bool isBlock() const { return false; }
198
199     protected:
200         StatementNode* m_next;
201         int m_lastLine;
202     };
203
204     class ConstantNode : public ExpressionNode {
205     public:
206         ConstantNode(const JSTokenLocation&, ResultType);
207         virtual bool isPure(BytecodeGenerator&) const override { return true; }
208         virtual bool isConstant() const  override { return true; }
209         virtual JSValue jsValue(BytecodeGenerator&) const = 0;
210     private:
211         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
212         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
213     };
214
215     class NullNode : public ConstantNode {
216     public:
217         NullNode(const JSTokenLocation&);
218
219     private:
220         virtual bool isNull() const override { return true; }
221         virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
222     };
223
224     class BooleanNode : public ConstantNode {
225     public:
226         BooleanNode(const JSTokenLocation&, bool value);
227         bool value() { return m_value; }
228
229     private:
230         virtual bool isBoolean() const override { return true; }
231         virtual JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
232
233         bool m_value;
234     };
235
236     class NumberNode : public ConstantNode {
237     public:
238         NumberNode(const JSTokenLocation&, double value);
239         double value() { return m_value; }
240         void setValue(double value) { m_value = value; }
241
242     private:
243         virtual bool isNumber() const override { return true; }
244         virtual JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
245
246         double m_value;
247     };
248
249     class StringNode : public ConstantNode {
250     public:
251         StringNode(const JSTokenLocation&, const Identifier&);
252         const Identifier& value() { return m_value; }
253
254     private:
255         virtual bool isString() const override { return true; }
256         virtual JSValue jsValue(BytecodeGenerator&) const override;
257
258         const Identifier& m_value;
259     };
260     
261     class ThrowableExpressionData {
262     public:
263         ThrowableExpressionData()
264             : m_divot(-1, -1, -1)
265             , m_divotStart(-1, -1, -1)
266             , m_divotEnd(-1, -1, -1)
267         {
268         }
269         
270         ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
271             : m_divot(divot)
272             , m_divotStart(start)
273             , m_divotEnd(end)
274         {
275             ASSERT(m_divot.offset >= m_divot.lineStartOffset);
276             ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset);
277             ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset);
278         }
279
280         void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
281         {
282             ASSERT(divot.offset >= divot.lineStartOffset);
283             ASSERT(divotStart.offset >= divotStart.lineStartOffset);
284             ASSERT(divotEnd.offset >= divotEnd.lineStartOffset);
285             m_divot = divot;
286             m_divotStart = divotStart;
287             m_divotEnd = divotEnd;
288         }
289
290         const JSTextPosition& divot() const { return m_divot; }
291         const JSTextPosition& divotStart() const { return m_divotStart; }
292         const JSTextPosition& divotEnd() const { return m_divotEnd; }
293
294     protected:
295         RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
296
297     private:
298         JSTextPosition m_divot;
299         JSTextPosition m_divotStart;
300         JSTextPosition m_divotEnd;
301     };
302
303     class ThrowableSubExpressionData : public ThrowableExpressionData {
304     public:
305         ThrowableSubExpressionData()
306             : m_subexpressionDivotOffset(0)
307             , m_subexpressionEndOffset(0)
308             , m_subexpressionLineOffset(0)
309             , m_subexpressionLineStartOffset(0)
310         {
311         }
312
313         ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
314             : ThrowableExpressionData(divot, divotStart, divotEnd)
315             , m_subexpressionDivotOffset(0)
316             , m_subexpressionEndOffset(0)
317             , m_subexpressionLineOffset(0)
318             , m_subexpressionLineStartOffset(0)
319         {
320         }
321
322         void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
323         {
324             ASSERT(subexpressionDivot.offset <= divot().offset);
325             // Overflow means we can't do this safely, so just point at the primary divot,
326             // divotLine, or divotLineStart.
327             if ((divot() - subexpressionDivot.offset) & ~0xFFFF)
328                 return;
329             if ((divot().line - subexpressionDivot.line) & ~0xFFFF)
330                 return;
331             if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF)
332                 return;
333             if ((divotEnd() - subexpressionOffset) & ~0xFFFF)
334                 return;
335             m_subexpressionDivotOffset = divot() - subexpressionDivot.offset;
336             m_subexpressionEndOffset = divotEnd() - subexpressionOffset;
337             m_subexpressionLineOffset = divot().line - subexpressionDivot.line;
338             m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset;
339         }
340
341         JSTextPosition subexpressionDivot()
342         {
343             int newLine = divot().line - m_subexpressionLineOffset;
344             int newOffset = divot().offset - m_subexpressionDivotOffset;
345             int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset;
346             return JSTextPosition(newLine, newOffset, newLineStartOffset);
347         }
348         JSTextPosition subexpressionStart() { return divotStart(); }
349         JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); }
350
351     protected:
352         uint16_t m_subexpressionDivotOffset;
353         uint16_t m_subexpressionEndOffset;
354         uint16_t m_subexpressionLineOffset;
355         uint16_t m_subexpressionLineStartOffset;
356     };
357     
358     class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
359     public:
360         ThrowablePrefixedSubExpressionData()
361             : m_subexpressionDivotOffset(0)
362             , m_subexpressionStartOffset(0)
363             , m_subexpressionLineOffset(0)
364             , m_subexpressionLineStartOffset(0)
365         {
366         }
367
368         ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
369             : ThrowableExpressionData(divot, start, end)
370             , m_subexpressionDivotOffset(0)
371             , m_subexpressionStartOffset(0)
372             , m_subexpressionLineOffset(0)
373             , m_subexpressionLineStartOffset(0)
374         {
375         }
376
377         void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
378         {
379             ASSERT(subexpressionDivot.offset >= divot().offset);
380             // Overflow means we can't do this safely, so just point at the primary divot,
381             // divotLine, or divotLineStart.
382             if ((subexpressionDivot.offset - divot()) & ~0xFFFF) 
383                 return;
384             if ((subexpressionDivot.line - divot().line) & ~0xFFFF)
385                 return;
386             if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF)
387                 return;
388             if ((subexpressionOffset - divotStart()) & ~0xFFFF) 
389                 return;
390             m_subexpressionDivotOffset = subexpressionDivot.offset - divot();
391             m_subexpressionStartOffset = subexpressionOffset - divotStart();
392             m_subexpressionLineOffset = subexpressionDivot.line - divot().line;
393             m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset;
394         }
395
396         JSTextPosition subexpressionDivot()
397         {
398             int newLine = divot().line + m_subexpressionLineOffset;
399             int newOffset = divot().offset + m_subexpressionDivotOffset;
400             int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset;
401             return JSTextPosition(newLine, newOffset, newLineStartOffset);
402         }
403         JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); }
404         JSTextPosition subexpressionEnd() { return divotEnd(); }
405
406     protected:
407         uint16_t m_subexpressionDivotOffset;
408         uint16_t m_subexpressionStartOffset;
409         uint16_t m_subexpressionLineOffset;
410         uint16_t m_subexpressionLineStartOffset;
411     };
412
413     class RegExpNode : public ExpressionNode, public ThrowableExpressionData {
414     public:
415         RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
416
417     private:
418         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
419
420         const Identifier& m_pattern;
421         const Identifier& m_flags;
422     };
423
424     class ThisNode : public ExpressionNode {
425     public:
426         ThisNode(const JSTokenLocation&);
427
428     private:
429         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
430     };
431
432     class ResolveNode : public ExpressionNode {
433     public:
434         ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
435
436         const Identifier& identifier() const { return m_ident; }
437
438     private:
439         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
440
441         virtual bool isPure(BytecodeGenerator&) const override;
442         virtual bool isLocation() const override { return true; }
443         virtual bool isResolveNode() const override { return true; }
444
445         const Identifier& m_ident;
446         JSTextPosition m_start;
447     };
448
449     class ElementNode : public ParserArenaFreeable {
450     public:
451         ElementNode(int elision, ExpressionNode*);
452         ElementNode(ElementNode*, int elision, ExpressionNode*);
453
454         int elision() const { return m_elision; }
455         ExpressionNode* value() { return m_node; }
456         ElementNode* next() { return m_next; }
457
458     private:
459         ElementNode* m_next;
460         int m_elision;
461         ExpressionNode* m_node;
462     };
463
464     class ArrayNode : public ExpressionNode {
465     public:
466         ArrayNode(const JSTokenLocation&, int elision);
467         ArrayNode(const JSTokenLocation&, ElementNode*);
468         ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
469
470         ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
471
472         ElementNode* elements() const { ASSERT(isSimpleArray()); return m_element; }
473     private:
474         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
475
476         virtual bool isSimpleArray() const override;
477
478         ElementNode* m_element;
479         int m_elision;
480         bool m_optional;
481     };
482
483     class PropertyNode : public ParserArenaFreeable {
484     public:
485         enum Type { Constant = 1, Getter = 2, Setter = 4 };
486
487         PropertyNode(const Identifier&, ExpressionNode*, Type);
488         PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type);
489         
490         ExpressionNode* expressionName() const { return m_expression; }
491         const Identifier* name() const { return m_name; }
492
493         Type type() const { return m_type; }
494
495     private:
496         friend class PropertyListNode;
497         const Identifier* m_name;
498         ExpressionNode* m_expression;
499         ExpressionNode* m_assign;
500         Type m_type;
501     };
502
503     class PropertyListNode : public ExpressionNode {
504     public:
505         PropertyListNode(const JSTokenLocation&, PropertyNode*);
506         PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
507
508     private:
509         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
510         void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
511
512         PropertyNode* m_node;
513         PropertyListNode* m_next;
514     };
515
516     class ObjectLiteralNode : public ExpressionNode {
517     public:
518         ObjectLiteralNode(const JSTokenLocation&);
519         ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
520
521     private:
522         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
523
524         PropertyListNode* m_list;
525     };
526     
527     class BracketAccessorNode : public ExpressionNode, public ThrowableExpressionData {
528     public:
529         BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
530
531         ExpressionNode* base() const { return m_base; }
532         ExpressionNode* subscript() const { return m_subscript; }
533
534         bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
535
536     private:
537         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
538
539         virtual bool isLocation() const override { return true; }
540         virtual bool isBracketAccessorNode() const override { return true; }
541
542         ExpressionNode* m_base;
543         ExpressionNode* m_subscript;
544         bool m_subscriptHasAssignments;
545     };
546
547     class DotAccessorNode : public ExpressionNode, public ThrowableExpressionData {
548     public:
549         DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
550
551         ExpressionNode* base() const { return m_base; }
552         const Identifier& identifier() const { return m_ident; }
553
554     private:
555         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
556
557         virtual bool isLocation() const override { return true; }
558         virtual bool isDotAccessorNode() const override { return true; }
559
560         ExpressionNode* m_base;
561         const Identifier& m_ident;
562     };
563
564     class SpreadExpressionNode : public ExpressionNode, public ThrowableExpressionData {
565     public:
566         SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
567         
568         ExpressionNode* expression() const { return m_expression; }
569         
570     private:
571         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
572         
573         virtual bool isSpreadExpression() const override { return true; }
574         ExpressionNode* m_expression;
575     };
576
577     class ArgumentListNode : public ExpressionNode {
578     public:
579         ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
580         ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
581
582         ArgumentListNode* m_next;
583         ExpressionNode* m_expr;
584
585     private:
586         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
587     };
588
589     class ArgumentsNode : public ParserArenaFreeable {
590     public:
591         ArgumentsNode();
592         ArgumentsNode(ArgumentListNode*);
593
594         ArgumentListNode* m_listNode;
595     };
596
597     class NewExprNode : public ExpressionNode, public ThrowableExpressionData {
598     public:
599         NewExprNode(const JSTokenLocation&, ExpressionNode*);
600         NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
601
602     private:
603         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
604
605         ExpressionNode* m_expr;
606         ArgumentsNode* m_args;
607     };
608
609     class EvalFunctionCallNode : public ExpressionNode, public ThrowableExpressionData {
610     public:
611         EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
612
613     private:
614         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
615
616         ArgumentsNode* m_args;
617     };
618
619     class FunctionCallValueNode : public ExpressionNode, public ThrowableExpressionData {
620     public:
621         FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
622
623     private:
624         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
625
626         ExpressionNode* m_expr;
627         ArgumentsNode* m_args;
628     };
629
630     class FunctionCallResolveNode : public ExpressionNode, public ThrowableExpressionData {
631     public:
632         FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
633
634     private:
635         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
636
637         const Identifier& m_ident;
638         ArgumentsNode* m_args;
639     };
640     
641     class FunctionCallBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
642     public:
643         FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
644
645     private:
646         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
647
648         ExpressionNode* m_base;
649         ExpressionNode* m_subscript;
650         ArgumentsNode* m_args;
651     };
652
653     class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
654     public:
655         FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
656
657     private:
658         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
659
660     protected:
661         ExpressionNode* m_base;
662         const Identifier& m_ident;
663         ArgumentsNode* m_args;
664     };
665
666     class CallFunctionCallDotNode : public FunctionCallDotNode {
667     public:
668         CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
669
670     private:
671         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
672     };
673     
674     class ApplyFunctionCallDotNode : public FunctionCallDotNode {
675     public:
676         ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
677
678     private:
679         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
680     };
681
682     class DeleteResolveNode : public ExpressionNode, public ThrowableExpressionData {
683     public:
684         DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
685
686     private:
687         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
688
689         const Identifier& m_ident;
690     };
691
692     class DeleteBracketNode : public ExpressionNode, public ThrowableExpressionData {
693     public:
694         DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
695
696     private:
697         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
698
699         ExpressionNode* m_base;
700         ExpressionNode* m_subscript;
701     };
702
703     class DeleteDotNode : public ExpressionNode, public ThrowableExpressionData {
704     public:
705         DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
706
707     private:
708         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
709
710         ExpressionNode* m_base;
711         const Identifier& m_ident;
712     };
713
714     class DeleteValueNode : public ExpressionNode {
715     public:
716         DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
717
718     private:
719         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
720
721         ExpressionNode* m_expr;
722     };
723
724     class VoidNode : public ExpressionNode {
725     public:
726         VoidNode(const JSTokenLocation&, ExpressionNode*);
727
728     private:
729         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
730
731         ExpressionNode* m_expr;
732     };
733
734     class TypeOfResolveNode : public ExpressionNode {
735     public:
736         TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
737
738         const Identifier& identifier() const { return m_ident; }
739
740     private:
741         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
742
743         const Identifier& m_ident;
744     };
745
746     class TypeOfValueNode : public ExpressionNode {
747     public:
748         TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
749
750     private:
751         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
752
753         ExpressionNode* m_expr;
754     };
755
756     class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
757     public:
758         PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
759
760     protected:
761         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
762         virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
763         virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
764         virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
765
766         ExpressionNode* m_expr;
767         Operator m_operator;
768     };
769
770     class PostfixNode : public PrefixNode {
771     public:
772         PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
773
774     private:
775         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
776         virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override;
777         virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override;
778         virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override;
779     };
780
781     class UnaryOpNode : public ExpressionNode {
782     public:
783         UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
784
785     protected:
786         ExpressionNode* expr() { return m_expr; }
787         const ExpressionNode* expr() const { return m_expr; }
788
789     private:
790         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
791
792         OpcodeID opcodeID() const { return m_opcodeID; }
793
794         ExpressionNode* m_expr;
795         OpcodeID m_opcodeID;
796     };
797
798     class UnaryPlusNode : public UnaryOpNode {
799     public:
800         UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
801
802     private:
803         virtual ExpressionNode* stripUnaryPlus() override { return expr(); }
804     };
805
806     class NegateNode : public UnaryOpNode {
807     public:
808         NegateNode(const JSTokenLocation&, ExpressionNode*);
809     };
810
811     class BitwiseNotNode : public ExpressionNode {
812     public:
813         BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
814
815     protected:
816         ExpressionNode* expr() { return m_expr; }
817         const ExpressionNode* expr() const { return m_expr; }
818
819     private:
820         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
821
822         ExpressionNode* m_expr;
823     };
824  
825     class LogicalNotNode : public UnaryOpNode {
826     public:
827         LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
828     private:
829         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
830     };
831
832     class BinaryOpNode : public ExpressionNode {
833     public:
834         BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
835         BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
836
837         RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
838         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
839
840         ExpressionNode* lhs() { return m_expr1; };
841         ExpressionNode* rhs() { return m_expr2; };
842
843     private:
844         void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
845         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
846
847     protected:
848         OpcodeID opcodeID() const { return m_opcodeID; }
849
850     protected:
851         ExpressionNode* m_expr1;
852         ExpressionNode* m_expr2;
853     private:
854         OpcodeID m_opcodeID;
855     protected:
856         bool m_rightHasAssignments;
857     };
858
859     class MultNode : public BinaryOpNode {
860     public:
861         MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
862     };
863
864     class DivNode : public BinaryOpNode {
865     public:
866         DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
867     };
868
869     class ModNode : public BinaryOpNode {
870     public:
871         ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
872     };
873
874     class AddNode : public BinaryOpNode {
875     public:
876         AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
877
878         virtual bool isAdd() const override { return true; }
879     };
880
881     class SubNode : public BinaryOpNode {
882     public:
883         SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
884
885         virtual bool isSubtract() const override { return true; }
886     };
887
888     class LeftShiftNode : public BinaryOpNode {
889     public:
890         LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
891     };
892
893     class RightShiftNode : public BinaryOpNode {
894     public:
895         RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
896     };
897
898     class UnsignedRightShiftNode : public BinaryOpNode {
899     public:
900         UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
901     };
902
903     class LessNode : public BinaryOpNode {
904     public:
905         LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
906     };
907
908     class GreaterNode : public BinaryOpNode {
909     public:
910         GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
911     };
912
913     class LessEqNode : public BinaryOpNode {
914     public:
915         LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
916     };
917
918     class GreaterEqNode : public BinaryOpNode {
919     public:
920         GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
921     };
922
923     class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
924     public:
925         ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
926         ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
927
928     private:
929         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
930     };
931     
932     class InstanceOfNode : public ThrowableBinaryOpNode {
933     public:
934         InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
935
936     private:
937         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
938     };
939
940     class InNode : public ThrowableBinaryOpNode {
941     public:
942         InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
943     };
944
945     class EqualNode : public BinaryOpNode {
946     public:
947         EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
948
949     private:
950         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
951     };
952
953     class NotEqualNode : public BinaryOpNode {
954     public:
955         NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
956     };
957
958     class StrictEqualNode : public BinaryOpNode {
959     public:
960         StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
961
962     private:
963         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
964     };
965
966     class NotStrictEqualNode : public BinaryOpNode {
967     public:
968         NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
969     };
970
971     class BitAndNode : public BinaryOpNode {
972     public:
973         BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
974     };
975
976     class BitOrNode : public BinaryOpNode {
977     public:
978         BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
979     };
980
981     class BitXOrNode : public BinaryOpNode {
982     public:
983         BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
984     };
985
986     // m_expr1 && m_expr2, m_expr1 || m_expr2
987     class LogicalOpNode : public ExpressionNode {
988     public:
989         LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
990
991     private:
992         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
993         virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label* trueTarget, Label* falseTarget, FallThroughMode) override;
994
995         ExpressionNode* m_expr1;
996         ExpressionNode* m_expr2;
997         LogicalOperator m_operator;
998     };
999
1000     // The ternary operator, "m_logical ? m_expr1 : m_expr2"
1001     class ConditionalNode : public ExpressionNode {
1002     public:
1003         ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
1004
1005     private:
1006         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1007
1008         ExpressionNode* m_logical;
1009         ExpressionNode* m_expr1;
1010         ExpressionNode* m_expr2;
1011     };
1012
1013     class ReadModifyResolveNode : public ExpressionNode, public ThrowableExpressionData {
1014     public:
1015         ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode*  right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1016
1017     private:
1018         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1019
1020         const Identifier& m_ident;
1021         ExpressionNode* m_right;
1022         Operator m_operator;
1023         bool m_rightHasAssignments;
1024     };
1025
1026     class AssignResolveNode : public ExpressionNode, public ThrowableExpressionData {
1027     public:
1028         AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right);
1029
1030     private:
1031         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1032
1033         const Identifier& m_ident;
1034         ExpressionNode* m_right;
1035     };
1036
1037     class ReadModifyBracketNode : public ExpressionNode, public ThrowableSubExpressionData {
1038     public:
1039         ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1040
1041     private:
1042         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1043
1044         ExpressionNode* m_base;
1045         ExpressionNode* m_subscript;
1046         ExpressionNode* m_right;
1047         unsigned m_operator : 30;
1048         bool m_subscriptHasAssignments : 1;
1049         bool m_rightHasAssignments : 1;
1050     };
1051
1052     class AssignBracketNode : public ExpressionNode, public ThrowableExpressionData {
1053     public:
1054         AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1055
1056     private:
1057         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1058
1059         ExpressionNode* m_base;
1060         ExpressionNode* m_subscript;
1061         ExpressionNode* m_right;
1062         bool m_subscriptHasAssignments : 1;
1063         bool m_rightHasAssignments : 1;
1064     };
1065
1066     class AssignDotNode : public ExpressionNode, public ThrowableExpressionData {
1067     public:
1068         AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1069
1070     private:
1071         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1072
1073         ExpressionNode* m_base;
1074         const Identifier& m_ident;
1075         ExpressionNode* m_right;
1076         bool m_rightHasAssignments;
1077     };
1078
1079     class ReadModifyDotNode : public ExpressionNode, public ThrowableSubExpressionData {
1080     public:
1081         ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1082
1083     private:
1084         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1085
1086         ExpressionNode* m_base;
1087         const Identifier& m_ident;
1088         ExpressionNode* m_right;
1089         unsigned m_operator : 31;
1090         bool m_rightHasAssignments : 1;
1091     };
1092
1093     class AssignErrorNode : public ExpressionNode, public ThrowableExpressionData {
1094     public:
1095         AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1096
1097     private:
1098         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1099     };
1100     
1101     class CommaNode final : public ExpressionNode {
1102     public:
1103         CommaNode(const JSTokenLocation&, ExpressionNode*);
1104
1105         void setNext(CommaNode* next) { m_next = next; }
1106         CommaNode* next() { return m_next; }
1107
1108     private:
1109         virtual bool isCommaNode() const override { return true; }
1110         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1111
1112         ExpressionNode* m_expr;
1113         CommaNode* m_next;
1114     };
1115     
1116     class ConstDeclNode : public ExpressionNode {
1117     public:
1118         ConstDeclNode(const JSTokenLocation&, const Identifier&, ExpressionNode*);
1119
1120         bool hasInitializer() const { return m_init; }
1121         const Identifier& ident() { return m_ident; }
1122
1123     private:
1124         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1125         virtual RegisterID* emitCodeSingle(BytecodeGenerator&);
1126
1127         const Identifier& m_ident;
1128
1129     public:
1130         ConstDeclNode* m_next;
1131
1132     private:
1133         ExpressionNode* m_init;
1134     };
1135
1136     class ConstStatementNode : public StatementNode {
1137     public:
1138         ConstStatementNode(const JSTokenLocation&, ConstDeclNode* next);
1139
1140     private:
1141         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1142
1143         ConstDeclNode* m_next;
1144     };
1145
1146     class SourceElements final : public ParserArenaFreeable {
1147     public:
1148         SourceElements();
1149
1150         void append(StatementNode*);
1151
1152         StatementNode* singleStatement() const;
1153         StatementNode* lastStatement() const;
1154
1155         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1156
1157     private:
1158         StatementNode* m_head;
1159         StatementNode* m_tail;
1160     };
1161
1162     class BlockNode : public StatementNode {
1163     public:
1164         BlockNode(const JSTokenLocation&, SourceElements* = 0);
1165
1166         StatementNode* singleStatement() const;
1167         StatementNode* lastStatement() const;
1168
1169     private:
1170         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1171
1172         virtual bool isBlock() const override { return true; }
1173
1174         SourceElements* m_statements;
1175     };
1176
1177     class EmptyStatementNode : public StatementNode {
1178     public:
1179         EmptyStatementNode(const JSTokenLocation&);
1180
1181     private:
1182         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1183
1184         virtual bool isEmptyStatement() const override { return true; }
1185     };
1186     
1187     class DebuggerStatementNode : public StatementNode {
1188     public:
1189         DebuggerStatementNode(const JSTokenLocation&);
1190         
1191     private:
1192         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1193     };
1194
1195     class ExprStatementNode : public StatementNode {
1196     public:
1197         ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
1198
1199         ExpressionNode* expr() const { return m_expr; }
1200
1201     private:
1202         virtual bool isExprStatement() const override { return true; }
1203
1204         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1205
1206         ExpressionNode* m_expr;
1207     };
1208
1209     class VarStatementNode : public StatementNode {
1210     public:
1211         VarStatementNode(const JSTokenLocation&, ExpressionNode*);
1212     private:
1213         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1214
1215         ExpressionNode* m_expr;
1216     };
1217
1218     class EmptyVarExpression : public ExpressionNode {
1219     public:
1220         EmptyVarExpression(const JSTokenLocation&, const Identifier&);
1221
1222     private:
1223         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1224
1225         const Identifier& m_ident;
1226     };
1227
1228
1229     class IfElseNode : public StatementNode {
1230     public:
1231         IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1232
1233     private:
1234         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1235         bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
1236             Label*& trueTarget, FallThroughMode&);
1237
1238         ExpressionNode* m_condition;
1239         StatementNode* m_ifBlock;
1240         StatementNode* m_elseBlock;
1241     };
1242
1243     class DoWhileNode : public StatementNode {
1244     public:
1245         DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
1246
1247     private:
1248         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1249
1250         StatementNode* m_statement;
1251         ExpressionNode* m_expr;
1252     };
1253
1254     class WhileNode : public StatementNode {
1255     public:
1256         WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
1257
1258     private:
1259         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1260
1261         ExpressionNode* m_expr;
1262         StatementNode* m_statement;
1263     };
1264
1265     class ForNode : public StatementNode {
1266     public:
1267         ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*);
1268
1269     private:
1270         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1271
1272         ExpressionNode* m_expr1;
1273         ExpressionNode* m_expr2;
1274         ExpressionNode* m_expr3;
1275         StatementNode* m_statement;
1276     };
1277     
1278     class DeconstructionPatternNode;
1279     
1280     class EnumerationNode : public StatementNode, public ThrowableExpressionData {
1281     public:
1282         EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1283         
1284     protected:
1285         ExpressionNode* m_lexpr;
1286         ExpressionNode* m_expr;
1287         StatementNode* m_statement;
1288     };
1289     
1290     class ForInNode : public EnumerationNode {
1291     public:
1292         ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1293
1294     private:
1295         RegisterID* tryGetBoundLocal(BytecodeGenerator&);
1296         void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
1297         void emitMultiLoopBytecode(BytecodeGenerator&, RegisterID* dst);
1298
1299         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1300     };
1301     
1302     class ForOfNode : public EnumerationNode {
1303     public:
1304         ForOfNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*);
1305         
1306     private:
1307         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1308     };
1309
1310     class ContinueNode : public StatementNode, public ThrowableExpressionData {
1311     public:
1312         ContinueNode(const JSTokenLocation&, const Identifier&);
1313         Label* trivialTarget(BytecodeGenerator&);
1314         
1315     private:
1316         virtual bool isContinue() const override { return true; }
1317         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1318
1319         const Identifier& m_ident;
1320     };
1321
1322     class BreakNode : public StatementNode, public ThrowableExpressionData {
1323     public:
1324         BreakNode(const JSTokenLocation&, const Identifier&);
1325         Label* trivialTarget(BytecodeGenerator&);
1326         
1327     private:
1328         virtual bool isBreak() const override { return true; }
1329         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1330
1331         const Identifier& m_ident;
1332     };
1333
1334     class ReturnNode : public StatementNode, public ThrowableExpressionData {
1335     public:
1336         ReturnNode(const JSTokenLocation&, ExpressionNode* value);
1337
1338         ExpressionNode* value() { return m_value; }
1339
1340     private:
1341         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1342
1343         virtual bool isReturnNode() const override { return true; }
1344
1345         ExpressionNode* m_value;
1346     };
1347
1348     class WithNode : public StatementNode {
1349     public:
1350         WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
1351
1352     private:
1353         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1354
1355         ExpressionNode* m_expr;
1356         StatementNode* m_statement;
1357         JSTextPosition m_divot;
1358         uint32_t m_expressionLength;
1359     };
1360
1361     class LabelNode : public StatementNode, public ThrowableExpressionData {
1362     public:
1363         LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
1364
1365     private:
1366         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1367
1368         const Identifier& m_name;
1369         StatementNode* m_statement;
1370     };
1371
1372     class ThrowNode : public StatementNode, public ThrowableExpressionData {
1373     public:
1374         ThrowNode(const JSTokenLocation&, ExpressionNode*);
1375
1376     private:
1377         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1378
1379         ExpressionNode* m_expr;
1380     };
1381
1382     class TryNode : public StatementNode {
1383     public:
1384         TryNode(const JSTokenLocation&, StatementNode* tryBlock, const Identifier& exceptionIdent, StatementNode* catchBlock, StatementNode* finallyBlock);
1385
1386     private:
1387         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1388
1389         StatementNode* m_tryBlock;
1390         const Identifier& m_exceptionIdent;
1391         StatementNode* m_catchBlock;
1392         StatementNode* m_finallyBlock;
1393     };
1394
1395     class ParameterNode : public ParserArenaDeletable {
1396     public:
1397         ParameterNode(PassRefPtr<DeconstructionPatternNode>);
1398         ParameterNode(ParameterNode*, PassRefPtr<DeconstructionPatternNode>);
1399
1400         DeconstructionPatternNode* pattern() const { return m_pattern.get(); }
1401         ParameterNode* nextParam() const { return m_next; }
1402
1403     private:
1404         RefPtr<DeconstructionPatternNode> m_pattern;
1405         ParameterNode* m_next;
1406     };
1407
1408     class ScopeNode : public StatementNode, public ParserArenaRoot {
1409     public:
1410         typedef DeclarationStacks::VarStack VarStack;
1411         typedef DeclarationStacks::FunctionStack FunctionStack;
1412
1413         ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
1414         ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, CodeFeatures, int numConstants);
1415
1416         using ParserArenaRoot::operator new;
1417
1418         const SourceCode& source() const { return m_source; }
1419         const String& sourceURL() const { return m_source.provider()->url(); }
1420         intptr_t sourceID() const { return m_source.providerID(); }
1421
1422         int startLine() const { return m_startLineNumber; }
1423         int startStartOffset() const { return m_startStartOffset; }
1424         int startLineStartOffset() const { return m_startLineStartOffset; }
1425
1426         void setFeatures(CodeFeatures features) { m_features = features; }
1427         CodeFeatures features() { return m_features; }
1428
1429         bool usesEval() const { return m_features & EvalFeature; }
1430         bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
1431         bool modifiesParameter() const { return m_features & ModifiedParameterFeature; }
1432         bool modifiesArguments() const { return m_features & (EvalFeature | ModifiedArgumentsFeature); }
1433         bool isStrictMode() const { return m_features & StrictModeFeature; }
1434         void setUsesArguments() { m_features |= ArgumentsFeature; }
1435         bool usesThis() const { return m_features & ThisFeature; }
1436         bool needsActivationForMoreThanVariables() const { return m_features & (EvalFeature | WithFeature | CatchFeature); }
1437         bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature | CatchFeature)); }
1438         bool hasCapturedVariables() const { return !!m_capturedVariables.size(); }
1439         size_t capturedVariableCount() const { return m_capturedVariables.size(); }
1440         const IdentifierSet& capturedVariables() const { return m_capturedVariables; }
1441         bool captures(const Identifier& ident) { return m_capturedVariables.contains(ident.impl()); }
1442
1443         VarStack& varStack() { return m_varStack; }
1444         FunctionStack& functionStack() { return m_functionStack; }
1445
1446         int neededConstants()
1447         {
1448             // We may need 2 more constants than the count given by the parser,
1449             // because of the various uses of jsUndefined() and jsNull().
1450             return m_numConstants + 2;
1451         }
1452
1453         StatementNode* singleStatement() const;
1454
1455         void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1456         
1457         void setClosedVariables(Vector<RefPtr<StringImpl>>&&) { }
1458
1459     protected:
1460         int m_startLineNumber;
1461         unsigned m_startStartOffset;
1462         unsigned m_startLineStartOffset;
1463
1464     private:
1465         CodeFeatures m_features;
1466         SourceCode m_source;
1467         VarStack m_varStack;
1468         FunctionStack m_functionStack;
1469         int m_numConstants;
1470         SourceElements* m_statements;
1471         IdentifierSet m_capturedVariables;
1472     };
1473
1474     class ProgramNode : public ScopeNode {
1475     public:
1476         ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1477
1478         unsigned startColumn() const { return m_startColumn; }
1479         unsigned endColumn() const { return m_endColumn; }
1480
1481         static const bool scopeIsFunction = false;
1482
1483         void setClosedVariables(Vector<RefPtr<StringImpl>>&&);
1484         const Vector<RefPtr<StringImpl>>& closedVariables() const { return m_closedVariables; }
1485
1486     private:
1487         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1488         Vector<RefPtr<StringImpl>> m_closedVariables;
1489         unsigned m_startColumn;
1490         unsigned m_endColumn;
1491     };
1492
1493     class EvalNode : public ScopeNode {
1494     public:
1495         EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1496
1497         ALWAYS_INLINE unsigned startColumn() const { return 0; }
1498         unsigned endColumn() const { return m_endColumn; }
1499
1500         static const bool scopeIsFunction = false;
1501
1502     private:
1503         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1504
1505         unsigned m_endColumn;
1506     };
1507
1508     class FunctionParameters : public RefCounted<FunctionParameters> {
1509         WTF_MAKE_FAST_ALLOCATED;
1510         WTF_MAKE_NONCOPYABLE(FunctionParameters);
1511     public:
1512         static PassRefPtr<FunctionParameters> create(ParameterNode*);
1513         ~FunctionParameters();
1514
1515         unsigned size() const { return m_size; }
1516         DeconstructionPatternNode* at(unsigned index) { ASSERT(index < m_size); return patterns()[index]; }
1517
1518     private:
1519         FunctionParameters(ParameterNode*, unsigned size);
1520
1521         DeconstructionPatternNode** patterns() { return &m_storage; }
1522
1523         unsigned m_size;
1524         DeconstructionPatternNode* m_storage;
1525     };
1526
1527     class FunctionBodyNode final : public StatementNode, public ParserArenaDeletable {
1528     public:
1529         using ParserArenaDeletable::operator new;
1530
1531         FunctionBodyNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, bool isInStrictContext);
1532
1533         FunctionParameters* parameters() const { return m_parameters.get(); }
1534
1535         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1536
1537         void finishParsing(const SourceCode&, ParameterNode*, const Identifier&, FunctionMode);
1538         
1539         void overrideName(const Identifier& ident) { m_ident = ident; }
1540         const Identifier& ident() { return m_ident; }
1541         void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
1542         const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
1543
1544         FunctionMode functionMode() { return m_functionMode; }
1545
1546         void setFunctionNameStart(int functionNameStart) { m_functionNameStart = functionNameStart; }
1547         int functionNameStart() const { return m_functionNameStart; }
1548         void setFunctionKeywordStart(int functionKeywordStart) { m_functionKeywordStart = functionKeywordStart; }
1549         int functionKeywordStart() const { return m_functionKeywordStart; }
1550         unsigned startColumn() const { return m_startColumn; }
1551         unsigned endColumn() const { return m_endColumn; }
1552
1553         void setEndPosition(JSTextPosition);
1554
1555         const SourceCode& source() const { return m_source; }
1556
1557         int startStartOffset() const { return m_startStartOffset; }
1558         bool isInStrictContext() const { return m_isInStrictContext; }
1559
1560     protected:
1561         Identifier m_ident;
1562         Identifier m_inferredName;
1563         FunctionMode m_functionMode;
1564         RefPtr<FunctionParameters> m_parameters;
1565         int m_functionNameStart;
1566         int m_functionKeywordStart;
1567         unsigned m_startColumn;
1568         unsigned m_endColumn;
1569         SourceCode m_source;
1570         int m_startStartOffset;
1571         bool m_isInStrictContext;
1572     };
1573
1574     class FunctionNode final : public ScopeNode {
1575     public:
1576         FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VarStack&, FunctionStack&, IdentifierSet&, const SourceCode&, CodeFeatures, int numConstants);
1577
1578         FunctionParameters* parameters() const { return m_parameters.get(); }
1579
1580         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1581
1582         void finishParsing(PassRefPtr<FunctionParameters>, const Identifier&, FunctionMode);
1583         
1584         const Identifier& ident() { return m_ident; }
1585
1586         FunctionMode functionMode() { return m_functionMode; }
1587
1588         unsigned startColumn() const { return m_startColumn; }
1589         unsigned endColumn() const { return m_endColumn; }
1590
1591         static const bool scopeIsFunction = true;
1592
1593     private:
1594         Identifier m_ident;
1595         FunctionMode m_functionMode;
1596         RefPtr<FunctionParameters> m_parameters;
1597         unsigned m_startColumn;
1598         unsigned m_endColumn;
1599     };
1600
1601     class FuncExprNode : public ExpressionNode {
1602     public:
1603         FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1604
1605         FunctionBodyNode* body() { return m_body; }
1606
1607     private:
1608         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1609
1610         virtual bool isFuncExprNode() const override { return true; }
1611
1612         FunctionBodyNode* m_body;
1613     };
1614
1615 #if ENABLE(ES6_CLASS_SYNTAX)
1616     class ClassExprNode final : public ExpressionNode {
1617     public:
1618         ClassExprNode(const JSTokenLocation&, const Identifier&, ExpressionNode* constructorExpresssion,
1619             ExpressionNode* parentClass, PropertyListNode* instanceMethods, PropertyListNode* staticMethods);
1620
1621         const Identifier& name() { return m_name; }
1622
1623     private:
1624         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1625
1626         const Identifier& m_name;
1627         ExpressionNode* m_constructorExpression;
1628         ExpressionNode* m_parentClassExpression;
1629         PropertyListNode* m_instanceMethods;
1630         PropertyListNode* m_staticMethods;
1631     };
1632 #endif
1633
1634     class DeconstructionPatternNode : public RefCounted<DeconstructionPatternNode> {
1635         WTF_MAKE_NONCOPYABLE(DeconstructionPatternNode);
1636         WTF_MAKE_FAST_ALLOCATED;
1637
1638     public:
1639         virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
1640         virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
1641         virtual void toString(StringBuilder&) const = 0;
1642
1643         virtual bool isBindingNode() const { return false; }
1644         virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
1645         
1646         virtual ~DeconstructionPatternNode() = 0;
1647         
1648     protected:
1649         DeconstructionPatternNode();
1650     };
1651
1652     class ArrayPatternNode : public DeconstructionPatternNode {
1653     public:
1654         static PassRefPtr<ArrayPatternNode> create();
1655         void appendIndex(const JSTokenLocation&, DeconstructionPatternNode* node)
1656         {
1657             m_targetPatterns.append(node);
1658         }
1659
1660     private:
1661         ArrayPatternNode();
1662         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
1663         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
1664         virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
1665         virtual void toString(StringBuilder&) const override;
1666
1667         Vector<RefPtr<DeconstructionPatternNode>> m_targetPatterns;
1668     };
1669     
1670     class ObjectPatternNode : public DeconstructionPatternNode {
1671     public:
1672         static PassRefPtr<ObjectPatternNode> create();
1673         void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DeconstructionPatternNode* pattern)
1674         {
1675             m_targetPatterns.append(Entry(identifier, wasString, pattern));
1676         }
1677         
1678     private:
1679         ObjectPatternNode();
1680         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
1681         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
1682         virtual void toString(StringBuilder&) const override;
1683         struct Entry {
1684             Entry(const Identifier& propertyName, bool wasString, DeconstructionPatternNode* pattern)
1685                 : propertyName(propertyName)
1686                 , wasString(wasString)
1687                 , pattern(pattern)
1688             {
1689             }
1690             Identifier propertyName;
1691             bool wasString;
1692             RefPtr<DeconstructionPatternNode> pattern;
1693         };
1694         Vector<Entry> m_targetPatterns;
1695     };
1696
1697     class BindingNode : public DeconstructionPatternNode {
1698     public:
1699         static PassRefPtr<BindingNode> create(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
1700         const Identifier& boundProperty() const { return m_boundProperty; }
1701
1702         const JSTextPosition& divotStart() const { return m_divotStart; }
1703         const JSTextPosition& divotEnd() const { return m_divotEnd; }
1704         
1705     private:
1706         BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end);
1707
1708         virtual void collectBoundIdentifiers(Vector<Identifier>&) const override;
1709         virtual void bindValue(BytecodeGenerator&, RegisterID*) const override;
1710         virtual void toString(StringBuilder&) const override;
1711         
1712         virtual bool isBindingNode() const override { return true; }
1713
1714         JSTextPosition m_divotStart;
1715         JSTextPosition m_divotEnd;
1716         Identifier m_boundProperty;
1717     };
1718
1719     class DeconstructingAssignmentNode : public ExpressionNode, public ParserArenaDeletable {
1720     public:
1721         DeconstructingAssignmentNode(const JSTokenLocation&, PassRefPtr<DeconstructionPatternNode>, ExpressionNode*);
1722         DeconstructionPatternNode* bindings() { return m_bindings.get(); }
1723         
1724         using ParserArenaDeletable::operator new;
1725
1726     private:
1727         virtual bool isAssignmentLocation() const override { return true; }
1728         virtual bool isDeconstructionNode() const override { return true; }
1729         virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1730
1731         RefPtr<DeconstructionPatternNode> m_bindings;
1732         ExpressionNode* m_initializer;
1733     };
1734
1735     class FuncDeclNode : public StatementNode {
1736     public:
1737         FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionBodyNode*, const SourceCode&, ParameterNode* = 0);
1738
1739         FunctionBodyNode* body() { return m_body; }
1740
1741     private:
1742         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1743
1744         FunctionBodyNode* m_body;
1745     };
1746
1747 #if ENABLE(ES6_CLASS_SYNTAX)
1748     class ClassDeclNode final : public StatementNode {
1749     public:
1750         ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
1751
1752     private:
1753         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1754
1755         ExpressionNode* m_classDeclaration;
1756     };
1757 #endif
1758
1759     class CaseClauseNode : public ParserArenaFreeable {
1760     public:
1761         CaseClauseNode(ExpressionNode*, SourceElements* = 0);
1762
1763         ExpressionNode* expr() const { return m_expr; }
1764
1765         void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1766         void setStartOffset(int offset) { m_startOffset = offset; }
1767
1768     private:
1769         ExpressionNode* m_expr;
1770         SourceElements* m_statements;
1771         int m_startOffset;
1772     };
1773
1774     class ClauseListNode : public ParserArenaFreeable {
1775     public:
1776         ClauseListNode(CaseClauseNode*);
1777         ClauseListNode(ClauseListNode*, CaseClauseNode*);
1778
1779         CaseClauseNode* getClause() const { return m_clause; }
1780         ClauseListNode* getNext() const { return m_next; }
1781
1782     private:
1783         CaseClauseNode* m_clause;
1784         ClauseListNode* m_next;
1785     };
1786
1787     class CaseBlockNode : public ParserArenaFreeable {
1788     public:
1789         CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
1790
1791         void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
1792
1793     private:
1794         SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
1795         static const size_t s_tableSwitchMinimum = 3;
1796         ClauseListNode* m_list1;
1797         CaseClauseNode* m_defaultClause;
1798         ClauseListNode* m_list2;
1799     };
1800
1801     class SwitchNode : public StatementNode {
1802     public:
1803         SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*);
1804
1805     private:
1806         virtual void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1807
1808         ExpressionNode* m_expr;
1809         CaseBlockNode* m_block;
1810     };
1811
1812     struct ElementList {
1813         ElementNode* head;
1814         ElementNode* tail;
1815     };
1816
1817     struct PropertyList {
1818         PropertyListNode* head;
1819         PropertyListNode* tail;
1820     };
1821
1822     struct ArgumentList {
1823         ArgumentListNode* head;
1824         ArgumentListNode* tail;
1825     };
1826
1827     struct ConstDeclList {
1828         ConstDeclNode* head;
1829         ConstDeclNode* tail;
1830     };
1831
1832     struct ParameterList {
1833         ParameterNode* head;
1834         ParameterNode* tail;
1835     };
1836
1837     struct ClauseList {
1838         ClauseListNode* head;
1839         ClauseListNode* tail;
1840     };
1841
1842 } // namespace JSC
1843
1844 #endif // Nodes_h