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