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