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