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