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