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