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 "src/ast/ast-types.h"
9 : #include "src/ast/ast-value-factory.h"
10 : #include "src/ast/modules.h"
11 : #include "src/ast/variables.h"
12 : #include "src/bailout-reason.h"
13 : #include "src/base/flags.h"
14 : #include "src/factory.h"
15 : #include "src/globals.h"
16 : #include "src/isolate.h"
17 : #include "src/label.h"
18 : #include "src/list.h"
19 : #include "src/objects/literal-objects.h"
20 : #include "src/parsing/token.h"
21 : #include "src/runtime/runtime.h"
22 : #include "src/small-pointer-list.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 :
70 : #define LITERAL_NODE_LIST(V) \
71 : V(RegExpLiteral) \
72 : V(ObjectLiteral) \
73 : V(ArrayLiteral)
74 :
75 : #define PROPERTY_NODE_LIST(V) \
76 : V(Assignment) \
77 : V(CountOperation) \
78 : V(Property)
79 :
80 : #define CALL_NODE_LIST(V) \
81 : V(Call) \
82 : V(CallNew)
83 :
84 : #define EXPRESSION_NODE_LIST(V) \
85 : LITERAL_NODE_LIST(V) \
86 : PROPERTY_NODE_LIST(V) \
87 : CALL_NODE_LIST(V) \
88 : V(FunctionLiteral) \
89 : V(ClassLiteral) \
90 : V(NativeFunctionLiteral) \
91 : V(Conditional) \
92 : V(VariableProxy) \
93 : V(Literal) \
94 : V(Suspend) \
95 : V(Throw) \
96 : V(CallRuntime) \
97 : V(UnaryOperation) \
98 : V(BinaryOperation) \
99 : V(CompareOperation) \
100 : V(Spread) \
101 : V(ThisFunction) \
102 : V(SuperPropertyReference) \
103 : V(SuperCallReference) \
104 : V(CaseClause) \
105 : V(EmptyParentheses) \
106 : V(GetIterator) \
107 : V(DoExpression) \
108 : V(RewritableExpression) \
109 : V(ImportCallExpression)
110 :
111 : #define AST_NODE_LIST(V) \
112 : DECLARATION_NODE_LIST(V) \
113 : STATEMENT_NODE_LIST(V) \
114 : EXPRESSION_NODE_LIST(V)
115 :
116 : // Forward declarations
117 : class AstNodeFactory;
118 : class Declaration;
119 : class Module;
120 : class BreakableStatement;
121 : class Expression;
122 : class IterationStatement;
123 : class MaterializedLiteral;
124 : class Statement;
125 : class TypeFeedbackOracle;
126 :
127 : #define DEF_FORWARD_DECLARATION(type) class type;
128 : AST_NODE_LIST(DEF_FORWARD_DECLARATION)
129 : #undef DEF_FORWARD_DECLARATION
130 :
131 : class FeedbackSlotCache {
132 : public:
133 : typedef std::pair<TypeofMode, Variable*> Key;
134 :
135 : explicit FeedbackSlotCache(Zone* zone) : map_(zone) {}
136 :
137 : void Put(TypeofMode typeof_mode, Variable* variable, FeedbackSlot slot) {
138 : Key key = std::make_pair(typeof_mode, variable);
139 : auto entry = std::make_pair(key, slot);
140 : map_.insert(entry);
141 : }
142 :
143 4772403 : FeedbackSlot Get(TypeofMode typeof_mode, Variable* variable) const {
144 4772403 : Key key = std::make_pair(typeof_mode, variable);
145 : auto iter = map_.find(key);
146 4772402 : if (iter != map_.end()) {
147 1740057 : return iter->second;
148 : }
149 3032345 : return FeedbackSlot();
150 : }
151 :
152 : private:
153 : ZoneMap<Key, FeedbackSlot> map_;
154 : };
155 :
156 :
157 3491858 : class AstProperties final BASE_EMBEDDED {
158 : public:
159 : enum Flag {
160 : kNoFlags = 0,
161 : kDontSelfOptimize = 1 << 0,
162 : kMustUseIgnitionTurbo = 1 << 1
163 : };
164 :
165 : typedef base::Flags<Flag> Flags;
166 :
167 13519498 : explicit AstProperties(Zone* zone) : node_count_(0), spec_(zone) {}
168 :
169 : Flags& flags() { return flags_; }
170 : Flags flags() const { return flags_; }
171 : int node_count() { return node_count_; }
172 153642198 : void add_node_count(int count) { node_count_ += count; }
173 :
174 : const FeedbackVectorSpec* get_spec() const { return &spec_; }
175 : FeedbackVectorSpec* get_spec() { return &spec_; }
176 :
177 : private:
178 : Flags flags_;
179 : int node_count_;
180 : FeedbackVectorSpec spec_;
181 : };
182 :
183 : DEFINE_OPERATORS_FOR_FLAGS(AstProperties::Flags)
184 :
185 :
186 : class AstNode: public ZoneObject {
187 : public:
188 : #define DECLARE_TYPE_ENUM(type) k##type,
189 : enum NodeType : uint8_t { AST_NODE_LIST(DECLARE_TYPE_ENUM) };
190 : #undef DECLARE_TYPE_ENUM
191 :
192 430847895 : void* operator new(size_t size, Zone* zone) { return zone->New(size); }
193 :
194 2610048886 : NodeType node_type() const { return NodeTypeField::decode(bit_field_); }
195 167982 : int position() const { return position_; }
196 :
197 : #ifdef DEBUG
198 : void Print();
199 : void Print(Isolate* isolate);
200 : #endif // DEBUG
201 :
202 : // Type testing & conversion functions overridden by concrete subclasses.
203 : #define DECLARE_NODE_FUNCTIONS(type) \
204 : V8_INLINE bool Is##type() const; \
205 : V8_INLINE type* As##type(); \
206 : V8_INLINE const type* As##type() const;
207 : AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
208 : #undef DECLARE_NODE_FUNCTIONS
209 :
210 : BreakableStatement* AsBreakableStatement();
211 : IterationStatement* AsIterationStatement();
212 : MaterializedLiteral* AsMaterializedLiteral();
213 :
214 : private:
215 : // Hidden to prevent accidental usage. It would have to load the
216 : // current zone from the TLS.
217 : void* operator new(size_t size);
218 :
219 : int position_;
220 : class NodeTypeField : public BitField<NodeType, 0, 6> {};
221 :
222 : protected:
223 : uint32_t bit_field_;
224 : static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext;
225 :
226 : AstNode(int position, NodeType type)
227 430847768 : : position_(position), bit_field_(NodeTypeField::encode(type)) {}
228 : };
229 :
230 :
231 : class Statement : public AstNode {
232 : public:
233 105114992 : bool IsEmpty() { return AsEmptyStatement() != NULL; }
234 : bool IsJump() const;
235 :
236 : protected:
237 : Statement(int position, NodeType type) : AstNode(position, type) {}
238 :
239 : static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
240 : };
241 :
242 :
243 : class SmallMapList final {
244 : public:
245 : SmallMapList() {}
246 : SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
247 :
248 175865 : void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
249 : void Clear() { list_.Clear(); }
250 89 : void Sort() { list_.Sort(); }
251 :
252 : bool is_empty() const { return list_.is_empty(); }
253 : int length() const { return list_.length(); }
254 :
255 196175 : void AddMapIfMissing(Handle<Map> map, Zone* zone) {
256 392350 : if (!Map::TryUpdate(map).ToHandle(&map)) return;
257 251099 : for (int i = 0; i < length(); ++i) {
258 29225 : if (at(i).is_identical_to(map)) return;
259 : }
260 : Add(map, zone);
261 : }
262 :
263 104464 : void FilterForPossibleTransitions(Map* root_map) {
264 209326 : for (int i = list_.length() - 1; i >= 0; i--) {
265 104862 : if (at(i)->FindRootMap() != root_map) {
266 1210 : list_.RemoveElement(list_.at(i));
267 : }
268 : }
269 104464 : }
270 :
271 : void Add(Handle<Map> handle, Zone* zone) {
272 270663 : list_.Add(handle.location(), zone);
273 : }
274 :
275 : Handle<Map> at(int i) const {
276 : return Handle<Map>(list_.at(i));
277 : }
278 :
279 : Handle<Map> first() const { return at(0); }
280 : Handle<Map> last() const { return at(length() - 1); }
281 :
282 : private:
283 : // The list stores pointers to Map*, that is Map**, so it's GC safe.
284 : SmallPointerList<Map*> list_;
285 :
286 : DISALLOW_COPY_AND_ASSIGN(SmallMapList);
287 : };
288 :
289 :
290 : class Expression : public AstNode {
291 : public:
292 : enum Context {
293 : // Not assigned a context yet, or else will not be visited during
294 : // code generation.
295 : kUninitialized,
296 : // Evaluated for its side effects.
297 : kEffect,
298 : // Evaluated for its value (and side effects).
299 : kValue,
300 : // Evaluated for control flow (and side effects).
301 : kTest
302 : };
303 :
304 : // Mark this expression as being in tail position.
305 : void MarkTail();
306 :
307 : // True iff the expression is a valid reference expression.
308 : bool IsValidReferenceExpression() const;
309 :
310 : // Helpers for ToBoolean conversion.
311 : bool ToBooleanIsTrue() const;
312 : bool ToBooleanIsFalse() const;
313 :
314 : // Symbols that cannot be parsed as array indices are considered property
315 : // names. We do not treat symbols that can be array indexes as property
316 : // names because [] for string objects is handled only by keyed ICs.
317 : bool IsPropertyName() const;
318 :
319 : // True iff the expression is a class or function expression without
320 : // a syntactic name.
321 : bool IsAnonymousFunctionDefinition() const;
322 :
323 : // True iff the expression is a literal represented as a smi.
324 : bool IsSmiLiteral() const;
325 :
326 : // True iff the expression is a literal represented as a number.
327 : bool IsNumberLiteral() const;
328 :
329 : // True iff the expression is a string literal.
330 : bool IsStringLiteral() const;
331 :
332 : // True iff the expression is the null literal.
333 : bool IsNullLiteral() const;
334 :
335 : // True if we can prove that the expression is the undefined literal. Note
336 : // that this also checks for loads of the global "undefined" variable.
337 : bool IsUndefinedLiteral() const;
338 :
339 : // True iff the expression is a valid target for an assignment.
340 : bool IsValidReferenceExpressionOrThis() const;
341 :
342 : // TODO(rossberg): this should move to its own AST node eventually.
343 : void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
344 : uint16_t to_boolean_types() const {
345 : return ToBooleanTypesField::decode(bit_field_);
346 : }
347 :
348 : SmallMapList* GetReceiverTypes();
349 : KeyedAccessStoreMode GetStoreMode() const;
350 : IcCheckType GetKeyType() const;
351 : bool IsMonomorphic() const;
352 :
353 117408119 : void set_base_id(int id) { base_id_ = id; }
354 : static int num_ids() { return parent_num_ids() + 2; }
355 : BailoutId id() const { return BailoutId(local_id(0)); }
356 : TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
357 :
358 : private:
359 25812438 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
360 :
361 : int base_id_;
362 : class ToBooleanTypesField
363 : : public BitField<uint16_t, AstNode::kNextBitFieldIndex, 9> {};
364 :
365 : protected:
366 : Expression(int pos, NodeType type)
367 327216011 : : AstNode(pos, type), base_id_(BailoutId::None().ToInt()) {
368 : bit_field_ = ToBooleanTypesField::update(bit_field_, 0);
369 : }
370 :
371 : static int parent_num_ids() { return 0; }
372 : void set_to_boolean_types(uint16_t types) {
373 2714298 : bit_field_ = ToBooleanTypesField::update(bit_field_, types);
374 : }
375 : int base_id() const {
376 : DCHECK(!BailoutId(base_id_).IsNone());
377 : return base_id_;
378 : }
379 :
380 : static const uint8_t kNextBitFieldIndex = ToBooleanTypesField::kNext;
381 : };
382 :
383 :
384 : class BreakableStatement : public Statement {
385 : public:
386 : enum BreakableType {
387 : TARGET_FOR_ANONYMOUS,
388 : TARGET_FOR_NAMED_ONLY
389 : };
390 :
391 : // The labels associated with this statement. May be NULL;
392 : // if it is != NULL, guaranteed to contain at least one entry.
393 : ZoneList<const AstRawString*>* labels() const { return labels_; }
394 :
395 : // Code generation
396 : Label* break_target() { return &break_target_; }
397 :
398 : // Testers.
399 : bool is_target_for_anonymous() const {
400 : return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS;
401 : }
402 :
403 8387753 : void set_base_id(int id) { base_id_ = id; }
404 : static int num_ids() { return parent_num_ids() + 2; }
405 : BailoutId EntryId() const { return BailoutId(local_id(0)); }
406 : BailoutId ExitId() const { return BailoutId(local_id(1)); }
407 :
408 : private:
409 2308440 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
410 :
411 : BreakableType breakableType() const {
412 : return BreakableTypeField::decode(bit_field_);
413 : }
414 :
415 : int base_id_;
416 : Label break_target_;
417 : ZoneList<const AstRawString*>* labels_;
418 :
419 : class BreakableTypeField
420 : : public BitField<BreakableType, Statement::kNextBitFieldIndex, 1> {};
421 :
422 : protected:
423 : BreakableStatement(ZoneList<const AstRawString*>* labels,
424 : BreakableType breakable_type, int position, NodeType type)
425 : : Statement(position, type),
426 : base_id_(BailoutId::None().ToInt()),
427 50099318 : labels_(labels) {
428 : DCHECK(labels == NULL || labels->length() > 0);
429 23820101 : bit_field_ |= BreakableTypeField::encode(breakable_type);
430 : }
431 : static int parent_num_ids() { return 0; }
432 :
433 : int base_id() const {
434 : DCHECK(!BailoutId(base_id_).IsNone());
435 : return base_id_;
436 : }
437 :
438 : static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext;
439 : };
440 :
441 :
442 : class Block final : public BreakableStatement {
443 : public:
444 880818 : ZoneList<Statement*>* statements() { return &statements_; }
445 : bool ignore_completion_value() const {
446 : return IgnoreCompletionField::decode(bit_field_);
447 : }
448 :
449 : static int num_ids() { return parent_num_ids() + 1; }
450 : BailoutId DeclsId() const { return BailoutId(local_id(0)); }
451 :
452 7514678 : bool IsJump() const {
453 12916213 : return !statements_.is_empty() && statements_.last()->IsJump()
454 8074435 : && labels() == NULL; // Good enough as an approximation...
455 : }
456 :
457 : Scope* scope() const { return scope_; }
458 6380002 : void set_scope(Scope* scope) { scope_ = scope; }
459 :
460 : private:
461 : friend class AstNodeFactory;
462 :
463 : Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
464 : bool ignore_completion_value, int pos)
465 : : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY, pos, kBlock),
466 : statements_(capacity, zone),
467 23820101 : scope_(NULL) {
468 23820100 : bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value);
469 : }
470 : static int parent_num_ids() { return BreakableStatement::num_ids(); }
471 1994152 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
472 :
473 : ZoneList<Statement*> statements_;
474 : Scope* scope_;
475 :
476 : class IgnoreCompletionField
477 : : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {};
478 : };
479 :
480 :
481 : class DoExpression final : public Expression {
482 : public:
483 : Block* block() { return block_; }
484 0 : void set_block(Block* b) { block_ = b; }
485 : VariableProxy* result() { return result_; }
486 0 : void set_result(VariableProxy* v) { result_ = v; }
487 : FunctionLiteral* represented_function() { return represented_function_; }
488 92611 : void set_represented_function(FunctionLiteral* f) {
489 92611 : represented_function_ = f;
490 92611 : }
491 : bool IsAnonymousFunctionDefinition() const;
492 :
493 : private:
494 : friend class AstNodeFactory;
495 :
496 : DoExpression(Block* block, VariableProxy* result, int pos)
497 : : Expression(pos, kDoExpression),
498 : block_(block),
499 : result_(result),
500 435266 : represented_function_(nullptr) {
501 : DCHECK_NOT_NULL(block_);
502 : DCHECK_NOT_NULL(result_);
503 : }
504 : static int parent_num_ids() { return Expression::num_ids(); }
505 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
506 :
507 : Block* block_;
508 : VariableProxy* result_;
509 : FunctionLiteral* represented_function_;
510 : };
511 :
512 :
513 : class Declaration : public AstNode {
514 : public:
515 : typedef ThreadedList<Declaration> List;
516 :
517 99748 : VariableProxy* proxy() const { return proxy_; }
518 : Scope* scope() const { return scope_; }
519 :
520 : protected:
521 : Declaration(VariableProxy* proxy, Scope* scope, int pos, NodeType type)
522 16427514 : : AstNode(pos, type), proxy_(proxy), scope_(scope), next_(nullptr) {}
523 :
524 : private:
525 : VariableProxy* proxy_;
526 : // Nested scope from which the declaration originated.
527 : Scope* scope_;
528 : // Declarations list threaded through the declarations.
529 : Declaration** next() { return &next_; }
530 : Declaration* next_;
531 : friend List;
532 : };
533 :
534 :
535 : class VariableDeclaration final : public Declaration {
536 : private:
537 : friend class AstNodeFactory;
538 :
539 : VariableDeclaration(VariableProxy* proxy, Scope* scope, int pos)
540 : : Declaration(proxy, scope, pos, kVariableDeclaration) {}
541 : };
542 :
543 :
544 : class FunctionDeclaration final : public Declaration {
545 : public:
546 : FunctionLiteral* fun() const { return fun_; }
547 22512 : void set_fun(FunctionLiteral* f) { fun_ = f; }
548 :
549 : private:
550 : friend class AstNodeFactory;
551 :
552 : FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, Scope* scope,
553 : int pos)
554 1752082 : : Declaration(proxy, scope, pos, kFunctionDeclaration), fun_(fun) {
555 : DCHECK(fun != NULL);
556 : }
557 :
558 : FunctionLiteral* fun_;
559 : };
560 :
561 :
562 : class IterationStatement : public BreakableStatement {
563 : public:
564 : Statement* body() const { return body_; }
565 80268 : void set_body(Statement* s) { body_ = s; }
566 :
567 : int suspend_count() const { return suspend_count_; }
568 : int first_suspend_id() const { return first_suspend_id_; }
569 355206 : void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
570 : void set_first_suspend_id(int first_suspend_id) {
571 355206 : first_suspend_id_ = first_suspend_id;
572 : }
573 :
574 : static int num_ids() { return parent_num_ids() + 1; }
575 : BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
576 :
577 : // Code generation
578 : Label* continue_target() { return &continue_target_; }
579 :
580 : protected:
581 : IterationStatement(ZoneList<const AstRawString*>* labels, int pos,
582 : NodeType type)
583 : : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, type),
584 : body_(NULL),
585 : suspend_count_(0),
586 2274408 : first_suspend_id_(0) {}
587 : static int parent_num_ids() { return BreakableStatement::num_ids(); }
588 1109793 : void Initialize(Statement* body) { body_ = body; }
589 :
590 : static const uint8_t kNextBitFieldIndex =
591 : BreakableStatement::kNextBitFieldIndex;
592 :
593 : private:
594 288615 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
595 :
596 : Statement* body_;
597 : Label continue_target_;
598 : int suspend_count_;
599 : int first_suspend_id_;
600 : };
601 :
602 :
603 : class DoWhileStatement final : public IterationStatement {
604 : public:
605 : void Initialize(Expression* cond, Statement* body) {
606 : IterationStatement::Initialize(body);
607 13845 : cond_ = cond;
608 : }
609 :
610 : Expression* cond() const { return cond_; }
611 0 : void set_cond(Expression* e) { cond_ = e; }
612 :
613 : static int num_ids() { return parent_num_ids() + 2; }
614 : BailoutId ContinueId() const { return BailoutId(local_id(0)); }
615 : BailoutId StackCheckId() const { return BackEdgeId(); }
616 : BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
617 :
618 : private:
619 : friend class AstNodeFactory;
620 :
621 : DoWhileStatement(ZoneList<const AstRawString*>* labels, int pos)
622 14676 : : IterationStatement(labels, pos, kDoWhileStatement), cond_(NULL) {}
623 : static int parent_num_ids() { return IterationStatement::num_ids(); }
624 8808 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
625 :
626 : Expression* cond_;
627 : };
628 :
629 :
630 : class WhileStatement final : public IterationStatement {
631 : public:
632 : void Initialize(Expression* cond, Statement* body) {
633 : IterationStatement::Initialize(body);
634 111535 : cond_ = cond;
635 : }
636 :
637 : Expression* cond() const { return cond_; }
638 0 : void set_cond(Expression* e) { cond_ = e; }
639 :
640 : static int num_ids() { return parent_num_ids() + 1; }
641 : BailoutId ContinueId() const { return EntryId(); }
642 : BailoutId StackCheckId() const { return BodyId(); }
643 : BailoutId BodyId() const { return BailoutId(local_id(0)); }
644 :
645 : private:
646 : friend class AstNodeFactory;
647 :
648 : WhileStatement(ZoneList<const AstRawString*>* labels, int pos)
649 112260 : : IterationStatement(labels, pos, kWhileStatement), cond_(NULL) {}
650 : static int parent_num_ids() { return IterationStatement::num_ids(); }
651 20044 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
652 :
653 : Expression* cond_;
654 : };
655 :
656 :
657 : class ForStatement final : public IterationStatement {
658 : public:
659 : void Initialize(Statement* init,
660 : Expression* cond,
661 : Statement* next,
662 : Statement* body) {
663 : IterationStatement::Initialize(body);
664 785243 : init_ = init;
665 785243 : cond_ = cond;
666 785243 : next_ = next;
667 : }
668 :
669 : Statement* init() const { return init_; }
670 : Expression* cond() const { return cond_; }
671 : Statement* next() const { return next_; }
672 :
673 0 : void set_init(Statement* s) { init_ = s; }
674 0 : void set_cond(Expression* e) { cond_ = e; }
675 0 : void set_next(Statement* s) { next_ = s; }
676 :
677 : static int num_ids() { return parent_num_ids() + 2; }
678 : BailoutId ContinueId() const { return BailoutId(local_id(0)); }
679 : BailoutId StackCheckId() const { return BodyId(); }
680 : BailoutId BodyId() const { return BailoutId(local_id(1)); }
681 :
682 : private:
683 : friend class AstNodeFactory;
684 :
685 : ForStatement(ZoneList<const AstRawString*>* labels, int pos)
686 : : IterationStatement(labels, pos, kForStatement),
687 : init_(NULL),
688 : cond_(NULL),
689 787600 : next_(NULL) {}
690 : static int parent_num_ids() { return IterationStatement::num_ids(); }
691 276690 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
692 :
693 : Statement* init_;
694 : Expression* cond_;
695 : Statement* next_;
696 : };
697 :
698 :
699 : class ForEachStatement : public IterationStatement {
700 : public:
701 : enum VisitMode {
702 : ENUMERATE, // for (each in subject) body;
703 : ITERATE // for (each of subject) body;
704 : };
705 :
706 : using IterationStatement::Initialize;
707 :
708 : static const char* VisitModeString(VisitMode mode) {
709 5577 : return mode == ITERATE ? "for-of" : "for-in";
710 : }
711 :
712 : protected:
713 : ForEachStatement(ZoneList<const AstRawString*>* labels, int pos,
714 : NodeType type)
715 : : IterationStatement(labels, pos, type) {}
716 : };
717 :
718 :
719 : class ForInStatement final : public ForEachStatement {
720 : public:
721 : void Initialize(Expression* each, Expression* subject, Statement* body) {
722 : ForEachStatement::Initialize(body);
723 65271 : each_ = each;
724 65271 : subject_ = subject;
725 : }
726 :
727 18917 : Expression* enumerable() const {
728 : return subject();
729 : }
730 :
731 : Expression* each() const { return each_; }
732 : Expression* subject() const { return subject_; }
733 :
734 0 : void set_each(Expression* e) { each_ = e; }
735 0 : void set_subject(Expression* e) { subject_ = e; }
736 :
737 : // Type feedback information.
738 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
739 : FeedbackSlotCache* cache);
740 : FeedbackSlot EachFeedbackSlot() const { return each_slot_; }
741 : FeedbackSlot ForInFeedbackSlot() {
742 : DCHECK(!for_in_feedback_slot_.IsInvalid());
743 : return for_in_feedback_slot_;
744 : }
745 :
746 : enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
747 : ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); }
748 : void set_for_in_type(ForInType type) {
749 2280 : bit_field_ = ForInTypeField::update(bit_field_, type);
750 : }
751 :
752 : static int num_ids() { return parent_num_ids() + 7; }
753 : BailoutId BodyId() const { return BailoutId(local_id(0)); }
754 : BailoutId EnumId() const { return BailoutId(local_id(1)); }
755 : BailoutId ToObjectId() const { return BailoutId(local_id(2)); }
756 : BailoutId PrepareId() const { return BailoutId(local_id(3)); }
757 : BailoutId FilterId() const { return BailoutId(local_id(4)); }
758 : BailoutId AssignmentId() const { return BailoutId(local_id(5)); }
759 : BailoutId IncrementId() const { return BailoutId(local_id(6)); }
760 : BailoutId StackCheckId() const { return BodyId(); }
761 :
762 : private:
763 : friend class AstNodeFactory;
764 :
765 : ForInStatement(ZoneList<const AstRawString*>* labels, int pos)
766 : : ForEachStatement(labels, pos, kForInStatement),
767 : each_(nullptr),
768 71499 : subject_(nullptr) {
769 71499 : bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN);
770 : }
771 :
772 : static int parent_num_ids() { return ForEachStatement::num_ids(); }
773 25939 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
774 :
775 : Expression* each_;
776 : Expression* subject_;
777 : FeedbackSlot each_slot_;
778 : FeedbackSlot for_in_feedback_slot_;
779 :
780 : class ForInTypeField
781 : : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {};
782 : };
783 :
784 :
785 : class ForOfStatement final : public ForEachStatement {
786 : public:
787 : void Initialize(Statement* body, Variable* iterator,
788 : Expression* assign_iterator, Expression* next_result,
789 : Expression* result_done, Expression* assign_each) {
790 : ForEachStatement::Initialize(body);
791 133899 : iterator_ = iterator;
792 133899 : assign_iterator_ = assign_iterator;
793 133899 : next_result_ = next_result;
794 133899 : result_done_ = result_done;
795 133899 : assign_each_ = assign_each;
796 : }
797 :
798 : Variable* iterator() const {
799 : return iterator_;
800 : }
801 :
802 : // iterator = subject[Symbol.iterator]()
803 : Expression* assign_iterator() const {
804 : return assign_iterator_;
805 : }
806 :
807 : // result = iterator.next() // with type check
808 : Expression* next_result() const {
809 : return next_result_;
810 : }
811 :
812 : // result.done
813 : Expression* result_done() const {
814 : return result_done_;
815 : }
816 :
817 : // each = result.value
818 : Expression* assign_each() const {
819 : return assign_each_;
820 : }
821 :
822 0 : void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
823 0 : void set_next_result(Expression* e) { next_result_ = e; }
824 0 : void set_result_done(Expression* e) { result_done_ = e; }
825 0 : void set_assign_each(Expression* e) { assign_each_ = e; }
826 :
827 : private:
828 : friend class AstNodeFactory;
829 :
830 : ForOfStatement(ZoneList<const AstRawString*>* labels, int pos)
831 : : ForEachStatement(labels, pos, kForOfStatement),
832 : iterator_(NULL),
833 : assign_iterator_(NULL),
834 : next_result_(NULL),
835 : result_done_(NULL),
836 151169 : assign_each_(NULL) {}
837 :
838 : Variable* iterator_;
839 : Expression* assign_iterator_;
840 : Expression* next_result_;
841 : Expression* result_done_;
842 : Expression* assign_each_;
843 : };
844 :
845 :
846 : class ExpressionStatement final : public Statement {
847 : public:
848 1492824 : void set_expression(Expression* e) { expression_ = e; }
849 5849170 : Expression* expression() const { return expression_; }
850 37837202 : bool IsJump() const { return expression_->IsThrow(); }
851 :
852 : private:
853 : friend class AstNodeFactory;
854 :
855 : ExpressionStatement(Expression* expression, int pos)
856 38736597 : : Statement(pos, kExpressionStatement), expression_(expression) {}
857 :
858 : Expression* expression_;
859 : };
860 :
861 :
862 : class JumpStatement : public Statement {
863 : public:
864 : bool IsJump() const { return true; }
865 :
866 : protected:
867 : JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
868 : };
869 :
870 :
871 : class ContinueStatement final : public JumpStatement {
872 : public:
873 : IterationStatement* target() const { return target_; }
874 :
875 : private:
876 : friend class AstNodeFactory;
877 :
878 : ContinueStatement(IterationStatement* target, int pos)
879 96521 : : JumpStatement(pos, kContinueStatement), target_(target) {}
880 :
881 : IterationStatement* target_;
882 : };
883 :
884 :
885 : class BreakStatement final : public JumpStatement {
886 : public:
887 : BreakableStatement* target() const { return target_; }
888 :
889 : private:
890 : friend class AstNodeFactory;
891 :
892 : BreakStatement(BreakableStatement* target, int pos)
893 335168 : : JumpStatement(pos, kBreakStatement), target_(target) {}
894 :
895 : BreakableStatement* target_;
896 : };
897 :
898 :
899 : class ReturnStatement final : public JumpStatement {
900 : public:
901 : enum Type { kNormal, kAsyncReturn };
902 : Expression* expression() const { return expression_; }
903 :
904 0 : void set_expression(Expression* e) { expression_ = e; }
905 : Type type() const { return TypeField::decode(bit_field_); }
906 2094887 : bool is_async_return() const { return type() == kAsyncReturn; }
907 :
908 : private:
909 : friend class AstNodeFactory;
910 :
911 : ReturnStatement(Expression* expression, Type type, int pos)
912 7514385 : : JumpStatement(pos, kReturnStatement), expression_(expression) {
913 22280 : bit_field_ |= TypeField::encode(type);
914 : }
915 :
916 : Expression* expression_;
917 :
918 : class TypeField
919 : : public BitField<Type, JumpStatement::kNextBitFieldIndex, 1> {};
920 : };
921 :
922 :
923 : class WithStatement final : public Statement {
924 : public:
925 : Scope* scope() { return scope_; }
926 : Expression* expression() const { return expression_; }
927 0 : void set_expression(Expression* e) { expression_ = e; }
928 : Statement* statement() const { return statement_; }
929 4821 : void set_statement(Statement* s) { statement_ = s; }
930 :
931 : private:
932 : friend class AstNodeFactory;
933 :
934 : WithStatement(Scope* scope, Expression* expression, Statement* statement,
935 : int pos)
936 : : Statement(pos, kWithStatement),
937 : scope_(scope),
938 : expression_(expression),
939 55609 : statement_(statement) {}
940 :
941 : Scope* scope_;
942 : Expression* expression_;
943 : Statement* statement_;
944 : };
945 :
946 :
947 : class CaseClause final : public Expression {
948 : public:
949 583065 : bool is_default() const { return label_ == NULL; }
950 583065 : Expression* label() const {
951 583065 : CHECK(!is_default());
952 583065 : return label_;
953 : }
954 0 : void set_label(Expression* e) { label_ = e; }
955 : Label* body_target() { return &body_target_; }
956 : ZoneList<Statement*>* statements() const { return statements_; }
957 :
958 : static int num_ids() { return parent_num_ids() + 2; }
959 : BailoutId EntryId() const { return BailoutId(local_id(0)); }
960 : TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
961 :
962 : AstType* compare_type() { return compare_type_; }
963 28295 : void set_compare_type(AstType* type) { compare_type_ = type; }
964 :
965 : // CaseClause will have both a slot in the feedback vector and the
966 : // TypeFeedbackId to record the type information. TypeFeedbackId is used by
967 : // full codegen and the feedback vector slot is used by interpreter.
968 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
969 : FeedbackSlotCache* cache);
970 :
971 : FeedbackSlot CompareOperationFeedbackSlot() { return feedback_slot_; }
972 :
973 : private:
974 : friend class AstNodeFactory;
975 :
976 : static int parent_num_ids() { return Expression::num_ids(); }
977 : CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
978 192115 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
979 :
980 : Expression* label_;
981 : Label body_target_;
982 : ZoneList<Statement*>* statements_;
983 : AstType* compare_type_;
984 : FeedbackSlot feedback_slot_;
985 : };
986 :
987 :
988 : class SwitchStatement final : public BreakableStatement {
989 : public:
990 : void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
991 91680 : tag_ = tag;
992 91680 : cases_ = cases;
993 : }
994 :
995 : Expression* tag() const { return tag_; }
996 : ZoneList<CaseClause*>* cases() const { return cases_; }
997 :
998 0 : void set_tag(Expression* t) { tag_ = t; }
999 :
1000 : private:
1001 : friend class AstNodeFactory;
1002 :
1003 : SwitchStatement(ZoneList<const AstRawString*>* labels, int pos)
1004 : : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, kSwitchStatement),
1005 : tag_(NULL),
1006 92354 : cases_(NULL) {}
1007 :
1008 : Expression* tag_;
1009 : ZoneList<CaseClause*>* cases_;
1010 : };
1011 :
1012 :
1013 : // If-statements always have non-null references to their then- and
1014 : // else-parts. When parsing if-statements with no explicit else-part,
1015 : // the parser implicitly creates an empty statement. Use the
1016 : // HasThenStatement() and HasElseStatement() functions to check if a
1017 : // given if-statement has a then- or an else-part containing code.
1018 : class IfStatement final : public Statement {
1019 : public:
1020 2514841 : bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1021 5147881 : bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1022 :
1023 : Expression* condition() const { return condition_; }
1024 : Statement* then_statement() const { return then_statement_; }
1025 : Statement* else_statement() const { return else_statement_; }
1026 :
1027 0 : void set_condition(Expression* e) { condition_ = e; }
1028 3530 : void set_then_statement(Statement* s) { then_statement_ = s; }
1029 3530 : void set_else_statement(Statement* s) { else_statement_ = s; }
1030 :
1031 4817518 : bool IsJump() const {
1032 2314356 : return HasThenStatement() && then_statement()->IsJump()
1033 3868095 : && HasElseStatement() && else_statement()->IsJump();
1034 : }
1035 :
1036 2093040 : void set_base_id(int id) { base_id_ = id; }
1037 : static int num_ids() { return parent_num_ids() + 3; }
1038 : BailoutId IfId() const { return BailoutId(local_id(0)); }
1039 : BailoutId ThenId() const { return BailoutId(local_id(1)); }
1040 : BailoutId ElseId() const { return BailoutId(local_id(2)); }
1041 :
1042 : private:
1043 : friend class AstNodeFactory;
1044 :
1045 : IfStatement(Expression* condition, Statement* then_statement,
1046 : Statement* else_statement, int pos)
1047 : : Statement(pos, kIfStatement),
1048 : base_id_(BailoutId::None().ToInt()),
1049 : condition_(condition),
1050 : then_statement_(then_statement),
1051 6321653 : else_statement_(else_statement) {}
1052 :
1053 : static int parent_num_ids() { return 0; }
1054 : int base_id() const {
1055 : DCHECK(!BailoutId(base_id_).IsNone());
1056 : return base_id_;
1057 : }
1058 2730097 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1059 :
1060 : int base_id_;
1061 : Expression* condition_;
1062 : Statement* then_statement_;
1063 : Statement* else_statement_;
1064 : };
1065 :
1066 :
1067 : class TryStatement : public Statement {
1068 : public:
1069 : Block* try_block() const { return try_block_; }
1070 12429 : void set_try_block(Block* b) { try_block_ = b; }
1071 :
1072 : // Prediction of whether exceptions thrown into the handler for this try block
1073 : // will be caught.
1074 : //
1075 : // This is set in ast-numbering and later compiled into the code's handler
1076 : // table. The runtime uses this information to implement a feature that
1077 : // notifies the debugger when an uncaught exception is thrown, _before_ the
1078 : // exception propagates to the top.
1079 : //
1080 : // Since it's generally undecidable whether an exception will be caught, our
1081 : // prediction is only an approximation.
1082 : HandlerTable::CatchPrediction catch_prediction() const {
1083 : return catch_prediction_;
1084 : }
1085 : void set_catch_prediction(HandlerTable::CatchPrediction prediction) {
1086 213933 : catch_prediction_ = prediction;
1087 : }
1088 :
1089 : protected:
1090 : TryStatement(Block* try_block, int pos, NodeType type)
1091 : : Statement(pos, type),
1092 : catch_prediction_(HandlerTable::UNCAUGHT),
1093 1038936 : try_block_(try_block) {}
1094 :
1095 : HandlerTable::CatchPrediction catch_prediction_;
1096 :
1097 : private:
1098 : Block* try_block_;
1099 : };
1100 :
1101 :
1102 : class TryCatchStatement final : public TryStatement {
1103 : public:
1104 : Scope* scope() { return scope_; }
1105 : Block* catch_block() const { return catch_block_; }
1106 8357 : void set_catch_block(Block* b) { catch_block_ = b; }
1107 :
1108 : // The clear_pending_message flag indicates whether or not to clear the
1109 : // isolate's pending exception message before executing the catch_block. In
1110 : // the normal use case, this flag is always on because the message object
1111 : // is not needed anymore when entering the catch block and should not be kept
1112 : // alive.
1113 : // The use case where the flag is off is when the catch block is guaranteed to
1114 : // rethrow the caught exception (using %ReThrow), which reuses the pending
1115 : // message instead of generating a new one.
1116 : // (When the catch block doesn't rethrow but is guaranteed to perform an
1117 : // ordinary throw, not clearing the old message is safe but not very useful.)
1118 : bool clear_pending_message() const {
1119 : return catch_prediction_ != HandlerTable::UNCAUGHT;
1120 : }
1121 :
1122 : private:
1123 : friend class AstNodeFactory;
1124 :
1125 : TryCatchStatement(Block* try_block, Scope* scope, Block* catch_block,
1126 : HandlerTable::CatchPrediction catch_prediction, int pos)
1127 : : TryStatement(try_block, pos, kTryCatchStatement),
1128 : scope_(scope),
1129 748956 : catch_block_(catch_block) {
1130 543588 : catch_prediction_ = catch_prediction;
1131 : }
1132 :
1133 : Scope* scope_;
1134 : Block* catch_block_;
1135 : };
1136 :
1137 :
1138 : class TryFinallyStatement final : public TryStatement {
1139 : public:
1140 : Block* finally_block() const { return finally_block_; }
1141 301 : void set_finally_block(Block* b) { finally_block_ = b; }
1142 :
1143 : private:
1144 : friend class AstNodeFactory;
1145 :
1146 : TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
1147 : : TryStatement(try_block, pos, kTryFinallyStatement),
1148 289980 : finally_block_(finally_block) {}
1149 :
1150 : Block* finally_block_;
1151 : };
1152 :
1153 :
1154 : class DebuggerStatement final : public Statement {
1155 : private:
1156 : friend class AstNodeFactory;
1157 :
1158 : explicit DebuggerStatement(int pos) : Statement(pos, kDebuggerStatement) {}
1159 : };
1160 :
1161 :
1162 : class EmptyStatement final : public Statement {
1163 : private:
1164 : friend class AstNodeFactory;
1165 : explicit EmptyStatement(int pos) : Statement(pos, kEmptyStatement) {}
1166 : };
1167 :
1168 :
1169 : // Delegates to another statement, which may be overwritten.
1170 : // This was introduced to implement ES2015 Annex B3.3 for conditionally making
1171 : // sloppy-mode block-scoped functions have a var binding, which is changed
1172 : // from one statement to another during parsing.
1173 : class SloppyBlockFunctionStatement final : public Statement {
1174 : public:
1175 : Statement* statement() const { return statement_; }
1176 10232 : void set_statement(Statement* statement) { statement_ = statement; }
1177 :
1178 : private:
1179 : friend class AstNodeFactory;
1180 :
1181 : explicit SloppyBlockFunctionStatement(Statement* statement)
1182 : : Statement(kNoSourcePosition, kSloppyBlockFunctionStatement),
1183 10583 : statement_(statement) {}
1184 :
1185 : Statement* statement_;
1186 : };
1187 :
1188 :
1189 : class Literal final : public Expression {
1190 : public:
1191 : // Returns true if literal represents a property name (i.e. cannot be parsed
1192 : // as array indices).
1193 22554065 : bool IsPropertyName() const { return value_->IsPropertyName(); }
1194 :
1195 575571 : Handle<String> AsPropertyName() {
1196 : DCHECK(IsPropertyName());
1197 : return Handle<String>::cast(value());
1198 : }
1199 :
1200 5546042 : const AstRawString* AsRawPropertyName() {
1201 : DCHECK(IsPropertyName());
1202 11092084 : return value_->AsString();
1203 : }
1204 :
1205 332147 : Smi* AsSmiLiteral() {
1206 : DCHECK(IsSmiLiteral());
1207 332147 : return raw_value()->AsSmi();
1208 : }
1209 :
1210 28009 : bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); }
1211 35659 : bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); }
1212 :
1213 : Handle<Object> value() const { return value_->value(); }
1214 9815027 : const AstValue* raw_value() const { return value_; }
1215 :
1216 : // Support for using Literal as a HashMap key. NOTE: Currently, this works
1217 : // only for string and number literals!
1218 : uint32_t Hash();
1219 : static bool Match(void* literal1, void* literal2);
1220 :
1221 : static int num_ids() { return parent_num_ids() + 1; }
1222 : TypeFeedbackId LiteralFeedbackId() const {
1223 : return TypeFeedbackId(local_id(0));
1224 : }
1225 :
1226 : private:
1227 : friend class AstNodeFactory;
1228 :
1229 : Literal(const AstValue* value, int position)
1230 76686092 : : Expression(position, kLiteral), value_(value) {}
1231 :
1232 : static int parent_num_ids() { return Expression::num_ids(); }
1233 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1234 :
1235 : const AstValue* value_;
1236 : };
1237 :
1238 : // Base class for literals that need space in the type feedback vector.
1239 : class MaterializedLiteral : public Expression {
1240 : public:
1241 : int depth() const {
1242 : // only callable after initialization.
1243 : DCHECK(depth_ >= 1);
1244 1963691 : return depth_;
1245 : }
1246 :
1247 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1248 : FeedbackSlotCache* cache) {
1249 1145104 : literal_slot_ = spec->AddLiteralSlot();
1250 : }
1251 :
1252 : FeedbackSlot literal_slot() const { return literal_slot_; }
1253 :
1254 : private:
1255 : int depth_ : 31;
1256 : FeedbackSlot literal_slot_;
1257 :
1258 : class IsSimpleField
1259 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1260 :
1261 : protected:
1262 : MaterializedLiteral(int pos, NodeType type)
1263 2484798 : : Expression(pos, type), depth_(0) {
1264 : bit_field_ |= IsSimpleField::encode(false);
1265 : }
1266 :
1267 : // A materialized literal is simple if the values consist of only
1268 : // constants and simple object and array literals.
1269 : bool is_simple() const { return IsSimpleField::decode(bit_field_); }
1270 : void set_is_simple(bool is_simple) {
1271 1366592 : bit_field_ = IsSimpleField::update(bit_field_, is_simple);
1272 : }
1273 : friend class CompileTimeValue;
1274 :
1275 : void set_depth(int depth) {
1276 : DCHECK_LE(1, depth);
1277 1154915 : depth_ = depth;
1278 : }
1279 :
1280 : // Populate the depth field and any flags the literal has.
1281 : void InitDepthAndFlags();
1282 :
1283 : // Populate the constant properties/elements fixed array.
1284 : void BuildConstants(Isolate* isolate);
1285 : friend class ArrayLiteral;
1286 : friend class ObjectLiteral;
1287 :
1288 : // If the expression is a literal, return the literal value;
1289 : // if the expression is a materialized literal and is simple return a
1290 : // compile time value as encoded by CompileTimeValue::GetValue().
1291 : // Otherwise, return undefined literal as the placeholder
1292 : // in the object literal boilerplate.
1293 : Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
1294 :
1295 : static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext;
1296 : };
1297 :
1298 : // Common supertype for ObjectLiteralProperty and ClassLiteralProperty
1299 : class LiteralProperty : public ZoneObject {
1300 : public:
1301 : Expression* key() const { return key_; }
1302 14041 : Expression* value() const { return value_; }
1303 0 : void set_key(Expression* e) { key_ = e; }
1304 0 : void set_value(Expression* e) { value_ = e; }
1305 :
1306 : bool is_computed_name() const { return is_computed_name_; }
1307 :
1308 : FeedbackSlot GetSlot(int offset = 0) const {
1309 : DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1310 887730 : return slots_[offset];
1311 : }
1312 :
1313 : FeedbackSlot GetStoreDataPropertySlot() const;
1314 :
1315 : void SetSlot(FeedbackSlot slot, int offset = 0) {
1316 : DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1317 887888 : slots_[offset] = slot;
1318 : }
1319 :
1320 : void SetStoreDataPropertySlot(FeedbackSlot slot);
1321 :
1322 : bool NeedsSetFunctionName() const;
1323 :
1324 : protected:
1325 : LiteralProperty(Expression* key, Expression* value, bool is_computed_name)
1326 15805389 : : key_(key), value_(value), is_computed_name_(is_computed_name) {}
1327 :
1328 : Expression* key_;
1329 : Expression* value_;
1330 : FeedbackSlot slots_[2];
1331 : bool is_computed_name_;
1332 : };
1333 :
1334 : // Property is used for passing information
1335 : // about an object literal's properties from the parser
1336 : // to the code generator.
1337 : class ObjectLiteralProperty final : public LiteralProperty {
1338 : public:
1339 : enum Kind : uint8_t {
1340 : CONSTANT, // Property with constant value (compile time).
1341 : COMPUTED, // Property with computed value (execution time).
1342 : MATERIALIZED_LITERAL, // Property value is a materialized literal.
1343 : GETTER,
1344 : SETTER, // Property is an accessor function.
1345 : PROTOTYPE, // Property is __proto__.
1346 : SPREAD
1347 : };
1348 :
1349 : Kind kind() const { return kind_; }
1350 :
1351 : // Type feedback information.
1352 : bool IsMonomorphic() const { return !receiver_type_.is_null(); }
1353 : Handle<Map> GetReceiverType() const { return receiver_type_; }
1354 :
1355 : bool IsCompileTimeValue() const;
1356 :
1357 : void set_emit_store(bool emit_store);
1358 : bool emit_store() const;
1359 :
1360 25290 : void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
1361 :
1362 : private:
1363 : friend class AstNodeFactory;
1364 :
1365 : ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
1366 : bool is_computed_name);
1367 : ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
1368 : Expression* value, bool is_computed_name);
1369 :
1370 : Kind kind_;
1371 : bool emit_store_;
1372 : Handle<Map> receiver_type_;
1373 : };
1374 :
1375 :
1376 : // An object literal has a boilerplate object that is used
1377 : // for minimizing the work when constructing it at runtime.
1378 : class ObjectLiteral final : public MaterializedLiteral {
1379 : public:
1380 : typedef ObjectLiteralProperty Property;
1381 :
1382 : Handle<BoilerplateDescription> constant_properties() const {
1383 : DCHECK(!constant_properties_.is_null());
1384 : return constant_properties_;
1385 : }
1386 819322 : int properties_count() const { return boilerplate_properties_; }
1387 : ZoneList<Property*>* properties() const { return properties_; }
1388 : bool fast_elements() const { return FastElementsField::decode(bit_field_); }
1389 : bool may_store_doubles() const {
1390 : return MayStoreDoublesField::decode(bit_field_);
1391 : }
1392 : bool has_elements() const { return HasElementsField::decode(bit_field_); }
1393 : bool has_shallow_properties() const {
1394 2724445 : return depth() == 1 && !has_elements() && !may_store_doubles();
1395 : }
1396 : bool has_rest_property() const {
1397 : return HasRestPropertyField::decode(bit_field_);
1398 : }
1399 :
1400 : // Decide if a property should be in the object boilerplate.
1401 : static bool IsBoilerplateProperty(Property* property);
1402 :
1403 : // Populate the depth field and flags.
1404 : void InitDepthAndFlags();
1405 :
1406 : // Get the constant properties fixed array, populating it if necessary.
1407 : Handle<BoilerplateDescription> GetOrBuildConstantProperties(
1408 : Isolate* isolate) {
1409 460139 : if (constant_properties_.is_null()) {
1410 400001 : BuildConstantProperties(isolate);
1411 : }
1412 : return constant_properties();
1413 : }
1414 :
1415 : // Populate the constant properties fixed array.
1416 : void BuildConstantProperties(Isolate* isolate);
1417 :
1418 : // Mark all computed expressions that are bound to a key that
1419 : // is shadowed by a later occurrence of the same key. For the
1420 : // marked expressions, no store code is emitted.
1421 : void CalculateEmitStore(Zone* zone);
1422 :
1423 : // Determines whether the {FastCloneShallowObject} builtin can be used.
1424 : bool IsFastCloningSupported() const;
1425 :
1426 : // Assemble bitfield of flags for the CreateObjectLiteral helper.
1427 510768 : int ComputeFlags(bool disable_mementos = false) const {
1428 510768 : int flags = fast_elements() ? kFastElements : kNoFlags;
1429 510768 : if (has_shallow_properties()) {
1430 146124 : flags |= kShallowProperties;
1431 : }
1432 510768 : if (disable_mementos) {
1433 19422 : flags |= kDisableMementos;
1434 : }
1435 510768 : return flags;
1436 : }
1437 :
1438 : enum Flags {
1439 : kNoFlags = 0,
1440 : kFastElements = 1,
1441 : kShallowProperties = 1 << 1,
1442 : kDisableMementos = 1 << 2,
1443 : kHasRestProperty = 1 << 3,
1444 : };
1445 :
1446 : struct Accessors: public ZoneObject {
1447 5042 : Accessors() : getter(NULL), setter(NULL), bailout_id(BailoutId::None()) {}
1448 : ObjectLiteralProperty* getter;
1449 : ObjectLiteralProperty* setter;
1450 : BailoutId bailout_id;
1451 : };
1452 :
1453 : BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1454 :
1455 : // Return an AST id for a property that is used in simulate instructions.
1456 13942 : BailoutId GetIdForPropertySet(int i) { return BailoutId(local_id(i + 1)); }
1457 :
1458 : // Unlike other AST nodes, this number of bailout IDs allocated for an
1459 : // ObjectLiteral can vary, so num_ids() is not a static method.
1460 752293 : int num_ids() const { return parent_num_ids() + 1 + properties()->length(); }
1461 :
1462 : // Object literals need one feedback slot for each non-trivial value, as well
1463 : // as some slots for home objects.
1464 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1465 : FeedbackSlotCache* cache);
1466 :
1467 : private:
1468 : friend class AstNodeFactory;
1469 :
1470 : ObjectLiteral(ZoneList<Property*>* properties,
1471 : uint32_t boilerplate_properties, int pos,
1472 : bool has_rest_property)
1473 : : MaterializedLiteral(pos, kObjectLiteral),
1474 : boilerplate_properties_(boilerplate_properties),
1475 3181534 : properties_(properties) {
1476 : bit_field_ |= FastElementsField::encode(false) |
1477 : HasElementsField::encode(false) |
1478 : MayStoreDoublesField::encode(false) |
1479 1590767 : HasRestPropertyField::encode(has_rest_property);
1480 : }
1481 :
1482 : static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1483 158334 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1484 :
1485 : uint32_t boilerplate_properties_;
1486 : Handle<BoilerplateDescription> constant_properties_;
1487 : ZoneList<Property*>* properties_;
1488 :
1489 : class FastElementsField
1490 : : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {};
1491 : class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> {
1492 : };
1493 : class MayStoreDoublesField
1494 : : public BitField<bool, HasElementsField::kNext, 1> {};
1495 : class HasRestPropertyField
1496 : : public BitField<bool, MayStoreDoublesField::kNext, 1> {};
1497 : };
1498 :
1499 :
1500 : // A map from property names to getter/setter pairs allocated in the zone.
1501 : class AccessorTable
1502 : : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
1503 : bool (*)(void*, void*),
1504 : ZoneAllocationPolicy> {
1505 : public:
1506 : explicit AccessorTable(Zone* zone)
1507 : : base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
1508 : bool (*)(void*, void*), ZoneAllocationPolicy>(
1509 : Literal::Match, ZoneAllocationPolicy(zone)),
1510 491354 : zone_(zone) {}
1511 :
1512 5802 : Iterator lookup(Literal* literal) {
1513 11604 : Iterator it = find(literal, true, ZoneAllocationPolicy(zone_));
1514 10844 : if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors();
1515 5802 : return it;
1516 : }
1517 :
1518 : private:
1519 : Zone* zone_;
1520 : };
1521 :
1522 :
1523 : // Node for capturing a regexp literal.
1524 : class RegExpLiteral final : public MaterializedLiteral {
1525 : public:
1526 33706 : Handle<String> pattern() const { return pattern_->string(); }
1527 : const AstRawString* raw_pattern() const { return pattern_; }
1528 : int flags() const { return flags_; }
1529 :
1530 : private:
1531 : friend class AstNodeFactory;
1532 :
1533 : RegExpLiteral(const AstRawString* pattern, int flags, int pos)
1534 : : MaterializedLiteral(pos, kRegExpLiteral),
1535 : flags_(flags),
1536 97489 : pattern_(pattern) {
1537 : set_depth(1);
1538 : }
1539 :
1540 : int const flags_;
1541 : const AstRawString* const pattern_;
1542 : };
1543 :
1544 :
1545 : // An array literal has a literals object that is used
1546 : // for minimizing the work when constructing it at runtime.
1547 : class ArrayLiteral final : public MaterializedLiteral {
1548 : public:
1549 : Handle<ConstantElementsPair> constant_elements() const {
1550 : return constant_elements_;
1551 : }
1552 : ElementsKind constant_elements_kind() const;
1553 :
1554 : ZoneList<Expression*>* values() const { return values_; }
1555 :
1556 : BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1557 :
1558 : // Return an AST id for an element that is used in simulate instructions.
1559 150928 : BailoutId GetIdForElement(int i) { return BailoutId(local_id(i + 1)); }
1560 :
1561 : // Unlike other AST nodes, this number of bailout IDs allocated for an
1562 : // ArrayLiteral can vary, so num_ids() is not a static method.
1563 309216 : int num_ids() const { return parent_num_ids() + 1 + values()->length(); }
1564 :
1565 : // Populate the depth field and flags.
1566 : void InitDepthAndFlags();
1567 :
1568 : // Get the constant elements fixed array, populating it if necessary.
1569 : Handle<ConstantElementsPair> GetOrBuildConstantElements(Isolate* isolate) {
1570 239703 : if (constant_elements_.is_null()) {
1571 221478 : BuildConstantElements(isolate);
1572 : }
1573 : return constant_elements();
1574 : }
1575 :
1576 : // Populate the constant elements fixed array.
1577 : void BuildConstantElements(Isolate* isolate);
1578 :
1579 : // Determines whether the {FastCloneShallowArray} builtin can be used.
1580 : bool IsFastCloningSupported() const;
1581 :
1582 : // Assemble bitfield of flags for the CreateArrayLiteral helper.
1583 : int ComputeFlags(bool disable_mementos = false) const {
1584 167075 : int flags = depth() == 1 ? kShallowElements : kNoFlags;
1585 : if (disable_mementos) {
1586 14116 : flags |= kDisableMementos;
1587 : }
1588 : return flags;
1589 : }
1590 :
1591 : // Provide a mechanism for iterating through values to rewrite spreads.
1592 3324 : ZoneList<Expression*>::iterator FirstSpread() const {
1593 6648 : return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_
1594 9972 : : values_->end();
1595 : }
1596 26058 : ZoneList<Expression*>::iterator EndValue() const { return values_->end(); }
1597 :
1598 : // Rewind an array literal omitting everything from the first spread on.
1599 : void RewindSpreads();
1600 :
1601 : enum Flags {
1602 : kNoFlags = 0,
1603 : kShallowElements = 1,
1604 : kDisableMementos = 1 << 1
1605 : };
1606 :
1607 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1608 : FeedbackSlotCache* cache);
1609 : FeedbackSlot LiteralFeedbackSlot() const { return literal_slot_; }
1610 :
1611 : private:
1612 : friend class AstNodeFactory;
1613 :
1614 : ArrayLiteral(ZoneList<Expression*>* values, int first_spread_index, int pos)
1615 : : MaterializedLiteral(pos, kArrayLiteral),
1616 : first_spread_index_(first_spread_index),
1617 1593084 : values_(values) {}
1618 :
1619 : static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1620 225055 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1621 :
1622 : int first_spread_index_;
1623 : FeedbackSlot literal_slot_;
1624 : Handle<ConstantElementsPair> constant_elements_;
1625 : ZoneList<Expression*>* values_;
1626 : };
1627 :
1628 :
1629 : class VariableProxy final : public Expression {
1630 : public:
1631 5109410 : bool IsValidReferenceExpression() const {
1632 10218183 : return !is_this() && !is_new_target();
1633 : }
1634 :
1635 2722760 : Handle<String> name() const { return raw_name()->string(); }
1636 227028617 : const AstRawString* raw_name() const {
1637 227028617 : return is_resolved() ? var_->raw_name() : raw_name_;
1638 : }
1639 :
1640 124087 : Variable* var() const {
1641 : DCHECK(is_resolved());
1642 124087 : return var_;
1643 : }
1644 : void set_var(Variable* v) {
1645 : DCHECK(!is_resolved());
1646 : DCHECK_NOT_NULL(v);
1647 107010904 : var_ = v;
1648 : }
1649 :
1650 151969660 : bool is_this() const { return IsThisField::decode(bit_field_); }
1651 :
1652 : bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
1653 10681921 : void set_is_assigned() {
1654 33409724 : bit_field_ = IsAssignedField::update(bit_field_, true);
1655 16704862 : if (is_resolved()) {
1656 : var()->set_maybe_assigned();
1657 : }
1658 5806610 : }
1659 :
1660 : bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
1661 : void set_is_resolved() {
1662 200265519 : bit_field_ = IsResolvedField::update(bit_field_, true);
1663 : }
1664 :
1665 141085670 : bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
1666 : void set_is_new_target() {
1667 50584 : bit_field_ = IsNewTargetField::update(bit_field_, true);
1668 : }
1669 :
1670 : HoleCheckMode hole_check_mode() const {
1671 : return HoleCheckModeField::decode(bit_field_);
1672 : }
1673 : void set_needs_hole_check() {
1674 : bit_field_ =
1675 1043228 : HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
1676 : }
1677 :
1678 : // Bind this proxy to the variable var.
1679 : void BindTo(Variable* var);
1680 :
1681 28627431 : bool UsesVariableFeedbackSlot() const {
1682 28627431 : return var()->IsUnallocated() || var()->IsLookupSlot();
1683 : }
1684 :
1685 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, TypeofMode typeof_mode,
1686 : FeedbackSlotCache* cache);
1687 :
1688 : FeedbackSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
1689 :
1690 : static int num_ids() { return parent_num_ids() + 1; }
1691 : BailoutId BeforeId() const { return BailoutId(local_id(0)); }
1692 135140276 : void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
1693 : VariableProxy* next_unresolved() { return next_unresolved_; }
1694 :
1695 : private:
1696 : friend class AstNodeFactory;
1697 :
1698 : VariableProxy(Variable* var, int start_position);
1699 : VariableProxy(const AstRawString* name, VariableKind variable_kind,
1700 : int start_position);
1701 : explicit VariableProxy(const VariableProxy* copy_from);
1702 :
1703 : static int parent_num_ids() { return Expression::num_ids(); }
1704 6112246 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1705 :
1706 : class IsThisField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {
1707 : };
1708 : class IsAssignedField : public BitField<bool, IsThisField::kNext, 1> {};
1709 : class IsResolvedField : public BitField<bool, IsAssignedField::kNext, 1> {};
1710 : class IsNewTargetField : public BitField<bool, IsResolvedField::kNext, 1> {};
1711 : class HoleCheckModeField
1712 : : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {};
1713 :
1714 : FeedbackSlot variable_feedback_slot_;
1715 : union {
1716 : const AstRawString* raw_name_; // if !is_resolved_
1717 : Variable* var_; // if is_resolved_
1718 : };
1719 : VariableProxy* next_unresolved_;
1720 : };
1721 :
1722 :
1723 : // Left-hand side can only be a property, a global or a (parameter or local)
1724 : // slot.
1725 : enum LhsKind {
1726 : VARIABLE,
1727 : NAMED_PROPERTY,
1728 : KEYED_PROPERTY,
1729 : NAMED_SUPER_PROPERTY,
1730 : KEYED_SUPER_PROPERTY
1731 : };
1732 :
1733 :
1734 : class Property final : public Expression {
1735 : public:
1736 : bool IsValidReferenceExpression() const { return true; }
1737 :
1738 11489988 : Expression* obj() const { return obj_; }
1739 27 : Expression* key() const { return key_; }
1740 :
1741 0 : void set_obj(Expression* e) { obj_ = e; }
1742 0 : void set_key(Expression* e) { key_ = e; }
1743 :
1744 : static int num_ids() { return parent_num_ids() + 1; }
1745 : BailoutId LoadId() const { return BailoutId(local_id(0)); }
1746 :
1747 : bool IsStringAccess() const {
1748 : return IsStringAccessField::decode(bit_field_);
1749 : }
1750 :
1751 : // Type feedback information.
1752 823131 : bool IsMonomorphic() const { return receiver_types_.length() == 1; }
1753 : SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1754 : KeyedAccessStoreMode GetStoreMode() const { return STANDARD_STORE; }
1755 : IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
1756 431240 : bool IsUninitialized() const {
1757 1653765 : return !is_for_call() && HasNoTypeInformation();
1758 : }
1759 72399 : bool HasNoTypeInformation() const {
1760 : return GetInlineCacheState() == UNINITIALIZED;
1761 : }
1762 : InlineCacheState GetInlineCacheState() const {
1763 : return InlineCacheStateField::decode(bit_field_);
1764 : }
1765 : void set_is_string_access(bool b) {
1766 80314 : bit_field_ = IsStringAccessField::update(bit_field_, b);
1767 : }
1768 : void set_key_type(IcCheckType key_type) {
1769 40157 : bit_field_ = KeyTypeField::update(bit_field_, key_type);
1770 : }
1771 : void set_inline_cache_state(InlineCacheState state) {
1772 1208018 : bit_field_ = InlineCacheStateField::update(bit_field_, state);
1773 : }
1774 : void mark_for_call() {
1775 11188328 : bit_field_ = IsForCallField::update(bit_field_, true);
1776 : }
1777 : bool is_for_call() const { return IsForCallField::decode(bit_field_); }
1778 :
1779 27453771 : bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
1780 :
1781 6642321 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1782 6642321 : FeedbackSlotCache* cache) {
1783 6642321 : if (key()->IsPropertyName()) {
1784 5974255 : property_feedback_slot_ = spec->AddLoadICSlot();
1785 : } else {
1786 668064 : property_feedback_slot_ = spec->AddKeyedLoadICSlot();
1787 : }
1788 6642319 : }
1789 :
1790 : FeedbackSlot PropertyFeedbackSlot() const { return property_feedback_slot_; }
1791 :
1792 : // Returns the properties assign type.
1793 39778865 : static LhsKind GetAssignType(Property* property) {
1794 27519185 : if (property == NULL) return VARIABLE;
1795 12259681 : bool super_access = property->IsSuperAccess();
1796 12259680 : return (property->key()->IsPropertyName())
1797 : ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
1798 12259684 : : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
1799 : }
1800 :
1801 : private:
1802 : friend class AstNodeFactory;
1803 :
1804 : Property(Expression* obj, Expression* key, int pos)
1805 26399616 : : Expression(pos, kProperty), obj_(obj), key_(key) {
1806 : bit_field_ |= IsForCallField::encode(false) |
1807 : IsStringAccessField::encode(false) |
1808 : InlineCacheStateField::encode(UNINITIALIZED);
1809 : }
1810 :
1811 : static int parent_num_ids() { return Expression::num_ids(); }
1812 2691692 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1813 :
1814 : class IsForCallField
1815 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1816 : class IsStringAccessField : public BitField<bool, IsForCallField::kNext, 1> {
1817 : };
1818 : class KeyTypeField
1819 : : public BitField<IcCheckType, IsStringAccessField::kNext, 1> {};
1820 : class InlineCacheStateField
1821 : : public BitField<InlineCacheState, KeyTypeField::kNext, 4> {};
1822 :
1823 : FeedbackSlot property_feedback_slot_;
1824 : Expression* obj_;
1825 : Expression* key_;
1826 : SmallMapList receiver_types_;
1827 : };
1828 :
1829 :
1830 : class Call final : public Expression {
1831 : public:
1832 : Expression* expression() const { return expression_; }
1833 : ZoneList<Expression*>* arguments() const { return arguments_; }
1834 :
1835 0 : void set_expression(Expression* e) { expression_ = e; }
1836 :
1837 : // Type feedback information.
1838 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1839 : FeedbackSlotCache* cache);
1840 :
1841 : FeedbackSlot CallFeedbackICSlot() const { return ic_slot_; }
1842 :
1843 609736 : SmallMapList* GetReceiverTypes() {
1844 609736 : if (expression()->IsProperty()) {
1845 609736 : return expression()->AsProperty()->GetReceiverTypes();
1846 : }
1847 : return nullptr;
1848 : }
1849 :
1850 1045548 : bool IsMonomorphic() const {
1851 745193 : if (expression()->IsProperty()) {
1852 600710 : return expression()->AsProperty()->IsMonomorphic();
1853 : }
1854 444838 : return !target_.is_null();
1855 : }
1856 :
1857 : Handle<JSFunction> target() { return target_; }
1858 :
1859 : Handle<AllocationSite> allocation_site() { return allocation_site_; }
1860 :
1861 : void SetKnownGlobalTarget(Handle<JSFunction> target) {
1862 162126 : target_ = target;
1863 : set_is_uninitialized(false);
1864 : }
1865 168005 : void set_target(Handle<JSFunction> target) { target_ = target; }
1866 : void set_allocation_site(Handle<AllocationSite> site) {
1867 73025 : allocation_site_ = site;
1868 : }
1869 :
1870 : static int num_ids() { return parent_num_ids() + 2; }
1871 : BailoutId ReturnId() const { return BailoutId(local_id(0)); }
1872 : BailoutId CallId() const { return BailoutId(local_id(1)); }
1873 :
1874 : bool is_uninitialized() const {
1875 : return IsUninitializedField::decode(bit_field_);
1876 : }
1877 : void set_is_uninitialized(bool b) {
1878 1636476 : bit_field_ = IsUninitializedField::update(bit_field_, b);
1879 : }
1880 :
1881 : bool is_possibly_eval() const {
1882 : return IsPossiblyEvalField::decode(bit_field_);
1883 : }
1884 :
1885 : TailCallMode tail_call_mode() const {
1886 : return IsTailField::decode(bit_field_) ? TailCallMode::kAllow
1887 6864533 : : TailCallMode::kDisallow;
1888 : }
1889 7334 : void MarkTail() { bit_field_ = IsTailField::update(bit_field_, true); }
1890 :
1891 2402291 : bool only_last_arg_is_spread() {
1892 6312057 : return !arguments_->is_empty() && arguments_->last()->IsSpread();
1893 : }
1894 :
1895 : enum CallType {
1896 : GLOBAL_CALL,
1897 : WITH_CALL,
1898 : NAMED_PROPERTY_CALL,
1899 : KEYED_PROPERTY_CALL,
1900 : NAMED_SUPER_PROPERTY_CALL,
1901 : KEYED_SUPER_PROPERTY_CALL,
1902 : SUPER_CALL,
1903 : OTHER_CALL
1904 : };
1905 :
1906 : enum PossiblyEval {
1907 : IS_POSSIBLY_EVAL,
1908 : NOT_EVAL,
1909 : };
1910 :
1911 : // Helpers to determine how to handle the call.
1912 : CallType GetCallType() const;
1913 :
1914 : #ifdef DEBUG
1915 : // Used to assert that the FullCodeGenerator records the return site.
1916 : bool return_is_recorded_;
1917 : #endif
1918 :
1919 : private:
1920 : friend class AstNodeFactory;
1921 :
1922 11753105 : Call(Expression* expression, ZoneList<Expression*>* arguments, int pos,
1923 : PossiblyEval possibly_eval)
1924 : : Expression(pos, kCall),
1925 : expression_(expression),
1926 11753105 : arguments_(arguments) {
1927 : bit_field_ |=
1928 : IsUninitializedField::encode(false) |
1929 23506210 : IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL);
1930 :
1931 11753102 : if (expression->IsProperty()) {
1932 5594165 : expression->AsProperty()->mark_for_call();
1933 : }
1934 11753101 : }
1935 :
1936 : static int parent_num_ids() { return Expression::num_ids(); }
1937 2453175 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1938 :
1939 : class IsUninitializedField
1940 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1941 : class IsTailField : public BitField<bool, IsUninitializedField::kNext, 1> {};
1942 : class IsPossiblyEvalField : public BitField<bool, IsTailField::kNext, 1> {};
1943 :
1944 : FeedbackSlot ic_slot_;
1945 : Expression* expression_;
1946 : ZoneList<Expression*>* arguments_;
1947 : Handle<JSFunction> target_;
1948 : Handle<AllocationSite> allocation_site_;
1949 : };
1950 :
1951 :
1952 : class CallNew final : public Expression {
1953 : public:
1954 : Expression* expression() const { return expression_; }
1955 : ZoneList<Expression*>* arguments() const { return arguments_; }
1956 :
1957 0 : void set_expression(Expression* e) { expression_ = e; }
1958 :
1959 : // Type feedback information.
1960 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
1961 : FeedbackSlotCache* cache) {
1962 : // CallNew stores feedback in the exact same way as Call. We can
1963 : // piggyback on the type feedback infrastructure for calls.
1964 359312 : callnew_feedback_slot_ = spec->AddCallICSlot();
1965 : }
1966 :
1967 : FeedbackSlot CallNewFeedbackSlot() {
1968 : DCHECK(!callnew_feedback_slot_.IsInvalid());
1969 : return callnew_feedback_slot_;
1970 : }
1971 :
1972 : bool IsMonomorphic() const { return IsMonomorphicField::decode(bit_field_); }
1973 : Handle<JSFunction> target() const { return target_; }
1974 : Handle<AllocationSite> allocation_site() const {
1975 : return allocation_site_;
1976 : }
1977 :
1978 : static int num_ids() { return parent_num_ids() + 1; }
1979 : static int feedback_slots() { return 1; }
1980 : BailoutId ReturnId() const { return BailoutId(local_id(0)); }
1981 :
1982 : void set_allocation_site(Handle<AllocationSite> site) {
1983 32299 : allocation_site_ = site;
1984 : }
1985 : void set_is_monomorphic(bool monomorphic) {
1986 89304 : bit_field_ = IsMonomorphicField::update(bit_field_, monomorphic);
1987 : }
1988 5012 : void set_target(Handle<JSFunction> target) { target_ = target; }
1989 : void SetKnownGlobalTarget(Handle<JSFunction> target) {
1990 12353 : target_ = target;
1991 : set_is_monomorphic(true);
1992 : }
1993 :
1994 221335 : bool only_last_arg_is_spread() {
1995 510805 : return !arguments_->is_empty() && arguments_->last()->IsSpread();
1996 : }
1997 :
1998 : private:
1999 : friend class AstNodeFactory;
2000 :
2001 : CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
2002 : : Expression(pos, kCallNew),
2003 : expression_(expression),
2004 1028428 : arguments_(arguments) {
2005 : bit_field_ |= IsMonomorphicField::encode(false);
2006 : }
2007 :
2008 : static int parent_num_ids() { return Expression::num_ids(); }
2009 128379 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2010 :
2011 : FeedbackSlot callnew_feedback_slot_;
2012 : Expression* expression_;
2013 : ZoneList<Expression*>* arguments_;
2014 : Handle<JSFunction> target_;
2015 : Handle<AllocationSite> allocation_site_;
2016 :
2017 : class IsMonomorphicField
2018 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2019 : };
2020 :
2021 :
2022 : // The CallRuntime class does not represent any official JavaScript
2023 : // language construct. Instead it is used to call a C or JS function
2024 : // with a set of arguments. This is used from the builtins that are
2025 : // implemented in JavaScript (see "v8natives.js").
2026 : class CallRuntime final : public Expression {
2027 : public:
2028 : ZoneList<Expression*>* arguments() const { return arguments_; }
2029 : bool is_jsruntime() const { return function_ == NULL; }
2030 :
2031 : int context_index() const {
2032 : DCHECK(is_jsruntime());
2033 : return context_index_;
2034 : }
2035 : void set_context_index(int index) {
2036 : DCHECK(is_jsruntime());
2037 6984 : context_index_ = index;
2038 : }
2039 : const Runtime::Function* function() const {
2040 : DCHECK(!is_jsruntime());
2041 : return function_;
2042 : }
2043 :
2044 : static int num_ids() { return parent_num_ids() + 1; }
2045 : BailoutId CallId() { return BailoutId(local_id(0)); }
2046 : const char* debug_name();
2047 :
2048 : private:
2049 : friend class AstNodeFactory;
2050 :
2051 : CallRuntime(const Runtime::Function* function,
2052 : ZoneList<Expression*>* arguments, int pos)
2053 : : Expression(pos, kCallRuntime),
2054 : function_(function),
2055 4524778 : arguments_(arguments) {}
2056 : CallRuntime(int context_index, ZoneList<Expression*>* arguments, int pos)
2057 : : Expression(pos, kCallRuntime),
2058 : context_index_(context_index),
2059 : function_(NULL),
2060 489605 : arguments_(arguments) {}
2061 :
2062 : static int parent_num_ids() { return Expression::num_ids(); }
2063 252980 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2064 :
2065 : int context_index_;
2066 : const Runtime::Function* function_;
2067 : ZoneList<Expression*>* arguments_;
2068 : };
2069 :
2070 :
2071 : class UnaryOperation final : public Expression {
2072 : public:
2073 : Token::Value op() const { return OperatorField::decode(bit_field_); }
2074 : Expression* expression() const { return expression_; }
2075 0 : void set_expression(Expression* e) { expression_ = e; }
2076 :
2077 : // For unary not (Token::NOT), the AST ids where true and false will
2078 : // actually be materialized, respectively.
2079 : static int num_ids() { return parent_num_ids() + 2; }
2080 : BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
2081 : BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
2082 :
2083 : void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
2084 :
2085 : private:
2086 : friend class AstNodeFactory;
2087 :
2088 : UnaryOperation(Token::Value op, Expression* expression, int pos)
2089 4376550 : : Expression(pos, kUnaryOperation), expression_(expression) {
2090 4376550 : bit_field_ |= OperatorField::encode(op);
2091 : DCHECK(Token::IsUnaryOp(op));
2092 : }
2093 :
2094 : static int parent_num_ids() { return Expression::num_ids(); }
2095 52748 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2096 :
2097 : Expression* expression_;
2098 :
2099 : class OperatorField
2100 : : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
2101 : };
2102 :
2103 :
2104 : class BinaryOperation final : public Expression {
2105 : public:
2106 : Token::Value op() const { return OperatorField::decode(bit_field_); }
2107 : Expression* left() const { return left_; }
2108 0 : void set_left(Expression* e) { left_ = e; }
2109 : Expression* right() const { return right_; }
2110 0 : void set_right(Expression* e) { right_ = e; }
2111 : Handle<AllocationSite> allocation_site() const { return allocation_site_; }
2112 : void set_allocation_site(Handle<AllocationSite> allocation_site) {
2113 511901 : allocation_site_ = allocation_site;
2114 : }
2115 :
2116 1242 : void MarkTail() {
2117 1242 : switch (op()) {
2118 : case Token::COMMA:
2119 : case Token::AND:
2120 : case Token::OR:
2121 446 : right_->MarkTail();
2122 : default:
2123 : break;
2124 : }
2125 1242 : }
2126 :
2127 : // The short-circuit logical operations need an AST ID for their
2128 : // right-hand subexpression.
2129 : static int num_ids() { return parent_num_ids() + 2; }
2130 : BailoutId RightId() const { return BailoutId(local_id(0)); }
2131 :
2132 : // BinaryOperation will have both a slot in the feedback vector and the
2133 : // TypeFeedbackId to record the type information. TypeFeedbackId is used
2134 : // by full codegen and the feedback vector slot is used by interpreter.
2135 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2136 : FeedbackSlotCache* cache);
2137 :
2138 : FeedbackSlot BinaryOperationFeedbackSlot() const { return feedback_slot_; }
2139 :
2140 : TypeFeedbackId BinaryOperationFeedbackId() const {
2141 : return TypeFeedbackId(local_id(1));
2142 : }
2143 :
2144 : // Returns true if one side is a Smi literal, returning the other side's
2145 : // sub-expression in |subexpr| and the literal Smi in |literal|.
2146 : bool IsSmiLiteralOperation(Expression** subexpr, Smi** literal);
2147 :
2148 : Maybe<int> fixed_right_arg() const {
2149 381164 : return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
2150 : }
2151 : void set_fixed_right_arg(Maybe<int> arg) {
2152 511901 : has_fixed_right_arg_ = arg.IsJust();
2153 512195 : if (arg.IsJust()) fixed_right_arg_value_ = arg.FromJust();
2154 : }
2155 :
2156 : void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
2157 :
2158 : private:
2159 : friend class AstNodeFactory;
2160 :
2161 : BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
2162 : : Expression(pos, kBinaryOperation),
2163 : has_fixed_right_arg_(false),
2164 : fixed_right_arg_value_(0),
2165 : left_(left),
2166 7952078 : right_(right) {
2167 7952078 : bit_field_ |= OperatorField::encode(op);
2168 : DCHECK(Token::IsBinaryOp(op));
2169 : }
2170 :
2171 : static int parent_num_ids() { return Expression::num_ids(); }
2172 1516409 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2173 :
2174 : // TODO(rossberg): the fixed arg should probably be represented as a Constant
2175 : // type for the RHS. Currenty it's actually a Maybe<int>
2176 : bool has_fixed_right_arg_;
2177 : int fixed_right_arg_value_;
2178 : Expression* left_;
2179 : Expression* right_;
2180 : Handle<AllocationSite> allocation_site_;
2181 : FeedbackSlot feedback_slot_;
2182 :
2183 : class OperatorField
2184 : : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
2185 : };
2186 :
2187 :
2188 : class CountOperation final : public Expression {
2189 : public:
2190 : bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
2191 490153 : bool is_postfix() const { return !is_prefix(); }
2192 :
2193 : Token::Value op() const { return TokenField::decode(bit_field_); }
2194 237928 : Token::Value binary_op() {
2195 237928 : return (op() == Token::INC) ? Token::ADD : Token::SUB;
2196 : }
2197 :
2198 : Expression* expression() const { return expression_; }
2199 0 : void set_expression(Expression* e) { expression_ = e; }
2200 :
2201 1597 : bool IsMonomorphic() const { return receiver_types_.length() == 1; }
2202 : SmallMapList* GetReceiverTypes() { return &receiver_types_; }
2203 : IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
2204 : KeyedAccessStoreMode GetStoreMode() const {
2205 : return StoreModeField::decode(bit_field_);
2206 : }
2207 : AstType* type() const { return type_; }
2208 : void set_key_type(IcCheckType type) {
2209 45981 : bit_field_ = KeyTypeField::update(bit_field_, type);
2210 : }
2211 : void set_store_mode(KeyedAccessStoreMode mode) {
2212 91962 : bit_field_ = StoreModeField::update(bit_field_, mode);
2213 : }
2214 45981 : void set_type(AstType* type) { type_ = type; }
2215 :
2216 : static int num_ids() { return parent_num_ids() + 4; }
2217 : BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2218 : BailoutId ToNumberId() const { return BailoutId(local_id(1)); }
2219 : TypeFeedbackId CountBinOpFeedbackId() const {
2220 : return TypeFeedbackId(local_id(2));
2221 : }
2222 : TypeFeedbackId CountStoreFeedbackId() const {
2223 : return TypeFeedbackId(local_id(3));
2224 : }
2225 :
2226 : // Feedback slot for binary operation is only used by ignition.
2227 : FeedbackSlot CountBinaryOpFeedbackSlot() const {
2228 : return binary_operation_slot_;
2229 : }
2230 :
2231 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2232 : FeedbackSlotCache* cache);
2233 : FeedbackSlot CountSlot() const { return slot_; }
2234 :
2235 : private:
2236 : friend class AstNodeFactory;
2237 :
2238 : CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
2239 1547929 : : Expression(pos, kCountOperation), type_(NULL), expression_(expr) {
2240 : bit_field_ |=
2241 : IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) |
2242 1547929 : StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op);
2243 : }
2244 :
2245 : static int parent_num_ids() { return Expression::num_ids(); }
2246 318738 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2247 :
2248 : class IsPrefixField
2249 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2250 : class KeyTypeField : public BitField<IcCheckType, IsPrefixField::kNext, 1> {};
2251 : class StoreModeField
2252 : : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
2253 : class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
2254 :
2255 : FeedbackSlot slot_;
2256 : FeedbackSlot binary_operation_slot_;
2257 : AstType* type_;
2258 : Expression* expression_;
2259 : SmallMapList receiver_types_;
2260 : };
2261 :
2262 :
2263 : class CompareOperation final : public Expression {
2264 : public:
2265 : Token::Value op() const { return OperatorField::decode(bit_field_); }
2266 : Expression* left() const { return left_; }
2267 : Expression* right() const { return right_; }
2268 :
2269 0 : void set_left(Expression* e) { left_ = e; }
2270 0 : void set_right(Expression* e) { right_ = e; }
2271 :
2272 : // Type feedback information.
2273 : static int num_ids() { return parent_num_ids() + 1; }
2274 : TypeFeedbackId CompareOperationFeedbackId() const {
2275 : return TypeFeedbackId(local_id(0));
2276 : }
2277 : AstType* combined_type() const { return combined_type_; }
2278 506717 : void set_combined_type(AstType* type) { combined_type_ = type; }
2279 :
2280 : // CompareOperation will have both a slot in the feedback vector and the
2281 : // TypeFeedbackId to record the type information. TypeFeedbackId is used
2282 : // by full codegen and the feedback vector slot is used by interpreter.
2283 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2284 : FeedbackSlotCache* cache);
2285 :
2286 : FeedbackSlot CompareOperationFeedbackSlot() const { return feedback_slot_; }
2287 :
2288 : // Match special cases.
2289 : bool IsLiteralCompareTypeof(Expression** expr, Literal** literal);
2290 : bool IsLiteralCompareUndefined(Expression** expr);
2291 : bool IsLiteralCompareNull(Expression** expr);
2292 :
2293 : private:
2294 : friend class AstNodeFactory;
2295 :
2296 : CompareOperation(Token::Value op, Expression* left, Expression* right,
2297 : int pos)
2298 : : Expression(pos, kCompareOperation),
2299 : left_(left),
2300 : right_(right),
2301 7069284 : combined_type_(AstType::None()) {
2302 7069284 : bit_field_ |= OperatorField::encode(op);
2303 : DCHECK(Token::IsCompareOp(op));
2304 : }
2305 :
2306 : static int parent_num_ids() { return Expression::num_ids(); }
2307 943358 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2308 :
2309 : Expression* left_;
2310 : Expression* right_;
2311 :
2312 : AstType* combined_type_;
2313 : FeedbackSlot feedback_slot_;
2314 : class OperatorField
2315 : : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
2316 : };
2317 :
2318 :
2319 : class Spread final : public Expression {
2320 : public:
2321 5397 : Expression* expression() const { return expression_; }
2322 0 : void set_expression(Expression* e) { expression_ = e; }
2323 :
2324 : int expression_position() const { return expr_pos_; }
2325 :
2326 : static int num_ids() { return parent_num_ids(); }
2327 :
2328 : private:
2329 : friend class AstNodeFactory;
2330 :
2331 : Spread(Expression* expression, int pos, int expr_pos)
2332 : : Expression(pos, kSpread),
2333 : expr_pos_(expr_pos),
2334 51563 : expression_(expression) {}
2335 :
2336 : static int parent_num_ids() { return Expression::num_ids(); }
2337 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2338 :
2339 : int expr_pos_;
2340 : Expression* expression_;
2341 : };
2342 :
2343 :
2344 : class Conditional final : public Expression {
2345 : public:
2346 : Expression* condition() const { return condition_; }
2347 : Expression* then_expression() const { return then_expression_; }
2348 : Expression* else_expression() const { return else_expression_; }
2349 :
2350 0 : void set_condition(Expression* e) { condition_ = e; }
2351 0 : void set_then_expression(Expression* e) { then_expression_ = e; }
2352 0 : void set_else_expression(Expression* e) { else_expression_ = e; }
2353 :
2354 140 : void MarkTail() {
2355 140 : then_expression_->MarkTail();
2356 140 : else_expression_->MarkTail();
2357 140 : }
2358 :
2359 : static int num_ids() { return parent_num_ids() + 2; }
2360 : BailoutId ThenId() const { return BailoutId(local_id(0)); }
2361 : BailoutId ElseId() const { return BailoutId(local_id(1)); }
2362 :
2363 : private:
2364 : friend class AstNodeFactory;
2365 :
2366 : Conditional(Expression* condition, Expression* then_expression,
2367 : Expression* else_expression, int position)
2368 : : Expression(position, kConditional),
2369 : condition_(condition),
2370 : then_expression_(then_expression),
2371 465734 : else_expression_(else_expression) {}
2372 :
2373 : static int parent_num_ids() { return Expression::num_ids(); }
2374 64301 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2375 :
2376 : Expression* condition_;
2377 : Expression* then_expression_;
2378 : Expression* else_expression_;
2379 : };
2380 :
2381 :
2382 : class Assignment final : public Expression {
2383 : public:
2384 : Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
2385 :
2386 : Token::Value binary_op() const;
2387 :
2388 : Token::Value op() const { return TokenField::decode(bit_field_); }
2389 : Expression* target() const { return target_; }
2390 : Expression* value() const { return value_; }
2391 :
2392 0 : void set_target(Expression* e) { target_ = e; }
2393 0 : void set_value(Expression* e) { value_ = e; }
2394 :
2395 : BinaryOperation* binary_operation() const { return binary_operation_; }
2396 :
2397 : // This check relies on the definition order of token in token.h.
2398 100764472 : bool is_compound() const { return op() > Token::ASSIGN; }
2399 :
2400 : static int num_ids() { return parent_num_ids() + 2; }
2401 : BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2402 :
2403 : // Type feedback information.
2404 : TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
2405 : bool IsUninitialized() const {
2406 : return IsUninitializedField::decode(bit_field_);
2407 : }
2408 : bool HasNoTypeInformation() {
2409 : return IsUninitializedField::decode(bit_field_);
2410 : }
2411 72372 : bool IsMonomorphic() const { return receiver_types_.length() == 1; }
2412 : SmallMapList* GetReceiverTypes() { return &receiver_types_; }
2413 : IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
2414 : KeyedAccessStoreMode GetStoreMode() const {
2415 : return StoreModeField::decode(bit_field_);
2416 : }
2417 : void set_is_uninitialized(bool b) {
2418 146090 : bit_field_ = IsUninitializedField::update(bit_field_, b);
2419 : }
2420 : void set_key_type(IcCheckType key_type) {
2421 4974 : bit_field_ = KeyTypeField::update(bit_field_, key_type);
2422 : }
2423 : void set_store_mode(KeyedAccessStoreMode mode) {
2424 9948 : bit_field_ = StoreModeField::update(bit_field_, mode);
2425 : }
2426 :
2427 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2428 : FeedbackSlotCache* cache);
2429 : FeedbackSlot AssignmentSlot() const { return slot_; }
2430 :
2431 : private:
2432 : friend class AstNodeFactory;
2433 :
2434 : Assignment(Token::Value op, Expression* target, Expression* value, int pos);
2435 :
2436 : static int parent_num_ids() { return Expression::num_ids(); }
2437 2911373 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2438 :
2439 : class IsUninitializedField
2440 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2441 : class KeyTypeField
2442 : : public BitField<IcCheckType, IsUninitializedField::kNext, 1> {};
2443 : class StoreModeField
2444 : : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
2445 : class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
2446 :
2447 : FeedbackSlot slot_;
2448 : Expression* target_;
2449 : Expression* value_;
2450 : BinaryOperation* binary_operation_;
2451 : SmallMapList receiver_types_;
2452 : };
2453 :
2454 :
2455 : // The RewritableExpression class is a wrapper for AST nodes that wait
2456 : // for some potential rewriting. However, even if such nodes are indeed
2457 : // rewritten, the RewritableExpression wrapper nodes will survive in the
2458 : // final AST and should be just ignored, i.e., they should be treated as
2459 : // equivalent to the wrapped nodes. For this reason and to simplify later
2460 : // phases, RewritableExpressions are considered as exceptions of AST nodes
2461 : // in the following sense:
2462 : //
2463 : // 1. IsRewritableExpression and AsRewritableExpression behave as usual.
2464 : // 2. All other Is* and As* methods are practically delegated to the
2465 : // wrapped node, i.e. IsArrayLiteral() will return true iff the
2466 : // wrapped node is an array literal.
2467 : //
2468 : // Furthermore, an invariant that should be respected is that the wrapped
2469 : // node is not a RewritableExpression.
2470 : class RewritableExpression final : public Expression {
2471 : public:
2472 407921 : Expression* expression() const { return expr_; }
2473 174794 : bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); }
2474 :
2475 : void Rewrite(Expression* new_expression) {
2476 : DCHECK(!is_rewritten());
2477 : DCHECK_NOT_NULL(new_expression);
2478 : DCHECK(!new_expression->IsRewritableExpression());
2479 110763 : expr_ = new_expression;
2480 228054 : bit_field_ = IsRewrittenField::update(bit_field_, true);
2481 : }
2482 :
2483 : static int num_ids() { return parent_num_ids(); }
2484 :
2485 : private:
2486 : friend class AstNodeFactory;
2487 :
2488 : explicit RewritableExpression(Expression* expression)
2489 : : Expression(expression->position(), kRewritableExpression),
2490 263314 : expr_(expression) {
2491 : bit_field_ |= IsRewrittenField::encode(false);
2492 : DCHECK(!expression->IsRewritableExpression());
2493 : }
2494 :
2495 : int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2496 :
2497 : Expression* expr_;
2498 :
2499 : class IsRewrittenField
2500 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2501 : };
2502 :
2503 : // There are several types of Suspend node:
2504 : //
2505 : // Yield
2506 : // YieldStar
2507 : // Await
2508 : //
2509 : // Our Yield is different from the JS yield in that it "returns" its argument as
2510 : // is, without wrapping it in an iterator result object. Such wrapping, if
2511 : // desired, must be done beforehand (see the parser).
2512 : class Suspend final : public Expression {
2513 : public:
2514 : enum OnException { kOnExceptionThrow, kOnExceptionRethrow };
2515 :
2516 : Expression* generator_object() const { return generator_object_; }
2517 : Expression* expression() const { return expression_; }
2518 : OnException on_exception() const {
2519 : return OnExceptionField::decode(bit_field_);
2520 : }
2521 19833 : bool rethrow_on_exception() const {
2522 : return on_exception() == kOnExceptionRethrow;
2523 : }
2524 :
2525 : int suspend_id() const { return suspend_id_; }
2526 : SuspendFlags flags() const { return FlagsField::decode(bit_field_); }
2527 : SuspendFlags suspend_type() const {
2528 : return flags() & SuspendFlags::kSuspendTypeMask;
2529 : }
2530 39666 : SuspendFlags generator_type() const {
2531 : return flags() & SuspendFlags::kGeneratorTypeMask;
2532 : }
2533 : bool is_yield() const { return suspend_type() == SuspendFlags::kYield; }
2534 : bool is_yield_star() const {
2535 : return suspend_type() == SuspendFlags::kYieldStar;
2536 : }
2537 : bool is_await() const { return suspend_type() == SuspendFlags::kAwait; }
2538 : bool is_async_generator() const {
2539 : return generator_type() == SuspendFlags::kAsyncGenerator;
2540 : }
2541 30943 : inline bool IsNonInitialAsyncGeneratorYield() const {
2542 : // Return true if is_async_generator() && !is_await() && yield_id() > 0
2543 30943 : return suspend_id() > 0 && (flags() & SuspendFlags::kAsyncGeneratorAwait) ==
2544 : SuspendFlags::kAsyncGenerator;
2545 : }
2546 :
2547 0 : void set_generator_object(Expression* e) { generator_object_ = e; }
2548 0 : void set_expression(Expression* e) { expression_ = e; }
2549 25371 : void set_suspend_id(int id) { suspend_id_ = id; }
2550 : void set_suspend_type(SuspendFlags type) {
2551 : DCHECK_EQ(0, static_cast<int>(type & ~SuspendFlags::kSuspendTypeMask));
2552 : bit_field_ = FlagsField::update(bit_field_, type);
2553 : }
2554 :
2555 : private:
2556 : friend class AstNodeFactory;
2557 :
2558 : Suspend(Expression* generator_object, Expression* expression, int pos,
2559 : OnException on_exception, SuspendFlags flags)
2560 : : Expression(pos, kSuspend),
2561 : suspend_id_(-1),
2562 : generator_object_(generator_object),
2563 186530 : expression_(expression) {
2564 : bit_field_ |=
2565 186530 : OnExceptionField::encode(on_exception) | FlagsField::encode(flags);
2566 : }
2567 :
2568 : int suspend_id_;
2569 : Expression* generator_object_;
2570 : Expression* expression_;
2571 :
2572 : class OnExceptionField
2573 : : public BitField<OnException, Expression::kNextBitFieldIndex, 1> {};
2574 : class FlagsField
2575 : : public BitField<SuspendFlags, OnExceptionField::kNext,
2576 : static_cast<int>(SuspendFlags::kBitWidth)> {};
2577 : };
2578 :
2579 :
2580 : class Throw final : public Expression {
2581 : public:
2582 : Expression* exception() const { return exception_; }
2583 0 : void set_exception(Expression* e) { exception_ = e; }
2584 :
2585 : private:
2586 : friend class AstNodeFactory;
2587 :
2588 : Throw(Expression* exception, int pos)
2589 759489 : : Expression(pos, kThrow), exception_(exception) {}
2590 :
2591 : Expression* exception_;
2592 : };
2593 :
2594 :
2595 : class FunctionLiteral final : public Expression {
2596 : public:
2597 : enum FunctionType {
2598 : kAnonymousExpression,
2599 : kNamedExpression,
2600 : kDeclaration,
2601 : kAccessorOrMethod
2602 : };
2603 :
2604 : enum IdType { kIdTypeInvalid = -1, kIdTypeTopLevel = 0 };
2605 :
2606 : enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters };
2607 :
2608 : enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
2609 :
2610 6249647 : Handle<String> name() const { return raw_name_->string(); }
2611 : const AstConsString* raw_name() const { return raw_name_; }
2612 865381 : void set_raw_name(const AstConsString* name) { raw_name_ = name; }
2613 : DeclarationScope* scope() const { return scope_; }
2614 : ZoneList<Statement*>* body() const { return body_; }
2615 8048547 : void set_function_token_position(int pos) { function_token_position_ = pos; }
2616 : int function_token_position() const { return function_token_position_; }
2617 : int start_position() const;
2618 : int end_position() const;
2619 : int SourceSize() const { return end_position() - start_position(); }
2620 6235390 : bool is_declaration() const { return function_type() == kDeclaration; }
2621 6235390 : bool is_named_expression() const {
2622 : return function_type() == kNamedExpression;
2623 : }
2624 7769908 : bool is_anonymous_expression() const {
2625 6235390 : return function_type() == kAnonymousExpression;
2626 : }
2627 : LanguageMode language_mode() const;
2628 :
2629 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2630 : FeedbackSlotCache* cache) {
2631 5458771 : literal_feedback_slot_ = spec->AddCreateClosureSlot();
2632 : }
2633 :
2634 : FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; }
2635 :
2636 : static bool NeedsHomeObject(Expression* expr);
2637 :
2638 : int expected_property_count() {
2639 : // Not valid for lazy functions.
2640 : DCHECK_NOT_NULL(body_);
2641 : return expected_property_count_;
2642 : }
2643 : int parameter_count() { return parameter_count_; }
2644 : int function_length() { return function_length_; }
2645 :
2646 : bool AllowsLazyCompilation();
2647 :
2648 441 : Handle<String> debug_name() const {
2649 441 : if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
2650 : return raw_name_->string();
2651 : }
2652 425 : return inferred_name();
2653 : }
2654 :
2655 6235813 : Handle<String> inferred_name() const {
2656 6235813 : if (!inferred_name_.is_null()) {
2657 : DCHECK(raw_inferred_name_ == NULL);
2658 425 : return inferred_name_;
2659 : }
2660 6235388 : if (raw_inferred_name_ != NULL) {
2661 : return raw_inferred_name_->string();
2662 : }
2663 0 : UNREACHABLE();
2664 : return Handle<String>();
2665 : }
2666 :
2667 : // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2668 : void set_inferred_name(Handle<String> inferred_name) {
2669 : DCHECK(!inferred_name.is_null());
2670 1297591 : inferred_name_ = inferred_name;
2671 : DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
2672 1297591 : raw_inferred_name_ = NULL;
2673 : }
2674 :
2675 : void set_raw_inferred_name(const AstConsString* raw_inferred_name) {
2676 : DCHECK(raw_inferred_name != NULL);
2677 2902909 : raw_inferred_name_ = raw_inferred_name;
2678 : DCHECK(inferred_name_.is_null());
2679 2902909 : inferred_name_ = Handle<String>();
2680 : }
2681 :
2682 : bool pretenure() const { return Pretenure::decode(bit_field_); }
2683 3732050 : void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
2684 :
2685 : bool has_duplicate_parameters() const {
2686 : // Not valid for lazy functions.
2687 : DCHECK_NOT_NULL(body_);
2688 : return HasDuplicateParameters::decode(bit_field_);
2689 : }
2690 :
2691 : // This is used as a heuristic on when to eagerly compile a function
2692 : // literal. We consider the following constructs as hints that the
2693 : // function will be called immediately:
2694 : // - (function() { ... })();
2695 : // - var x = function() { ... }();
2696 : bool ShouldEagerCompile() const;
2697 : void SetShouldEagerCompile();
2698 :
2699 : // A hint that we expect this function to be called (exactly) once,
2700 : // i.e. we suspect it's an initialization function.
2701 : bool should_be_used_once_hint() const {
2702 : return ShouldNotBeUsedOnceHintField::decode(bit_field_);
2703 : }
2704 : void set_should_be_used_once_hint() {
2705 104 : bit_field_ = ShouldNotBeUsedOnceHintField::update(bit_field_, true);
2706 : }
2707 :
2708 : FunctionType function_type() const {
2709 : return FunctionTypeBits::decode(bit_field_);
2710 : }
2711 : FunctionKind kind() const;
2712 :
2713 3685394 : int ast_node_count() { return ast_properties_.node_count(); }
2714 : AstProperties::Flags flags() const { return ast_properties_.flags(); }
2715 : void set_ast_properties(AstProperties* ast_properties) {
2716 : ast_properties_ = *ast_properties;
2717 : }
2718 : const FeedbackVectorSpec* feedback_vector_spec() const {
2719 : return ast_properties_.get_spec();
2720 : }
2721 1107437 : bool dont_optimize() { return dont_optimize_reason() != kNoReason; }
2722 : BailoutReason dont_optimize_reason() {
2723 : return DontOptimizeReasonField::decode(bit_field_);
2724 : }
2725 : void set_dont_optimize_reason(BailoutReason reason) {
2726 6983704 : bit_field_ = DontOptimizeReasonField::update(bit_field_, reason);
2727 : }
2728 :
2729 : bool IsAnonymousFunctionDefinition() const {
2730 : return is_anonymous_expression();
2731 : }
2732 :
2733 : int suspend_count() { return suspend_count_; }
2734 3491852 : void set_suspend_count(int suspend_count) { suspend_count_ = suspend_count; }
2735 :
2736 3158276 : int return_position() {
2737 6316553 : return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0));
2738 : }
2739 :
2740 : int function_literal_id() const { return function_literal_id_; }
2741 : void set_function_literal_id(int function_literal_id) {
2742 299 : function_literal_id_ = function_literal_id;
2743 : }
2744 :
2745 : private:
2746 : friend class AstNodeFactory;
2747 :
2748 10027664 : FunctionLiteral(Zone* zone, const AstRawString* name,
2749 10027656 : AstValueFactory* ast_value_factory, DeclarationScope* scope,
2750 : ZoneList<Statement*>* body, int expected_property_count,
2751 : int parameter_count, int function_length,
2752 : FunctionType function_type,
2753 : ParameterFlag has_duplicate_parameters,
2754 : EagerCompileHint eager_compile_hint, int position,
2755 : bool has_braces, int function_literal_id)
2756 : : Expression(position, kFunctionLiteral),
2757 : expected_property_count_(expected_property_count),
2758 : parameter_count_(parameter_count),
2759 : function_length_(function_length),
2760 : function_token_position_(kNoSourcePosition),
2761 : suspend_count_(0),
2762 : has_braces_(has_braces),
2763 10027664 : raw_name_(ast_value_factory->NewConsString(name)),
2764 : scope_(scope),
2765 : body_(body),
2766 : raw_inferred_name_(ast_value_factory->empty_cons_string()),
2767 : ast_properties_(zone),
2768 40110637 : function_literal_id_(function_literal_id) {
2769 : bit_field_ |= FunctionTypeBits::encode(function_type) |
2770 10027661 : Pretenure::encode(false) |
2771 : HasDuplicateParameters::encode(has_duplicate_parameters ==
2772 10027661 : kHasDuplicateParameters) |
2773 : ShouldNotBeUsedOnceHintField::encode(false) |
2774 10027661 : DontOptimizeReasonField::encode(kNoReason);
2775 10027661 : if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
2776 : DCHECK_EQ(body == nullptr, expected_property_count < 0);
2777 10027660 : }
2778 :
2779 : class FunctionTypeBits
2780 : : public BitField<FunctionType, Expression::kNextBitFieldIndex, 2> {};
2781 : class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {};
2782 : class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {};
2783 : class ShouldNotBeUsedOnceHintField
2784 : : public BitField<bool, HasDuplicateParameters::kNext, 1> {};
2785 : class DontOptimizeReasonField
2786 : : public BitField<BailoutReason, ShouldNotBeUsedOnceHintField::kNext, 8> {
2787 : };
2788 :
2789 : int expected_property_count_;
2790 : int parameter_count_;
2791 : int function_length_;
2792 : int function_token_position_;
2793 : int suspend_count_;
2794 : bool has_braces_;
2795 :
2796 : const AstConsString* raw_name_;
2797 : DeclarationScope* scope_;
2798 : ZoneList<Statement*>* body_;
2799 : const AstConsString* raw_inferred_name_;
2800 : Handle<String> inferred_name_;
2801 : AstProperties ast_properties_;
2802 : int function_literal_id_;
2803 : FeedbackSlot literal_feedback_slot_;
2804 : };
2805 :
2806 : // Property is used for passing information
2807 : // about a class literal's properties from the parser to the code generator.
2808 : class ClassLiteralProperty final : public LiteralProperty {
2809 : public:
2810 : enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
2811 :
2812 : Kind kind() const { return kind_; }
2813 :
2814 : bool is_static() const { return is_static_; }
2815 :
2816 : private:
2817 : friend class AstNodeFactory;
2818 :
2819 : ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
2820 : bool is_static, bool is_computed_name);
2821 :
2822 : Kind kind_;
2823 : bool is_static_;
2824 : };
2825 :
2826 : class ClassLiteral final : public Expression {
2827 : public:
2828 : typedef ClassLiteralProperty Property;
2829 :
2830 : VariableProxy* class_variable_proxy() const { return class_variable_proxy_; }
2831 : Expression* extends() const { return extends_; }
2832 0 : void set_extends(Expression* e) { extends_ = e; }
2833 : FunctionLiteral* constructor() const { return constructor_; }
2834 0 : void set_constructor(FunctionLiteral* f) { constructor_ = f; }
2835 : ZoneList<Property*>* properties() const { return properties_; }
2836 41550 : int start_position() const { return position(); }
2837 : int end_position() const { return end_position_; }
2838 : bool has_name_static_property() const {
2839 : return HasNameStaticProperty::decode(bit_field_);
2840 : }
2841 : bool has_static_computed_names() const {
2842 : return HasStaticComputedNames::decode(bit_field_);
2843 : }
2844 :
2845 : // Object literals need one feedback slot for each non-trivial value, as well
2846 : // as some slots for home objects.
2847 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2848 : FeedbackSlotCache* cache);
2849 :
2850 43578 : bool NeedsProxySlot() const {
2851 165659 : return class_variable_proxy() != nullptr &&
2852 82047 : class_variable_proxy()->var()->IsUnallocated();
2853 : }
2854 :
2855 : FeedbackSlot HomeObjectSlot() const { return home_object_slot_; }
2856 : FeedbackSlot ProxySlot() const { return proxy_slot_; }
2857 :
2858 : private:
2859 : friend class AstNodeFactory;
2860 :
2861 : ClassLiteral(VariableProxy* class_variable_proxy, Expression* extends,
2862 : FunctionLiteral* constructor, ZoneList<Property*>* properties,
2863 : int start_position, int end_position,
2864 : bool has_name_static_property, bool has_static_computed_names)
2865 : : Expression(start_position, kClassLiteral),
2866 : end_position_(end_position),
2867 : class_variable_proxy_(class_variable_proxy),
2868 : extends_(extends),
2869 : constructor_(constructor),
2870 185222 : properties_(properties) {
2871 : bit_field_ |= HasNameStaticProperty::encode(has_name_static_property) |
2872 92611 : HasStaticComputedNames::encode(has_static_computed_names);
2873 : }
2874 :
2875 : int end_position_;
2876 : FeedbackSlot home_object_slot_;
2877 : FeedbackSlot proxy_slot_;
2878 : VariableProxy* class_variable_proxy_;
2879 : Expression* extends_;
2880 : FunctionLiteral* constructor_;
2881 : ZoneList<Property*>* properties_;
2882 :
2883 : class HasNameStaticProperty
2884 : : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2885 : class HasStaticComputedNames
2886 : : public BitField<bool, HasNameStaticProperty::kNext, 1> {};
2887 : };
2888 :
2889 :
2890 : class NativeFunctionLiteral final : public Expression {
2891 : public:
2892 2988 : Handle<String> name() const { return name_->string(); }
2893 : v8::Extension* extension() const { return extension_; }
2894 : FeedbackSlot LiteralFeedbackSlot() const { return literal_feedback_slot_; }
2895 :
2896 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
2897 : FeedbackSlotCache* cache) {
2898 : // TODO(mvstanton): The FeedbackSlotCache can be adapted
2899 : // to always return the same slot for this case.
2900 2988 : literal_feedback_slot_ = spec->AddCreateClosureSlot();
2901 : }
2902 :
2903 : private:
2904 : friend class AstNodeFactory;
2905 :
2906 : NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
2907 : int pos)
2908 : : Expression(pos, kNativeFunctionLiteral),
2909 : name_(name),
2910 2988 : extension_(extension) {}
2911 :
2912 : const AstRawString* name_;
2913 : v8::Extension* extension_;
2914 : FeedbackSlot literal_feedback_slot_;
2915 : };
2916 :
2917 :
2918 : class ThisFunction final : public Expression {
2919 : private:
2920 : friend class AstNodeFactory;
2921 : explicit ThisFunction(int pos) : Expression(pos, kThisFunction) {}
2922 : };
2923 :
2924 :
2925 : class SuperPropertyReference final : public Expression {
2926 : public:
2927 : VariableProxy* this_var() const { return this_var_; }
2928 0 : void set_this_var(VariableProxy* v) { this_var_ = v; }
2929 : Expression* home_object() const { return home_object_; }
2930 0 : void set_home_object(Expression* e) { home_object_ = e; }
2931 :
2932 : private:
2933 : friend class AstNodeFactory;
2934 :
2935 : SuperPropertyReference(VariableProxy* this_var, Expression* home_object,
2936 : int pos)
2937 : : Expression(pos, kSuperPropertyReference),
2938 : this_var_(this_var),
2939 6119 : home_object_(home_object) {
2940 : DCHECK(this_var->is_this());
2941 : DCHECK(home_object->IsProperty());
2942 : }
2943 :
2944 : VariableProxy* this_var_;
2945 : Expression* home_object_;
2946 : };
2947 :
2948 :
2949 : class SuperCallReference final : public Expression {
2950 : public:
2951 : VariableProxy* this_var() const { return this_var_; }
2952 0 : void set_this_var(VariableProxy* v) { this_var_ = v; }
2953 : VariableProxy* new_target_var() const { return new_target_var_; }
2954 0 : void set_new_target_var(VariableProxy* v) { new_target_var_ = v; }
2955 : VariableProxy* this_function_var() const { return this_function_var_; }
2956 0 : void set_this_function_var(VariableProxy* v) { this_function_var_ = v; }
2957 :
2958 : private:
2959 : friend class AstNodeFactory;
2960 :
2961 : SuperCallReference(VariableProxy* this_var, VariableProxy* new_target_var,
2962 : VariableProxy* this_function_var, int pos)
2963 : : Expression(pos, kSuperCallReference),
2964 : this_var_(this_var),
2965 : new_target_var_(new_target_var),
2966 21195 : this_function_var_(this_function_var) {
2967 : DCHECK(this_var->is_this());
2968 : DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2969 : DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
2970 : }
2971 :
2972 : VariableProxy* this_var_;
2973 : VariableProxy* new_target_var_;
2974 : VariableProxy* this_function_var_;
2975 : };
2976 :
2977 : // This AST Node is used to represent a dynamic import call --
2978 : // import(argument).
2979 : class ImportCallExpression final : public Expression {
2980 : public:
2981 : Expression* argument() const { return argument_; }
2982 0 : void set_argument(Expression* argument) { argument_ = argument; }
2983 :
2984 : private:
2985 : friend class AstNodeFactory;
2986 :
2987 : ImportCallExpression(Expression* argument, int pos)
2988 948 : : Expression(pos, kImportCallExpression), argument_(argument) {}
2989 :
2990 : Expression* argument_;
2991 : };
2992 :
2993 : // This class is produced when parsing the () in arrow functions without any
2994 : // arguments and is not actually a valid expression.
2995 : class EmptyParentheses final : public Expression {
2996 : private:
2997 : friend class AstNodeFactory;
2998 :
2999 : explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {}
3000 : };
3001 :
3002 : // Represents the spec operation `GetIterator()`
3003 : // (defined at https://tc39.github.io/ecma262/#sec-getiterator). Ignition
3004 : // desugars this into a LoadIC / JSLoadNamed, CallIC, and a type-check to
3005 : // validate return value of the Symbol.iterator() call.
3006 : enum class IteratorType { kNormal, kAsync };
3007 : class GetIterator final : public Expression {
3008 : public:
3009 : IteratorType hint() const { return hint_; }
3010 :
3011 : Expression* iterable() const { return iterable_; }
3012 0 : void set_iterable(Expression* iterable) { iterable_ = iterable; }
3013 :
3014 : static int num_ids() { return parent_num_ids(); }
3015 :
3016 42385 : void AssignFeedbackSlots(FeedbackVectorSpec* spec, LanguageMode language_mode,
3017 42385 : FeedbackSlotCache* cache) {
3018 42385 : iterator_property_feedback_slot_ = spec->AddLoadICSlot();
3019 42385 : iterator_call_feedback_slot_ = spec->AddCallICSlot();
3020 42385 : if (hint() == IteratorType::kAsync) {
3021 380 : async_iterator_property_feedback_slot_ = spec->AddLoadICSlot();
3022 380 : async_iterator_call_feedback_slot_ = spec->AddCallICSlot();
3023 : }
3024 42385 : }
3025 :
3026 : FeedbackSlot IteratorPropertyFeedbackSlot() const {
3027 : return iterator_property_feedback_slot_;
3028 : }
3029 :
3030 : FeedbackSlot IteratorCallFeedbackSlot() const {
3031 : return iterator_call_feedback_slot_;
3032 : }
3033 :
3034 : FeedbackSlot AsyncIteratorPropertyFeedbackSlot() const {
3035 : return async_iterator_property_feedback_slot_;
3036 : }
3037 :
3038 : FeedbackSlot AsyncIteratorCallFeedbackSlot() const {
3039 : return async_iterator_call_feedback_slot_;
3040 : }
3041 :
3042 : private:
3043 : friend class AstNodeFactory;
3044 :
3045 : explicit GetIterator(Expression* iterable, IteratorType hint, int pos)
3046 213364 : : Expression(pos, kGetIterator), hint_(hint), iterable_(iterable) {}
3047 :
3048 : IteratorType hint_;
3049 : Expression* iterable_;
3050 : FeedbackSlot iterator_property_feedback_slot_;
3051 : FeedbackSlot iterator_call_feedback_slot_;
3052 : FeedbackSlot async_iterator_property_feedback_slot_;
3053 : FeedbackSlot async_iterator_call_feedback_slot_;
3054 : };
3055 :
3056 : // ----------------------------------------------------------------------------
3057 : // Basic visitor
3058 : // Sub-class should parametrize AstVisitor with itself, e.g.:
3059 : // class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
3060 :
3061 : template <class Subclass>
3062 : class AstVisitor BASE_EMBEDDED {
3063 : public:
3064 9367524 : void Visit(AstNode* node) { impl()->Visit(node); }
3065 :
3066 : void VisitDeclarations(Declaration::List* declarations) {
3067 5377147 : for (Declaration* decl : *declarations) Visit(decl);
3068 : }
3069 :
3070 3165325 : void VisitStatements(ZoneList<Statement*>* statements) {
3071 18243520 : for (int i = 0; i < statements->length(); i++) {
3072 16125745 : Statement* stmt = statements->at(i);
3073 : Visit(stmt);
3074 7003978 : if (stmt->IsJump()) break;
3075 : }
3076 3165322 : }
3077 :
3078 1696 : void VisitExpressions(ZoneList<Expression*>* expressions) {
3079 11668 : for (int i = 0; i < expressions->length(); i++) {
3080 : // The variable statement visiting code may pass NULL expressions
3081 : // to this code. Maybe this should be handled by introducing an
3082 : // undefined expression or literal? Revisit this code if this
3083 : // changes
3084 9972 : Expression* expression = expressions->at(i);
3085 4138 : if (expression != NULL) Visit(expression);
3086 : }
3087 1696 : }
3088 :
3089 : protected:
3090 : Subclass* impl() { return static_cast<Subclass*>(this); }
3091 : };
3092 :
3093 : #define GENERATE_VISIT_CASE(NodeType) \
3094 : case AstNode::k##NodeType: \
3095 : return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
3096 :
3097 : #define GENERATE_AST_VISITOR_SWITCH() \
3098 : switch (node->node_type()) { \
3099 : AST_NODE_LIST(GENERATE_VISIT_CASE) \
3100 : }
3101 :
3102 : #define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \
3103 : public: \
3104 : void VisitNoStackOverflowCheck(AstNode* node) { \
3105 : GENERATE_AST_VISITOR_SWITCH() \
3106 : } \
3107 : \
3108 : void Visit(AstNode* node) { \
3109 : if (CheckStackOverflow()) return; \
3110 : VisitNoStackOverflowCheck(node); \
3111 : } \
3112 : \
3113 : void SetStackOverflow() { stack_overflow_ = true; } \
3114 : void ClearStackOverflow() { stack_overflow_ = false; } \
3115 : bool HasStackOverflow() const { return stack_overflow_; } \
3116 : \
3117 : bool CheckStackOverflow() { \
3118 : if (stack_overflow_) return true; \
3119 : if (GetCurrentStackPosition() < stack_limit_) { \
3120 : stack_overflow_ = true; \
3121 : return true; \
3122 : } \
3123 : return false; \
3124 : } \
3125 : \
3126 : private: \
3127 : void InitializeAstVisitor(Isolate* isolate) { \
3128 : stack_limit_ = isolate->stack_guard()->real_climit(); \
3129 : stack_overflow_ = false; \
3130 : } \
3131 : \
3132 : void InitializeAstVisitor(uintptr_t stack_limit) { \
3133 : stack_limit_ = stack_limit; \
3134 : stack_overflow_ = false; \
3135 : } \
3136 : \
3137 : uintptr_t stack_limit_; \
3138 : bool stack_overflow_
3139 :
3140 : #define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW() \
3141 : public: \
3142 : void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
3143 : \
3144 : private:
3145 :
3146 : #define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \
3147 : public: \
3148 : AstNode* Rewrite(AstNode* node) { \
3149 : DCHECK_NULL(replacement_); \
3150 : DCHECK_NOT_NULL(node); \
3151 : Visit(node); \
3152 : if (HasStackOverflow()) return node; \
3153 : if (replacement_ == nullptr) return node; \
3154 : AstNode* result = replacement_; \
3155 : replacement_ = nullptr; \
3156 : return result; \
3157 : } \
3158 : \
3159 : private: \
3160 : void InitializeAstRewriter(Isolate* isolate) { \
3161 : InitializeAstVisitor(isolate); \
3162 : replacement_ = nullptr; \
3163 : } \
3164 : \
3165 : void InitializeAstRewriter(uintptr_t stack_limit) { \
3166 : InitializeAstVisitor(stack_limit); \
3167 : replacement_ = nullptr; \
3168 : } \
3169 : \
3170 : DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \
3171 : \
3172 : protected: \
3173 : AstNode* replacement_
3174 : // Generic macro for rewriting things; `GET` is the expression to be
3175 : // rewritten; `SET` is a command that should do the rewriting, i.e.
3176 : // something sensible with the variable called `replacement`.
3177 : #define AST_REWRITE(Type, GET, SET) \
3178 : do { \
3179 : DCHECK(!HasStackOverflow()); \
3180 : DCHECK_NULL(replacement_); \
3181 : Visit(GET); \
3182 : if (HasStackOverflow()) return; \
3183 : if (replacement_ == nullptr) break; \
3184 : Type* replacement = reinterpret_cast<Type*>(replacement_); \
3185 : do { \
3186 : SET; \
3187 : } while (false); \
3188 : replacement_ = nullptr; \
3189 : } while (false)
3190 :
3191 : // Macro for rewriting object properties; it assumes that `object` has
3192 : // `property` with a public getter and setter.
3193 : #define AST_REWRITE_PROPERTY(Type, object, property) \
3194 : do { \
3195 : auto _obj = (object); \
3196 : AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \
3197 : } while (false)
3198 :
3199 : // Macro for rewriting list elements; it assumes that `list` has methods
3200 : // `at` and `Set`.
3201 : #define AST_REWRITE_LIST_ELEMENT(Type, list, index) \
3202 : do { \
3203 : auto _list = (list); \
3204 : auto _index = (index); \
3205 : AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \
3206 : } while (false)
3207 :
3208 :
3209 : // ----------------------------------------------------------------------------
3210 : // AstNode factory
3211 :
3212 : class AstNodeFactory final BASE_EMBEDDED {
3213 : public:
3214 17905297 : explicit AstNodeFactory(AstValueFactory* ast_value_factory)
3215 22884268 : : zone_(nullptr), ast_value_factory_(ast_value_factory) {
3216 22884268 : if (ast_value_factory != nullptr) {
3217 19454495 : zone_ = ast_value_factory->zone();
3218 : }
3219 12794 : }
3220 :
3221 : AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
3222 3429793 : void set_ast_value_factory(AstValueFactory* ast_value_factory) {
3223 3429793 : ast_value_factory_ = ast_value_factory;
3224 3429793 : zone_ = ast_value_factory->zone();
3225 : }
3226 :
3227 83888 : VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
3228 : Scope* scope, int pos) {
3229 167776 : return new (zone_) VariableDeclaration(proxy, scope, pos);
3230 : }
3231 :
3232 : FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
3233 : FunctionLiteral* fun,
3234 : Scope* scope, int pos) {
3235 : return new (zone_) FunctionDeclaration(proxy, fun, scope, pos);
3236 : }
3237 :
3238 23820101 : Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity,
3239 : bool ignore_completion_value, int pos) {
3240 : return new (zone_)
3241 71460302 : Block(zone_, labels, capacity, ignore_completion_value, pos);
3242 : }
3243 :
3244 : #define STATEMENT_WITH_LABELS(NodeType) \
3245 : NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
3246 : return new (zone_) NodeType(labels, pos); \
3247 : }
3248 29352 : STATEMENT_WITH_LABELS(DoWhileStatement)
3249 224520 : STATEMENT_WITH_LABELS(WhileStatement)
3250 1575200 : STATEMENT_WITH_LABELS(ForStatement)
3251 184708 : STATEMENT_WITH_LABELS(SwitchStatement)
3252 : #undef STATEMENT_WITH_LABELS
3253 :
3254 179481 : ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3255 : ZoneList<const AstRawString*>* labels,
3256 : int pos) {
3257 179481 : switch (visit_mode) {
3258 : case ForEachStatement::ENUMERATE: {
3259 71499 : return new (zone_) ForInStatement(labels, pos);
3260 : }
3261 : case ForEachStatement::ITERATE: {
3262 107982 : return new (zone_) ForOfStatement(labels, pos);
3263 : }
3264 : }
3265 0 : UNREACHABLE();
3266 : return NULL;
3267 : }
3268 :
3269 43187 : ForOfStatement* NewForOfStatement(ZoneList<const AstRawString*>* labels,
3270 : int pos) {
3271 86374 : return new (zone_) ForOfStatement(labels, pos);
3272 : }
3273 :
3274 772437 : ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3275 1544874 : return new (zone_) ExpressionStatement(expression, pos);
3276 : }
3277 :
3278 : ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3279 : return new (zone_) ContinueStatement(target, pos);
3280 : }
3281 :
3282 : BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3283 : return new (zone_) BreakStatement(target, pos);
3284 : }
3285 :
3286 32224 : ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3287 : return new (zone_)
3288 64448 : ReturnStatement(expression, ReturnStatement::kNormal, pos);
3289 : }
3290 :
3291 : ReturnStatement* NewAsyncReturnStatement(Expression* expression, int pos) {
3292 : return new (zone_)
3293 : ReturnStatement(expression, ReturnStatement::kAsyncReturn, pos);
3294 : }
3295 :
3296 : WithStatement* NewWithStatement(Scope* scope,
3297 : Expression* expression,
3298 : Statement* statement,
3299 : int pos) {
3300 : return new (zone_) WithStatement(scope, expression, statement, pos);
3301 : }
3302 :
3303 : IfStatement* NewIfStatement(Expression* condition,
3304 : Statement* then_statement,
3305 : Statement* else_statement,
3306 : int pos) {
3307 : return new (zone_)
3308 : IfStatement(condition, then_statement, else_statement, pos);
3309 : }
3310 :
3311 : TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
3312 : Block* catch_block, int pos) {
3313 : return new (zone_) TryCatchStatement(try_block, scope, catch_block,
3314 : HandlerTable::CAUGHT, pos);
3315 : }
3316 :
3317 : TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
3318 : Scope* scope,
3319 : Block* catch_block,
3320 : int pos) {
3321 : return new (zone_) TryCatchStatement(try_block, scope, catch_block,
3322 : HandlerTable::UNCAUGHT, pos);
3323 : }
3324 :
3325 : TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
3326 : Scope* scope,
3327 : Block* catch_block,
3328 : int pos) {
3329 : return new (zone_) TryCatchStatement(try_block, scope, catch_block,
3330 : HandlerTable::DESUGARING, pos);
3331 : }
3332 :
3333 : TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
3334 : Scope* scope,
3335 : Block* catch_block,
3336 : int pos) {
3337 : return new (zone_) TryCatchStatement(try_block, scope, catch_block,
3338 : HandlerTable::ASYNC_AWAIT, pos);
3339 : }
3340 :
3341 : TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
3342 : Block* finally_block, int pos) {
3343 : return new (zone_) TryFinallyStatement(try_block, finally_block, pos);
3344 : }
3345 :
3346 : DebuggerStatement* NewDebuggerStatement(int pos) {
3347 : return new (zone_) DebuggerStatement(pos);
3348 : }
3349 :
3350 : EmptyStatement* NewEmptyStatement(int pos) {
3351 : return new (zone_) EmptyStatement(pos);
3352 : }
3353 :
3354 10583 : SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement() {
3355 : return new (zone_)
3356 21166 : SloppyBlockFunctionStatement(NewEmptyStatement(kNoSourcePosition));
3357 : }
3358 :
3359 : CaseClause* NewCaseClause(
3360 : Expression* label, ZoneList<Statement*>* statements, int pos) {
3361 535223 : return new (zone_) CaseClause(label, statements, pos);
3362 : }
3363 :
3364 36634589 : Literal* NewStringLiteral(const AstRawString* string, int pos) {
3365 73269134 : return new (zone_) Literal(ast_value_factory_->NewString(string), pos);
3366 : }
3367 :
3368 : // A JavaScript symbol (ECMA-262 edition 6).
3369 6119 : Literal* NewSymbolLiteral(AstSymbol symbol, int pos) {
3370 12238 : return new (zone_) Literal(ast_value_factory_->NewSymbol(symbol), pos);
3371 : }
3372 :
3373 4501096 : Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) {
3374 : return new (zone_)
3375 9002192 : Literal(ast_value_factory_->NewNumber(number, with_dot), pos);
3376 : }
3377 :
3378 30000019 : Literal* NewSmiLiteral(uint32_t number, int pos) {
3379 60000045 : return new (zone_) Literal(ast_value_factory_->NewSmi(number), pos);
3380 : }
3381 :
3382 1790858 : Literal* NewBooleanLiteral(bool b, int pos) {
3383 3581716 : return new (zone_) Literal(ast_value_factory_->NewBoolean(b), pos);
3384 : }
3385 :
3386 1052936 : Literal* NewNullLiteral(int pos) {
3387 2105872 : return new (zone_) Literal(ast_value_factory_->NewNull(), pos);
3388 : }
3389 :
3390 1263276 : Literal* NewUndefinedLiteral(int pos) {
3391 2526552 : return new (zone_) Literal(ast_value_factory_->NewUndefined(), pos);
3392 : }
3393 :
3394 1437236 : Literal* NewTheHoleLiteral(int pos) {
3395 2874472 : return new (zone_) Literal(ast_value_factory_->NewTheHole(), pos);
3396 : }
3397 :
3398 1590767 : ObjectLiteral* NewObjectLiteral(
3399 : ZoneList<ObjectLiteral::Property*>* properties,
3400 : uint32_t boilerplate_properties, int pos, bool has_rest_property) {
3401 : return new (zone_) ObjectLiteral(properties, boilerplate_properties, pos,
3402 3181534 : has_rest_property);
3403 : }
3404 :
3405 : ObjectLiteral::Property* NewObjectLiteralProperty(
3406 : Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
3407 : bool is_computed_name) {
3408 : return new (zone_)
3409 220800 : ObjectLiteral::Property(key, value, kind, is_computed_name);
3410 : }
3411 :
3412 4696999 : ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
3413 : Expression* value,
3414 : bool is_computed_name) {
3415 : return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
3416 9393999 : is_computed_name);
3417 : }
3418 :
3419 97489 : RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
3420 : int pos) {
3421 194978 : return new (zone_) RegExpLiteral(pattern, flags, pos);
3422 : }
3423 :
3424 26105 : ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3425 : int pos) {
3426 52210 : return new (zone_) ArrayLiteral(values, -1, pos);
3427 : }
3428 :
3429 770437 : ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3430 : int first_spread_index, int pos) {
3431 1540874 : return new (zone_) ArrayLiteral(values, first_spread_index, pos);
3432 : }
3433 :
3434 480536 : VariableProxy* NewVariableProxy(Variable* var,
3435 : int start_position = kNoSourcePosition) {
3436 14236844 : return new (zone_) VariableProxy(var, start_position);
3437 : }
3438 :
3439 83888 : VariableProxy* NewVariableProxy(const AstRawString* name,
3440 : VariableKind variable_kind,
3441 : int start_position = kNoSourcePosition) {
3442 : DCHECK_NOT_NULL(name);
3443 124296345 : return new (zone_) VariableProxy(name, variable_kind, start_position);
3444 : }
3445 :
3446 : // Recreates the VariableProxy in this Zone.
3447 : VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
3448 2534705 : return new (zone_) VariableProxy(proxy);
3449 : }
3450 :
3451 157 : Property* NewProperty(Expression* obj, Expression* key, int pos) {
3452 314 : return new (zone_) Property(obj, key, pos);
3453 : }
3454 :
3455 : Call* NewCall(Expression* expression, ZoneList<Expression*>* arguments,
3456 : int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
3457 11753107 : return new (zone_) Call(expression, arguments, pos, possibly_eval);
3458 : }
3459 :
3460 1028428 : CallNew* NewCallNew(Expression* expression,
3461 : ZoneList<Expression*>* arguments,
3462 : int pos) {
3463 2056856 : return new (zone_) CallNew(expression, arguments, pos);
3464 : }
3465 :
3466 2557204 : CallRuntime* NewCallRuntime(Runtime::FunctionId id,
3467 : ZoneList<Expression*>* arguments, int pos) {
3468 5114408 : return new (zone_) CallRuntime(Runtime::FunctionForId(id), arguments, pos);
3469 : }
3470 :
3471 1967574 : CallRuntime* NewCallRuntime(const Runtime::Function* function,
3472 : ZoneList<Expression*>* arguments, int pos) {
3473 3935148 : return new (zone_) CallRuntime(function, arguments, pos);
3474 : }
3475 :
3476 344323 : CallRuntime* NewCallRuntime(int context_index,
3477 : ZoneList<Expression*>* arguments, int pos) {
3478 688646 : return new (zone_) CallRuntime(context_index, arguments, pos);
3479 : }
3480 :
3481 : UnaryOperation* NewUnaryOperation(Token::Value op,
3482 : Expression* expression,
3483 : int pos) {
3484 : return new (zone_) UnaryOperation(op, expression, pos);
3485 : }
3486 :
3487 7952078 : BinaryOperation* NewBinaryOperation(Token::Value op,
3488 : Expression* left,
3489 : Expression* right,
3490 : int pos) {
3491 15904156 : return new (zone_) BinaryOperation(op, left, right, pos);
3492 : }
3493 :
3494 1547929 : CountOperation* NewCountOperation(Token::Value op,
3495 : bool is_prefix,
3496 : Expression* expr,
3497 : int pos) {
3498 3095858 : return new (zone_) CountOperation(op, is_prefix, expr, pos);
3499 : }
3500 :
3501 7069283 : CompareOperation* NewCompareOperation(Token::Value op,
3502 : Expression* left,
3503 : Expression* right,
3504 : int pos) {
3505 14138567 : return new (zone_) CompareOperation(op, left, right, pos);
3506 : }
3507 :
3508 : Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3509 : return new (zone_) Spread(expression, pos, expr_pos);
3510 : }
3511 :
3512 : Conditional* NewConditional(Expression* condition,
3513 : Expression* then_expression,
3514 : Expression* else_expression,
3515 : int position) {
3516 : return new (zone_)
3517 : Conditional(condition, then_expression, else_expression, position);
3518 : }
3519 :
3520 : RewritableExpression* NewRewritableExpression(Expression* expression) {
3521 : DCHECK_NOT_NULL(expression);
3522 : return new (zone_) RewritableExpression(expression);
3523 : }
3524 :
3525 28097094 : Assignment* NewAssignment(Token::Value op,
3526 : Expression* target,
3527 : Expression* value,
3528 563565 : int pos) {
3529 : DCHECK(Token::IsAssignmentOp(op));
3530 :
3531 43339224 : if (op != Token::INIT && target->IsVariableProxy()) {
3532 8483267 : target->AsVariableProxy()->set_is_assigned();
3533 : }
3534 :
3535 56194201 : Assignment* assign = new (zone_) Assignment(op, target, value, pos);
3536 28097090 : if (assign->is_compound()) {
3537 : assign->binary_operation_ =
3538 1127130 : NewBinaryOperation(assign->binary_op(), target, value, pos + 1);
3539 : }
3540 28097090 : return assign;
3541 : }
3542 :
3543 186530 : Suspend* NewSuspend(Expression* generator_object, Expression* expression,
3544 : int pos, Suspend::OnException on_exception,
3545 : SuspendFlags flags) {
3546 186530 : if (!expression) expression = NewUndefinedLiteral(pos);
3547 : return new (zone_)
3548 373060 : Suspend(generator_object, expression, pos, on_exception, flags);
3549 : }
3550 :
3551 378107 : Throw* NewThrow(Expression* exception, int pos) {
3552 756214 : return new (zone_) Throw(exception, pos);
3553 : }
3554 :
3555 8143841 : FunctionLiteral* NewFunctionLiteral(
3556 : const AstRawString* name, DeclarationScope* scope,
3557 : ZoneList<Statement*>* body, int expected_property_count,
3558 : int parameter_count, int function_length,
3559 : FunctionLiteral::ParameterFlag has_duplicate_parameters,
3560 : FunctionLiteral::FunctionType function_type,
3561 : FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
3562 : bool has_braces, int function_literal_id) {
3563 : return new (zone_) FunctionLiteral(
3564 : zone_, name, ast_value_factory_, scope, body, expected_property_count,
3565 : parameter_count, function_length, function_type,
3566 : has_duplicate_parameters, eager_compile_hint, position, has_braces,
3567 16287687 : function_literal_id);
3568 : }
3569 :
3570 : // Creates a FunctionLiteral representing a top-level script, the
3571 : // result of an eval (top-level or otherwise), or the result of calling
3572 : // the Function constructor.
3573 1883811 : FunctionLiteral* NewScriptOrEvalFunctionLiteral(DeclarationScope* scope,
3574 : ZoneList<Statement*>* body,
3575 : int expected_property_count,
3576 : int parameter_count) {
3577 : return new (zone_) FunctionLiteral(
3578 1883811 : zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
3579 : body, expected_property_count, parameter_count, parameter_count,
3580 : FunctionLiteral::kAnonymousExpression,
3581 : FunctionLiteral::kNoDuplicateParameters,
3582 : FunctionLiteral::kShouldLazyCompile, 0, true,
3583 3767632 : FunctionLiteral::kIdTypeTopLevel);
3584 : }
3585 :
3586 : ClassLiteral::Property* NewClassLiteralProperty(
3587 : Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
3588 : bool is_static, bool is_computed_name) {
3589 : return new (zone_)
3590 350663 : ClassLiteral::Property(key, value, kind, is_static, is_computed_name);
3591 : }
3592 :
3593 92611 : ClassLiteral* NewClassLiteral(VariableProxy* proxy, Expression* extends,
3594 : FunctionLiteral* constructor,
3595 : ZoneList<ClassLiteral::Property*>* properties,
3596 : int start_position, int end_position,
3597 : bool has_name_static_property,
3598 : bool has_static_computed_names) {
3599 : return new (zone_) ClassLiteral(
3600 : proxy, extends, constructor, properties, start_position, end_position,
3601 185222 : has_name_static_property, has_static_computed_names);
3602 : }
3603 :
3604 2988 : NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
3605 : v8::Extension* extension,
3606 : int pos) {
3607 5976 : return new (zone_) NativeFunctionLiteral(name, extension, pos);
3608 : }
3609 :
3610 435266 : DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) {
3611 : VariableProxy* result = NewVariableProxy(result_var, pos);
3612 870532 : return new (zone_) DoExpression(block, result, pos);
3613 : }
3614 :
3615 : ThisFunction* NewThisFunction(int pos) {
3616 : return new (zone_) ThisFunction(pos);
3617 : }
3618 :
3619 : SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var,
3620 : Expression* home_object,
3621 : int pos) {
3622 : return new (zone_) SuperPropertyReference(this_var, home_object, pos);
3623 : }
3624 :
3625 : SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
3626 : VariableProxy* new_target_var,
3627 : VariableProxy* this_function_var,
3628 : int pos) {
3629 : return new (zone_)
3630 : SuperCallReference(this_var, new_target_var, this_function_var, pos);
3631 : }
3632 :
3633 : EmptyParentheses* NewEmptyParentheses(int pos) {
3634 : return new (zone_) EmptyParentheses(pos);
3635 : }
3636 :
3637 213364 : GetIterator* NewGetIterator(Expression* iterable, IteratorType hint,
3638 : int pos) {
3639 426728 : return new (zone_) GetIterator(iterable, hint, pos);
3640 : }
3641 :
3642 : ImportCallExpression* NewImportCallExpression(Expression* args, int pos) {
3643 : return new (zone_) ImportCallExpression(args, pos);
3644 : }
3645 :
3646 : Zone* zone() const { return zone_; }
3647 16710541 : void set_zone(Zone* zone) { zone_ = zone; }
3648 :
3649 : // Handles use of temporary zones when parsing inner function bodies.
3650 : class BodyScope {
3651 : public:
3652 : BodyScope(AstNodeFactory* factory, Zone* temp_zone, bool use_temp_zone)
3653 7562020 : : factory_(factory), prev_zone_(factory->zone_) {
3654 7562020 : if (use_temp_zone) {
3655 1403478 : factory->zone_ = temp_zone;
3656 : }
3657 : }
3658 :
3659 15124085 : void Reset() { factory_->zone_ = prev_zone_; }
3660 : ~BodyScope() { Reset(); }
3661 :
3662 : private:
3663 : AstNodeFactory* factory_;
3664 : Zone* prev_zone_;
3665 : };
3666 :
3667 : private:
3668 : // This zone may be deallocated upon returning from parsing a function body
3669 : // which we can guarantee is not going to be compiled or have its AST
3670 : // inspected.
3671 : // See ParseFunctionLiteral in parser.cc for preconditions.
3672 : Zone* zone_;
3673 : AstValueFactory* ast_value_factory_;
3674 : };
3675 :
3676 :
3677 : // Type testing & conversion functions overridden by concrete subclasses.
3678 : // Inline functions for AstNode.
3679 :
3680 : #define DECLARE_NODE_FUNCTIONS(type) \
3681 : bool AstNode::Is##type() const { \
3682 : NodeType mine = node_type(); \
3683 : if (mine == AstNode::kRewritableExpression && \
3684 : AstNode::k##type != AstNode::kRewritableExpression) \
3685 : mine = reinterpret_cast<const RewritableExpression*>(this) \
3686 : ->expression() \
3687 : ->node_type(); \
3688 : return mine == AstNode::k##type; \
3689 : } \
3690 : type* AstNode::As##type() { \
3691 : NodeType mine = node_type(); \
3692 : AstNode* result = this; \
3693 : if (mine == AstNode::kRewritableExpression && \
3694 : AstNode::k##type != AstNode::kRewritableExpression) { \
3695 : result = \
3696 : reinterpret_cast<const RewritableExpression*>(this)->expression(); \
3697 : mine = result->node_type(); \
3698 : } \
3699 : return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \
3700 : } \
3701 : const type* AstNode::As##type() const { \
3702 : NodeType mine = node_type(); \
3703 : const AstNode* result = this; \
3704 : if (mine == AstNode::kRewritableExpression && \
3705 : AstNode::k##type != AstNode::kRewritableExpression) { \
3706 : result = \
3707 : reinterpret_cast<const RewritableExpression*>(this)->expression(); \
3708 : mine = result->node_type(); \
3709 : } \
3710 : return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \
3711 : : NULL; \
3712 : }
3713 1304557857 : AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3714 : #undef DECLARE_NODE_FUNCTIONS
3715 :
3716 :
3717 : } // namespace internal
3718 : } // namespace v8
3719 :
3720 : #endif // V8_AST_AST_H_
|