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