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