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