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