1/*
2 * Copyright (C) 1999-2000 Harri Porten (porten@kde.org)
3 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
4 * Copyright (C) 2003-2018 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#pragma once
27
28#include "BytecodeIntrinsicRegistry.h"
29#include "JITCode.h"
30#include "ParserArena.h"
31#include "ParserModes.h"
32#include "ParserTokens.h"
33#include "ResultType.h"
34#include "SourceCode.h"
35#include "SymbolTable.h"
36#include "VariableEnvironment.h"
37#include <wtf/MathExtras.h>
38#include <wtf/SmallPtrSet.h>
39
40namespace JSC {
41
42 enum OpcodeID : unsigned;
43
44 class ArgumentListNode;
45 class BytecodeGenerator;
46 class FunctionMetadataNode;
47 class FunctionParameters;
48 class Label;
49 class ModuleAnalyzer;
50 class ModuleScopeData;
51 class PropertyListNode;
52 class ReadModifyResolveNode;
53 class RegisterID;
54 class ScopeNode;
55
56 typedef SmallPtrSet<UniquedStringImpl*> UniquedStringImplPtrSet;
57
58 enum Operator : uint8_t {
59 OpEqual,
60 OpPlusEq,
61 OpMinusEq,
62 OpMultEq,
63 OpDivEq,
64 OpPlusPlus,
65 OpMinusMinus,
66 OpAndEq,
67 OpXOrEq,
68 OpOrEq,
69 OpModEq,
70 OpPowEq,
71 OpLShift,
72 OpRShift,
73 OpURShift
74 };
75
76 enum LogicalOperator : uint8_t {
77 OpLogicalAnd,
78 OpLogicalOr
79 };
80
81 enum FallThroughMode : uint8_t {
82 FallThroughMeansTrue = 0,
83 FallThroughMeansFalse = 1
84 };
85 inline FallThroughMode invert(FallThroughMode fallThroughMode) { return static_cast<FallThroughMode>(!fallThroughMode); }
86
87 namespace DeclarationStacks {
88 typedef Vector<FunctionMetadataNode*> FunctionStack;
89 }
90
91 struct SwitchInfo {
92 enum SwitchType : uint8_t { SwitchNone, SwitchImmediate, SwitchCharacter, SwitchString };
93 uint32_t bytecodeOffset;
94 SwitchType switchType;
95 };
96
97 enum class AssignmentContext : uint8_t {
98 DeclarationStatement,
99 ConstDeclarationStatement,
100 AssignmentExpression
101 };
102
103 class ParserArenaFreeable {
104 public:
105 // ParserArenaFreeable objects are freed when the arena is deleted.
106 // Destructors are not called. Clients must not call delete on such objects.
107 void* operator new(size_t, ParserArena&);
108 };
109
110 class ParserArenaDeletable {
111 public:
112 virtual ~ParserArenaDeletable() { }
113
114 // ParserArenaDeletable objects are deleted when the arena is deleted.
115 // Clients must not call delete directly on such objects.
116 template<typename T> void* operator new(size_t, ParserArena&);
117 };
118
119#define JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED_IMPL(__classToNew) \
120 void* operator new(size_t size, ParserArena& parserArena) \
121 { \
122 return ParserArenaDeletable::operator new<__classToNew>(size, parserArena); \
123 }
124
125#define JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(__classToNew) \
126 public: \
127 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED_IMPL(__classToNew) \
128 private: \
129 typedef int __thisIsHereToForceASemicolonAfterThisMacro
130
131 class ParserArenaRoot {
132 WTF_MAKE_FAST_ALLOCATED;
133 protected:
134 ParserArenaRoot(ParserArena&);
135
136 public:
137 ParserArena& parserArena() { return m_arena; }
138 virtual ~ParserArenaRoot() { }
139
140 protected:
141 ParserArena m_arena;
142 };
143
144 class Node : public ParserArenaFreeable {
145 protected:
146 Node(const JSTokenLocation&);
147
148 public:
149 virtual ~Node() { }
150
151 int firstLine() const { return m_position.line; }
152 int startOffset() const { return m_position.offset; }
153 int endOffset() const { return m_endOffset; }
154 int lineStartOffset() const { return m_position.lineStartOffset; }
155 const JSTextPosition& position() const { return m_position; }
156 void setEndOffset(int offset) { m_endOffset = offset; }
157 void setStartOffset(int offset) { m_position.offset = offset; }
158
159 bool needsDebugHook() const { return m_needsDebugHook; }
160 void setNeedsDebugHook() { m_needsDebugHook = true; }
161
162 protected:
163 JSTextPosition m_position;
164 int m_endOffset { -1 };
165 bool m_needsDebugHook { false };
166 };
167
168 class ExpressionNode : public Node {
169 protected:
170 ExpressionNode(const JSTokenLocation&, ResultType = ResultType::unknownType());
171
172 public:
173 virtual RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
174
175 virtual bool isNumber() const { return false; }
176 virtual bool isString() const { return false; }
177 virtual bool isBigInt() const { return false; }
178 virtual bool isObjectLiteral() const { return false; }
179 virtual bool isArrayLiteral() const { return false; }
180 virtual bool isNull() const { return false; }
181 virtual bool isPure(BytecodeGenerator&) const { return false; }
182 virtual bool isConstant() const { return false; }
183 virtual bool isLocation() const { return false; }
184 virtual bool isAssignmentLocation() const { return isLocation(); }
185 virtual bool isResolveNode() const { return false; }
186 virtual bool isAssignResolveNode() const { return false; }
187 virtual bool isBracketAccessorNode() const { return false; }
188 virtual bool isDotAccessorNode() const { return false; }
189 virtual bool isDestructuringNode() const { return false; }
190 virtual bool isBaseFuncExprNode() const { return false; }
191 virtual bool isFuncExprNode() const { return false; }
192 virtual bool isArrowFuncExprNode() const { return false; }
193 virtual bool isClassExprNode() const { return false; }
194 virtual bool isCommaNode() const { return false; }
195 virtual bool isSimpleArray() const { return false; }
196 virtual bool isAdd() const { return false; }
197 virtual bool isSubtract() const { return false; }
198 virtual bool isBoolean() const { return false; }
199 virtual bool isSpreadExpression() const { return false; }
200 virtual bool isSuperNode() const { return false; }
201 virtual bool isImportNode() const { return false; }
202 virtual bool isMetaProperty() const { return false; }
203 virtual bool isNewTarget() const { return false; }
204 virtual bool isImportMeta() const { return false; }
205 virtual bool isBytecodeIntrinsicNode() const { return false; }
206 virtual bool isBinaryOpNode() const { return false; }
207
208 virtual void emitBytecodeInConditionContext(BytecodeGenerator&, Label&, Label&, FallThroughMode);
209
210 virtual ExpressionNode* stripUnaryPlus() { return this; }
211
212 ResultType resultDescriptor() const { return m_resultType; }
213
214 private:
215 ResultType m_resultType;
216 };
217
218 class StatementNode : public Node {
219 protected:
220 StatementNode(const JSTokenLocation&);
221
222 public:
223 virtual void emitBytecode(BytecodeGenerator&, RegisterID* destination = 0) = 0;
224
225 void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset);
226 unsigned lastLine() const { return m_lastLine; }
227
228 StatementNode* next() const { return m_next; }
229 void setNext(StatementNode* next) { m_next = next; }
230
231 virtual bool hasCompletionValue() const { return true; }
232 virtual bool hasEarlyBreakOrContinue() const { return false; }
233
234 virtual bool isEmptyStatement() const { return false; }
235 virtual bool isDebuggerStatement() const { return false; }
236 virtual bool isFunctionNode() const { return false; }
237 virtual bool isReturnNode() const { return false; }
238 virtual bool isExprStatement() const { return false; }
239 virtual bool isBreak() const { return false; }
240 virtual bool isContinue() const { return false; }
241 virtual bool isLabel() const { return false; }
242 virtual bool isBlock() const { return false; }
243 virtual bool isFuncDeclNode() const { return false; }
244 virtual bool isModuleDeclarationNode() const { return false; }
245 virtual bool isForOfNode() const { return false; }
246
247 protected:
248 int m_lastLine { -1 };
249 StatementNode* m_next { nullptr };
250 };
251
252 class VariableEnvironmentNode : public ParserArenaDeletable {
253 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(VariableEnvironmentNode);
254 public:
255 typedef DeclarationStacks::FunctionStack FunctionStack;
256
257 VariableEnvironmentNode()
258 {
259 }
260
261 VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables);
262 VariableEnvironmentNode(VariableEnvironment& lexicalDeclaredVariables, FunctionStack&&);
263
264 VariableEnvironment& lexicalVariables() { return m_lexicalVariables; }
265 FunctionStack& functionStack() { return m_functionStack; }
266
267 protected:
268 VariableEnvironment m_lexicalVariables;
269 FunctionStack m_functionStack;
270 };
271
272 class ConstantNode : public ExpressionNode {
273 public:
274 ConstantNode(const JSTokenLocation&, ResultType);
275 bool isPure(BytecodeGenerator&) const override { return true; }
276 bool isConstant() const override { return true; }
277 virtual JSValue jsValue(BytecodeGenerator&) const = 0;
278 private:
279 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
280 void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
281 };
282
283 class NullNode final : public ConstantNode {
284 public:
285 NullNode(const JSTokenLocation&);
286
287 private:
288 bool isNull() const override { return true; }
289 JSValue jsValue(BytecodeGenerator&) const override { return jsNull(); }
290 };
291
292 class BooleanNode final : public ConstantNode {
293 public:
294 BooleanNode(const JSTokenLocation&, bool value);
295 bool value() { return m_value; }
296
297 private:
298 bool isBoolean() const override { return true; }
299 JSValue jsValue(BytecodeGenerator&) const override { return jsBoolean(m_value); }
300
301 bool m_value;
302 };
303
304 class NumberNode : public ConstantNode {
305 public:
306 NumberNode(const JSTokenLocation&, double value);
307 double value() const { return m_value; }
308 virtual bool isIntegerNode() const = 0;
309 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) final;
310
311 private:
312 bool isNumber() const final { return true; }
313 JSValue jsValue(BytecodeGenerator&) const override { return jsNumber(m_value); }
314
315 double m_value;
316 };
317
318 class DoubleNode : public NumberNode {
319 public:
320 DoubleNode(const JSTokenLocation&, double value);
321
322 private:
323 bool isIntegerNode() const override { return false; }
324 };
325
326 // An integer node represent a number represented as an integer (e.g. 42 instead of 42., 42.0, 42e0)
327 class IntegerNode final : public DoubleNode {
328 public:
329 IntegerNode(const JSTokenLocation&, double value);
330 bool isIntegerNode() const final { return true; }
331 };
332
333 class StringNode final : public ConstantNode {
334 public:
335 StringNode(const JSTokenLocation&, const Identifier&);
336 const Identifier& value() { return m_value; }
337
338 private:
339 bool isString() const override { return true; }
340 JSValue jsValue(BytecodeGenerator&) const override;
341
342 const Identifier& m_value;
343 };
344
345 class BigIntNode final : public ConstantNode {
346 public:
347 BigIntNode(const JSTokenLocation&, const Identifier&, uint8_t radix);
348 BigIntNode(const JSTokenLocation&, const Identifier&, uint8_t radix, bool sign);
349 const Identifier& value() { return m_value; }
350
351 const Identifier& identifier() const { return m_value; }
352 uint8_t radix() const { return m_radix; }
353 bool sign() const { return m_sign; }
354
355 private:
356 bool isBigInt() const final { return true; }
357 JSValue jsValue(BytecodeGenerator&) const final;
358
359 const Identifier& m_value;
360 const uint8_t m_radix;
361 const bool m_sign;
362 };
363
364 class ThrowableExpressionData {
365 public:
366 ThrowableExpressionData()
367 : m_divot(-1, -1, -1)
368 , m_divotStart(-1, -1, -1)
369 , m_divotEnd(-1, -1, -1)
370 {
371 }
372
373 ThrowableExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
374 : m_divot(divot)
375 , m_divotStart(start)
376 , m_divotEnd(end)
377 {
378 ASSERT(m_divot.offset >= m_divot.lineStartOffset);
379 ASSERT(m_divotStart.offset >= m_divotStart.lineStartOffset);
380 ASSERT(m_divotEnd.offset >= m_divotEnd.lineStartOffset);
381 }
382
383 void setExceptionSourceCode(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
384 {
385 ASSERT(divot.offset >= divot.lineStartOffset);
386 ASSERT(divotStart.offset >= divotStart.lineStartOffset);
387 ASSERT(divotEnd.offset >= divotEnd.lineStartOffset);
388 m_divot = divot;
389 m_divotStart = divotStart;
390 m_divotEnd = divotEnd;
391 }
392
393 const JSTextPosition& divot() const { return m_divot; }
394 const JSTextPosition& divotStart() const { return m_divotStart; }
395 const JSTextPosition& divotEnd() const { return m_divotEnd; }
396
397 protected:
398 RegisterID* emitThrowReferenceError(BytecodeGenerator&, const String& message);
399
400 private:
401 JSTextPosition m_divot;
402 JSTextPosition m_divotStart;
403 JSTextPosition m_divotEnd;
404 };
405
406 class ThrowableSubExpressionData : public ThrowableExpressionData {
407 public:
408 ThrowableSubExpressionData()
409 : m_subexpressionDivotOffset(0)
410 , m_subexpressionEndOffset(0)
411 , m_subexpressionLineOffset(0)
412 , m_subexpressionLineStartOffset(0)
413 {
414 }
415
416 ThrowableSubExpressionData(const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd)
417 : ThrowableExpressionData(divot, divotStart, divotEnd)
418 , m_subexpressionDivotOffset(0)
419 , m_subexpressionEndOffset(0)
420 , m_subexpressionLineOffset(0)
421 , m_subexpressionLineStartOffset(0)
422 {
423 }
424
425 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
426 {
427 ASSERT(subexpressionDivot.offset <= divot().offset);
428 // Overflow means we can't do this safely, so just point at the primary divot,
429 // divotLine, or divotLineStart.
430 if ((divot() - subexpressionDivot.offset) & ~0xFFFF)
431 return;
432 if ((divot().line - subexpressionDivot.line) & ~0xFFFF)
433 return;
434 if ((divot().lineStartOffset - subexpressionDivot.lineStartOffset) & ~0xFFFF)
435 return;
436 if ((divotEnd() - subexpressionOffset) & ~0xFFFF)
437 return;
438 m_subexpressionDivotOffset = divot() - subexpressionDivot.offset;
439 m_subexpressionEndOffset = divotEnd() - subexpressionOffset;
440 m_subexpressionLineOffset = divot().line - subexpressionDivot.line;
441 m_subexpressionLineStartOffset = divot().lineStartOffset - subexpressionDivot.lineStartOffset;
442 }
443
444 JSTextPosition subexpressionDivot()
445 {
446 int newLine = divot().line - m_subexpressionLineOffset;
447 int newOffset = divot().offset - m_subexpressionDivotOffset;
448 int newLineStartOffset = divot().lineStartOffset - m_subexpressionLineStartOffset;
449 return JSTextPosition(newLine, newOffset, newLineStartOffset);
450 }
451 JSTextPosition subexpressionStart() { return divotStart(); }
452 JSTextPosition subexpressionEnd() { return divotEnd() - static_cast<int>(m_subexpressionEndOffset); }
453
454 protected:
455 uint16_t m_subexpressionDivotOffset;
456 uint16_t m_subexpressionEndOffset;
457 uint16_t m_subexpressionLineOffset;
458 uint16_t m_subexpressionLineStartOffset;
459 };
460
461 class ThrowablePrefixedSubExpressionData : public ThrowableExpressionData {
462 public:
463 ThrowablePrefixedSubExpressionData()
464 : m_subexpressionDivotOffset(0)
465 , m_subexpressionStartOffset(0)
466 , m_subexpressionLineOffset(0)
467 , m_subexpressionLineStartOffset(0)
468 {
469 }
470
471 ThrowablePrefixedSubExpressionData(const JSTextPosition& divot, const JSTextPosition& start, const JSTextPosition& end)
472 : ThrowableExpressionData(divot, start, end)
473 , m_subexpressionDivotOffset(0)
474 , m_subexpressionStartOffset(0)
475 , m_subexpressionLineOffset(0)
476 , m_subexpressionLineStartOffset(0)
477 {
478 }
479
480 void setSubexpressionInfo(const JSTextPosition& subexpressionDivot, int subexpressionOffset)
481 {
482 ASSERT(subexpressionDivot.offset >= divot().offset);
483 // Overflow means we can't do this safely, so just point at the primary divot,
484 // divotLine, or divotLineStart.
485 if ((subexpressionDivot.offset - divot()) & ~0xFFFF)
486 return;
487 if ((subexpressionDivot.line - divot().line) & ~0xFFFF)
488 return;
489 if ((subexpressionDivot.lineStartOffset - divot().lineStartOffset) & ~0xFFFF)
490 return;
491 if ((subexpressionOffset - divotStart()) & ~0xFFFF)
492 return;
493 m_subexpressionDivotOffset = subexpressionDivot.offset - divot();
494 m_subexpressionStartOffset = subexpressionOffset - divotStart();
495 m_subexpressionLineOffset = subexpressionDivot.line - divot().line;
496 m_subexpressionLineStartOffset = subexpressionDivot.lineStartOffset - divot().lineStartOffset;
497 }
498
499 JSTextPosition subexpressionDivot()
500 {
501 int newLine = divot().line + m_subexpressionLineOffset;
502 int newOffset = divot().offset + m_subexpressionDivotOffset;
503 int newLineStartOffset = divot().lineStartOffset + m_subexpressionLineStartOffset;
504 return JSTextPosition(newLine, newOffset, newLineStartOffset);
505 }
506 JSTextPosition subexpressionStart() { return divotStart() + static_cast<int>(m_subexpressionStartOffset); }
507 JSTextPosition subexpressionEnd() { return divotEnd(); }
508
509 protected:
510 uint16_t m_subexpressionDivotOffset;
511 uint16_t m_subexpressionStartOffset;
512 uint16_t m_subexpressionLineOffset;
513 uint16_t m_subexpressionLineStartOffset;
514 };
515
516 class TemplateExpressionListNode final : public ParserArenaFreeable {
517 public:
518 TemplateExpressionListNode(ExpressionNode*);
519 TemplateExpressionListNode(TemplateExpressionListNode*, ExpressionNode*);
520
521 ExpressionNode* value() { return m_node; }
522 TemplateExpressionListNode* next() { return m_next; }
523
524 private:
525 TemplateExpressionListNode* m_next { nullptr };
526 ExpressionNode* m_node { nullptr };
527 };
528
529 class TemplateStringNode final : public ExpressionNode {
530 public:
531 TemplateStringNode(const JSTokenLocation&, const Identifier* cooked, const Identifier* raw);
532
533 const Identifier* cooked() { return m_cooked; }
534 const Identifier* raw() { return m_raw; }
535
536 private:
537 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
538
539 const Identifier* m_cooked;
540 const Identifier* m_raw;
541 };
542
543 class TemplateStringListNode final : public ParserArenaFreeable {
544 public:
545 TemplateStringListNode(TemplateStringNode*);
546 TemplateStringListNode(TemplateStringListNode*, TemplateStringNode*);
547
548 TemplateStringNode* value() { return m_node; }
549 TemplateStringListNode* next() { return m_next; }
550
551 private:
552 TemplateStringListNode* m_next { nullptr };
553 TemplateStringNode* m_node { nullptr };
554 };
555
556 class TemplateLiteralNode final : public ExpressionNode {
557 public:
558 TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*);
559 TemplateLiteralNode(const JSTokenLocation&, TemplateStringListNode*, TemplateExpressionListNode*);
560
561 TemplateStringListNode* templateStrings() const { return m_templateStrings; }
562 TemplateExpressionListNode* templateExpressions() const { return m_templateExpressions; }
563
564 private:
565 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
566
567 TemplateStringListNode* m_templateStrings;
568 TemplateExpressionListNode* m_templateExpressions;
569 };
570
571 class TaggedTemplateNode final : public ExpressionNode, public ThrowableExpressionData {
572 public:
573 TaggedTemplateNode(const JSTokenLocation&, ExpressionNode*, TemplateLiteralNode*);
574
575 TemplateLiteralNode* templateLiteral() const { return m_templateLiteral; }
576
577 private:
578 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
579
580 ExpressionNode* m_tag;
581 TemplateLiteralNode* m_templateLiteral;
582 };
583
584 class RegExpNode final : public ExpressionNode, public ThrowableExpressionData {
585 public:
586 RegExpNode(const JSTokenLocation&, const Identifier& pattern, const Identifier& flags);
587
588 private:
589 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
590
591 const Identifier& m_pattern;
592 const Identifier& m_flags;
593 };
594
595 class ThisNode final : public ExpressionNode {
596 public:
597 ThisNode(const JSTokenLocation&);
598
599 private:
600 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
601 };
602
603 class SuperNode final : public ExpressionNode {
604 public:
605 SuperNode(const JSTokenLocation&);
606
607 private:
608 bool isSuperNode() const override { return true; }
609 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
610 };
611
612 class ImportNode final : public ExpressionNode, public ThrowableExpressionData {
613 public:
614 ImportNode(const JSTokenLocation&, ExpressionNode*);
615
616 private:
617 bool isImportNode() const override { return true; }
618 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
619
620 ExpressionNode* m_expr;
621 };
622
623 class MetaPropertyNode : public ExpressionNode {
624 public:
625 MetaPropertyNode(const JSTokenLocation&);
626
627 private:
628 bool isMetaProperty() const final { return true; }
629 };
630
631 class NewTargetNode final : public MetaPropertyNode {
632 public:
633 NewTargetNode(const JSTokenLocation&);
634
635 private:
636 bool isNewTarget() const final { return true; }
637 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
638 };
639
640 class ImportMetaNode final : public MetaPropertyNode {
641 public:
642 ImportMetaNode(const JSTokenLocation&, ExpressionNode*);
643
644 private:
645 bool isImportMeta() const final { return true; }
646 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
647
648 ExpressionNode* m_expr;
649 };
650
651 class ResolveNode final : public ExpressionNode {
652 public:
653 ResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& start);
654
655 const Identifier& identifier() const { return m_ident; }
656
657 private:
658 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
659
660 bool isPure(BytecodeGenerator&) const override;
661 bool isLocation() const override { return true; }
662 bool isResolveNode() const override { return true; }
663
664 const Identifier& m_ident;
665 JSTextPosition m_start;
666 };
667
668 class ElementNode final : public ParserArenaFreeable {
669 public:
670 ElementNode(int elision, ExpressionNode*);
671 ElementNode(ElementNode*, int elision, ExpressionNode*);
672
673 int elision() const { return m_elision; }
674 ExpressionNode* value() { return m_node; }
675 ElementNode* next() { return m_next; }
676
677 private:
678 ElementNode* m_next { nullptr };
679 ExpressionNode* m_node;
680 int m_elision;
681 };
682
683 class ArrayNode final : public ExpressionNode {
684 public:
685 ArrayNode(const JSTokenLocation&, int elision);
686 ArrayNode(const JSTokenLocation&, ElementNode*);
687 ArrayNode(const JSTokenLocation&, int elision, ElementNode*);
688
689 bool isArrayLiteral() const override { return true; }
690
691 ArgumentListNode* toArgumentList(ParserArena&, int, int) const;
692
693 ElementNode* elements() const { return m_element; }
694 private:
695 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
696
697 bool isSimpleArray() const override;
698
699 ElementNode* m_element;
700 int m_elision;
701 bool m_optional;
702 };
703
704 enum class ClassElementTag : uint8_t { No, Instance, Static, LastTag };
705 class PropertyNode final : public ParserArenaFreeable {
706 public:
707 enum Type : uint8_t { Constant = 1, Getter = 2, Setter = 4, Computed = 8, Shorthand = 16, Spread = 32 };
708 enum PutType : uint8_t { Unknown, KnownDirect };
709
710 PropertyNode(const Identifier&, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
711 PropertyNode(ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
712 PropertyNode(ExpressionNode* propertyName, ExpressionNode*, Type, PutType, SuperBinding, ClassElementTag);
713
714 ExpressionNode* expressionName() const { return m_expression; }
715 const Identifier* name() const { return m_name; }
716
717 Type type() const { return static_cast<Type>(m_type); }
718 bool needsSuperBinding() const { return m_needsSuperBinding; }
719 bool isClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) != ClassElementTag::No; }
720 bool isStaticClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Static; }
721 bool isInstanceClassProperty() const { return static_cast<ClassElementTag>(m_classElementTag) == ClassElementTag::Instance; }
722 bool isOverriddenByDuplicate() const { return m_isOverriddenByDuplicate; }
723 void setIsOverriddenByDuplicate() { m_isOverriddenByDuplicate = true; }
724 PutType putType() const { return static_cast<PutType>(m_putType); }
725
726 private:
727 friend class PropertyListNode;
728 const Identifier* m_name;
729 ExpressionNode* m_expression;
730 ExpressionNode* m_assign;
731 unsigned m_type : 6;
732 unsigned m_needsSuperBinding : 1;
733 unsigned m_putType : 1;
734 static_assert(1 << 2 > static_cast<unsigned>(ClassElementTag::LastTag), "ClassElementTag shouldn't use more than two bits");
735 unsigned m_classElementTag : 2;
736 unsigned m_isOverriddenByDuplicate: 1;
737 };
738
739 class PropertyListNode final : public ExpressionNode {
740 public:
741 PropertyListNode(const JSTokenLocation&, PropertyNode*);
742 PropertyListNode(const JSTokenLocation&, PropertyNode*, PropertyListNode*);
743
744 bool hasStaticallyNamedProperty(const Identifier& propName);
745
746 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID*, RegisterID*);
747
748 private:
749 RegisterID* emitBytecode(BytecodeGenerator& generator, RegisterID* dst = nullptr) override
750 {
751 return emitBytecode(generator, dst, nullptr);
752 }
753 void emitPutConstantProperty(BytecodeGenerator&, RegisterID*, PropertyNode&);
754
755 PropertyNode* m_node;
756 PropertyListNode* m_next { nullptr };
757 };
758
759 class ObjectLiteralNode final : public ExpressionNode {
760 public:
761 ObjectLiteralNode(const JSTokenLocation&);
762 ObjectLiteralNode(const JSTokenLocation&, PropertyListNode*);
763 bool isObjectLiteral() const override { return true; }
764
765 private:
766 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
767
768 PropertyListNode* m_list;
769 };
770
771 class BracketAccessorNode final : public ExpressionNode, public ThrowableExpressionData {
772 public:
773 BracketAccessorNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments);
774
775 ExpressionNode* base() const { return m_base; }
776 ExpressionNode* subscript() const { return m_subscript; }
777
778 bool subscriptHasAssignments() const { return m_subscriptHasAssignments; }
779
780 private:
781 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
782
783 bool isLocation() const override { return true; }
784 bool isBracketAccessorNode() const override { return true; }
785
786 ExpressionNode* m_base;
787 ExpressionNode* m_subscript;
788 bool m_subscriptHasAssignments;
789 };
790
791 class DotAccessorNode final : public ExpressionNode, public ThrowableExpressionData {
792 public:
793 DotAccessorNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&);
794
795 ExpressionNode* base() const { return m_base; }
796 const Identifier& identifier() const { return m_ident; }
797
798 private:
799 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
800
801 bool isLocation() const override { return true; }
802 bool isDotAccessorNode() const override { return true; }
803
804 ExpressionNode* m_base;
805 const Identifier& m_ident;
806 };
807
808 class SpreadExpressionNode final : public ExpressionNode, public ThrowableExpressionData {
809 public:
810 SpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
811
812 ExpressionNode* expression() const { return m_expression; }
813
814 private:
815 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
816
817 bool isSpreadExpression() const override { return true; }
818 ExpressionNode* m_expression;
819 };
820
821 class ObjectSpreadExpressionNode final : public ExpressionNode, public ThrowableExpressionData {
822 public:
823 ObjectSpreadExpressionNode(const JSTokenLocation&, ExpressionNode*);
824
825 ExpressionNode* expression() const { return m_expression; }
826
827 private:
828 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
829
830 ExpressionNode* m_expression;
831 };
832
833 class ArgumentListNode final : public ExpressionNode {
834 public:
835 ArgumentListNode(const JSTokenLocation&, ExpressionNode*);
836 ArgumentListNode(const JSTokenLocation&, ArgumentListNode*, ExpressionNode*);
837
838 ArgumentListNode* m_next { nullptr };
839 ExpressionNode* m_expr;
840
841 private:
842 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
843 };
844
845 class ArgumentsNode final : public ParserArenaFreeable {
846 public:
847 ArgumentsNode();
848 ArgumentsNode(ArgumentListNode*);
849
850 ArgumentListNode* m_listNode;
851 };
852
853 class NewExprNode final : public ExpressionNode, public ThrowableExpressionData {
854 public:
855 NewExprNode(const JSTokenLocation&, ExpressionNode*);
856 NewExprNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*);
857
858 private:
859 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
860
861 ExpressionNode* m_expr;
862 ArgumentsNode* m_args;
863 };
864
865 class EvalFunctionCallNode final : public ExpressionNode, public ThrowableExpressionData {
866 public:
867 EvalFunctionCallNode(const JSTokenLocation&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
868
869 private:
870 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
871
872 ArgumentsNode* m_args;
873 };
874
875 class FunctionCallValueNode final : public ExpressionNode, public ThrowableExpressionData {
876 public:
877 FunctionCallValueNode(const JSTokenLocation&, ExpressionNode*, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
878
879 private:
880 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
881
882 ExpressionNode* m_expr;
883 ArgumentsNode* m_args;
884 };
885
886 class FunctionCallResolveNode final : public ExpressionNode, public ThrowableExpressionData {
887 public:
888 FunctionCallResolveNode(const JSTokenLocation&, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
889
890 private:
891 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
892
893 const Identifier& m_ident;
894 ArgumentsNode* m_args;
895 };
896
897 class FunctionCallBracketNode final : public ExpressionNode, public ThrowableSubExpressionData {
898 public:
899 FunctionCallBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, bool subscriptHasAssignments, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
900
901 private:
902 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
903
904 ExpressionNode* m_base;
905 ExpressionNode* m_subscript;
906 ArgumentsNode* m_args;
907 bool m_subscriptHasAssignments;
908 };
909
910 class FunctionCallDotNode : public ExpressionNode, public ThrowableSubExpressionData {
911 public:
912 FunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
913
914 private:
915 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
916
917 protected:
918 ExpressionNode* m_base;
919 const Identifier& m_ident;
920 ArgumentsNode* m_args;
921 };
922
923 class BytecodeIntrinsicNode final : public ExpressionNode, public ThrowableExpressionData {
924 public:
925 enum class Type : uint8_t {
926 Constant,
927 Function
928 };
929
930 typedef RegisterID* (BytecodeIntrinsicNode::* EmitterType)(BytecodeGenerator&, RegisterID*);
931
932 BytecodeIntrinsicNode(Type, const JSTokenLocation&, EmitterType, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
933
934 bool isBytecodeIntrinsicNode() const override { return true; }
935
936 Type type() const { return m_type; }
937 EmitterType emitter() const { return m_emitter; }
938 const Identifier& identifier() const { return m_ident; }
939
940#define JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS(name) RegisterID* emit_intrinsic_##name(BytecodeGenerator&, RegisterID*);
941 JSC_COMMON_BYTECODE_INTRINSIC_FUNCTIONS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
942 JSC_COMMON_BYTECODE_INTRINSIC_CONSTANTS_EACH_NAME(JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS)
943#undef JSC_DECLARE_BYTECODE_INTRINSIC_FUNCTIONS
944
945 private:
946 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
947
948 EmitterType m_emitter;
949 const Identifier& m_ident;
950 ArgumentsNode* m_args;
951 Type m_type;
952 };
953
954 class CallFunctionCallDotNode final : public FunctionCallDotNode {
955 public:
956 CallFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, size_t distanceToInnermostCallOrApply);
957
958 private:
959 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
960 size_t m_distanceToInnermostCallOrApply;
961 };
962
963 class ApplyFunctionCallDotNode final : public FunctionCallDotNode {
964 public:
965 ApplyFunctionCallDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ArgumentsNode*, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd, size_t distanceToInnermostCallOrApply);
966
967 private:
968 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
969 size_t m_distanceToInnermostCallOrApply;
970 };
971
972 class DeleteResolveNode final : public ExpressionNode, public ThrowableExpressionData {
973 public:
974 DeleteResolveNode(const JSTokenLocation&, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
975
976 private:
977 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
978
979 const Identifier& m_ident;
980 };
981
982 class DeleteBracketNode final : public ExpressionNode, public ThrowableExpressionData {
983 public:
984 DeleteBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
985
986 private:
987 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
988
989 ExpressionNode* m_base;
990 ExpressionNode* m_subscript;
991 };
992
993 class DeleteDotNode final : public ExpressionNode, public ThrowableExpressionData {
994 public:
995 DeleteDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
996
997 private:
998 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
999
1000 ExpressionNode* m_base;
1001 const Identifier& m_ident;
1002 };
1003
1004 class DeleteValueNode final : public ExpressionNode {
1005 public:
1006 DeleteValueNode(const JSTokenLocation&, ExpressionNode*);
1007
1008 private:
1009 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1010
1011 ExpressionNode* m_expr;
1012 };
1013
1014 class VoidNode final : public ExpressionNode {
1015 public:
1016 VoidNode(const JSTokenLocation&, ExpressionNode*);
1017
1018 private:
1019 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1020
1021 ExpressionNode* m_expr;
1022 };
1023
1024 class TypeOfResolveNode final : public ExpressionNode {
1025 public:
1026 TypeOfResolveNode(const JSTokenLocation&, const Identifier&);
1027
1028 const Identifier& identifier() const { return m_ident; }
1029
1030 private:
1031 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1032
1033 const Identifier& m_ident;
1034 };
1035
1036 class TypeOfValueNode final : public ExpressionNode {
1037 public:
1038 TypeOfValueNode(const JSTokenLocation&, ExpressionNode*);
1039
1040 private:
1041 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1042
1043 ExpressionNode* m_expr;
1044 };
1045
1046 class PrefixNode : public ExpressionNode, public ThrowablePrefixedSubExpressionData {
1047 public:
1048 PrefixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1049
1050 protected:
1051 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1052 virtual RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0);
1053 virtual RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0);
1054 virtual RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0);
1055
1056 ExpressionNode* m_expr;
1057 Operator m_operator;
1058 };
1059
1060 class PostfixNode final : public PrefixNode {
1061 public:
1062 PostfixNode(const JSTokenLocation&, ExpressionNode*, Operator, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1063
1064 private:
1065 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1066 RegisterID* emitResolve(BytecodeGenerator&, RegisterID* = 0) override;
1067 RegisterID* emitBracket(BytecodeGenerator&, RegisterID* = 0) override;
1068 RegisterID* emitDot(BytecodeGenerator&, RegisterID* = 0) override;
1069 };
1070
1071 class UnaryOpNode : public ExpressionNode {
1072 public:
1073 UnaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode*, OpcodeID);
1074
1075 protected:
1076 ExpressionNode* expr() { return m_expr; }
1077 const ExpressionNode* expr() const { return m_expr; }
1078 OpcodeID opcodeID() const { return m_opcodeID; }
1079
1080 private:
1081 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1082
1083 ExpressionNode* m_expr;
1084 OpcodeID m_opcodeID;
1085 };
1086
1087 class UnaryPlusNode final : public UnaryOpNode {
1088 public:
1089 UnaryPlusNode(const JSTokenLocation&, ExpressionNode*);
1090
1091 private:
1092 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1093
1094 ExpressionNode* stripUnaryPlus() override { return expr(); }
1095 };
1096
1097 class NegateNode final : public UnaryOpNode {
1098 public:
1099 NegateNode(const JSTokenLocation&, ExpressionNode*);
1100 };
1101
1102 class BitwiseNotNode final : public UnaryOpNode {
1103 public:
1104 BitwiseNotNode(const JSTokenLocation&, ExpressionNode*);
1105 };
1106
1107 class LogicalNotNode final : public UnaryOpNode {
1108 public:
1109 LogicalNotNode(const JSTokenLocation&, ExpressionNode*);
1110 private:
1111 void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
1112 };
1113
1114 class BinaryOpNode : public ExpressionNode {
1115 public:
1116 BinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
1117 BinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
1118
1119 RegisterID* emitStrcat(BytecodeGenerator& generator, RegisterID* destination, RegisterID* lhs = 0, ReadModifyResolveNode* emitExpressionInfoForMe = 0);
1120 void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
1121
1122 ExpressionNode* lhs() { return m_expr1; };
1123 ExpressionNode* rhs() { return m_expr2; };
1124
1125 bool isBinaryOpNode() const override { return true; }
1126
1127 private:
1128 enum class UInt32Result : uint8_t { UInt32, Constant, };
1129
1130 void tryFoldToBranch(BytecodeGenerator&, TriState& branchCondition, ExpressionNode*& branchExpression);
1131 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1132
1133 protected:
1134 OpcodeID opcodeID() const { return m_opcodeID; }
1135
1136 protected:
1137 bool m_rightHasAssignments;
1138 bool m_shouldToUnsignedResult { true };
1139 private:
1140 OpcodeID m_opcodeID;
1141 protected:
1142 ExpressionNode* m_expr1;
1143 ExpressionNode* m_expr2;
1144 };
1145
1146 class PowNode final : public BinaryOpNode {
1147 public:
1148 PowNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1149 };
1150
1151 class MultNode final : public BinaryOpNode {
1152 public:
1153 MultNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1154 };
1155
1156 class DivNode final : public BinaryOpNode {
1157 public:
1158 DivNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1159 };
1160
1161 class ModNode final : public BinaryOpNode {
1162 public:
1163 ModNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1164 };
1165
1166 class AddNode final : public BinaryOpNode {
1167 public:
1168 AddNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1169
1170 bool isAdd() const override { return true; }
1171 };
1172
1173 class SubNode final : public BinaryOpNode {
1174 public:
1175 SubNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1176
1177 bool isSubtract() const override { return true; }
1178 };
1179
1180 class LeftShiftNode final : public BinaryOpNode {
1181 public:
1182 LeftShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1183 };
1184
1185 class RightShiftNode final : public BinaryOpNode {
1186 public:
1187 RightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1188 };
1189
1190 class UnsignedRightShiftNode final : public BinaryOpNode {
1191 public:
1192 UnsignedRightShiftNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1193 };
1194
1195 class LessNode final : public BinaryOpNode {
1196 public:
1197 LessNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1198 };
1199
1200 class GreaterNode final : public BinaryOpNode {
1201 public:
1202 GreaterNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1203 };
1204
1205 class LessEqNode final : public BinaryOpNode {
1206 public:
1207 LessEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1208 };
1209
1210 class GreaterEqNode final : public BinaryOpNode {
1211 public:
1212 GreaterEqNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1213 };
1214
1215 class ThrowableBinaryOpNode : public BinaryOpNode, public ThrowableExpressionData {
1216 public:
1217 ThrowableBinaryOpNode(const JSTokenLocation&, ResultType, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
1218 ThrowableBinaryOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, OpcodeID, bool rightHasAssignments);
1219
1220 private:
1221 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1222 };
1223
1224 class InstanceOfNode final : public ThrowableBinaryOpNode {
1225 public:
1226 InstanceOfNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1227
1228 private:
1229 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1230 };
1231
1232 class InNode final : public ThrowableBinaryOpNode {
1233 public:
1234 InNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1235
1236 private:
1237 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1238 };
1239
1240 class EqualNode final : public BinaryOpNode {
1241 public:
1242 EqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1243
1244 private:
1245 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1246 };
1247
1248 class NotEqualNode final : public BinaryOpNode {
1249 public:
1250 NotEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1251 };
1252
1253 class StrictEqualNode final : public BinaryOpNode {
1254 public:
1255 StrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1256
1257 private:
1258 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1259 };
1260
1261 class NotStrictEqualNode final : public BinaryOpNode {
1262 public:
1263 NotStrictEqualNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1264 };
1265
1266 class BitAndNode final : public BinaryOpNode {
1267 public:
1268 BitAndNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1269 };
1270
1271 class BitOrNode final : public BinaryOpNode {
1272 public:
1273 BitOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1274 };
1275
1276 class BitXOrNode final : public BinaryOpNode {
1277 public:
1278 BitXOrNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, bool rightHasAssignments);
1279 };
1280
1281 // m_expr1 && m_expr2, m_expr1 || m_expr2
1282 class LogicalOpNode final : public ExpressionNode {
1283 public:
1284 LogicalOpNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, LogicalOperator);
1285
1286 private:
1287 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1288 void emitBytecodeInConditionContext(BytecodeGenerator&, Label& trueTarget, Label& falseTarget, FallThroughMode) override;
1289
1290 LogicalOperator m_operator;
1291 ExpressionNode* m_expr1;
1292 ExpressionNode* m_expr2;
1293 };
1294
1295 // The ternary operator, "m_logical ? m_expr1 : m_expr2"
1296 class ConditionalNode final : public ExpressionNode {
1297 public:
1298 ConditionalNode(const JSTokenLocation&, ExpressionNode* logical, ExpressionNode* expr1, ExpressionNode* expr2);
1299
1300 private:
1301 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1302
1303 ExpressionNode* m_logical;
1304 ExpressionNode* m_expr1;
1305 ExpressionNode* m_expr2;
1306 };
1307
1308 class ReadModifyResolveNode final : public ExpressionNode, public ThrowableExpressionData {
1309 public:
1310 ReadModifyResolveNode(const JSTokenLocation&, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1311
1312 private:
1313 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1314
1315 const Identifier& m_ident;
1316 ExpressionNode* m_right;
1317 Operator m_operator;
1318 bool m_rightHasAssignments;
1319 };
1320
1321 class AssignResolveNode final : public ExpressionNode, public ThrowableExpressionData {
1322 public:
1323 AssignResolveNode(const JSTokenLocation&, const Identifier&, ExpressionNode* right, AssignmentContext);
1324 bool isAssignResolveNode() const override { return true; }
1325 const Identifier& identifier() const { return m_ident; }
1326
1327 private:
1328 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1329
1330 const Identifier& m_ident;
1331 ExpressionNode* m_right;
1332 AssignmentContext m_assignmentContext;
1333 };
1334
1335 class ReadModifyBracketNode final : public ExpressionNode, public ThrowableSubExpressionData {
1336 public:
1337 ReadModifyBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, Operator, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1338
1339 private:
1340 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1341
1342 ExpressionNode* m_base;
1343 ExpressionNode* m_subscript;
1344 ExpressionNode* m_right;
1345 unsigned m_operator : 30;
1346 bool m_subscriptHasAssignments : 1;
1347 bool m_rightHasAssignments : 1;
1348 };
1349
1350 class AssignBracketNode final : public ExpressionNode, public ThrowableExpressionData {
1351 public:
1352 AssignBracketNode(const JSTokenLocation&, ExpressionNode* base, ExpressionNode* subscript, ExpressionNode* right, bool subscriptHasAssignments, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1353
1354 private:
1355 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1356
1357 ExpressionNode* m_base;
1358 ExpressionNode* m_subscript;
1359 ExpressionNode* m_right;
1360 bool m_subscriptHasAssignments : 1;
1361 bool m_rightHasAssignments : 1;
1362 };
1363
1364 class AssignDotNode final : public ExpressionNode, public ThrowableExpressionData {
1365 public:
1366 AssignDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1367
1368 private:
1369 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1370
1371 ExpressionNode* m_base;
1372 const Identifier& m_ident;
1373 ExpressionNode* m_right;
1374 bool m_rightHasAssignments;
1375 };
1376
1377 class ReadModifyDotNode final : public ExpressionNode, public ThrowableSubExpressionData {
1378 public:
1379 ReadModifyDotNode(const JSTokenLocation&, ExpressionNode* base, const Identifier&, Operator, ExpressionNode* right, bool rightHasAssignments, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1380
1381 private:
1382 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1383
1384 ExpressionNode* m_base;
1385 const Identifier& m_ident;
1386 ExpressionNode* m_right;
1387 unsigned m_operator : 31;
1388 bool m_rightHasAssignments : 1;
1389 };
1390
1391 class AssignErrorNode final : public ExpressionNode, public ThrowableExpressionData {
1392 public:
1393 AssignErrorNode(const JSTokenLocation&, const JSTextPosition& divot, const JSTextPosition& divotStart, const JSTextPosition& divotEnd);
1394
1395 private:
1396 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1397 };
1398
1399 class CommaNode final : public ExpressionNode {
1400 public:
1401 CommaNode(const JSTokenLocation&, ExpressionNode*);
1402
1403 void setNext(CommaNode* next) { m_next = next; }
1404 CommaNode* next() { return m_next; }
1405
1406 private:
1407 bool isCommaNode() const override { return true; }
1408 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1409
1410 ExpressionNode* m_expr;
1411 CommaNode* m_next { nullptr };
1412 };
1413
1414 class SourceElements final : public ParserArenaFreeable {
1415 public:
1416 SourceElements();
1417
1418 void append(StatementNode*);
1419
1420 StatementNode* singleStatement() const;
1421 StatementNode* lastStatement() const;
1422
1423 bool hasCompletionValue() const;
1424 bool hasEarlyBreakOrContinue() const;
1425
1426 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
1427 void analyzeModule(ModuleAnalyzer&);
1428
1429 private:
1430 StatementNode* m_head { nullptr };
1431 StatementNode* m_tail { nullptr };
1432 };
1433
1434 class BlockNode final : public StatementNode, public VariableEnvironmentNode {
1435 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(BlockNode);
1436 public:
1437 BlockNode(const JSTokenLocation&, SourceElements*, VariableEnvironment&, FunctionStack&&);
1438
1439 StatementNode* singleStatement() const;
1440 StatementNode* lastStatement() const;
1441
1442 private:
1443 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1444
1445 bool hasCompletionValue() const override;
1446 bool hasEarlyBreakOrContinue() const override;
1447
1448 bool isBlock() const override { return true; }
1449
1450 SourceElements* m_statements;
1451 };
1452
1453 class EmptyStatementNode final : public StatementNode {
1454 public:
1455 EmptyStatementNode(const JSTokenLocation&);
1456
1457 private:
1458 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1459
1460 bool hasCompletionValue() const override { return false; }
1461 bool isEmptyStatement() const override { return true; }
1462 };
1463
1464 class DebuggerStatementNode final : public StatementNode {
1465 public:
1466 DebuggerStatementNode(const JSTokenLocation&);
1467
1468 bool hasCompletionValue() const override { return false; }
1469 bool isDebuggerStatement() const override { return true; }
1470
1471 private:
1472 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1473 };
1474
1475 class ExprStatementNode final : public StatementNode {
1476 public:
1477 ExprStatementNode(const JSTokenLocation&, ExpressionNode*);
1478
1479 ExpressionNode* expr() const { return m_expr; }
1480
1481 private:
1482 bool isExprStatement() const override { return true; }
1483
1484 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1485
1486 ExpressionNode* m_expr;
1487 };
1488
1489 class DeclarationStatement final : public StatementNode {
1490 public:
1491 DeclarationStatement(const JSTokenLocation&, ExpressionNode*);
1492 private:
1493 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1494
1495 bool hasCompletionValue() const override { return false; }
1496
1497 ExpressionNode* m_expr;
1498 };
1499
1500 class EmptyVarExpression final : public ExpressionNode {
1501 public:
1502 EmptyVarExpression(const JSTokenLocation&, const Identifier&);
1503
1504 private:
1505 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1506
1507 const Identifier& m_ident;
1508 };
1509
1510 class EmptyLetExpression final : public ExpressionNode {
1511 public:
1512 EmptyLetExpression(const JSTokenLocation&, const Identifier&);
1513
1514 private:
1515 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1516
1517 const Identifier& m_ident;
1518 };
1519
1520 class IfElseNode final : public StatementNode {
1521 public:
1522 IfElseNode(const JSTokenLocation&, ExpressionNode* condition, StatementNode* ifBlock, StatementNode* elseBlock);
1523
1524 private:
1525 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1526 bool tryFoldBreakAndContinue(BytecodeGenerator&, StatementNode* ifBlock,
1527 Label*& trueTarget, FallThroughMode&);
1528
1529 ExpressionNode* m_condition;
1530 StatementNode* m_ifBlock;
1531 StatementNode* m_elseBlock;
1532 };
1533
1534 class DoWhileNode final : public StatementNode {
1535 public:
1536 DoWhileNode(const JSTokenLocation&, StatementNode*, ExpressionNode*);
1537
1538 private:
1539 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1540
1541 StatementNode* m_statement;
1542 ExpressionNode* m_expr;
1543 };
1544
1545 class WhileNode final : public StatementNode {
1546 public:
1547 WhileNode(const JSTokenLocation&, ExpressionNode*, StatementNode*);
1548
1549 private:
1550 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1551
1552 ExpressionNode* m_expr;
1553 StatementNode* m_statement;
1554 };
1555
1556 class ForNode final : public StatementNode, public VariableEnvironmentNode {
1557 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForNode);
1558 public:
1559 ForNode(const JSTokenLocation&, ExpressionNode* expr1, ExpressionNode* expr2, ExpressionNode* expr3, StatementNode*, VariableEnvironment&);
1560
1561 private:
1562 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1563
1564 ExpressionNode* m_expr1;
1565 ExpressionNode* m_expr2;
1566 ExpressionNode* m_expr3;
1567 StatementNode* m_statement;
1568 };
1569
1570 class DestructuringPatternNode;
1571
1572 class EnumerationNode : public StatementNode, public ThrowableExpressionData, public VariableEnvironmentNode {
1573 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(EnumerationNode);
1574 public:
1575 EnumerationNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
1576
1577 ExpressionNode* lexpr() const { return m_lexpr; }
1578 ExpressionNode* expr() const { return m_expr; }
1579
1580 protected:
1581 ExpressionNode* m_lexpr;
1582 ExpressionNode* m_expr;
1583 StatementNode* m_statement;
1584 };
1585
1586 class ForInNode final : public EnumerationNode {
1587 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForInNode);
1588 public:
1589 ForInNode(const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
1590
1591 private:
1592 RegisterID* tryGetBoundLocal(BytecodeGenerator&);
1593 void emitLoopHeader(BytecodeGenerator&, RegisterID* propertyName);
1594
1595 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1596 };
1597
1598 class ForOfNode final : public EnumerationNode {
1599 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ForOfNode);
1600 public:
1601 ForOfNode(bool, const JSTokenLocation&, ExpressionNode*, ExpressionNode*, StatementNode*, VariableEnvironment&);
1602 bool isForOfNode() const override { return true; }
1603 bool isForAwait() const { return m_isForAwait; }
1604
1605 private:
1606 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1607
1608 const bool m_isForAwait;
1609 };
1610
1611 class ContinueNode final : public StatementNode, public ThrowableExpressionData {
1612 public:
1613 ContinueNode(const JSTokenLocation&, const Identifier&);
1614 Label* trivialTarget(BytecodeGenerator&);
1615
1616 private:
1617 bool hasCompletionValue() const override { return false; }
1618 bool isContinue() const override { return true; }
1619 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1620
1621 const Identifier& m_ident;
1622 };
1623
1624 class BreakNode final : public StatementNode, public ThrowableExpressionData {
1625 public:
1626 BreakNode(const JSTokenLocation&, const Identifier&);
1627 Label* trivialTarget(BytecodeGenerator&);
1628
1629 private:
1630 bool hasCompletionValue() const override { return false; }
1631 bool isBreak() const override { return true; }
1632 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1633
1634 const Identifier& m_ident;
1635 };
1636
1637 class ReturnNode final : public StatementNode, public ThrowableExpressionData {
1638 public:
1639 ReturnNode(const JSTokenLocation&, ExpressionNode* value);
1640
1641 ExpressionNode* value() { return m_value; }
1642
1643 private:
1644 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1645
1646 bool isReturnNode() const override { return true; }
1647
1648 ExpressionNode* m_value;
1649 };
1650
1651 class WithNode final : public StatementNode {
1652 public:
1653 WithNode(const JSTokenLocation&, ExpressionNode*, StatementNode*, const JSTextPosition& divot, uint32_t expressionLength);
1654
1655 private:
1656 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1657
1658 ExpressionNode* m_expr;
1659 StatementNode* m_statement;
1660 JSTextPosition m_divot;
1661 uint32_t m_expressionLength;
1662 };
1663
1664 class LabelNode final : public StatementNode, public ThrowableExpressionData {
1665 public:
1666 LabelNode(const JSTokenLocation&, const Identifier& name, StatementNode*);
1667
1668 bool isLabel() const override { return true; }
1669
1670 private:
1671 bool hasCompletionValue() const override { return m_statement->hasCompletionValue(); }
1672 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1673
1674 const Identifier& m_name;
1675 StatementNode* m_statement;
1676 };
1677
1678 class ThrowNode final : public StatementNode, public ThrowableExpressionData {
1679 public:
1680 ThrowNode(const JSTokenLocation&, ExpressionNode*);
1681
1682 private:
1683 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1684
1685 ExpressionNode* m_expr;
1686 };
1687
1688 class TryNode final : public StatementNode, public VariableEnvironmentNode {
1689 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(TryNode);
1690 public:
1691 TryNode(const JSTokenLocation&, StatementNode* tryBlock, DestructuringPatternNode* catchPattern, StatementNode* catchBlock, VariableEnvironment& catchEnvironment, StatementNode* finallyBlock);
1692
1693 private:
1694 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1695
1696 StatementNode* m_tryBlock;
1697 DestructuringPatternNode* m_catchPattern;
1698 StatementNode* m_catchBlock;
1699 StatementNode* m_finallyBlock;
1700 };
1701
1702 class ScopeNode : public StatementNode, public ParserArenaRoot, public VariableEnvironmentNode {
1703 public:
1704 // ScopeNode is never directly instantiate. The life-cycle of its derived classes are
1705 // managed using std::unique_ptr. Hence, though ScopeNode extends VariableEnvironmentNode,
1706 // which in turn extends ParserArenaDeletable, we don't want to use ParserArenaDeletable's
1707 // new for allocation.
1708 using ParserArenaRoot::operator new;
1709
1710 ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, bool inStrictContext);
1711 ScopeNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, const SourceCode&, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants);
1712
1713 const SourceCode& source() const { return m_source; }
1714 const String& sourceURL() const { return m_source.provider()->url(); }
1715 intptr_t sourceID() const { return m_source.providerID(); }
1716
1717 int startLine() const { return m_startLineNumber; }
1718 int startStartOffset() const { return m_startStartOffset; }
1719 int startLineStartOffset() const { return m_startLineStartOffset; }
1720
1721 void setFeatures(CodeFeatures features) { m_features = features; }
1722 CodeFeatures features() { return m_features; }
1723 InnerArrowFunctionCodeFeatures innerArrowFunctionCodeFeatures() { return m_innerArrowFunctionCodeFeatures; }
1724 bool doAnyInnerArrowFunctionsUseAnyFeature() { return m_innerArrowFunctionCodeFeatures != NoInnerArrowFunctionFeatures; }
1725 bool doAnyInnerArrowFunctionsUseArguments() { return m_innerArrowFunctionCodeFeatures & ArgumentsInnerArrowFunctionFeature; }
1726 bool doAnyInnerArrowFunctionsUseSuperCall() { return m_innerArrowFunctionCodeFeatures & SuperCallInnerArrowFunctionFeature; }
1727 bool doAnyInnerArrowFunctionsUseSuperProperty() { return m_innerArrowFunctionCodeFeatures & SuperPropertyInnerArrowFunctionFeature; }
1728 bool doAnyInnerArrowFunctionsUseEval() { return m_innerArrowFunctionCodeFeatures & EvalInnerArrowFunctionFeature; }
1729 bool doAnyInnerArrowFunctionsUseThis() { return m_innerArrowFunctionCodeFeatures & ThisInnerArrowFunctionFeature; }
1730 bool doAnyInnerArrowFunctionsUseNewTarget() { return m_innerArrowFunctionCodeFeatures & NewTargetInnerArrowFunctionFeature; }
1731
1732 bool usesEval() const { return m_features & EvalFeature; }
1733 bool usesArguments() const { return (m_features & ArgumentsFeature) && !(m_features & ShadowsArgumentsFeature); }
1734 bool usesArrowFunction() const { return m_features & ArrowFunctionFeature; }
1735 bool isStrictMode() const { return m_features & StrictModeFeature; }
1736 void setUsesArguments() { m_features |= ArgumentsFeature; }
1737 bool usesThis() const { return m_features & ThisFeature; }
1738 bool usesSuperCall() const { return m_features & SuperCallFeature; }
1739 bool usesSuperProperty() const { return m_features & SuperPropertyFeature; }
1740 bool usesNewTarget() const { return m_features & NewTargetFeature; }
1741 bool needsActivation() const { return (hasCapturedVariables()) || (m_features & (EvalFeature | WithFeature)); }
1742 bool hasCapturedVariables() const { return m_varDeclarations.hasCapturedVariables(); }
1743 bool captures(UniquedStringImpl* uid) { return m_varDeclarations.captures(uid); }
1744 bool captures(const Identifier& ident) { return captures(ident.impl()); }
1745 bool hasSloppyModeHoistedFunction(UniquedStringImpl* uid) const { return m_sloppyModeHoistedFunctions.contains(uid); }
1746
1747 VariableEnvironment& varDeclarations() { return m_varDeclarations; }
1748
1749 int neededConstants()
1750 {
1751 // We may need 2 more constants than the count given by the parser,
1752 // because of the various uses of jsUndefined() and jsNull().
1753 return m_numConstants + 2;
1754 }
1755
1756 StatementNode* singleStatement() const;
1757
1758 bool hasCompletionValue() const override;
1759 bool hasEarlyBreakOrContinue() const override;
1760
1761 void emitStatementsBytecode(BytecodeGenerator&, RegisterID* destination);
1762
1763 void analyzeModule(ModuleAnalyzer&);
1764
1765 protected:
1766 int m_startLineNumber;
1767 unsigned m_startStartOffset;
1768 unsigned m_startLineStartOffset;
1769
1770 private:
1771 CodeFeatures m_features;
1772 InnerArrowFunctionCodeFeatures m_innerArrowFunctionCodeFeatures;
1773 SourceCode m_source;
1774 VariableEnvironment m_varDeclarations;
1775 UniquedStringImplPtrSet m_sloppyModeHoistedFunctions;
1776 int m_numConstants;
1777 SourceElements* m_statements;
1778 };
1779
1780 class ProgramNode final : public ScopeNode {
1781 public:
1782 ProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
1783
1784 unsigned startColumn() const { return m_startColumn; }
1785 unsigned endColumn() const { return m_endColumn; }
1786
1787 static const bool scopeIsFunction = false;
1788
1789 private:
1790 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1791 unsigned m_startColumn;
1792 unsigned m_endColumn;
1793 };
1794
1795 class EvalNode final : public ScopeNode {
1796 public:
1797 EvalNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
1798
1799 ALWAYS_INLINE unsigned startColumn() const { return 0; }
1800 unsigned endColumn() const { return m_endColumn; }
1801
1802 static const bool scopeIsFunction = false;
1803
1804 private:
1805 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1806
1807 unsigned m_endColumn;
1808 };
1809
1810 class ModuleProgramNode final : public ScopeNode {
1811 public:
1812 ModuleProgramNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
1813
1814 unsigned startColumn() const { return m_startColumn; }
1815 unsigned endColumn() const { return m_endColumn; }
1816
1817 static const bool scopeIsFunction = false;
1818
1819 ModuleScopeData& moduleScopeData()
1820 {
1821 return m_moduleScopeData;
1822 }
1823
1824 private:
1825 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1826 unsigned m_startColumn;
1827 unsigned m_endColumn;
1828 Ref<ModuleScopeData> m_moduleScopeData;
1829 };
1830
1831 class ModuleNameNode final : public Node {
1832 public:
1833 ModuleNameNode(const JSTokenLocation&, const Identifier& moduleName);
1834
1835 const Identifier& moduleName() { return m_moduleName; }
1836
1837 private:
1838 const Identifier& m_moduleName;
1839 };
1840
1841 class ImportSpecifierNode final : public Node {
1842 public:
1843 ImportSpecifierNode(const JSTokenLocation&, const Identifier& importedName, const Identifier& localName);
1844
1845 const Identifier& importedName() { return m_importedName; }
1846 const Identifier& localName() { return m_localName; }
1847
1848 private:
1849 const Identifier& m_importedName;
1850 const Identifier& m_localName;
1851 };
1852
1853 class ImportSpecifierListNode final : public ParserArenaDeletable {
1854 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ImportSpecifierListNode);
1855 public:
1856 typedef Vector<ImportSpecifierNode*, 3> Specifiers;
1857
1858 const Specifiers& specifiers() const { return m_specifiers; }
1859 void append(ImportSpecifierNode* specifier)
1860 {
1861 m_specifiers.append(specifier);
1862 }
1863
1864 private:
1865 Specifiers m_specifiers;
1866 };
1867
1868 class ModuleDeclarationNode : public StatementNode {
1869 public:
1870 virtual void analyzeModule(ModuleAnalyzer&) = 0;
1871 bool hasCompletionValue() const override { return false; }
1872 bool isModuleDeclarationNode() const override { return true; }
1873
1874 protected:
1875 ModuleDeclarationNode(const JSTokenLocation&);
1876 };
1877
1878 class ImportDeclarationNode final : public ModuleDeclarationNode {
1879 public:
1880 ImportDeclarationNode(const JSTokenLocation&, ImportSpecifierListNode*, ModuleNameNode*);
1881
1882 ImportSpecifierListNode* specifierList() const { return m_specifierList; }
1883 ModuleNameNode* moduleName() const { return m_moduleName; }
1884
1885 private:
1886 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1887 void analyzeModule(ModuleAnalyzer&) override;
1888
1889 ImportSpecifierListNode* m_specifierList;
1890 ModuleNameNode* m_moduleName;
1891 };
1892
1893 class ExportAllDeclarationNode final : public ModuleDeclarationNode {
1894 public:
1895 ExportAllDeclarationNode(const JSTokenLocation&, ModuleNameNode*);
1896
1897 ModuleNameNode* moduleName() const { return m_moduleName; }
1898
1899 private:
1900 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1901 void analyzeModule(ModuleAnalyzer&) override;
1902
1903 ModuleNameNode* m_moduleName;
1904 };
1905
1906 class ExportDefaultDeclarationNode final : public ModuleDeclarationNode {
1907 public:
1908 ExportDefaultDeclarationNode(const JSTokenLocation&, StatementNode*, const Identifier& localName);
1909
1910 const StatementNode& declaration() const { return *m_declaration; }
1911 const Identifier& localName() const { return m_localName; }
1912
1913 private:
1914 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1915 void analyzeModule(ModuleAnalyzer&) override;
1916 StatementNode* m_declaration;
1917 const Identifier& m_localName;
1918 };
1919
1920 class ExportLocalDeclarationNode final : public ModuleDeclarationNode {
1921 public:
1922 ExportLocalDeclarationNode(const JSTokenLocation&, StatementNode*);
1923
1924 const StatementNode& declaration() const { return *m_declaration; }
1925
1926 private:
1927 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1928 void analyzeModule(ModuleAnalyzer&) override;
1929 StatementNode* m_declaration;
1930 };
1931
1932 class ExportSpecifierNode final : public Node {
1933 public:
1934 ExportSpecifierNode(const JSTokenLocation&, const Identifier& localName, const Identifier& exportedName);
1935
1936 const Identifier& exportedName() { return m_exportedName; }
1937 const Identifier& localName() { return m_localName; }
1938
1939 private:
1940 const Identifier& m_localName;
1941 const Identifier& m_exportedName;
1942 };
1943
1944 class ExportSpecifierListNode final : public ParserArenaDeletable {
1945 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ExportSpecifierListNode);
1946 public:
1947 typedef Vector<ExportSpecifierNode*, 3> Specifiers;
1948
1949 const Specifiers& specifiers() const { return m_specifiers; }
1950 void append(ExportSpecifierNode* specifier)
1951 {
1952 m_specifiers.append(specifier);
1953 }
1954
1955 private:
1956 Specifiers m_specifiers;
1957 };
1958
1959 class ExportNamedDeclarationNode final : public ModuleDeclarationNode {
1960 public:
1961 ExportNamedDeclarationNode(const JSTokenLocation&, ExportSpecifierListNode*, ModuleNameNode*);
1962
1963 ExportSpecifierListNode* specifierList() const { return m_specifierList; }
1964 ModuleNameNode* moduleName() const { return m_moduleName; }
1965
1966 private:
1967 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
1968 void analyzeModule(ModuleAnalyzer&) override;
1969 ExportSpecifierListNode* m_specifierList;
1970 ModuleNameNode* m_moduleName { nullptr };
1971 };
1972
1973 class FunctionMetadataNode final : public ParserArenaDeletable, public Node {
1974 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(FunctionMetadataNode);
1975 public:
1976 FunctionMetadataNode(
1977 ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end,
1978 unsigned startColumn, unsigned endColumn, int functionKeywordStart,
1979 int functionNameStart, int parametersStart, bool isInStrictContext,
1980 ConstructorKind, SuperBinding, unsigned parameterCount,
1981 SourceParseMode, bool isArrowFunctionBodyExpression);
1982 FunctionMetadataNode(
1983 const JSTokenLocation& start, const JSTokenLocation& end,
1984 unsigned startColumn, unsigned endColumn, int functionKeywordStart,
1985 int functionNameStart, int parametersStart, bool isInStrictContext,
1986 ConstructorKind, SuperBinding, unsigned parameterCount,
1987 SourceParseMode, bool isArrowFunctionBodyExpression);
1988
1989 void dump(PrintStream&) const;
1990
1991 void finishParsing(const SourceCode&, const Identifier&, FunctionMode);
1992
1993 void overrideName(const Identifier& ident) { m_ident = ident; }
1994 const Identifier& ident() { return m_ident; }
1995 void setEcmaName(const Identifier& ecmaName) { m_ecmaName = ecmaName; }
1996 const Identifier& ecmaName() { return m_ident.isEmpty() ? m_ecmaName : m_ident; }
1997 void setInferredName(const Identifier& inferredName) { ASSERT(!inferredName.isNull()); m_inferredName = inferredName; }
1998 const Identifier& inferredName() { return m_inferredName.isEmpty() ? m_ident : m_inferredName; }
1999
2000 FunctionMode functionMode() { return m_functionMode; }
2001
2002 int functionNameStart() const { return m_functionNameStart; }
2003 int functionKeywordStart() const { return m_functionKeywordStart; }
2004 int parametersStart() const { return m_parametersStart; }
2005 unsigned startColumn() const { return m_startColumn; }
2006 unsigned endColumn() const { return m_endColumn; }
2007 unsigned parameterCount() const { return m_parameterCount; }
2008 SourceParseMode parseMode() const { return m_parseMode; }
2009
2010 void setEndPosition(JSTextPosition);
2011
2012 const SourceCode& source() const { return m_source; }
2013 const SourceCode& classSource() const { return m_classSource; }
2014 void setClassSource(const SourceCode& source) { m_classSource = source; }
2015
2016 int startStartOffset() const { return m_startStartOffset; }
2017 bool isInStrictContext() const { return m_isInStrictContext; }
2018 SuperBinding superBinding() { return static_cast<SuperBinding>(m_superBinding); }
2019 ConstructorKind constructorKind() { return static_cast<ConstructorKind>(m_constructorKind); }
2020 bool isArrowFunctionBodyExpression() const { return m_isArrowFunctionBodyExpression; }
2021
2022 void setLoc(unsigned firstLine, unsigned lastLine, int startOffset, int lineStartOffset)
2023 {
2024 m_lastLine = lastLine;
2025 m_position = JSTextPosition(firstLine, startOffset, lineStartOffset);
2026 ASSERT(m_position.offset >= m_position.lineStartOffset);
2027 }
2028 unsigned lastLine() const { return m_lastLine; }
2029
2030 bool operator==(const FunctionMetadataNode&) const;
2031 bool operator!=(const FunctionMetadataNode& other) const
2032 {
2033 return !(*this == other);
2034 }
2035
2036 public:
2037 unsigned m_isInStrictContext : 1;
2038 unsigned m_superBinding : 1;
2039 unsigned m_constructorKind : 2;
2040 unsigned m_isArrowFunctionBodyExpression : 1;
2041 SourceParseMode m_parseMode;
2042 FunctionMode m_functionMode;
2043 Identifier m_ident;
2044 Identifier m_ecmaName;
2045 Identifier m_inferredName;
2046 unsigned m_startColumn;
2047 unsigned m_endColumn;
2048 int m_functionKeywordStart;
2049 int m_functionNameStart;
2050 int m_parametersStart;
2051 SourceCode m_source;
2052 SourceCode m_classSource;
2053 int m_startStartOffset;
2054 unsigned m_parameterCount;
2055 int m_lastLine;
2056 };
2057
2058 class FunctionNode final : public ScopeNode {
2059 public:
2060 FunctionNode(ParserArena&, const JSTokenLocation& start, const JSTokenLocation& end, unsigned startColumn, unsigned endColumn, SourceElements*, VariableEnvironment&, FunctionStack&&, VariableEnvironment&, UniquedStringImplPtrSet&&, FunctionParameters*, const SourceCode&, CodeFeatures, InnerArrowFunctionCodeFeatures, int numConstants, RefPtr<ModuleScopeData>&&);
2061
2062 FunctionParameters* parameters() const { return m_parameters; }
2063
2064 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2065
2066 bool isFunctionNode() const override { return true; }
2067
2068 void finishParsing(const Identifier&, FunctionMode);
2069
2070 const Identifier& ident() { return m_ident; }
2071
2072 FunctionMode functionMode() const { return m_functionMode; }
2073
2074 unsigned startColumn() const { return m_startColumn; }
2075 unsigned endColumn() const { return m_endColumn; }
2076
2077 static const bool scopeIsFunction = true;
2078
2079 private:
2080 Identifier m_ident;
2081 FunctionMode m_functionMode;
2082 FunctionParameters* m_parameters;
2083 unsigned m_startColumn;
2084 unsigned m_endColumn;
2085 };
2086
2087 class BaseFuncExprNode : public ExpressionNode {
2088 public:
2089 FunctionMetadataNode* metadata() { return m_metadata; }
2090
2091 bool isBaseFuncExprNode() const override { return true; }
2092
2093 protected:
2094 BaseFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode);
2095
2096 FunctionMetadataNode* m_metadata;
2097 };
2098
2099
2100 class FuncExprNode : public BaseFuncExprNode {
2101 public:
2102 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
2103
2104 protected:
2105 FuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&, FunctionMode);
2106
2107 private:
2108 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2109
2110 bool isFuncExprNode() const override { return true; }
2111 };
2112
2113 class ArrowFuncExprNode final : public BaseFuncExprNode {
2114 public:
2115 ArrowFuncExprNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
2116
2117 private:
2118 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2119
2120 bool isArrowFuncExprNode() const override { return true; }
2121 };
2122
2123 class MethodDefinitionNode final : public FuncExprNode {
2124 public:
2125 MethodDefinitionNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
2126
2127 private:
2128 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2129 };
2130
2131 class YieldExprNode final : public ExpressionNode, public ThrowableExpressionData {
2132 public:
2133 YieldExprNode(const JSTokenLocation&, ExpressionNode* argument, bool delegate);
2134
2135 ExpressionNode* argument() const { return m_argument; }
2136 bool delegate() const { return m_delegate; }
2137
2138 private:
2139 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2140
2141 ExpressionNode* m_argument;
2142 bool m_delegate;
2143 };
2144
2145 class AwaitExprNode final : public ExpressionNode, public ThrowableExpressionData {
2146 public:
2147 AwaitExprNode(const JSTokenLocation&, ExpressionNode* argument);
2148
2149 ExpressionNode* argument() const { return m_argument; }
2150
2151 private:
2152 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2153
2154 ExpressionNode* m_argument;
2155 };
2156
2157 class ClassExprNode final : public ExpressionNode, public VariableEnvironmentNode {
2158 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ClassExprNode);
2159 public:
2160 ClassExprNode(const JSTokenLocation&, const Identifier&, const SourceCode& classSource,
2161 VariableEnvironment& classEnvironment, ExpressionNode* constructorExpresssion,
2162 ExpressionNode* parentClass, PropertyListNode* classElements);
2163
2164 const Identifier& name() { return m_name; }
2165 const Identifier& ecmaName() { return m_ecmaName ? *m_ecmaName : m_name; }
2166 void setEcmaName(const Identifier& name) { m_ecmaName = m_name.isNull() ? &name : &m_name; }
2167
2168 bool hasStaticProperty(const Identifier& propName) { return m_classElements ? m_classElements->hasStaticallyNamedProperty(propName) : false; }
2169
2170 private:
2171 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2172
2173 bool isClassExprNode() const override { return true; }
2174
2175 SourceCode m_classSource;
2176 const Identifier& m_name;
2177 const Identifier* m_ecmaName;
2178 ExpressionNode* m_constructorExpression;
2179 ExpressionNode* m_classHeritage;
2180 PropertyListNode* m_classElements;
2181 };
2182
2183 class DestructuringPatternNode : public ParserArenaFreeable {
2184 public:
2185 virtual ~DestructuringPatternNode() { }
2186 virtual void collectBoundIdentifiers(Vector<Identifier>&) const = 0;
2187 virtual void bindValue(BytecodeGenerator&, RegisterID* source) const = 0;
2188 virtual void toString(StringBuilder&) const = 0;
2189
2190 virtual bool isBindingNode() const { return false; }
2191 virtual bool isAssignmentElementNode() const { return false; }
2192 virtual bool isRestParameter() const { return false; }
2193 virtual RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID*, ExpressionNode*) { return 0; }
2194
2195 protected:
2196 DestructuringPatternNode();
2197 };
2198
2199 class ArrayPatternNode final : public DestructuringPatternNode, public ParserArenaDeletable, public ThrowableExpressionData {
2200 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ArrayPatternNode);
2201 public:
2202 ArrayPatternNode();
2203 enum class BindingType : uint8_t {
2204 Elision,
2205 Element,
2206 RestElement
2207 };
2208
2209 void appendIndex(BindingType bindingType, const JSTokenLocation&, DestructuringPatternNode* node, ExpressionNode* defaultValue)
2210 {
2211 m_targetPatterns.append({ bindingType, node, defaultValue });
2212 }
2213
2214 private:
2215 struct Entry {
2216 BindingType bindingType;
2217 DestructuringPatternNode* pattern;
2218 ExpressionNode* defaultValue;
2219 };
2220 void collectBoundIdentifiers(Vector<Identifier>&) const override;
2221 void bindValue(BytecodeGenerator&, RegisterID*) const override;
2222 RegisterID* emitDirectBinding(BytecodeGenerator&, RegisterID* dst, ExpressionNode*) override;
2223 void toString(StringBuilder&) const override;
2224
2225 Vector<Entry> m_targetPatterns;
2226 };
2227
2228 class ObjectPatternNode final : public DestructuringPatternNode, public ParserArenaDeletable, public ThrowableExpressionData {
2229 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(ObjectPatternNode);
2230 public:
2231 ObjectPatternNode();
2232 enum class BindingType : uint8_t {
2233 Element,
2234 RestElement
2235 };
2236 void appendEntry(const JSTokenLocation&, const Identifier& identifier, bool wasString, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType)
2237 {
2238 m_targetPatterns.append(Entry{ identifier, nullptr, wasString, pattern, defaultValue, bindingType });
2239 }
2240
2241 void appendEntry(VM& vm, const JSTokenLocation&, ExpressionNode* propertyExpression, DestructuringPatternNode* pattern, ExpressionNode* defaultValue, BindingType bindingType)
2242 {
2243 m_targetPatterns.append(Entry{ vm.propertyNames->nullIdentifier, propertyExpression, false, pattern, defaultValue, bindingType });
2244 }
2245
2246 void setContainsRestElement(bool containsRestElement)
2247 {
2248 m_containsRestElement = containsRestElement;
2249 }
2250
2251 void setContainsComputedProperty(bool containsComputedProperty)
2252 {
2253 m_containsComputedProperty = containsComputedProperty;
2254 }
2255
2256 private:
2257 void collectBoundIdentifiers(Vector<Identifier>&) const override;
2258 void bindValue(BytecodeGenerator&, RegisterID*) const override;
2259 void toString(StringBuilder&) const override;
2260 struct Entry {
2261 const Identifier& propertyName;
2262 ExpressionNode* propertyExpression;
2263 bool wasString;
2264 DestructuringPatternNode* pattern;
2265 ExpressionNode* defaultValue;
2266 BindingType bindingType;
2267 };
2268 bool m_containsRestElement { false };
2269 bool m_containsComputedProperty { false };
2270 Vector<Entry> m_targetPatterns;
2271 };
2272
2273 class BindingNode final: public DestructuringPatternNode {
2274 public:
2275 BindingNode(const Identifier& boundProperty, const JSTextPosition& start, const JSTextPosition& end, AssignmentContext);
2276 const Identifier& boundProperty() const { return m_boundProperty; }
2277
2278 const JSTextPosition& divotStart() const { return m_divotStart; }
2279 const JSTextPosition& divotEnd() const { return m_divotEnd; }
2280
2281 private:
2282 void collectBoundIdentifiers(Vector<Identifier>&) const override;
2283 void bindValue(BytecodeGenerator&, RegisterID*) const override;
2284 void toString(StringBuilder&) const override;
2285
2286 bool isBindingNode() const override { return true; }
2287
2288 JSTextPosition m_divotStart;
2289 JSTextPosition m_divotEnd;
2290 const Identifier& m_boundProperty;
2291 AssignmentContext m_bindingContext;
2292 };
2293
2294 class RestParameterNode final : public DestructuringPatternNode {
2295 public:
2296 RestParameterNode(DestructuringPatternNode*, unsigned numParametersToSkip);
2297
2298 bool isRestParameter() const override { return true; }
2299
2300 void emit(BytecodeGenerator&);
2301
2302 private:
2303 void collectBoundIdentifiers(Vector<Identifier>&) const override;
2304 void bindValue(BytecodeGenerator&, RegisterID*) const override;
2305 void toString(StringBuilder&) const override;
2306
2307 DestructuringPatternNode* m_pattern;
2308 unsigned m_numParametersToSkip;
2309 };
2310
2311 class AssignmentElementNode final : public DestructuringPatternNode {
2312 public:
2313 AssignmentElementNode(ExpressionNode* assignmentTarget, const JSTextPosition& start, const JSTextPosition& end);
2314 const ExpressionNode* assignmentTarget() { return m_assignmentTarget; }
2315
2316 const JSTextPosition& divotStart() const { return m_divotStart; }
2317 const JSTextPosition& divotEnd() const { return m_divotEnd; }
2318
2319 private:
2320 void collectBoundIdentifiers(Vector<Identifier>&) const override;
2321 void bindValue(BytecodeGenerator&, RegisterID*) const override;
2322 void toString(StringBuilder&) const override;
2323
2324 bool isAssignmentElementNode() const override { return true; }
2325
2326 JSTextPosition m_divotStart;
2327 JSTextPosition m_divotEnd;
2328 ExpressionNode* m_assignmentTarget;
2329 };
2330
2331 class DestructuringAssignmentNode final : public ExpressionNode {
2332 public:
2333 DestructuringAssignmentNode(const JSTokenLocation&, DestructuringPatternNode*, ExpressionNode*);
2334 DestructuringPatternNode* bindings() { return m_bindings; }
2335
2336 private:
2337 bool isAssignmentLocation() const override { return true; }
2338 bool isDestructuringNode() const override { return true; }
2339 RegisterID* emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2340
2341 DestructuringPatternNode* m_bindings;
2342 ExpressionNode* m_initializer;
2343 };
2344
2345 class FunctionParameters final : public ParserArenaDeletable {
2346 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(FunctionParameters);
2347 public:
2348 FunctionParameters();
2349 ALWAYS_INLINE unsigned size() const { return m_patterns.size(); }
2350 ALWAYS_INLINE std::pair<DestructuringPatternNode*, ExpressionNode*> at(unsigned index) { return m_patterns[index]; }
2351 ALWAYS_INLINE void append(DestructuringPatternNode* pattern, ExpressionNode* defaultValue)
2352 {
2353 ASSERT(pattern);
2354
2355 // http://www.ecma-international.org/ecma-262/6.0/index.html#sec-functiondeclarationinstantiation
2356 // This implements IsSimpleParameterList in the Ecma 2015 spec.
2357 // If IsSimpleParameterList is false, we will create a strict-mode like arguments object.
2358 // IsSimpleParameterList is false if the argument list contains any default parameter values,
2359 // a rest parameter, or any destructuring patterns.
2360 // If we do have default parameters, destructuring parameters, or a rest parameter, our parameters will be allocated in a different scope.
2361
2362 bool hasDefaultParameterValue = defaultValue;
2363 bool isSimpleParameter = !hasDefaultParameterValue && pattern->isBindingNode();
2364 m_isSimpleParameterList &= isSimpleParameter;
2365
2366 m_patterns.append(std::make_pair(pattern, defaultValue));
2367 }
2368 ALWAYS_INLINE bool isSimpleParameterList() const { return m_isSimpleParameterList; }
2369
2370 private:
2371
2372 Vector<std::pair<DestructuringPatternNode*, ExpressionNode*>, 3> m_patterns;
2373 bool m_isSimpleParameterList { true };
2374 };
2375
2376 class FuncDeclNode final : public StatementNode {
2377 public:
2378 FuncDeclNode(const JSTokenLocation&, const Identifier&, FunctionMetadataNode*, const SourceCode&);
2379
2380 bool hasCompletionValue() const override { return false; }
2381 bool isFuncDeclNode() const override { return true; }
2382 FunctionMetadataNode* metadata() { return m_metadata; }
2383
2384 private:
2385 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2386
2387 FunctionMetadataNode* m_metadata;
2388 };
2389
2390 class ClassDeclNode final : public StatementNode {
2391 public:
2392 ClassDeclNode(const JSTokenLocation&, ExpressionNode* classExpression);
2393
2394 private:
2395 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2396
2397 bool hasCompletionValue() const override { return false; }
2398
2399 ExpressionNode* m_classDeclaration;
2400 };
2401
2402 class CaseClauseNode final : public ParserArenaFreeable {
2403 public:
2404 CaseClauseNode(ExpressionNode*, SourceElements* = 0);
2405
2406 ExpressionNode* expr() const { return m_expr; }
2407
2408 void emitBytecode(BytecodeGenerator&, RegisterID* destination);
2409 void setStartOffset(int offset) { m_startOffset = offset; }
2410
2411 private:
2412 ExpressionNode* m_expr;
2413 SourceElements* m_statements;
2414 int m_startOffset;
2415 };
2416
2417 class ClauseListNode final : public ParserArenaFreeable {
2418 public:
2419 ClauseListNode(CaseClauseNode*);
2420 ClauseListNode(ClauseListNode*, CaseClauseNode*);
2421
2422 CaseClauseNode* getClause() const { return m_clause; }
2423 ClauseListNode* getNext() const { return m_next; }
2424
2425 private:
2426 CaseClauseNode* m_clause;
2427 ClauseListNode* m_next { nullptr };
2428 };
2429
2430 class CaseBlockNode final : public ParserArenaFreeable {
2431 public:
2432 CaseBlockNode(ClauseListNode* list1, CaseClauseNode* defaultClause, ClauseListNode* list2);
2433
2434 void emitBytecodeForBlock(BytecodeGenerator&, RegisterID* input, RegisterID* destination);
2435
2436 private:
2437 SwitchInfo::SwitchType tryTableSwitch(Vector<ExpressionNode*, 8>& literalVector, int32_t& min_num, int32_t& max_num);
2438 static const size_t s_tableSwitchMinimum = 3;
2439 ClauseListNode* m_list1;
2440 CaseClauseNode* m_defaultClause;
2441 ClauseListNode* m_list2;
2442 };
2443
2444 class SwitchNode final : public StatementNode, public VariableEnvironmentNode {
2445 JSC_MAKE_PARSER_ARENA_DELETABLE_ALLOCATED(SwitchNode);
2446 public:
2447 SwitchNode(const JSTokenLocation&, ExpressionNode*, CaseBlockNode*, VariableEnvironment&, FunctionStack&&);
2448
2449 private:
2450 void emitBytecode(BytecodeGenerator&, RegisterID* = 0) override;
2451
2452 ExpressionNode* m_expr;
2453 CaseBlockNode* m_block;
2454 };
2455
2456 struct ElementList {
2457 ElementNode* head;
2458 ElementNode* tail;
2459 };
2460
2461 struct PropertyList {
2462 PropertyListNode* head;
2463 PropertyListNode* tail;
2464 };
2465
2466 struct ArgumentList {
2467 ArgumentListNode* head;
2468 ArgumentListNode* tail;
2469 };
2470
2471 struct ClauseList {
2472 ClauseListNode* head;
2473 ClauseListNode* tail;
2474 };
2475
2476} // namespace JSC
2477