blob: dcb440d7c77a66fd95db37af81410e48bc8217c5 [file] [log] [blame]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001// 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/assembler.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/base/smart-pointers.h"
15#include "src/factory.h"
16#include "src/isolate.h"
17#include "src/list.h"
18#include "src/parsing/token.h"
19#include "src/runtime/runtime.h"
20#include "src/small-pointer-list.h"
21#include "src/types.h"
22#include "src/utils.h"
23
24namespace v8 {
25namespace 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 V(ImportDeclaration) \
44 V(ExportDeclaration)
45
46#define STATEMENT_NODE_LIST(V) \
47 V(Block) \
48 V(ExpressionStatement) \
49 V(EmptyStatement) \
50 V(SloppyBlockFunctionStatement) \
51 V(IfStatement) \
52 V(ContinueStatement) \
53 V(BreakStatement) \
54 V(ReturnStatement) \
55 V(WithStatement) \
56 V(SwitchStatement) \
57 V(DoWhileStatement) \
58 V(WhileStatement) \
59 V(ForStatement) \
60 V(ForInStatement) \
61 V(ForOfStatement) \
62 V(TryCatchStatement) \
63 V(TryFinallyStatement) \
64 V(DebuggerStatement)
65
66#define EXPRESSION_NODE_LIST(V) \
67 V(FunctionLiteral) \
68 V(ClassLiteral) \
69 V(NativeFunctionLiteral) \
70 V(Conditional) \
71 V(VariableProxy) \
72 V(Literal) \
73 V(RegExpLiteral) \
74 V(ObjectLiteral) \
75 V(ArrayLiteral) \
76 V(Assignment) \
77 V(Yield) \
78 V(Throw) \
79 V(Property) \
80 V(Call) \
81 V(CallNew) \
82 V(CallRuntime) \
83 V(UnaryOperation) \
84 V(CountOperation) \
85 V(BinaryOperation) \
86 V(CompareOperation) \
87 V(Spread) \
88 V(ThisFunction) \
89 V(SuperPropertyReference) \
90 V(SuperCallReference) \
91 V(CaseClause) \
92 V(EmptyParentheses) \
93 V(DoExpression) \
Ben Murdoch097c5b22016-05-18 11:27:45 +010094 V(RewritableExpression)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000095
96#define AST_NODE_LIST(V) \
97 DECLARATION_NODE_LIST(V) \
98 STATEMENT_NODE_LIST(V) \
99 EXPRESSION_NODE_LIST(V)
100
101// Forward declarations
102class AstNodeFactory;
103class AstVisitor;
104class Declaration;
105class Module;
106class BreakableStatement;
107class Expression;
108class IterationStatement;
109class MaterializedLiteral;
110class Statement;
111class TypeFeedbackOracle;
112
113#define DEF_FORWARD_DECLARATION(type) class type;
114AST_NODE_LIST(DEF_FORWARD_DECLARATION)
115#undef DEF_FORWARD_DECLARATION
116
117
118// Typedef only introduced to avoid unreadable code.
119typedef ZoneList<Handle<String>> ZoneStringList;
120typedef ZoneList<Handle<Object>> ZoneObjectList;
121
122
123#define DECLARE_NODE_TYPE(type) \
124 void Accept(AstVisitor* v) override; \
125 AstNode::NodeType node_type() const final { return AstNode::k##type; } \
126 friend class AstNodeFactory;
127
128
129class FeedbackVectorSlotCache {
130 public:
131 explicit FeedbackVectorSlotCache(Zone* zone)
132 : zone_(zone),
133 hash_map_(HashMap::PointersMatch, ZoneHashMap::kDefaultHashMapCapacity,
134 ZoneAllocationPolicy(zone)) {}
135
136 void Put(Variable* variable, FeedbackVectorSlot slot) {
137 ZoneHashMap::Entry* entry = hash_map_.LookupOrInsert(
138 variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_));
139 entry->value = reinterpret_cast<void*>(slot.ToInt());
140 }
141
142 ZoneHashMap::Entry* Get(Variable* variable) const {
143 return hash_map_.Lookup(variable, ComputePointerHash(variable));
144 }
145
146 private:
147 Zone* zone_;
148 ZoneHashMap hash_map_;
149};
150
151
152class AstProperties final BASE_EMBEDDED {
153 public:
154 enum Flag {
155 kNoFlags = 0,
156 kDontSelfOptimize = 1 << 0,
157 kDontCrankshaft = 1 << 1
158 };
159
160 typedef base::Flags<Flag> Flags;
161
162 explicit AstProperties(Zone* zone) : node_count_(0), spec_(zone) {}
163
164 Flags& flags() { return flags_; }
165 Flags flags() const { return flags_; }
166 int node_count() { return node_count_; }
167 void add_node_count(int count) { node_count_ += count; }
168
169 const FeedbackVectorSpec* get_spec() const { return &spec_; }
170 FeedbackVectorSpec* get_spec() { return &spec_; }
171
172 private:
173 Flags flags_;
174 int node_count_;
175 FeedbackVectorSpec spec_;
176};
177
178DEFINE_OPERATORS_FOR_FLAGS(AstProperties::Flags)
179
180
181class AstNode: public ZoneObject {
182 public:
183#define DECLARE_TYPE_ENUM(type) k##type,
184 enum NodeType {
185 AST_NODE_LIST(DECLARE_TYPE_ENUM)
186 kInvalid = -1
187 };
188#undef DECLARE_TYPE_ENUM
189
190 void* operator new(size_t size, Zone* zone) { return zone->New(size); }
191
192 explicit AstNode(int position): position_(position) {}
193 virtual ~AstNode() {}
194
195 virtual void Accept(AstVisitor* v) = 0;
196 virtual NodeType node_type() const = 0;
197 int position() const { return position_; }
198
Ben Murdoch097c5b22016-05-18 11:27:45 +0100199#ifdef DEBUG
200 void PrettyPrint(Isolate* isolate);
201 void PrettyPrint();
202 void Print(Isolate* isolate);
203 void Print();
204#endif // DEBUG
205
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000206 // Type testing & conversion functions overridden by concrete subclasses.
207#define DECLARE_NODE_FUNCTIONS(type) \
Ben Murdoch097c5b22016-05-18 11:27:45 +0100208 V8_INLINE bool Is##type() const; \
209 V8_INLINE type* As##type(); \
210 V8_INLINE const type* As##type() const;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000211 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
212#undef DECLARE_NODE_FUNCTIONS
213
214 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
215 virtual IterationStatement* AsIterationStatement() { return NULL; }
216 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
217
218 // The interface for feedback slots, with default no-op implementations for
219 // node types which don't actually have this. Note that this is conceptually
220 // not really nice, but multiple inheritance would introduce yet another
221 // vtable entry per node, something we don't want for space reasons.
222 virtual void AssignFeedbackVectorSlots(Isolate* isolate,
223 FeedbackVectorSpec* spec,
224 FeedbackVectorSlotCache* cache) {}
225
226 private:
227 // Hidden to prevent accidental usage. It would have to load the
228 // current zone from the TLS.
229 void* operator new(size_t size);
230
231 friend class CaseClause; // Generates AST IDs.
232
233 int position_;
234};
235
236
237class Statement : public AstNode {
238 public:
239 explicit Statement(Zone* zone, int position) : AstNode(position) {}
240
241 bool IsEmpty() { return AsEmptyStatement() != NULL; }
242 virtual bool IsJump() const { return false; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000243};
244
245
246class SmallMapList final {
247 public:
248 SmallMapList() {}
249 SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
250
251 void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
252 void Clear() { list_.Clear(); }
253 void Sort() { list_.Sort(); }
254
255 bool is_empty() const { return list_.is_empty(); }
256 int length() const { return list_.length(); }
257
258 void AddMapIfMissing(Handle<Map> map, Zone* zone) {
259 if (!Map::TryUpdate(map).ToHandle(&map)) return;
260 for (int i = 0; i < length(); ++i) {
261 if (at(i).is_identical_to(map)) return;
262 }
263 Add(map, zone);
264 }
265
266 void FilterForPossibleTransitions(Map* root_map) {
267 for (int i = list_.length() - 1; i >= 0; i--) {
268 if (at(i)->FindRootMap() != root_map) {
269 list_.RemoveElement(list_.at(i));
270 }
271 }
272 }
273
274 void Add(Handle<Map> handle, Zone* zone) {
275 list_.Add(handle.location(), zone);
276 }
277
278 Handle<Map> at(int i) const {
279 return Handle<Map>(list_.at(i));
280 }
281
282 Handle<Map> first() const { return at(0); }
283 Handle<Map> last() const { return at(length() - 1); }
284
285 private:
286 // The list stores pointers to Map*, that is Map**, so it's GC safe.
287 SmallPointerList<Map*> list_;
288
289 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
290};
291
292
293class Expression : public AstNode {
294 public:
295 enum Context {
296 // Not assigned a context yet, or else will not be visited during
297 // code generation.
298 kUninitialized,
299 // Evaluated for its side effects.
300 kEffect,
301 // Evaluated for its value (and side effects).
302 kValue,
303 // Evaluated for control flow (and side effects).
304 kTest
305 };
306
307 // Mark this expression as being in tail position.
308 virtual void MarkTail() {}
309
310 // True iff the expression is a valid reference expression.
311 virtual bool IsValidReferenceExpression() const { return false; }
312
313 // Helpers for ToBoolean conversion.
314 virtual bool ToBooleanIsTrue() const { return false; }
315 virtual bool ToBooleanIsFalse() const { return false; }
316
317 // Symbols that cannot be parsed as array indices are considered property
318 // names. We do not treat symbols that can be array indexes as property
319 // names because [] for string objects is handled only by keyed ICs.
320 virtual bool IsPropertyName() const { return false; }
321
Ben Murdoch097c5b22016-05-18 11:27:45 +0100322 // True iff the expression is a class or function expression without
323 // a syntactic name.
324 virtual bool IsAnonymousFunctionDefinition() const { return false; }
325
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000326 // True iff the expression is a literal represented as a smi.
327 bool IsSmiLiteral() 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.
336 bool IsUndefinedLiteral(Isolate* isolate) const;
337
338 // True iff the expression is a valid target for an assignment.
339 bool IsValidReferenceExpressionOrThis() const;
340
341 // Expression type bounds
342 Bounds bounds() const { return bounds_; }
343 void set_bounds(Bounds bounds) { bounds_ = bounds; }
344
345 // Type feedback information for assignments and properties.
346 virtual bool IsMonomorphic() {
347 UNREACHABLE();
348 return false;
349 }
350 virtual SmallMapList* GetReceiverTypes() {
351 UNREACHABLE();
352 return NULL;
353 }
354 virtual KeyedAccessStoreMode GetStoreMode() const {
355 UNREACHABLE();
356 return STANDARD_STORE;
357 }
358 virtual IcCheckType GetKeyType() const {
359 UNREACHABLE();
360 return ELEMENT;
361 }
362
363 // TODO(rossberg): this should move to its own AST node eventually.
364 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
365 uint16_t to_boolean_types() const {
366 return ToBooleanTypesField::decode(bit_field_);
367 }
368
369 void set_base_id(int id) { base_id_ = id; }
370 static int num_ids() { return parent_num_ids() + 2; }
371 BailoutId id() const { return BailoutId(local_id(0)); }
372 TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
373
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000374 protected:
375 Expression(Zone* zone, int pos)
376 : AstNode(pos),
377 base_id_(BailoutId::None().ToInt()),
378 bounds_(Bounds::Unbounded()),
379 bit_field_(0) {}
380 static int parent_num_ids() { return 0; }
381 void set_to_boolean_types(uint16_t types) {
382 bit_field_ = ToBooleanTypesField::update(bit_field_, types);
383 }
384
385 int base_id() const {
386 DCHECK(!BailoutId(base_id_).IsNone());
387 return base_id_;
388 }
389
390 private:
391 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
392
393 int base_id_;
394 Bounds bounds_;
395 class ToBooleanTypesField : public BitField16<uint16_t, 0, 9> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000396 uint16_t bit_field_;
397 // Ends with 16-bit field; deriving classes in turn begin with
398 // 16-bit fields for optimum packing efficiency.
399};
400
401
402class BreakableStatement : public Statement {
403 public:
404 enum BreakableType {
405 TARGET_FOR_ANONYMOUS,
406 TARGET_FOR_NAMED_ONLY
407 };
408
409 // The labels associated with this statement. May be NULL;
410 // if it is != NULL, guaranteed to contain at least one entry.
411 ZoneList<const AstRawString*>* labels() const { return labels_; }
412
413 // Type testing & conversion.
414 BreakableStatement* AsBreakableStatement() final { return this; }
415
416 // Code generation
417 Label* break_target() { return &break_target_; }
418
419 // Testers.
420 bool is_target_for_anonymous() const {
421 return breakable_type_ == TARGET_FOR_ANONYMOUS;
422 }
423
424 void set_base_id(int id) { base_id_ = id; }
425 static int num_ids() { return parent_num_ids() + 2; }
426 BailoutId EntryId() const { return BailoutId(local_id(0)); }
427 BailoutId ExitId() const { return BailoutId(local_id(1)); }
428
429 protected:
430 BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
431 BreakableType breakable_type, int position)
432 : Statement(zone, position),
433 labels_(labels),
434 breakable_type_(breakable_type),
435 base_id_(BailoutId::None().ToInt()) {
436 DCHECK(labels == NULL || labels->length() > 0);
437 }
438 static int parent_num_ids() { return 0; }
439
440 int base_id() const {
441 DCHECK(!BailoutId(base_id_).IsNone());
442 return base_id_;
443 }
444
445 private:
446 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
447
448 ZoneList<const AstRawString*>* labels_;
449 BreakableType breakable_type_;
450 Label break_target_;
451 int base_id_;
452};
453
454
455class Block final : public BreakableStatement {
456 public:
457 DECLARE_NODE_TYPE(Block)
458
459 ZoneList<Statement*>* statements() { return &statements_; }
460 bool ignore_completion_value() const { return ignore_completion_value_; }
461
462 static int num_ids() { return parent_num_ids() + 1; }
463 BailoutId DeclsId() const { return BailoutId(local_id(0)); }
464
465 bool IsJump() const override {
466 return !statements_.is_empty() && statements_.last()->IsJump()
467 && labels() == NULL; // Good enough as an approximation...
468 }
469
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000470 Scope* scope() const { return scope_; }
471 void set_scope(Scope* scope) { scope_ = scope; }
472
473 protected:
474 Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
475 bool ignore_completion_value, int pos)
476 : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos),
477 statements_(capacity, zone),
478 ignore_completion_value_(ignore_completion_value),
479 scope_(NULL) {}
480 static int parent_num_ids() { return BreakableStatement::num_ids(); }
481
482 private:
483 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
484
485 ZoneList<Statement*> statements_;
486 bool ignore_completion_value_;
487 Scope* scope_;
488};
489
490
491class DoExpression final : public Expression {
492 public:
493 DECLARE_NODE_TYPE(DoExpression)
494
495 Block* block() { return block_; }
496 void set_block(Block* b) { block_ = b; }
497 VariableProxy* result() { return result_; }
498 void set_result(VariableProxy* v) { result_ = v; }
499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500 protected:
501 DoExpression(Zone* zone, Block* block, VariableProxy* result, int pos)
502 : Expression(zone, pos), block_(block), result_(result) {
503 DCHECK_NOT_NULL(block_);
504 DCHECK_NOT_NULL(result_);
505 }
506 static int parent_num_ids() { return Expression::num_ids(); }
507
508 private:
509 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
510
511 Block* block_;
512 VariableProxy* result_;
513};
514
515
516class Declaration : public AstNode {
517 public:
518 VariableProxy* proxy() const { return proxy_; }
519 VariableMode mode() const { return mode_; }
520 Scope* scope() const { return scope_; }
521 virtual InitializationFlag initialization() const = 0;
522 virtual bool IsInlineable() const;
523
524 protected:
525 Declaration(Zone* zone, VariableProxy* proxy, VariableMode mode, Scope* scope,
526 int pos)
527 : AstNode(pos), mode_(mode), proxy_(proxy), scope_(scope) {
528 DCHECK(IsDeclaredVariableMode(mode));
529 }
530
531 private:
532 VariableMode mode_;
533 VariableProxy* proxy_;
534
535 // Nested scope from which the declaration originated.
536 Scope* scope_;
537};
538
539
540class VariableDeclaration final : public Declaration {
541 public:
542 DECLARE_NODE_TYPE(VariableDeclaration)
543
544 InitializationFlag initialization() const override {
545 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
546 }
547
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000548 protected:
549 VariableDeclaration(Zone* zone, VariableProxy* proxy, VariableMode mode,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100550 Scope* scope, int pos)
551 : Declaration(zone, proxy, mode, scope, pos) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000552};
553
554
555class FunctionDeclaration final : public Declaration {
556 public:
557 DECLARE_NODE_TYPE(FunctionDeclaration)
558
559 FunctionLiteral* fun() const { return fun_; }
560 void set_fun(FunctionLiteral* f) { fun_ = f; }
561 InitializationFlag initialization() const override {
562 return kCreatedInitialized;
563 }
564 bool IsInlineable() const override;
565
566 protected:
567 FunctionDeclaration(Zone* zone,
568 VariableProxy* proxy,
569 VariableMode mode,
570 FunctionLiteral* fun,
571 Scope* scope,
572 int pos)
573 : Declaration(zone, proxy, mode, scope, pos),
574 fun_(fun) {
575 DCHECK(mode == VAR || mode == LET || mode == CONST);
576 DCHECK(fun != NULL);
577 }
578
579 private:
580 FunctionLiteral* fun_;
581};
582
583
584class ImportDeclaration final : public Declaration {
585 public:
586 DECLARE_NODE_TYPE(ImportDeclaration)
587
588 const AstRawString* import_name() const { return import_name_; }
589 const AstRawString* module_specifier() const { return module_specifier_; }
590 void set_module_specifier(const AstRawString* module_specifier) {
591 DCHECK(module_specifier_ == NULL);
592 module_specifier_ = module_specifier;
593 }
594 InitializationFlag initialization() const override {
595 return kNeedsInitialization;
596 }
597
598 protected:
599 ImportDeclaration(Zone* zone, VariableProxy* proxy,
600 const AstRawString* import_name,
601 const AstRawString* module_specifier, Scope* scope, int pos)
602 : Declaration(zone, proxy, IMPORT, scope, pos),
603 import_name_(import_name),
604 module_specifier_(module_specifier) {}
605
606 private:
607 const AstRawString* import_name_;
608 const AstRawString* module_specifier_;
609};
610
611
612class ExportDeclaration final : public Declaration {
613 public:
614 DECLARE_NODE_TYPE(ExportDeclaration)
615
616 InitializationFlag initialization() const override {
617 return kCreatedInitialized;
618 }
619
620 protected:
621 ExportDeclaration(Zone* zone, VariableProxy* proxy, Scope* scope, int pos)
622 : Declaration(zone, proxy, LET, scope, pos) {}
623};
624
625
626class Module : public AstNode {
627 public:
628 ModuleDescriptor* descriptor() const { return descriptor_; }
629 Block* body() const { return body_; }
630
631 protected:
632 Module(Zone* zone, int pos)
633 : AstNode(pos), descriptor_(ModuleDescriptor::New(zone)), body_(NULL) {}
634 Module(Zone* zone, ModuleDescriptor* descriptor, int pos, Block* body = NULL)
635 : AstNode(pos), descriptor_(descriptor), body_(body) {}
636
637 private:
638 ModuleDescriptor* descriptor_;
639 Block* body_;
640};
641
642
643class IterationStatement : public BreakableStatement {
644 public:
645 // Type testing & conversion.
646 IterationStatement* AsIterationStatement() final { return this; }
647
648 Statement* body() const { return body_; }
649 void set_body(Statement* s) { body_ = s; }
650
651 static int num_ids() { return parent_num_ids() + 1; }
652 BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
653 virtual BailoutId ContinueId() const = 0;
654 virtual BailoutId StackCheckId() const = 0;
655
656 // Code generation
657 Label* continue_target() { return &continue_target_; }
658
659 protected:
660 IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
661 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
662 body_(NULL) {}
663 static int parent_num_ids() { return BreakableStatement::num_ids(); }
664 void Initialize(Statement* body) { body_ = body; }
665
666 private:
667 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
668
669 Statement* body_;
670 Label continue_target_;
671};
672
673
674class DoWhileStatement final : public IterationStatement {
675 public:
676 DECLARE_NODE_TYPE(DoWhileStatement)
677
678 void Initialize(Expression* cond, Statement* body) {
679 IterationStatement::Initialize(body);
680 cond_ = cond;
681 }
682
683 Expression* cond() const { return cond_; }
684 void set_cond(Expression* e) { cond_ = e; }
685
686 static int num_ids() { return parent_num_ids() + 2; }
687 BailoutId ContinueId() const override { return BailoutId(local_id(0)); }
688 BailoutId StackCheckId() const override { return BackEdgeId(); }
689 BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
690
691 protected:
692 DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
693 : IterationStatement(zone, labels, pos), cond_(NULL) {}
694 static int parent_num_ids() { return IterationStatement::num_ids(); }
695
696 private:
697 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
698
699 Expression* cond_;
700};
701
702
703class WhileStatement final : public IterationStatement {
704 public:
705 DECLARE_NODE_TYPE(WhileStatement)
706
707 void Initialize(Expression* cond, Statement* body) {
708 IterationStatement::Initialize(body);
709 cond_ = cond;
710 }
711
712 Expression* cond() const { return cond_; }
713 void set_cond(Expression* e) { cond_ = e; }
714
715 static int num_ids() { return parent_num_ids() + 1; }
716 BailoutId ContinueId() const override { return EntryId(); }
717 BailoutId StackCheckId() const override { return BodyId(); }
718 BailoutId BodyId() const { return BailoutId(local_id(0)); }
719
720 protected:
721 WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
722 : IterationStatement(zone, labels, pos), cond_(NULL) {}
723 static int parent_num_ids() { return IterationStatement::num_ids(); }
724
725 private:
726 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
727
728 Expression* cond_;
729};
730
731
732class ForStatement final : public IterationStatement {
733 public:
734 DECLARE_NODE_TYPE(ForStatement)
735
736 void Initialize(Statement* init,
737 Expression* cond,
738 Statement* next,
739 Statement* body) {
740 IterationStatement::Initialize(body);
741 init_ = init;
742 cond_ = cond;
743 next_ = next;
744 }
745
746 Statement* init() const { return init_; }
747 Expression* cond() const { return cond_; }
748 Statement* next() const { return next_; }
749
750 void set_init(Statement* s) { init_ = s; }
751 void set_cond(Expression* e) { cond_ = e; }
752 void set_next(Statement* s) { next_ = s; }
753
754 static int num_ids() { return parent_num_ids() + 2; }
755 BailoutId ContinueId() const override { return BailoutId(local_id(0)); }
756 BailoutId StackCheckId() const override { return BodyId(); }
757 BailoutId BodyId() const { return BailoutId(local_id(1)); }
758
759 protected:
760 ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
761 : IterationStatement(zone, labels, pos),
762 init_(NULL),
763 cond_(NULL),
764 next_(NULL) {}
765 static int parent_num_ids() { return IterationStatement::num_ids(); }
766
767 private:
768 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
769
770 Statement* init_;
771 Expression* cond_;
772 Statement* next_;
773};
774
775
776class ForEachStatement : public IterationStatement {
777 public:
778 enum VisitMode {
779 ENUMERATE, // for (each in subject) body;
780 ITERATE // for (each of subject) body;
781 };
782
783 void Initialize(Expression* each, Expression* subject, Statement* body) {
784 IterationStatement::Initialize(body);
785 each_ = each;
786 subject_ = subject;
787 }
788
789 Expression* each() const { return each_; }
790 Expression* subject() const { return subject_; }
791
792 void set_each(Expression* e) { each_ = e; }
793 void set_subject(Expression* e) { subject_ = e; }
794
795 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
796 FeedbackVectorSlotCache* cache) override;
797 FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; }
798
Ben Murdoch097c5b22016-05-18 11:27:45 +0100799 static const char* VisitModeString(VisitMode mode) {
800 return mode == ITERATE ? "for-of" : "for-in";
801 }
802
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000803 protected:
804 ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
805 : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {}
806
807 private:
808 Expression* each_;
809 Expression* subject_;
810 FeedbackVectorSlot each_slot_;
811};
812
813
814class ForInStatement final : public ForEachStatement {
815 public:
816 DECLARE_NODE_TYPE(ForInStatement)
817
818 Expression* enumerable() const {
819 return subject();
820 }
821
822 // Type feedback information.
823 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
824 FeedbackVectorSlotCache* cache) override {
825 ForEachStatement::AssignFeedbackVectorSlots(isolate, spec, cache);
826 for_in_feedback_slot_ = spec->AddGeneralSlot();
827 }
828
829 FeedbackVectorSlot ForInFeedbackSlot() {
830 DCHECK(!for_in_feedback_slot_.IsInvalid());
831 return for_in_feedback_slot_;
832 }
833
834 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
835 ForInType for_in_type() const { return for_in_type_; }
836 void set_for_in_type(ForInType type) { for_in_type_ = type; }
837
838 static int num_ids() { return parent_num_ids() + 6; }
839 BailoutId BodyId() const { return BailoutId(local_id(0)); }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100840 BailoutId EnumId() const { return BailoutId(local_id(1)); }
841 BailoutId ToObjectId() const { return BailoutId(local_id(2)); }
842 BailoutId PrepareId() const { return BailoutId(local_id(3)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843 BailoutId FilterId() const { return BailoutId(local_id(4)); }
844 BailoutId AssignmentId() const { return BailoutId(local_id(5)); }
845 BailoutId ContinueId() const override { return EntryId(); }
846 BailoutId StackCheckId() const override { return BodyId(); }
847
848 protected:
849 ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
850 : ForEachStatement(zone, labels, pos), for_in_type_(SLOW_FOR_IN) {}
851 static int parent_num_ids() { return ForEachStatement::num_ids(); }
852
853 private:
854 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
855
856 ForInType for_in_type_;
857 FeedbackVectorSlot for_in_feedback_slot_;
858};
859
860
861class ForOfStatement final : public ForEachStatement {
862 public:
863 DECLARE_NODE_TYPE(ForOfStatement)
864
865 void Initialize(Expression* each,
866 Expression* subject,
867 Statement* body,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100868 Variable* iterator,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869 Expression* assign_iterator,
870 Expression* next_result,
871 Expression* result_done,
872 Expression* assign_each) {
873 ForEachStatement::Initialize(each, subject, body);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100874 iterator_ = iterator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000875 assign_iterator_ = assign_iterator;
876 next_result_ = next_result;
877 result_done_ = result_done;
878 assign_each_ = assign_each;
879 }
880
881 Expression* iterable() const {
882 return subject();
883 }
884
Ben Murdoch097c5b22016-05-18 11:27:45 +0100885 Variable* iterator() const {
886 return iterator_;
887 }
888
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000889 // iterator = subject[Symbol.iterator]()
890 Expression* assign_iterator() const {
891 return assign_iterator_;
892 }
893
894 // result = iterator.next() // with type check
895 Expression* next_result() const {
896 return next_result_;
897 }
898
899 // result.done
900 Expression* result_done() const {
901 return result_done_;
902 }
903
904 // each = result.value
905 Expression* assign_each() const {
906 return assign_each_;
907 }
908
909 void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
910 void set_next_result(Expression* e) { next_result_ = e; }
911 void set_result_done(Expression* e) { result_done_ = e; }
912 void set_assign_each(Expression* e) { assign_each_ = e; }
913
914 BailoutId ContinueId() const override { return EntryId(); }
915 BailoutId StackCheckId() const override { return BackEdgeId(); }
916
917 static int num_ids() { return parent_num_ids() + 1; }
918 BailoutId BackEdgeId() const { return BailoutId(local_id(0)); }
919
920 protected:
921 ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
922 : ForEachStatement(zone, labels, pos),
Ben Murdoch097c5b22016-05-18 11:27:45 +0100923 iterator_(NULL),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000924 assign_iterator_(NULL),
925 next_result_(NULL),
926 result_done_(NULL),
927 assign_each_(NULL) {}
928 static int parent_num_ids() { return ForEachStatement::num_ids(); }
929
930 private:
931 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
932
Ben Murdoch097c5b22016-05-18 11:27:45 +0100933 Variable* iterator_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000934 Expression* assign_iterator_;
935 Expression* next_result_;
936 Expression* result_done_;
937 Expression* assign_each_;
938};
939
940
941class ExpressionStatement final : public Statement {
942 public:
943 DECLARE_NODE_TYPE(ExpressionStatement)
944
945 void set_expression(Expression* e) { expression_ = e; }
946 Expression* expression() const { return expression_; }
947 bool IsJump() const override { return expression_->IsThrow(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000948
949 protected:
950 ExpressionStatement(Zone* zone, Expression* expression, int pos)
951 : Statement(zone, pos), expression_(expression) { }
952
953 private:
954 Expression* expression_;
955};
956
957
958class JumpStatement : public Statement {
959 public:
960 bool IsJump() const final { return true; }
961
962 protected:
963 explicit JumpStatement(Zone* zone, int pos) : Statement(zone, pos) {}
964};
965
966
967class ContinueStatement final : public JumpStatement {
968 public:
969 DECLARE_NODE_TYPE(ContinueStatement)
970
971 IterationStatement* target() const { return target_; }
972
973 protected:
974 explicit ContinueStatement(Zone* zone, IterationStatement* target, int pos)
975 : JumpStatement(zone, pos), target_(target) { }
976
977 private:
978 IterationStatement* target_;
979};
980
981
982class BreakStatement final : public JumpStatement {
983 public:
984 DECLARE_NODE_TYPE(BreakStatement)
985
986 BreakableStatement* target() const { return target_; }
987
988 protected:
989 explicit BreakStatement(Zone* zone, BreakableStatement* target, int pos)
990 : JumpStatement(zone, pos), target_(target) { }
991
992 private:
993 BreakableStatement* target_;
994};
995
996
997class ReturnStatement final : public JumpStatement {
998 public:
999 DECLARE_NODE_TYPE(ReturnStatement)
1000
1001 Expression* expression() const { return expression_; }
1002
1003 void set_expression(Expression* e) { expression_ = e; }
1004
1005 protected:
1006 explicit ReturnStatement(Zone* zone, Expression* expression, int pos)
1007 : JumpStatement(zone, pos), expression_(expression) { }
1008
1009 private:
1010 Expression* expression_;
1011};
1012
1013
1014class WithStatement final : public Statement {
1015 public:
1016 DECLARE_NODE_TYPE(WithStatement)
1017
1018 Scope* scope() { return scope_; }
1019 Expression* expression() const { return expression_; }
1020 void set_expression(Expression* e) { expression_ = e; }
1021 Statement* statement() const { return statement_; }
1022 void set_statement(Statement* s) { statement_ = s; }
1023
1024 void set_base_id(int id) { base_id_ = id; }
1025 static int num_ids() { return parent_num_ids() + 2; }
1026 BailoutId ToObjectId() const { return BailoutId(local_id(0)); }
1027 BailoutId EntryId() const { return BailoutId(local_id(1)); }
1028
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001029 protected:
1030 WithStatement(Zone* zone, Scope* scope, Expression* expression,
1031 Statement* statement, int pos)
1032 : Statement(zone, pos),
1033 scope_(scope),
1034 expression_(expression),
1035 statement_(statement),
1036 base_id_(BailoutId::None().ToInt()) {}
1037 static int parent_num_ids() { return 0; }
1038
1039 int base_id() const {
1040 DCHECK(!BailoutId(base_id_).IsNone());
1041 return base_id_;
1042 }
1043
1044 private:
1045 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1046
1047 Scope* scope_;
1048 Expression* expression_;
1049 Statement* statement_;
1050 int base_id_;
1051};
1052
1053
1054class CaseClause final : public Expression {
1055 public:
1056 DECLARE_NODE_TYPE(CaseClause)
1057
1058 bool is_default() const { return label_ == NULL; }
1059 Expression* label() const {
1060 CHECK(!is_default());
1061 return label_;
1062 }
1063 void set_label(Expression* e) { label_ = e; }
1064 Label* body_target() { return &body_target_; }
1065 ZoneList<Statement*>* statements() const { return statements_; }
1066
1067 static int num_ids() { return parent_num_ids() + 2; }
1068 BailoutId EntryId() const { return BailoutId(local_id(0)); }
1069 TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
1070
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001071 Type* compare_type() { return compare_type_; }
1072 void set_compare_type(Type* type) { compare_type_ = type; }
1073
1074 protected:
1075 static int parent_num_ids() { return Expression::num_ids(); }
1076
1077 private:
1078 CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
1079 int pos);
1080 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1081
1082 Expression* label_;
1083 Label body_target_;
1084 ZoneList<Statement*>* statements_;
1085 Type* compare_type_;
1086};
1087
1088
1089class SwitchStatement final : public BreakableStatement {
1090 public:
1091 DECLARE_NODE_TYPE(SwitchStatement)
1092
1093 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1094 tag_ = tag;
1095 cases_ = cases;
1096 }
1097
1098 Expression* tag() const { return tag_; }
1099 ZoneList<CaseClause*>* cases() const { return cases_; }
1100
1101 void set_tag(Expression* t) { tag_ = t; }
1102
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001103 protected:
1104 SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
1105 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
1106 tag_(NULL),
1107 cases_(NULL) {}
1108
1109 private:
1110 Expression* tag_;
1111 ZoneList<CaseClause*>* cases_;
1112};
1113
1114
1115// If-statements always have non-null references to their then- and
1116// else-parts. When parsing if-statements with no explicit else-part,
1117// the parser implicitly creates an empty statement. Use the
1118// HasThenStatement() and HasElseStatement() functions to check if a
1119// given if-statement has a then- or an else-part containing code.
1120class IfStatement final : public Statement {
1121 public:
1122 DECLARE_NODE_TYPE(IfStatement)
1123
1124 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1125 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1126
1127 Expression* condition() const { return condition_; }
1128 Statement* then_statement() const { return then_statement_; }
1129 Statement* else_statement() const { return else_statement_; }
1130
1131 void set_condition(Expression* e) { condition_ = e; }
1132 void set_then_statement(Statement* s) { then_statement_ = s; }
1133 void set_else_statement(Statement* s) { else_statement_ = s; }
1134
1135 bool IsJump() const override {
1136 return HasThenStatement() && then_statement()->IsJump()
1137 && HasElseStatement() && else_statement()->IsJump();
1138 }
1139
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001140 void set_base_id(int id) { base_id_ = id; }
1141 static int num_ids() { return parent_num_ids() + 3; }
1142 BailoutId IfId() const { return BailoutId(local_id(0)); }
1143 BailoutId ThenId() const { return BailoutId(local_id(1)); }
1144 BailoutId ElseId() const { return BailoutId(local_id(2)); }
1145
1146 protected:
1147 IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
1148 Statement* else_statement, int pos)
1149 : Statement(zone, pos),
1150 condition_(condition),
1151 then_statement_(then_statement),
1152 else_statement_(else_statement),
1153 base_id_(BailoutId::None().ToInt()) {}
1154 static int parent_num_ids() { return 0; }
1155
1156 int base_id() const {
1157 DCHECK(!BailoutId(base_id_).IsNone());
1158 return base_id_;
1159 }
1160
1161 private:
1162 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1163
1164 Expression* condition_;
1165 Statement* then_statement_;
1166 Statement* else_statement_;
1167 int base_id_;
1168};
1169
1170
1171class TryStatement : public Statement {
1172 public:
1173 Block* try_block() const { return try_block_; }
1174 void set_try_block(Block* b) { try_block_ = b; }
1175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001176 protected:
1177 TryStatement(Zone* zone, Block* try_block, int pos)
Ben Murdoch097c5b22016-05-18 11:27:45 +01001178 : Statement(zone, pos), try_block_(try_block) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001179
1180 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001181 Block* try_block_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001182};
1183
1184
1185class TryCatchStatement final : public TryStatement {
1186 public:
1187 DECLARE_NODE_TYPE(TryCatchStatement)
1188
1189 Scope* scope() { return scope_; }
1190 Variable* variable() { return variable_; }
1191 Block* catch_block() const { return catch_block_; }
1192 void set_catch_block(Block* b) { catch_block_ = b; }
1193
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001194 protected:
1195 TryCatchStatement(Zone* zone, Block* try_block, Scope* scope,
1196 Variable* variable, Block* catch_block, int pos)
1197 : TryStatement(zone, try_block, pos),
1198 scope_(scope),
1199 variable_(variable),
1200 catch_block_(catch_block) {}
1201
1202 private:
1203 Scope* scope_;
1204 Variable* variable_;
1205 Block* catch_block_;
1206};
1207
1208
1209class TryFinallyStatement final : public TryStatement {
1210 public:
1211 DECLARE_NODE_TYPE(TryFinallyStatement)
1212
1213 Block* finally_block() const { return finally_block_; }
1214 void set_finally_block(Block* b) { finally_block_ = b; }
1215
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001216 protected:
1217 TryFinallyStatement(Zone* zone, Block* try_block, Block* finally_block,
1218 int pos)
1219 : TryStatement(zone, try_block, pos), finally_block_(finally_block) {}
1220
1221 private:
1222 Block* finally_block_;
1223};
1224
1225
1226class DebuggerStatement final : public Statement {
1227 public:
1228 DECLARE_NODE_TYPE(DebuggerStatement)
1229
1230 void set_base_id(int id) { base_id_ = id; }
1231 static int num_ids() { return parent_num_ids() + 1; }
1232 BailoutId DebugBreakId() const { return BailoutId(local_id(0)); }
1233
1234 protected:
1235 explicit DebuggerStatement(Zone* zone, int pos)
1236 : Statement(zone, pos), base_id_(BailoutId::None().ToInt()) {}
1237 static int parent_num_ids() { return 0; }
1238
1239 int base_id() const {
1240 DCHECK(!BailoutId(base_id_).IsNone());
1241 return base_id_;
1242 }
1243
1244 private:
1245 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1246
1247 int base_id_;
1248};
1249
1250
1251class EmptyStatement final : public Statement {
1252 public:
1253 DECLARE_NODE_TYPE(EmptyStatement)
1254
1255 protected:
1256 explicit EmptyStatement(Zone* zone, int pos): Statement(zone, pos) {}
1257};
1258
1259
1260// Delegates to another statement, which may be overwritten.
1261// This was introduced to implement ES2015 Annex B3.3 for conditionally making
1262// sloppy-mode block-scoped functions have a var binding, which is changed
1263// from one statement to another during parsing.
1264class SloppyBlockFunctionStatement final : public Statement {
1265 public:
1266 DECLARE_NODE_TYPE(SloppyBlockFunctionStatement)
1267
1268 Statement* statement() const { return statement_; }
1269 void set_statement(Statement* statement) { statement_ = statement; }
1270 Scope* scope() const { return scope_; }
1271
1272 private:
1273 SloppyBlockFunctionStatement(Zone* zone, Statement* statement, Scope* scope)
1274 : Statement(zone, RelocInfo::kNoPosition),
1275 statement_(statement),
1276 scope_(scope) {}
1277
1278 Statement* statement_;
1279 Scope* const scope_;
1280};
1281
1282
1283class Literal final : public Expression {
1284 public:
1285 DECLARE_NODE_TYPE(Literal)
1286
1287 bool IsPropertyName() const override { return value_->IsPropertyName(); }
1288
1289 Handle<String> AsPropertyName() {
1290 DCHECK(IsPropertyName());
1291 return Handle<String>::cast(value());
1292 }
1293
1294 const AstRawString* AsRawPropertyName() {
1295 DCHECK(IsPropertyName());
1296 return value_->AsString();
1297 }
1298
1299 bool ToBooleanIsTrue() const override { return value()->BooleanValue(); }
1300 bool ToBooleanIsFalse() const override { return !value()->BooleanValue(); }
1301
1302 Handle<Object> value() const { return value_->value(); }
1303 const AstValue* raw_value() const { return value_; }
1304
1305 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1306 // only for string and number literals!
1307 uint32_t Hash();
1308 static bool Match(void* literal1, void* literal2);
1309
1310 static int num_ids() { return parent_num_ids() + 1; }
1311 TypeFeedbackId LiteralFeedbackId() const {
1312 return TypeFeedbackId(local_id(0));
1313 }
1314
1315 protected:
1316 Literal(Zone* zone, const AstValue* value, int position)
1317 : Expression(zone, position), value_(value) {}
1318 static int parent_num_ids() { return Expression::num_ids(); }
1319
1320 private:
1321 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1322
1323 const AstValue* value_;
1324};
1325
1326
1327class AstLiteralReindexer;
1328
1329// Base class for literals that needs space in the corresponding JSFunction.
1330class MaterializedLiteral : public Expression {
1331 public:
1332 MaterializedLiteral* AsMaterializedLiteral() final { return this; }
1333
1334 int literal_index() { return literal_index_; }
1335
1336 int depth() const {
1337 // only callable after initialization.
1338 DCHECK(depth_ >= 1);
1339 return depth_;
1340 }
1341
1342 bool is_strong() const { return is_strong_; }
1343
1344 protected:
1345 MaterializedLiteral(Zone* zone, int literal_index, bool is_strong, int pos)
1346 : Expression(zone, pos),
1347 literal_index_(literal_index),
1348 is_simple_(false),
1349 is_strong_(is_strong),
1350 depth_(0) {}
1351
1352 // A materialized literal is simple if the values consist of only
1353 // constants and simple object and array literals.
1354 bool is_simple() const { return is_simple_; }
1355 void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
1356 friend class CompileTimeValue;
1357
1358 void set_depth(int depth) {
1359 DCHECK(depth >= 1);
1360 depth_ = depth;
1361 }
1362
1363 // Populate the constant properties/elements fixed array.
1364 void BuildConstants(Isolate* isolate);
1365 friend class ArrayLiteral;
1366 friend class ObjectLiteral;
1367
1368 // If the expression is a literal, return the literal value;
1369 // if the expression is a materialized literal and is simple return a
1370 // compile time value as encoded by CompileTimeValue::GetValue().
1371 // Otherwise, return undefined literal as the placeholder
1372 // in the object literal boilerplate.
1373 Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
1374
1375 private:
1376 int literal_index_;
1377 bool is_simple_;
1378 bool is_strong_;
1379 int depth_;
1380
1381 friend class AstLiteralReindexer;
1382};
1383
1384
1385// Property is used for passing information
1386// about an object literal's properties from the parser
1387// to the code generator.
1388class ObjectLiteralProperty final : public ZoneObject {
1389 public:
1390 enum Kind {
1391 CONSTANT, // Property with constant value (compile time).
1392 COMPUTED, // Property with computed value (execution time).
1393 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1394 GETTER, SETTER, // Property is an accessor function.
1395 PROTOTYPE // Property is __proto__.
1396 };
1397
1398 Expression* key() { return key_; }
1399 Expression* value() { return value_; }
1400 Kind kind() { return kind_; }
1401
1402 void set_key(Expression* e) { key_ = e; }
1403 void set_value(Expression* e) { value_ = e; }
1404
1405 // Type feedback information.
1406 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1407 Handle<Map> GetReceiverType() { return receiver_type_; }
1408
1409 bool IsCompileTimeValue();
1410
1411 void set_emit_store(bool emit_store);
1412 bool emit_store();
1413
1414 bool is_static() const { return is_static_; }
1415 bool is_computed_name() const { return is_computed_name_; }
1416
1417 FeedbackVectorSlot GetSlot(int offset = 0) const {
1418 DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1419 return slots_[offset];
1420 }
1421 void SetSlot(FeedbackVectorSlot slot, int offset = 0) {
1422 DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1423 slots_[offset] = slot;
1424 }
1425
1426 void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
1427
Ben Murdoch097c5b22016-05-18 11:27:45 +01001428 bool NeedsSetFunctionName() const;
1429
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001430 protected:
1431 friend class AstNodeFactory;
1432
1433 ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
1434 bool is_static, bool is_computed_name);
1435 ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
1436 Expression* value, bool is_static,
1437 bool is_computed_name);
1438
1439 private:
1440 Expression* key_;
1441 Expression* value_;
1442 FeedbackVectorSlot slots_[2];
1443 Kind kind_;
1444 bool emit_store_;
1445 bool is_static_;
1446 bool is_computed_name_;
1447 Handle<Map> receiver_type_;
1448};
1449
1450
1451// An object literal has a boilerplate object that is used
1452// for minimizing the work when constructing it at runtime.
1453class ObjectLiteral final : public MaterializedLiteral {
1454 public:
1455 typedef ObjectLiteralProperty Property;
1456
1457 DECLARE_NODE_TYPE(ObjectLiteral)
1458
1459 Handle<FixedArray> constant_properties() const {
1460 return constant_properties_;
1461 }
1462 int properties_count() const { return constant_properties_->length() / 2; }
1463 ZoneList<Property*>* properties() const { return properties_; }
1464 bool fast_elements() const { return fast_elements_; }
1465 bool may_store_doubles() const { return may_store_doubles_; }
1466 bool has_function() const { return has_function_; }
1467 bool has_elements() const { return has_elements_; }
Ben Murdoch097c5b22016-05-18 11:27:45 +01001468 bool has_shallow_properties() const {
1469 return depth() == 1 && !has_elements() && !may_store_doubles();
1470 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001471
1472 // Decide if a property should be in the object boilerplate.
1473 static bool IsBoilerplateProperty(Property* property);
1474
1475 // Populate the constant properties fixed array.
1476 void BuildConstantProperties(Isolate* isolate);
1477
1478 // Mark all computed expressions that are bound to a key that
1479 // is shadowed by a later occurrence of the same key. For the
1480 // marked expressions, no store code is emitted.
1481 void CalculateEmitStore(Zone* zone);
1482
1483 // Assemble bitfield of flags for the CreateObjectLiteral helper.
1484 int ComputeFlags(bool disable_mementos = false) const {
1485 int flags = fast_elements() ? kFastElements : kNoFlags;
1486 flags |= has_function() ? kHasFunction : kNoFlags;
Ben Murdoch097c5b22016-05-18 11:27:45 +01001487 if (has_shallow_properties()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001488 flags |= kShallowProperties;
1489 }
1490 if (disable_mementos) {
1491 flags |= kDisableMementos;
1492 }
1493 if (is_strong()) {
1494 flags |= kIsStrong;
1495 }
1496 return flags;
1497 }
1498
1499 enum Flags {
1500 kNoFlags = 0,
1501 kFastElements = 1,
1502 kHasFunction = 1 << 1,
1503 kShallowProperties = 1 << 2,
1504 kDisableMementos = 1 << 3,
1505 kIsStrong = 1 << 4
1506 };
1507
1508 struct Accessors: public ZoneObject {
1509 Accessors() : getter(NULL), setter(NULL) {}
1510 ObjectLiteralProperty* getter;
1511 ObjectLiteralProperty* setter;
1512 };
1513
1514 BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1515
1516 // Return an AST id for a property that is used in simulate instructions.
1517 BailoutId GetIdForPropertyName(int i) {
1518 return BailoutId(local_id(2 * i + 1));
1519 }
1520 BailoutId GetIdForPropertySet(int i) {
1521 return BailoutId(local_id(2 * i + 2));
1522 }
1523
1524 // Unlike other AST nodes, this number of bailout IDs allocated for an
1525 // ObjectLiteral can vary, so num_ids() is not a static method.
1526 int num_ids() const {
1527 return parent_num_ids() + 1 + 2 * properties()->length();
1528 }
1529
1530 // Object literals need one feedback slot for each non-trivial value, as well
1531 // as some slots for home objects.
1532 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1533 FeedbackVectorSlotCache* cache) override;
1534
1535 protected:
1536 ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
1537 int boilerplate_properties, bool has_function, bool is_strong,
1538 int pos)
1539 : MaterializedLiteral(zone, literal_index, is_strong, pos),
1540 properties_(properties),
1541 boilerplate_properties_(boilerplate_properties),
1542 fast_elements_(false),
1543 has_elements_(false),
1544 may_store_doubles_(false),
1545 has_function_(has_function) {}
1546 static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1547
1548 private:
1549 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1550 Handle<FixedArray> constant_properties_;
1551 ZoneList<Property*>* properties_;
1552 int boilerplate_properties_;
1553 bool fast_elements_;
1554 bool has_elements_;
1555 bool may_store_doubles_;
1556 bool has_function_;
1557 FeedbackVectorSlot slot_;
1558};
1559
1560
1561// A map from property names to getter/setter pairs allocated in the zone.
1562class AccessorTable : public TemplateHashMap<Literal, ObjectLiteral::Accessors,
1563 ZoneAllocationPolicy> {
1564 public:
1565 explicit AccessorTable(Zone* zone)
1566 : TemplateHashMap<Literal, ObjectLiteral::Accessors,
1567 ZoneAllocationPolicy>(Literal::Match,
1568 ZoneAllocationPolicy(zone)),
1569 zone_(zone) {}
1570
1571 Iterator lookup(Literal* literal) {
1572 Iterator it = find(literal, true, ZoneAllocationPolicy(zone_));
1573 if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors();
1574 return it;
1575 }
1576
1577 private:
1578 Zone* zone_;
1579};
1580
1581
1582// Node for capturing a regexp literal.
1583class RegExpLiteral final : public MaterializedLiteral {
1584 public:
1585 DECLARE_NODE_TYPE(RegExpLiteral)
1586
1587 Handle<String> pattern() const { return pattern_->string(); }
1588 int flags() const { return flags_; }
1589
1590 protected:
1591 RegExpLiteral(Zone* zone, const AstRawString* pattern, int flags,
1592 int literal_index, bool is_strong, int pos)
1593 : MaterializedLiteral(zone, literal_index, is_strong, pos),
1594 pattern_(pattern),
1595 flags_(flags) {
1596 set_depth(1);
1597 }
1598
1599 private:
1600 const AstRawString* const pattern_;
1601 int const flags_;
1602};
1603
1604
1605// An array literal has a literals object that is used
1606// for minimizing the work when constructing it at runtime.
1607class ArrayLiteral final : public MaterializedLiteral {
1608 public:
1609 DECLARE_NODE_TYPE(ArrayLiteral)
1610
1611 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1612 ElementsKind constant_elements_kind() const {
1613 DCHECK_EQ(2, constant_elements_->length());
1614 return static_cast<ElementsKind>(
1615 Smi::cast(constant_elements_->get(0))->value());
1616 }
1617
1618 ZoneList<Expression*>* values() const { return values_; }
1619
1620 BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1621
1622 // Return an AST id for an element that is used in simulate instructions.
1623 BailoutId GetIdForElement(int i) { return BailoutId(local_id(i + 1)); }
1624
1625 // Unlike other AST nodes, this number of bailout IDs allocated for an
1626 // ArrayLiteral can vary, so num_ids() is not a static method.
1627 int num_ids() const { return parent_num_ids() + 1 + values()->length(); }
1628
1629 // Populate the constant elements fixed array.
1630 void BuildConstantElements(Isolate* isolate);
1631
1632 // Assemble bitfield of flags for the CreateArrayLiteral helper.
1633 int ComputeFlags(bool disable_mementos = false) const {
1634 int flags = depth() == 1 ? kShallowElements : kNoFlags;
1635 if (disable_mementos) {
1636 flags |= kDisableMementos;
1637 }
1638 if (is_strong()) {
1639 flags |= kIsStrong;
1640 }
1641 return flags;
1642 }
1643
Ben Murdoch097c5b22016-05-18 11:27:45 +01001644 // Provide a mechanism for iterating through values to rewrite spreads.
1645 ZoneList<Expression*>::iterator FirstSpread() const {
1646 return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_
1647 : values_->end();
1648 }
1649 ZoneList<Expression*>::iterator EndValue() const { return values_->end(); }
1650
1651 // Rewind an array literal omitting everything from the first spread on.
1652 void RewindSpreads() {
1653 values_->Rewind(first_spread_index_);
1654 first_spread_index_ = -1;
1655 }
1656
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001657 enum Flags {
1658 kNoFlags = 0,
1659 kShallowElements = 1,
1660 kDisableMementos = 1 << 1,
1661 kIsStrong = 1 << 2
1662 };
1663
1664 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1665 FeedbackVectorSlotCache* cache) override;
1666 FeedbackVectorSlot LiteralFeedbackSlot() const { return literal_slot_; }
1667
1668 protected:
1669 ArrayLiteral(Zone* zone, ZoneList<Expression*>* values,
1670 int first_spread_index, int literal_index, bool is_strong,
1671 int pos)
1672 : MaterializedLiteral(zone, literal_index, is_strong, pos),
1673 values_(values),
1674 first_spread_index_(first_spread_index) {}
1675 static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1676
1677 private:
1678 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1679
1680 Handle<FixedArray> constant_elements_;
1681 ZoneList<Expression*>* values_;
1682 int first_spread_index_;
1683 FeedbackVectorSlot literal_slot_;
1684};
1685
1686
1687class VariableProxy final : public Expression {
1688 public:
1689 DECLARE_NODE_TYPE(VariableProxy)
1690
1691 bool IsValidReferenceExpression() const override {
1692 return !is_this() && !is_new_target();
1693 }
1694
1695 bool IsArguments() const { return is_resolved() && var()->is_arguments(); }
1696
1697 Handle<String> name() const { return raw_name()->string(); }
1698 const AstRawString* raw_name() const {
1699 return is_resolved() ? var_->raw_name() : raw_name_;
1700 }
1701
1702 Variable* var() const {
1703 DCHECK(is_resolved());
1704 return var_;
1705 }
1706 void set_var(Variable* v) {
1707 DCHECK(!is_resolved());
1708 DCHECK_NOT_NULL(v);
1709 var_ = v;
1710 }
1711
1712 bool is_this() const { return IsThisField::decode(bit_field_); }
1713
1714 bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
1715 void set_is_assigned() {
1716 bit_field_ = IsAssignedField::update(bit_field_, true);
1717 }
1718
1719 bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
1720 void set_is_resolved() {
1721 bit_field_ = IsResolvedField::update(bit_field_, true);
1722 }
1723
1724 bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
1725 void set_is_new_target() {
1726 bit_field_ = IsNewTargetField::update(bit_field_, true);
1727 }
1728
1729 int end_position() const { return end_position_; }
1730
1731 // Bind this proxy to the variable var.
1732 void BindTo(Variable* var);
1733
1734 bool UsesVariableFeedbackSlot() const {
1735 return var()->IsUnallocated() || var()->IsLookupSlot();
1736 }
1737
1738 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1739 FeedbackVectorSlotCache* cache) override;
1740
1741 FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
1742
1743 static int num_ids() { return parent_num_ids() + 1; }
1744 BailoutId BeforeId() const { return BailoutId(local_id(0)); }
1745
1746 protected:
1747 VariableProxy(Zone* zone, Variable* var, int start_position,
1748 int end_position);
1749
1750 VariableProxy(Zone* zone, const AstRawString* name,
1751 Variable::Kind variable_kind, int start_position,
1752 int end_position);
1753 static int parent_num_ids() { return Expression::num_ids(); }
1754 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1755
1756 class IsThisField : public BitField8<bool, 0, 1> {};
1757 class IsAssignedField : public BitField8<bool, 1, 1> {};
1758 class IsResolvedField : public BitField8<bool, 2, 1> {};
1759 class IsNewTargetField : public BitField8<bool, 3, 1> {};
1760
1761 // Start with 16-bit (or smaller) field, which should get packed together
1762 // with Expression's trailing 16-bit field.
1763 uint8_t bit_field_;
1764 FeedbackVectorSlot variable_feedback_slot_;
1765 union {
1766 const AstRawString* raw_name_; // if !is_resolved_
1767 Variable* var_; // if is_resolved_
1768 };
1769 // Position is stored in the AstNode superclass, but VariableProxy needs to
1770 // know its end position too (for error messages). It cannot be inferred from
1771 // the variable name length because it can contain escapes.
1772 int end_position_;
1773};
1774
1775
1776// Left-hand side can only be a property, a global or a (parameter or local)
1777// slot.
1778enum LhsKind {
1779 VARIABLE,
1780 NAMED_PROPERTY,
1781 KEYED_PROPERTY,
1782 NAMED_SUPER_PROPERTY,
1783 KEYED_SUPER_PROPERTY
1784};
1785
1786
1787class Property final : public Expression {
1788 public:
1789 DECLARE_NODE_TYPE(Property)
1790
1791 bool IsValidReferenceExpression() const override { return true; }
1792
1793 Expression* obj() const { return obj_; }
1794 Expression* key() const { return key_; }
1795
1796 void set_obj(Expression* e) { obj_ = e; }
1797 void set_key(Expression* e) { key_ = e; }
1798
1799 static int num_ids() { return parent_num_ids() + 1; }
1800 BailoutId LoadId() const { return BailoutId(local_id(0)); }
1801
1802 bool IsStringAccess() const {
1803 return IsStringAccessField::decode(bit_field_);
1804 }
1805
1806 // Type feedback information.
1807 bool IsMonomorphic() override { return receiver_types_.length() == 1; }
1808 SmallMapList* GetReceiverTypes() override { return &receiver_types_; }
1809 KeyedAccessStoreMode GetStoreMode() const override { return STANDARD_STORE; }
1810 IcCheckType GetKeyType() const override {
1811 return KeyTypeField::decode(bit_field_);
1812 }
1813 bool IsUninitialized() const {
1814 return !is_for_call() && HasNoTypeInformation();
1815 }
1816 bool HasNoTypeInformation() const {
1817 return GetInlineCacheState() == UNINITIALIZED;
1818 }
1819 InlineCacheState GetInlineCacheState() const {
1820 return InlineCacheStateField::decode(bit_field_);
1821 }
1822 void set_is_string_access(bool b) {
1823 bit_field_ = IsStringAccessField::update(bit_field_, b);
1824 }
1825 void set_key_type(IcCheckType key_type) {
1826 bit_field_ = KeyTypeField::update(bit_field_, key_type);
1827 }
1828 void set_inline_cache_state(InlineCacheState state) {
1829 bit_field_ = InlineCacheStateField::update(bit_field_, state);
1830 }
1831 void mark_for_call() {
1832 bit_field_ = IsForCallField::update(bit_field_, true);
1833 }
1834 bool is_for_call() const { return IsForCallField::decode(bit_field_); }
1835
1836 bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
1837
1838 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1839 FeedbackVectorSlotCache* cache) override {
1840 FeedbackVectorSlotKind kind = key()->IsPropertyName()
1841 ? FeedbackVectorSlotKind::LOAD_IC
1842 : FeedbackVectorSlotKind::KEYED_LOAD_IC;
1843 property_feedback_slot_ = spec->AddSlot(kind);
1844 }
1845
1846 FeedbackVectorSlot PropertyFeedbackSlot() const {
1847 return property_feedback_slot_;
1848 }
1849
1850 static LhsKind GetAssignType(Property* property) {
1851 if (property == NULL) return VARIABLE;
1852 bool super_access = property->IsSuperAccess();
1853 return (property->key()->IsPropertyName())
1854 ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
1855 : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
1856 }
1857
1858 protected:
1859 Property(Zone* zone, Expression* obj, Expression* key, int pos)
1860 : Expression(zone, pos),
1861 bit_field_(IsForCallField::encode(false) |
1862 IsStringAccessField::encode(false) |
1863 InlineCacheStateField::encode(UNINITIALIZED)),
1864 obj_(obj),
1865 key_(key) {}
1866 static int parent_num_ids() { return Expression::num_ids(); }
1867
1868 private:
1869 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1870
1871 class IsForCallField : public BitField8<bool, 0, 1> {};
1872 class IsStringAccessField : public BitField8<bool, 1, 1> {};
1873 class KeyTypeField : public BitField8<IcCheckType, 2, 1> {};
1874 class InlineCacheStateField : public BitField8<InlineCacheState, 3, 4> {};
1875 uint8_t bit_field_;
1876 FeedbackVectorSlot property_feedback_slot_;
1877 Expression* obj_;
1878 Expression* key_;
1879 SmallMapList receiver_types_;
1880};
1881
1882
1883class Call final : public Expression {
1884 public:
1885 DECLARE_NODE_TYPE(Call)
1886
1887 Expression* expression() const { return expression_; }
1888 ZoneList<Expression*>* arguments() const { return arguments_; }
1889
1890 void set_expression(Expression* e) { expression_ = e; }
1891
1892 // Type feedback information.
1893 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1894 FeedbackVectorSlotCache* cache) override;
1895
1896 FeedbackVectorSlot CallFeedbackSlot() const { return stub_slot_; }
1897
1898 FeedbackVectorSlot CallFeedbackICSlot() const { return ic_slot_; }
1899
1900 SmallMapList* GetReceiverTypes() override {
1901 if (expression()->IsProperty()) {
1902 return expression()->AsProperty()->GetReceiverTypes();
1903 }
1904 return NULL;
1905 }
1906
1907 bool IsMonomorphic() override {
1908 if (expression()->IsProperty()) {
1909 return expression()->AsProperty()->IsMonomorphic();
1910 }
1911 return !target_.is_null();
1912 }
1913
1914 bool global_call() const {
1915 VariableProxy* proxy = expression_->AsVariableProxy();
1916 return proxy != NULL && proxy->var()->IsUnallocatedOrGlobalSlot();
1917 }
1918
1919 bool known_global_function() const {
1920 return global_call() && !target_.is_null();
1921 }
1922
1923 Handle<JSFunction> target() { return target_; }
1924
1925 Handle<AllocationSite> allocation_site() { return allocation_site_; }
1926
1927 void SetKnownGlobalTarget(Handle<JSFunction> target) {
1928 target_ = target;
1929 set_is_uninitialized(false);
1930 }
1931 void set_target(Handle<JSFunction> target) { target_ = target; }
1932 void set_allocation_site(Handle<AllocationSite> site) {
1933 allocation_site_ = site;
1934 }
1935
1936 static int num_ids() { return parent_num_ids() + 4; }
1937 BailoutId ReturnId() const { return BailoutId(local_id(0)); }
1938 BailoutId EvalId() const { return BailoutId(local_id(1)); }
1939 BailoutId LookupId() const { return BailoutId(local_id(2)); }
1940 BailoutId CallId() const { return BailoutId(local_id(3)); }
1941
1942 bool is_uninitialized() const {
1943 return IsUninitializedField::decode(bit_field_);
1944 }
1945 void set_is_uninitialized(bool b) {
1946 bit_field_ = IsUninitializedField::update(bit_field_, b);
1947 }
1948
Ben Murdoch097c5b22016-05-18 11:27:45 +01001949 TailCallMode tail_call_mode() const {
1950 return IsTailField::decode(bit_field_) ? TailCallMode::kAllow
1951 : TailCallMode::kDisallow;
1952 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001953 void MarkTail() override {
1954 bit_field_ = IsTailField::update(bit_field_, true);
1955 }
1956
1957 enum CallType {
1958 POSSIBLY_EVAL_CALL,
1959 GLOBAL_CALL,
1960 LOOKUP_SLOT_CALL,
1961 NAMED_PROPERTY_CALL,
1962 KEYED_PROPERTY_CALL,
1963 NAMED_SUPER_PROPERTY_CALL,
1964 KEYED_SUPER_PROPERTY_CALL,
1965 SUPER_CALL,
1966 OTHER_CALL
1967 };
1968
1969 // Helpers to determine how to handle the call.
1970 CallType GetCallType(Isolate* isolate) const;
1971 bool IsUsingCallFeedbackSlot(Isolate* isolate) const;
1972 bool IsUsingCallFeedbackICSlot(Isolate* isolate) const;
1973
1974#ifdef DEBUG
1975 // Used to assert that the FullCodeGenerator records the return site.
1976 bool return_is_recorded_;
1977#endif
1978
1979 protected:
1980 Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
1981 int pos)
1982 : Expression(zone, pos),
1983 expression_(expression),
1984 arguments_(arguments),
1985 bit_field_(IsUninitializedField::encode(false)) {
1986 if (expression->IsProperty()) {
1987 expression->AsProperty()->mark_for_call();
1988 }
1989 }
1990 static int parent_num_ids() { return Expression::num_ids(); }
1991
1992 private:
1993 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1994
1995 FeedbackVectorSlot ic_slot_;
1996 FeedbackVectorSlot stub_slot_;
1997 Expression* expression_;
1998 ZoneList<Expression*>* arguments_;
1999 Handle<JSFunction> target_;
2000 Handle<AllocationSite> allocation_site_;
2001 class IsUninitializedField : public BitField8<bool, 0, 1> {};
2002 class IsTailField : public BitField8<bool, 1, 1> {};
2003 uint8_t bit_field_;
2004};
2005
2006
2007class CallNew final : public Expression {
2008 public:
2009 DECLARE_NODE_TYPE(CallNew)
2010
2011 Expression* expression() const { return expression_; }
2012 ZoneList<Expression*>* arguments() const { return arguments_; }
2013
2014 void set_expression(Expression* e) { expression_ = e; }
2015
2016 // Type feedback information.
2017 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2018 FeedbackVectorSlotCache* cache) override {
2019 callnew_feedback_slot_ = spec->AddGeneralSlot();
2020 }
2021
2022 FeedbackVectorSlot CallNewFeedbackSlot() {
2023 DCHECK(!callnew_feedback_slot_.IsInvalid());
2024 return callnew_feedback_slot_;
2025 }
2026
2027 bool IsMonomorphic() override { return is_monomorphic_; }
2028 Handle<JSFunction> target() const { return target_; }
2029 Handle<AllocationSite> allocation_site() const {
2030 return allocation_site_;
2031 }
2032
2033 static int num_ids() { return parent_num_ids() + 1; }
2034 static int feedback_slots() { return 1; }
2035 BailoutId ReturnId() const { return BailoutId(local_id(0)); }
2036
2037 void set_allocation_site(Handle<AllocationSite> site) {
2038 allocation_site_ = site;
2039 }
2040 void set_is_monomorphic(bool monomorphic) { is_monomorphic_ = monomorphic; }
2041 void set_target(Handle<JSFunction> target) { target_ = target; }
2042 void SetKnownGlobalTarget(Handle<JSFunction> target) {
2043 target_ = target;
2044 is_monomorphic_ = true;
2045 }
2046
2047 protected:
2048 CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
2049 int pos)
2050 : Expression(zone, pos),
2051 expression_(expression),
2052 arguments_(arguments),
2053 is_monomorphic_(false) {}
2054
2055 static int parent_num_ids() { return Expression::num_ids(); }
2056
2057 private:
2058 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2059
2060 Expression* expression_;
2061 ZoneList<Expression*>* arguments_;
2062 bool is_monomorphic_;
2063 Handle<JSFunction> target_;
2064 Handle<AllocationSite> allocation_site_;
2065 FeedbackVectorSlot callnew_feedback_slot_;
2066};
2067
2068
2069// The CallRuntime class does not represent any official JavaScript
2070// language construct. Instead it is used to call a C or JS function
2071// with a set of arguments. This is used from the builtins that are
2072// implemented in JavaScript (see "v8natives.js").
2073class CallRuntime final : public Expression {
2074 public:
2075 DECLARE_NODE_TYPE(CallRuntime)
2076
2077 ZoneList<Expression*>* arguments() const { return arguments_; }
2078 bool is_jsruntime() const { return function_ == NULL; }
2079
2080 int context_index() const {
2081 DCHECK(is_jsruntime());
2082 return context_index_;
2083 }
2084 const Runtime::Function* function() const {
2085 DCHECK(!is_jsruntime());
2086 return function_;
2087 }
2088
2089 static int num_ids() { return parent_num_ids() + 1; }
2090 BailoutId CallId() { return BailoutId(local_id(0)); }
2091
2092 const char* debug_name() {
2093 return is_jsruntime() ? "(context function)" : function_->name;
2094 }
2095
2096 protected:
2097 CallRuntime(Zone* zone, const Runtime::Function* function,
2098 ZoneList<Expression*>* arguments, int pos)
2099 : Expression(zone, pos), function_(function), arguments_(arguments) {}
2100
2101 CallRuntime(Zone* zone, int context_index, ZoneList<Expression*>* arguments,
2102 int pos)
2103 : Expression(zone, pos),
2104 function_(NULL),
2105 context_index_(context_index),
2106 arguments_(arguments) {}
2107
2108 static int parent_num_ids() { return Expression::num_ids(); }
2109
2110 private:
2111 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2112
2113 const Runtime::Function* function_;
2114 int context_index_;
2115 ZoneList<Expression*>* arguments_;
2116};
2117
2118
2119class UnaryOperation final : public Expression {
2120 public:
2121 DECLARE_NODE_TYPE(UnaryOperation)
2122
2123 Token::Value op() const { return op_; }
2124 Expression* expression() const { return expression_; }
2125 void set_expression(Expression* e) { expression_ = e; }
2126
2127 // For unary not (Token::NOT), the AST ids where true and false will
2128 // actually be materialized, respectively.
2129 static int num_ids() { return parent_num_ids() + 2; }
2130 BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
2131 BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
2132
2133 void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override;
2134
2135 protected:
2136 UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos)
2137 : Expression(zone, pos), op_(op), expression_(expression) {
2138 DCHECK(Token::IsUnaryOp(op));
2139 }
2140 static int parent_num_ids() { return Expression::num_ids(); }
2141
2142 private:
2143 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2144
2145 Token::Value op_;
2146 Expression* expression_;
2147};
2148
2149
2150class BinaryOperation final : public Expression {
2151 public:
2152 DECLARE_NODE_TYPE(BinaryOperation)
2153
2154 Token::Value op() const { return static_cast<Token::Value>(op_); }
2155 Expression* left() const { return left_; }
2156 void set_left(Expression* e) { left_ = e; }
2157 Expression* right() const { return right_; }
2158 void set_right(Expression* e) { right_ = e; }
2159 Handle<AllocationSite> allocation_site() const { return allocation_site_; }
2160 void set_allocation_site(Handle<AllocationSite> allocation_site) {
2161 allocation_site_ = allocation_site;
2162 }
2163
2164 void MarkTail() override {
2165 switch (op()) {
2166 case Token::COMMA:
2167 case Token::AND:
2168 case Token::OR:
2169 right_->MarkTail();
2170 default:
2171 break;
2172 }
2173 }
2174
2175 // The short-circuit logical operations need an AST ID for their
2176 // right-hand subexpression.
2177 static int num_ids() { return parent_num_ids() + 2; }
2178 BailoutId RightId() const { return BailoutId(local_id(0)); }
2179
2180 TypeFeedbackId BinaryOperationFeedbackId() const {
2181 return TypeFeedbackId(local_id(1));
2182 }
2183 Maybe<int> fixed_right_arg() const {
2184 return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
2185 }
2186 void set_fixed_right_arg(Maybe<int> arg) {
2187 has_fixed_right_arg_ = arg.IsJust();
2188 if (arg.IsJust()) fixed_right_arg_value_ = arg.FromJust();
2189 }
2190
2191 void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) override;
2192
2193 protected:
2194 BinaryOperation(Zone* zone, Token::Value op, Expression* left,
2195 Expression* right, int pos)
2196 : Expression(zone, pos),
2197 op_(static_cast<byte>(op)),
2198 has_fixed_right_arg_(false),
2199 fixed_right_arg_value_(0),
2200 left_(left),
2201 right_(right) {
2202 DCHECK(Token::IsBinaryOp(op));
2203 }
2204 static int parent_num_ids() { return Expression::num_ids(); }
2205
2206 private:
2207 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2208
2209 const byte op_; // actually Token::Value
2210 // TODO(rossberg): the fixed arg should probably be represented as a Constant
2211 // type for the RHS. Currenty it's actually a Maybe<int>
2212 bool has_fixed_right_arg_;
2213 int fixed_right_arg_value_;
2214 Expression* left_;
2215 Expression* right_;
2216 Handle<AllocationSite> allocation_site_;
2217};
2218
2219
2220class CountOperation final : public Expression {
2221 public:
2222 DECLARE_NODE_TYPE(CountOperation)
2223
2224 bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
2225 bool is_postfix() const { return !is_prefix(); }
2226
2227 Token::Value op() const { return TokenField::decode(bit_field_); }
2228 Token::Value binary_op() {
2229 return (op() == Token::INC) ? Token::ADD : Token::SUB;
2230 }
2231
2232 Expression* expression() const { return expression_; }
2233 void set_expression(Expression* e) { expression_ = e; }
2234
2235 bool IsMonomorphic() override { return receiver_types_.length() == 1; }
2236 SmallMapList* GetReceiverTypes() override { return &receiver_types_; }
2237 IcCheckType GetKeyType() const override {
2238 return KeyTypeField::decode(bit_field_);
2239 }
2240 KeyedAccessStoreMode GetStoreMode() const override {
2241 return StoreModeField::decode(bit_field_);
2242 }
2243 Type* type() const { return type_; }
2244 void set_key_type(IcCheckType type) {
2245 bit_field_ = KeyTypeField::update(bit_field_, type);
2246 }
2247 void set_store_mode(KeyedAccessStoreMode mode) {
2248 bit_field_ = StoreModeField::update(bit_field_, mode);
2249 }
2250 void set_type(Type* type) { type_ = type; }
2251
2252 static int num_ids() { return parent_num_ids() + 4; }
2253 BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2254 BailoutId ToNumberId() const { return BailoutId(local_id(1)); }
2255 TypeFeedbackId CountBinOpFeedbackId() const {
2256 return TypeFeedbackId(local_id(2));
2257 }
2258 TypeFeedbackId CountStoreFeedbackId() const {
2259 return TypeFeedbackId(local_id(3));
2260 }
2261
2262 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2263 FeedbackVectorSlotCache* cache) override;
2264 FeedbackVectorSlot CountSlot() const { return slot_; }
2265
2266 protected:
2267 CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
2268 int pos)
2269 : Expression(zone, pos),
2270 bit_field_(
2271 IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) |
2272 StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op)),
2273 type_(NULL),
2274 expression_(expr) {}
2275 static int parent_num_ids() { return Expression::num_ids(); }
2276
2277 private:
2278 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2279
2280 class IsPrefixField : public BitField16<bool, 0, 1> {};
2281 class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
2282 class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 3> {};
2283 class TokenField : public BitField16<Token::Value, 5, 8> {};
2284
2285 // Starts with 16-bit field, which should get packed together with
2286 // Expression's trailing 16-bit field.
2287 uint16_t bit_field_;
2288 Type* type_;
2289 Expression* expression_;
2290 SmallMapList receiver_types_;
2291 FeedbackVectorSlot slot_;
2292};
2293
2294
2295class CompareOperation final : public Expression {
2296 public:
2297 DECLARE_NODE_TYPE(CompareOperation)
2298
2299 Token::Value op() const { return op_; }
2300 Expression* left() const { return left_; }
2301 Expression* right() const { return right_; }
2302
2303 void set_left(Expression* e) { left_ = e; }
2304 void set_right(Expression* e) { right_ = e; }
2305
2306 // Type feedback information.
2307 static int num_ids() { return parent_num_ids() + 1; }
2308 TypeFeedbackId CompareOperationFeedbackId() const {
2309 return TypeFeedbackId(local_id(0));
2310 }
2311 Type* combined_type() const { return combined_type_; }
2312 void set_combined_type(Type* type) { combined_type_ = type; }
2313
2314 // Match special cases.
2315 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
2316 bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
2317 bool IsLiteralCompareNull(Expression** expr);
2318
2319 protected:
2320 CompareOperation(Zone* zone, Token::Value op, Expression* left,
2321 Expression* right, int pos)
2322 : Expression(zone, pos),
2323 op_(op),
2324 left_(left),
2325 right_(right),
Ben Murdoch097c5b22016-05-18 11:27:45 +01002326 combined_type_(Type::None()) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002327 DCHECK(Token::IsCompareOp(op));
2328 }
2329 static int parent_num_ids() { return Expression::num_ids(); }
2330
2331 private:
2332 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2333
2334 Token::Value op_;
2335 Expression* left_;
2336 Expression* right_;
2337
2338 Type* combined_type_;
2339};
2340
2341
2342class Spread final : public Expression {
2343 public:
2344 DECLARE_NODE_TYPE(Spread)
2345
2346 Expression* expression() const { return expression_; }
2347 void set_expression(Expression* e) { expression_ = e; }
2348
Ben Murdoch097c5b22016-05-18 11:27:45 +01002349 int expression_position() const { return expr_pos_; }
2350
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002351 static int num_ids() { return parent_num_ids(); }
2352
2353 protected:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002354 Spread(Zone* zone, Expression* expression, int pos, int expr_pos)
2355 : Expression(zone, pos), expression_(expression), expr_pos_(expr_pos) {}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002356 static int parent_num_ids() { return Expression::num_ids(); }
2357
2358 private:
2359 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2360
2361 Expression* expression_;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002362 int expr_pos_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002363};
2364
2365
2366class Conditional final : public Expression {
2367 public:
2368 DECLARE_NODE_TYPE(Conditional)
2369
2370 Expression* condition() const { return condition_; }
2371 Expression* then_expression() const { return then_expression_; }
2372 Expression* else_expression() const { return else_expression_; }
2373
2374 void set_condition(Expression* e) { condition_ = e; }
2375 void set_then_expression(Expression* e) { then_expression_ = e; }
2376 void set_else_expression(Expression* e) { else_expression_ = e; }
2377
2378 void MarkTail() override {
2379 then_expression_->MarkTail();
2380 else_expression_->MarkTail();
2381 }
2382
2383 static int num_ids() { return parent_num_ids() + 2; }
2384 BailoutId ThenId() const { return BailoutId(local_id(0)); }
2385 BailoutId ElseId() const { return BailoutId(local_id(1)); }
2386
2387 protected:
2388 Conditional(Zone* zone, Expression* condition, Expression* then_expression,
2389 Expression* else_expression, int position)
2390 : Expression(zone, position),
2391 condition_(condition),
2392 then_expression_(then_expression),
2393 else_expression_(else_expression) {}
2394 static int parent_num_ids() { return Expression::num_ids(); }
2395
2396 private:
2397 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2398
2399 Expression* condition_;
2400 Expression* then_expression_;
2401 Expression* else_expression_;
2402};
2403
2404
2405class Assignment final : public Expression {
2406 public:
2407 DECLARE_NODE_TYPE(Assignment)
2408
2409 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
2410
2411 Token::Value binary_op() const;
2412
2413 Token::Value op() const { return TokenField::decode(bit_field_); }
2414 Expression* target() const { return target_; }
2415 Expression* value() const { return value_; }
2416
2417 void set_target(Expression* e) { target_ = e; }
2418 void set_value(Expression* e) { value_ = e; }
2419
2420 BinaryOperation* binary_operation() const { return binary_operation_; }
2421
2422 // This check relies on the definition order of token in token.h.
2423 bool is_compound() const { return op() > Token::ASSIGN; }
2424
2425 static int num_ids() { return parent_num_ids() + 2; }
2426 BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2427
2428 // Type feedback information.
2429 TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
2430 bool IsMonomorphic() override { return receiver_types_.length() == 1; }
2431 bool IsUninitialized() const {
2432 return IsUninitializedField::decode(bit_field_);
2433 }
2434 bool HasNoTypeInformation() {
2435 return IsUninitializedField::decode(bit_field_);
2436 }
2437 SmallMapList* GetReceiverTypes() override { return &receiver_types_; }
2438 IcCheckType GetKeyType() const override {
2439 return KeyTypeField::decode(bit_field_);
2440 }
2441 KeyedAccessStoreMode GetStoreMode() const override {
2442 return StoreModeField::decode(bit_field_);
2443 }
2444 void set_is_uninitialized(bool b) {
2445 bit_field_ = IsUninitializedField::update(bit_field_, b);
2446 }
2447 void set_key_type(IcCheckType key_type) {
2448 bit_field_ = KeyTypeField::update(bit_field_, key_type);
2449 }
2450 void set_store_mode(KeyedAccessStoreMode mode) {
2451 bit_field_ = StoreModeField::update(bit_field_, mode);
2452 }
2453
2454 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2455 FeedbackVectorSlotCache* cache) override;
2456 FeedbackVectorSlot AssignmentSlot() const { return slot_; }
2457
2458 protected:
2459 Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
2460 int pos);
2461 static int parent_num_ids() { return Expression::num_ids(); }
2462
2463 private:
2464 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2465
2466 class IsUninitializedField : public BitField16<bool, 0, 1> {};
2467 class KeyTypeField
2468 : public BitField16<IcCheckType, IsUninitializedField::kNext, 1> {};
2469 class StoreModeField
2470 : public BitField16<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
2471 class TokenField : public BitField16<Token::Value, StoreModeField::kNext, 8> {
2472 };
2473
2474 // Starts with 16-bit field, which should get packed together with
2475 // Expression's trailing 16-bit field.
2476 uint16_t bit_field_;
2477 Expression* target_;
2478 Expression* value_;
2479 BinaryOperation* binary_operation_;
2480 SmallMapList receiver_types_;
2481 FeedbackVectorSlot slot_;
2482};
2483
2484
Ben Murdoch097c5b22016-05-18 11:27:45 +01002485// The RewritableExpression class is a wrapper for AST nodes that wait
2486// for some potential rewriting. However, even if such nodes are indeed
2487// rewritten, the RewritableExpression wrapper nodes will survive in the
2488// final AST and should be just ignored, i.e., they should be treated as
2489// equivalent to the wrapped nodes. For this reason and to simplify later
2490// phases, RewritableExpressions are considered as exceptions of AST nodes
2491// in the following sense:
2492//
2493// 1. IsRewritableExpression and AsRewritableExpression behave as usual.
2494// 2. All other Is* and As* methods are practically delegated to the
2495// wrapped node, i.e. IsArrayLiteral() will return true iff the
2496// wrapped node is an array literal.
2497//
2498// Furthermore, an invariant that should be respected is that the wrapped
2499// node is not a RewritableExpression.
2500class RewritableExpression : public Expression {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002501 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002502 DECLARE_NODE_TYPE(RewritableExpression)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002503
Ben Murdoch097c5b22016-05-18 11:27:45 +01002504 Expression* expression() const { return expr_; }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002505 bool is_rewritten() const { return is_rewritten_; }
2506
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002507 void Rewrite(Expression* new_expression) {
2508 DCHECK(!is_rewritten());
2509 DCHECK_NOT_NULL(new_expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01002510 DCHECK(!new_expression->IsRewritableExpression());
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002511 expr_ = new_expression;
2512 is_rewritten_ = true;
2513 }
2514
2515 static int num_ids() { return parent_num_ids(); }
2516
2517 protected:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002518 RewritableExpression(Zone* zone, Expression* expression)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002519 : Expression(zone, expression->position()),
2520 is_rewritten_(false),
Ben Murdoch097c5b22016-05-18 11:27:45 +01002521 expr_(expression) {
2522 DCHECK(!expression->IsRewritableExpression());
2523 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002524
2525 private:
2526 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2527
2528 bool is_rewritten_;
2529 Expression* expr_;
2530};
2531
2532
2533class Yield final : public Expression {
2534 public:
2535 DECLARE_NODE_TYPE(Yield)
2536
2537 enum Kind {
2538 kInitial, // The initial yield that returns the unboxed generator object.
2539 kSuspend, // A normal yield: { value: EXPRESSION, done: false }
2540 kDelegating, // A yield*.
2541 kFinal // A return: { value: EXPRESSION, done: true }
2542 };
2543
2544 Expression* generator_object() const { return generator_object_; }
2545 Expression* expression() const { return expression_; }
2546 Kind yield_kind() const { return yield_kind_; }
2547
2548 void set_generator_object(Expression* e) { generator_object_ = e; }
2549 void set_expression(Expression* e) { expression_ = e; }
2550
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002551 protected:
2552 Yield(Zone* zone, Expression* generator_object, Expression* expression,
2553 Kind yield_kind, int pos)
2554 : Expression(zone, pos),
2555 generator_object_(generator_object),
2556 expression_(expression),
2557 yield_kind_(yield_kind) {}
2558
2559 private:
2560 Expression* generator_object_;
2561 Expression* expression_;
2562 Kind yield_kind_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002563};
2564
2565
2566class Throw final : public Expression {
2567 public:
2568 DECLARE_NODE_TYPE(Throw)
2569
2570 Expression* exception() const { return exception_; }
2571 void set_exception(Expression* e) { exception_ = e; }
2572
2573 protected:
2574 Throw(Zone* zone, Expression* exception, int pos)
2575 : Expression(zone, pos), exception_(exception) {}
2576
2577 private:
2578 Expression* exception_;
2579};
2580
2581
2582class FunctionLiteral final : public Expression {
2583 public:
2584 enum FunctionType {
2585 kAnonymousExpression,
2586 kNamedExpression,
2587 kDeclaration,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002588 kAccessorOrMethod
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002589 };
2590
2591 enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters };
2592
2593 enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
2594
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002595 DECLARE_NODE_TYPE(FunctionLiteral)
2596
2597 Handle<String> name() const { return raw_name_->string(); }
2598 const AstString* raw_name() const { return raw_name_; }
2599 void set_raw_name(const AstString* name) { raw_name_ = name; }
2600 Scope* scope() const { return scope_; }
2601 ZoneList<Statement*>* body() const { return body_; }
2602 void set_function_token_position(int pos) { function_token_position_ = pos; }
2603 int function_token_position() const { return function_token_position_; }
2604 int start_position() const;
2605 int end_position() const;
2606 int SourceSize() const { return end_position() - start_position(); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002607 bool is_declaration() const { return IsDeclaration::decode(bitfield_); }
2608 bool is_named_expression() const {
2609 return IsNamedExpression::decode(bitfield_);
2610 }
2611 bool is_anonymous_expression() const {
2612 return IsAnonymousExpression::decode(bitfield_);
2613 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002614 LanguageMode language_mode() const;
2615
2616 static bool NeedsHomeObject(Expression* expr);
2617
2618 int materialized_literal_count() { return materialized_literal_count_; }
2619 int expected_property_count() { return expected_property_count_; }
2620 int parameter_count() { return parameter_count_; }
2621
2622 bool AllowsLazyCompilation();
2623 bool AllowsLazyCompilationWithoutContext();
2624
2625 Handle<String> debug_name() const {
2626 if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
2627 return raw_name_->string();
2628 }
2629 return inferred_name();
2630 }
2631
2632 Handle<String> inferred_name() const {
2633 if (!inferred_name_.is_null()) {
2634 DCHECK(raw_inferred_name_ == NULL);
2635 return inferred_name_;
2636 }
2637 if (raw_inferred_name_ != NULL) {
2638 return raw_inferred_name_->string();
2639 }
2640 UNREACHABLE();
2641 return Handle<String>();
2642 }
2643
2644 // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2645 void set_inferred_name(Handle<String> inferred_name) {
2646 DCHECK(!inferred_name.is_null());
2647 inferred_name_ = inferred_name;
2648 DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
2649 raw_inferred_name_ = NULL;
2650 }
2651
2652 void set_raw_inferred_name(const AstString* raw_inferred_name) {
2653 DCHECK(raw_inferred_name != NULL);
2654 raw_inferred_name_ = raw_inferred_name;
2655 DCHECK(inferred_name_.is_null());
2656 inferred_name_ = Handle<String>();
2657 }
2658
2659 bool pretenure() const { return Pretenure::decode(bitfield_); }
2660 void set_pretenure() { bitfield_ = Pretenure::update(bitfield_, true); }
2661
2662 bool has_duplicate_parameters() const {
2663 return HasDuplicateParameters::decode(bitfield_);
2664 }
2665
2666 bool is_function() const { return IsFunction::decode(bitfield_); }
2667
2668 // This is used as a heuristic on when to eagerly compile a function
2669 // literal. We consider the following constructs as hints that the
2670 // function will be called immediately:
2671 // - (function() { ... })();
2672 // - var x = function() { ... }();
2673 bool should_eager_compile() const {
2674 return ShouldEagerCompile::decode(bitfield_);
2675 }
2676 void set_should_eager_compile() {
2677 bitfield_ = ShouldEagerCompile::update(bitfield_, true);
2678 }
2679
2680 // A hint that we expect this function to be called (exactly) once,
2681 // i.e. we suspect it's an initialization function.
2682 bool should_be_used_once_hint() const {
2683 return ShouldBeUsedOnceHint::decode(bitfield_);
2684 }
2685 void set_should_be_used_once_hint() {
2686 bitfield_ = ShouldBeUsedOnceHint::update(bitfield_, true);
2687 }
2688
2689 FunctionKind kind() const { return FunctionKindBits::decode(bitfield_); }
2690
2691 int ast_node_count() { return ast_properties_.node_count(); }
2692 AstProperties::Flags flags() const { return ast_properties_.flags(); }
2693 void set_ast_properties(AstProperties* ast_properties) {
2694 ast_properties_ = *ast_properties;
2695 }
2696 const FeedbackVectorSpec* feedback_vector_spec() const {
2697 return ast_properties_.get_spec();
2698 }
2699 bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
2700 BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
2701 void set_dont_optimize_reason(BailoutReason reason) {
2702 dont_optimize_reason_ = reason;
2703 }
2704
Ben Murdoch097c5b22016-05-18 11:27:45 +01002705 bool IsAnonymousFunctionDefinition() const final {
2706 return is_anonymous_expression();
2707 }
2708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002709 protected:
2710 FunctionLiteral(Zone* zone, const AstString* name,
2711 AstValueFactory* ast_value_factory, Scope* scope,
2712 ZoneList<Statement*>* body, int materialized_literal_count,
2713 int expected_property_count, int parameter_count,
2714 FunctionType function_type,
2715 ParameterFlag has_duplicate_parameters,
2716 EagerCompileHint eager_compile_hint, FunctionKind kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +01002717 int position, bool is_function)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002718 : Expression(zone, position),
2719 raw_name_(name),
2720 scope_(scope),
2721 body_(body),
2722 raw_inferred_name_(ast_value_factory->empty_string()),
2723 ast_properties_(zone),
2724 dont_optimize_reason_(kNoReason),
2725 materialized_literal_count_(materialized_literal_count),
2726 expected_property_count_(expected_property_count),
2727 parameter_count_(parameter_count),
2728 function_token_position_(RelocInfo::kNoPosition) {
2729 bitfield_ =
Ben Murdoch097c5b22016-05-18 11:27:45 +01002730 IsDeclaration::encode(function_type == kDeclaration) |
2731 IsNamedExpression::encode(function_type == kNamedExpression) |
2732 IsAnonymousExpression::encode(function_type == kAnonymousExpression) |
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002733 Pretenure::encode(false) |
2734 HasDuplicateParameters::encode(has_duplicate_parameters ==
2735 kHasDuplicateParameters) |
Ben Murdoch097c5b22016-05-18 11:27:45 +01002736 IsFunction::encode(is_function) |
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002737 ShouldEagerCompile::encode(eager_compile_hint == kShouldEagerCompile) |
2738 FunctionKindBits::encode(kind) | ShouldBeUsedOnceHint::encode(false);
2739 DCHECK(IsValidFunctionKind(kind));
2740 }
2741
2742 private:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002743 class IsDeclaration : public BitField16<bool, 0, 1> {};
2744 class IsNamedExpression : public BitField16<bool, 1, 1> {};
2745 class IsAnonymousExpression : public BitField16<bool, 2, 1> {};
2746 class Pretenure : public BitField16<bool, 3, 1> {};
2747 class HasDuplicateParameters : public BitField16<bool, 4, 1> {};
2748 class IsFunction : public BitField16<bool, 5, 1> {};
2749 class ShouldEagerCompile : public BitField16<bool, 6, 1> {};
2750 class ShouldBeUsedOnceHint : public BitField16<bool, 7, 1> {};
2751 class FunctionKindBits : public BitField16<FunctionKind, 8, 8> {};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002752
2753 // Start with 16-bit field, which should get packed together
2754 // with Expression's trailing 16-bit field.
2755 uint16_t bitfield_;
2756
2757 const AstString* raw_name_;
2758 Scope* scope_;
2759 ZoneList<Statement*>* body_;
2760 const AstString* raw_inferred_name_;
2761 Handle<String> inferred_name_;
2762 AstProperties ast_properties_;
2763 BailoutReason dont_optimize_reason_;
2764
2765 int materialized_literal_count_;
2766 int expected_property_count_;
2767 int parameter_count_;
2768 int function_token_position_;
2769};
2770
2771
2772class ClassLiteral final : public Expression {
2773 public:
2774 typedef ObjectLiteralProperty Property;
2775
2776 DECLARE_NODE_TYPE(ClassLiteral)
2777
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002778 Scope* scope() const { return scope_; }
2779 VariableProxy* class_variable_proxy() const { return class_variable_proxy_; }
2780 Expression* extends() const { return extends_; }
2781 void set_extends(Expression* e) { extends_ = e; }
2782 FunctionLiteral* constructor() const { return constructor_; }
2783 void set_constructor(FunctionLiteral* f) { constructor_ = f; }
2784 ZoneList<Property*>* properties() const { return properties_; }
2785 int start_position() const { return position(); }
2786 int end_position() const { return end_position_; }
2787
2788 BailoutId EntryId() const { return BailoutId(local_id(0)); }
2789 BailoutId DeclsId() const { return BailoutId(local_id(1)); }
2790 BailoutId ExitId() { return BailoutId(local_id(2)); }
2791 BailoutId CreateLiteralId() const { return BailoutId(local_id(3)); }
Ben Murdoch097c5b22016-05-18 11:27:45 +01002792 BailoutId PrototypeId() { return BailoutId(local_id(4)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002793
2794 // Return an AST id for a property that is used in simulate instructions.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002795 BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 5)); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002796
2797 // Unlike other AST nodes, this number of bailout IDs allocated for an
2798 // ClassLiteral can vary, so num_ids() is not a static method.
Ben Murdoch097c5b22016-05-18 11:27:45 +01002799 int num_ids() const { return parent_num_ids() + 5 + properties()->length(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002800
2801 // Object literals need one feedback slot for each non-trivial value, as well
2802 // as some slots for home objects.
2803 void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2804 FeedbackVectorSlotCache* cache) override;
2805
2806 bool NeedsProxySlot() const {
2807 return class_variable_proxy() != nullptr &&
2808 class_variable_proxy()->var()->IsUnallocated();
2809 }
2810
Ben Murdoch097c5b22016-05-18 11:27:45 +01002811 FeedbackVectorSlot PrototypeSlot() const { return prototype_slot_; }
2812 FeedbackVectorSlot ProxySlot() const { return proxy_slot_; }
2813
2814 bool IsAnonymousFunctionDefinition() const final {
2815 return constructor()->raw_name()->length() == 0;
2816 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002817
2818 protected:
Ben Murdoch097c5b22016-05-18 11:27:45 +01002819 ClassLiteral(Zone* zone, Scope* scope, VariableProxy* class_variable_proxy,
2820 Expression* extends, FunctionLiteral* constructor,
2821 ZoneList<Property*>* properties, int start_position,
2822 int end_position)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002823 : Expression(zone, start_position),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002824 scope_(scope),
2825 class_variable_proxy_(class_variable_proxy),
2826 extends_(extends),
2827 constructor_(constructor),
2828 properties_(properties),
2829 end_position_(end_position) {}
2830
2831 static int parent_num_ids() { return Expression::num_ids(); }
2832
2833 private:
2834 int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2835
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002836 Scope* scope_;
2837 VariableProxy* class_variable_proxy_;
2838 Expression* extends_;
2839 FunctionLiteral* constructor_;
2840 ZoneList<Property*>* properties_;
2841 int end_position_;
Ben Murdoch097c5b22016-05-18 11:27:45 +01002842 FeedbackVectorSlot prototype_slot_;
2843 FeedbackVectorSlot proxy_slot_;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00002844};
2845
2846
2847class NativeFunctionLiteral final : public Expression {
2848 public:
2849 DECLARE_NODE_TYPE(NativeFunctionLiteral)
2850
2851 Handle<String> name() const { return name_->string(); }
2852 v8::Extension* extension() const { return extension_; }
2853
2854 protected:
2855 NativeFunctionLiteral(Zone* zone, const AstRawString* name,
2856 v8::Extension* extension, int pos)
2857 : Expression(zone, pos), name_(name), extension_(extension) {}
2858
2859 private:
2860 const AstRawString* name_;
2861 v8::Extension* extension_;
2862};
2863
2864
2865class ThisFunction final : public Expression {
2866 public:
2867 DECLARE_NODE_TYPE(ThisFunction)
2868
2869 protected:
2870 ThisFunction(Zone* zone, int pos) : Expression(zone, pos) {}
2871};
2872
2873
2874class SuperPropertyReference final : public Expression {
2875 public:
2876 DECLARE_NODE_TYPE(SuperPropertyReference)
2877
2878 VariableProxy* this_var() const { return this_var_; }
2879 void set_this_var(VariableProxy* v) { this_var_ = v; }
2880 Expression* home_object() const { return home_object_; }
2881 void set_home_object(Expression* e) { home_object_ = e; }
2882
2883 protected:
2884 SuperPropertyReference(Zone* zone, VariableProxy* this_var,
2885 Expression* home_object, int pos)
2886 : Expression(zone, pos), this_var_(this_var), home_object_(home_object) {
2887 DCHECK(this_var->is_this());
2888 DCHECK(home_object->IsProperty());
2889 }
2890
2891 private:
2892 VariableProxy* this_var_;
2893 Expression* home_object_;
2894};
2895
2896
2897class SuperCallReference final : public Expression {
2898 public:
2899 DECLARE_NODE_TYPE(SuperCallReference)
2900
2901 VariableProxy* this_var() const { return this_var_; }
2902 void set_this_var(VariableProxy* v) { this_var_ = v; }
2903 VariableProxy* new_target_var() const { return new_target_var_; }
2904 void set_new_target_var(VariableProxy* v) { new_target_var_ = v; }
2905 VariableProxy* this_function_var() const { return this_function_var_; }
2906 void set_this_function_var(VariableProxy* v) { this_function_var_ = v; }
2907
2908 protected:
2909 SuperCallReference(Zone* zone, VariableProxy* this_var,
2910 VariableProxy* new_target_var,
2911 VariableProxy* this_function_var, int pos)
2912 : Expression(zone, pos),
2913 this_var_(this_var),
2914 new_target_var_(new_target_var),
2915 this_function_var_(this_function_var) {
2916 DCHECK(this_var->is_this());
2917 DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2918 DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
2919 }
2920
2921 private:
2922 VariableProxy* this_var_;
2923 VariableProxy* new_target_var_;
2924 VariableProxy* this_function_var_;
2925};
2926
2927
2928// This class is produced when parsing the () in arrow functions without any
2929// arguments and is not actually a valid expression.
2930class EmptyParentheses final : public Expression {
2931 public:
2932 DECLARE_NODE_TYPE(EmptyParentheses)
2933
2934 private:
2935 EmptyParentheses(Zone* zone, int pos) : Expression(zone, pos) {}
2936};
2937
2938
2939#undef DECLARE_NODE_TYPE
2940
2941
2942// ----------------------------------------------------------------------------
2943// Basic visitor
2944// - leaf node visitors are abstract.
2945
2946class AstVisitor BASE_EMBEDDED {
2947 public:
2948 AstVisitor() {}
2949 virtual ~AstVisitor() {}
2950
2951 // Stack overflow check and dynamic dispatch.
2952 virtual void Visit(AstNode* node) = 0;
2953
2954 // Iteration left-to-right.
2955 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
2956 virtual void VisitStatements(ZoneList<Statement*>* statements);
2957 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2958
2959 // Individual AST nodes.
2960#define DEF_VISIT(type) \
2961 virtual void Visit##type(type* node) = 0;
2962 AST_NODE_LIST(DEF_VISIT)
2963#undef DEF_VISIT
2964};
2965
2966#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \
2967 public: \
2968 void Visit(AstNode* node) final { \
2969 if (!CheckStackOverflow()) node->Accept(this); \
2970 } \
2971 \
2972 void SetStackOverflow() { stack_overflow_ = true; } \
2973 void ClearStackOverflow() { stack_overflow_ = false; } \
2974 bool HasStackOverflow() const { return stack_overflow_; } \
2975 \
2976 bool CheckStackOverflow() { \
2977 if (stack_overflow_) return true; \
2978 if (GetCurrentStackPosition() < stack_limit_) { \
2979 stack_overflow_ = true; \
2980 return true; \
2981 } \
2982 return false; \
2983 } \
2984 \
2985 private: \
2986 void InitializeAstVisitor(Isolate* isolate) { \
2987 stack_limit_ = isolate->stack_guard()->real_climit(); \
2988 stack_overflow_ = false; \
2989 } \
2990 \
2991 void InitializeAstVisitor(uintptr_t stack_limit) { \
2992 stack_limit_ = stack_limit; \
2993 stack_overflow_ = false; \
2994 } \
2995 \
2996 uintptr_t stack_limit_; \
2997 bool stack_overflow_
2998
2999#define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS() \
3000 public: \
3001 AstNode* Rewrite(AstNode* node) { \
3002 DCHECK_NULL(replacement_); \
3003 DCHECK_NOT_NULL(node); \
3004 Visit(node); \
3005 if (HasStackOverflow()) return node; \
3006 if (replacement_ == nullptr) return node; \
3007 AstNode* result = replacement_; \
3008 replacement_ = nullptr; \
3009 return result; \
3010 } \
3011 \
3012 private: \
3013 void InitializeAstRewriter(Isolate* isolate) { \
3014 InitializeAstVisitor(isolate); \
3015 replacement_ = nullptr; \
3016 } \
3017 \
3018 void InitializeAstRewriter(uintptr_t stack_limit) { \
3019 InitializeAstVisitor(stack_limit); \
3020 replacement_ = nullptr; \
3021 } \
3022 \
3023 DEFINE_AST_VISITOR_SUBCLASS_MEMBERS(); \
3024 \
3025 protected: \
3026 AstNode* replacement_
3027
3028// Generic macro for rewriting things; `GET` is the expression to be
3029// rewritten; `SET` is a command that should do the rewriting, i.e.
3030// something sensible with the variable called `replacement`.
3031#define AST_REWRITE(Type, GET, SET) \
3032 do { \
3033 DCHECK(!HasStackOverflow()); \
3034 DCHECK_NULL(replacement_); \
3035 Visit(GET); \
3036 if (HasStackOverflow()) return; \
3037 if (replacement_ == nullptr) break; \
3038 Type* replacement = reinterpret_cast<Type*>(replacement_); \
3039 do { \
3040 SET; \
3041 } while (false); \
3042 replacement_ = nullptr; \
3043 } while (false)
3044
3045// Macro for rewriting object properties; it assumes that `object` has
3046// `property` with a public getter and setter.
3047#define AST_REWRITE_PROPERTY(Type, object, property) \
3048 do { \
3049 auto _obj = (object); \
3050 AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \
3051 } while (false)
3052
3053// Macro for rewriting list elements; it assumes that `list` has methods
3054// `at` and `Set`.
3055#define AST_REWRITE_LIST_ELEMENT(Type, list, index) \
3056 do { \
3057 auto _list = (list); \
3058 auto _index = (index); \
3059 AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \
3060 } while (false)
3061
3062
3063// ----------------------------------------------------------------------------
3064// AstNode factory
3065
3066class AstNodeFactory final BASE_EMBEDDED {
3067 public:
3068 explicit AstNodeFactory(AstValueFactory* ast_value_factory)
3069 : local_zone_(ast_value_factory->zone()),
3070 parser_zone_(ast_value_factory->zone()),
3071 ast_value_factory_(ast_value_factory) {}
3072
3073 AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
3074
Ben Murdoch097c5b22016-05-18 11:27:45 +01003075 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
3076 VariableMode mode, Scope* scope,
3077 int pos) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003078 return new (parser_zone_)
Ben Murdoch097c5b22016-05-18 11:27:45 +01003079 VariableDeclaration(parser_zone_, proxy, mode, scope, pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003080 }
3081
3082 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
3083 VariableMode mode,
3084 FunctionLiteral* fun,
3085 Scope* scope,
3086 int pos) {
3087 return new (parser_zone_)
3088 FunctionDeclaration(parser_zone_, proxy, mode, fun, scope, pos);
3089 }
3090
3091 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
3092 const AstRawString* import_name,
3093 const AstRawString* module_specifier,
3094 Scope* scope, int pos) {
3095 return new (parser_zone_) ImportDeclaration(
3096 parser_zone_, proxy, import_name, module_specifier, scope, pos);
3097 }
3098
3099 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
3100 Scope* scope,
3101 int pos) {
3102 return new (parser_zone_)
3103 ExportDeclaration(parser_zone_, proxy, scope, pos);
3104 }
3105
3106 Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity,
3107 bool ignore_completion_value, int pos) {
3108 return new (local_zone_)
3109 Block(local_zone_, labels, capacity, ignore_completion_value, pos);
3110 }
3111
3112#define STATEMENT_WITH_LABELS(NodeType) \
3113 NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
3114 return new (local_zone_) NodeType(local_zone_, labels, pos); \
3115 }
3116 STATEMENT_WITH_LABELS(DoWhileStatement)
3117 STATEMENT_WITH_LABELS(WhileStatement)
3118 STATEMENT_WITH_LABELS(ForStatement)
3119 STATEMENT_WITH_LABELS(SwitchStatement)
3120#undef STATEMENT_WITH_LABELS
3121
3122 ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3123 ZoneList<const AstRawString*>* labels,
3124 int pos) {
3125 switch (visit_mode) {
3126 case ForEachStatement::ENUMERATE: {
3127 return new (local_zone_) ForInStatement(local_zone_, labels, pos);
3128 }
3129 case ForEachStatement::ITERATE: {
3130 return new (local_zone_) ForOfStatement(local_zone_, labels, pos);
3131 }
3132 }
3133 UNREACHABLE();
3134 return NULL;
3135 }
3136
3137 ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3138 return new (local_zone_) ExpressionStatement(local_zone_, expression, pos);
3139 }
3140
3141 ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3142 return new (local_zone_) ContinueStatement(local_zone_, target, pos);
3143 }
3144
3145 BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3146 return new (local_zone_) BreakStatement(local_zone_, target, pos);
3147 }
3148
3149 ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3150 return new (local_zone_) ReturnStatement(local_zone_, expression, pos);
3151 }
3152
3153 WithStatement* NewWithStatement(Scope* scope,
3154 Expression* expression,
3155 Statement* statement,
3156 int pos) {
3157 return new (local_zone_)
3158 WithStatement(local_zone_, scope, expression, statement, pos);
3159 }
3160
3161 IfStatement* NewIfStatement(Expression* condition,
3162 Statement* then_statement,
3163 Statement* else_statement,
3164 int pos) {
3165 return new (local_zone_) IfStatement(local_zone_, condition, then_statement,
3166 else_statement, pos);
3167 }
3168
3169 TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
3170 Variable* variable,
3171 Block* catch_block, int pos) {
3172 return new (local_zone_) TryCatchStatement(local_zone_, try_block, scope,
3173 variable, catch_block, pos);
3174 }
3175
3176 TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
3177 Block* finally_block, int pos) {
3178 return new (local_zone_)
3179 TryFinallyStatement(local_zone_, try_block, finally_block, pos);
3180 }
3181
3182 DebuggerStatement* NewDebuggerStatement(int pos) {
3183 return new (local_zone_) DebuggerStatement(local_zone_, pos);
3184 }
3185
3186 EmptyStatement* NewEmptyStatement(int pos) {
3187 return new (local_zone_) EmptyStatement(local_zone_, pos);
3188 }
3189
3190 SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(
3191 Statement* statement, Scope* scope) {
3192 return new (parser_zone_)
3193 SloppyBlockFunctionStatement(parser_zone_, statement, scope);
3194 }
3195
3196 CaseClause* NewCaseClause(
3197 Expression* label, ZoneList<Statement*>* statements, int pos) {
3198 return new (local_zone_) CaseClause(local_zone_, label, statements, pos);
3199 }
3200
3201 Literal* NewStringLiteral(const AstRawString* string, int pos) {
3202 return new (local_zone_)
3203 Literal(local_zone_, ast_value_factory_->NewString(string), pos);
3204 }
3205
3206 // A JavaScript symbol (ECMA-262 edition 6).
3207 Literal* NewSymbolLiteral(const char* name, int pos) {
3208 return new (local_zone_)
3209 Literal(local_zone_, ast_value_factory_->NewSymbol(name), pos);
3210 }
3211
3212 Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) {
3213 return new (local_zone_) Literal(
3214 local_zone_, ast_value_factory_->NewNumber(number, with_dot), pos);
3215 }
3216
3217 Literal* NewSmiLiteral(int number, int pos) {
3218 return new (local_zone_)
3219 Literal(local_zone_, ast_value_factory_->NewSmi(number), pos);
3220 }
3221
3222 Literal* NewBooleanLiteral(bool b, int pos) {
3223 return new (local_zone_)
3224 Literal(local_zone_, ast_value_factory_->NewBoolean(b), pos);
3225 }
3226
3227 Literal* NewNullLiteral(int pos) {
3228 return new (local_zone_)
3229 Literal(local_zone_, ast_value_factory_->NewNull(), pos);
3230 }
3231
3232 Literal* NewUndefinedLiteral(int pos) {
3233 return new (local_zone_)
3234 Literal(local_zone_, ast_value_factory_->NewUndefined(), pos);
3235 }
3236
3237 Literal* NewTheHoleLiteral(int pos) {
3238 return new (local_zone_)
3239 Literal(local_zone_, ast_value_factory_->NewTheHole(), pos);
3240 }
3241
3242 ObjectLiteral* NewObjectLiteral(
3243 ZoneList<ObjectLiteral::Property*>* properties,
3244 int literal_index,
3245 int boilerplate_properties,
3246 bool has_function,
3247 bool is_strong,
3248 int pos) {
3249 return new (local_zone_)
3250 ObjectLiteral(local_zone_, properties, literal_index,
3251 boilerplate_properties, has_function, is_strong, pos);
3252 }
3253
3254 ObjectLiteral::Property* NewObjectLiteralProperty(
3255 Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
3256 bool is_static, bool is_computed_name) {
3257 return new (local_zone_)
3258 ObjectLiteral::Property(key, value, kind, is_static, is_computed_name);
3259 }
3260
3261 ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
3262 Expression* value,
3263 bool is_static,
3264 bool is_computed_name) {
3265 return new (local_zone_) ObjectLiteral::Property(
3266 ast_value_factory_, key, value, is_static, is_computed_name);
3267 }
3268
3269 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
3270 int literal_index, bool is_strong, int pos) {
3271 return new (local_zone_) RegExpLiteral(local_zone_, pattern, flags,
3272 literal_index, is_strong, pos);
3273 }
3274
3275 ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3276 int literal_index,
3277 bool is_strong,
3278 int pos) {
3279 return new (local_zone_)
3280 ArrayLiteral(local_zone_, values, -1, literal_index, is_strong, pos);
3281 }
3282
3283 ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3284 int first_spread_index, int literal_index,
3285 bool is_strong, int pos) {
3286 return new (local_zone_) ArrayLiteral(
3287 local_zone_, values, first_spread_index, literal_index, is_strong, pos);
3288 }
3289
3290 VariableProxy* NewVariableProxy(Variable* var,
3291 int start_position = RelocInfo::kNoPosition,
3292 int end_position = RelocInfo::kNoPosition) {
3293 return new (parser_zone_)
3294 VariableProxy(parser_zone_, var, start_position, end_position);
3295 }
3296
3297 VariableProxy* NewVariableProxy(const AstRawString* name,
3298 Variable::Kind variable_kind,
3299 int start_position = RelocInfo::kNoPosition,
3300 int end_position = RelocInfo::kNoPosition) {
3301 DCHECK_NOT_NULL(name);
3302 return new (parser_zone_) VariableProxy(parser_zone_, name, variable_kind,
3303 start_position, end_position);
3304 }
3305
3306 Property* NewProperty(Expression* obj, Expression* key, int pos) {
3307 return new (local_zone_) Property(local_zone_, obj, key, pos);
3308 }
3309
3310 Call* NewCall(Expression* expression,
3311 ZoneList<Expression*>* arguments,
3312 int pos) {
3313 return new (local_zone_) Call(local_zone_, expression, arguments, pos);
3314 }
3315
3316 CallNew* NewCallNew(Expression* expression,
3317 ZoneList<Expression*>* arguments,
3318 int pos) {
3319 return new (local_zone_) CallNew(local_zone_, expression, arguments, pos);
3320 }
3321
3322 CallRuntime* NewCallRuntime(Runtime::FunctionId id,
3323 ZoneList<Expression*>* arguments, int pos) {
3324 return new (local_zone_)
3325 CallRuntime(local_zone_, Runtime::FunctionForId(id), arguments, pos);
3326 }
3327
3328 CallRuntime* NewCallRuntime(const Runtime::Function* function,
3329 ZoneList<Expression*>* arguments, int pos) {
3330 return new (local_zone_) CallRuntime(local_zone_, function, arguments, pos);
3331 }
3332
3333 CallRuntime* NewCallRuntime(int context_index,
3334 ZoneList<Expression*>* arguments, int pos) {
3335 return new (local_zone_)
3336 CallRuntime(local_zone_, context_index, arguments, pos);
3337 }
3338
3339 UnaryOperation* NewUnaryOperation(Token::Value op,
3340 Expression* expression,
3341 int pos) {
3342 return new (local_zone_) UnaryOperation(local_zone_, op, expression, pos);
3343 }
3344
3345 BinaryOperation* NewBinaryOperation(Token::Value op,
3346 Expression* left,
3347 Expression* right,
3348 int pos) {
3349 return new (local_zone_) BinaryOperation(local_zone_, op, left, right, pos);
3350 }
3351
3352 CountOperation* NewCountOperation(Token::Value op,
3353 bool is_prefix,
3354 Expression* expr,
3355 int pos) {
3356 return new (local_zone_)
3357 CountOperation(local_zone_, op, is_prefix, expr, pos);
3358 }
3359
3360 CompareOperation* NewCompareOperation(Token::Value op,
3361 Expression* left,
3362 Expression* right,
3363 int pos) {
3364 return new (local_zone_)
3365 CompareOperation(local_zone_, op, left, right, pos);
3366 }
3367
Ben Murdoch097c5b22016-05-18 11:27:45 +01003368 Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3369 return new (local_zone_) Spread(local_zone_, expression, pos, expr_pos);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003370 }
3371
3372 Conditional* NewConditional(Expression* condition,
3373 Expression* then_expression,
3374 Expression* else_expression,
3375 int position) {
3376 return new (local_zone_) Conditional(
3377 local_zone_, condition, then_expression, else_expression, position);
3378 }
3379
Ben Murdoch097c5b22016-05-18 11:27:45 +01003380 RewritableExpression* NewRewritableExpression(Expression* expression) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003381 DCHECK_NOT_NULL(expression);
Ben Murdoch097c5b22016-05-18 11:27:45 +01003382 return new (local_zone_) RewritableExpression(local_zone_, expression);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003383 }
3384
3385 Assignment* NewAssignment(Token::Value op,
3386 Expression* target,
3387 Expression* value,
3388 int pos) {
3389 DCHECK(Token::IsAssignmentOp(op));
3390 Assignment* assign =
3391 new (local_zone_) Assignment(local_zone_, op, target, value, pos);
3392 if (assign->is_compound()) {
3393 DCHECK(Token::IsAssignmentOp(op));
3394 assign->binary_operation_ =
3395 NewBinaryOperation(assign->binary_op(), target, value, pos + 1);
3396 }
3397 return assign;
3398 }
3399
3400 Yield* NewYield(Expression *generator_object,
3401 Expression* expression,
3402 Yield::Kind yield_kind,
3403 int pos) {
3404 if (!expression) expression = NewUndefinedLiteral(pos);
3405 return new (local_zone_)
3406 Yield(local_zone_, generator_object, expression, yield_kind, pos);
3407 }
3408
3409 Throw* NewThrow(Expression* exception, int pos) {
3410 return new (local_zone_) Throw(local_zone_, exception, pos);
3411 }
3412
3413 FunctionLiteral* NewFunctionLiteral(
3414 const AstRawString* name, Scope* scope, ZoneList<Statement*>* body,
3415 int materialized_literal_count, int expected_property_count,
3416 int parameter_count,
3417 FunctionLiteral::ParameterFlag has_duplicate_parameters,
3418 FunctionLiteral::FunctionType function_type,
3419 FunctionLiteral::EagerCompileHint eager_compile_hint, FunctionKind kind,
3420 int position) {
3421 return new (parser_zone_) FunctionLiteral(
3422 parser_zone_, name, ast_value_factory_, scope, body,
3423 materialized_literal_count, expected_property_count, parameter_count,
3424 function_type, has_duplicate_parameters, eager_compile_hint, kind,
Ben Murdoch097c5b22016-05-18 11:27:45 +01003425 position, true);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003426 }
3427
Ben Murdoch097c5b22016-05-18 11:27:45 +01003428 // Creates a FunctionLiteral representing a top-level script, the
3429 // result of an eval (top-level or otherwise), or the result of calling
3430 // the Function constructor.
3431 FunctionLiteral* NewScriptOrEvalFunctionLiteral(
3432 Scope* scope, ZoneList<Statement*>* body, int materialized_literal_count,
3433 int expected_property_count) {
3434 return new (parser_zone_) FunctionLiteral(
3435 parser_zone_, ast_value_factory_->empty_string(), ast_value_factory_,
3436 scope, body, materialized_literal_count, expected_property_count, 0,
3437 FunctionLiteral::kAnonymousExpression,
3438 FunctionLiteral::kNoDuplicateParameters,
3439 FunctionLiteral::kShouldLazyCompile, FunctionKind::kNormalFunction, 0,
3440 false);
3441 }
3442
3443 ClassLiteral* NewClassLiteral(Scope* scope, VariableProxy* proxy,
3444 Expression* extends,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003445 FunctionLiteral* constructor,
3446 ZoneList<ObjectLiteral::Property*>* properties,
3447 int start_position, int end_position) {
3448 return new (parser_zone_)
Ben Murdoch097c5b22016-05-18 11:27:45 +01003449 ClassLiteral(parser_zone_, scope, proxy, extends, constructor,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003450 properties, start_position, end_position);
3451 }
3452
3453 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
3454 v8::Extension* extension,
3455 int pos) {
3456 return new (parser_zone_)
3457 NativeFunctionLiteral(parser_zone_, name, extension, pos);
3458 }
3459
3460 DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) {
3461 VariableProxy* result = NewVariableProxy(result_var, pos);
3462 return new (parser_zone_) DoExpression(parser_zone_, block, result, pos);
3463 }
3464
3465 ThisFunction* NewThisFunction(int pos) {
3466 return new (local_zone_) ThisFunction(local_zone_, pos);
3467 }
3468
3469 SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var,
3470 Expression* home_object,
3471 int pos) {
3472 return new (parser_zone_)
3473 SuperPropertyReference(parser_zone_, this_var, home_object, pos);
3474 }
3475
3476 SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
3477 VariableProxy* new_target_var,
3478 VariableProxy* this_function_var,
3479 int pos) {
3480 return new (parser_zone_) SuperCallReference(
3481 parser_zone_, this_var, new_target_var, this_function_var, pos);
3482 }
3483
3484 EmptyParentheses* NewEmptyParentheses(int pos) {
3485 return new (local_zone_) EmptyParentheses(local_zone_, pos);
3486 }
3487
3488 Zone* zone() const { return local_zone_; }
3489
3490 // Handles use of temporary zones when parsing inner function bodies.
3491 class BodyScope {
3492 public:
3493 BodyScope(AstNodeFactory* factory, Zone* temp_zone, bool use_temp_zone)
3494 : factory_(factory), prev_zone_(factory->local_zone_) {
3495 if (use_temp_zone) {
3496 factory->local_zone_ = temp_zone;
3497 }
3498 }
3499
3500 ~BodyScope() { factory_->local_zone_ = prev_zone_; }
3501
3502 private:
3503 AstNodeFactory* factory_;
3504 Zone* prev_zone_;
3505 };
3506
3507 private:
3508 // This zone may be deallocated upon returning from parsing a function body
3509 // which we can guarantee is not going to be compiled or have its AST
3510 // inspected.
3511 // See ParseFunctionLiteral in parser.cc for preconditions.
3512 Zone* local_zone_;
3513 // ZoneObjects which need to persist until scope analysis must be allocated in
3514 // the parser-level zone.
3515 Zone* parser_zone_;
3516 AstValueFactory* ast_value_factory_;
3517};
3518
3519
Ben Murdoch097c5b22016-05-18 11:27:45 +01003520// Type testing & conversion functions overridden by concrete subclasses.
3521// Inline functions for AstNode.
3522
3523#define DECLARE_NODE_FUNCTIONS(type) \
3524 bool AstNode::Is##type() const { \
3525 NodeType mine = node_type(); \
3526 if (mine == AstNode::kRewritableExpression && \
3527 AstNode::k##type != AstNode::kRewritableExpression) \
3528 mine = reinterpret_cast<const RewritableExpression*>(this) \
3529 ->expression() \
3530 ->node_type(); \
3531 return mine == AstNode::k##type; \
3532 } \
3533 type* AstNode::As##type() { \
3534 NodeType mine = node_type(); \
3535 AstNode* result = this; \
3536 if (mine == AstNode::kRewritableExpression && \
3537 AstNode::k##type != AstNode::kRewritableExpression) { \
3538 result = \
3539 reinterpret_cast<const RewritableExpression*>(this)->expression(); \
3540 mine = result->node_type(); \
3541 } \
3542 return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \
3543 } \
3544 const type* AstNode::As##type() const { \
3545 NodeType mine = node_type(); \
3546 const AstNode* result = this; \
3547 if (mine == AstNode::kRewritableExpression && \
3548 AstNode::k##type != AstNode::kRewritableExpression) { \
3549 result = \
3550 reinterpret_cast<const RewritableExpression*>(this)->expression(); \
3551 mine = result->node_type(); \
3552 } \
3553 return mine == AstNode::k##type ? reinterpret_cast<const type*>(result) \
3554 : NULL; \
3555 }
3556AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3557#undef DECLARE_NODE_FUNCTIONS
3558
3559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00003560} // namespace internal
3561} // namespace v8
3562
3563#endif // V8_AST_AST_H_