1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef V8_AST_AST_H_
6 #define V8_AST_AST_H_
7
8 #include <memory>
9
10 #include "src/ast/ast-value-factory.h"
11 #include "src/ast/modules.h"
12 #include "src/ast/variables.h"
13 #include "src/base/pointer-with-payload.h"
14 #include "src/base/threaded-list.h"
15 #include "src/codegen/bailout-reason.h"
16 #include "src/codegen/label.h"
17 #include "src/common/globals.h"
18 #include "src/heap/factory.h"
19 #include "src/objects/elements-kind.h"
20 #include "src/objects/function-syntax-kind.h"
21 #include "src/objects/literal-objects.h"
22 #include "src/objects/smi.h"
23 #include "src/parsing/token.h"
24 #include "src/runtime/runtime.h"
25 #include "src/zone/zone-list.h"
26
27 namespace v8 {
28 namespace internal {
29
30 // The abstract syntax tree is an intermediate, light-weight
31 // representation of the parsed JavaScript code suitable for
32 // compilation to native code.
33
34 // Nodes are allocated in a separate zone, which allows faster
35 // allocation and constant-time deallocation of the entire syntax
36 // tree.
37
38
39 // ----------------------------------------------------------------------------
40 // Nodes of the abstract syntax tree. Only concrete classes are
41 // enumerated here.
42
43 #define DECLARATION_NODE_LIST(V) \
44 V(VariableDeclaration) \
45 V(FunctionDeclaration)
46
47 #define ITERATION_NODE_LIST(V) \
48 V(DoWhileStatement) \
49 V(WhileStatement) \
50 V(ForStatement) \
51 V(ForInStatement) \
52 V(ForOfStatement)
53
54 #define BREAKABLE_NODE_LIST(V) \
55 V(Block) \
56 V(SwitchStatement)
57
58 #define STATEMENT_NODE_LIST(V) \
59 ITERATION_NODE_LIST(V) \
60 BREAKABLE_NODE_LIST(V) \
61 V(ExpressionStatement) \
62 V(EmptyStatement) \
63 V(SloppyBlockFunctionStatement) \
64 V(IfStatement) \
65 V(ContinueStatement) \
66 V(BreakStatement) \
67 V(ReturnStatement) \
68 V(WithStatement) \
69 V(TryCatchStatement) \
70 V(TryFinallyStatement) \
71 V(DebuggerStatement) \
72 V(InitializeClassMembersStatement) \
73 V(InitializeClassStaticElementsStatement)
74
75 #define LITERAL_NODE_LIST(V) \
76 V(RegExpLiteral) \
77 V(ObjectLiteral) \
78 V(ArrayLiteral)
79
80 #define EXPRESSION_NODE_LIST(V) \
81 LITERAL_NODE_LIST(V) \
82 V(Assignment) \
83 V(Await) \
84 V(BinaryOperation) \
85 V(NaryOperation) \
86 V(Call) \
87 V(CallNew) \
88 V(CallRuntime) \
89 V(ClassLiteral) \
90 V(CompareOperation) \
91 V(CompoundAssignment) \
92 V(Conditional) \
93 V(CountOperation) \
94 V(EmptyParentheses) \
95 V(FunctionLiteral) \
96 V(GetTemplateObject) \
97 V(ImportCallExpression) \
98 V(Literal) \
99 V(NativeFunctionLiteral) \
100 V(OptionalChain) \
101 V(Property) \
102 V(Spread) \
103 V(SuperCallReference) \
104 V(SuperPropertyReference) \
105 V(TemplateLiteral) \
106 V(ThisExpression) \
107 V(Throw) \
108 V(UnaryOperation) \
109 V(VariableProxy) \
110 V(Yield) \
111 V(YieldStar)
112
113 #define FAILURE_NODE_LIST(V) V(FailureExpression)
114
115 #define AST_NODE_LIST(V) \
116 DECLARATION_NODE_LIST(V) \
117 STATEMENT_NODE_LIST(V) \
118 EXPRESSION_NODE_LIST(V)
119
120 // Forward declarations
121 class Isolate;
122
123 class AstNode;
124 class AstNodeFactory;
125 class Declaration;
126 class BreakableStatement;
127 class Expression;
128 class IterationStatement;
129 class MaterializedLiteral;
130 class NestedVariableDeclaration;
131 class ProducedPreparseData;
132 class Statement;
133
134 #define DEF_FORWARD_DECLARATION(type) class type;
135 AST_NODE_LIST(DEF_FORWARD_DECLARATION)
FAILURE_NODE_LIST(DEF_FORWARD_DECLARATION)136 FAILURE_NODE_LIST(DEF_FORWARD_DECLARATION)
137 #undef DEF_FORWARD_DECLARATION
138
139 class AstNode: public ZoneObject {
140 public:
141 #define DECLARE_TYPE_ENUM(type) k##type,
142 enum NodeType : uint8_t {
143 AST_NODE_LIST(DECLARE_TYPE_ENUM) /* , */
144 FAILURE_NODE_LIST(DECLARE_TYPE_ENUM)
145 };
146 #undef DECLARE_TYPE_ENUM
147
148 NodeType node_type() const { return NodeTypeField::decode(bit_field_); }
149 int position() const { return position_; }
150
151 #ifdef DEBUG
152 void Print(Isolate* isolate);
153 #endif // DEBUG
154
155 // Type testing & conversion functions overridden by concrete subclasses.
156 #define DECLARE_NODE_FUNCTIONS(type) \
157 V8_INLINE bool Is##type() const; \
158 V8_INLINE type* As##type(); \
159 V8_INLINE const type* As##type() const;
160 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
161 FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
162 #undef DECLARE_NODE_FUNCTIONS
163
164 IterationStatement* AsIterationStatement();
165 MaterializedLiteral* AsMaterializedLiteral();
166
167 private:
168 int position_;
169 using NodeTypeField = base::BitField<NodeType, 0, 6>;
170
171 protected:
172 uint32_t bit_field_;
173
174 template <class T, int size>
175 using NextBitField = NodeTypeField::Next<T, size>;
176
177 AstNode(int position, NodeType type)
178 : position_(position), bit_field_(NodeTypeField::encode(type)) {}
179 };
180
181
182 class Statement : public AstNode {
183 protected:
Statement(int position,NodeType type)184 Statement(int position, NodeType type) : AstNode(position, type) {}
185 };
186
187
188 class Expression : public AstNode {
189 public:
190 enum Context {
191 // Not assigned a context yet, or else will not be visited during
192 // code generation.
193 kUninitialized,
194 // Evaluated for its side effects.
195 kEffect,
196 // Evaluated for its value (and side effects).
197 kValue,
198 // Evaluated for control flow (and side effects).
199 kTest
200 };
201
202 // True iff the expression is a valid reference expression.
203 bool IsValidReferenceExpression() const;
204
205 // True iff the expression is a private name.
206 bool IsPrivateName() const;
207
208 // Helpers for ToBoolean conversion.
209 bool ToBooleanIsTrue() const;
210 bool ToBooleanIsFalse() const;
211
212 // Symbols that cannot be parsed as array indices are considered property
213 // names. We do not treat symbols that can be array indexes as property
214 // names because [] for string objects is handled only by keyed ICs.
215 bool IsPropertyName() const;
216
217 // True iff the expression is a class or function expression without
218 // a syntactic name.
219 bool IsAnonymousFunctionDefinition() const;
220
221 // True iff the expression is a concise method definition.
222 bool IsConciseMethodDefinition() const;
223
224 // True iff the expression is an accessor function definition.
225 bool IsAccessorFunctionDefinition() const;
226
227 // True iff the expression is a literal represented as a smi.
228 bool IsSmiLiteral() const;
229
230 // True iff the expression is a literal represented as a number.
231 V8_EXPORT_PRIVATE bool IsNumberLiteral() const;
232
233 // True iff the expression is a string literal.
234 bool IsStringLiteral() const;
235
236 // True iff the expression is the null literal.
237 bool IsNullLiteral() const;
238
239 // True iff the expression is the hole literal.
240 bool IsTheHoleLiteral() const;
241
242 // True if we can prove that the expression is the undefined literal. Note
243 // that this also checks for loads of the global "undefined" variable.
244 bool IsUndefinedLiteral() const;
245
246 // True if either null literal or undefined literal.
IsNullOrUndefinedLiteral()247 inline bool IsNullOrUndefinedLiteral() const {
248 return IsNullLiteral() || IsUndefinedLiteral();
249 }
250
251 // True if a literal and not null or undefined.
252 bool IsLiteralButNotNullOrUndefined() const;
253
254 bool IsCompileTimeValue();
255
IsPattern()256 bool IsPattern() {
257 STATIC_ASSERT(kObjectLiteral + 1 == kArrayLiteral);
258 return base::IsInRange(node_type(), kObjectLiteral, kArrayLiteral);
259 }
260
is_parenthesized()261 bool is_parenthesized() const {
262 return IsParenthesizedField::decode(bit_field_);
263 }
264
mark_parenthesized()265 void mark_parenthesized() {
266 bit_field_ = IsParenthesizedField::update(bit_field_, true);
267 }
268
clear_parenthesized()269 void clear_parenthesized() {
270 bit_field_ = IsParenthesizedField::update(bit_field_, false);
271 }
272
273 private:
274 using IsParenthesizedField = AstNode::NextBitField<bool, 1>;
275
276 protected:
Expression(int pos,NodeType type)277 Expression(int pos, NodeType type) : AstNode(pos, type) {
278 DCHECK(!is_parenthesized());
279 }
280
281 template <class T, int size>
282 using NextBitField = IsParenthesizedField::Next<T, size>;
283 };
284
285 class FailureExpression : public Expression {
286 private:
287 friend class AstNodeFactory;
288 friend Zone;
FailureExpression()289 FailureExpression() : Expression(kNoSourcePosition, kFailureExpression) {}
290 };
291
292 // V8's notion of BreakableStatement does not correspond to the notion of
293 // BreakableStatement in ECMAScript. In V8, the idea is that a
294 // BreakableStatement is a statement that can be the target of a break
295 // statement.
296 //
297 // Since we don't want to track a list of labels for all kinds of statements, we
298 // only declare switchs, loops, and blocks as BreakableStatements. This means
299 // that we implement breaks targeting other statement forms as breaks targeting
300 // a substatement thereof. For instance, in "foo: if (b) { f(); break foo; }" we
301 // pretend that foo is the label of the inner block. That's okay because one
302 // can't observe the difference.
303 // TODO(verwaest): Reconsider this optimization now that the tracking of labels
304 // is done at runtime.
305 class BreakableStatement : public Statement {
306 protected:
BreakableStatement(int position,NodeType type)307 BreakableStatement(int position, NodeType type) : Statement(position, type) {}
308 };
309
310 class Block final : public BreakableStatement {
311 public:
statements()312 ZonePtrList<Statement>* statements() { return &statements_; }
ignore_completion_value()313 bool ignore_completion_value() const {
314 return IgnoreCompletionField::decode(bit_field_);
315 }
is_breakable()316 bool is_breakable() const { return IsBreakableField::decode(bit_field_); }
317
scope()318 Scope* scope() const { return scope_; }
set_scope(Scope * scope)319 void set_scope(Scope* scope) { scope_ = scope; }
320
InitializeStatements(const ScopedPtrList<Statement> & statements,Zone * zone)321 void InitializeStatements(const ScopedPtrList<Statement>& statements,
322 Zone* zone) {
323 DCHECK_EQ(0, statements_.length());
324 statements_ = ZonePtrList<Statement>(statements.ToConstVector(), zone);
325 }
326
327 private:
328 friend class AstNodeFactory;
329 friend Zone;
330
331 ZonePtrList<Statement> statements_;
332 Scope* scope_;
333
334 using IgnoreCompletionField = BreakableStatement::NextBitField<bool, 1>;
335 using IsBreakableField = IgnoreCompletionField::Next<bool, 1>;
336
337 protected:
Block(Zone * zone,int capacity,bool ignore_completion_value,bool is_breakable)338 Block(Zone* zone, int capacity, bool ignore_completion_value,
339 bool is_breakable)
340 : BreakableStatement(kNoSourcePosition, kBlock),
341 statements_(capacity, zone),
342 scope_(nullptr) {
343 bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value) |
344 IsBreakableField::encode(is_breakable);
345 }
346
Block(bool ignore_completion_value,bool is_breakable)347 Block(bool ignore_completion_value, bool is_breakable)
348 : Block(nullptr, 0, ignore_completion_value, is_breakable) {}
349 };
350
351 class Declaration : public AstNode {
352 public:
353 using List = base::ThreadedList<Declaration>;
354
var()355 Variable* var() const { return var_; }
set_var(Variable * var)356 void set_var(Variable* var) { var_ = var; }
357
358 protected:
Declaration(int pos,NodeType type)359 Declaration(int pos, NodeType type) : AstNode(pos, type), next_(nullptr) {}
360
361 private:
362 Variable* var_;
363 // Declarations list threaded through the declarations.
next()364 Declaration** next() { return &next_; }
365 Declaration* next_;
366 friend List;
367 friend base::ThreadedListTraits<Declaration>;
368 };
369
370 class VariableDeclaration : public Declaration {
371 public:
372 inline NestedVariableDeclaration* AsNested();
373
374 private:
375 friend class AstNodeFactory;
376 friend Zone;
377
378 using IsNestedField = Declaration::NextBitField<bool, 1>;
379
380 protected:
381 explicit VariableDeclaration(int pos, bool is_nested = false)
Declaration(pos,kVariableDeclaration)382 : Declaration(pos, kVariableDeclaration) {
383 bit_field_ = IsNestedField::update(bit_field_, is_nested);
384 }
385
386 template <class T, int size>
387 using NextBitField = IsNestedField::Next<T, size>;
388 };
389
390 // For var declarations that appear in a block scope.
391 // Only distinguished from VariableDeclaration during Scope analysis,
392 // so it doesn't get its own NodeType.
393 class NestedVariableDeclaration final : public VariableDeclaration {
394 public:
scope()395 Scope* scope() const { return scope_; }
396
397 private:
398 friend class AstNodeFactory;
399 friend Zone;
400
NestedVariableDeclaration(Scope * scope,int pos)401 NestedVariableDeclaration(Scope* scope, int pos)
402 : VariableDeclaration(pos, true), scope_(scope) {}
403
404 // Nested scope from which the declaration originated.
405 Scope* scope_;
406 };
407
AsNested()408 inline NestedVariableDeclaration* VariableDeclaration::AsNested() {
409 return IsNestedField::decode(bit_field_)
410 ? static_cast<NestedVariableDeclaration*>(this)
411 : nullptr;
412 }
413
414 class FunctionDeclaration final : public Declaration {
415 public:
fun()416 FunctionLiteral* fun() const { return fun_; }
417
418 private:
419 friend class AstNodeFactory;
420 friend Zone;
421
FunctionDeclaration(FunctionLiteral * fun,int pos)422 FunctionDeclaration(FunctionLiteral* fun, int pos)
423 : Declaration(pos, kFunctionDeclaration), fun_(fun) {}
424
425 FunctionLiteral* fun_;
426 };
427
428
429 class IterationStatement : public BreakableStatement {
430 public:
body()431 Statement* body() const { return body_; }
set_body(Statement * s)432 void set_body(Statement* s) { body_ = s; }
433
434 protected:
IterationStatement(int pos,NodeType type)435 IterationStatement(int pos, NodeType type)
436 : BreakableStatement(pos, type), body_(nullptr) {}
Initialize(Statement * body)437 void Initialize(Statement* body) { body_ = body; }
438
439 private:
440 Statement* body_;
441 };
442
443
444 class DoWhileStatement final : public IterationStatement {
445 public:
Initialize(Expression * cond,Statement * body)446 void Initialize(Expression* cond, Statement* body) {
447 IterationStatement::Initialize(body);
448 cond_ = cond;
449 }
450
cond()451 Expression* cond() const { return cond_; }
452
453 private:
454 friend class AstNodeFactory;
455 friend Zone;
456
DoWhileStatement(int pos)457 explicit DoWhileStatement(int pos)
458 : IterationStatement(pos, kDoWhileStatement), cond_(nullptr) {}
459
460 Expression* cond_;
461 };
462
463
464 class WhileStatement final : public IterationStatement {
465 public:
Initialize(Expression * cond,Statement * body)466 void Initialize(Expression* cond, Statement* body) {
467 IterationStatement::Initialize(body);
468 cond_ = cond;
469 }
470
cond()471 Expression* cond() const { return cond_; }
472
473 private:
474 friend class AstNodeFactory;
475 friend Zone;
476
WhileStatement(int pos)477 explicit WhileStatement(int pos)
478 : IterationStatement(pos, kWhileStatement), cond_(nullptr) {}
479
480 Expression* cond_;
481 };
482
483
484 class ForStatement final : public IterationStatement {
485 public:
Initialize(Statement * init,Expression * cond,Statement * next,Statement * body)486 void Initialize(Statement* init, Expression* cond, Statement* next,
487 Statement* body) {
488 IterationStatement::Initialize(body);
489 init_ = init;
490 cond_ = cond;
491 next_ = next;
492 }
493
init()494 Statement* init() const { return init_; }
cond()495 Expression* cond() const { return cond_; }
next()496 Statement* next() const { return next_; }
497
498 private:
499 friend class AstNodeFactory;
500 friend Zone;
501
ForStatement(int pos)502 explicit ForStatement(int pos)
503 : IterationStatement(pos, kForStatement),
504 init_(nullptr),
505 cond_(nullptr),
506 next_(nullptr) {}
507
508 Statement* init_;
509 Expression* cond_;
510 Statement* next_;
511 };
512
513 // Shared class for for-in and for-of statements.
514 class ForEachStatement : public IterationStatement {
515 public:
516 enum VisitMode {
517 ENUMERATE, // for (each in subject) body;
518 ITERATE // for (each of subject) body;
519 };
520
521 using IterationStatement::Initialize;
522
VisitModeString(VisitMode mode)523 static const char* VisitModeString(VisitMode mode) {
524 return mode == ITERATE ? "for-of" : "for-in";
525 }
526
Initialize(Expression * each,Expression * subject,Statement * body)527 void Initialize(Expression* each, Expression* subject, Statement* body) {
528 IterationStatement::Initialize(body);
529 each_ = each;
530 subject_ = subject;
531 }
532
each()533 Expression* each() const { return each_; }
subject()534 Expression* subject() const { return subject_; }
535
536 protected:
537 friend class AstNodeFactory;
538 friend Zone;
539
ForEachStatement(int pos,NodeType type)540 ForEachStatement(int pos, NodeType type)
541 : IterationStatement(pos, type), each_(nullptr), subject_(nullptr) {}
542
543 Expression* each_;
544 Expression* subject_;
545 };
546
547 class ForInStatement final : public ForEachStatement {
548 private:
549 friend class AstNodeFactory;
550 friend Zone;
551
ForInStatement(int pos)552 explicit ForInStatement(int pos) : ForEachStatement(pos, kForInStatement) {}
553 };
554
555 enum class IteratorType { kNormal, kAsync };
556 class ForOfStatement final : public ForEachStatement {
557 public:
type()558 IteratorType type() const { return type_; }
559
560 private:
561 friend class AstNodeFactory;
562 friend Zone;
563
ForOfStatement(int pos,IteratorType type)564 ForOfStatement(int pos, IteratorType type)
565 : ForEachStatement(pos, kForOfStatement), type_(type) {}
566
567 IteratorType type_;
568 };
569
570 class ExpressionStatement final : public Statement {
571 public:
set_expression(Expression * e)572 void set_expression(Expression* e) { expression_ = e; }
expression()573 Expression* expression() const { return expression_; }
574
575 private:
576 friend class AstNodeFactory;
577 friend Zone;
578
ExpressionStatement(Expression * expression,int pos)579 ExpressionStatement(Expression* expression, int pos)
580 : Statement(pos, kExpressionStatement), expression_(expression) {}
581
582 Expression* expression_;
583 };
584
585
586 class JumpStatement : public Statement {
587 protected:
JumpStatement(int pos,NodeType type)588 JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
589 };
590
591
592 class ContinueStatement final : public JumpStatement {
593 public:
target()594 IterationStatement* target() const { return target_; }
595
596 private:
597 friend class AstNodeFactory;
598 friend Zone;
599
ContinueStatement(IterationStatement * target,int pos)600 ContinueStatement(IterationStatement* target, int pos)
601 : JumpStatement(pos, kContinueStatement), target_(target) {}
602
603 IterationStatement* target_;
604 };
605
606
607 class BreakStatement final : public JumpStatement {
608 public:
target()609 BreakableStatement* target() const { return target_; }
610
611 private:
612 friend class AstNodeFactory;
613 friend Zone;
614
BreakStatement(BreakableStatement * target,int pos)615 BreakStatement(BreakableStatement* target, int pos)
616 : JumpStatement(pos, kBreakStatement), target_(target) {}
617
618 BreakableStatement* target_;
619 };
620
621
622 class ReturnStatement final : public JumpStatement {
623 public:
624 enum Type { kNormal, kAsyncReturn, kSyntheticAsyncReturn };
expression()625 Expression* expression() const { return expression_; }
626
type()627 Type type() const { return TypeField::decode(bit_field_); }
is_async_return()628 bool is_async_return() const { return type() != kNormal; }
is_synthetic_async_return()629 bool is_synthetic_async_return() const {
630 return type() == kSyntheticAsyncReturn;
631 }
632
633 // This constant is used to indicate that the return position
634 // from the FunctionLiteral should be used when emitting code.
635 static constexpr int kFunctionLiteralReturnPosition = -2;
636 STATIC_ASSERT(kFunctionLiteralReturnPosition == kNoSourcePosition - 1);
637
end_position()638 int end_position() const { return end_position_; }
639
640 private:
641 friend class AstNodeFactory;
642 friend Zone;
643
ReturnStatement(Expression * expression,Type type,int pos,int end_position)644 ReturnStatement(Expression* expression, Type type, int pos, int end_position)
645 : JumpStatement(pos, kReturnStatement),
646 expression_(expression),
647 end_position_(end_position) {
648 bit_field_ |= TypeField::encode(type);
649 }
650
651 Expression* expression_;
652 int end_position_;
653
654 using TypeField = JumpStatement::NextBitField<Type, 2>;
655 };
656
657
658 class WithStatement final : public Statement {
659 public:
scope()660 Scope* scope() { return scope_; }
expression()661 Expression* expression() const { return expression_; }
statement()662 Statement* statement() const { return statement_; }
set_statement(Statement * s)663 void set_statement(Statement* s) { statement_ = s; }
664
665 private:
666 friend class AstNodeFactory;
667 friend Zone;
668
WithStatement(Scope * scope,Expression * expression,Statement * statement,int pos)669 WithStatement(Scope* scope, Expression* expression, Statement* statement,
670 int pos)
671 : Statement(pos, kWithStatement),
672 scope_(scope),
673 expression_(expression),
674 statement_(statement) {}
675
676 Scope* scope_;
677 Expression* expression_;
678 Statement* statement_;
679 };
680
681 class CaseClause final : public ZoneObject {
682 public:
is_default()683 bool is_default() const { return label_ == nullptr; }
label()684 Expression* label() const {
685 DCHECK(!is_default());
686 return label_;
687 }
statements()688 ZonePtrList<Statement>* statements() { return &statements_; }
689
690 private:
691 friend class AstNodeFactory;
692 friend Zone;
693
694 CaseClause(Zone* zone, Expression* label,
695 const ScopedPtrList<Statement>& statements);
696
697 Expression* label_;
698 ZonePtrList<Statement> statements_;
699 };
700
701
702 class SwitchStatement final : public BreakableStatement {
703 public:
tag()704 Expression* tag() const { return tag_; }
set_tag(Expression * t)705 void set_tag(Expression* t) { tag_ = t; }
706
cases()707 ZonePtrList<CaseClause>* cases() { return &cases_; }
708
709 private:
710 friend class AstNodeFactory;
711 friend Zone;
712
SwitchStatement(Zone * zone,Expression * tag,int pos)713 SwitchStatement(Zone* zone, Expression* tag, int pos)
714 : BreakableStatement(pos, kSwitchStatement), tag_(tag), cases_(4, zone) {}
715
716 Expression* tag_;
717 ZonePtrList<CaseClause> cases_;
718 };
719
720
721 // If-statements always have non-null references to their then- and
722 // else-parts. When parsing if-statements with no explicit else-part,
723 // the parser implicitly creates an empty statement. Use the
724 // HasThenStatement() and HasElseStatement() functions to check if a
725 // given if-statement has a then- or an else-part containing code.
726 class IfStatement final : public Statement {
727 public:
HasThenStatement()728 bool HasThenStatement() const { return !then_statement_->IsEmptyStatement(); }
HasElseStatement()729 bool HasElseStatement() const { return !else_statement_->IsEmptyStatement(); }
730
condition()731 Expression* condition() const { return condition_; }
then_statement()732 Statement* then_statement() const { return then_statement_; }
else_statement()733 Statement* else_statement() const { return else_statement_; }
734
set_then_statement(Statement * s)735 void set_then_statement(Statement* s) { then_statement_ = s; }
set_else_statement(Statement * s)736 void set_else_statement(Statement* s) { else_statement_ = s; }
737
738 private:
739 friend class AstNodeFactory;
740 friend Zone;
741
IfStatement(Expression * condition,Statement * then_statement,Statement * else_statement,int pos)742 IfStatement(Expression* condition, Statement* then_statement,
743 Statement* else_statement, int pos)
744 : Statement(pos, kIfStatement),
745 condition_(condition),
746 then_statement_(then_statement),
747 else_statement_(else_statement) {}
748
749 Expression* condition_;
750 Statement* then_statement_;
751 Statement* else_statement_;
752 };
753
754
755 class TryStatement : public Statement {
756 public:
try_block()757 Block* try_block() const { return try_block_; }
set_try_block(Block * b)758 void set_try_block(Block* b) { try_block_ = b; }
759
760 protected:
TryStatement(Block * try_block,int pos,NodeType type)761 TryStatement(Block* try_block, int pos, NodeType type)
762 : Statement(pos, type), try_block_(try_block) {}
763
764 private:
765 Block* try_block_;
766 };
767
768
769 class TryCatchStatement final : public TryStatement {
770 public:
scope()771 Scope* scope() { return scope_; }
catch_block()772 Block* catch_block() const { return catch_block_; }
set_catch_block(Block * b)773 void set_catch_block(Block* b) { catch_block_ = b; }
774
775 // Prediction of whether exceptions thrown into the handler for this try block
776 // will be caught.
777 //
778 // BytecodeGenerator tracks the state of catch prediction, which can change
779 // with each TryCatchStatement encountered. The tracked catch prediction is
780 // later compiled into the code's handler table. The runtime uses this
781 // information to implement a feature that notifies the debugger when an
782 // uncaught exception is thrown, _before_ the exception propagates to the top.
783 //
784 // If this try/catch statement is meant to rethrow (HandlerTable::UNCAUGHT),
785 // the catch prediction value is set to the same value as the surrounding
786 // catch prediction.
787 //
788 // Since it's generally undecidable whether an exception will be caught, our
789 // prediction is only an approximation.
790 // ---------------------------------------------------------------------------
GetCatchPrediction(HandlerTable::CatchPrediction outer_catch_prediction)791 inline HandlerTable::CatchPrediction GetCatchPrediction(
792 HandlerTable::CatchPrediction outer_catch_prediction) const {
793 if (catch_prediction_ == HandlerTable::UNCAUGHT) {
794 return outer_catch_prediction;
795 }
796 return catch_prediction_;
797 }
798
799 // Indicates whether or not code should be generated to clear the pending
800 // exception. The pending exception is cleared for cases where the exception
801 // is not guaranteed to be rethrown, indicated by the value
802 // HandlerTable::UNCAUGHT. If both the current and surrounding catch handler's
803 // are predicted uncaught, the exception is not cleared.
804 //
805 // If this handler is not going to simply rethrow the exception, this method
806 // indicates that the isolate's pending exception message should be cleared
807 // before executing the catch_block.
808 // In the normal use case, this flag is always on because the message object
809 // is not needed anymore when entering the catch block and should not be
810 // kept alive.
811 // The use case where the flag is off is when the catch block is guaranteed
812 // to rethrow the caught exception (using %ReThrow), which reuses the
813 // pending message instead of generating a new one.
814 // (When the catch block doesn't rethrow but is guaranteed to perform an
815 // ordinary throw, not clearing the old message is safe but not very
816 // useful.)
817 //
818 // For scripts in repl mode there is exactly one catch block with
819 // UNCAUGHT_ASYNC_AWAIT prediction. This catch block needs to preserve
820 // the exception so it can be re-used later by the inspector.
ShouldClearPendingException(HandlerTable::CatchPrediction outer_catch_prediction)821 inline bool ShouldClearPendingException(
822 HandlerTable::CatchPrediction outer_catch_prediction) const {
823 if (catch_prediction_ == HandlerTable::UNCAUGHT_ASYNC_AWAIT) {
824 DCHECK_EQ(outer_catch_prediction, HandlerTable::UNCAUGHT);
825 return false;
826 }
827
828 return catch_prediction_ != HandlerTable::UNCAUGHT ||
829 outer_catch_prediction != HandlerTable::UNCAUGHT;
830 }
831
is_try_catch_for_async()832 bool is_try_catch_for_async() {
833 return catch_prediction_ == HandlerTable::ASYNC_AWAIT;
834 }
835
836 private:
837 friend class AstNodeFactory;
838 friend Zone;
839
TryCatchStatement(Block * try_block,Scope * scope,Block * catch_block,HandlerTable::CatchPrediction catch_prediction,int pos)840 TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block,
841 HandlerTable::CatchPrediction catch_prediction, int pos)
842 : TryStatement(try_block, pos, kTryCatchStatement),
843 scope_(scope),
844 catch_block_(catch_block),
845 catch_prediction_(catch_prediction) {}
846
847 Scope* scope_;
848 Block* catch_block_;
849 HandlerTable::CatchPrediction catch_prediction_;
850 };
851
852
853 class TryFinallyStatement final : public TryStatement {
854 public:
finally_block()855 Block* finally_block() const { return finally_block_; }
set_finally_block(Block * b)856 void set_finally_block(Block* b) { finally_block_ = b; }
857
858 private:
859 friend class AstNodeFactory;
860 friend Zone;
861
TryFinallyStatement(Block * try_block,Block * finally_block,int pos)862 TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
863 : TryStatement(try_block, pos, kTryFinallyStatement),
864 finally_block_(finally_block) {}
865
866 Block* finally_block_;
867 };
868
869
870 class DebuggerStatement final : public Statement {
871 private:
872 friend class AstNodeFactory;
873 friend Zone;
874
DebuggerStatement(int pos)875 explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {}
876 };
877
878
879 class EmptyStatement final : public Statement {
880 private:
881 friend class AstNodeFactory;
882 friend Zone;
EmptyStatement()883 EmptyStatement() : Statement(kNoSourcePosition, kEmptyStatement) {}
884 };
885
886
887 // Delegates to another statement, which may be overwritten.
888 // This was introduced to implement ES2015 Annex B3.3 for conditionally making
889 // sloppy-mode block-scoped functions have a var binding, which is changed
890 // from one statement to another during parsing.
891 class SloppyBlockFunctionStatement final : public Statement {
892 public:
statement()893 Statement* statement() const { return statement_; }
set_statement(Statement * statement)894 void set_statement(Statement* statement) { statement_ = statement; }
scope()895 Scope* scope() const { return var_->scope(); }
var()896 Variable* var() const { return var_; }
init()897 Token::Value init() const { return TokenField::decode(bit_field_); }
name()898 const AstRawString* name() const { return var_->raw_name(); }
next()899 SloppyBlockFunctionStatement** next() { return &next_; }
900
901 private:
902 friend class AstNodeFactory;
903 friend Zone;
904
905 using TokenField = Statement::NextBitField<Token::Value, 8>;
906
SloppyBlockFunctionStatement(int pos,Variable * var,Token::Value init,Statement * statement)907 SloppyBlockFunctionStatement(int pos, Variable* var, Token::Value init,
908 Statement* statement)
909 : Statement(pos, kSloppyBlockFunctionStatement),
910 var_(var),
911 statement_(statement),
912 next_(nullptr) {
913 bit_field_ = TokenField::update(bit_field_, init);
914 }
915
916 Variable* var_;
917 Statement* statement_;
918 SloppyBlockFunctionStatement* next_;
919 };
920
921
922 class Literal final : public Expression {
923 public:
924 enum Type {
925 kSmi,
926 kHeapNumber,
927 kBigInt,
928 kString,
929 kBoolean,
930 kUndefined,
931 kNull,
932 kTheHole,
933 };
934
type()935 Type type() const { return TypeField::decode(bit_field_); }
936
937 // Returns true if literal represents a property name (i.e. cannot be parsed
938 // as array indices).
939 bool IsPropertyName() const;
940
941 // Returns true if literal represents an array index.
942 // Note, that in general the following statement is not true:
943 // key->IsPropertyName() != key->AsArrayIndex(...)
944 // but for non-computed LiteralProperty properties the following is true:
945 // property->key()->IsPropertyName() != property->key()->AsArrayIndex(...)
946 bool AsArrayIndex(uint32_t* index) const;
947
AsRawPropertyName()948 const AstRawString* AsRawPropertyName() {
949 DCHECK(IsPropertyName());
950 return string_;
951 }
952
AsSmiLiteral()953 Smi AsSmiLiteral() const {
954 DCHECK_EQ(kSmi, type());
955 return Smi::FromInt(smi_);
956 }
957
958 // Returns true if literal represents a Number.
IsNumber()959 bool IsNumber() const { return type() == kHeapNumber || type() == kSmi; }
AsNumber()960 double AsNumber() const {
961 DCHECK(IsNumber());
962 switch (type()) {
963 case kSmi:
964 return smi_;
965 case kHeapNumber:
966 return number_;
967 default:
968 UNREACHABLE();
969 }
970 }
971
AsBigInt()972 AstBigInt AsBigInt() const {
973 DCHECK_EQ(type(), kBigInt);
974 return bigint_;
975 }
976
IsString()977 bool IsString() const { return type() == kString; }
AsRawString()978 const AstRawString* AsRawString() {
979 DCHECK_EQ(type(), kString);
980 return string_;
981 }
982
983 V8_EXPORT_PRIVATE bool ToBooleanIsTrue() const;
ToBooleanIsFalse()984 bool ToBooleanIsFalse() const { return !ToBooleanIsTrue(); }
985
986 bool ToUint32(uint32_t* value) const;
987
988 // Returns an appropriate Object representing this Literal, allocating
989 // a heap object if needed.
990 template <typename IsolateT>
991 Handle<Object> BuildValue(IsolateT* isolate) const;
992
993 // Support for using Literal as a HashMap key. NOTE: Currently, this works
994 // only for string and number literals!
995 uint32_t Hash();
996 static bool Match(void* literal1, void* literal2);
997
998 private:
999 friend class AstNodeFactory;
1000 friend Zone;
1001
1002 using TypeField = Expression::NextBitField<Type, 4>;
1003
Literal(int smi,int position)1004 Literal(int smi, int position) : Expression(position, kLiteral), smi_(smi) {
1005 bit_field_ = TypeField::update(bit_field_, kSmi);
1006 }
1007
Literal(double number,int position)1008 Literal(double number, int position)
1009 : Expression(position, kLiteral), number_(number) {
1010 bit_field_ = TypeField::update(bit_field_, kHeapNumber);
1011 }
1012
Literal(AstBigInt bigint,int position)1013 Literal(AstBigInt bigint, int position)
1014 : Expression(position, kLiteral), bigint_(bigint) {
1015 bit_field_ = TypeField::update(bit_field_, kBigInt);
1016 }
1017
Literal(const AstRawString * string,int position)1018 Literal(const AstRawString* string, int position)
1019 : Expression(position, kLiteral), string_(string) {
1020 bit_field_ = TypeField::update(bit_field_, kString);
1021 }
1022
Literal(bool boolean,int position)1023 Literal(bool boolean, int position)
1024 : Expression(position, kLiteral), boolean_(boolean) {
1025 bit_field_ = TypeField::update(bit_field_, kBoolean);
1026 }
1027
Literal(Type type,int position)1028 Literal(Type type, int position) : Expression(position, kLiteral) {
1029 DCHECK(type == kNull || type == kUndefined || type == kTheHole);
1030 bit_field_ = TypeField::update(bit_field_, type);
1031 }
1032
1033 union {
1034 const AstRawString* string_;
1035 int smi_;
1036 double number_;
1037 AstBigInt bigint_;
1038 bool boolean_;
1039 };
1040 };
1041
1042 // Base class for literals that need space in the type feedback vector.
1043 class MaterializedLiteral : public Expression {
1044 public:
1045 // A Materializedliteral is simple if the values consist of only
1046 // constants and simple object and array literals.
1047 bool IsSimple() const;
1048
1049 protected:
MaterializedLiteral(int pos,NodeType type)1050 MaterializedLiteral(int pos, NodeType type) : Expression(pos, type) {}
1051
1052 bool NeedsInitialAllocationSite();
1053
1054 friend class CompileTimeValue;
1055
1056 friend class LiteralBoilerplateBuilder;
1057 friend class ArrayLiteralBoilerplateBuilder;
1058 friend class ObjectLiteralBoilerplateBuilder;
1059 };
1060
1061 // Node for capturing a regexp literal.
1062 class RegExpLiteral final : public MaterializedLiteral {
1063 public:
pattern()1064 Handle<String> pattern() const { return pattern_->string(); }
raw_pattern()1065 const AstRawString* raw_pattern() const { return pattern_; }
flags()1066 int flags() const { return flags_; }
1067
1068 private:
1069 friend class AstNodeFactory;
1070 friend Zone;
1071
RegExpLiteral(const AstRawString * pattern,int flags,int pos)1072 RegExpLiteral(const AstRawString* pattern, int flags, int pos)
1073 : MaterializedLiteral(pos, kRegExpLiteral),
1074 flags_(flags),
1075 pattern_(pattern) {}
1076
1077 int const flags_;
1078 const AstRawString* const pattern_;
1079 };
1080
1081 // Base class for Array and Object literals
1082 class AggregateLiteral : public MaterializedLiteral {
1083 public:
1084 enum Flags {
1085 kNoFlags = 0,
1086 kIsShallow = 1,
1087 kDisableMementos = 1 << 1,
1088 kNeedsInitialAllocationSite = 1 << 2,
1089 kIsShallowAndDisableMementos = kIsShallow | kDisableMementos,
1090 };
1091
1092 protected:
AggregateLiteral(int pos,NodeType type)1093 AggregateLiteral(int pos, NodeType type) : MaterializedLiteral(pos, type) {}
1094 };
1095
1096 // Base class for build literal boilerplate, providing common code for handling
1097 // nested subliterals.
1098 class LiteralBoilerplateBuilder {
1099 public:
1100 enum DepthKind { kUninitialized, kShallow, kNotShallow };
1101
1102 static constexpr int kDepthKindBits = 2;
1103 STATIC_ASSERT((1 << kDepthKindBits) > kNotShallow);
1104
is_initialized()1105 bool is_initialized() const {
1106 return kUninitialized != DepthField::decode(bit_field_);
1107 }
depth()1108 DepthKind depth() const {
1109 DCHECK(is_initialized());
1110 return DepthField::decode(bit_field_);
1111 }
1112
1113 // If the expression is a literal, return the literal value;
1114 // if the expression is a materialized literal and is_simple
1115 // then return an Array or Object Boilerplate Description
1116 // Otherwise, return undefined literal as the placeholder
1117 // in the object literal boilerplate.
1118 template <typename IsolateT>
1119 static Handle<Object> GetBoilerplateValue(Expression* expression,
1120 IsolateT* isolate);
1121
is_shallow()1122 bool is_shallow() const { return depth() == kShallow; }
needs_initial_allocation_site()1123 bool needs_initial_allocation_site() const {
1124 return NeedsInitialAllocationSiteField::decode(bit_field_);
1125 }
1126
1127 int ComputeFlags(bool disable_mementos = false) const {
1128 int flags = AggregateLiteral::kNoFlags;
1129 if (is_shallow()) flags |= AggregateLiteral::kIsShallow;
1130 if (disable_mementos) flags |= AggregateLiteral::kDisableMementos;
1131 if (needs_initial_allocation_site())
1132 flags |= AggregateLiteral::kNeedsInitialAllocationSite;
1133 return flags;
1134 }
1135
1136 // An AggregateLiteral is simple if the values consist of only
1137 // constants and simple object and array literals.
is_simple()1138 bool is_simple() const { return IsSimpleField::decode(bit_field_); }
1139
boilerplate_descriptor_kind()1140 ElementsKind boilerplate_descriptor_kind() const {
1141 return BoilerplateDescriptorKindField::decode(bit_field_);
1142 }
1143
1144 private:
1145 // we actually only care three conditions for depth
1146 // - depth == kUninitialized, DCHECK(!is_initialized())
1147 // - depth == kShallow, which means depth = 1
1148 // - depth == kNotShallow, which means depth > 1
1149 using DepthField = base::BitField<DepthKind, 0, kDepthKindBits>;
1150 using NeedsInitialAllocationSiteField = DepthField::Next<bool, 1>;
1151 using IsSimpleField = NeedsInitialAllocationSiteField::Next<bool, 1>;
1152 using BoilerplateDescriptorKindField =
1153 IsSimpleField::Next<ElementsKind, kFastElementsKindBits>;
1154
1155 protected:
1156 uint32_t bit_field_;
1157
LiteralBoilerplateBuilder()1158 LiteralBoilerplateBuilder() {
1159 bit_field_ =
1160 DepthField::encode(kUninitialized) |
1161 NeedsInitialAllocationSiteField::encode(false) |
1162 IsSimpleField::encode(false) |
1163 BoilerplateDescriptorKindField::encode(FIRST_FAST_ELEMENTS_KIND);
1164 }
1165
set_is_simple(bool is_simple)1166 void set_is_simple(bool is_simple) {
1167 bit_field_ = IsSimpleField::update(bit_field_, is_simple);
1168 }
1169
set_boilerplate_descriptor_kind(ElementsKind kind)1170 void set_boilerplate_descriptor_kind(ElementsKind kind) {
1171 DCHECK(IsFastElementsKind(kind));
1172 bit_field_ = BoilerplateDescriptorKindField::update(bit_field_, kind);
1173 }
1174
set_depth(DepthKind depth)1175 void set_depth(DepthKind depth) {
1176 DCHECK(!is_initialized());
1177 bit_field_ = DepthField::update(bit_field_, depth);
1178 }
1179
set_needs_initial_allocation_site(bool required)1180 void set_needs_initial_allocation_site(bool required) {
1181 bit_field_ = NeedsInitialAllocationSiteField::update(bit_field_, required);
1182 }
1183
1184 // Populate the depth field and any flags the literal builder has
1185 static void InitDepthAndFlags(MaterializedLiteral* expr);
1186
1187 // Populate the constant properties/elements fixed array.
1188 template <typename IsolateT>
1189 void BuildConstants(IsolateT* isolate, MaterializedLiteral* expr);
1190
1191 template <class T, int size>
1192 using NextBitField = BoilerplateDescriptorKindField::Next<T, size>;
1193 };
1194
1195 // Common supertype for ObjectLiteralProperty and ClassLiteralProperty
1196 class LiteralProperty : public ZoneObject {
1197 public:
key()1198 Expression* key() const { return key_and_is_computed_name_.GetPointer(); }
value()1199 Expression* value() const { return value_; }
1200
is_computed_name()1201 bool is_computed_name() const {
1202 return key_and_is_computed_name_.GetPayload();
1203 }
1204 bool NeedsSetFunctionName() const;
1205
1206 protected:
LiteralProperty(Expression * key,Expression * value,bool is_computed_name)1207 LiteralProperty(Expression* key, Expression* value, bool is_computed_name)
1208 : key_and_is_computed_name_(key, is_computed_name), value_(value) {}
1209
1210 base::PointerWithPayload<Expression, bool, 1> key_and_is_computed_name_;
1211 Expression* value_;
1212 };
1213
1214 // Property is used for passing information
1215 // about an object literal's properties from the parser
1216 // to the code generator.
1217 class ObjectLiteralProperty final : public LiteralProperty {
1218 public:
1219 enum Kind : uint8_t {
1220 CONSTANT, // Property with constant value (compile time).
1221 COMPUTED, // Property with computed value (execution time).
1222 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1223 GETTER,
1224 SETTER, // Property is an accessor function.
1225 PROTOTYPE, // Property is __proto__.
1226 SPREAD
1227 };
1228
kind()1229 Kind kind() const { return kind_; }
1230
1231 bool IsCompileTimeValue() const;
1232
1233 void set_emit_store(bool emit_store);
1234 bool emit_store() const;
1235
IsNullPrototype()1236 bool IsNullPrototype() const {
1237 return IsPrototype() && value()->IsNullLiteral();
1238 }
IsPrototype()1239 bool IsPrototype() const { return kind() == PROTOTYPE; }
1240
1241 private:
1242 friend class AstNodeFactory;
1243 friend Zone;
1244
1245 ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
1246 bool is_computed_name);
1247 ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
1248 Expression* value, bool is_computed_name);
1249
1250 Kind kind_;
1251 bool emit_store_;
1252 };
1253
1254 // class for build object boilerplate
1255 class ObjectLiteralBoilerplateBuilder final : public LiteralBoilerplateBuilder {
1256 public:
1257 using Property = ObjectLiteralProperty;
1258
ObjectLiteralBoilerplateBuilder(ZoneList<Property * > * properties,uint32_t boilerplate_properties,bool has_rest_property)1259 ObjectLiteralBoilerplateBuilder(ZoneList<Property*>* properties,
1260 uint32_t boilerplate_properties,
1261 bool has_rest_property)
1262 : properties_(properties),
1263 boilerplate_properties_(boilerplate_properties) {
1264 bit_field_ |= HasElementsField::encode(false) |
1265 HasRestPropertyField::encode(has_rest_property) |
1266 FastElementsField::encode(false) |
1267 HasNullPrototypeField::encode(false);
1268 }
boilerplate_description()1269 Handle<ObjectBoilerplateDescription> boilerplate_description() const {
1270 DCHECK(!boilerplate_description_.is_null());
1271 return boilerplate_description_;
1272 }
1273 // Determines whether the {CreateShallowArrayLiteral} builtin can be used.
1274 bool IsFastCloningSupported() const;
1275
properties_count()1276 int properties_count() const { return boilerplate_properties_; }
properties()1277 const ZonePtrList<Property>* properties() const { return properties_; }
has_elements()1278 bool has_elements() const { return HasElementsField::decode(bit_field_); }
has_rest_property()1279 bool has_rest_property() const {
1280 return HasRestPropertyField::decode(bit_field_);
1281 }
fast_elements()1282 bool fast_elements() const { return FastElementsField::decode(bit_field_); }
has_null_prototype()1283 bool has_null_prototype() const {
1284 return HasNullPrototypeField::decode(bit_field_);
1285 }
1286
1287 // Populate the boilerplate description.
1288 template <typename IsolateT>
1289 void BuildBoilerplateDescription(IsolateT* isolate);
1290
1291 // Get the boilerplate description, populating it if necessary.
1292 template <typename IsolateT>
GetOrBuildBoilerplateDescription(IsolateT * isolate)1293 Handle<ObjectBoilerplateDescription> GetOrBuildBoilerplateDescription(
1294 IsolateT* isolate) {
1295 if (boilerplate_description_.is_null()) {
1296 BuildBoilerplateDescription(isolate);
1297 }
1298 return boilerplate_description_;
1299 }
1300
is_empty()1301 bool is_empty() const {
1302 DCHECK(is_initialized());
1303 return !has_elements() && properties_count() == 0 &&
1304 properties()->length() == 0;
1305 }
1306 // Assemble bitfield of flags for the CreateObjectLiteral helper.
1307 int ComputeFlags(bool disable_mementos = false) const;
1308
IsEmptyObjectLiteral()1309 bool IsEmptyObjectLiteral() const {
1310 return is_empty() && !has_null_prototype();
1311 }
1312
1313 int EncodeLiteralType();
1314
1315 // Populate the depth field and flags, returns the depth.
1316 void InitDepthAndFlags();
1317
1318 private:
1319 void InitFlagsForPendingNullPrototype(int i);
1320
set_has_elements(bool has_elements)1321 void set_has_elements(bool has_elements) {
1322 bit_field_ = HasElementsField::update(bit_field_, has_elements);
1323 }
set_fast_elements(bool fast_elements)1324 void set_fast_elements(bool fast_elements) {
1325 bit_field_ = FastElementsField::update(bit_field_, fast_elements);
1326 }
set_has_null_protoype(bool has_null_prototype)1327 void set_has_null_protoype(bool has_null_prototype) {
1328 bit_field_ = HasNullPrototypeField::update(bit_field_, has_null_prototype);
1329 }
1330 ZoneList<Property*>* properties_;
1331 uint32_t boilerplate_properties_;
1332 Handle<ObjectBoilerplateDescription> boilerplate_description_;
1333
1334 using HasElementsField = LiteralBoilerplateBuilder::NextBitField<bool, 1>;
1335 using HasRestPropertyField = HasElementsField::Next<bool, 1>;
1336 using FastElementsField = HasRestPropertyField::Next<bool, 1>;
1337 using HasNullPrototypeField = FastElementsField::Next<bool, 1>;
1338 };
1339
1340 // An object literal has a boilerplate object that is used
1341 // for minimizing the work when constructing it at runtime.
1342 class ObjectLiteral final : public AggregateLiteral {
1343 public:
1344 using Property = ObjectLiteralProperty;
1345
1346 enum Flags {
1347 kFastElements = 1 << 3,
1348 kHasNullPrototype = 1 << 4,
1349 };
1350 STATIC_ASSERT(
1351 static_cast<int>(AggregateLiteral::kNeedsInitialAllocationSite) <
1352 static_cast<int>(kFastElements));
1353
1354 // Mark all computed expressions that are bound to a key that
1355 // is shadowed by a later occurrence of the same key. For the
1356 // marked expressions, no store code is emitted.
1357 void CalculateEmitStore(Zone* zone);
1358
properties()1359 ZoneList<Property*>* properties() { return &properties_; }
1360
builder()1361 const ObjectLiteralBoilerplateBuilder* builder() const { return &builder_; }
1362
builder()1363 ObjectLiteralBoilerplateBuilder* builder() { return &builder_; }
1364
home_object()1365 Variable* home_object() const { return home_object_; }
1366
1367 private:
1368 friend class AstNodeFactory;
1369 friend Zone;
1370
ObjectLiteral(Zone * zone,const ScopedPtrList<Property> & properties,uint32_t boilerplate_properties,int pos,bool has_rest_property,Variable * home_object)1371 ObjectLiteral(Zone* zone, const ScopedPtrList<Property>& properties,
1372 uint32_t boilerplate_properties, int pos,
1373 bool has_rest_property, Variable* home_object)
1374 : AggregateLiteral(pos, kObjectLiteral),
1375 properties_(properties.ToConstVector(), zone),
1376 home_object_(home_object),
1377 builder_(&properties_, boilerplate_properties, has_rest_property) {}
1378
1379 ZoneList<Property*> properties_;
1380 Variable* home_object_;
1381 ObjectLiteralBoilerplateBuilder builder_;
1382 };
1383
1384 // class for build boilerplate for array literal, including
1385 // array_literal, spread call elements
1386 class ArrayLiteralBoilerplateBuilder final : public LiteralBoilerplateBuilder {
1387 public:
ArrayLiteralBoilerplateBuilder(const ZonePtrList<Expression> * values,int first_spread_index)1388 ArrayLiteralBoilerplateBuilder(const ZonePtrList<Expression>* values,
1389 int first_spread_index)
1390 : values_(values), first_spread_index_(first_spread_index) {}
boilerplate_description()1391 Handle<ArrayBoilerplateDescription> boilerplate_description() const {
1392 return boilerplate_description_;
1393 }
1394
1395 // Determines whether the {CreateShallowArrayLiteral} builtin can be used.
1396 bool IsFastCloningSupported() const;
1397
1398 // Assemble bitfield of flags for the CreateArrayLiteral helper.
1399 int ComputeFlags(bool disable_mementos = false) const {
1400 return LiteralBoilerplateBuilder::ComputeFlags(disable_mementos);
1401 }
1402
first_spread_index()1403 int first_spread_index() const { return first_spread_index_; }
1404
1405 // Populate the depth field and flags
1406 void InitDepthAndFlags();
1407
1408 // Get the boilerplate description, populating it if necessary.
1409 template <typename IsolateT>
GetOrBuildBoilerplateDescription(IsolateT * isolate)1410 Handle<ArrayBoilerplateDescription> GetOrBuildBoilerplateDescription(
1411 IsolateT* isolate) {
1412 if (boilerplate_description_.is_null()) {
1413 BuildBoilerplateDescription(isolate);
1414 }
1415 return boilerplate_description_;
1416 }
1417
1418 // Populate the boilerplate description.
1419 template <typename IsolateT>
1420 void BuildBoilerplateDescription(IsolateT* isolate);
1421
1422 const ZonePtrList<Expression>* values_;
1423 int first_spread_index_;
1424 Handle<ArrayBoilerplateDescription> boilerplate_description_;
1425 };
1426
1427 // An array literal has a literals object that is used
1428 // for minimizing the work when constructing it at runtime.
1429 class ArrayLiteral final : public AggregateLiteral {
1430 public:
values()1431 const ZonePtrList<Expression>* values() const { return &values_; }
1432
builder()1433 const ArrayLiteralBoilerplateBuilder* builder() const { return &builder_; }
builder()1434 ArrayLiteralBoilerplateBuilder* builder() { return &builder_; }
1435
1436 private:
1437 friend class AstNodeFactory;
1438 friend Zone;
1439
ArrayLiteral(Zone * zone,const ScopedPtrList<Expression> & values,int first_spread_index,int pos)1440 ArrayLiteral(Zone* zone, const ScopedPtrList<Expression>& values,
1441 int first_spread_index, int pos)
1442 : AggregateLiteral(pos, kArrayLiteral),
1443 values_(values.ToConstVector(), zone),
1444 builder_(&values_, first_spread_index) {}
1445
1446 ZonePtrList<Expression> values_;
1447 ArrayLiteralBoilerplateBuilder builder_;
1448 };
1449
1450 enum class HoleCheckMode { kRequired, kElided };
1451
1452 class ThisExpression final : public Expression {
1453 private:
1454 friend class AstNodeFactory;
1455 friend Zone;
ThisExpression(int pos)1456 explicit ThisExpression(int pos) : Expression(pos, kThisExpression) {}
1457 };
1458
1459 class VariableProxy final : public Expression {
1460 public:
IsValidReferenceExpression()1461 bool IsValidReferenceExpression() const { return !is_new_target(); }
1462
name()1463 Handle<String> name() const { return raw_name()->string(); }
raw_name()1464 const AstRawString* raw_name() const {
1465 return is_resolved() ? var_->raw_name() : raw_name_;
1466 }
1467
var()1468 Variable* var() const {
1469 DCHECK(is_resolved());
1470 return var_;
1471 }
set_var(Variable * v)1472 void set_var(Variable* v) {
1473 DCHECK(!is_resolved());
1474 DCHECK_NOT_NULL(v);
1475 var_ = v;
1476 }
1477
location()1478 Scanner::Location location() {
1479 return Scanner::Location(position(), position() + raw_name()->length());
1480 }
1481
is_assigned()1482 bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
set_is_assigned()1483 void set_is_assigned() {
1484 bit_field_ = IsAssignedField::update(bit_field_, true);
1485 if (is_resolved()) {
1486 var()->SetMaybeAssigned();
1487 }
1488 }
clear_is_assigned()1489 void clear_is_assigned() {
1490 bit_field_ = IsAssignedField::update(bit_field_, false);
1491 }
1492
is_resolved()1493 bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
set_is_resolved()1494 void set_is_resolved() {
1495 bit_field_ = IsResolvedField::update(bit_field_, true);
1496 }
1497
is_new_target()1498 bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
set_is_new_target()1499 void set_is_new_target() {
1500 bit_field_ = IsNewTargetField::update(bit_field_, true);
1501 }
1502
hole_check_mode()1503 HoleCheckMode hole_check_mode() const {
1504 HoleCheckMode mode = HoleCheckModeField::decode(bit_field_);
1505 DCHECK_IMPLIES(mode == HoleCheckMode::kRequired,
1506 var()->binding_needs_init() ||
1507 var()->local_if_not_shadowed()->binding_needs_init());
1508 return mode;
1509 }
set_needs_hole_check()1510 void set_needs_hole_check() {
1511 bit_field_ =
1512 HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
1513 }
1514
IsPrivateName()1515 bool IsPrivateName() const { return raw_name()->IsPrivateName(); }
1516
1517 // Bind this proxy to the variable var.
1518 void BindTo(Variable* var);
1519
next_unresolved()1520 V8_INLINE VariableProxy* next_unresolved() { return next_unresolved_; }
is_removed_from_unresolved()1521 V8_INLINE bool is_removed_from_unresolved() const {
1522 return IsRemovedFromUnresolvedField::decode(bit_field_);
1523 }
1524
mark_removed_from_unresolved()1525 void mark_removed_from_unresolved() {
1526 bit_field_ = IsRemovedFromUnresolvedField::update(bit_field_, true);
1527 }
1528
1529 // Provides filtered access to the unresolved variable proxy threaded list.
1530 struct UnresolvedNext {
filterUnresolvedNext1531 static VariableProxy** filter(VariableProxy** t) {
1532 VariableProxy** n = t;
1533 // Skip over possibly removed values.
1534 while (*n != nullptr && (*n)->is_removed_from_unresolved()) {
1535 n = (*n)->next();
1536 }
1537 return n;
1538 }
1539
startUnresolvedNext1540 static VariableProxy** start(VariableProxy** head) { return filter(head); }
1541
nextUnresolvedNext1542 static VariableProxy** next(VariableProxy* t) { return filter(t->next()); }
1543 };
1544
1545 private:
1546 friend class AstNodeFactory;
1547 friend Zone;
1548
1549 VariableProxy(Variable* var, int start_position);
1550
VariableProxy(const AstRawString * name,VariableKind variable_kind,int start_position)1551 VariableProxy(const AstRawString* name, VariableKind variable_kind,
1552 int start_position)
1553 : Expression(start_position, kVariableProxy),
1554 raw_name_(name),
1555 next_unresolved_(nullptr) {
1556 DCHECK_NE(THIS_VARIABLE, variable_kind);
1557 bit_field_ |= IsAssignedField::encode(false) |
1558 IsResolvedField::encode(false) |
1559 IsRemovedFromUnresolvedField::encode(false) |
1560 HoleCheckModeField::encode(HoleCheckMode::kElided);
1561 }
1562
1563 explicit VariableProxy(const VariableProxy* copy_from);
1564
1565 using IsAssignedField = Expression::NextBitField<bool, 1>;
1566 using IsResolvedField = IsAssignedField::Next<bool, 1>;
1567 using IsRemovedFromUnresolvedField = IsResolvedField::Next<bool, 1>;
1568 using IsNewTargetField = IsRemovedFromUnresolvedField::Next<bool, 1>;
1569 using HoleCheckModeField = IsNewTargetField::Next<HoleCheckMode, 1>;
1570
1571 union {
1572 const AstRawString* raw_name_; // if !is_resolved_
1573 Variable* var_; // if is_resolved_
1574 };
1575
next()1576 V8_INLINE VariableProxy** next() { return &next_unresolved_; }
1577 VariableProxy* next_unresolved_;
1578
1579 friend base::ThreadedListTraits<VariableProxy>;
1580 };
1581
1582 // Wraps an optional chain to provide a wrapper for jump labels.
1583 class OptionalChain final : public Expression {
1584 public:
expression()1585 Expression* expression() const { return expression_; }
1586
1587 private:
1588 friend class AstNodeFactory;
1589 friend Zone;
1590
OptionalChain(Expression * expression)1591 explicit OptionalChain(Expression* expression)
1592 : Expression(0, kOptionalChain), expression_(expression) {}
1593
1594 Expression* expression_;
1595 };
1596
1597 // Assignments to a property will use one of several types of property access.
1598 // Otherwise, the assignment is to a non-property (a global, a local slot, a
1599 // parameter slot, or a destructuring pattern).
1600 enum AssignType {
1601 NON_PROPERTY, // destructuring
1602 NAMED_PROPERTY, // obj.key
1603 KEYED_PROPERTY, // obj[key] and obj.#key when #key is a private field
1604 NAMED_SUPER_PROPERTY, // super.key
1605 KEYED_SUPER_PROPERTY, // super[key]
1606 PRIVATE_METHOD, // obj.#key: #key is a private method
1607 PRIVATE_GETTER_ONLY, // obj.#key: #key only has a getter defined
1608 PRIVATE_SETTER_ONLY, // obj.#key: #key only has a setter defined
1609 PRIVATE_GETTER_AND_SETTER // obj.#key: #key has both accessors defined
1610 };
1611
1612 class Property final : public Expression {
1613 public:
is_optional_chain_link()1614 bool is_optional_chain_link() const {
1615 return IsOptionalChainLinkField::decode(bit_field_);
1616 }
1617
IsValidReferenceExpression()1618 bool IsValidReferenceExpression() const { return true; }
1619
obj()1620 Expression* obj() const { return obj_; }
key()1621 Expression* key() const { return key_; }
1622
IsSuperAccess()1623 bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
IsPrivateReference()1624 bool IsPrivateReference() const { return key()->IsPrivateName(); }
1625
1626 // Returns the properties assign type.
GetAssignType(Property * property)1627 static AssignType GetAssignType(Property* property) {
1628 if (property == nullptr) return NON_PROPERTY;
1629 if (property->IsPrivateReference()) {
1630 DCHECK(!property->IsSuperAccess());
1631 VariableProxy* proxy = property->key()->AsVariableProxy();
1632 DCHECK_NOT_NULL(proxy);
1633 Variable* var = proxy->var();
1634
1635 switch (var->mode()) {
1636 case VariableMode::kPrivateMethod:
1637 return PRIVATE_METHOD;
1638 case VariableMode::kConst:
1639 return KEYED_PROPERTY; // Use KEYED_PROPERTY for private fields.
1640 case VariableMode::kPrivateGetterOnly:
1641 return PRIVATE_GETTER_ONLY;
1642 case VariableMode::kPrivateSetterOnly:
1643 return PRIVATE_SETTER_ONLY;
1644 case VariableMode::kPrivateGetterAndSetter:
1645 return PRIVATE_GETTER_AND_SETTER;
1646 default:
1647 UNREACHABLE();
1648 }
1649 }
1650 bool super_access = property->IsSuperAccess();
1651 return (property->key()->IsPropertyName())
1652 ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
1653 : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
1654 }
1655
1656 private:
1657 friend class AstNodeFactory;
1658 friend Zone;
1659
Property(Expression * obj,Expression * key,int pos,bool optional_chain)1660 Property(Expression* obj, Expression* key, int pos, bool optional_chain)
1661 : Expression(pos, kProperty), obj_(obj), key_(key) {
1662 bit_field_ |= IsOptionalChainLinkField::encode(optional_chain);
1663 }
1664
1665 using IsOptionalChainLinkField = Expression::NextBitField<bool, 1>;
1666
1667 Expression* obj_;
1668 Expression* key_;
1669 };
1670
1671 class CallBase : public Expression {
1672 public:
expression()1673 Expression* expression() const { return expression_; }
arguments()1674 const ZonePtrList<Expression>* arguments() const { return &arguments_; }
1675
1676 enum SpreadPosition { kNoSpread, kHasFinalSpread, kHasNonFinalSpread };
spread_position()1677 SpreadPosition spread_position() const {
1678 return SpreadPositionField::decode(bit_field_);
1679 }
1680
1681 protected:
CallBase(Zone * zone,NodeType type,Expression * expression,const ScopedPtrList<Expression> & arguments,int pos,bool has_spread)1682 CallBase(Zone* zone, NodeType type, Expression* expression,
1683 const ScopedPtrList<Expression>& arguments, int pos, bool has_spread)
1684 : Expression(pos, type),
1685 expression_(expression),
1686 arguments_(arguments.ToConstVector(), zone) {
1687 DCHECK(type == kCall || type == kCallNew);
1688 if (has_spread) {
1689 ComputeSpreadPosition();
1690 } else {
1691 bit_field_ |= SpreadPositionField::encode(kNoSpread);
1692 }
1693 }
1694
1695 // Only valid to be called if there is a spread in arguments_.
1696 void ComputeSpreadPosition();
1697
1698 using SpreadPositionField = Expression::NextBitField<SpreadPosition, 2>;
1699
1700 template <class T, int size>
1701 using NextBitField = SpreadPositionField::Next<T, size>;
1702
1703 Expression* expression_;
1704 ZonePtrList<Expression> arguments_;
1705 };
1706
1707 class Call final : public CallBase {
1708 public:
is_possibly_eval()1709 bool is_possibly_eval() const {
1710 return IsPossiblyEvalField::decode(bit_field_);
1711 }
1712
is_tagged_template()1713 bool is_tagged_template() const {
1714 return IsTaggedTemplateField::decode(bit_field_);
1715 }
1716
is_optional_chain_link()1717 bool is_optional_chain_link() const {
1718 return IsOptionalChainLinkField::decode(bit_field_);
1719 }
1720
1721 enum CallType {
1722 GLOBAL_CALL,
1723 WITH_CALL,
1724 NAMED_PROPERTY_CALL,
1725 KEYED_PROPERTY_CALL,
1726 NAMED_OPTIONAL_CHAIN_PROPERTY_CALL,
1727 KEYED_OPTIONAL_CHAIN_PROPERTY_CALL,
1728 NAMED_SUPER_PROPERTY_CALL,
1729 KEYED_SUPER_PROPERTY_CALL,
1730 PRIVATE_CALL,
1731 PRIVATE_OPTIONAL_CHAIN_CALL,
1732 SUPER_CALL,
1733 OTHER_CALL,
1734 };
1735
1736 enum PossiblyEval {
1737 IS_POSSIBLY_EVAL,
1738 NOT_EVAL,
1739 };
1740
1741 // Helpers to determine how to handle the call.
1742 CallType GetCallType() const;
1743
1744 enum class TaggedTemplateTag { kTrue };
1745
1746 private:
1747 friend class AstNodeFactory;
1748 friend Zone;
1749
Call(Zone * zone,Expression * expression,const ScopedPtrList<Expression> & arguments,int pos,bool has_spread,PossiblyEval possibly_eval,bool optional_chain)1750 Call(Zone* zone, Expression* expression,
1751 const ScopedPtrList<Expression>& arguments, int pos, bool has_spread,
1752 PossiblyEval possibly_eval, bool optional_chain)
1753 : CallBase(zone, kCall, expression, arguments, pos, has_spread) {
1754 bit_field_ |=
1755 IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL) |
1756 IsTaggedTemplateField::encode(false) |
1757 IsOptionalChainLinkField::encode(optional_chain);
1758 }
1759
Call(Zone * zone,Expression * expression,const ScopedPtrList<Expression> & arguments,int pos,TaggedTemplateTag tag)1760 Call(Zone* zone, Expression* expression,
1761 const ScopedPtrList<Expression>& arguments, int pos,
1762 TaggedTemplateTag tag)
1763 : CallBase(zone, kCall, expression, arguments, pos, false) {
1764 bit_field_ |= IsPossiblyEvalField::encode(false) |
1765 IsTaggedTemplateField::encode(true) |
1766 IsOptionalChainLinkField::encode(false);
1767 }
1768
1769 using IsPossiblyEvalField = CallBase::NextBitField<bool, 1>;
1770 using IsTaggedTemplateField = IsPossiblyEvalField::Next<bool, 1>;
1771 using IsOptionalChainLinkField = IsTaggedTemplateField::Next<bool, 1>;
1772 };
1773
1774 class CallNew final : public CallBase {
1775 private:
1776 friend class AstNodeFactory;
1777 friend Zone;
1778
CallNew(Zone * zone,Expression * expression,const ScopedPtrList<Expression> & arguments,int pos,bool has_spread)1779 CallNew(Zone* zone, Expression* expression,
1780 const ScopedPtrList<Expression>& arguments, int pos, bool has_spread)
1781 : CallBase(zone, kCallNew, expression, arguments, pos, has_spread) {}
1782 };
1783
1784 // The CallRuntime class does not represent any official JavaScript
1785 // language construct. Instead it is used to call a C or JS function
1786 // with a set of arguments. This is used from the builtins that are
1787 // implemented in JavaScript.
1788 class CallRuntime final : public Expression {
1789 public:
arguments()1790 const ZonePtrList<Expression>* arguments() const { return &arguments_; }
is_jsruntime()1791 bool is_jsruntime() const { return function_ == nullptr; }
1792
context_index()1793 int context_index() const {
1794 DCHECK(is_jsruntime());
1795 return context_index_;
1796 }
function()1797 const Runtime::Function* function() const {
1798 DCHECK(!is_jsruntime());
1799 return function_;
1800 }
1801
1802 const char* debug_name();
1803
1804 private:
1805 friend class AstNodeFactory;
1806 friend Zone;
1807
CallRuntime(Zone * zone,const Runtime::Function * function,const ScopedPtrList<Expression> & arguments,int pos)1808 CallRuntime(Zone* zone, const Runtime::Function* function,
1809 const ScopedPtrList<Expression>& arguments, int pos)
1810 : Expression(pos, kCallRuntime),
1811 function_(function),
1812 arguments_(arguments.ToConstVector(), zone) {}
CallRuntime(Zone * zone,int context_index,const ScopedPtrList<Expression> & arguments,int pos)1813 CallRuntime(Zone* zone, int context_index,
1814 const ScopedPtrList<Expression>& arguments, int pos)
1815 : Expression(pos, kCallRuntime),
1816 context_index_(context_index),
1817 function_(nullptr),
1818 arguments_(arguments.ToConstVector(), zone) {}
1819
1820 int context_index_;
1821 const Runtime::Function* function_;
1822 ZonePtrList<Expression> arguments_;
1823 };
1824
1825
1826 class UnaryOperation final : public Expression {
1827 public:
op()1828 Token::Value op() const { return OperatorField::decode(bit_field_); }
expression()1829 Expression* expression() const { return expression_; }
1830
1831 private:
1832 friend class AstNodeFactory;
1833 friend Zone;
1834
UnaryOperation(Token::Value op,Expression * expression,int pos)1835 UnaryOperation(Token::Value op, Expression* expression, int pos)
1836 : Expression(pos, kUnaryOperation), expression_(expression) {
1837 bit_field_ |= OperatorField::encode(op);
1838 DCHECK(Token::IsUnaryOp(op));
1839 }
1840
1841 Expression* expression_;
1842
1843 using OperatorField = Expression::NextBitField<Token::Value, 7>;
1844 };
1845
1846
1847 class BinaryOperation final : public Expression {
1848 public:
op()1849 Token::Value op() const { return OperatorField::decode(bit_field_); }
left()1850 Expression* left() const { return left_; }
right()1851 Expression* right() const { return right_; }
1852
1853 // Returns true if one side is a Smi literal, returning the other side's
1854 // sub-expression in |subexpr| and the literal Smi in |literal|.
1855 bool IsSmiLiteralOperation(Expression** subexpr, Smi* literal);
1856
1857 private:
1858 friend class AstNodeFactory;
1859 friend Zone;
1860
BinaryOperation(Token::Value op,Expression * left,Expression * right,int pos)1861 BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
1862 : Expression(pos, kBinaryOperation), left_(left), right_(right) {
1863 bit_field_ |= OperatorField::encode(op);
1864 DCHECK(Token::IsBinaryOp(op));
1865 }
1866
1867 Expression* left_;
1868 Expression* right_;
1869
1870 using OperatorField = Expression::NextBitField<Token::Value, 7>;
1871 };
1872
1873 class NaryOperation final : public Expression {
1874 public:
op()1875 Token::Value op() const { return OperatorField::decode(bit_field_); }
first()1876 Expression* first() const { return first_; }
subsequent(size_t index)1877 Expression* subsequent(size_t index) const {
1878 return subsequent_[index].expression;
1879 }
1880
subsequent_length()1881 size_t subsequent_length() const { return subsequent_.size(); }
subsequent_op_position(size_t index)1882 int subsequent_op_position(size_t index) const {
1883 return subsequent_[index].op_position;
1884 }
1885
AddSubsequent(Expression * expr,int pos)1886 void AddSubsequent(Expression* expr, int pos) {
1887 subsequent_.emplace_back(expr, pos);
1888 }
1889
1890 private:
1891 friend class AstNodeFactory;
1892 friend Zone;
1893
NaryOperation(Zone * zone,Token::Value op,Expression * first,size_t initial_subsequent_size)1894 NaryOperation(Zone* zone, Token::Value op, Expression* first,
1895 size_t initial_subsequent_size)
1896 : Expression(first->position(), kNaryOperation),
1897 first_(first),
1898 subsequent_(zone) {
1899 bit_field_ |= OperatorField::encode(op);
1900 DCHECK(Token::IsBinaryOp(op));
1901 DCHECK_NE(op, Token::EXP);
1902 subsequent_.reserve(initial_subsequent_size);
1903 }
1904
1905 // Nary operations store the first (lhs) child expression inline, and the
1906 // child expressions (rhs of each op) are stored out-of-line, along with
1907 // their operation's position. Note that the Nary operation expression's
1908 // position has no meaning.
1909 //
1910 // So an nary add:
1911 //
1912 // expr + expr + expr + ...
1913 //
1914 // is stored as:
1915 //
1916 // (expr) [(+ expr), (+ expr), ...]
1917 // '-.--' '-----------.-----------'
1918 // first subsequent entry list
1919
1920 Expression* first_;
1921
1922 struct NaryOperationEntry {
1923 Expression* expression;
1924 int op_position;
NaryOperationEntryNaryOperationEntry1925 NaryOperationEntry(Expression* e, int pos)
1926 : expression(e), op_position(pos) {}
1927 };
1928 ZoneVector<NaryOperationEntry> subsequent_;
1929
1930 using OperatorField = Expression::NextBitField<Token::Value, 7>;
1931 };
1932
1933 class CountOperation final : public Expression {
1934 public:
is_prefix()1935 bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
is_postfix()1936 bool is_postfix() const { return !is_prefix(); }
1937
op()1938 Token::Value op() const { return TokenField::decode(bit_field_); }
1939
expression()1940 Expression* expression() const { return expression_; }
1941
1942 private:
1943 friend class AstNodeFactory;
1944 friend Zone;
1945
CountOperation(Token::Value op,bool is_prefix,Expression * expr,int pos)1946 CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
1947 : Expression(pos, kCountOperation), expression_(expr) {
1948 bit_field_ |= IsPrefixField::encode(is_prefix) | TokenField::encode(op);
1949 }
1950
1951 using IsPrefixField = Expression::NextBitField<bool, 1>;
1952 using TokenField = IsPrefixField::Next<Token::Value, 7>;
1953
1954 Expression* expression_;
1955 };
1956
1957
1958 class CompareOperation final : public Expression {
1959 public:
op()1960 Token::Value op() const { return OperatorField::decode(bit_field_); }
left()1961 Expression* left() const { return left_; }
right()1962 Expression* right() const { return right_; }
1963
1964 // Match special cases.
1965 bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
1966 bool IsLiteralCompareUndefined(Expression** expr);
1967 bool IsLiteralCompareNull(Expression** expr);
1968
1969 private:
1970 friend class AstNodeFactory;
1971 friend Zone;
1972
CompareOperation(Token::Value op,Expression * left,Expression * right,int pos)1973 CompareOperation(Token::Value op, Expression* left, Expression* right,
1974 int pos)
1975 : Expression(pos, kCompareOperation), left_(left), right_(right) {
1976 bit_field_ |= OperatorField::encode(op);
1977 DCHECK(Token::IsCompareOp(op));
1978 }
1979
1980 Expression* left_;
1981 Expression* right_;
1982
1983 using OperatorField = Expression::NextBitField<Token::Value, 7>;
1984 };
1985
1986
1987 class Spread final : public Expression {
1988 public:
expression()1989 Expression* expression() const { return expression_; }
1990
expression_position()1991 int expression_position() const { return expr_pos_; }
1992
1993 private:
1994 friend class AstNodeFactory;
1995 friend Zone;
1996
Spread(Expression * expression,int pos,int expr_pos)1997 Spread(Expression* expression, int pos, int expr_pos)
1998 : Expression(pos, kSpread),
1999 expr_pos_(expr_pos),
2000 expression_(expression) {}
2001
2002 int expr_pos_;
2003 Expression* expression_;
2004 };
2005
2006 class Conditional final : public Expression {
2007 public:
condition()2008 Expression* condition() const { return condition_; }
then_expression()2009 Expression* then_expression() const { return then_expression_; }
else_expression()2010 Expression* else_expression() const { return else_expression_; }
2011
2012 private:
2013 friend class AstNodeFactory;
2014 friend Zone;
2015
Conditional(Expression * condition,Expression * then_expression,Expression * else_expression,int position)2016 Conditional(Expression* condition, Expression* then_expression,
2017 Expression* else_expression, int position)
2018 : Expression(position, kConditional),
2019 condition_(condition),
2020 then_expression_(then_expression),
2021 else_expression_(else_expression) {}
2022
2023 Expression* condition_;
2024 Expression* then_expression_;
2025 Expression* else_expression_;
2026 };
2027
2028 class Assignment : public Expression {
2029 public:
op()2030 Token::Value op() const { return TokenField::decode(bit_field_); }
target()2031 Expression* target() const { return target_; }
value()2032 Expression* value() const { return value_; }
2033
2034 // The assignment was generated as part of block-scoped sloppy-mode
2035 // function hoisting, see
2036 // ES#sec-block-level-function-declarations-web-legacy-compatibility-semantics
lookup_hoisting_mode()2037 LookupHoistingMode lookup_hoisting_mode() const {
2038 return static_cast<LookupHoistingMode>(
2039 LookupHoistingModeField::decode(bit_field_));
2040 }
set_lookup_hoisting_mode(LookupHoistingMode mode)2041 void set_lookup_hoisting_mode(LookupHoistingMode mode) {
2042 bit_field_ =
2043 LookupHoistingModeField::update(bit_field_, static_cast<bool>(mode));
2044 }
2045
2046 protected:
2047 Assignment(NodeType type, Token::Value op, Expression* target,
2048 Expression* value, int pos);
2049
2050 private:
2051 friend class AstNodeFactory;
2052 friend Zone;
2053
2054 using TokenField = Expression::NextBitField<Token::Value, 7>;
2055 using LookupHoistingModeField = TokenField::Next<bool, 1>;
2056
2057 Expression* target_;
2058 Expression* value_;
2059 };
2060
2061 class CompoundAssignment final : public Assignment {
2062 public:
binary_operation()2063 BinaryOperation* binary_operation() const { return binary_operation_; }
2064
2065 private:
2066 friend class AstNodeFactory;
2067 friend Zone;
2068
CompoundAssignment(Token::Value op,Expression * target,Expression * value,int pos,BinaryOperation * binary_operation)2069 CompoundAssignment(Token::Value op, Expression* target, Expression* value,
2070 int pos, BinaryOperation* binary_operation)
2071 : Assignment(kCompoundAssignment, op, target, value, pos),
2072 binary_operation_(binary_operation) {}
2073
2074 BinaryOperation* binary_operation_;
2075 };
2076
2077 // There are several types of Suspend node:
2078 //
2079 // Yield
2080 // YieldStar
2081 // Await
2082 //
2083 // Our Yield is different from the JS yield in that it "returns" its argument as
2084 // is, without wrapping it in an iterator result object. Such wrapping, if
2085 // desired, must be done beforehand (see the parser).
2086 class Suspend : public Expression {
2087 public:
2088 // With {kNoControl}, the {Suspend} behaves like yield, except that it never
2089 // throws and never causes the current generator to return. This is used to
2090 // desugar yield*.
2091 // TODO(caitp): remove once yield* desugaring for async generators is handled
2092 // in BytecodeGenerator.
2093 enum OnAbruptResume { kOnExceptionThrow, kNoControl };
2094
expression()2095 Expression* expression() const { return expression_; }
on_abrupt_resume()2096 OnAbruptResume on_abrupt_resume() const {
2097 return OnAbruptResumeField::decode(bit_field_);
2098 }
2099
2100 private:
2101 friend class AstNodeFactory;
2102 friend Zone;
2103 friend class Yield;
2104 friend class YieldStar;
2105 friend class Await;
2106
Suspend(NodeType node_type,Expression * expression,int pos,OnAbruptResume on_abrupt_resume)2107 Suspend(NodeType node_type, Expression* expression, int pos,
2108 OnAbruptResume on_abrupt_resume)
2109 : Expression(pos, node_type), expression_(expression) {
2110 bit_field_ |= OnAbruptResumeField::encode(on_abrupt_resume);
2111 }
2112
2113 Expression* expression_;
2114
2115 using OnAbruptResumeField = Expression::NextBitField<OnAbruptResume, 1>;
2116 };
2117
2118 class Yield final : public Suspend {
2119 private:
2120 friend class AstNodeFactory;
2121 friend Zone;
Yield(Expression * expression,int pos,OnAbruptResume on_abrupt_resume)2122 Yield(Expression* expression, int pos, OnAbruptResume on_abrupt_resume)
2123 : Suspend(kYield, expression, pos, on_abrupt_resume) {}
2124 };
2125
2126 class YieldStar final : public Suspend {
2127 private:
2128 friend class AstNodeFactory;
2129 friend Zone;
YieldStar(Expression * expression,int pos)2130 YieldStar(Expression* expression, int pos)
2131 : Suspend(kYieldStar, expression, pos,
2132 Suspend::OnAbruptResume::kNoControl) {}
2133 };
2134
2135 class Await final : public Suspend {
2136 private:
2137 friend class AstNodeFactory;
2138 friend Zone;
2139
Await(Expression * expression,int pos)2140 Await(Expression* expression, int pos)
2141 : Suspend(kAwait, expression, pos, Suspend::kOnExceptionThrow) {}
2142 };
2143
2144 class Throw final : public Expression {
2145 public:
exception()2146 Expression* exception() const { return exception_; }
2147
2148 private:
2149 friend class AstNodeFactory;
2150 friend Zone;
2151
Throw(Expression * exception,int pos)2152 Throw(Expression* exception, int pos)
2153 : Expression(pos, kThrow), exception_(exception) {}
2154
2155 Expression* exception_;
2156 };
2157
2158
2159 class FunctionLiteral final : public Expression {
2160 public:
2161 enum ParameterFlag : uint8_t {
2162 kNoDuplicateParameters,
2163 kHasDuplicateParameters
2164 };
2165 enum EagerCompileHint : uint8_t { kShouldEagerCompile, kShouldLazyCompile };
2166
2167 // Empty handle means that the function does not have a shared name (i.e.
2168 // the name will be set dynamically after creation of the function closure).
2169 template <typename IsolateT>
GetName(IsolateT * isolate)2170 MaybeHandle<String> GetName(IsolateT* isolate) const {
2171 return raw_name_ ? raw_name_->AllocateFlat(isolate) : MaybeHandle<String>();
2172 }
has_shared_name()2173 bool has_shared_name() const { return raw_name_ != nullptr; }
raw_name()2174 const AstConsString* raw_name() const { return raw_name_; }
set_raw_name(const AstConsString * name)2175 void set_raw_name(const AstConsString* name) { raw_name_ = name; }
scope()2176 DeclarationScope* scope() const { return scope_; }
body()2177 ZonePtrList<Statement>* body() { return &body_; }
set_function_token_position(int pos)2178 void set_function_token_position(int pos) { function_token_position_ = pos; }
function_token_position()2179 int function_token_position() const { return function_token_position_; }
2180 int start_position() const;
2181 int end_position() const;
is_anonymous_expression()2182 bool is_anonymous_expression() const {
2183 return syntax_kind() == FunctionSyntaxKind::kAnonymousExpression;
2184 }
2185
is_toplevel()2186 bool is_toplevel() const {
2187 return function_literal_id() == kFunctionLiteralIdTopLevel;
2188 }
2189 V8_EXPORT_PRIVATE LanguageMode language_mode() const;
2190
add_expected_properties(int number_properties)2191 void add_expected_properties(int number_properties) {
2192 expected_property_count_ += number_properties;
2193 }
expected_property_count()2194 int expected_property_count() { return expected_property_count_; }
parameter_count()2195 int parameter_count() { return parameter_count_; }
function_length()2196 int function_length() { return function_length_; }
2197
2198 bool AllowsLazyCompilation();
2199
CanSuspend()2200 bool CanSuspend() {
2201 if (suspend_count() > 0) {
2202 DCHECK(IsResumableFunction(kind()));
2203 return true;
2204 }
2205 return false;
2206 }
2207
2208 // Returns either name or inferred name as a cstring.
2209 std::unique_ptr<char[]> GetDebugName() const;
2210
GetInferredName(Isolate * isolate)2211 Handle<String> GetInferredName(Isolate* isolate) {
2212 if (!inferred_name_.is_null()) {
2213 DCHECK_NULL(raw_inferred_name_);
2214 return inferred_name_;
2215 }
2216 if (raw_inferred_name_ != nullptr) {
2217 return raw_inferred_name_->GetString(isolate);
2218 }
2219 UNREACHABLE();
2220 }
GetInferredName(LocalIsolate * isolate)2221 Handle<String> GetInferredName(LocalIsolate* isolate) const {
2222 DCHECK(inferred_name_.is_null());
2223 DCHECK_NOT_NULL(raw_inferred_name_);
2224 return raw_inferred_name_->GetString(isolate);
2225 }
raw_inferred_name()2226 const AstConsString* raw_inferred_name() { return raw_inferred_name_; }
2227
2228 // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2229 void set_inferred_name(Handle<String> inferred_name);
2230 void set_raw_inferred_name(AstConsString* raw_inferred_name);
2231
pretenure()2232 bool pretenure() const { return Pretenure::decode(bit_field_); }
set_pretenure()2233 void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
2234
has_duplicate_parameters()2235 bool has_duplicate_parameters() const {
2236 // Not valid for lazy functions.
2237 DCHECK(ShouldEagerCompile());
2238 return HasDuplicateParameters::decode(bit_field_);
2239 }
2240
should_parallel_compile()2241 bool should_parallel_compile() const {
2242 return ShouldParallelCompileField::decode(bit_field_);
2243 }
set_should_parallel_compile()2244 void set_should_parallel_compile() {
2245 bit_field_ = ShouldParallelCompileField::update(bit_field_, true);
2246 }
2247
2248 // This is used as a heuristic on when to eagerly compile a function
2249 // literal. We consider the following constructs as hints that the
2250 // function will be called immediately:
2251 // - (function() { ... })();
2252 // - var x = function() { ... }();
2253 V8_EXPORT_PRIVATE bool ShouldEagerCompile() const;
2254 V8_EXPORT_PRIVATE void SetShouldEagerCompile();
2255
syntax_kind()2256 FunctionSyntaxKind syntax_kind() const {
2257 return FunctionSyntaxKindBits::decode(bit_field_);
2258 }
2259 FunctionKind kind() const;
2260
IsAnonymousFunctionDefinition()2261 bool IsAnonymousFunctionDefinition() const {
2262 return is_anonymous_expression();
2263 }
2264
suspend_count()2265 int suspend_count() { return suspend_count_; }
set_suspend_count(int suspend_count)2266 void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
2267
return_position()2268 int return_position() {
2269 return std::max(
2270 start_position(),
2271 end_position() - (HasBracesField::decode(bit_field_) ? 1 : 0));
2272 }
2273
function_literal_id()2274 int function_literal_id() const { return function_literal_id_; }
set_function_literal_id(int function_literal_id)2275 void set_function_literal_id(int function_literal_id) {
2276 function_literal_id_ = function_literal_id;
2277 }
2278
set_requires_instance_members_initializer(bool value)2279 void set_requires_instance_members_initializer(bool value) {
2280 bit_field_ = RequiresInstanceMembersInitializer::update(bit_field_, value);
2281 }
requires_instance_members_initializer()2282 bool requires_instance_members_initializer() const {
2283 return RequiresInstanceMembersInitializer::decode(bit_field_);
2284 }
2285
set_has_static_private_methods_or_accessors(bool value)2286 void set_has_static_private_methods_or_accessors(bool value) {
2287 bit_field_ =
2288 HasStaticPrivateMethodsOrAccessorsField::update(bit_field_, value);
2289 }
has_static_private_methods_or_accessors()2290 bool has_static_private_methods_or_accessors() const {
2291 return HasStaticPrivateMethodsOrAccessorsField::decode(bit_field_);
2292 }
2293
2294 void set_class_scope_has_private_brand(bool value);
2295 bool class_scope_has_private_brand() const;
2296
2297 bool private_name_lookup_skips_outer_class() const;
2298
produced_preparse_data()2299 ProducedPreparseData* produced_preparse_data() const {
2300 return produced_preparse_data_;
2301 }
2302
2303 private:
2304 friend class AstNodeFactory;
2305 friend Zone;
2306
2307 FunctionLiteral(Zone* zone, const AstConsString* name,
2308 AstValueFactory* ast_value_factory, DeclarationScope* scope,
2309 const ScopedPtrList<Statement>& body,
2310 int expected_property_count, int parameter_count,
2311 int function_length, FunctionSyntaxKind function_syntax_kind,
2312 ParameterFlag has_duplicate_parameters,
2313 EagerCompileHint eager_compile_hint, int position,
2314 bool has_braces, int function_literal_id,
2315 ProducedPreparseData* produced_preparse_data = nullptr)
Expression(position,kFunctionLiteral)2316 : Expression(position, kFunctionLiteral),
2317 expected_property_count_(expected_property_count),
2318 parameter_count_(parameter_count),
2319 function_length_(function_length),
2320 function_token_position_(kNoSourcePosition),
2321 suspend_count_(0),
2322 function_literal_id_(function_literal_id),
2323 raw_name_(name),
2324 scope_(scope),
2325 body_(body.ToConstVector(), zone),
2326 raw_inferred_name_(ast_value_factory->empty_cons_string()),
2327 produced_preparse_data_(produced_preparse_data) {
2328 bit_field_ |= FunctionSyntaxKindBits::encode(function_syntax_kind) |
2329 Pretenure::encode(false) |
2330 HasDuplicateParameters::encode(has_duplicate_parameters ==
2331 kHasDuplicateParameters) |
2332 RequiresInstanceMembersInitializer::encode(false) |
2333 HasBracesField::encode(has_braces) |
2334 ShouldParallelCompileField::encode(false);
2335 if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
2336 }
2337
2338 using FunctionSyntaxKindBits =
2339 Expression::NextBitField<FunctionSyntaxKind, 3>;
2340 using Pretenure = FunctionSyntaxKindBits::Next<bool, 1>;
2341 using HasDuplicateParameters = Pretenure::Next<bool, 1>;
2342 using RequiresInstanceMembersInitializer =
2343 HasDuplicateParameters::Next<bool, 1>;
2344 using HasStaticPrivateMethodsOrAccessorsField =
2345 RequiresInstanceMembersInitializer::Next<bool, 1>;
2346 using HasBracesField = HasStaticPrivateMethodsOrAccessorsField::Next<bool, 1>;
2347 using ShouldParallelCompileField = HasBracesField::Next<bool, 1>;
2348
2349 // expected_property_count_ is the sum of instance fields and properties.
2350 // It can vary depending on whether a function is lazily or eagerly parsed.
2351 int expected_property_count_;
2352 int parameter_count_;
2353 int function_length_;
2354 int function_token_position_;
2355 int suspend_count_;
2356 int function_literal_id_;
2357
2358 const AstConsString* raw_name_;
2359 DeclarationScope* scope_;
2360 ZonePtrList<Statement> body_;
2361 AstConsString* raw_inferred_name_;
2362 Handle<String> inferred_name_;
2363 ProducedPreparseData* produced_preparse_data_;
2364 };
2365
2366 // Property is used for passing information
2367 // about a class literal's properties from the parser to the code generator.
2368 class ClassLiteralProperty final : public LiteralProperty {
2369 public:
2370 enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
2371
kind()2372 Kind kind() const { return kind_; }
2373
is_static()2374 bool is_static() const { return is_static_; }
2375
is_private()2376 bool is_private() const { return is_private_; }
2377
set_computed_name_var(Variable * var)2378 void set_computed_name_var(Variable* var) {
2379 DCHECK_EQ(FIELD, kind());
2380 DCHECK(!is_private());
2381 private_or_computed_name_var_ = var;
2382 }
2383
computed_name_var()2384 Variable* computed_name_var() const {
2385 DCHECK_EQ(FIELD, kind());
2386 DCHECK(!is_private());
2387 return private_or_computed_name_var_;
2388 }
2389
set_private_name_var(Variable * var)2390 void set_private_name_var(Variable* var) {
2391 DCHECK(is_private());
2392 private_or_computed_name_var_ = var;
2393 }
private_name_var()2394 Variable* private_name_var() const {
2395 DCHECK(is_private());
2396 return private_or_computed_name_var_;
2397 }
2398
2399 private:
2400 friend class AstNodeFactory;
2401 friend Zone;
2402
2403 ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
2404 bool is_static, bool is_computed_name, bool is_private);
2405
2406 Kind kind_;
2407 bool is_static_;
2408 bool is_private_;
2409 Variable* private_or_computed_name_var_;
2410 };
2411
2412 class ClassLiteralStaticElement final : public ZoneObject {
2413 public:
2414 enum Kind : uint8_t { PROPERTY, STATIC_BLOCK };
2415
kind()2416 Kind kind() const { return kind_; }
2417
property()2418 ClassLiteralProperty* property() const {
2419 DCHECK(kind() == PROPERTY);
2420 return property_;
2421 }
2422
static_block()2423 Block* static_block() const {
2424 DCHECK(kind() == STATIC_BLOCK);
2425 return static_block_;
2426 }
2427
2428 private:
2429 friend class AstNodeFactory;
2430 friend Zone;
2431
ClassLiteralStaticElement(ClassLiteralProperty * property)2432 explicit ClassLiteralStaticElement(ClassLiteralProperty* property)
2433 : kind_(PROPERTY), property_(property) {}
2434
ClassLiteralStaticElement(Block * static_block)2435 explicit ClassLiteralStaticElement(Block* static_block)
2436 : kind_(STATIC_BLOCK), static_block_(static_block) {}
2437
2438 Kind kind_;
2439
2440 union {
2441 ClassLiteralProperty* property_;
2442 Block* static_block_;
2443 };
2444 };
2445
2446 class InitializeClassMembersStatement final : public Statement {
2447 public:
2448 using Property = ClassLiteralProperty;
2449
fields()2450 ZonePtrList<Property>* fields() const { return fields_; }
2451
2452 private:
2453 friend class AstNodeFactory;
2454 friend Zone;
2455
InitializeClassMembersStatement(ZonePtrList<Property> * fields,int pos)2456 InitializeClassMembersStatement(ZonePtrList<Property>* fields, int pos)
2457 : Statement(pos, kInitializeClassMembersStatement), fields_(fields) {}
2458
2459 ZonePtrList<Property>* fields_;
2460 };
2461
2462 class InitializeClassStaticElementsStatement final : public Statement {
2463 public:
2464 using StaticElement = ClassLiteralStaticElement;
2465
elements()2466 ZonePtrList<StaticElement>* elements() const { return elements_; }
2467
2468 private:
2469 friend class AstNodeFactory;
2470 friend Zone;
2471
InitializeClassStaticElementsStatement(ZonePtrList<StaticElement> * elements,int pos)2472 InitializeClassStaticElementsStatement(ZonePtrList<StaticElement>* elements,
2473 int pos)
2474 : Statement(pos, kInitializeClassStaticElementsStatement),
2475 elements_(elements) {}
2476
2477 ZonePtrList<StaticElement>* elements_;
2478 };
2479
2480 class ClassLiteral final : public Expression {
2481 public:
2482 using Property = ClassLiteralProperty;
2483 using StaticElement = ClassLiteralStaticElement;
2484
scope()2485 ClassScope* scope() const { return scope_; }
extends()2486 Expression* extends() const { return extends_; }
constructor()2487 FunctionLiteral* constructor() const { return constructor_; }
public_members()2488 ZonePtrList<Property>* public_members() const { return public_members_; }
private_members()2489 ZonePtrList<Property>* private_members() const { return private_members_; }
start_position()2490 int start_position() const { return position(); }
end_position()2491 int end_position() const { return end_position_; }
has_static_computed_names()2492 bool has_static_computed_names() const {
2493 return HasStaticComputedNames::decode(bit_field_);
2494 }
2495
is_anonymous_expression()2496 bool is_anonymous_expression() const {
2497 return IsAnonymousExpression::decode(bit_field_);
2498 }
has_private_methods()2499 bool has_private_methods() const {
2500 return HasPrivateMethods::decode(bit_field_);
2501 }
IsAnonymousFunctionDefinition()2502 bool IsAnonymousFunctionDefinition() const {
2503 return is_anonymous_expression();
2504 }
2505
static_initializer()2506 FunctionLiteral* static_initializer() const { return static_initializer_; }
2507
instance_members_initializer_function()2508 FunctionLiteral* instance_members_initializer_function() const {
2509 return instance_members_initializer_function_;
2510 }
2511
home_object()2512 Variable* home_object() const { return home_object_; }
2513
static_home_object()2514 Variable* static_home_object() const { return static_home_object_; }
2515
2516 private:
2517 friend class AstNodeFactory;
2518 friend Zone;
2519
ClassLiteral(ClassScope * scope,Expression * extends,FunctionLiteral * constructor,ZonePtrList<Property> * public_members,ZonePtrList<Property> * private_members,FunctionLiteral * static_initializer,FunctionLiteral * instance_members_initializer_function,int start_position,int end_position,bool has_static_computed_names,bool is_anonymous,bool has_private_methods,Variable * home_object,Variable * static_home_object)2520 ClassLiteral(ClassScope* scope, Expression* extends,
2521 FunctionLiteral* constructor,
2522 ZonePtrList<Property>* public_members,
2523 ZonePtrList<Property>* private_members,
2524 FunctionLiteral* static_initializer,
2525 FunctionLiteral* instance_members_initializer_function,
2526 int start_position, int end_position,
2527 bool has_static_computed_names, bool is_anonymous,
2528 bool has_private_methods, Variable* home_object,
2529 Variable* static_home_object)
2530 : Expression(start_position, kClassLiteral),
2531 end_position_(end_position),
2532 scope_(scope),
2533 extends_(extends),
2534 constructor_(constructor),
2535 public_members_(public_members),
2536 private_members_(private_members),
2537 static_initializer_(static_initializer),
2538 instance_members_initializer_function_(
2539 instance_members_initializer_function),
2540 home_object_(home_object),
2541 static_home_object_(static_home_object) {
2542 bit_field_ |= HasStaticComputedNames::encode(has_static_computed_names) |
2543 IsAnonymousExpression::encode(is_anonymous) |
2544 HasPrivateMethods::encode(has_private_methods);
2545 }
2546
2547 int end_position_;
2548 ClassScope* scope_;
2549 Expression* extends_;
2550 FunctionLiteral* constructor_;
2551 ZonePtrList<Property>* public_members_;
2552 ZonePtrList<Property>* private_members_;
2553 FunctionLiteral* static_initializer_;
2554 FunctionLiteral* instance_members_initializer_function_;
2555 using HasStaticComputedNames = Expression::NextBitField<bool, 1>;
2556 using IsAnonymousExpression = HasStaticComputedNames::Next<bool, 1>;
2557 using HasPrivateMethods = IsAnonymousExpression::Next<bool, 1>;
2558 Variable* home_object_;
2559 Variable* static_home_object_;
2560 };
2561
2562
2563 class NativeFunctionLiteral final : public Expression {
2564 public:
name()2565 Handle<String> name() const { return name_->string(); }
raw_name()2566 const AstRawString* raw_name() const { return name_; }
extension()2567 v8::Extension* extension() const { return extension_; }
2568
2569 private:
2570 friend class AstNodeFactory;
2571 friend Zone;
2572
NativeFunctionLiteral(const AstRawString * name,v8::Extension * extension,int pos)2573 NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
2574 int pos)
2575 : Expression(pos, kNativeFunctionLiteral),
2576 name_(name),
2577 extension_(extension) {}
2578
2579 const AstRawString* name_;
2580 v8::Extension* extension_;
2581 };
2582
2583
2584 class SuperPropertyReference final : public Expression {
2585 public:
home_object()2586 VariableProxy* home_object() const { return home_object_; }
2587
2588 private:
2589 friend class AstNodeFactory;
2590 friend Zone;
2591
SuperPropertyReference(VariableProxy * home_object,int pos)2592 explicit SuperPropertyReference(VariableProxy* home_object, int pos)
2593 : Expression(pos, kSuperPropertyReference), home_object_(home_object) {}
2594
2595 VariableProxy* home_object_;
2596 };
2597
2598
2599 class SuperCallReference final : public Expression {
2600 public:
new_target_var()2601 VariableProxy* new_target_var() const { return new_target_var_; }
this_function_var()2602 VariableProxy* this_function_var() const { return this_function_var_; }
2603
2604 private:
2605 friend class AstNodeFactory;
2606 friend Zone;
2607
2608 // We take in ThisExpression* only as a proof that it was accessed.
SuperCallReference(VariableProxy * new_target_var,VariableProxy * this_function_var,int pos)2609 SuperCallReference(VariableProxy* new_target_var,
2610 VariableProxy* this_function_var, int pos)
2611 : Expression(pos, kSuperCallReference),
2612 new_target_var_(new_target_var),
2613 this_function_var_(this_function_var) {
2614 DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2615 DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
2616 }
2617
2618 VariableProxy* new_target_var_;
2619 VariableProxy* this_function_var_;
2620 };
2621
2622 // This AST Node is used to represent a dynamic import call --
2623 // import(argument).
2624 class ImportCallExpression final : public Expression {
2625 public:
specifier()2626 Expression* specifier() const { return specifier_; }
import_assertions()2627 Expression* import_assertions() const { return import_assertions_; }
2628
2629 private:
2630 friend class AstNodeFactory;
2631 friend Zone;
2632
ImportCallExpression(Expression * specifier,int pos)2633 ImportCallExpression(Expression* specifier, int pos)
2634 : Expression(pos, kImportCallExpression),
2635 specifier_(specifier),
2636 import_assertions_(nullptr) {}
2637
ImportCallExpression(Expression * specifier,Expression * import_assertions,int pos)2638 ImportCallExpression(Expression* specifier, Expression* import_assertions,
2639 int pos)
2640 : Expression(pos, kImportCallExpression),
2641 specifier_(specifier),
2642 import_assertions_(import_assertions) {}
2643
2644 Expression* specifier_;
2645 Expression* import_assertions_;
2646 };
2647
2648 // This class is produced when parsing the () in arrow functions without any
2649 // arguments and is not actually a valid expression.
2650 class EmptyParentheses final : public Expression {
2651 private:
2652 friend class AstNodeFactory;
2653 friend Zone;
2654
EmptyParentheses(int pos)2655 explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {
2656 mark_parenthesized();
2657 }
2658 };
2659
2660 // Represents the spec operation `GetTemplateObject(templateLiteral)`
2661 // (defined at https://tc39.github.io/ecma262/#sec-gettemplateobject).
2662 class GetTemplateObject final : public Expression {
2663 public:
cooked_strings()2664 const ZonePtrList<const AstRawString>* cooked_strings() const {
2665 return cooked_strings_;
2666 }
raw_strings()2667 const ZonePtrList<const AstRawString>* raw_strings() const {
2668 return raw_strings_;
2669 }
2670
2671 template <typename IsolateT>
2672 Handle<TemplateObjectDescription> GetOrBuildDescription(IsolateT* isolate);
2673
2674 private:
2675 friend class AstNodeFactory;
2676 friend Zone;
2677
GetTemplateObject(const ZonePtrList<const AstRawString> * cooked_strings,const ZonePtrList<const AstRawString> * raw_strings,int pos)2678 GetTemplateObject(const ZonePtrList<const AstRawString>* cooked_strings,
2679 const ZonePtrList<const AstRawString>* raw_strings, int pos)
2680 : Expression(pos, kGetTemplateObject),
2681 cooked_strings_(cooked_strings),
2682 raw_strings_(raw_strings) {}
2683
2684 const ZonePtrList<const AstRawString>* cooked_strings_;
2685 const ZonePtrList<const AstRawString>* raw_strings_;
2686 };
2687
2688 class TemplateLiteral final : public Expression {
2689 public:
string_parts()2690 const ZonePtrList<const AstRawString>* string_parts() const {
2691 return string_parts_;
2692 }
substitutions()2693 const ZonePtrList<Expression>* substitutions() const {
2694 return substitutions_;
2695 }
2696
2697 private:
2698 friend class AstNodeFactory;
2699 friend Zone;
TemplateLiteral(const ZonePtrList<const AstRawString> * parts,const ZonePtrList<Expression> * substitutions,int pos)2700 TemplateLiteral(const ZonePtrList<const AstRawString>* parts,
2701 const ZonePtrList<Expression>* substitutions, int pos)
2702 : Expression(pos, kTemplateLiteral),
2703 string_parts_(parts),
2704 substitutions_(substitutions) {}
2705
2706 const ZonePtrList<const AstRawString>* string_parts_;
2707 const ZonePtrList<Expression>* substitutions_;
2708 };
2709
2710 // ----------------------------------------------------------------------------
2711 // Basic visitor
2712 // Sub-class should parametrize AstVisitor with itself, e.g.:
2713 // class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
2714
2715 template <class Subclass>
2716 class AstVisitor {
2717 public:
Visit(AstNode * node)2718 void Visit(AstNode* node) { impl()->Visit(node); }
2719
VisitDeclarations(Declaration::List * declarations)2720 void VisitDeclarations(Declaration::List* declarations) {
2721 for (Declaration* decl : *declarations) Visit(decl);
2722 }
2723
VisitStatements(const ZonePtrList<Statement> * statements)2724 void VisitStatements(const ZonePtrList<Statement>* statements) {
2725 for (int i = 0; i < statements->length(); i++) {
2726 Statement* stmt = statements->at(i);
2727 Visit(stmt);
2728 }
2729 }
2730
VisitExpressions(const ZonePtrList<Expression> * expressions)2731 void VisitExpressions(const ZonePtrList<Expression>* expressions) {
2732 for (int i = 0; i < expressions->length(); i++) {
2733 // The variable statement visiting code may pass null expressions
2734 // to this code. Maybe this should be handled by introducing an
2735 // undefined expression or literal? Revisit this code if this
2736 // changes.
2737 Expression* expression = expressions->at(i);
2738 if (expression != nullptr) Visit(expression);
2739 }
2740 }
2741
2742 protected:
impl()2743 Subclass* impl() { return static_cast<Subclass*>(this); }
2744 };
2745
2746 #define GENERATE_VISIT_CASE(NodeType) \
2747 case AstNode::k##NodeType: \
2748 return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
2749
2750 #define GENERATE_FAILURE_CASE(NodeType) \
2751 case AstNode::k##NodeType: \
2752 UNREACHABLE();
2753
2754 #define GENERATE_AST_VISITOR_SWITCH() \
2755 switch (node->node_type()) { \
2756 AST_NODE_LIST(GENERATE_VISIT_CASE) \
2757 FAILURE_NODE_LIST(GENERATE_FAILURE_CASE) \
2758 }
2759
2760 #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \
2761 public: \
2762 void VisitNoStackOverflowCheck(AstNode* node) { \
2763 GENERATE_AST_VISITOR_SWITCH() \
2764 } \
2765 \
2766 void Visit(AstNode* node) { \
2767 if (CheckStackOverflow()) return; \
2768 VisitNoStackOverflowCheck(node); \
2769 } \
2770 \
2771 void SetStackOverflow() { stack_overflow_ = true; } \
2772 void ClearStackOverflow() { stack_overflow_ = false; } \
2773 bool HasStackOverflow() const { return stack_overflow_; } \
2774 \
2775 bool CheckStackOverflow() { \
2776 if (stack_overflow_) return true; \
2777 if (GetCurrentStackPosition() < stack_limit_) { \
2778 stack_overflow_ = true; \
2779 return true; \
2780 } \
2781 return false; \
2782 } \
2783 \
2784 protected: \
2785 uintptr_t stack_limit() const { return stack_limit_; } \
2786 \
2787 private: \
2788 void InitializeAstVisitor(Isolate* isolate) { \
2789 stack_limit_ = isolate->stack_guard()->real_climit(); \
2790 stack_overflow_ = false; \
2791 } \
2792 \
2793 void InitializeAstVisitor(uintptr_t stack_limit) { \
2794 stack_limit_ = stack_limit; \
2795 stack_overflow_ = false; \
2796 } \
2797 \
2798 uintptr_t stack_limit_; \
2799 bool stack_overflow_
2800
2801 #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() \
2802 public: \
2803 void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
2804 \
2805 private:
2806
2807 // ----------------------------------------------------------------------------
2808 // AstNode factory
2809
2810 class AstNodeFactory final {
2811 public:
AstNodeFactory(AstValueFactory * ast_value_factory,Zone * zone)2812 AstNodeFactory(AstValueFactory* ast_value_factory, Zone* zone)
2813 : zone_(zone),
2814 ast_value_factory_(ast_value_factory),
2815 empty_statement_(zone->New<class EmptyStatement>()),
2816 this_expression_(zone->New<class ThisExpression>(kNoSourcePosition)),
2817 failure_expression_(zone->New<class FailureExpression>()) {}
2818
ast_node_factory()2819 AstNodeFactory* ast_node_factory() { return this; }
ast_value_factory()2820 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
2821
NewVariableDeclaration(int pos)2822 VariableDeclaration* NewVariableDeclaration(int pos) {
2823 return zone_->New<VariableDeclaration>(pos);
2824 }
2825
NewNestedVariableDeclaration(Scope * scope,int pos)2826 NestedVariableDeclaration* NewNestedVariableDeclaration(Scope* scope,
2827 int pos) {
2828 return zone_->New<NestedVariableDeclaration>(scope, pos);
2829 }
2830
NewFunctionDeclaration(FunctionLiteral * fun,int pos)2831 FunctionDeclaration* NewFunctionDeclaration(FunctionLiteral* fun, int pos) {
2832 return zone_->New<FunctionDeclaration>(fun, pos);
2833 }
2834
NewBlock(int capacity,bool ignore_completion_value)2835 Block* NewBlock(int capacity, bool ignore_completion_value) {
2836 return zone_->New<Block>(zone_, capacity, ignore_completion_value, false);
2837 }
2838
NewBlock(bool ignore_completion_value,bool is_breakable)2839 Block* NewBlock(bool ignore_completion_value, bool is_breakable) {
2840 return zone_->New<Block>(ignore_completion_value, is_breakable);
2841 }
2842
NewBlock(bool ignore_completion_value,const ScopedPtrList<Statement> & statements)2843 Block* NewBlock(bool ignore_completion_value,
2844 const ScopedPtrList<Statement>& statements) {
2845 Block* result = NewBlock(ignore_completion_value, false);
2846 result->InitializeStatements(statements, zone_);
2847 return result;
2848 }
2849
2850 #define STATEMENT_WITH_POSITION(NodeType) \
2851 NodeType* New##NodeType(int pos) { return zone_->New<NodeType>(pos); }
2852 STATEMENT_WITH_POSITION(DoWhileStatement)
STATEMENT_WITH_POSITION(WhileStatement)2853 STATEMENT_WITH_POSITION(WhileStatement)
2854 STATEMENT_WITH_POSITION(ForStatement)
2855 #undef STATEMENT_WITH_POSITION
2856
2857 SwitchStatement* NewSwitchStatement(Expression* tag, int pos) {
2858 return zone_->New<SwitchStatement>(zone_, tag, pos);
2859 }
2860
NewForEachStatement(ForEachStatement::VisitMode visit_mode,int pos)2861 ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
2862 int pos) {
2863 switch (visit_mode) {
2864 case ForEachStatement::ENUMERATE: {
2865 return zone_->New<ForInStatement>(pos);
2866 }
2867 case ForEachStatement::ITERATE: {
2868 return zone_->New<ForOfStatement>(pos, IteratorType::kNormal);
2869 }
2870 }
2871 UNREACHABLE();
2872 }
2873
NewForOfStatement(int pos,IteratorType type)2874 ForOfStatement* NewForOfStatement(int pos, IteratorType type) {
2875 return zone_->New<ForOfStatement>(pos, type);
2876 }
2877
NewExpressionStatement(Expression * expression,int pos)2878 ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
2879 return zone_->New<ExpressionStatement>(expression, pos);
2880 }
2881
NewContinueStatement(IterationStatement * target,int pos)2882 ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
2883 return zone_->New<ContinueStatement>(target, pos);
2884 }
2885
NewBreakStatement(BreakableStatement * target,int pos)2886 BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
2887 return zone_->New<BreakStatement>(target, pos);
2888 }
2889
2890 ReturnStatement* NewReturnStatement(
2891 Expression* expression, int pos,
2892 int end_position = ReturnStatement::kFunctionLiteralReturnPosition) {
2893 return zone_->New<ReturnStatement>(expression, ReturnStatement::kNormal,
2894 pos, end_position);
2895 }
2896
NewAsyncReturnStatement(Expression * expression,int pos,int end_position)2897 ReturnStatement* NewAsyncReturnStatement(Expression* expression, int pos,
2898 int end_position) {
2899 return zone_->New<ReturnStatement>(
2900 expression, ReturnStatement::kAsyncReturn, pos, end_position);
2901 }
2902
2903 ReturnStatement* NewSyntheticAsyncReturnStatement(
2904 Expression* expression, int pos,
2905 int end_position = ReturnStatement::kFunctionLiteralReturnPosition) {
2906 return zone_->New<ReturnStatement>(
2907 expression, ReturnStatement::kSyntheticAsyncReturn, pos, end_position);
2908 }
2909
NewWithStatement(Scope * scope,Expression * expression,Statement * statement,int pos)2910 WithStatement* NewWithStatement(Scope* scope,
2911 Expression* expression,
2912 Statement* statement,
2913 int pos) {
2914 return zone_->New<WithStatement>(scope, expression, statement, pos);
2915 }
2916
NewIfStatement(Expression * condition,Statement * then_statement,Statement * else_statement,int pos)2917 IfStatement* NewIfStatement(Expression* condition, Statement* then_statement,
2918 Statement* else_statement, int pos) {
2919 return zone_->New<IfStatement>(condition, then_statement, else_statement,
2920 pos);
2921 }
2922
NewTryCatchStatement(Block * try_block,Scope * scope,Block * catch_block,int pos)2923 TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
2924 Block* catch_block, int pos) {
2925 return zone_->New<TryCatchStatement>(try_block, scope, catch_block,
2926 HandlerTable::CAUGHT, pos);
2927 }
2928
NewTryCatchStatementForReThrow(Block * try_block,Scope * scope,Block * catch_block,int pos)2929 TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
2930 Scope* scope,
2931 Block* catch_block,
2932 int pos) {
2933 return zone_->New<TryCatchStatement>(try_block, scope, catch_block,
2934 HandlerTable::UNCAUGHT, pos);
2935 }
2936
NewTryCatchStatementForAsyncAwait(Block * try_block,Scope * scope,Block * catch_block,int pos)2937 TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
2938 Scope* scope,
2939 Block* catch_block,
2940 int pos) {
2941 return zone_->New<TryCatchStatement>(try_block, scope, catch_block,
2942 HandlerTable::ASYNC_AWAIT, pos);
2943 }
2944
NewTryCatchStatementForReplAsyncAwait(Block * try_block,Scope * scope,Block * catch_block,int pos)2945 TryCatchStatement* NewTryCatchStatementForReplAsyncAwait(Block* try_block,
2946 Scope* scope,
2947 Block* catch_block,
2948 int pos) {
2949 return zone_->New<TryCatchStatement>(
2950 try_block, scope, catch_block, HandlerTable::UNCAUGHT_ASYNC_AWAIT, pos);
2951 }
2952
NewTryFinallyStatement(Block * try_block,Block * finally_block,int pos)2953 TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
2954 Block* finally_block, int pos) {
2955 return zone_->New<TryFinallyStatement>(try_block, finally_block, pos);
2956 }
2957
NewDebuggerStatement(int pos)2958 DebuggerStatement* NewDebuggerStatement(int pos) {
2959 return zone_->New<DebuggerStatement>(pos);
2960 }
2961
EmptyStatement()2962 class EmptyStatement* EmptyStatement() {
2963 return empty_statement_;
2964 }
2965
ThisExpression()2966 class ThisExpression* ThisExpression() {
2967 // Clear any previously set "parenthesized" flag on this_expression_ so this
2968 // particular token does not inherit the it. The flag is used to check
2969 // during arrow function head parsing whether we came from parenthesized
2970 // exprssion parsing, since additional arrow function verification was done
2971 // there. It does not matter whether a flag is unset after arrow head
2972 // verification, so clearing at this point is fine.
2973 this_expression_->clear_parenthesized();
2974 return this_expression_;
2975 }
2976
NewThisExpression(int pos)2977 class ThisExpression* NewThisExpression(int pos) {
2978 DCHECK_NE(pos, kNoSourcePosition);
2979 return zone_->New<class ThisExpression>(pos);
2980 }
2981
FailureExpression()2982 class FailureExpression* FailureExpression() {
2983 return failure_expression_;
2984 }
2985
NewSloppyBlockFunctionStatement(int pos,Variable * var,Token::Value init)2986 SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(
2987 int pos, Variable* var, Token::Value init) {
2988 return zone_->New<SloppyBlockFunctionStatement>(pos, var, init,
2989 EmptyStatement());
2990 }
2991
NewCaseClause(Expression * label,const ScopedPtrList<Statement> & statements)2992 CaseClause* NewCaseClause(Expression* label,
2993 const ScopedPtrList<Statement>& statements) {
2994 return zone_->New<CaseClause>(zone_, label, statements);
2995 }
2996
NewStringLiteral(const AstRawString * string,int pos)2997 Literal* NewStringLiteral(const AstRawString* string, int pos) {
2998 DCHECK_NOT_NULL(string);
2999 return zone_->New<Literal>(string, pos);
3000 }
3001
3002 Literal* NewNumberLiteral(double number, int pos);
3003
NewSmiLiteral(int number,int pos)3004 Literal* NewSmiLiteral(int number, int pos) {
3005 return zone_->New<Literal>(number, pos);
3006 }
3007
NewBigIntLiteral(AstBigInt bigint,int pos)3008 Literal* NewBigIntLiteral(AstBigInt bigint, int pos) {
3009 return zone_->New<Literal>(bigint, pos);
3010 }
3011
NewBooleanLiteral(bool b,int pos)3012 Literal* NewBooleanLiteral(bool b, int pos) {
3013 return zone_->New<Literal>(b, pos);
3014 }
3015
NewNullLiteral(int pos)3016 Literal* NewNullLiteral(int pos) {
3017 return zone_->New<Literal>(Literal::kNull, pos);
3018 }
3019
NewUndefinedLiteral(int pos)3020 Literal* NewUndefinedLiteral(int pos) {
3021 return zone_->New<Literal>(Literal::kUndefined, pos);
3022 }
3023
NewTheHoleLiteral()3024 Literal* NewTheHoleLiteral() {
3025 return zone_->New<Literal>(Literal::kTheHole, kNoSourcePosition);
3026 }
3027
3028 ObjectLiteral* NewObjectLiteral(
3029 const ScopedPtrList<ObjectLiteral::Property>& properties,
3030 uint32_t boilerplate_properties, int pos, bool has_rest_property,
3031 Variable* home_object = nullptr) {
3032 return zone_->New<ObjectLiteral>(zone_, properties, boilerplate_properties,
3033 pos, has_rest_property, home_object);
3034 }
3035
NewObjectLiteralProperty(Expression * key,Expression * value,ObjectLiteralProperty::Kind kind,bool is_computed_name)3036 ObjectLiteral::Property* NewObjectLiteralProperty(
3037 Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
3038 bool is_computed_name) {
3039 return zone_->New<ObjectLiteral::Property>(key, value, kind,
3040 is_computed_name);
3041 }
3042
NewObjectLiteralProperty(Expression * key,Expression * value,bool is_computed_name)3043 ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
3044 Expression* value,
3045 bool is_computed_name) {
3046 return zone_->New<ObjectLiteral::Property>(ast_value_factory_, key, value,
3047 is_computed_name);
3048 }
3049
NewRegExpLiteral(const AstRawString * pattern,int flags,int pos)3050 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
3051 int pos) {
3052 return zone_->New<RegExpLiteral>(pattern, flags, pos);
3053 }
3054
NewArrayLiteral(const ScopedPtrList<Expression> & values,int pos)3055 ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
3056 int pos) {
3057 return zone_->New<ArrayLiteral>(zone_, values, -1, pos);
3058 }
3059
NewArrayLiteral(const ScopedPtrList<Expression> & values,int first_spread_index,int pos)3060 ArrayLiteral* NewArrayLiteral(const ScopedPtrList<Expression>& values,
3061 int first_spread_index, int pos) {
3062 return zone_->New<ArrayLiteral>(zone_, values, first_spread_index, pos);
3063 }
3064
3065 VariableProxy* NewVariableProxy(Variable* var,
3066 int start_position = kNoSourcePosition) {
3067 return zone_->New<VariableProxy>(var, start_position);
3068 }
3069
3070 VariableProxy* NewVariableProxy(const AstRawString* name,
3071 VariableKind variable_kind,
3072 int start_position = kNoSourcePosition) {
3073 DCHECK_NOT_NULL(name);
3074 return zone_->New<VariableProxy>(name, variable_kind, start_position);
3075 }
3076
3077 // Recreates the VariableProxy in this Zone.
CopyVariableProxy(VariableProxy * proxy)3078 VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
3079 return zone_->New<VariableProxy>(proxy);
3080 }
3081
CopyVariable(Variable * variable)3082 Variable* CopyVariable(Variable* variable) {
3083 return zone_->New<Variable>(variable);
3084 }
3085
NewOptionalChain(Expression * expression)3086 OptionalChain* NewOptionalChain(Expression* expression) {
3087 return zone_->New<OptionalChain>(expression);
3088 }
3089
3090 Property* NewProperty(Expression* obj, Expression* key, int pos,
3091 bool optional_chain = false) {
3092 return zone_->New<Property>(obj, key, pos, optional_chain);
3093 }
3094
3095 Call* NewCall(Expression* expression,
3096 const ScopedPtrList<Expression>& arguments, int pos,
3097 bool has_spread,
3098 Call::PossiblyEval possibly_eval = Call::NOT_EVAL,
3099 bool optional_chain = false) {
3100 DCHECK_IMPLIES(possibly_eval == Call::IS_POSSIBLY_EVAL, !optional_chain);
3101 return zone_->New<Call>(zone_, expression, arguments, pos, has_spread,
3102 possibly_eval, optional_chain);
3103 }
3104
NewTaggedTemplate(Expression * expression,const ScopedPtrList<Expression> & arguments,int pos)3105 Call* NewTaggedTemplate(Expression* expression,
3106 const ScopedPtrList<Expression>& arguments, int pos) {
3107 return zone_->New<Call>(zone_, expression, arguments, pos,
3108 Call::TaggedTemplateTag::kTrue);
3109 }
3110
NewCallNew(Expression * expression,const ScopedPtrList<Expression> & arguments,int pos,bool has_spread)3111 CallNew* NewCallNew(Expression* expression,
3112 const ScopedPtrList<Expression>& arguments, int pos,
3113 bool has_spread) {
3114 return zone_->New<CallNew>(zone_, expression, arguments, pos, has_spread);
3115 }
3116
NewCallRuntime(Runtime::FunctionId id,const ScopedPtrList<Expression> & arguments,int pos)3117 CallRuntime* NewCallRuntime(Runtime::FunctionId id,
3118 const ScopedPtrList<Expression>& arguments,
3119 int pos) {
3120 return zone_->New<CallRuntime>(zone_, Runtime::FunctionForId(id), arguments,
3121 pos);
3122 }
3123
NewCallRuntime(const Runtime::Function * function,const ScopedPtrList<Expression> & arguments,int pos)3124 CallRuntime* NewCallRuntime(const Runtime::Function* function,
3125 const ScopedPtrList<Expression>& arguments,
3126 int pos) {
3127 return zone_->New<CallRuntime>(zone_, function, arguments, pos);
3128 }
3129
NewCallRuntime(int context_index,const ScopedPtrList<Expression> & arguments,int pos)3130 CallRuntime* NewCallRuntime(int context_index,
3131 const ScopedPtrList<Expression>& arguments,
3132 int pos) {
3133 return zone_->New<CallRuntime>(zone_, context_index, arguments, pos);
3134 }
3135
NewUnaryOperation(Token::Value op,Expression * expression,int pos)3136 UnaryOperation* NewUnaryOperation(Token::Value op,
3137 Expression* expression,
3138 int pos) {
3139 return zone_->New<UnaryOperation>(op, expression, pos);
3140 }
3141
NewBinaryOperation(Token::Value op,Expression * left,Expression * right,int pos)3142 BinaryOperation* NewBinaryOperation(Token::Value op,
3143 Expression* left,
3144 Expression* right,
3145 int pos) {
3146 return zone_->New<BinaryOperation>(op, left, right, pos);
3147 }
3148
NewNaryOperation(Token::Value op,Expression * first,size_t initial_subsequent_size)3149 NaryOperation* NewNaryOperation(Token::Value op, Expression* first,
3150 size_t initial_subsequent_size) {
3151 return zone_->New<NaryOperation>(zone_, op, first, initial_subsequent_size);
3152 }
3153
NewCountOperation(Token::Value op,bool is_prefix,Expression * expr,int pos)3154 CountOperation* NewCountOperation(Token::Value op,
3155 bool is_prefix,
3156 Expression* expr,
3157 int pos) {
3158 return zone_->New<CountOperation>(op, is_prefix, expr, pos);
3159 }
3160
NewCompareOperation(Token::Value op,Expression * left,Expression * right,int pos)3161 CompareOperation* NewCompareOperation(Token::Value op,
3162 Expression* left,
3163 Expression* right,
3164 int pos) {
3165 return zone_->New<CompareOperation>(op, left, right, pos);
3166 }
3167
NewSpread(Expression * expression,int pos,int expr_pos)3168 Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3169 return zone_->New<Spread>(expression, pos, expr_pos);
3170 }
3171
NewConditional(Expression * condition,Expression * then_expression,Expression * else_expression,int position)3172 Conditional* NewConditional(Expression* condition,
3173 Expression* then_expression,
3174 Expression* else_expression,
3175 int position) {
3176 return zone_->New<Conditional>(condition, then_expression, else_expression,
3177 position);
3178 }
3179
NewAssignment(Token::Value op,Expression * target,Expression * value,int pos)3180 Assignment* NewAssignment(Token::Value op,
3181 Expression* target,
3182 Expression* value,
3183 int pos) {
3184 DCHECK(Token::IsAssignmentOp(op));
3185 DCHECK_NOT_NULL(target);
3186 DCHECK_NOT_NULL(value);
3187
3188 if (op != Token::INIT && target->IsVariableProxy()) {
3189 target->AsVariableProxy()->set_is_assigned();
3190 }
3191
3192 if (op == Token::ASSIGN || op == Token::INIT) {
3193 return zone_->New<Assignment>(AstNode::kAssignment, op, target, value,
3194 pos);
3195 } else {
3196 return zone_->New<CompoundAssignment>(
3197 op, target, value, pos,
3198 NewBinaryOperation(Token::BinaryOpForAssignment(op), target, value,
3199 pos + 1));
3200 }
3201 }
3202
NewYield(Expression * expression,int pos,Suspend::OnAbruptResume on_abrupt_resume)3203 Suspend* NewYield(Expression* expression, int pos,
3204 Suspend::OnAbruptResume on_abrupt_resume) {
3205 if (!expression) expression = NewUndefinedLiteral(pos);
3206 return zone_->New<Yield>(expression, pos, on_abrupt_resume);
3207 }
3208
NewYieldStar(Expression * expression,int pos)3209 YieldStar* NewYieldStar(Expression* expression, int pos) {
3210 return zone_->New<YieldStar>(expression, pos);
3211 }
3212
NewAwait(Expression * expression,int pos)3213 Await* NewAwait(Expression* expression, int pos) {
3214 if (!expression) expression = NewUndefinedLiteral(pos);
3215 return zone_->New<Await>(expression, pos);
3216 }
3217
NewThrow(Expression * exception,int pos)3218 Throw* NewThrow(Expression* exception, int pos) {
3219 return zone_->New<Throw>(exception, pos);
3220 }
3221
3222 FunctionLiteral* NewFunctionLiteral(
3223 const AstRawString* name, DeclarationScope* scope,
3224 const ScopedPtrList<Statement>& body, int expected_property_count,
3225 int parameter_count, int function_length,
3226 FunctionLiteral::ParameterFlag has_duplicate_parameters,
3227 FunctionSyntaxKind function_syntax_kind,
3228 FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
3229 bool has_braces, int function_literal_id,
3230 ProducedPreparseData* produced_preparse_data = nullptr) {
3231 return zone_->New<FunctionLiteral>(
3232 zone_, name ? ast_value_factory_->NewConsString(name) : nullptr,
3233 ast_value_factory_, scope, body, expected_property_count,
3234 parameter_count, function_length, function_syntax_kind,
3235 has_duplicate_parameters, eager_compile_hint, position, has_braces,
3236 function_literal_id, produced_preparse_data);
3237 }
3238
3239 // Creates a FunctionLiteral representing a top-level script, the
3240 // result of an eval (top-level or otherwise), or the result of calling
3241 // the Function constructor.
NewScriptOrEvalFunctionLiteral(DeclarationScope * scope,const ScopedPtrList<Statement> & body,int expected_property_count,int parameter_count)3242 FunctionLiteral* NewScriptOrEvalFunctionLiteral(
3243 DeclarationScope* scope, const ScopedPtrList<Statement>& body,
3244 int expected_property_count, int parameter_count) {
3245 return zone_->New<FunctionLiteral>(
3246 zone_, ast_value_factory_->empty_cons_string(), ast_value_factory_,
3247 scope, body, expected_property_count, parameter_count, parameter_count,
3248 FunctionSyntaxKind::kAnonymousExpression,
3249 FunctionLiteral::kNoDuplicateParameters,
3250 FunctionLiteral::kShouldLazyCompile, 0, /* has_braces */ false,
3251 kFunctionLiteralIdTopLevel);
3252 }
3253
NewClassLiteralProperty(Expression * key,Expression * value,ClassLiteralProperty::Kind kind,bool is_static,bool is_computed_name,bool is_private)3254 ClassLiteral::Property* NewClassLiteralProperty(
3255 Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
3256 bool is_static, bool is_computed_name, bool is_private) {
3257 return zone_->New<ClassLiteral::Property>(key, value, kind, is_static,
3258 is_computed_name, is_private);
3259 }
3260
NewClassLiteralStaticElement(ClassLiteral::Property * property)3261 ClassLiteral::StaticElement* NewClassLiteralStaticElement(
3262 ClassLiteral::Property* property) {
3263 return zone_->New<ClassLiteral::StaticElement>(property);
3264 }
3265
NewClassLiteralStaticElement(Block * static_block)3266 ClassLiteral::StaticElement* NewClassLiteralStaticElement(
3267 Block* static_block) {
3268 return zone_->New<ClassLiteral::StaticElement>(static_block);
3269 }
3270
NewClassLiteral(ClassScope * scope,Expression * extends,FunctionLiteral * constructor,ZonePtrList<ClassLiteral::Property> * public_members,ZonePtrList<ClassLiteral::Property> * private_members,FunctionLiteral * static_initializer,FunctionLiteral * instance_members_initializer_function,int start_position,int end_position,bool has_static_computed_names,bool is_anonymous,bool has_private_methods,Variable * home_object,Variable * static_home_object)3271 ClassLiteral* NewClassLiteral(
3272 ClassScope* scope, Expression* extends, FunctionLiteral* constructor,
3273 ZonePtrList<ClassLiteral::Property>* public_members,
3274 ZonePtrList<ClassLiteral::Property>* private_members,
3275 FunctionLiteral* static_initializer,
3276 FunctionLiteral* instance_members_initializer_function,
3277 int start_position, int end_position, bool has_static_computed_names,
3278 bool is_anonymous, bool has_private_methods, Variable* home_object,
3279 Variable* static_home_object) {
3280 return zone_->New<ClassLiteral>(
3281 scope, extends, constructor, public_members, private_members,
3282 static_initializer, instance_members_initializer_function,
3283 start_position, end_position, has_static_computed_names, is_anonymous,
3284 has_private_methods, home_object, static_home_object);
3285 }
3286
NewNativeFunctionLiteral(const AstRawString * name,v8::Extension * extension,int pos)3287 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
3288 v8::Extension* extension,
3289 int pos) {
3290 return zone_->New<NativeFunctionLiteral>(name, extension, pos);
3291 }
3292
NewSuperPropertyReference(VariableProxy * home_object_var,int pos)3293 SuperPropertyReference* NewSuperPropertyReference(
3294 VariableProxy* home_object_var, int pos) {
3295 return zone_->New<SuperPropertyReference>(home_object_var, pos);
3296 }
3297
NewSuperCallReference(VariableProxy * new_target_var,VariableProxy * this_function_var,int pos)3298 SuperCallReference* NewSuperCallReference(VariableProxy* new_target_var,
3299 VariableProxy* this_function_var,
3300 int pos) {
3301 return zone_->New<SuperCallReference>(new_target_var, this_function_var,
3302 pos);
3303 }
3304
NewEmptyParentheses(int pos)3305 EmptyParentheses* NewEmptyParentheses(int pos) {
3306 return zone_->New<EmptyParentheses>(pos);
3307 }
3308
NewGetTemplateObject(const ZonePtrList<const AstRawString> * cooked_strings,const ZonePtrList<const AstRawString> * raw_strings,int pos)3309 GetTemplateObject* NewGetTemplateObject(
3310 const ZonePtrList<const AstRawString>* cooked_strings,
3311 const ZonePtrList<const AstRawString>* raw_strings, int pos) {
3312 return zone_->New<GetTemplateObject>(cooked_strings, raw_strings, pos);
3313 }
3314
NewTemplateLiteral(const ZonePtrList<const AstRawString> * string_parts,const ZonePtrList<Expression> * substitutions,int pos)3315 TemplateLiteral* NewTemplateLiteral(
3316 const ZonePtrList<const AstRawString>* string_parts,
3317 const ZonePtrList<Expression>* substitutions, int pos) {
3318 return zone_->New<TemplateLiteral>(string_parts, substitutions, pos);
3319 }
3320
NewImportCallExpression(Expression * specifier,int pos)3321 ImportCallExpression* NewImportCallExpression(Expression* specifier,
3322 int pos) {
3323 return zone_->New<ImportCallExpression>(specifier, pos);
3324 }
3325
NewImportCallExpression(Expression * specifier,Expression * import_assertions,int pos)3326 ImportCallExpression* NewImportCallExpression(Expression* specifier,
3327 Expression* import_assertions,
3328 int pos) {
3329 return zone_->New<ImportCallExpression>(specifier, import_assertions, pos);
3330 }
3331
NewInitializeClassMembersStatement(ZonePtrList<ClassLiteral::Property> * args,int pos)3332 InitializeClassMembersStatement* NewInitializeClassMembersStatement(
3333 ZonePtrList<ClassLiteral::Property>* args, int pos) {
3334 return zone_->New<InitializeClassMembersStatement>(args, pos);
3335 }
3336
3337 InitializeClassStaticElementsStatement*
NewInitializeClassStaticElementsStatement(ZonePtrList<ClassLiteral::StaticElement> * args,int pos)3338 NewInitializeClassStaticElementsStatement(
3339 ZonePtrList<ClassLiteral::StaticElement>* args, int pos) {
3340 return zone_->New<InitializeClassStaticElementsStatement>(args, pos);
3341 }
3342
zone()3343 Zone* zone() const { return zone_; }
3344
3345 private:
3346 // This zone may be deallocated upon returning from parsing a function body
3347 // which we can guarantee is not going to be compiled or have its AST
3348 // inspected.
3349 // See ParseFunctionLiteral in parser.cc for preconditions.
3350 Zone* zone_;
3351 AstValueFactory* ast_value_factory_;
3352 class EmptyStatement* empty_statement_;
3353 class ThisExpression* this_expression_;
3354 class FailureExpression* failure_expression_;
3355 };
3356
3357
3358 // Type testing & conversion functions overridden by concrete subclasses.
3359 // Inline functions for AstNode.
3360
3361 #define DECLARE_NODE_FUNCTIONS(type) \
3362 bool AstNode::Is##type() const { return node_type() == AstNode::k##type; } \
3363 type* AstNode::As##type() { \
3364 return node_type() == AstNode::k##type ? reinterpret_cast<type*>(this) \
3365 : nullptr; \
3366 } \
3367 const type* AstNode::As##type() const { \
3368 return node_type() == AstNode::k##type \
3369 ? reinterpret_cast<const type*>(this) \
3370 : nullptr; \
3371 }
3372 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3373 FAILURE_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3374 #undef DECLARE_NODE_FUNCTIONS
3375
3376 } // namespace internal
3377 } // namespace v8
3378
3379 #endif // V8_AST_AST_H_
3380