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