13ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// Copyright 2012 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifndef V8_AST_AST_H_
6014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define V8_AST_AST_H_
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
8f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch#include "src/ast/ast-types.h"
9014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/ast-value-factory.h"
10014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/modules.h"
11014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/ast/variables.h"
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/bailout-reason.h"
13014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/flags.h"
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/factory.h"
15f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#include "src/globals.h"
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/isolate.h"
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/list.h"
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/parsing/token.h"
19958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/runtime/runtime.h"
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/small-pointer-list.h"
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/utils.h"
22a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
23a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace v8 {
24a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blocknamespace internal {
25a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
26a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The abstract syntax tree is an intermediate, light-weight
27a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// representation of the parsed JavaScript code suitable for
28a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// compilation to native code.
29a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
30a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Nodes are allocated in a separate zone, which allows faster
31a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// allocation and constant-time deallocation of the entire syntax
32a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// tree.
33a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
34a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
35a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// ----------------------------------------------------------------------------
36a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Nodes of the abstract syntax tree. Only concrete classes are
37a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// enumerated here.
38a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
39b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARATION_NODE_LIST(V) \
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(VariableDeclaration)         \
41f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(FunctionDeclaration)
42f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
43f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define ITERATION_NODE_LIST(V) \
44f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(DoWhileStatement)          \
45f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(WhileStatement)            \
46f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(ForStatement)              \
47f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(ForInStatement)            \
48f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(ForOfStatement)
49f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
50f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define BREAKABLE_NODE_LIST(V) \
51f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(Block)                     \
52f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(SwitchStatement)
533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define STATEMENT_NODE_LIST(V)    \
55f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ITERATION_NODE_LIST(V)          \
56f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BREAKABLE_NODE_LIST(V)          \
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(ExpressionStatement)          \
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(EmptyStatement)               \
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(SloppyBlockFunctionStatement) \
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(IfStatement)                  \
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(ContinueStatement)            \
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(BreakStatement)               \
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(ReturnStatement)              \
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(WithStatement)                \
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(TryCatchStatement)            \
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(TryFinallyStatement)          \
67a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  V(DebuggerStatement)
68a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
69f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define LITERAL_NODE_LIST(V) \
70f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(RegExpLiteral)           \
71f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(ObjectLiteral)           \
72f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(ArrayLiteral)
73f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
74f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define PROPERTY_NODE_LIST(V) \
75f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(Assignment)               \
76f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(CountOperation)           \
77f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(Property)
78f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define CALL_NODE_LIST(V) \
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(Call)                 \
81f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  V(CallNew)
82f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
83b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define EXPRESSION_NODE_LIST(V) \
84f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  LITERAL_NODE_LIST(V)          \
85f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  PROPERTY_NODE_LIST(V)         \
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CALL_NODE_LIST(V)             \
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(FunctionLiteral)            \
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ClassLiteral)               \
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(NativeFunctionLiteral)      \
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Conditional)                \
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(VariableProxy)              \
92b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Literal)                    \
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Yield)                      \
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(Throw)                      \
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CallRuntime)                \
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(UnaryOperation)             \
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(BinaryOperation)            \
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(CompareOperation)           \
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(Spread)                     \
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  V(ThisFunction)               \
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(SuperPropertyReference)     \
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(SuperCallReference)         \
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(CaseClause)                 \
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(EmptyParentheses)           \
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  V(DoExpression)               \
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V(RewritableExpression)
107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define AST_NODE_LIST(V)                        \
1093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  DECLARATION_NODE_LIST(V)                      \
110a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  STATEMENT_NODE_LIST(V)                        \
111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  EXPRESSION_NODE_LIST(V)
112a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Forward declarations
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass AstNodeFactory;
1153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Declaration;
1163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Module;
1173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass BreakableStatement;
1183ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Expression;
1193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass IterationStatement;
120b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass MaterializedLiteral;
1213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdochclass Statement;
122b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdochclass TypeFeedbackOracle;
123a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
124a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#define DEF_FORWARD_DECLARATION(type) class type;
125a7e24c173cf37484693b9abb38e494fa7bd7baebSteve BlockAST_NODE_LIST(DEF_FORWARD_DECLARATION)
126a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block#undef DEF_FORWARD_DECLARATION
127a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
128a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FeedbackVectorSlotCache {
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit FeedbackVectorSlotCache(Zone* zone)
132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : zone_(zone),
133f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        hash_map_(ZoneHashMap::kDefaultHashMapCapacity,
134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ZoneAllocationPolicy(zone)) {}
135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Put(Variable* variable, FeedbackVectorSlot slot) {
137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ZoneHashMap::Entry* entry = hash_map_.LookupOrInsert(
138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        variable, ComputePointerHash(variable), ZoneAllocationPolicy(zone_));
139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    entry->value = reinterpret_cast<void*>(slot.ToInt());
140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneHashMap::Entry* Get(Variable* variable) const {
143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return hash_map_.Lookup(variable, ComputePointerHash(variable));
144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone_;
148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneHashMap hash_map_;
149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstProperties final BASE_EMBEDDED {
1533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum Flag {
155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kNoFlags = 0,
156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDontSelfOptimize = 1 << 0,
157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDontCrankshaft = 1 << 1
158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  typedef base::Flags<Flag> Flags;
1613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit AstProperties(Zone* zone) : node_count_(0), spec_(zone) {}
1633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Flags& flags() { return flags_; }
165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Flags flags() const { return flags_; }
1663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int node_count() { return node_count_; }
1673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void add_node_count(int count) { node_count_ += count; }
1683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const FeedbackVectorSpec* get_spec() const { return &spec_; }
170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSpec* get_spec() { return &spec_; }
171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
1733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Flags flags_;
1743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int node_count_;
175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FeedbackVectorSpec spec_;
1763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
1775d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochDEFINE_OPERATORS_FOR_FLAGS(AstProperties::Flags)
179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass AstNode: public ZoneObject {
182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
183f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#define DECLARE_TYPE_ENUM(type) k##type,
184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  enum NodeType : uint8_t { AST_NODE_LIST(DECLARE_TYPE_ENUM) };
185f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#undef DECLARE_TYPE_ENUM
186f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void* operator new(size_t size, Zone* zone) { return zone->New(size); }
188b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
189f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  NodeType node_type() const { return NodeTypeField::decode(bit_field_); }
190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int position() const { return position_; }
191f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#ifdef DEBUG
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void Print(Isolate* isolate);
194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#endif  // DEBUG
195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
196f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  // Type testing & conversion functions overridden by concrete subclasses.
197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define DECLARE_NODE_FUNCTIONS(type) \
198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V8_INLINE bool Is##type() const;   \
199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V8_INLINE type* As##type();        \
200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  V8_INLINE const type* As##type() const;
201f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
202f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch#undef DECLARE_NODE_FUNCTIONS
203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BreakableStatement* AsBreakableStatement();
205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IterationStatement* AsIterationStatement();
206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MaterializedLiteral* AsMaterializedLiteral();
207b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
208b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch private:
2093fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // Hidden to prevent accidental usage. It would have to load the
2103fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  // current zone from the TLS.
2113fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  void* operator new(size_t size);
21244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int position_;
214f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class NodeTypeField : public BitField<NodeType, 0, 6> {};
215f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
216f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  uint32_t bit_field_;
218f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = NodeTypeField::kNext;
219f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
220f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstNode(int position, NodeType type)
221f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : position_(position), bit_field_(NodeTypeField::encode(type)) {}
222a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
223a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
224a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Statement : public AstNode {
226a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
227a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool IsEmpty() { return AsEmptyStatement() != NULL; }
228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsJump() const;
229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch protected:
231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Statement(int position, NodeType type) : AstNode(position, type) {}
232f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
233f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
234a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
236a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SmallMapList final {
23869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch public:
23969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SmallMapList() {}
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
24169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
24369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  void Clear() { list_.Clear(); }
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Sort() { list_.Sort(); }
24569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
24669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  bool is_empty() const { return list_.is_empty(); }
24769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  int length() const { return list_.length(); }
24869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void AddMapIfMissing(Handle<Map> map, Zone* zone) {
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!Map::TryUpdate(map).ToHandle(&map)) return;
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = 0; i < length(); ++i) {
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (at(i).is_identical_to(map)) return;
253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Add(map, zone);
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void FilterForPossibleTransitions(Map* root_map) {
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (int i = list_.length() - 1; i >= 0; i--) {
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (at(i)->FindRootMap() != root_map) {
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        list_.RemoveElement(list_.at(i));
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void Add(Handle<Map> handle, Zone* zone) {
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    list_.Add(handle.location(), zone);
26769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
26869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
26969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Handle<Map> at(int i) const {
27069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch    return Handle<Map>(list_.at(i));
27169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  }
27269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
27369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Handle<Map> first() const { return at(0); }
27469a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Handle<Map> last() const { return at(length() - 1); }
27569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
27669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch private:
27769a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  // The list stores pointers to Map*, that is Map**, so it's GC safe.
27869a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SmallPointerList<Map*> list_;
27969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
28069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  DISALLOW_COPY_AND_ASSIGN(SmallMapList);
28169a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch};
28269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
28369a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Expression : public AstNode {
285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
286b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  enum Context {
287b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Not assigned a context yet, or else will not be visited during
288b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // code generation.
289b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kUninitialized,
290b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Evaluated for its side effects.
291b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kEffect,
292b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Evaluated for its value (and side effects).
293b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kValue,
294b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    // Evaluated for control flow (and side effects).
295b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch    kTest
296b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  };
297b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Mark this expression as being in tail position.
299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void MarkTail();
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // True iff the expression is a valid reference expression.
302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsValidReferenceExpression() const;
303a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
304b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Helpers for ToBoolean conversion.
305f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool ToBooleanIsTrue() const;
306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool ToBooleanIsFalse() const;
307b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
308e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // Symbols that cannot be parsed as array indices are considered property
309e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // names.  We do not treat symbols that can be array indexes as property
310e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // names because [] for string objects is handled only by keyed ICs.
311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsPropertyName() const;
312e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
313109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // True iff the expression is a class or function expression without
314109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // a syntactic name.
315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsAnonymousFunctionDefinition() const;
316109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
31780d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen  // True iff the expression is a literal represented as a smi.
318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsSmiLiteral() const;
3193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // True iff the expression is a string literal.
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsStringLiteral() const;
3223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // True iff the expression is the null literal.
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool IsNullLiteral() const;
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // True if we can prove that the expression is the undefined literal. Note
3273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // that this also checks for loads of the global "undefined" variable.
3283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsUndefinedLiteral() const;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // True iff the expression is a valid target for an assignment.
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsValidReferenceExpressionOrThis() const;
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(rossberg): this should move to its own AST node eventually.
334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uint16_t to_boolean_types() const {
336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ToBooleanTypesField::decode(bit_field_);
337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SmallMapList* GetReceiverTypes();
340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  KeyedAccessStoreMode GetStoreMode() const;
341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IcCheckType GetKeyType() const;
342f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsMonomorphic() const;
343f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_base_id(int id) { base_id_ = id; }
345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId id() const { return BailoutId(local_id(0)); }
347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
348402d937239b0e2fd11bf2f4fe972ad78aa9fd481Andrei Popescu
349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int base_id_;
353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ToBooleanTypesField
354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<uint16_t, AstNode::kNextBitFieldIndex, 9> {};
355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Expression(int pos, NodeType type)
358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : AstNode(pos, type), base_id_(BailoutId::None().ToInt()) {
359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = ToBooleanTypesField::update(bit_field_, 0);
360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
361f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return 0; }
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_to_boolean_types(uint16_t types) {
364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = ToBooleanTypesField::update(bit_field_, types);
365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int base_id() const {
367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!BailoutId(base_id_).IsNone());
368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base_id_;
369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
3703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
371f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = ToBooleanTypesField::kNext;
372a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
373a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
374a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass BreakableStatement : public Statement {
376a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum BreakableType {
378a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TARGET_FOR_ANONYMOUS,
379a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    TARGET_FOR_NAMED_ONLY
380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  };
381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // The labels associated with this statement. May be NULL;
383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // if it is != NULL, guaranteed to contain at least one entry.
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<const AstRawString*>* labels() const { return labels_; }
385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation
3878b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Label* break_target() { return &break_target_; }
388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
389a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Testers.
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool is_target_for_anonymous() const {
391f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return BreakableTypeField::decode(bit_field_) == TARGET_FOR_ANONYMOUS;
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
393a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_base_id(int id) { base_id_ = id; }
395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId EntryId() const { return BailoutId(local_id(0)); }
397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ExitId() const { return BailoutId(local_id(1)); }
398b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
401f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
402f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BreakableType breakableType() const {
403f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return BreakableTypeField::decode(bit_field_);
404f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
405f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
406f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int base_id_;
407f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Label break_target_;
408f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ZoneList<const AstRawString*>* labels_;
409f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
410f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class BreakableTypeField
411f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<BreakableType, Statement::kNextBitFieldIndex, 1> {};
412f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
414f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BreakableStatement(ZoneList<const AstRawString*>* labels,
415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                     BreakableType breakable_type, int position, NodeType type)
416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(position, type),
417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        base_id_(BailoutId::None().ToInt()),
418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        labels_(labels) {
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(labels == NULL || labels->length() > 0);
420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= BreakableTypeField::encode(breakable_type);
4213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return 0; }
4233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int base_id() const {
425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!BailoutId(base_id_).IsNone());
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base_id_;
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
428a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
429f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = BreakableTypeField::kNext;
430a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
431a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
432a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Block final : public BreakableStatement {
434a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
435a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Statement*>* statements() { return &statements_; }
436f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool ignore_completion_value() const {
437f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IgnoreCompletionField::decode(bit_field_);
438f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
439a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId DeclsId() const { return BailoutId(local_id(0)); }
44269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch
443f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsJump() const {
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !statements_.is_empty() && statements_.last()->IsJump()
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        && labels() == NULL;  // Good enough as an approximation...
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope() const { return scope_; }
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_scope(Scope* scope) { scope_ = scope; }
4503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
451f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
453f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        bool ignore_completion_value, int pos)
456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : BreakableStatement(labels, TARGET_FOR_NAMED_ONLY, pos, kBlock),
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        statements_(capacity, zone),
458f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        scope_(NULL) {
459f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= IgnoreCompletionField::encode(ignore_completion_value);
460f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return BreakableStatement::num_ids(); }
462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
464a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Statement*> statements_;
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope_;
466f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
467f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IgnoreCompletionField
468f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, BreakableStatement::kNextBitFieldIndex, 1> {};
469f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
470f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
471f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = IgnoreCompletionField::kNext;
472a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
473a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
474a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DoExpression final : public Expression {
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Block* block() { return block_; }
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_block(Block* b) { block_ = b; }
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* result() { return result_; }
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_result(VariableProxy* v) { result_ = v; }
481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FunctionLiteral* represented_function() { return represented_function_; }
482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_represented_function(FunctionLiteral* f) {
483f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    represented_function_ = f;
484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
485f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsAnonymousFunctionDefinition() const;
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = Expression::kNextBitFieldIndex;
489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DoExpression(Block* block, VariableProxy* result, int pos)
494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kDoExpression),
495f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        block_(block),
496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        result_(result),
497f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        represented_function_(nullptr) {
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(block_);
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(result_);
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Block* block_;
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* result_;
506f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FunctionLiteral* represented_function_;
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass Declaration : public AstNode {
511a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
512c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  typedef ThreadedList<Declaration> List;
513c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
5143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  VariableProxy* proxy() const { return proxy_; }
5153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope* scope() const { return scope_; }
5163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
518f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Declaration(VariableProxy* proxy, Scope* scope, int pos, NodeType type)
519c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : AstNode(pos, type), proxy_(proxy), scope_(scope), next_(nullptr) {}
5205d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = AstNode::kNextBitFieldIndex;
522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
5233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VariableProxy* proxy_;
5253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Nested scope from which the declaration originated.
5263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope* scope_;
527c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // Declarations list threaded through the declarations.
528c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Declaration** next() { return &next_; }
529c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Declaration* next_;
530c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  friend List;
5313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
5323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass VariableDeclaration final : public Declaration {
535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
536f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
5373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VariableDeclaration(VariableProxy* proxy, Scope* scope, int pos)
539f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Declaration(proxy, scope, pos, kVariableDeclaration) {}
5403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
5413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
5423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FunctionDeclaration final : public Declaration {
5443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
5453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FunctionLiteral* fun() const { return fun_; }
546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_fun(FunctionLiteral* f) { fun_ = f; }
5473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FunctionDeclaration(VariableProxy* proxy, FunctionLiteral* fun, Scope* scope,
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                      int pos)
553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Declaration(proxy, scope, pos, kFunctionDeclaration), fun_(fun) {
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(fun != NULL);
5553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
5565d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
55785b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  FunctionLiteral* fun_;
5583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
5595d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
5603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass IterationStatement : public BreakableStatement {
562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* body() const { return body_; }
564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_body(Statement* s) { body_ = s; }
565b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
566bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int yield_count() const { return yield_count_; }
567bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int first_yield_id() const { return first_yield_id_; }
568bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_yield_count(int yield_count) { yield_count_ = yield_count; }
569bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_first_yield_id(int first_yield_id) {
570bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    first_yield_id_ = first_yield_id;
571bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
572bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
576a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // Code generation
5778b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Label* continue_target()  { return &continue_target_; }
578a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
579a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block protected:
580f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IterationStatement(ZoneList<const AstRawString*>* labels, int pos,
581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                     NodeType type)
582f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, type),
583bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        body_(NULL),
584bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        yield_count_(0),
585bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        first_yield_id_(0) {}
586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return BreakableStatement::num_ids(); }
587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void Initialize(Statement* body) { body_ = body; }
588a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
589f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex =
590f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      BreakableStatement::kNextBitFieldIndex;
591f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
592a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
595a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* body_;
5968b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Label continue_target_;
597bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int yield_count_;
598bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int first_yield_id_;
599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
601a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DoWhileStatement final : public IterationStatement {
603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
6043ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Initialize(Expression* cond, Statement* body) {
6053ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    IterationStatement::Initialize(body);
6063ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    cond_ = cond;
6073ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
6083ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6093ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Expression* cond() const { return cond_; }
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_cond(Expression* e) { cond_ = e; }
6113ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
613f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId ContinueId() const { return BailoutId(local_id(0)); }
614f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId StackCheckId() const { return BackEdgeId(); }
615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
616b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6173ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
619f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
620f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DoWhileStatement(ZoneList<const AstRawString*>* labels, int pos)
621f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : IterationStatement(labels, pos, kDoWhileStatement), cond_(NULL) {}
622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return IterationStatement::num_ids(); }
623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Expression* cond_;
6263ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
6273ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6283ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass WhileStatement final : public IterationStatement {
6303ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
6313ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  void Initialize(Expression* cond, Statement* body) {
6323ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    IterationStatement::Initialize(body);
6333ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block    cond_ = cond;
6343ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  }
6353ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6363ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block  Expression* cond() const { return cond_; }
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_cond(Expression* e) { cond_ = e; }
6383ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
640f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId ContinueId() const { return EntryId(); }
641f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId StackCheckId() const { return BodyId(); }
642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId BodyId() const { return BailoutId(local_id(0)); }
643b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
6443ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block private:
645f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
646f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
647f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  WhileStatement(ZoneList<const AstRawString*>* labels, int pos)
648f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : IterationStatement(labels, pos, kWhileStatement), cond_(NULL) {}
649f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return IterationStatement::num_ids(); }
650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Expression* cond_;
6533ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block};
6543ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
6553ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ForStatement final : public IterationStatement {
6573ce2e2076e8e3e60cf1810eec160ea2d8557e9e7Steve Block public:
658a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Initialize(Statement* init,
659a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  Expression* cond,
660a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  Statement* next,
661a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block                  Statement* body) {
662a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    IterationStatement::Initialize(body);
663a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    init_ = init;
664a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    cond_ = cond;
665a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    next_ = next;
666a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
667a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
6680d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Statement* init() const { return init_; }
6690d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Expression* cond() const { return cond_; }
6700d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Statement* next() const { return next_; }
67180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_init(Statement* s) { init_ = s; }
673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_cond(Expression* e) { cond_ = e; }
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_next(Statement* s) { next_ = s; }
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
677f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId ContinueId() const { return BailoutId(local_id(0)); }
678f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId StackCheckId() const { return BodyId(); }
679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId BodyId() const { return BailoutId(local_id(1)); }
6803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
681f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
682f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
683f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
684f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ForStatement(ZoneList<const AstRawString*>* labels, int pos)
685f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : IterationStatement(labels, pos, kForStatement),
6863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        init_(NULL),
6873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        cond_(NULL),
688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        next_(NULL) {}
689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return IterationStatement::num_ids(); }
690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
692a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* init_;
693a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* cond_;
694a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* next_;
695a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
696a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
697a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass ForEachStatement : public IterationStatement {
699a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum VisitMode {
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ENUMERATE,   // for (each in subject) body;
702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ITERATE      // for (each of subject) body;
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
704f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
705bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  using IterationStatement::Initialize;
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
707109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  static const char* VisitModeString(VisitMode mode) {
708109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return mode == ITERATE ? "for-of" : "for-in";
709109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
710109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
7113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
712f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ForEachStatement(ZoneList<const AstRawString*>* labels, int pos,
713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                   NodeType type)
714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : IterationStatement(labels, pos, type) {}
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
716b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ForInStatement final : public ForEachStatement {
719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void Initialize(Expression* each, Expression* subject, Statement* body) {
721bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ForEachStatement::Initialize(body);
722bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    each_ = each;
723bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    subject_ = subject;
724bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
725bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* enumerable() const {
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return subject();
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Expression* each() const { return each_; }
731bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Expression* subject() const { return subject_; }
732bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
733bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_each(Expression* e) { each_ = e; }
734bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_subject(Expression* e) { subject_ = e; }
735bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type feedback information.
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
738f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
7393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FeedbackVectorSlot EachFeedbackSlot() const { return each_slot_; }
740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FeedbackVectorSlot ForInFeedbackSlot() {
741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!for_in_feedback_slot_.IsInvalid());
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return for_in_feedback_slot_;
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
746f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ForInType for_in_type() const { return ForInTypeField::decode(bit_field_); }
747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_for_in_type(ForInType type) {
748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = ForInTypeField::update(bit_field_, type);
749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static int num_ids() { return parent_num_ids() + 7; }
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId BodyId() const { return BailoutId(local_id(0)); }
753109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BailoutId EnumId() const { return BailoutId(local_id(1)); }
754109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BailoutId ToObjectId() const { return BailoutId(local_id(2)); }
755109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BailoutId PrepareId() const { return BailoutId(local_id(3)); }
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId FilterId() const { return BailoutId(local_id(4)); }
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId AssignmentId() const { return BailoutId(local_id(5)); }
758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BailoutId IncrementId() const { return BailoutId(local_id(6)); }
759f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId StackCheckId() const { return BodyId(); }
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
764f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ForInStatement(ZoneList<const AstRawString*>* labels, int pos)
765f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : ForEachStatement(labels, pos, kForInStatement),
766bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        each_(nullptr),
767f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        subject_(nullptr) {
768f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = ForInTypeField::update(bit_field_, SLOW_FOR_IN);
769f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
770f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return ForEachStatement::num_ids(); }
772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
774bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Expression* each_;
775bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  Expression* subject_;
7763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  FeedbackVectorSlot each_slot_;
777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FeedbackVectorSlot for_in_feedback_slot_;
778f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ForInTypeField
780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<ForInType, ForEachStatement::kNextBitFieldIndex, 1> {};
781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = ForInTypeField::kNext;
784a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
785a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
786a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ForOfStatement final : public ForEachStatement {
788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
789bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void Initialize(Statement* body, Variable* iterator,
790bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                  Expression* assign_iterator, Expression* next_result,
791bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                  Expression* result_done, Expression* assign_each) {
792bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    ForEachStatement::Initialize(body);
793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    iterator_ = iterator;
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assign_iterator_ = assign_iterator;
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    next_result_ = next_result;
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result_done_ = result_done;
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assign_each_ = assign_each;
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Variable* iterator() const {
801109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return iterator_;
802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
803109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // iterator = subject[Symbol.iterator]()
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* assign_iterator() const {
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return assign_iterator_;
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // result = iterator.next()  // with type check
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* next_result() const {
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return next_result_;
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // result.done
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* result_done() const {
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return result_done_;
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // each = result.value
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* assign_each() const {
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return assign_each_;
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_assign_iterator(Expression* e) { assign_iterator_ = e; }
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_next_result(Expression* e) { next_result_ = e; }
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_result_done(Expression* e) { result_done_ = e; }
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_assign_each(Expression* e) { assign_each_ = e; }
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
829f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId ContinueId() const { return EntryId(); }
830f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId StackCheckId() const { return BackEdgeId(); }
831b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId BackEdgeId() const { return BailoutId(local_id(0)); }
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
835f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
836f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
837f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
838f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ForOfStatement(ZoneList<const AstRawString*>* labels, int pos)
839f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : ForEachStatement(labels, pos, kForOfStatement),
840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        iterator_(NULL),
841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assign_iterator_(NULL),
842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_result_(NULL),
843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        result_done_(NULL),
844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        assign_each_(NULL) {}
845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return ForEachStatement::num_ids(); }
846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
848109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Variable* iterator_;
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* assign_iterator_;
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* next_result_;
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* result_done_;
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* assign_each_;
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ExpressionStatement final : public Statement {
857a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
85885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  void set_expression(Expression* e) { expression_ = e; }
85985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Expression* expression() const { return expression_; }
860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsJump() const { return expression_->IsThrow(); }
8613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
862a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
863f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
864f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
865f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ExpressionStatement(Expression* expression, int pos)
866f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(pos, kExpressionStatement), expression_(expression) {}
867f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
868a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
869a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
870a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
871a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass JumpStatement : public Statement {
873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
874f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsJump() const { return true; }
875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  JumpStatement(int pos, NodeType type) : Statement(pos, type) {}
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ContinueStatement final : public JumpStatement {
882a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8830d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  IterationStatement* target() const { return target_; }
8843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
885a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
886f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
887f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
888f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ContinueStatement(IterationStatement* target, int pos)
889f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : JumpStatement(pos, kContinueStatement), target_(target) {}
890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
891a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  IterationStatement* target_;
892a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
893a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
894a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BreakStatement final : public JumpStatement {
896a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
8970d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  BreakableStatement* target() const { return target_; }
8983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
899a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
901f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
902f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BreakStatement(BreakableStatement* target, int pos)
903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : JumpStatement(pos, kBreakStatement), target_(target) {}
904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
905a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  BreakableStatement* target_;
906a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
907a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
908a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ReturnStatement final : public JumpStatement {
910a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
911b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Expression* expression() const { return expression_; }
9123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
915a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
918f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ReturnStatement(Expression* expression, int pos)
919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : JumpStatement(pos, kReturnStatement), expression_(expression) {}
920f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
922a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
923a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
924a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass WithStatement final : public Statement {
926a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope() { return scope_; }
9280d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Expression* expression() const { return expression_; }
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
93069a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Statement* statement() const { return statement_; }
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_statement(Statement* s) { statement_ = s; }
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_base_id(int id) { base_id_ = id; }
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids() + 2; }
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId ToObjectId() const { return BailoutId(local_id(0)); }
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId EntryId() const { return BailoutId(local_id(1)); }
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
938f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
939f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
940f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
941f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  WithStatement(Scope* scope, Expression* expression, Statement* statement,
942f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                int pos)
943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(pos, kWithStatement),
944f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        base_id_(BailoutId::None().ToInt()),
945b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        scope_(scope),
946b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        expression_(expression),
947f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        statement_(statement) {}
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
949f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return 0; }
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int base_id() const {
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!BailoutId(base_id_).IsNone());
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return base_id_;
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int base_id_;
957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Scope* scope_;
958a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
95969a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  Statement* statement_;
960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
962a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CaseClause final : public Expression {
964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
9650d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  bool is_default() const { return label_ == NULL; }
9660d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Expression* label() const {
967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    CHECK(!is_default());
968a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return label_;
969a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_label(Expression* e) { label_ = e; }
9718b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Label* body_target() { return &body_target_; }
9720d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  ZoneList<Statement*>* statements() const { return statements_; }
973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId EntryId() const { return BailoutId(local_id(0)); }
976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
97744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
978f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* compare_type() { return compare_type_; }
979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_compare_type(AstType* type) { compare_type_ = type; }
980f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
981f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // CaseClause will have both a slot in the feedback vector and the
982f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TypeFeedbackId to record the type information. TypeFeedbackId is used by
983f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // full codegen and the feedback vector slot is used by interpreter.
984f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
985f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 FeedbackVectorSlotCache* cache);
986f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
987f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot CompareOperationFeedbackSlot() {
988f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return type_feedback_slot_;
989f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
990b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
991a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
992f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
995f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CaseClause(Expression* label, ZoneList<Statement*>* statements, int pos);
996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
998a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* label_;
9998b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Label body_target_;
1000a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Statement*>* statements_;
1001f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* compare_type_;
1002f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot type_feedback_slot_;
1003a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1004a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1005a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SwitchStatement final : public BreakableStatement {
1007a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1008a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1009a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    tag_ = tag;
1010a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    cases_ = cases;
1011a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1012a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
10130d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  Expression* tag() const { return tag_; }
10140d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  ZoneList<CaseClause*>* cases() const { return cases_; }
10153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_tag(Expression* t) { tag_ = t; }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1018f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1019f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1020f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1021f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SwitchStatement(ZoneList<const AstRawString*>* labels, int pos)
1022f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : BreakableStatement(labels, TARGET_FOR_ANONYMOUS, pos, kSwitchStatement),
10233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        tag_(NULL),
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        cases_(NULL) {}
1025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* tag_;
1027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<CaseClause*>* cases_;
1028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1029a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1031a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// If-statements always have non-null references to their then- and
1032a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// else-parts. When parsing if-statements with no explicit else-part,
1033a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// the parser implicitly creates an empty statement. Use the
1034a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// HasThenStatement() and HasElseStatement() functions to check if a
1035a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// given if-statement has a then- or an else-part containing code.
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass IfStatement final : public Statement {
1037a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
103885b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
103985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
104085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
104185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Expression* condition() const { return condition_; }
104285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Statement* then_statement() const { return then_statement_; }
104385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Statement* else_statement() const { return else_statement_; }
104485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_condition(Expression* e) { condition_ = e; }
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_then_statement(Statement* s) { then_statement_ = s; }
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_else_statement(Statement* s) { else_statement_ = s; }
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsJump() const {
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return HasThenStatement() && then_statement()->IsJump()
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        && HasElseStatement() && else_statement()->IsJump();
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
105385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_base_id(int id) { base_id_ = id; }
1055958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 3; }
1056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId IfId() const { return BailoutId(local_id(0)); }
1057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ThenId() const { return BailoutId(local_id(1)); }
1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ElseId() const { return BailoutId(local_id(2)); }
10593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IfStatement(Expression* condition, Statement* then_statement,
1064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              Statement* else_statement, int pos)
1065f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(pos, kIfStatement),
1066f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        base_id_(BailoutId::None().ToInt()),
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        condition_(condition),
10683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        then_statement_(then_statement),
1069f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        else_statement_(else_statement) {}
1070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1071f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return 0; }
1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int base_id() const {
1073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!BailoutId(base_id_).IsNone());
1074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base_id_;
1075958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1076958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1077958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int base_id_;
1079a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* condition_;
1080a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* then_statement_;
1081a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Statement* else_statement_;
1082a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1083a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1084a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass TryStatement : public Statement {
1086a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1087a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Block* try_block() const { return try_block_; }
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_try_block(Block* b) { try_block_ = b; }
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1090f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Prediction of whether exceptions thrown into the handler for this try block
1091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // will be caught.
1092f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //
1093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // This is set in ast-numbering and later compiled into the code's handler
1094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // table.  The runtime uses this information to implement a feature that
1095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // notifies the debugger when an uncaught exception is thrown, _before_ the
1096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // exception propagates to the top.
1097f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  //
1098f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Since it's generally undecidable whether an exception will be caught, our
1099f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // prediction is only an approximation.
1100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandlerTable::CatchPrediction catch_prediction() const {
1101f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return catch_prediction_;
1102f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1103f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_catch_prediction(HandlerTable::CatchPrediction prediction) {
1104f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    catch_prediction_ = prediction;
1105f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1106f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
11073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch protected:
1108f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TryStatement(Block* try_block, int pos, NodeType type)
1109f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(pos, type),
1110f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        catch_prediction_(HandlerTable::UNCAUGHT),
1111f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        try_block_(try_block) {}
1112f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1113f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  HandlerTable::CatchPrediction catch_prediction_;
1114a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1116a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Block* try_block_;
1117a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1118a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1119a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TryCatchStatement final : public TryStatement {
1121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
11223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Scope* scope() { return scope_; }
11233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Variable* variable() { return variable_; }
11243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Block* catch_block() const { return catch_block_; }
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_catch_block(Block* b) { catch_block_ = b; }
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
11273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The clear_pending_message flag indicates whether or not to clear the
11283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // isolate's pending exception message before executing the catch_block.  In
11293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // the normal use case, this flag is always on because the message object
11303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // is not needed anymore when entering the catch block and should not be kept
11313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // alive.
11323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // The use case where the flag is off is when the catch block is guaranteed to
11333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // rethrow the caught exception (using %ReThrow), which reuses the pending
11343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // message instead of generating a new one.
11353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // (When the catch block doesn't rethrow but is guaranteed to perform an
11363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // ordinary throw, not clearing the old message is safe but not very useful.)
1137f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool clear_pending_message() const {
1138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return catch_prediction_ != HandlerTable::UNCAUGHT;
1139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
11403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
1141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TryCatchStatement(Block* try_block, Scope* scope, Variable* variable,
1145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    Block* catch_block,
1146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                    HandlerTable::CatchPrediction catch_prediction, int pos)
1147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : TryStatement(try_block, pos, kTryCatchStatement),
11483fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        scope_(scope),
11493fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        variable_(variable),
1150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        catch_block_(catch_block) {
1151f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    catch_prediction_ = catch_prediction;
1152f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1153a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
11543fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Scope* scope_;
11553fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch  Variable* variable_;
1156a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Block* catch_block_;
1157a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1158a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1159a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass TryFinallyStatement final : public TryStatement {
1161a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1162a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Block* finally_block() const { return finally_block_; }
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_finally_block(Block* b) { finally_block_ = b; }
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1165a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1167f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1168f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TryFinallyStatement(Block* try_block, Block* finally_block, int pos)
1169f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : TryStatement(try_block, pos, kTryFinallyStatement),
1170f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        finally_block_(finally_block) {}
1171f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1172a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Block* finally_block_;
1173a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1174a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1175a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass DebuggerStatement final : public Statement {
1177a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_base_id(int id) { base_id_ = id; }
1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId DebugBreakId() const { return BailoutId(local_id(0)); }
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1183f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1185f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit DebuggerStatement(int pos)
1186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(pos, kDebuggerStatement),
1187f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        base_id_(BailoutId::None().ToInt()) {}
1188f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1189f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return 0; }
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int base_id() const {
1191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!BailoutId(base_id_).IsNone());
1192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return base_id_;
1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int base_id_;
1197a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1198a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1199a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass EmptyStatement final : public Statement {
1201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1202f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1203f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit EmptyStatement(int pos) : Statement(pos, kEmptyStatement) {}
1204a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1205a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1206a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Delegates to another statement, which may be overwritten.
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This was introduced to implement ES2015 Annex B3.3 for conditionally making
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// sloppy-mode block-scoped functions have a var binding, which is changed
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// from one statement to another during parsing.
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SloppyBlockFunctionStatement final : public Statement {
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Statement* statement() const { return statement_; }
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_statement(Statement* statement) { statement_ = statement; }
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scope* scope() const { return scope_; }
1216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SloppyBlockFunctionStatement* next() { return next_; }
1217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_next(SloppyBlockFunctionStatement* next) { next_ = next; }
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SloppyBlockFunctionStatement(Statement* statement, Scope* scope)
1223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Statement(kNoSourcePosition, kSloppyBlockFunctionStatement),
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        statement_(statement),
1225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        scope_(scope),
1226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        next_(nullptr) {}
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Statement* statement_;
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Scope* const scope_;
1230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SloppyBlockFunctionStatement* next_;
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Literal final : public Expression {
1235a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1236f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Returns true if literal represents a property name (i.e. cannot be parsed
1237f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // as array indices).
1238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsPropertyName() const { return value_->IsPropertyName(); }
1239e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke
1240b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<String> AsPropertyName() {
1241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsPropertyName());
1242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>::cast(value());
1243b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  }
1244b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstRawString* AsRawPropertyName() {
1246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(IsPropertyName());
1247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return value_->AsString();
124844f0eee88ff00398ff7f715fab053374d808c90dSteve Block  }
1249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool ToBooleanIsTrue() const { return raw_value()->BooleanValue(); }
1251f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool ToBooleanIsFalse() const { return !raw_value()->BooleanValue(); }
1252a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> value() const { return value_->value(); }
1254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* raw_value() const { return value_; }
12553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
12563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Support for using Literal as a HashMap key. NOTE: Currently, this works
12573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // only for string and number literals!
1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  uint32_t Hash();
1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static bool Match(void* literal1, void* literal2);
12603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId LiteralFeedbackId() const {
1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return TypeFeedbackId(local_id(0));
12643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
12653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1266a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1267f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1269f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Literal(const AstValue* value, int position)
1270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(position, kLiteral), value_(value) {}
1271f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
12743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstValue* value_;
1276a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1277a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1278a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstLiteralReindexer;
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1281a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Base class for literals that needs space in the corresponding JSFunction.
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochclass MaterializedLiteral : public Expression {
1283a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1284a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int literal_index() { return literal_index_; }
1285a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int depth() const {
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // only callable after initialization.
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(depth_ >= 1);
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return depth_;
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1292f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
1293f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int depth_ : 31;
1294f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  int literal_index_;
1295f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1296f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  friend class AstLiteralReindexer;
1297f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1298f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsSimpleField
1299f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1300f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch protected:
1302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  MaterializedLiteral(int literal_index, int pos, NodeType type)
1303f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : Expression(pos, type), depth_(0), literal_index_(literal_index) {
1304f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= IsSimpleField::encode(false);
1305f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1307a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // A materialized literal is simple if the values consist of only
1308a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  // constants and simple object and array literals.
1309f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_simple() const { return IsSimpleField::decode(bit_field_); }
1310f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_is_simple(bool is_simple) {
1311f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = IsSimpleField::update(bit_field_, is_simple);
1312f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class CompileTimeValue;
1314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_depth(int depth) {
1316f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    DCHECK_LE(1, depth);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    depth_ = depth;
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
13193ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Populate the constant properties/elements fixed array.
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildConstants(Isolate* isolate);
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class ArrayLiteral;
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  friend class ObjectLiteral;
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the expression is a literal, return the literal value;
1326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // if the expression is a materialized literal and is simple return a
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // compile time value as encoded by CompileTimeValue::GetValue().
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Otherwise, return undefined literal as the placeholder
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // in the object literal boilerplate.
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
1331a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1332f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = IsSimpleField::kNext;
1333a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1334a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1335f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Common supertype for ObjectLiteralProperty and ClassLiteralProperty
1336f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass LiteralProperty : public ZoneObject {
1337f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch public:
1338f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expression* key() const { return key_; }
1339f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expression* value() const { return value_; }
1340f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_key(Expression* e) { key_ = e; }
1341f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_value(Expression* e) { value_ = e; }
1342f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1343f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_computed_name() const { return is_computed_name_; }
1344f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1345f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot GetSlot(int offset = 0) const {
1346f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1347f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return slots_[offset];
1348f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1349f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void SetSlot(FeedbackVectorSlot slot, int offset = 0) {
1351f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK_LT(offset, static_cast<int>(arraysize(slots_)));
1352f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    slots_[offset] = slot;
1353f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1354f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1355f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool NeedsSetFunctionName() const;
1356f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1357f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
1358f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  LiteralProperty(Expression* key, Expression* value, bool is_computed_name)
1359f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : key_(key), value_(value), is_computed_name_(is_computed_name) {}
1360f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1361f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expression* key_;
1362f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Expression* value_;
1363f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot slots_[2];
1364f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_computed_name_;
1365f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch};
1366a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Property is used for passing information
1368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// about an object literal's properties from the parser
1369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// to the code generator.
1370f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass ObjectLiteralProperty final : public LiteralProperty {
1371a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1372f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  enum Kind : uint8_t {
1373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    CONSTANT,              // Property with constant value (compile time).
1374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    COMPUTED,              // Property with computed value (execution time).
1375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MATERIALIZED_LITERAL,  // Property value is a materialized literal.
1376f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    GETTER,
1377f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    SETTER,    // Property is an accessor function.
1378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    PROTOTYPE  // Property is __proto__.
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1380a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1381f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Kind kind() const { return kind_; }
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type feedback information.
1384f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool IsMonomorphic() const { return !receiver_type_.is_null(); }
1385f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Handle<Map> GetReceiverType() const { return receiver_type_; }
13863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1387f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool IsCompileTimeValue() const;
1388d0582a6c46733687d045e4188a1bcd0123c758a1Steve Block
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_emit_store(bool emit_store);
1390f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool emit_store() const;
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_receiver_type(Handle<Map> map) { receiver_type_ = map; }
1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1395958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  friend class AstNodeFactory;
13963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectLiteralProperty(Expression* key, Expression* value, Kind kind,
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                        bool is_computed_name);
1399f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ObjectLiteralProperty(AstValueFactory* ast_value_factory, Expression* key,
1400f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                        Expression* value, bool is_computed_name);
14013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Kind kind_;
1403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool emit_store_;
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<Map> receiver_type_;
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// An object literal has a boilerplate object that is used
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// for minimizing the work when constructing it at runtime.
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ObjectLiteral final : public MaterializedLiteral {
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  typedef ObjectLiteralProperty Property;
1413a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1414a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> constant_properties() const {
1415a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    return constant_properties_;
1416a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
1417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int properties_count() const { return boilerplate_properties_; }
1418a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Property*>* properties() const { return properties_; }
1419f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool fast_elements() const { return FastElementsField::decode(bit_field_); }
1420f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool may_store_doubles() const {
1421f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return MayStoreDoublesField::decode(bit_field_);
1422f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1423f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool has_elements() const { return HasElementsField::decode(bit_field_); }
1424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool has_shallow_properties() const {
1425109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return depth() == 1 && !has_elements() && !may_store_doubles();
1426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
14276ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Decide if a property should be in the object boilerplate.
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static bool IsBoilerplateProperty(Property* property);
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Populate the constant properties fixed array.
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildConstantProperties(Isolate* isolate);
14333e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
14343e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // Mark all computed expressions that are bound to a key that
14353e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // is shadowed by a later occurrence of the same key. For the
14363e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu  // marked expressions, no store code is emitted.
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void CalculateEmitStore(Zone* zone);
1438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assemble bitfield of flags for the CreateObjectLiteral helper.
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int ComputeFlags(bool disable_mementos = false) const {
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int flags = fast_elements() ? kFastElements : kNoFlags;
1442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (has_shallow_properties()) {
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags |= kShallowProperties;
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (disable_mementos) {
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags |= kDisableMementos;
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return flags;
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
14503e5fa29ddb82551500b118e9bf37af3966277b70Teng-Hui Zhu
145144f0eee88ff00398ff7f715fab053374d808c90dSteve Block  enum Flags {
145244f0eee88ff00398ff7f715fab053374d808c90dSteve Block    kNoFlags = 0,
145344f0eee88ff00398ff7f715fab053374d808c90dSteve Block    kFastElements = 1,
14543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    kShallowProperties = 1 << 1,
14553b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    kDisableMementos = 1 << 2
145644f0eee88ff00398ff7f715fab053374d808c90dSteve Block  };
145744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
14583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  struct Accessors: public ZoneObject {
145913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    Accessors() : getter(NULL), setter(NULL), bailout_id(BailoutId::None()) {}
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ObjectLiteralProperty* getter;
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ObjectLiteralProperty* setter;
146213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    BailoutId bailout_id;
14633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
14643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Return an AST id for a property that is used in simulate instructions.
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId GetIdForPropertyName(int i) {
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return BailoutId(local_id(2 * i + 1));
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId GetIdForPropertySet(int i) {
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return BailoutId(local_id(2 * i + 2));
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Unlike other AST nodes, this number of bailout IDs allocated for an
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ObjectLiteral can vary, so num_ids() is not a static method.
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int num_ids() const {
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return parent_num_ids() + 1 + 2 * properties()->length();
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Object literals need one feedback slot for each non-trivial value, as well
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // as some slots for home objects.
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1484f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1486f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1487f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1488f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1489f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ObjectLiteral(ZoneList<Property*>* properties, int literal_index,
1490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                uint32_t boilerplate_properties, int pos)
1491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : MaterializedLiteral(literal_index, pos, kObjectLiteral),
1492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        boilerplate_properties_(boilerplate_properties),
1493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        properties_(properties) {
1494f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= FastElementsField::encode(false) |
1495f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  HasElementsField::encode(false) |
1496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  MayStoreDoublesField::encode(false);
1497f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
14983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1499f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1502f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  uint32_t boilerplate_properties_;
1503f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot slot_;
1504a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Handle<FixedArray> constant_properties_;
1505a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Property*>* properties_;
1506f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1507f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class FastElementsField
1508f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, MaterializedLiteral::kNextBitFieldIndex, 1> {};
1509f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class HasElementsField : public BitField<bool, FastElementsField::kNext, 1> {
1510f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
1511f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class MayStoreDoublesField
1512f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, HasElementsField::kNext, 1> {};
1513f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1514f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch protected:
1515f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  static const uint8_t kNextBitFieldIndex = MayStoreDoublesField::kNext;
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// A map from property names to getter/setter pairs allocated in the zone.
152013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochclass AccessorTable
152113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    : public base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
1522f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                   bool (*)(void*, void*),
152313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                   ZoneAllocationPolicy> {
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  explicit AccessorTable(Zone* zone)
152613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      : base::TemplateHashMap<Literal, ObjectLiteral::Accessors,
1527f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                              bool (*)(void*, void*), ZoneAllocationPolicy>(
1528f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            Literal::Match, ZoneAllocationPolicy(zone)),
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        zone_(zone) {}
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Iterator lookup(Literal* literal) {
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Iterator it = find(literal, true, ZoneAllocationPolicy(zone_));
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (it->second == NULL) it->second = new (zone_) ObjectLiteral::Accessors();
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return it;
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone_;
1539a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1540a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1541a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1542a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Node for capturing a regexp literal.
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass RegExpLiteral final : public MaterializedLiteral {
1544a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> pattern() const { return pattern_->string(); }
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int flags() const { return flags_; }
15473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1548f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1549f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1550f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1551f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  RegExpLiteral(const AstRawString* pattern, int flags, int literal_index,
1552f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                int pos)
1553f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : MaterializedLiteral(literal_index, pos, kRegExpLiteral),
1554f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        flags_(flags),
1555f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        pattern_(pattern) {
1556b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    set_depth(1);
1557b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1558a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int const flags_;
1560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const AstRawString* const pattern_;
1561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// An array literal has a literals object that is used
1565a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// for minimizing the work when constructing it at runtime.
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ArrayLiteral final : public MaterializedLiteral {
1567a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
15683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<FixedArray> constant_elements() const { return constant_elements_; }
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ElementsKind constant_elements_kind() const {
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_EQ(2, constant_elements_->length());
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return static_cast<ElementsKind>(
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Smi::cast(constant_elements_->get(0))->value());
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
15753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* values() const { return values_; }
15763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
1578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
15793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  // Return an AST id for an element that is used in simulate instructions.
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId GetIdForElement(int i) { return BailoutId(local_id(i + 1)); }
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Unlike other AST nodes, this number of bailout IDs allocated for an
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ArrayLiteral can vary, so num_ids() is not a static method.
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int num_ids() const { return parent_num_ids() + 1 + values()->length(); }
15853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Populate the constant elements fixed array.
1587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void BuildConstantElements(Isolate* isolate);
1588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Assemble bitfield of flags for the CreateArrayLiteral helper.
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int ComputeFlags(bool disable_mementos = false) const {
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int flags = depth() == 1 ? kShallowElements : kNoFlags;
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (disable_mementos) {
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      flags |= kDisableMementos;
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return flags;
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Provide a mechanism for iterating through values to rewrite spreads.
1599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ZoneList<Expression*>::iterator FirstSpread() const {
1600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return (first_spread_index_ >= 0) ? values_->begin() + first_spread_index_
1601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                      : values_->end();
1602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ZoneList<Expression*>::iterator EndValue() const { return values_->end(); }
1604109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1605109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Rewind an array literal omitting everything from the first spread on.
1606109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void RewindSpreads() {
1607109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    values_->Rewind(first_spread_index_);
1608109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    first_spread_index_ = -1;
1609109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1610109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
1611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum Flags {
1612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kNoFlags = 0,
1613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    kShallowElements = 1,
16143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    kDisableMementos = 1 << 1
1615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
16163ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1618f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot LiteralFeedbackSlot() const { return literal_slot_; }
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1621a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
1622f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1623f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1624f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ArrayLiteral(ZoneList<Expression*>* values, int first_spread_index,
1625f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               int literal_index, int pos)
1626f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : MaterializedLiteral(literal_index, pos, kArrayLiteral),
1627f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        first_spread_index_(first_spread_index),
1628f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        values_(values) {}
1629f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1630f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1631958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1632958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int first_spread_index_;
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot literal_slot_;
1635f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<FixedArray> constant_elements_;
1636f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ZoneList<Expression*>* values_;
1637a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass VariableProxy final : public Expression {
1641a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1642f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsValidReferenceExpression() const {
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return !is_this() && !is_new_target();
16443ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
16453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Handle<String> name() const { return raw_name()->string(); }
1647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const AstRawString* raw_name() const {
1648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return is_resolved() ? var_->raw_name() : raw_name_;
1649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
16503ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Variable* var() const {
1652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(is_resolved());
1653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return var_;
1654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_var(Variable* v) {
1656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!is_resolved());
1657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK_NOT_NULL(v);
1658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    var_ = v;
1659958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1661958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_this() const { return IsThisField::decode(bit_field_); }
1662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
1664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_is_assigned() {
1665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsAssignedField::update(bit_field_, true);
1666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1667958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
1669958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_is_resolved() {
1670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsResolvedField::update(bit_field_, true);
1671958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool is_new_target() const { return IsNewTargetField::decode(bit_field_); }
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_is_new_target() {
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bit_field_ = IsNewTargetField::update(bit_field_, true);
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1678c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  HoleCheckMode hole_check_mode() const {
1679c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return HoleCheckModeField::decode(bit_field_);
1680c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1681c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void set_needs_hole_check() {
1682c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    bit_field_ =
1683c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        HoleCheckModeField::update(bit_field_, HoleCheckMode::kRequired);
1684c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
16856ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Bind this proxy to the variable var.
1687a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void BindTo(Variable* var);
1688a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool UsesVariableFeedbackSlot() const {
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return var()->IsUnallocated() || var()->IsLookupSlot();
1691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1694f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
16953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot VariableFeedbackSlot() { return variable_feedback_slot_; }
1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids() + 1; }
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId BeforeId() const { return BailoutId(local_id(0)); }
1700f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_next_unresolved(VariableProxy* next) { next_unresolved_ = next; }
1701f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VariableProxy* next_unresolved() { return next_unresolved_; }
170285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1703f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1704f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1705f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1706c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  VariableProxy(Variable* var, int start_position);
1707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  VariableProxy(const AstRawString* name, VariableKind variable_kind,
1708c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                int start_position);
1709f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit VariableProxy(const VariableProxy* copy_from);
171085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1714f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsThisField : public BitField<bool, Expression::kNextBitFieldIndex, 1> {
1715f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
1716f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsAssignedField : public BitField<bool, IsThisField::kNext, 1> {};
1717f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsResolvedField : public BitField<bool, IsAssignedField::kNext, 1> {};
1718f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsNewTargetField : public BitField<bool, IsResolvedField::kNext, 1> {};
1719c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  class HoleCheckModeField
1720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : public BitField<HoleCheckMode, IsNewTargetField::kNext, 1> {};
1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot variable_feedback_slot_;
1723958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  union {
1724958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const AstRawString* raw_name_;  // if !is_resolved_
1725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Variable* var_;                 // if is_resolved_
1726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  };
1727f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VariableProxy* next_unresolved_;
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Left-hand side can only be a property, a global or a (parameter or local)
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// slot.
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochenum LhsKind {
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VARIABLE,
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NAMED_PROPERTY,
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  KEYED_PROPERTY,
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  NAMED_SUPER_PROPERTY,
1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  KEYED_SUPER_PROPERTY
1739a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1740a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1741a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Property final : public Expression {
1743a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1744f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsValidReferenceExpression() const { return true; }
1745a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1746a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* obj() const { return obj_; }
1747a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* key() const { return key_; }
1748a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_obj(Expression* e) { obj_ = e; }
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_key(Expression* e) { key_ = e; }
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids() + 1; }
1753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId LoadId() const { return BailoutId(local_id(0)); }
1754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsStringAccess() const {
1756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsStringAccessField::decode(bit_field_);
1757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
17589fac840a46e8b7e26894f4792ba26dde14c56b04Steve Block
1759b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Type feedback information.
1760f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsMonomorphic() const { return receiver_types_.length() == 1; }
1761f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SmallMapList* GetReceiverTypes() { return &receiver_types_; }
1762f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  KeyedAccessStoreMode GetStoreMode() const { return STANDARD_STORE; }
1763f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
1764958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsUninitialized() const {
1765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return !is_for_call() && HasNoTypeInformation();
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasNoTypeInformation() const {
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return GetInlineCacheState() == UNINITIALIZED;
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InlineCacheState GetInlineCacheState() const {
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return InlineCacheStateField::decode(bit_field_);
1772958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_is_string_access(bool b) {
1774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsStringAccessField::update(bit_field_, b);
1775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_key_type(IcCheckType key_type) {
1777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = KeyTypeField::update(bit_field_, key_type);
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_inline_cache_state(InlineCacheState state) {
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bit_field_ = InlineCacheStateField::update(bit_field_, state);
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void mark_for_call() {
1783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsForCallField::update(bit_field_, true);
1784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_for_call() const { return IsForCallField::decode(bit_field_); }
17863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool IsSuperAccess() { return obj()->IsSuperPropertyReference(); }
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1790f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache) {
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    FeedbackVectorSlotKind kind = key()->IsPropertyName()
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      ? FeedbackVectorSlotKind::LOAD_IC
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      : FeedbackVectorSlotKind::KEYED_LOAD_IC;
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    property_feedback_slot_ = spec->AddSlot(kind);
1795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot PropertyFeedbackSlot() const {
1798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return property_feedback_slot_;
1799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
18003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1801f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Returns the properties assign type.
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static LhsKind GetAssignType(Property* property) {
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (property == NULL) return VARIABLE;
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool super_access = property->IsSuperAccess();
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return (property->key()->IsPropertyName())
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               ? (super_access ? NAMED_SUPER_PROPERTY : NAMED_PROPERTY)
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               : (super_access ? KEYED_SUPER_PROPERTY : KEYED_PROPERTY);
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1810f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1811f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1812f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1813f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Property(Expression* obj, Expression* key, int pos)
1814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : Expression(pos, kProperty), obj_(obj), key_(key) {
1815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= IsForCallField::encode(false) |
1816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  IsStringAccessField::encode(false) |
1817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  InlineCacheStateField::encode(UNINITIALIZED);
1818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1819b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
1821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1823f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsForCallField
1824f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1825f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsStringAccessField : public BitField<bool, IsForCallField::kNext, 1> {
1826f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  };
1827f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class KeyTypeField
1828f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<IcCheckType, IsStringAccessField::kNext, 1> {};
1829f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class InlineCacheStateField
1830f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<InlineCacheState, KeyTypeField::kNext, 4> {};
1831f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot property_feedback_slot_;
1833a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* obj_;
1834a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* key_;
183569a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SmallMapList receiver_types_;
1836a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
1837a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1838a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Call final : public Expression {
1840a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
1841a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression() const { return expression_; }
1842a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Expression*>* arguments() const { return arguments_; }
1843a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type feedback information.
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot CallFeedbackICSlot() const { return ic_slot_; }
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1852f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SmallMapList* GetReceiverTypes() {
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (expression()->IsProperty()) {
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return expression()->AsProperty()->GetReceiverTypes();
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1856f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return nullptr;
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsMonomorphic() const {
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (expression()->IsProperty()) {
1861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return expression()->AsProperty()->IsMonomorphic();
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return !target_.is_null();
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> target() { return target_; }
1867b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site() { return allocation_site_; }
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetKnownGlobalTarget(Handle<JSFunction> target) {
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    target_ = target;
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_is_uninitialized(false);
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_target(Handle<JSFunction> target) { target_ = target; }
1875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_allocation_site(Handle<AllocationSite> site) {
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_site_ = site;
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids() + 4; }
1880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId EvalId() const { return BailoutId(local_id(1)); }
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId LookupId() const { return BailoutId(local_id(2)); }
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId CallId() const { return BailoutId(local_id(3)); }
1884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_uninitialized() const {
1886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsUninitializedField::decode(bit_field_);
1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_is_uninitialized(bool b) {
1889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsUninitializedField::update(bit_field_, b);
1890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool is_possibly_eval() const {
1893f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return IsPossiblyEvalField::decode(bit_field_);
1894f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
1895f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1896109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TailCallMode tail_call_mode() const {
1897109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return IsTailField::decode(bit_field_) ? TailCallMode::kAllow
1898109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                           : TailCallMode::kDisallow;
1899109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
1900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void MarkTail() { bit_field_ = IsTailField::update(bit_field_, true); }
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum CallType {
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    GLOBAL_CALL,
1904c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    WITH_CALL,
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NAMED_PROPERTY_CALL,
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    KEYED_PROPERTY_CALL,
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    NAMED_SUPER_PROPERTY_CALL,
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    KEYED_SUPER_PROPERTY_CALL,
1909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SUPER_CALL,
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    OTHER_CALL
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  };
1912b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  enum PossiblyEval {
1914f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    IS_POSSIBLY_EVAL,
1915f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    NOT_EVAL,
1916f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  };
1917f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Helpers to determine how to handle the call.
1919f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallType GetCallType() const;
1920b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1921b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#ifdef DEBUG
1922b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Used to assert that the FullCodeGenerator records the return site.
1923b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  bool return_is_recorded_;
1924b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch#endif
1925b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
1926f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
1927f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
1928f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Call(Expression* expression, ZoneList<Expression*>* arguments, int pos,
1930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch       PossiblyEval possibly_eval)
1931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kCall),
19323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        expression_(expression),
1933f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        arguments_(arguments) {
1934f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |=
1935f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IsUninitializedField::encode(false) |
1936f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IsPossiblyEvalField::encode(possibly_eval == IS_POSSIBLY_EVAL);
1937f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (expression->IsProperty()) {
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      expression->AsProperty()->mark_for_call();
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
19423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1943f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1946f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsUninitializedField
1947f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
1948f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsTailField : public BitField<bool, IsUninitializedField::kNext, 1> {};
1949f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsPossiblyEvalField : public BitField<bool, IsTailField::kNext, 1> {};
1950f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot ic_slot_;
1952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
1953a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Expression*>* arguments_;
1954b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  Handle<JSFunction> target_;
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site_;
195644f0eee88ff00398ff7f715fab053374d808c90dSteve Block};
195744f0eee88ff00398ff7f715fab053374d808c90dSteve Block
195844f0eee88ff00398ff7f715fab053374d808c90dSteve Block
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CallNew final : public Expression {
1960a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
19613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expression* expression() const { return expression_; }
19623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* arguments() const { return arguments_; }
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Type feedback information.
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
1968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache) {
1969f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // CallNew stores feedback in the exact same way as Call. We can
1970f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    // piggyback on the type feedback infrastructure for calls.
1971f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    callnew_feedback_slot_ = spec->AddCallICSlot();
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  FeedbackVectorSlot CallNewFeedbackSlot() {
1975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!callnew_feedback_slot_.IsInvalid());
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return callnew_feedback_slot_;
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
19783ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1979f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool IsMonomorphic() const { return IsMonomorphicField::decode(bit_field_); }
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<JSFunction> target() const { return target_; }
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site() const {
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return allocation_site_;
1983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
19843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  static int feedback_slots() { return 1; }
1987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
19883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_allocation_site(Handle<AllocationSite> site) {
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocation_site_ = site;
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1992f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_is_monomorphic(bool monomorphic) {
1993f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = IsMonomorphicField::update(bit_field_, monomorphic);
1994f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_target(Handle<JSFunction> target) { target_ = target; }
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void SetKnownGlobalTarget(Handle<JSFunction> target) {
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    target_ = target;
1998f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    set_is_monomorphic(true);
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallNew(Expression* expression, ZoneList<Expression*>* arguments, int pos)
2005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kCallNew),
20063fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        expression_(expression),
2007f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        arguments_(arguments) {
2008f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= IsMonomorphicField::encode(false);
2009f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return Expression::num_ids(); }
2012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot callnew_feedback_slot_;
2015a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
2016a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Expression*>* arguments_;
20173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Handle<JSFunction> target_;
2018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site_;
2019f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2020f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsMonomorphicField
2021f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2022a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2023a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2024a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2025a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// The CallRuntime class does not represent any official JavaScript
2026a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// language construct. Instead it is used to call a C or JS function
2027a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// with a set of arguments. This is used from the builtins that are
2028a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// implemented in JavaScript (see "v8natives.js").
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CallRuntime final : public Expression {
2030a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
20313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ZoneList<Expression*>* arguments() const { return arguments_; }
20323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool is_jsruntime() const { return function_ == NULL; }
20333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int context_index() const {
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(is_jsruntime());
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return context_index_;
2037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2038f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_context_index(int index) {
2039f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    DCHECK(is_jsruntime());
2040f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    context_index_ = index;
2041f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const Runtime::Function* function() const {
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!is_jsruntime());
2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return function_;
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2047958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId CallId() { return BailoutId(local_id(0)); }
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const char* debug_name() {
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return is_jsruntime() ? "(context function)" : function_->name;
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2054f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2055f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2057f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallRuntime(const Runtime::Function* function,
2058f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch              ZoneList<Expression*>* arguments, int pos)
2059f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kCallRuntime),
2060f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        function_(function),
2061f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        arguments_(arguments) {}
2062f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CallRuntime(int context_index, ZoneList<Expression*>* arguments, int pos)
2063f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kCallRuntime),
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        context_index_(context_index),
2065f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        function_(NULL),
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        arguments_(arguments) {}
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int parent_num_ids() { return Expression::num_ids(); }
2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int context_index_;
2072f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const Runtime::Function* function_;
2073a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  ZoneList<Expression*>* arguments_;
2074a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2075a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2076a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass UnaryOperation final : public Expression {
2078a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2079f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value op() const { return OperatorField::decode(bit_field_); }
20805d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch  Expression* expression() const { return expression_; }
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
20825d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // For unary not (Token::NOT), the AST ids where true and false will
2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // actually be materialized, respectively.
2085958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
2086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
2087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
20883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2089f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
20903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2092f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  UnaryOperation(Token::Value op, Expression* expression, int pos)
2095f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : Expression(pos, kUnaryOperation), expression_(expression) {
2096f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= OperatorField::encode(op);
2097b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsUnaryOp(op));
20983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
20993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2100f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2101958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2103a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* expression_;
2104f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2105f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class OperatorField
2106f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
2107a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2108a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2109a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass BinaryOperation final : public Expression {
2111a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2112f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value op() const { return OperatorField::decode(bit_field_); }
2113a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* left() const { return left_; }
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_left(Expression* e) { left_ = e; }
2115a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* right() const { return right_; }
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_right(Expression* e) { right_ = e; }
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site() const { return allocation_site_; }
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_allocation_site(Handle<AllocationSite> allocation_site) {
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_site_ = allocation_site;
2120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2121a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void MarkTail() {
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (op()) {
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::COMMA:
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::AND:
2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case Token::OR:
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        right_->MarkTail();
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      default:
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // The short-circuit logical operations need an AST ID for their
2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // right-hand subexpression.
2135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
2136958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId RightId() const { return BailoutId(local_id(0)); }
2137b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // BinaryOperation will have both a slot in the feedback vector and the
2139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // TypeFeedbackId to record the type information. TypeFeedbackId is used
2140f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // by full codegen and the feedback vector slot is used by interpreter.
2141f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2142f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
2143f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot BinaryOperationFeedbackSlot() const {
2145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return type_feedback_slot_;
2146f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2147f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId BinaryOperationFeedbackId() const {
2149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return TypeFeedbackId(local_id(1));
2150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Maybe<int> fixed_right_arg() const {
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return has_fixed_right_arg_ ? Just(fixed_right_arg_value_) : Nothing<int>();
2153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_fixed_right_arg(Maybe<int> arg) {
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    has_fixed_right_arg_ = arg.IsJust();
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (arg.IsJust()) fixed_right_arg_value_ = arg.FromJust();
2157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2159f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
21603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2161f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2162f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2164f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BinaryOperation(Token::Value op, Expression* left, Expression* right, int pos)
2165f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kBinaryOperation),
2166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        has_fixed_right_arg_(false),
2167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        fixed_right_arg_value_(0),
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        left_(left),
2169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        right_(right) {
2170f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= OperatorField::encode(op);
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsBinaryOp(op));
21723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
21733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(rossberg): the fixed arg should probably be represented as a Constant
2178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // type for the RHS. Currenty it's actually a Maybe<int>
2179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool has_fixed_right_arg_;
2180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int fixed_right_arg_value_;
2181a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* left_;
2182a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* right_;
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<AllocationSite> allocation_site_;
2184f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot type_feedback_slot_;
2185f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2186f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class OperatorField
2187f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
2188a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2189a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2190a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CountOperation final : public Expression {
219280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen public:
2193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
2194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool is_postfix() const { return !is_prefix(); }
219580d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
2196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Token::Value op() const { return TokenField::decode(bit_field_); }
2197e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  Token::Value binary_op() {
219880d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen    return (op() == Token::INC) ? Token::ADD : Token::SUB;
2199e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  }
220080d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
22018b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Expression* expression() const { return expression_; }
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
2203a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2204f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsMonomorphic() const { return receiver_types_.length() == 1; }
2205f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SmallMapList* GetReceiverTypes() { return &receiver_types_; }
2206f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
2207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  KeyedAccessStoreMode GetStoreMode() const {
2208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return StoreModeField::decode(bit_field_);
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2210f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* type() const { return type_; }
2211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_key_type(IcCheckType type) {
2212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = KeyTypeField::update(bit_field_, type);
2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_store_mode(KeyedAccessStoreMode mode) {
2215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = StoreModeField::update(bit_field_, mode);
2216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2217f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_type(AstType* type) { type_ = type; }
2218a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids() + 4; }
2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BailoutId ToNumberId() const { return BailoutId(local_id(1)); }
2222958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId CountBinOpFeedbackId() const {
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return TypeFeedbackId(local_id(2));
2224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId CountStoreFeedbackId() const {
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return TypeFeedbackId(local_id(3));
2227958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2228b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Feedback slot for binary operation is only used by ignition.
2230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot CountBinaryOpFeedbackSlot() const {
2231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return binary_operation_slot_;
2232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot CountSlot() const { return slot_; }
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2238f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2239f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2240f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2241f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CountOperation(Token::Value op, bool is_prefix, Expression* expr, int pos)
2242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : Expression(pos, kCountOperation), type_(NULL), expression_(expr) {
2243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |=
2244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IsPrefixField::encode(is_prefix) | KeyTypeField::encode(ELEMENT) |
2245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        StoreModeField::encode(STANDARD_STORE) | TokenField::encode(op);
2246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2248f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2251f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsPrefixField
2252f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2253f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class KeyTypeField : public BitField<IcCheckType, IsPrefixField::kNext, 1> {};
2254f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class StoreModeField
2255f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
2256f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
2257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot slot_;
2259f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot binary_operation_slot_;
2260f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* type_;
22618b112d2025046f85ef7f6be087c6129c872ebad2Ben Murdoch  Expression* expression_;
226269a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SmallMapList receiver_types_;
2263a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2264a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2265a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass CompareOperation final : public Expression {
2267a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2268f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Token::Value op() const { return OperatorField::decode(bit_field_); }
226985b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Expression* left() const { return left_; }
227085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  Expression* right() const { return right_; }
227185b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_left(Expression* e) { left_ = e; }
2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_right(Expression* e) { right_ = e; }
2274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
227585b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // Type feedback information.
2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 1; }
2277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId CompareOperationFeedbackId() const {
2278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return TypeFeedbackId(local_id(0));
2279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2280f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* combined_type() const { return combined_type_; }
2281f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_combined_type(AstType* type) { combined_type_ = type; }
2282f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2283f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // CompareOperation will have both a slot in the feedback vector and the
2284f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // TypeFeedbackId to record the type information. TypeFeedbackId is used
2285f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  // by full codegen and the feedback vector slot is used by interpreter.
2286f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2287f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                 FeedbackVectorSlotCache* cache);
2288f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2289f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot CompareOperationFeedbackSlot() const {
2290f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return type_feedback_slot_;
2291f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
229285b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
229385b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  // Match special cases.
229485b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch  bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
22953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  bool IsLiteralCompareUndefined(Expression** expr);
22963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  bool IsLiteralCompareNull(Expression** expr);
22973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2299f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2300f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2301f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  CompareOperation(Token::Value op, Expression* left, Expression* right,
2302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                   int pos)
2303f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kCompareOperation),
23043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        left_(left),
23053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        right_(right),
2306f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        combined_type_(AstType::None()) {
2307f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= OperatorField::encode(op);
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Token::IsCompareOp(op));
23093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
231085b71799222b55eb5dd74ea26efe0c64ab655c8cBen Murdoch
2311f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2314a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* left_;
2315a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* right_;
2316b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2317f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  AstType* combined_type_;
2318f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FeedbackVectorSlot type_feedback_slot_;
2319f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class OperatorField
2320f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<Token::Value, Expression::kNextBitFieldIndex, 7> {};
232180d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen};
232280d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
232380d68eab642096c1a48b6474d6ec33064b0ad1f5Kristian Monsen
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Spread final : public Expression {
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* expression() const { return expression_; }
2327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
2328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2329109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int expression_position() const { return expr_pos_; }
2330109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids(); }
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:
2334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2335f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2336f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Spread(Expression* expression, int pos, int expr_pos)
2337f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kSpread),
2338f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        expr_pos_(expr_pos),
2339f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        expression_(expression) {}
2340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2344109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  int expr_pos_;
2345f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Expression* expression_;
2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Conditional final : public Expression {
23505d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch public:
23513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expression* condition() const { return condition_; }
23523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expression* then_expression() const { return then_expression_; }
23533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Expression* else_expression() const { return else_expression_; }
23545d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_condition(Expression* e) { condition_ = e; }
2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_then_expression(Expression* e) { then_expression_ = e; }
2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_else_expression(Expression* e) { else_expression_ = e; }
2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2359f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void MarkTail() {
2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    then_expression_->MarkTail();
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    else_expression_->MarkTail();
2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
2365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ThenId() const { return BailoutId(local_id(0)); }
2366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId ElseId() const { return BailoutId(local_id(1)); }
23675d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2368f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2369f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2370f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2371f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Conditional(Expression* condition, Expression* then_expression,
2372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              Expression* else_expression, int position)
2373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(position, kConditional),
23743fb3ca8c7ca439d408449a395897395c0faae8d1Ben Murdoch        condition_(condition),
2375a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block        then_expression_(then_expression),
2376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        else_expression_(else_expression) {}
23777f4d5bd8c03935e2c0cd412e561b8fc5a6a880aeBen Murdoch
2378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2381a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* condition_;
2382a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* then_expression_;
2383a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* else_expression_;
2384a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2385a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2386a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Assignment final : public Expression {
2388a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
23896ded16be15dd865a9b21ea304d5273c8be299c87Steve Block  Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
23906ded16be15dd865a9b21ea304d5273c8be299c87Steve Block
2391a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Token::Value binary_op() const;
2392a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  Token::Value op() const { return TokenField::decode(bit_field_); }
2394a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* target() const { return target_; }
2395a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* value() const { return value_; }
2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_target(Expression* e) { target_ = e; }
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_value(Expression* e) { value_ = e; }
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2400b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  BinaryOperation* binary_operation() const { return binary_operation_; }
2401b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2402e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  // This check relies on the definition order of token in token.h.
2403e46be819fca9468a0cd4e74859ce0f778eb8ca60Leon Clarke  bool is_compound() const { return op() > Token::ASSIGN; }
2404a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2405958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  static int num_ids() { return parent_num_ids() + 2; }
2406958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2407a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2408b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  // Type feedback information.
2409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool IsUninitialized() const {
2411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsUninitializedField::decode(bit_field_);
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool HasNoTypeInformation() {
2414958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return IsUninitializedField::decode(bit_field_);
2415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2416f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsMonomorphic() const { return receiver_types_.length() == 1; }
2417f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SmallMapList* GetReceiverTypes() { return &receiver_types_; }
2418f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  IcCheckType GetKeyType() const { return KeyTypeField::decode(bit_field_); }
2419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  KeyedAccessStoreMode GetStoreMode() const {
2420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return StoreModeField::decode(bit_field_);
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_is_uninitialized(bool b) {
2423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = IsUninitializedField::update(bit_field_, b);
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_key_type(IcCheckType key_type) {
2426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = KeyTypeField::update(bit_field_, key_type);
2427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void set_store_mode(KeyedAccessStoreMode mode) {
2429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    bit_field_ = StoreModeField::update(bit_field_, mode);
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2431b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2433f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FeedbackVectorSlot AssignmentSlot() const { return slot_; }
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2436a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2437f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2438f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2439f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Assignment(Token::Value op, Expression* target, Expression* value, int pos);
2440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2441f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2444f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsUninitializedField
2445f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class KeyTypeField
2447f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<IcCheckType, IsUninitializedField::kNext, 1> {};
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class StoreModeField
2449f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<KeyedAccessStoreMode, KeyTypeField::kNext, 3> {};
2450f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class TokenField : public BitField<Token::Value, StoreModeField::kNext, 7> {};
2451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot slot_;
2453a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* target_;
2454a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* value_;
2455b0fe1620dcb4135ac3ab2d66ff93072373911299Ben Murdoch  BinaryOperation* binary_operation_;
245669a99ed0b2b2ef69d393c371b03db3a98aaf880eBen Murdoch  SmallMapList receiver_types_;
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// The RewritableExpression class is a wrapper for AST nodes that wait
2461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// for some potential rewriting.  However, even if such nodes are indeed
2462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// rewritten, the RewritableExpression wrapper nodes will survive in the
2463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// final AST and should be just ignored, i.e., they should be treated as
2464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// equivalent to the wrapped nodes.  For this reason and to simplify later
2465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// phases, RewritableExpressions are considered as exceptions of AST nodes
2466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// in the following sense:
2467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch//
2468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// 1. IsRewritableExpression and AsRewritableExpression behave as usual.
2469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// 2. All other Is* and As* methods are practically delegated to the
2470109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch//    wrapped node, i.e. IsArrayLiteral() will return true iff the
2471109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch//    wrapped node is an array literal.
2472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch//
2473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Furthermore, an invariant that should be respected is that the wrapped
2474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// node is not a RewritableExpression.
2475f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochclass RewritableExpression final : public Expression {
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:
2477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Expression* expression() const { return expr_; }
2478f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_rewritten() const { return IsRewrittenField::decode(bit_field_); }
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void Rewrite(Expression* new_expression) {
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!is_rewritten());
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(new_expression);
2483109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!new_expression->IsRewritableExpression());
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    expr_ = new_expression;
2485f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = IsRewrittenField::update(bit_field_, true);
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int num_ids() { return parent_num_ids(); }
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2490f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2491f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2492f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2493f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit RewritableExpression(Expression* expression)
2494f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(expression->position(), kRewritableExpression),
2495109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        expr_(expression) {
2496f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= IsRewrittenField::encode(false);
2497109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!expression->IsRewritableExpression());
2498109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* expr_;
2503f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2504f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsRewrittenField
2505f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, Expression::kNextBitFieldIndex, 1> {};
2506a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2507a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
25083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// Our Yield is different from the JS yield in that it "returns" its argument as
25093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// is, without wrapping it in an iterator result object.  Such wrapping, if
25103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch// desired, must be done beforehand (see the parser).
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Yield final : public Expression {
2512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2513f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  enum OnException { kOnExceptionThrow, kOnExceptionRethrow };
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* generator_object() const { return generator_object_; }
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* expression() const { return expression_; }
2517f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  OnException on_exception() const {
2518f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return OnExceptionField::decode(bit_field_);
2519f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2520f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool rethrow_on_exception() const {
2521f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return on_exception() == kOnExceptionRethrow;
2522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2523bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int yield_id() const { return yield_id_; }
2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_generator_object(Expression* e) { generator_object_ = e; }
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_expression(Expression* e) { expression_ = e; }
2527bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_yield_id(int yield_id) { yield_id_ = yield_id; }
2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2531f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2532f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Yield(Expression* generator_object, Expression* expression, int pos,
2533f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        OnException on_exception)
2534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kYield),
2535f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        yield_id_(-1),
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        generator_object_(generator_object),
2537f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        expression_(expression) {
2538f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |= OnExceptionField::encode(on_exception);
2539f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2541f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int yield_id_;
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* generator_object_;
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* expression_;
2544f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2545f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class OnExceptionField
2546f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<OnException, Expression::kNextBitFieldIndex, 1> {};
2547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass Throw final : public Expression {
2551a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2552a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* exception() const { return exception_; }
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_exception(Expression* e) { exception_ = e; }
25543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2555a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2556f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2557f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2558f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Throw(Expression* exception, int pos)
2559f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kThrow), exception_(exception) {}
2560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2561a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  Expression* exception_;
2562a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2563a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2564a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass FunctionLiteral final : public Expression {
2566a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  enum FunctionType {
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kAnonymousExpression,
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kNamedExpression,
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    kDeclaration,
2571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    kAccessorOrMethod
25723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  };
25733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum ParameterFlag { kNoDuplicateParameters, kHasDuplicateParameters };
2575a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  enum EagerCompileHint { kShouldEagerCompile, kShouldLazyCompile };
2577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> name() const { return raw_name_->string(); }
2579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const AstString* raw_name() const { return raw_name_; }
2580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_raw_name(const AstString* name) { raw_name_ = name; }
2581f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* scope() const { return scope_; }
25820d5e116f6aee03185f237311a943491bb079a768Kristian Monsen  ZoneList<Statement*>* body() const { return body_; }
2583a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_function_token_position(int pos) { function_token_position_ = pos; }
2584a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int function_token_position() const { return function_token_position_; }
25853ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int start_position() const;
25863ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int end_position() const;
25873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int SourceSize() const { return end_position() - start_position(); }
2588bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  bool is_declaration() const { return function_type() == kDeclaration; }
2589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_named_expression() const {
2590bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return function_type() == kNamedExpression;
2591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool is_anonymous_expression() const {
2593bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    return function_type() == kAnonymousExpression;
2594109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LanguageMode language_mode() const;
2596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static bool NeedsHomeObject(Expression* expr);
2598a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2599a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int materialized_literal_count() { return materialized_literal_count_; }
2600a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int expected_property_count() { return expected_property_count_; }
26013ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int parameter_count() { return parameter_count_; }
2602c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int function_length() { return function_length_; }
2603a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2604a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  bool AllowsLazyCompilation();
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2606f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  Handle<String> debug_name() const {
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return raw_name_->string();
2609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2610f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch    return inferred_name();
2611f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch  }
2612f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> inferred_name() const {
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!inferred_name_.is_null()) {
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(raw_inferred_name_ == NULL);
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return inferred_name_;
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (raw_inferred_name_ != NULL) {
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return raw_inferred_name_->string();
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
2622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return Handle<String>();
2623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2626a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  void set_inferred_name(Handle<String> inferred_name) {
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!inferred_name.is_null());
2628a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block    inferred_name_ = inferred_name;
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    raw_inferred_name_ = NULL;
2631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_raw_inferred_name(const AstString* raw_inferred_name) {
2634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(raw_inferred_name != NULL);
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    raw_inferred_name_ = raw_inferred_name;
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(inferred_name_.is_null());
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    inferred_name_ = Handle<String>();
2638a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2639a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2640f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool pretenure() const { return Pretenure::decode(bit_field_); }
2641f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_pretenure() { bit_field_ = Pretenure::update(bit_field_, true); }
26423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool has_duplicate_parameters() const {
2644f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return HasDuplicateParameters::decode(bit_field_);
26453ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
26463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2647f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_function() const { return IsFunction::decode(bit_field_); }
26483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This is used as a heuristic on when to eagerly compile a function
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // literal. We consider the following constructs as hints that the
2651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // function will be called immediately:
2652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - (function() { ... })();
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // - var x = function() { ... }();
2654c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool ShouldEagerCompile() const;
2655c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void SetShouldEagerCompile();
2656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // A hint that we expect this function to be called (exactly) once,
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // i.e. we suspect it's an initialization function.
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool should_be_used_once_hint() const {
2660f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return ShouldNotBeUsedOnceHintField::decode(bit_field_);
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_should_be_used_once_hint() {
2663f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = ShouldNotBeUsedOnceHintField::update(bit_field_, true);
2664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2666bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  FunctionType function_type() const {
2667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return FunctionTypeBits::decode(bit_field_);
2668bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  }
2669f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  FunctionKind kind() const;
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
26713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int ast_node_count() { return ast_properties_.node_count(); }
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstProperties::Flags flags() const { return ast_properties_.flags(); }
26733ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  void set_ast_properties(AstProperties* ast_properties) {
26743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch    ast_properties_ = *ast_properties;
26753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const FeedbackVectorSpec* feedback_vector_spec() const {
2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return ast_properties_.get_spec();
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2679f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool dont_optimize() { return dont_optimize_reason() != kNoReason; }
2680f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  BailoutReason dont_optimize_reason() {
2681f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return DontOptimizeReasonField::decode(bit_field_);
2682f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  void set_dont_optimize_reason(BailoutReason reason) {
2684f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ = DontOptimizeReasonField::update(bit_field_, reason);
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
26865d4cdbf7a67d3662fa0bee4efdb7edd8daec9b0bBen Murdoch
2687f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  bool IsAnonymousFunctionDefinition() const {
2688109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return is_anonymous_expression();
2689109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
2690109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2691bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int yield_count() { return yield_count_; }
2692bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  void set_yield_count(int yield_count) { yield_count_ = yield_count; }
2693bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch
2694f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool requires_class_field_init() {
2695f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return RequiresClassFieldInit::decode(bit_field_);
2696f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2697f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_requires_class_field_init(bool requires_class_field_init) {
2698f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ =
2699f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        RequiresClassFieldInit::update(bit_field_, requires_class_field_init);
2700f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2701f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_class_field_initializer() {
2702f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return IsClassFieldInitializer::decode(bit_field_);
2703f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2704f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_is_class_field_initializer(bool is_class_field_initializer) {
2705f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ =
2706f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IsClassFieldInitializer::update(bit_field_, is_class_field_initializer);
2707f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2708f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2709c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int return_position() {
2710c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return std::max(start_position(), end_position() - (has_braces_ ? 1 : 0));
2711c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2712c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2713f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2714f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2715f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionLiteral(Zone* zone, const AstString* name,
2717f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                  AstValueFactory* ast_value_factory, DeclarationScope* scope,
2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                  ZoneList<Statement*>* body, int materialized_literal_count,
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  int expected_property_count, int parameter_count,
2720c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                  int function_length, FunctionType function_type,
27213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                  ParameterFlag has_duplicate_parameters,
2722f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                  EagerCompileHint eager_compile_hint, int position,
2723c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                  bool is_function, bool has_braces)
2724f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(position, kFunctionLiteral),
27253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        materialized_literal_count_(materialized_literal_count),
27263ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        expected_property_count_(expected_property_count),
27273ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch        parameter_count_(parameter_count),
2728c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        function_length_(function_length),
2729f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        function_token_position_(kNoSourcePosition),
2730f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        yield_count_(0),
2731c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        has_braces_(has_braces),
2732f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        raw_name_(name),
2733f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        scope_(scope),
2734f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        body_(body),
2735f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        raw_inferred_name_(ast_value_factory->empty_string()),
2736f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ast_properties_(zone) {
2737f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    bit_field_ |=
2738bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        FunctionTypeBits::encode(function_type) | Pretenure::encode(false) |
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        HasDuplicateParameters::encode(has_duplicate_parameters ==
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       kHasDuplicateParameters) |
2741109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        IsFunction::encode(is_function) |
2742f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        RequiresClassFieldInit::encode(false) |
2743f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ShouldNotBeUsedOnceHintField::encode(false) |
2744f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        DontOptimizeReasonField::encode(kNoReason) |
2745f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        IsClassFieldInitializer::encode(false);
2746c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (eager_compile_hint == kShouldEagerCompile) SetShouldEagerCompile();
2747f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2748f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2749f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class FunctionTypeBits
2750f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<FunctionType, Expression::kNextBitFieldIndex, 2> {};
2751f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class Pretenure : public BitField<bool, FunctionTypeBits::kNext, 1> {};
2752f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class HasDuplicateParameters : public BitField<bool, Pretenure::kNext, 1> {};
2753f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsFunction : public BitField<bool, HasDuplicateParameters::kNext, 1> {};
2754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class ShouldNotBeUsedOnceHintField
2755c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      : public BitField<bool, IsFunction::kNext, 1> {};
2756f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class RequiresClassFieldInit
2757f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, ShouldNotBeUsedOnceHintField::kNext, 1> {};
2758f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class IsClassFieldInitializer
2759f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<bool, RequiresClassFieldInit::kNext, 1> {};
2760f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  class DontOptimizeReasonField
2761f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      : public BitField<BailoutReason, IsClassFieldInitializer::kNext, 8> {};
27623ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2763a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int materialized_literal_count_;
2764a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int expected_property_count_;
27653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  int parameter_count_;
2766c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int function_length_;
2767a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  int function_token_position_;
2768bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  int yield_count_;
2769c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool has_braces_;
2770f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2771f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const AstString* raw_name_;
2772f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  DeclarationScope* scope_;
2773f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ZoneList<Statement*>* body_;
2774f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  const AstString* raw_inferred_name_;
2775f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Handle<String> inferred_name_;
2776f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  AstProperties ast_properties_;
2777a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2778a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2779f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// Property is used for passing information
2780f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch// about a class literal's properties from the parser to the code generator.
2781f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochclass ClassLiteralProperty final : public LiteralProperty {
2782f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch public:
2783f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  enum Kind : uint8_t { METHOD, GETTER, SETTER, FIELD };
2784f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2785f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Kind kind() const { return kind_; }
2786f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2787f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_static() const { return is_static_; }
2788f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2789f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch private:
2790f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  friend class AstNodeFactory;
2791f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2792f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ClassLiteralProperty(Expression* key, Expression* value, Kind kind,
2793f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                       bool is_static, bool is_computed_name);
2794f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2795f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  Kind kind_;
2796f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  bool is_static_;
2797f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch};
2798a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ClassLiteral final : public Expression {
2800a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2801f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  typedef ClassLiteralProperty Property;
2802f87a203d89e1bbb6708282e0b64dbd13d59b723dBen Murdoch
2803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VariableProxy* class_variable_proxy() const { return class_variable_proxy_; }
2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* extends() const { return extends_; }
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_extends(Expression* e) { extends_ = e; }
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionLiteral* constructor() const { return constructor_; }
2807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_constructor(FunctionLiteral* f) { constructor_ = f; }
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Property*>* properties() const { return properties_; }
2809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int start_position() const { return position(); }
2810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int end_position() const { return end_position_; }
28113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
2812f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  VariableProxy* static_initializer_proxy() const {
2813f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return static_initializer_proxy_;
2814f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2815f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  void set_static_initializer_proxy(VariableProxy* proxy) {
2816f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    static_initializer_proxy_ = proxy;
2817f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
2818f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
2819f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }
2820f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId PrototypeId() { return BailoutId(local_id(1)); }
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Return an AST id for a property that is used in simulate instructions.
2823f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  BailoutId GetIdForProperty(int i) { return BailoutId(local_id(i + 2)); }
2824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Unlike other AST nodes, this number of bailout IDs allocated for an
2826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // ClassLiteral can vary, so num_ids() is not a static method.
2827f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int num_ids() const { return parent_num_ids() + 2 + properties()->length(); }
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Object literals need one feedback slot for each non-trivial value, as well
2830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // as some slots for home objects.
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void AssignFeedbackVectorSlots(Isolate* isolate, FeedbackVectorSpec* spec,
2832f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                 FeedbackVectorSlotCache* cache);
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool NeedsProxySlot() const {
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return class_variable_proxy() != nullptr &&
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           class_variable_proxy()->var()->IsUnallocated();
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2839109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FeedbackVectorSlot PrototypeSlot() const { return prototype_slot_; }
2840109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FeedbackVectorSlot ProxySlot() const { return proxy_slot_; }
2841109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
2842f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2843f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2845f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ClassLiteral(VariableProxy* class_variable_proxy, Expression* extends,
2846f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               FunctionLiteral* constructor, ZoneList<Property*>* properties,
2847f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch               int start_position, int end_position)
2848f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(start_position, kClassLiteral),
2849f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        end_position_(end_position),
2850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        class_variable_proxy_(class_variable_proxy),
2851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        extends_(extends),
2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        constructor_(constructor),
2853f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        properties_(properties),
2854f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        static_initializer_proxy_(nullptr) {}
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  static int parent_num_ids() { return Expression::num_ids(); }
2857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2859f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int end_position_;
2860f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot prototype_slot_;
2861f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  FeedbackVectorSlot proxy_slot_;
2862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  VariableProxy* class_variable_proxy_;
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Expression* extends_;
2864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  FunctionLiteral* constructor_;
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ZoneList<Property*>* properties_;
2866f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  VariableProxy* static_initializer_proxy_;
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass NativeFunctionLiteral final : public Expression {
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Handle<String> name() const { return name_->string(); }
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Extension* extension() const { return extension_; }
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2875a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2876f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2877f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2878f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  NativeFunctionLiteral(const AstRawString* name, v8::Extension* extension,
2879f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                        int pos)
2880f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kNativeFunctionLiteral),
2881f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        name_(name),
2882f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        extension_(extension) {}
2883f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  const AstRawString* name_;
2885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  v8::Extension* extension_;
2886a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2887a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2888a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass ThisFunction final : public Expression {
2890f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2891f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2892f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit ThisFunction(int pos) : Expression(pos, kThisFunction) {}
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SuperPropertyReference final : public Expression {
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch public:
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* this_var() const { return this_var_; }
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_this_var(VariableProxy* v) { this_var_ = v; }
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* home_object() const { return home_object_; }
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_home_object(Expression* e) { home_object_ = e; }
2902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2903f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2904f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2905f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2906f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SuperPropertyReference(VariableProxy* this_var, Expression* home_object,
2907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                         int pos)
2908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kSuperPropertyReference),
2909f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        this_var_(this_var),
2910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        home_object_(home_object) {
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(this_var->is_this());
2912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(home_object->IsProperty());
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* this_var_;
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Expression* home_object_;
2917a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2918a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2919a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass SuperCallReference final : public Expression {
2921a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* this_var() const { return this_var_; }
2923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_this_var(VariableProxy* v) { this_var_ = v; }
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* new_target_var() const { return new_target_var_; }
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_new_target_var(VariableProxy* v) { new_target_var_ = v; }
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* this_function_var() const { return this_function_var_; }
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void set_this_function_var(VariableProxy* v) { this_function_var_ = v; }
2928a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2929f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
2930f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2931f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2932f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  SuperCallReference(VariableProxy* this_var, VariableProxy* new_target_var,
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     VariableProxy* this_function_var, int pos)
2934f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : Expression(pos, kSuperCallReference),
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        this_var_(this_var),
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new_target_var_(new_target_var),
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        this_function_var_(this_function_var) {
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(this_var->is_this());
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(new_target_var->raw_name()->IsOneByteEqualTo(".new.target"));
2940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(this_function_var->raw_name()->IsOneByteEqualTo(".this_function"));
2941a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block  }
2942a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* this_var_;
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* new_target_var_;
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VariableProxy* this_function_var_;
2946a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block};
2947a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2948a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// This class is produced when parsing the () in arrow functions without any
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// arguments and is not actually a valid expression.
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass EmptyParentheses final : public Expression {
2952a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block private:
2953f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  friend class AstNodeFactory;
2954a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2955f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  explicit EmptyParentheses(int pos) : Expression(pos, kEmptyParentheses) {}
2956f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch};
2957a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
29583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
29593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
29603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ----------------------------------------------------------------------------
2961a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block// Basic visitor
2962f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch// Sub-class should parametrize AstVisitor with itself, e.g.:
2963f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch//   class SpecificVisitor : public AstVisitor<SpecificVisitor> { ... }
2964a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2965f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdochtemplate <class Subclass>
2966a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Blockclass AstVisitor BASE_EMBEDDED {
2967a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block public:
2968f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Visit(AstNode* node) { impl()->Visit(node); }
2969f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
2970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  void VisitDeclarations(Declaration::List* declarations) {
2971c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    for (Declaration* decl : *declarations) Visit(decl);
2972f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2973a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2974f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void VisitStatements(ZoneList<Statement*>* statements) {
2975f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (int i = 0; i < statements->length(); i++) {
2976f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Statement* stmt = statements->at(i);
2977f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Visit(stmt);
2978f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (stmt->IsJump()) break;
2979f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2980f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2981a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2982f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void VisitExpressions(ZoneList<Expression*>* expressions) {
2983f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    for (int i = 0; i < expressions->length(); i++) {
2984f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // The variable statement visiting code may pass NULL expressions
2985f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // to this code. Maybe this should be handled by introducing an
2986f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // undefined expression or literal?  Revisit this code if this
2987f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      // changes
2988f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      Expression* expression = expressions->at(i);
2989f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      if (expression != NULL) Visit(expression);
2990f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
2991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
2992a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2993f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch protected:
2994f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Subclass* impl() { return static_cast<Subclass*>(this); }
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch};
2996a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
2997f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define GENERATE_VISIT_CASE(NodeType)                                   \
2998f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  case AstNode::k##NodeType:                                            \
2999f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return this->impl()->Visit##NodeType(static_cast<NodeType*>(node));
3000f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3001f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define GENERATE_AST_VISITOR_SWITCH()  \
3002f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  switch (node->node_type()) {         \
3003f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    AST_NODE_LIST(GENERATE_VISIT_CASE) \
3004f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3005f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()               \
3007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:                                                    \
3008f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void VisitNoStackOverflowCheck(AstNode* node) {           \
3009f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    GENERATE_AST_VISITOR_SWITCH()                           \
3010f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }                                                         \
3011f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                            \
3012f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Visit(AstNode* node) {                               \
3013f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (CheckStackOverflow()) return;                       \
3014f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    VisitNoStackOverflowCheck(node);                        \
3015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                         \
3016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                            \
3017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void SetStackOverflow() { stack_overflow_ = true; }       \
3018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void ClearStackOverflow() { stack_overflow_ = false; }    \
3019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool HasStackOverflow() const { return stack_overflow_; } \
3020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                            \
3021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool CheckStackOverflow() {                               \
3022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (stack_overflow_) return true;                       \
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (GetCurrentStackPosition() < stack_limit_) {         \
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      stack_overflow_ = true;                               \
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;                                          \
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }                                                       \
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;                                           \
3028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                         \
3029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                            \
3030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:                                                   \
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InitializeAstVisitor(Isolate* isolate) {             \
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    stack_limit_ = isolate->stack_guard()->real_climit();   \
3033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    stack_overflow_ = false;                                \
3034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }                                                         \
3035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                                            \
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InitializeAstVisitor(uintptr_t stack_limit) {        \
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    stack_limit_ = stack_limit;                             \
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    stack_overflow_ = false;                                \
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                         \
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                            \
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  uintptr_t stack_limit_;                                   \
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool stack_overflow_
3043a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3044f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch#define DEFINE_AST_VISITOR_MEMBERS_WITHOUT_STACKOVERFLOW()    \
3045f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch public:                                                      \
3046f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void Visit(AstNode* node) { GENERATE_AST_VISITOR_SWITCH() } \
3047f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                              \
3048f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch private:
3049f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define DEFINE_AST_REWRITER_SUBCLASS_MEMBERS()        \
3051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch public:                                              \
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstNode* Rewrite(AstNode* node) {                   \
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NULL(replacement_);                        \
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(node);                            \
3055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Visit(node);                                      \
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (HasStackOverflow()) return node;              \
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (replacement_ == nullptr) return node;         \
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AstNode* result = replacement_;                   \
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    replacement_ = nullptr;                           \
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return result;                                    \
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                   \
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                      \
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch private:                                             \
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InitializeAstRewriter(Isolate* isolate) {      \
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InitializeAstVisitor(isolate);                    \
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    replacement_ = nullptr;                           \
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                   \
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                      \
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  void InitializeAstRewriter(uintptr_t stack_limit) { \
3070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InitializeAstVisitor(stack_limit);                \
3071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    replacement_ = nullptr;                           \
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }                                                   \
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                      \
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DEFINE_AST_VISITOR_SUBCLASS_MEMBERS();              \
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                      \
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch protected:                                           \
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstNode* replacement_
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Generic macro for rewriting things; `GET` is the expression to be
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// rewritten; `SET` is a command that should do the rewriting, i.e.
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// something sensible with the variable called `replacement`.
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AST_REWRITE(Type, GET, SET)                            \
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                         \
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!HasStackOverflow());                               \
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NULL(replacement_);                                 \
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Visit(GET);                                                \
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (HasStackOverflow()) return;                            \
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (replacement_ == nullptr) break;                        \
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Type* replacement = reinterpret_cast<Type*>(replacement_); \
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    do {                                                       \
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SET;                                                     \
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } while (false);                                           \
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    replacement_ = nullptr;                                    \
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Macro for rewriting object properties; it assumes that `object` has
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// `property` with a public getter and setter.
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AST_REWRITE_PROPERTY(Type, object, property)                        \
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                                      \
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto _obj = (object);                                                   \
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AST_REWRITE(Type, _obj->property(), _obj->set_##property(replacement)); \
3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// Macro for rewriting list elements; it assumes that `list` has methods
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// `at` and `Set`.
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define AST_REWRITE_LIST_ELEMENT(Type, list, index)                        \
3106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                                                     \
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto _list = (list);                                                   \
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    auto _index = (index);                                                 \
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AST_REWRITE(Type, _list->at(_index), _list->Set(_index, replacement)); \
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
311244f0eee88ff00398ff7f715fab053374d808c90dSteve Block
31133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// ----------------------------------------------------------------------------
31143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch// AstNode factory
31153ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochclass AstNodeFactory final BASE_EMBEDDED {
31173ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch public:
3118958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit AstNodeFactory(AstValueFactory* ast_value_factory)
3119f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      : zone_(nullptr), ast_value_factory_(ast_value_factory) {
3120f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    if (ast_value_factory != nullptr) {
3121f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      zone_ = ast_value_factory->zone();
3122f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    }
3123f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
31243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  AstValueFactory* ast_value_factory() const { return ast_value_factory_; }
3126f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_ast_value_factory(AstValueFactory* ast_value_factory) {
3127f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    ast_value_factory_ = ast_value_factory;
3128f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    zone_ = ast_value_factory->zone();
3129f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
3132f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              Scope* scope, int pos) {
3133f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) VariableDeclaration(proxy, scope, pos);
31343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
31363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
31373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                              FunctionLiteral* fun,
3138f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                              Scope* scope, int pos) {
3139f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) FunctionDeclaration(proxy, fun, scope, pos);
31403ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31413ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Block* NewBlock(ZoneList<const AstRawString*>* labels, int capacity,
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  bool ignore_completion_value, int pos) {
3144f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3145f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Block(zone_, labels, capacity, ignore_completion_value, pos);
31463ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#define STATEMENT_WITH_LABELS(NodeType)                                     \
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
3150f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) NodeType(labels, pos);                               \
31513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATEMENT_WITH_LABELS(DoWhileStatement)
31533ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATEMENT_WITH_LABELS(WhileStatement)
31543ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATEMENT_WITH_LABELS(ForStatement)
31553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  STATEMENT_WITH_LABELS(SwitchStatement)
31563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch#undef STATEMENT_WITH_LABELS
31573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        ZoneList<const AstRawString*>* labels,
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                        int pos) {
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (visit_mode) {
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ForEachStatement::ENUMERATE: {
3163f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return new (zone_) ForInStatement(labels, pos);
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case ForEachStatement::ITERATE: {
3166f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        return new (zone_) ForOfStatement(labels, pos);
3167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return NULL;
3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3174f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ExpressionStatement(expression, pos);
31753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31763ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3178f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ContinueStatement(target, pos);
31793ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31803ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3182f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) BreakStatement(target, pos);
31833ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31843ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3186f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ReturnStatement(expression, pos);
31873ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31883ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  WithStatement* NewWithStatement(Scope* scope,
3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Expression* expression,
3191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  Statement* statement,
3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                  int pos) {
3193f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) WithStatement(scope, expression, statement, pos);
31943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
31953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
31963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  IfStatement* NewIfStatement(Expression* condition,
31973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Statement* then_statement,
3198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              Statement* else_statement,
3199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int pos) {
3200f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3201f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        IfStatement(condition, then_statement, else_statement, pos);
32023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TryCatchStatement* NewTryCatchStatement(Block* try_block, Scope* scope,
32053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                          Variable* variable,
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          Block* catch_block, int pos) {
3207f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) TryCatchStatement(
3208f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        try_block, scope, variable, catch_block, HandlerTable::CAUGHT, pos);
32093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
32103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
32113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  TryCatchStatement* NewTryCatchStatementForReThrow(Block* try_block,
32123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                    Scope* scope,
32133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                    Variable* variable,
32143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                    Block* catch_block,
32153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                                    int pos) {
3216f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) TryCatchStatement(
3217f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        try_block, scope, variable, catch_block, HandlerTable::UNCAUGHT, pos);
3218f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3219f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3220f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TryCatchStatement* NewTryCatchStatementForPromiseReject(Block* try_block,
3221f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                          Scope* scope,
3222f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                          Variable* variable,
3223f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                          Block* catch_block,
3224f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                          int pos) {
3225f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) TryCatchStatement(
3226f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        try_block, scope, variable, catch_block, HandlerTable::PROMISE, pos);
3227f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3228f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3229f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  TryCatchStatement* NewTryCatchStatementForDesugaring(Block* try_block,
3230f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       Scope* scope,
3231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       Variable* variable,
3232f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       Block* catch_block,
3233f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                                       int pos) {
3234f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) TryCatchStatement(
3235f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        try_block, scope, variable, catch_block, HandlerTable::DESUGARING, pos);
32363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3238f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TryCatchStatement* NewTryCatchStatementForAsyncAwait(Block* try_block,
3239f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                       Scope* scope,
3240f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                       Variable* variable,
3241f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                       Block* catch_block,
3242f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                                       int pos) {
3243f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return new (zone_)
3244f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        TryCatchStatement(try_block, scope, variable, catch_block,
3245f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                          HandlerTable::ASYNC_AWAIT, pos);
3246f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3247f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TryFinallyStatement* NewTryFinallyStatement(Block* try_block,
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              Block* finally_block, int pos) {
3250f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) TryFinallyStatement(try_block, finally_block, pos);
32513ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32523ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DebuggerStatement* NewDebuggerStatement(int pos) {
3254f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) DebuggerStatement(pos);
32553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32563ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  EmptyStatement* NewEmptyStatement(int pos) {
3258f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) EmptyStatement(pos);
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3261f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SloppyBlockFunctionStatement* NewSloppyBlockFunctionStatement(Scope* scope) {
3262f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return new (zone_) SloppyBlockFunctionStatement(
3263f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        NewEmptyStatement(kNoSourcePosition), scope);
3264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CaseClause* NewCaseClause(
3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      Expression* label, ZoneList<Statement*>* statements, int pos) {
3268f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CaseClause(label, statements, pos);
3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewStringLiteral(const AstRawString* string, int pos) {
3272f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewString(string), pos);
3273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // A JavaScript symbol (ECMA-262 edition 6).
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewSymbolLiteral(const char* name, int pos) {
3277f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewSymbol(name), pos);
3278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Literal* NewNumberLiteral(double number, int pos, bool with_dot = false) {
3281f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3282f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Literal(ast_value_factory_->NewNumber(number, with_dot), pos);
3283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3285c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Literal* NewSmiLiteral(uint32_t number, int pos) {
3286f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewSmi(number), pos);
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewBooleanLiteral(bool b, int pos) {
3290f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewBoolean(b), pos);
3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewNullLiteral(int pos) {
3294f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewNull(), pos);
32953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
32963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewUndefinedLiteral(int pos) {
3298f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewUndefined(), pos);
32993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Literal* NewTheHoleLiteral(int pos) {
3302f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Literal(ast_value_factory_->NewTheHole(), pos);
33033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  ObjectLiteral* NewObjectLiteral(
3306f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ZoneList<ObjectLiteral::Property*>* properties, int literal_index,
3307f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      uint32_t boilerplate_properties, int pos) {
3308f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3309f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ObjectLiteral(properties, literal_index, boilerplate_properties, pos);
33103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectLiteral::Property* NewObjectLiteralProperty(
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Expression* key, Expression* value, ObjectLiteralProperty::Kind kind,
3314f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bool is_computed_name) {
3315f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3316f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ObjectLiteral::Property(key, value, kind, is_computed_name);
3317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ObjectLiteral::Property* NewObjectLiteralProperty(Expression* key,
3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    Expression* value,
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    bool is_computed_name) {
3322f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ObjectLiteral::Property(ast_value_factory_, key, value,
3323f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                               is_computed_name);
33243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33253ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern, int flags,
33273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                  int literal_index, int pos) {
3328f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) RegExpLiteral(pattern, flags, literal_index, pos);
33293ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33303ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
33323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                int literal_index,
3333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                int pos) {
3334f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ArrayLiteral(values, -1, literal_index, pos);
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                int first_spread_index, int literal_index,
33393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch                                int pos) {
3340f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3341f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        ArrayLiteral(values, first_spread_index, literal_index, pos);
33423ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33433ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* NewVariableProxy(Variable* var,
3345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  int start_position = kNoSourcePosition) {
3346c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return new (zone_) VariableProxy(var, start_position);
33473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  VariableProxy* NewVariableProxy(const AstRawString* name,
3350f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                  VariableKind variable_kind,
3351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  int start_position = kNoSourcePosition) {
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(name);
3353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return new (zone_) VariableProxy(name, variable_kind, start_position);
3354f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  }
3355f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
3356f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  // Recreates the VariableProxy in this Zone.
3357f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  VariableProxy* CopyVariableProxy(VariableProxy* proxy) {
3358f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) VariableProxy(proxy);
33593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33603ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33613ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Property* NewProperty(Expression* obj, Expression* key, int pos) {
3362f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Property(obj, key, pos);
33633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33643ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3365f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Call* NewCall(Expression* expression, ZoneList<Expression*>* arguments,
3366f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                int pos, Call::PossiblyEval possibly_eval = Call::NOT_EVAL) {
3367f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Call(expression, arguments, pos, possibly_eval);
33683ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33693ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33703ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CallNew* NewCallNew(Expression* expression,
33713ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      ZoneList<Expression*>* arguments,
33723ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                      int pos) {
3373f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CallNew(expression, arguments, pos);
33743ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33753ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallRuntime* NewCallRuntime(Runtime::FunctionId id,
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              ZoneList<Expression*>* arguments, int pos) {
3378f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CallRuntime(Runtime::FunctionForId(id), arguments, pos);
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallRuntime* NewCallRuntime(const Runtime::Function* function,
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              ZoneList<Expression*>* arguments, int pos) {
3383f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CallRuntime(function, arguments, pos);
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CallRuntime* NewCallRuntime(int context_index,
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              ZoneList<Expression*>* arguments, int pos) {
3388f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CallRuntime(context_index, arguments, pos);
33893ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33903ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33913ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  UnaryOperation* NewUnaryOperation(Token::Value op,
33923ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression* expression,
33933ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    int pos) {
3394f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) UnaryOperation(op, expression, pos);
33953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
33963ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
33973ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  BinaryOperation* NewBinaryOperation(Token::Value op,
33983ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression* left,
33993ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      Expression* right,
34003ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                      int pos) {
3401f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) BinaryOperation(op, left, right, pos);
34023ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34033ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34043ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CountOperation* NewCountOperation(Token::Value op,
34053ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    bool is_prefix,
34063ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    Expression* expr,
34073ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                    int pos) {
3408f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CountOperation(op, is_prefix, expr, pos);
34093ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34103ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34113ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  CompareOperation* NewCompareOperation(Token::Value op,
34123ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Expression* left,
34133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        Expression* right,
34143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                                        int pos) {
3415f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) CompareOperation(op, left, right, pos);
3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Spread* NewSpread(Expression* expression, int pos, int expr_pos) {
3419f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Spread(expression, pos, expr_pos);
34203ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34213ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34223ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Conditional* NewConditional(Expression* condition,
34233ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Expression* then_expression,
34243ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                              Expression* else_expression,
3425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                              int position) {
3426f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3427f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        Conditional(condition, then_expression, else_expression, position);
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  RewritableExpression* NewRewritableExpression(Expression* expression) {
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NOT_NULL(expression);
3432f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) RewritableExpression(expression);
34333ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34343ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34353ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Assignment* NewAssignment(Token::Value op,
34363ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Expression* target,
34373ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            Expression* value,
34383ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch                            int pos) {
3439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(Token::IsAssignmentOp(op));
3440f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    Assignment* assign = new (zone_) Assignment(op, target, value, pos);
3441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (assign->is_compound()) {
3442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(Token::IsAssignmentOp(op));
3443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      assign->binary_operation_ =
3444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          NewBinaryOperation(assign->binary_op(), target, value, pos + 1);
3445958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
3446958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return assign;
34473ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34483ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3449f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Yield* NewYield(Expression* generator_object, Expression* expression, int pos,
3450f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                  Yield::OnException on_exception) {
3451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!expression) expression = NewUndefinedLiteral(pos);
3452f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Yield(generator_object, expression, pos, on_exception);
3453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
34553ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  Throw* NewThrow(Expression* exception, int pos) {
3456f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) Throw(exception, pos);
34573ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
34593ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  FunctionLiteral* NewFunctionLiteral(
3460f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      const AstRawString* name, DeclarationScope* scope,
3461f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      ZoneList<Statement*>* body, int materialized_literal_count,
3462c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int expected_property_count, int parameter_count, int function_length,
34633ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch      FunctionLiteral::ParameterFlag has_duplicate_parameters,
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      FunctionLiteral::FunctionType function_type,
3465c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      FunctionLiteral::EagerCompileHint eager_compile_hint, int position,
3466c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      bool has_braces) {
3467c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return new (zone_) FunctionLiteral(
3468c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        zone_, name, ast_value_factory_, scope, body,
3469c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        materialized_literal_count, expected_property_count, parameter_count,
3470c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        function_length, function_type, has_duplicate_parameters,
3471c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        eager_compile_hint, position, true, has_braces);
3472109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3473109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3474109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Creates a FunctionLiteral representing a top-level script, the
3475109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // result of an eval (top-level or otherwise), or the result of calling
3476109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // the Function constructor.
3477109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  FunctionLiteral* NewScriptOrEvalFunctionLiteral(
3478f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      DeclarationScope* scope, ZoneList<Statement*>* body,
3479f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int materialized_literal_count, int expected_property_count,
3480f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      int parameter_count) {
3481f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) FunctionLiteral(
3482f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        zone_, ast_value_factory_->empty_string(), ast_value_factory_, scope,
3483f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        body, materialized_literal_count, expected_property_count,
3484c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        parameter_count, parameter_count, FunctionLiteral::kAnonymousExpression,
3485109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        FunctionLiteral::kNoDuplicateParameters,
3486c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        FunctionLiteral::kShouldLazyCompile, 0, false, true);
3487f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  }
3488f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch
3489f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  ClassLiteral::Property* NewClassLiteralProperty(
3490f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      Expression* key, Expression* value, ClassLiteralProperty::Kind kind,
3491f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      bool is_static, bool is_computed_name) {
3492f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    return new (zone_)
3493f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        ClassLiteral::Property(key, value, kind, is_static, is_computed_name);
34943ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
34953ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3496f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  ClassLiteral* NewClassLiteral(VariableProxy* proxy, Expression* extends,
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                FunctionLiteral* constructor,
3498f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                                ZoneList<ClassLiteral::Property*>* properties,
3499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                int start_position, int end_position) {
3500f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ClassLiteral(proxy, extends, constructor, properties,
3501f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                                    start_position, end_position);
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  v8::Extension* extension,
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                  int pos) {
3507f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) NativeFunctionLiteral(name, extension, pos);
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DoExpression* NewDoExpression(Block* block, Variable* result_var, int pos) {
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VariableProxy* result = NewVariableProxy(result_var, pos);
3512f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) DoExpression(block, result, pos);
35133ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
35143ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  ThisFunction* NewThisFunction(int pos) {
3516f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) ThisFunction(pos);
3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SuperPropertyReference* NewSuperPropertyReference(VariableProxy* this_var,
3520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    Expression* home_object,
3521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                    int pos) {
3522f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) SuperPropertyReference(this_var, home_object, pos);
3523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SuperCallReference* NewSuperCallReference(VariableProxy* this_var,
3526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            VariableProxy* new_target_var,
3527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            VariableProxy* this_function_var,
3528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            int pos) {
3529f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_)
3530f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        SuperCallReference(this_var, new_target_var, this_function_var, pos);
35313ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch  }
35323ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  EmptyParentheses* NewEmptyParentheses(int pos) {
3534f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    return new (zone_) EmptyParentheses(pos);
3535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3537f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Zone* zone() const { return zone_; }
3538f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  void set_zone(Zone* zone) { zone_ = zone; }
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handles use of temporary zones when parsing inner function bodies.
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  class BodyScope {
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   public:
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BodyScope(AstNodeFactory* factory, Zone* temp_zone, bool use_temp_zone)
3544f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        : factory_(factory), prev_zone_(factory->zone_) {
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (use_temp_zone) {
3546f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        factory->zone_ = temp_zone;
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3550f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    void Reset() { factory_->zone_ = prev_zone_; }
3551f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    ~BodyScope() { Reset(); }
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch   private:
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    AstNodeFactory* factory_;
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Zone* prev_zone_;
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  };
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35583ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch private:
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // This zone may be deallocated upon returning from parsing a function body
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // which we can guarantee is not going to be compiled or have its AST
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // inspected.
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // See ParseFunctionLiteral in parser.cc for preconditions.
3563f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  Zone* zone_;
3564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AstValueFactory* ast_value_factory_;
35653ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch};
35663ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
35673ef787dbeca8a5fb1086949cda830dccee07bfbdBen Murdoch
3568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Type testing & conversion functions overridden by concrete subclasses.
3569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch// Inline functions for AstNode.
3570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#define DECLARE_NODE_FUNCTIONS(type)                                          \
3572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool AstNode::Is##type() const {                                            \
3573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    NodeType mine = node_type();                                              \
3574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (mine == AstNode::kRewritableExpression &&                             \
3575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        AstNode::k##type != AstNode::kRewritableExpression)                   \
3576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      mine = reinterpret_cast<const RewritableExpression*>(this)              \
3577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 ->expression()                                               \
3578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 ->node_type();                                               \
3579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return mine == AstNode::k##type;                                          \
3580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }                                                                           \
3581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  type* AstNode::As##type() {                                                 \
3582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    NodeType mine = node_type();                                              \
3583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    AstNode* result = this;                                                   \
3584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (mine == AstNode::kRewritableExpression &&                             \
3585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        AstNode::k##type != AstNode::kRewritableExpression) {                 \
3586109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      result =                                                                \
3587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          reinterpret_cast<const RewritableExpression*>(this)->expression();  \
3588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      mine = result->node_type();                                             \
3589109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }                                                                         \
3590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return mine == AstNode::k##type ? reinterpret_cast<type*>(result) : NULL; \
3591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }                                                                           \
3592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const type* AstNode::As##type() const {                                     \
3593109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    NodeType mine = node_type();                                              \
3594109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    const AstNode* result = this;                                             \
3595109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (mine == AstNode::kRewritableExpression &&                             \
3596109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        AstNode::k##type != AstNode::kRewritableExpression) {                 \
3597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      result =                                                                \
3598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          reinterpret_cast<const RewritableExpression*>(this)->expression();  \
3599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      mine = result->node_type();                                             \
3600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }                                                                         \
3601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return mine == AstNode::k##type ? reinterpret_cast<const type*>(result)   \
3602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                    : NULL;                                   \
3603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3604109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben MurdochAST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
3605109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch#undef DECLARE_NODE_FUNCTIONS
3606109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3607109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace internal
3609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace v8
3610a7e24c173cf37484693b9abb38e494fa7bd7baebSteve Block
3611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif  // V8_AST_AST_H_
3612