blob: 03f43ad0a7aa4f8261c349da0244099e491bcf9d [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_AST_H_
6#define V8_AST_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/v8.h"
Ben Murdoch3ef787d2012-04-12 10:51:47 +01009
Ben Murdochb8a8cc12014-11-26 15:28:44 +000010#include "src/assembler.h"
11#include "src/ast-value-factory.h"
12#include "src/bailout-reason.h"
13#include "src/factory.h"
14#include "src/feedback-slots.h"
15#include "src/interface.h"
16#include "src/isolate.h"
17#include "src/jsregexp.h"
18#include "src/list-inl.h"
19#include "src/runtime.h"
20#include "src/small-pointer-list.h"
21#include "src/smart-pointers.h"
22#include "src/token.h"
23#include "src/types.h"
24#include "src/utils.h"
25#include "src/variables.h"
26#include "src/zone-inl.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000027
28namespace v8 {
29namespace internal {
30
31// The abstract syntax tree is an intermediate, light-weight
32// representation of the parsed JavaScript code suitable for
33// compilation to native code.
34
35// Nodes are allocated in a separate zone, which allows faster
36// allocation and constant-time deallocation of the entire syntax
37// tree.
38
39
40// ----------------------------------------------------------------------------
41// Nodes of the abstract syntax tree. Only concrete classes are
42// enumerated here.
43
Ben Murdochb8a8cc12014-11-26 15:28:44 +000044#define DECLARATION_NODE_LIST(V) \
45 V(VariableDeclaration) \
46 V(FunctionDeclaration) \
47 V(ModuleDeclaration) \
48 V(ImportDeclaration) \
49 V(ExportDeclaration)
Ben Murdoch3ef787d2012-04-12 10:51:47 +010050
51#define MODULE_NODE_LIST(V) \
52 V(ModuleLiteral) \
53 V(ModuleVariable) \
54 V(ModulePath) \
55 V(ModuleUrl)
56
Steve Blocka7e24c12009-10-30 11:49:00 +000057#define STATEMENT_NODE_LIST(V) \
58 V(Block) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000059 V(ModuleStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000060 V(ExpressionStatement) \
61 V(EmptyStatement) \
62 V(IfStatement) \
63 V(ContinueStatement) \
64 V(BreakStatement) \
65 V(ReturnStatement) \
Ben Murdoch69a99ed2011-11-30 16:03:39 +000066 V(WithStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000067 V(SwitchStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000068 V(DoWhileStatement) \
69 V(WhileStatement) \
70 V(ForStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000071 V(ForInStatement) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +000072 V(ForOfStatement) \
Steve Block3ce2e202009-11-05 08:53:23 +000073 V(TryCatchStatement) \
74 V(TryFinallyStatement) \
Steve Blocka7e24c12009-10-30 11:49:00 +000075 V(DebuggerStatement)
76
Ben Murdochb8a8cc12014-11-26 15:28:44 +000077#define EXPRESSION_NODE_LIST(V) \
78 V(FunctionLiteral) \
79 V(ClassLiteral) \
80 V(NativeFunctionLiteral) \
81 V(Conditional) \
82 V(VariableProxy) \
83 V(Literal) \
84 V(RegExpLiteral) \
85 V(ObjectLiteral) \
86 V(ArrayLiteral) \
87 V(Assignment) \
88 V(Yield) \
89 V(Throw) \
90 V(Property) \
91 V(Call) \
92 V(CallNew) \
93 V(CallRuntime) \
94 V(UnaryOperation) \
95 V(CountOperation) \
96 V(BinaryOperation) \
97 V(CompareOperation) \
98 V(ThisFunction) \
99 V(SuperReference) \
100 V(CaseClause)
Steve Blocka7e24c12009-10-30 11:49:00 +0000101
102#define AST_NODE_LIST(V) \
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100103 DECLARATION_NODE_LIST(V) \
104 MODULE_NODE_LIST(V) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000105 STATEMENT_NODE_LIST(V) \
106 EXPRESSION_NODE_LIST(V)
107
108// Forward declarations
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100109class AstConstructionVisitor;
110template<class> class AstNodeFactory;
111class AstVisitor;
112class Declaration;
113class Module;
114class BreakableStatement;
115class Expression;
116class IterationStatement;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100117class MaterializedLiteral;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000118class OStream;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100119class Statement;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100120class TargetCollector;
121class TypeFeedbackOracle;
Steve Blocka7e24c12009-10-30 11:49:00 +0000122
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100123class RegExpAlternative;
124class RegExpAssertion;
125class RegExpAtom;
126class RegExpBackReference;
127class RegExpCapture;
128class RegExpCharacterClass;
129class RegExpCompiler;
130class RegExpDisjunction;
131class RegExpEmpty;
132class RegExpLookahead;
133class RegExpQuantifier;
134class RegExpText;
135
Steve Blocka7e24c12009-10-30 11:49:00 +0000136#define DEF_FORWARD_DECLARATION(type) class type;
137AST_NODE_LIST(DEF_FORWARD_DECLARATION)
138#undef DEF_FORWARD_DECLARATION
139
140
141// Typedef only introduced to avoid unreadable code.
142// Please do appreciate the required space in "> >".
143typedef ZoneList<Handle<String> > ZoneStringList;
144typedef ZoneList<Handle<Object> > ZoneObjectList;
145
146
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000147#define DECLARE_NODE_TYPE(type) \
148 virtual void Accept(AstVisitor* v) OVERRIDE; \
149 virtual AstNode::NodeType node_type() const FINAL OVERRIDE { \
150 return AstNode::k##type; \
151 } \
152 template<class> friend class AstNodeFactory;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100153
154
155enum AstPropertiesFlag {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100156 kDontSelfOptimize,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 kDontSoftInline,
158 kDontCache
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100159};
160
161
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000162class AstProperties FINAL BASE_EMBEDDED {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100163 public:
164 class Flags : public EnumSet<AstPropertiesFlag, int> {};
165
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166AstProperties() : node_count_(0), feedback_slots_(0) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100167
168 Flags* flags() { return &flags_; }
169 int node_count() { return node_count_; }
170 void add_node_count(int count) { node_count_ += count; }
171
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000172 int feedback_slots() const { return feedback_slots_; }
173 void increase_feedback_slots(int count) {
174 feedback_slots_ += count;
175 }
176
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100177 private:
178 Flags flags_;
179 int node_count_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 int feedback_slots_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100181};
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100182
183
Steve Blocka7e24c12009-10-30 11:49:00 +0000184class AstNode: public ZoneObject {
185 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000186 // For generating IDs for AstNodes.
187 class IdGen {
188 public:
189 explicit IdGen(int id = 0) : id_(id) {}
190
191 int GetNextId() { return ReserveIdRange(1); }
192 int ReserveIdRange(int n) {
193 int tmp = id_;
194 id_ += n;
195 return tmp;
196 }
197
198 private:
199 int id_;
200 };
201
Ben Murdochf87a2032010-10-22 12:50:53 +0100202#define DECLARE_TYPE_ENUM(type) k##type,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203 enum NodeType {
Ben Murdochf87a2032010-10-22 12:50:53 +0100204 AST_NODE_LIST(DECLARE_TYPE_ENUM)
205 kInvalid = -1
206 };
207#undef DECLARE_TYPE_ENUM
Steve Blocka7e24c12009-10-30 11:49:00 +0000208
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000209 void* operator new(size_t size, Zone* zone) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000210 return zone->New(static_cast<int>(size));
Steve Block44f0eee2011-05-26 01:26:41 +0100211 }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100212
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000213 explicit AstNode(int position): position_(position) {}
214 virtual ~AstNode() {}
Ben Murdochf87a2032010-10-22 12:50:53 +0100215
216 virtual void Accept(AstVisitor* v) = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000217 virtual NodeType node_type() const = 0;
218 int position() const { return position_; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100219
220 // Type testing & conversion functions overridden by concrete subclasses.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000221#define DECLARE_NODE_FUNCTIONS(type) \
222 bool Is##type() const { return node_type() == AstNode::k##type; } \
223 type* As##type() { \
224 return Is##type() ? reinterpret_cast<type*>(this) : NULL; \
225 } \
226 const type* As##type() const { \
227 return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
228 }
Ben Murdochf87a2032010-10-22 12:50:53 +0100229 AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
230#undef DECLARE_NODE_FUNCTIONS
231
Steve Blocka7e24c12009-10-30 11:49:00 +0000232 virtual TargetCollector* AsTargetCollector() { return NULL; }
233 virtual BreakableStatement* AsBreakableStatement() { return NULL; }
234 virtual IterationStatement* AsIterationStatement() { return NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000235 virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100236
Ben Murdochb0fe1622011-05-05 13:52:32 +0100237 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238 // Some nodes re-use bailout IDs for type feedback.
239 static TypeFeedbackId reuse(BailoutId id) {
240 return TypeFeedbackId(id.ToInt());
Steve Block44f0eee2011-05-26 01:26:41 +0100241 }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000242
Ben Murdochb0fe1622011-05-05 13:52:32 +0100243
244 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000245 // Hidden to prevent accidental usage. It would have to load the
246 // current zone from the TLS.
247 void* operator new(size_t size);
Steve Block44f0eee2011-05-26 01:26:41 +0100248
249 friend class CaseClause; // Generates AST IDs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250
251 int position_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000252};
253
254
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000255class Statement : public AstNode {
Steve Blocka7e24c12009-10-30 11:49:00 +0000256 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 explicit Statement(Zone* zone, int position) : AstNode(position) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000258
259 bool IsEmpty() { return AsEmptyStatement() != NULL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000260 virtual bool IsJump() const { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000261};
262
263
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264class SmallMapList FINAL {
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000265 public:
266 SmallMapList() {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000267 SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000268
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000269 void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000270 void Clear() { list_.Clear(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 void Sort() { list_.Sort(); }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000272
273 bool is_empty() const { return list_.is_empty(); }
274 int length() const { return list_.length(); }
275
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000276 void AddMapIfMissing(Handle<Map> map, Zone* zone) {
277 if (!Map::TryUpdate(map).ToHandle(&map)) return;
278 for (int i = 0; i < length(); ++i) {
279 if (at(i).is_identical_to(map)) return;
280 }
281 Add(map, zone);
282 }
283
284 void FilterForPossibleTransitions(Map* root_map) {
285 for (int i = list_.length() - 1; i >= 0; i--) {
286 if (at(i)->FindRootMap() != root_map) {
287 list_.RemoveElement(list_.at(i));
288 }
289 }
290 }
291
292 void Add(Handle<Map> handle, Zone* zone) {
293 list_.Add(handle.location(), zone);
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000294 }
295
296 Handle<Map> at(int i) const {
297 return Handle<Map>(list_.at(i));
298 }
299
300 Handle<Map> first() const { return at(0); }
301 Handle<Map> last() const { return at(length() - 1); }
302
303 private:
304 // The list stores pointers to Map*, that is Map**, so it's GC safe.
305 SmallPointerList<Map*> list_;
306
307 DISALLOW_COPY_AND_ASSIGN(SmallMapList);
308};
309
310
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000311class Expression : public AstNode {
Steve Blocka7e24c12009-10-30 11:49:00 +0000312 public:
Ben Murdochb0fe1622011-05-05 13:52:32 +0100313 enum Context {
314 // Not assigned a context yet, or else will not be visited during
315 // code generation.
316 kUninitialized,
317 // Evaluated for its side effects.
318 kEffect,
319 // Evaluated for its value (and side effects).
320 kValue,
321 // Evaluated for control flow (and side effects).
322 kTest
323 };
324
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000325 virtual bool IsValidReferenceExpression() const { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000326
Ben Murdochb0fe1622011-05-05 13:52:32 +0100327 // Helpers for ToBoolean conversion.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000328 virtual bool ToBooleanIsTrue() const { return false; }
329 virtual bool ToBooleanIsFalse() const { return false; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100330
Leon Clarkee46be812010-01-19 14:06:41 +0000331 // Symbols that cannot be parsed as array indices are considered property
332 // names. We do not treat symbols that can be array indexes as property
333 // names because [] for string objects is handled only by keyed ICs.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000334 virtual bool IsPropertyName() const { return false; }
Leon Clarkee46be812010-01-19 14:06:41 +0000335
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100336 // True iff the result can be safely overwritten (to avoid allocation).
337 // False for operations that can return one of their operands.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000338 virtual bool ResultOverwriteAllowed() const { return false; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100339
340 // True iff the expression is a literal represented as a smi.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341 bool IsSmiLiteral() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100342
343 // True iff the expression is a string literal.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 bool IsStringLiteral() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100345
346 // True iff the expression is the null literal.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000347 bool IsNullLiteral() const;
348
349 // True if we can prove that the expression is the undefined literal.
350 bool IsUndefinedLiteral(Isolate* isolate) const;
351
352 // Expression type bounds
353 Bounds bounds() const { return bounds_; }
354 void set_bounds(Bounds bounds) { bounds_ = bounds; }
355
356 // Whether the expression is parenthesized
357 unsigned parenthesization_level() const { return parenthesization_level_; }
358 bool is_parenthesized() const { return parenthesization_level_ > 0; }
359 void increase_parenthesization_level() { ++parenthesization_level_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100360
Ben Murdochb0fe1622011-05-05 13:52:32 +0100361 // Type feedback information for assignments and properties.
362 virtual bool IsMonomorphic() {
363 UNREACHABLE();
364 return false;
365 }
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000366 virtual SmallMapList* GetReceiverTypes() {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100367 UNREACHABLE();
368 return NULL;
369 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000370 virtual KeyedAccessStoreMode GetStoreMode() {
371 UNREACHABLE();
372 return STANDARD_STORE;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100373 }
374
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375 // TODO(rossberg): this should move to its own AST node eventually.
376 virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
377 byte to_boolean_types() const { return to_boolean_types_; }
378
379 BailoutId id() const { return id_; }
380 TypeFeedbackId test_id() const { return test_id_; }
Andrei Popescu402d9372010-02-26 13:31:12 +0000381
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100382 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000383 Expression(Zone* zone, int pos, IdGen* id_gen)
384 : AstNode(pos),
385 bounds_(Bounds::Unbounded(zone)),
386 parenthesization_level_(0),
387 id_(id_gen->GetNextId()),
388 test_id_(id_gen->GetNextId()) {}
389 void set_to_boolean_types(byte types) { to_boolean_types_ = types; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100390
Steve Blocka7e24c12009-10-30 11:49:00 +0000391 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000392 Bounds bounds_;
393 byte to_boolean_types_;
394 unsigned parenthesization_level_;
395
396 const BailoutId id_;
397 const TypeFeedbackId test_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000398};
399
400
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000401class BreakableStatement : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000402 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000403 enum BreakableType {
Steve Blocka7e24c12009-10-30 11:49:00 +0000404 TARGET_FOR_ANONYMOUS,
405 TARGET_FOR_NAMED_ONLY
406 };
407
408 // The labels associated with this statement. May be NULL;
409 // if it is != NULL, guaranteed to contain at least one entry.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 ZoneList<const AstRawString*>* labels() const { return labels_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000411
412 // Type testing & conversion.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000413 virtual BreakableStatement* AsBreakableStatement() FINAL OVERRIDE {
414 return this;
415 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000416
417 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100418 Label* break_target() { return &break_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000419
420 // Testers.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000421 bool is_target_for_anonymous() const {
422 return breakable_type_ == TARGET_FOR_ANONYMOUS;
423 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000424
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 BailoutId EntryId() const { return entry_id_; }
426 BailoutId ExitId() const { return exit_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100427
Steve Blocka7e24c12009-10-30 11:49:00 +0000428 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000429 BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
430 BreakableType breakable_type, int position, IdGen* id_gen)
431 : Statement(zone, position),
432 labels_(labels),
433 breakable_type_(breakable_type),
434 entry_id_(id_gen->GetNextId()),
435 exit_id_(id_gen->GetNextId()) {
436 DCHECK(labels == NULL || labels->length() > 0);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100437 }
438
Steve Blocka7e24c12009-10-30 11:49:00 +0000439
440 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441 ZoneList<const AstRawString*>* labels_;
442 BreakableType breakable_type_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100443 Label break_target_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000444 const BailoutId entry_id_;
445 const BailoutId exit_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000446};
447
448
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449class Block FINAL : public BreakableStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000450 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100451 DECLARE_NODE_TYPE(Block)
452
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000453 void AddStatement(Statement* statement, Zone* zone) {
454 statements_.Add(statement, zone);
455 }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100456
457 ZoneList<Statement*>* statements() { return &statements_; }
458 bool is_initializer_block() const { return is_initializer_block_; }
459
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000460 BailoutId DeclsId() const { return decls_id_; }
461
462 virtual bool IsJump() const OVERRIDE {
463 return !statements_.is_empty() && statements_.last()->IsJump()
464 && labels() == NULL; // Good enough as an approximation...
465 }
466
467 Scope* scope() const { return scope_; }
468 void set_scope(Scope* scope) { scope_ = scope; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100469
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100470 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000471 Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
472 bool is_initializer_block, int pos, IdGen* id_gen)
473 : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos, id_gen),
474 statements_(capacity, zone),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100475 is_initializer_block_(is_initializer_block),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000476 decls_id_(id_gen->GetNextId()),
477 scope_(NULL) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100478
Steve Blocka7e24c12009-10-30 11:49:00 +0000479 private:
480 ZoneList<Statement*> statements_;
481 bool is_initializer_block_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000482 const BailoutId decls_id_;
483 Scope* scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000484};
485
486
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000487class Declaration : public AstNode {
Steve Blocka7e24c12009-10-30 11:49:00 +0000488 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100489 VariableProxy* proxy() const { return proxy_; }
490 VariableMode mode() const { return mode_; }
491 Scope* scope() const { return scope_; }
492 virtual InitializationFlag initialization() const = 0;
493 virtual bool IsInlineable() const;
494
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100495 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000496 Declaration(Zone* zone,
497 VariableProxy* proxy,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100498 VariableMode mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000499 Scope* scope,
500 int pos)
501 : AstNode(pos),
502 proxy_(proxy),
Steve Blocka7e24c12009-10-30 11:49:00 +0000503 mode_(mode),
Ben Murdoch589d6972011-11-30 16:04:58 +0000504 scope_(scope) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000505 DCHECK(IsDeclaredVariableMode(mode));
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 }
507
Steve Blocka7e24c12009-10-30 11:49:00 +0000508 private:
509 VariableProxy* proxy_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100510 VariableMode mode_;
Ben Murdoch589d6972011-11-30 16:04:58 +0000511
512 // Nested scope from which the declaration originated.
513 Scope* scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000514};
515
516
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000517class VariableDeclaration FINAL : public Declaration {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100518 public:
519 DECLARE_NODE_TYPE(VariableDeclaration)
520
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000521 virtual InitializationFlag initialization() const OVERRIDE {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100522 return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
523 }
524
525 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 VariableDeclaration(Zone* zone,
527 VariableProxy* proxy,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100528 VariableMode mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000529 Scope* scope,
530 int pos)
531 : Declaration(zone, proxy, mode, scope, pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100532 }
533};
534
535
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000536class FunctionDeclaration FINAL : public Declaration {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100537 public:
538 DECLARE_NODE_TYPE(FunctionDeclaration)
539
540 FunctionLiteral* fun() const { return fun_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000541 virtual InitializationFlag initialization() const OVERRIDE {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100542 return kCreatedInitialized;
543 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000544 virtual bool IsInlineable() const OVERRIDE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100545
546 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000547 FunctionDeclaration(Zone* zone,
548 VariableProxy* proxy,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100549 VariableMode mode,
550 FunctionLiteral* fun,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000551 Scope* scope,
552 int pos)
553 : Declaration(zone, proxy, mode, scope, pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100554 fun_(fun) {
555 // At the moment there are no "const functions" in JavaScript...
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000556 DCHECK(mode == VAR || mode == LET);
557 DCHECK(fun != NULL);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100558 }
559
560 private:
561 FunctionLiteral* fun_;
562};
563
564
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000565class ModuleDeclaration FINAL : public Declaration {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100566 public:
567 DECLARE_NODE_TYPE(ModuleDeclaration)
568
569 Module* module() const { return module_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570 virtual InitializationFlag initialization() const OVERRIDE {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100571 return kCreatedInitialized;
572 }
573
574 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000575 ModuleDeclaration(Zone* zone,
576 VariableProxy* proxy,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100577 Module* module,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 Scope* scope,
579 int pos)
580 : Declaration(zone, proxy, MODULE, scope, pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100581 module_(module) {
582 }
583
584 private:
585 Module* module_;
586};
587
588
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000589class ImportDeclaration FINAL : public Declaration {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100590 public:
591 DECLARE_NODE_TYPE(ImportDeclaration)
592
593 Module* module() const { return module_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000594 virtual InitializationFlag initialization() const OVERRIDE {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100595 return kCreatedInitialized;
596 }
597
598 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000599 ImportDeclaration(Zone* zone,
600 VariableProxy* proxy,
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100601 Module* module,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 Scope* scope,
603 int pos)
604 : Declaration(zone, proxy, LET, scope, pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100605 module_(module) {
606 }
607
608 private:
609 Module* module_;
610};
611
612
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000613class ExportDeclaration FINAL : public Declaration {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100614 public:
615 DECLARE_NODE_TYPE(ExportDeclaration)
616
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 virtual InitializationFlag initialization() const OVERRIDE {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100618 return kCreatedInitialized;
619 }
620
621 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000622 ExportDeclaration(Zone* zone, VariableProxy* proxy, Scope* scope, int pos)
623 : Declaration(zone, proxy, LET, scope, pos) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100624};
625
626
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000627class Module : public AstNode {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100628 public:
629 Interface* interface() const { return interface_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100630 Block* body() const { return body_; }
631
632 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000633 Module(Zone* zone, int pos)
634 : AstNode(pos),
635 interface_(Interface::NewModule(zone)),
636 body_(NULL) {}
637 Module(Zone* zone, Interface* interface, int pos, Block* body = NULL)
638 : AstNode(pos),
639 interface_(interface),
640 body_(body) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100641
642 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000643 Interface* interface_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100644 Block* body_;
645};
646
647
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648class ModuleLiteral FINAL : public Module {
649 public:
650 DECLARE_NODE_TYPE(ModuleLiteral)
651
652 protected:
653 ModuleLiteral(Zone* zone, Block* body, Interface* interface, int pos)
654 : Module(zone, interface, pos, body) {}
655};
656
657
658class ModuleVariable FINAL : public Module {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100659 public:
660 DECLARE_NODE_TYPE(ModuleVariable)
661
662 VariableProxy* proxy() const { return proxy_; }
663
664 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665 inline ModuleVariable(Zone* zone, VariableProxy* proxy, int pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100666
667 private:
668 VariableProxy* proxy_;
669};
670
671
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000672class ModulePath FINAL : public Module {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100673 public:
674 DECLARE_NODE_TYPE(ModulePath)
675
676 Module* module() const { return module_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 Handle<String> name() const { return name_->string(); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100678
679 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000680 ModulePath(Zone* zone, Module* module, const AstRawString* name, int pos)
681 : Module(zone, pos), module_(module), name_(name) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100682
683 private:
684 Module* module_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000685 const AstRawString* name_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100686};
687
688
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000689class ModuleUrl FINAL : public Module {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100690 public:
691 DECLARE_NODE_TYPE(ModuleUrl)
692
693 Handle<String> url() const { return url_; }
694
695 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000696 ModuleUrl(Zone* zone, Handle<String> url, int pos)
697 : Module(zone, pos), url_(url) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100698 }
699
700 private:
701 Handle<String> url_;
702};
703
704
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000705class ModuleStatement FINAL : public Statement {
706 public:
707 DECLARE_NODE_TYPE(ModuleStatement)
708
709 VariableProxy* proxy() const { return proxy_; }
710 Block* body() const { return body_; }
711
712 protected:
713 ModuleStatement(Zone* zone, VariableProxy* proxy, Block* body, int pos)
714 : Statement(zone, pos),
715 proxy_(proxy),
716 body_(body) {
717 }
718
719 private:
720 VariableProxy* proxy_;
721 Block* body_;
722};
723
724
725class IterationStatement : public BreakableStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000726 public:
727 // Type testing & conversion.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000728 virtual IterationStatement* AsIterationStatement() FINAL OVERRIDE {
729 return this;
730 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000731
732 Statement* body() const { return body_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100733
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000734 BailoutId OsrEntryId() const { return osr_entry_id_; }
735 virtual BailoutId ContinueId() const = 0;
736 virtual BailoutId StackCheckId() const = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +0000737
738 // Code generation
Ben Murdoch8b112d22011-06-08 16:22:53 +0100739 Label* continue_target() { return &continue_target_; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000740
741 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000742 IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
743 IdGen* id_gen)
744 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100745 body_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000746 osr_entry_id_(id_gen->GetNextId()) {}
Steve Blocka7e24c12009-10-30 11:49:00 +0000747
748 void Initialize(Statement* body) {
749 body_ = body;
750 }
751
752 private:
753 Statement* body_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100754 Label continue_target_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000755
756 const BailoutId osr_entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000757};
758
759
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760class DoWhileStatement FINAL : public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000761 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100762 DECLARE_NODE_TYPE(DoWhileStatement)
763
Steve Block3ce2e202009-11-05 08:53:23 +0000764 void Initialize(Expression* cond, Statement* body) {
765 IterationStatement::Initialize(body);
766 cond_ = cond;
767 }
768
Steve Block3ce2e202009-11-05 08:53:23 +0000769 Expression* cond() const { return cond_; }
770
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000771 virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; }
772 virtual BailoutId StackCheckId() const OVERRIDE { return back_edge_id_; }
773 BailoutId BackEdgeId() const { return back_edge_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100774
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100775 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000776 DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
777 IdGen* id_gen)
778 : IterationStatement(zone, labels, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100779 cond_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000780 continue_id_(id_gen->GetNextId()),
781 back_edge_id_(id_gen->GetNextId()) {}
Ben Murdoch8b112d22011-06-08 16:22:53 +0100782
Steve Block3ce2e202009-11-05 08:53:23 +0000783 private:
784 Expression* cond_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000785
786 const BailoutId continue_id_;
787 const BailoutId back_edge_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000788};
789
790
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000791class WhileStatement FINAL : public IterationStatement {
Steve Block3ce2e202009-11-05 08:53:23 +0000792 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100793 DECLARE_NODE_TYPE(WhileStatement)
794
Steve Block3ce2e202009-11-05 08:53:23 +0000795 void Initialize(Expression* cond, Statement* body) {
796 IterationStatement::Initialize(body);
797 cond_ = cond;
798 }
799
Steve Block3ce2e202009-11-05 08:53:23 +0000800 Expression* cond() const { return cond_; }
801 bool may_have_function_literal() const {
802 return may_have_function_literal_;
803 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100804 void set_may_have_function_literal(bool value) {
805 may_have_function_literal_ = value;
806 }
Steve Block3ce2e202009-11-05 08:53:23 +0000807
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808 virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
809 virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
810 BailoutId BodyId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100811
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100812 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000813 WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
814 IdGen* id_gen)
815 : IterationStatement(zone, labels, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100816 cond_(NULL),
817 may_have_function_literal_(true),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000818 body_id_(id_gen->GetNextId()) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100819
Steve Block3ce2e202009-11-05 08:53:23 +0000820 private:
821 Expression* cond_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822
Steve Block3ce2e202009-11-05 08:53:23 +0000823 // True if there is a function literal subexpression in the condition.
824 bool may_have_function_literal_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825
826 const BailoutId body_id_;
Steve Block3ce2e202009-11-05 08:53:23 +0000827};
828
829
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000830class ForStatement FINAL : public IterationStatement {
Steve Block3ce2e202009-11-05 08:53:23 +0000831 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100832 DECLARE_NODE_TYPE(ForStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +0000833
834 void Initialize(Statement* init,
835 Expression* cond,
836 Statement* next,
837 Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000838 IterationStatement::Initialize(body);
839 init_ = init;
840 cond_ = cond;
841 next_ = next;
842 }
843
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100844 Statement* init() const { return init_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100845 Expression* cond() const { return cond_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100846 Statement* next() const { return next_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100847
Steve Blocka7e24c12009-10-30 11:49:00 +0000848 bool may_have_function_literal() const {
849 return may_have_function_literal_;
850 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100851 void set_may_have_function_literal(bool value) {
852 may_have_function_literal_ = value;
853 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000854
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000855 virtual BailoutId ContinueId() const OVERRIDE { return continue_id_; }
856 virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
857 BailoutId BodyId() const { return body_id_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100858
Steve Block6ded16b2010-05-10 14:33:55 +0100859 bool is_fast_smi_loop() { return loop_variable_ != NULL; }
860 Variable* loop_variable() { return loop_variable_; }
861 void set_loop_variable(Variable* var) { loop_variable_ = var; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100862
863 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864 ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
865 IdGen* id_gen)
866 : IterationStatement(zone, labels, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100867 init_(NULL),
868 cond_(NULL),
869 next_(NULL),
870 may_have_function_literal_(true),
871 loop_variable_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000872 continue_id_(id_gen->GetNextId()),
873 body_id_(id_gen->GetNextId()) {}
Steve Block6ded16b2010-05-10 14:33:55 +0100874
Steve Blocka7e24c12009-10-30 11:49:00 +0000875 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000876 Statement* init_;
877 Expression* cond_;
878 Statement* next_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000879
Steve Blocka7e24c12009-10-30 11:49:00 +0000880 // True if there is a function literal subexpression in the condition.
881 bool may_have_function_literal_;
Steve Block6ded16b2010-05-10 14:33:55 +0100882 Variable* loop_variable_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000883
884 const BailoutId continue_id_;
885 const BailoutId body_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000886};
887
888
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889class ForEachStatement : public IterationStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +0000890 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 enum VisitMode {
892 ENUMERATE, // for (each in subject) body;
893 ITERATE // for (each of subject) body;
894 };
Ben Murdochf87a2032010-10-22 12:50:53 +0100895
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000896 void Initialize(Expression* each, Expression* subject, Statement* body) {
Steve Blocka7e24c12009-10-30 11:49:00 +0000897 IterationStatement::Initialize(body);
898 each_ = each;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899 subject_ = subject;
Steve Blocka7e24c12009-10-30 11:49:00 +0000900 }
901
Steve Blocka7e24c12009-10-30 11:49:00 +0000902 Expression* each() const { return each_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000903 Expression* subject() const { return subject_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100904
905 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000906 ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
907 IdGen* id_gen)
908 : IterationStatement(zone, labels, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100909 each_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910 subject_(NULL) {}
Ben Murdochb0fe1622011-05-05 13:52:32 +0100911
Steve Blocka7e24c12009-10-30 11:49:00 +0000912 private:
913 Expression* each_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000914 Expression* subject_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000915};
916
917
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000918class ForInStatement FINAL : public ForEachStatement,
919 public FeedbackSlotInterface {
920 public:
921 DECLARE_NODE_TYPE(ForInStatement)
922
923 Expression* enumerable() const {
924 return subject();
925 }
926
927 // Type feedback information.
928 virtual int ComputeFeedbackSlotCount() { return 1; }
929 virtual void SetFirstFeedbackSlot(int slot) { for_in_feedback_slot_ = slot; }
930
931 int ForInFeedbackSlot() {
932 DCHECK(for_in_feedback_slot_ != kInvalidFeedbackSlot);
933 return for_in_feedback_slot_;
934 }
935
936 enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
937 ForInType for_in_type() const { return for_in_type_; }
938 void set_for_in_type(ForInType type) { for_in_type_ = type; }
939
940 BailoutId BodyId() const { return body_id_; }
941 BailoutId PrepareId() const { return prepare_id_; }
942 virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
943 virtual BailoutId StackCheckId() const OVERRIDE { return body_id_; }
944
945 protected:
946 ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
947 IdGen* id_gen)
948 : ForEachStatement(zone, labels, pos, id_gen),
949 for_in_type_(SLOW_FOR_IN),
950 for_in_feedback_slot_(kInvalidFeedbackSlot),
951 body_id_(id_gen->GetNextId()),
952 prepare_id_(id_gen->GetNextId()) {}
953
954 ForInType for_in_type_;
955 int for_in_feedback_slot_;
956 const BailoutId body_id_;
957 const BailoutId prepare_id_;
958};
959
960
961class ForOfStatement FINAL : public ForEachStatement {
962 public:
963 DECLARE_NODE_TYPE(ForOfStatement)
964
965 void Initialize(Expression* each,
966 Expression* subject,
967 Statement* body,
968 Expression* assign_iterator,
969 Expression* next_result,
970 Expression* result_done,
971 Expression* assign_each) {
972 ForEachStatement::Initialize(each, subject, body);
973 assign_iterator_ = assign_iterator;
974 next_result_ = next_result;
975 result_done_ = result_done;
976 assign_each_ = assign_each;
977 }
978
979 Expression* iterable() const {
980 return subject();
981 }
982
983 // var iterator = subject[Symbol.iterator]();
984 Expression* assign_iterator() const {
985 return assign_iterator_;
986 }
987
988 // var result = iterator.next();
989 Expression* next_result() const {
990 return next_result_;
991 }
992
993 // result.done
994 Expression* result_done() const {
995 return result_done_;
996 }
997
998 // each = result.value
999 Expression* assign_each() const {
1000 return assign_each_;
1001 }
1002
1003 virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
1004 virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
1005
1006 BailoutId BackEdgeId() const { return back_edge_id_; }
1007
1008 protected:
1009 ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
1010 IdGen* id_gen)
1011 : ForEachStatement(zone, labels, pos, id_gen),
1012 assign_iterator_(NULL),
1013 next_result_(NULL),
1014 result_done_(NULL),
1015 assign_each_(NULL),
1016 back_edge_id_(id_gen->GetNextId()) {}
1017
1018 Expression* assign_iterator_;
1019 Expression* next_result_;
1020 Expression* result_done_;
1021 Expression* assign_each_;
1022 const BailoutId back_edge_id_;
1023};
1024
1025
1026class ExpressionStatement FINAL : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001027 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001028 DECLARE_NODE_TYPE(ExpressionStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001029
1030 void set_expression(Expression* e) { expression_ = e; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001031 Expression* expression() const { return expression_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001032 virtual bool IsJump() const OVERRIDE { return expression_->IsThrow(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001033
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001034 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001035 ExpressionStatement(Zone* zone, Expression* expression, int pos)
1036 : Statement(zone, pos), expression_(expression) { }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001037
Steve Blocka7e24c12009-10-30 11:49:00 +00001038 private:
1039 Expression* expression_;
1040};
1041
1042
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001043class JumpStatement : public Statement {
1044 public:
1045 virtual bool IsJump() const FINAL OVERRIDE { return true; }
1046
1047 protected:
1048 explicit JumpStatement(Zone* zone, int pos) : Statement(zone, pos) {}
1049};
1050
1051
1052class ContinueStatement FINAL : public JumpStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001053 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001054 DECLARE_NODE_TYPE(ContinueStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001055
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001056 IterationStatement* target() const { return target_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001057
1058 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059 explicit ContinueStatement(Zone* zone, IterationStatement* target, int pos)
1060 : JumpStatement(zone, pos), target_(target) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001061
1062 private:
1063 IterationStatement* target_;
1064};
1065
1066
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001067class BreakStatement FINAL : public JumpStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001068 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001069 DECLARE_NODE_TYPE(BreakStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001070
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001071 BreakableStatement* target() const { return target_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001072
1073 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001074 explicit BreakStatement(Zone* zone, BreakableStatement* target, int pos)
1075 : JumpStatement(zone, pos), target_(target) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001076
1077 private:
1078 BreakableStatement* target_;
1079};
1080
1081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082class ReturnStatement FINAL : public JumpStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001083 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001084 DECLARE_NODE_TYPE(ReturnStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001085
Ben Murdochb0fe1622011-05-05 13:52:32 +01001086 Expression* expression() const { return expression_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001087
1088 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001089 explicit ReturnStatement(Zone* zone, Expression* expression, int pos)
1090 : JumpStatement(zone, pos), expression_(expression) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001091
1092 private:
1093 Expression* expression_;
1094};
1095
1096
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001097class WithStatement FINAL : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001098 public:
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001099 DECLARE_NODE_TYPE(WithStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001100
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101 Scope* scope() { return scope_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001102 Expression* expression() const { return expression_; }
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001103 Statement* statement() const { return statement_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001104
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001105 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001106 WithStatement(
1107 Zone* zone, Scope* scope,
1108 Expression* expression, Statement* statement, int pos)
1109 : Statement(zone, pos),
1110 scope_(scope),
1111 expression_(expression),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001112 statement_(statement) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001113
1114 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001115 Scope* scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001116 Expression* expression_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001117 Statement* statement_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001118};
1119
1120
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001121class CaseClause FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001122 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001123 DECLARE_NODE_TYPE(CaseClause)
Steve Blocka7e24c12009-10-30 11:49:00 +00001124
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001125 bool is_default() const { return label_ == NULL; }
1126 Expression* label() const {
Steve Blocka7e24c12009-10-30 11:49:00 +00001127 CHECK(!is_default());
1128 return label_;
1129 }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001130 Label* body_target() { return &body_target_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001131 ZoneList<Statement*>* statements() const { return statements_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001132
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001133 BailoutId EntryId() const { return entry_id_; }
Steve Block44f0eee2011-05-26 01:26:41 +01001134
Ben Murdochb0fe1622011-05-05 13:52:32 +01001135 // Type feedback information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001136 TypeFeedbackId CompareId() { return compare_id_; }
1137 Type* compare_type() { return compare_type_; }
1138 void set_compare_type(Type* type) { compare_type_ = type; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001139
Steve Blocka7e24c12009-10-30 11:49:00 +00001140 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001141 CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
1142 int pos, IdGen* id_gen);
1143
Steve Blocka7e24c12009-10-30 11:49:00 +00001144 Expression* label_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001145 Label body_target_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001146 ZoneList<Statement*>* statements_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001147 Type* compare_type_;
1148
1149 const TypeFeedbackId compare_id_;
1150 const BailoutId entry_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001151};
1152
1153
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001154class SwitchStatement FINAL : public BreakableStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001155 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001156 DECLARE_NODE_TYPE(SwitchStatement)
1157
Steve Blocka7e24c12009-10-30 11:49:00 +00001158 void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
1159 tag_ = tag;
1160 cases_ = cases;
1161 }
1162
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001163 Expression* tag() const { return tag_; }
1164 ZoneList<CaseClause*>* cases() const { return cases_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001165
1166 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001167 SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos,
1168 IdGen* id_gen)
1169 : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001170 tag_(NULL),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001171 cases_(NULL) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001172
1173 private:
1174 Expression* tag_;
1175 ZoneList<CaseClause*>* cases_;
1176};
1177
1178
1179// If-statements always have non-null references to their then- and
1180// else-parts. When parsing if-statements with no explicit else-part,
1181// the parser implicitly creates an empty statement. Use the
1182// HasThenStatement() and HasElseStatement() functions to check if a
1183// given if-statement has a then- or an else-part containing code.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001184class IfStatement FINAL : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 public:
Ben Murdoch85b71792012-04-11 18:30:58 +01001186 DECLARE_NODE_TYPE(IfStatement)
1187
Ben Murdoch85b71792012-04-11 18:30:58 +01001188 bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
1189 bool HasElseStatement() const { return !else_statement()->IsEmpty(); }
1190
1191 Expression* condition() const { return condition_; }
1192 Statement* then_statement() const { return then_statement_; }
1193 Statement* else_statement() const { return else_statement_; }
1194
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001195 virtual bool IsJump() const OVERRIDE {
1196 return HasThenStatement() && then_statement()->IsJump()
1197 && HasElseStatement() && else_statement()->IsJump();
1198 }
1199
1200 BailoutId IfId() const { return if_id_; }
1201 BailoutId ThenId() const { return then_id_; }
1202 BailoutId ElseId() const { return else_id_; }
Ben Murdoch85b71792012-04-11 18:30:58 +01001203
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001204 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001205 IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
1206 Statement* else_statement, int pos, IdGen* id_gen)
1207 : Statement(zone, pos),
1208 condition_(condition),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001209 then_statement_(then_statement),
1210 else_statement_(else_statement),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001211 if_id_(id_gen->GetNextId()),
1212 then_id_(id_gen->GetNextId()),
1213 else_id_(id_gen->GetNextId()) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001214
Steve Blocka7e24c12009-10-30 11:49:00 +00001215 private:
1216 Expression* condition_;
1217 Statement* then_statement_;
1218 Statement* else_statement_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001219 const BailoutId if_id_;
1220 const BailoutId then_id_;
1221 const BailoutId else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001222};
1223
1224
1225// NOTE: TargetCollectors are represented as nodes to fit in the target
1226// stack in the compiler; this should probably be reworked.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001227class TargetCollector FINAL : public AstNode {
Steve Blocka7e24c12009-10-30 11:49:00 +00001228 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001229 explicit TargetCollector(Zone* zone)
1230 : AstNode(RelocInfo::kNoPosition), targets_(0, zone) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001231
1232 // Adds a jump target to the collector. The collector stores a pointer not
1233 // a copy of the target to make binding work, so make sure not to pass in
1234 // references to something on the stack.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001235 void AddTarget(Label* target, Zone* zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00001236
1237 // Virtual behaviour. TargetCollectors are never part of the AST.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001238 virtual void Accept(AstVisitor* v) OVERRIDE { UNREACHABLE(); }
1239 virtual NodeType node_type() const OVERRIDE { return kInvalid; }
1240 virtual TargetCollector* AsTargetCollector() OVERRIDE { return this; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001241
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001242 ZoneList<Label*>* targets() { return &targets_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001243
1244 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001245 ZoneList<Label*> targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001246};
1247
1248
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001249class TryStatement : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001250 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001251 void set_escaping_targets(ZoneList<Label*>* targets) {
Steve Blocka7e24c12009-10-30 11:49:00 +00001252 escaping_targets_ = targets;
1253 }
1254
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001255 int index() const { return index_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001256 Block* try_block() const { return try_block_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01001257 ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001258
1259 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001260 TryStatement(Zone* zone, int index, Block* try_block, int pos)
1261 : Statement(zone, pos),
1262 index_(index),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001263 try_block_(try_block),
1264 escaping_targets_(NULL) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001265
1266 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001267 // Unique (per-function) index of this handler. This is not an AST ID.
1268 int index_;
1269
Steve Blocka7e24c12009-10-30 11:49:00 +00001270 Block* try_block_;
Ben Murdoch8b112d22011-06-08 16:22:53 +01001271 ZoneList<Label*>* escaping_targets_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001272};
1273
1274
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001275class TryCatchStatement FINAL : public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001276 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001277 DECLARE_NODE_TYPE(TryCatchStatement)
1278
1279 Scope* scope() { return scope_; }
1280 Variable* variable() { return variable_; }
1281 Block* catch_block() const { return catch_block_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001282
1283 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001284 TryCatchStatement(Zone* zone,
1285 int index,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001286 Block* try_block,
1287 Scope* scope,
1288 Variable* variable,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001289 Block* catch_block,
1290 int pos)
1291 : TryStatement(zone, index, try_block, pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001292 scope_(scope),
1293 variable_(variable),
1294 catch_block_(catch_block) {
1295 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001296
Steve Blocka7e24c12009-10-30 11:49:00 +00001297 private:
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001298 Scope* scope_;
1299 Variable* variable_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001300 Block* catch_block_;
1301};
1302
1303
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001304class TryFinallyStatement FINAL : public TryStatement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001305 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001306 DECLARE_NODE_TYPE(TryFinallyStatement)
Steve Blocka7e24c12009-10-30 11:49:00 +00001307
1308 Block* finally_block() const { return finally_block_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001309
1310 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001311 TryFinallyStatement(
1312 Zone* zone, int index, Block* try_block, Block* finally_block, int pos)
1313 : TryStatement(zone, index, try_block, pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001314 finally_block_(finally_block) { }
Steve Blocka7e24c12009-10-30 11:49:00 +00001315
1316 private:
1317 Block* finally_block_;
1318};
1319
1320
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001321class DebuggerStatement FINAL : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001322 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001323 DECLARE_NODE_TYPE(DebuggerStatement)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001324
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001325 BailoutId DebugBreakId() const { return debugger_id_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001326
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001327 protected:
1328 explicit DebuggerStatement(Zone* zone, int pos, IdGen* id_gen)
1329 : Statement(zone, pos), debugger_id_(id_gen->GetNextId()) {}
1330
1331 private:
1332 const BailoutId debugger_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001333};
1334
1335
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001336class EmptyStatement FINAL : public Statement {
Steve Blocka7e24c12009-10-30 11:49:00 +00001337 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001338 DECLARE_NODE_TYPE(EmptyStatement)
Ben Murdochb0fe1622011-05-05 13:52:32 +01001339
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001340 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001341 explicit EmptyStatement(Zone* zone, int pos): Statement(zone, pos) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001342};
1343
1344
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001345class Literal FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001346 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001347 DECLARE_NODE_TYPE(Literal)
1348
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001349 virtual bool IsPropertyName() const OVERRIDE {
1350 return value_->IsPropertyName();
Leon Clarkee46be812010-01-19 14:06:41 +00001351 }
1352
Ben Murdochb0fe1622011-05-05 13:52:32 +01001353 Handle<String> AsPropertyName() {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001354 DCHECK(IsPropertyName());
1355 return Handle<String>::cast(value());
Ben Murdochb0fe1622011-05-05 13:52:32 +01001356 }
1357
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001358 const AstRawString* AsRawPropertyName() {
1359 DCHECK(IsPropertyName());
1360 return value_->AsString();
Steve Blocka7e24c12009-10-30 11:49:00 +00001361 }
1362
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001363 virtual bool ToBooleanIsTrue() const OVERRIDE {
1364 return value()->BooleanValue();
1365 }
1366 virtual bool ToBooleanIsFalse() const OVERRIDE {
1367 return !value()->BooleanValue();
1368 }
1369
1370 Handle<Object> value() const { return value_->value(); }
1371 const AstValue* raw_value() const { return value_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001372
1373 // Support for using Literal as a HashMap key. NOTE: Currently, this works
1374 // only for string and number literals!
1375 uint32_t Hash() { return ToString()->Hash(); }
1376
1377 static bool Match(void* literal1, void* literal2) {
1378 Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
1379 Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001380 return String::Equals(s1, s2);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001381 }
1382
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001383 TypeFeedbackId LiteralFeedbackId() const { return reuse(id()); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001384
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001385 protected:
1386 Literal(Zone* zone, const AstValue* value, int position, IdGen* id_gen)
1387 : Expression(zone, position, id_gen),
1388 value_(value),
1389 isolate_(zone->isolate()) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001390
1391 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001392 Handle<String> ToString();
1393
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001394 const AstValue* value_;
1395 // TODO(dcarney): remove. this is only needed for Match and Hash.
1396 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001397};
1398
1399
1400// Base class for literals that needs space in the corresponding JSFunction.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001401class MaterializedLiteral : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001402 public:
Steve Blocka7e24c12009-10-30 11:49:00 +00001403 virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }
1404
1405 int literal_index() { return literal_index_; }
1406
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001407 int depth() const {
1408 // only callable after initialization.
1409 DCHECK(depth_ >= 1);
1410 return depth_;
1411 }
1412
1413 protected:
1414 MaterializedLiteral(Zone* zone, int literal_index, int pos, IdGen* id_gen)
1415 : Expression(zone, pos, id_gen),
1416 literal_index_(literal_index),
1417 is_simple_(false),
1418 depth_(0) {}
1419
Steve Blocka7e24c12009-10-30 11:49:00 +00001420 // A materialized literal is simple if the values consist of only
1421 // constants and simple object and array literals.
1422 bool is_simple() const { return is_simple_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001423 void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
1424 friend class CompileTimeValue;
Steve Blocka7e24c12009-10-30 11:49:00 +00001425
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001426 void set_depth(int depth) {
1427 DCHECK(depth >= 1);
1428 depth_ = depth;
1429 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001430
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001431 // Populate the constant properties/elements fixed array.
1432 void BuildConstants(Isolate* isolate);
1433 friend class ArrayLiteral;
1434 friend class ObjectLiteral;
1435
1436 // If the expression is a literal, return the literal value;
1437 // if the expression is a materialized literal and is simple return a
1438 // compile time value as encoded by CompileTimeValue::GetValue().
1439 // Otherwise, return undefined literal as the placeholder
1440 // in the object literal boilerplate.
1441 Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001442
1443 private:
1444 int literal_index_;
1445 bool is_simple_;
1446 int depth_;
1447};
1448
1449
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001450// Property is used for passing information
1451// about an object literal's properties from the parser
1452// to the code generator.
1453class ObjectLiteralProperty FINAL : public ZoneObject {
1454 public:
1455 enum Kind {
1456 CONSTANT, // Property with constant value (compile time).
1457 COMPUTED, // Property with computed value (execution time).
1458 MATERIALIZED_LITERAL, // Property value is a materialized literal.
1459 GETTER, SETTER, // Property is an accessor function.
1460 PROTOTYPE // Property is __proto__.
1461 };
1462
1463 ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory,
1464 Literal* key, Expression* value, bool is_static);
1465
1466 Literal* key() { return key_; }
1467 Expression* value() { return value_; }
1468 Kind kind() { return kind_; }
1469
1470 // Type feedback information.
1471 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1472 bool IsMonomorphic() { return !receiver_type_.is_null(); }
1473 Handle<Map> GetReceiverType() { return receiver_type_; }
1474
1475 bool IsCompileTimeValue();
1476
1477 void set_emit_store(bool emit_store);
1478 bool emit_store();
1479
1480 protected:
1481 template<class> friend class AstNodeFactory;
1482
1483 ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value,
1484 bool is_static);
1485 void set_key(Literal* key) { key_ = key; }
1486
1487 private:
1488 Literal* key_;
1489 Expression* value_;
1490 Kind kind_;
1491 bool emit_store_;
1492 bool is_static_;
1493 Handle<Map> receiver_type_;
1494};
1495
1496
Steve Blocka7e24c12009-10-30 11:49:00 +00001497// An object literal has a boilerplate object that is used
1498// for minimizing the work when constructing it at runtime.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001499class ObjectLiteral FINAL : public MaterializedLiteral {
Steve Blocka7e24c12009-10-30 11:49:00 +00001500 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001501 typedef ObjectLiteralProperty Property;
Steve Blocka7e24c12009-10-30 11:49:00 +00001502
Ben Murdochf87a2032010-10-22 12:50:53 +01001503 DECLARE_NODE_TYPE(ObjectLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00001504
1505 Handle<FixedArray> constant_properties() const {
1506 return constant_properties_;
1507 }
1508 ZoneList<Property*>* properties() const { return properties_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001509 bool fast_elements() const { return fast_elements_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001510 bool may_store_doubles() const { return may_store_doubles_; }
1511 bool has_function() const { return has_function_; }
Steve Block6ded16b2010-05-10 14:33:55 +01001512
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001513 // Decide if a property should be in the object boilerplate.
1514 static bool IsBoilerplateProperty(Property* property);
1515
1516 // Populate the constant properties fixed array.
1517 void BuildConstantProperties(Isolate* isolate);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001518
1519 // Mark all computed expressions that are bound to a key that
1520 // is shadowed by a later occurrence of the same key. For the
1521 // marked expressions, no store code is emitted.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001522 void CalculateEmitStore(Zone* zone);
1523
1524 // Assemble bitfield of flags for the CreateObjectLiteral helper.
1525 int ComputeFlags() const {
1526 int flags = fast_elements() ? kFastElements : kNoFlags;
1527 flags |= has_function() ? kHasFunction : kNoFlags;
1528 return flags;
1529 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -08001530
Steve Block44f0eee2011-05-26 01:26:41 +01001531 enum Flags {
1532 kNoFlags = 0,
1533 kFastElements = 1,
1534 kHasFunction = 1 << 1
1535 };
1536
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001537 struct Accessors: public ZoneObject {
1538 Accessors() : getter(NULL), setter(NULL) { }
1539 Expression* getter;
1540 Expression* setter;
1541 };
1542
1543 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001544 ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
1545 int boilerplate_properties, bool has_function, int pos,
1546 IdGen* id_gen)
1547 : MaterializedLiteral(zone, literal_index, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001548 properties_(properties),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001549 boilerplate_properties_(boilerplate_properties),
1550 fast_elements_(false),
1551 may_store_doubles_(false),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001552 has_function_(has_function) {}
1553
Steve Blocka7e24c12009-10-30 11:49:00 +00001554 private:
1555 Handle<FixedArray> constant_properties_;
1556 ZoneList<Property*>* properties_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001557 int boilerplate_properties_;
Steve Block6ded16b2010-05-10 14:33:55 +01001558 bool fast_elements_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001559 bool may_store_doubles_;
Steve Block44f0eee2011-05-26 01:26:41 +01001560 bool has_function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001561};
1562
1563
1564// Node for capturing a regexp literal.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001565class RegExpLiteral FINAL : public MaterializedLiteral {
Steve Blocka7e24c12009-10-30 11:49:00 +00001566 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001567 DECLARE_NODE_TYPE(RegExpLiteral)
1568
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001569 Handle<String> pattern() const { return pattern_->string(); }
1570 Handle<String> flags() const { return flags_->string(); }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001571
1572 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001573 RegExpLiteral(Zone* zone, const AstRawString* pattern,
1574 const AstRawString* flags, int literal_index, int pos,
1575 IdGen* id_gen)
1576 : MaterializedLiteral(zone, literal_index, pos, id_gen),
Steve Blocka7e24c12009-10-30 11:49:00 +00001577 pattern_(pattern),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001578 flags_(flags) {
1579 set_depth(1);
1580 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001581
Steve Blocka7e24c12009-10-30 11:49:00 +00001582 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001583 const AstRawString* pattern_;
1584 const AstRawString* flags_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001585};
1586
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001587
Steve Blocka7e24c12009-10-30 11:49:00 +00001588// An array literal has a literals object that is used
1589// for minimizing the work when constructing it at runtime.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001590class ArrayLiteral FINAL : public MaterializedLiteral {
Steve Blocka7e24c12009-10-30 11:49:00 +00001591 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001592 DECLARE_NODE_TYPE(ArrayLiteral)
1593
1594 Handle<FixedArray> constant_elements() const { return constant_elements_; }
1595 ZoneList<Expression*>* values() const { return values_; }
1596
1597 // Return an AST id for an element that is used in simulate instructions.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001598 BailoutId GetIdForElement(int i) {
1599 return BailoutId(first_element_id_.ToInt() + i);
1600 }
1601
1602 // Populate the constant elements fixed array.
1603 void BuildConstantElements(Isolate* isolate);
1604
1605 // Assemble bitfield of flags for the CreateArrayLiteral helper.
1606 int ComputeFlags() const {
1607 int flags = depth() == 1 ? kShallowElements : kNoFlags;
1608 flags |= ArrayLiteral::kDisableMementos;
1609 return flags;
1610 }
1611
1612 enum Flags {
1613 kNoFlags = 0,
1614 kShallowElements = 1,
1615 kDisableMementos = 1 << 1
1616 };
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001617
1618 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001619 ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
1620 int pos, IdGen* id_gen)
1621 : MaterializedLiteral(zone, literal_index, pos, id_gen),
Ben Murdochb0fe1622011-05-05 13:52:32 +01001622 values_(values),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001623 first_element_id_(id_gen->ReserveIdRange(values->length())) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001624
Steve Blocka7e24c12009-10-30 11:49:00 +00001625 private:
Leon Clarkee46be812010-01-19 14:06:41 +00001626 Handle<FixedArray> constant_elements_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001627 ZoneList<Expression*>* values_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001628 const BailoutId first_element_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001629};
1630
1631
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001632class VariableProxy FINAL : public Expression, public FeedbackSlotInterface {
Steve Blocka7e24c12009-10-30 11:49:00 +00001633 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001634 DECLARE_NODE_TYPE(VariableProxy)
Steve Blocka7e24c12009-10-30 11:49:00 +00001635
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001636 virtual bool IsValidReferenceExpression() const OVERRIDE {
1637 return var_ == NULL ? true : var_->IsValidReference();
Steve Blocka7e24c12009-10-30 11:49:00 +00001638 }
1639
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001640 bool IsArguments() const { return var_ != NULL && var_->is_arguments(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001641
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001642 Handle<String> name() const { return name_->string(); }
1643 const AstRawString* raw_name() const { return name_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001644 Variable* var() const { return var_; }
1645 bool is_this() const { return is_this_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001646 Interface* interface() const { return interface_; }
1647
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001648 bool is_assigned() const { return is_assigned_; }
1649 void set_is_assigned() { is_assigned_ = true; }
Steve Block6ded16b2010-05-10 14:33:55 +01001650
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001651 // Bind this proxy to the variable var. Interfaces must match.
Steve Blocka7e24c12009-10-30 11:49:00 +00001652 void BindTo(Variable* var);
1653
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001654 virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
1655 virtual void SetFirstFeedbackSlot(int slot) {
1656 variable_feedback_slot_ = slot;
1657 }
1658
1659 int VariableFeedbackSlot() { return variable_feedback_slot_; }
1660
Steve Blocka7e24c12009-10-30 11:49:00 +00001661 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001662 VariableProxy(Zone* zone, Variable* var, int position, IdGen* id_gen);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001663
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001664 VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
1665 Interface* interface, int position, IdGen* id_gen);
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001666
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001667 const AstRawString* name_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001668 Variable* var_; // resolved variable, or NULL
1669 bool is_this_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001670 bool is_assigned_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001671 Interface* interface_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001672 int variable_feedback_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001673};
1674
1675
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001676class Property FINAL : public Expression, public FeedbackSlotInterface {
Steve Blocka7e24c12009-10-30 11:49:00 +00001677 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001678 DECLARE_NODE_TYPE(Property)
Steve Blocka7e24c12009-10-30 11:49:00 +00001679
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001680 virtual bool IsValidReferenceExpression() const OVERRIDE { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001681
1682 Expression* obj() const { return obj_; }
1683 Expression* key() const { return key_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001684
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001685 BailoutId LoadId() const { return load_id_; }
1686
Steve Block44f0eee2011-05-26 01:26:41 +01001687 bool IsStringAccess() const { return is_string_access_; }
Steve Block9fac8402011-05-12 15:51:54 +01001688
Ben Murdochb0fe1622011-05-05 13:52:32 +01001689 // Type feedback information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001690 virtual bool IsMonomorphic() OVERRIDE {
1691 return receiver_types_.length() == 1;
1692 }
1693 virtual SmallMapList* GetReceiverTypes() OVERRIDE {
1694 return &receiver_types_;
1695 }
1696 virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
1697 return STANDARD_STORE;
1698 }
1699 bool IsUninitialized() { return !is_for_call_ && is_uninitialized_; }
1700 bool HasNoTypeInformation() {
1701 return is_uninitialized_;
1702 }
1703 void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
1704 void set_is_string_access(bool b) { is_string_access_ = b; }
1705 void mark_for_call() { is_for_call_ = true; }
1706 bool IsForCall() { return is_for_call_; }
1707
1708 bool IsSuperAccess() {
1709 return obj()->IsSuperReference();
1710 }
1711
1712 TypeFeedbackId PropertyFeedbackId() { return reuse(id()); }
1713
1714 virtual int ComputeFeedbackSlotCount() { return FLAG_vector_ics ? 1 : 0; }
1715 virtual void SetFirstFeedbackSlot(int slot) {
1716 property_feedback_slot_ = slot;
1717 }
1718
1719 int PropertyFeedbackSlot() const { return property_feedback_slot_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001720
1721 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001722 Property(Zone* zone, Expression* obj, Expression* key, int pos, IdGen* id_gen)
1723 : Expression(zone, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001724 obj_(obj),
1725 key_(key),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001726 load_id_(id_gen->GetNextId()),
1727 property_feedback_slot_(kInvalidFeedbackSlot),
1728 is_for_call_(false),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001729 is_uninitialized_(false),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001730 is_string_access_(false) {}
Ben Murdochb0fe1622011-05-05 13:52:32 +01001731
Steve Blocka7e24c12009-10-30 11:49:00 +00001732 private:
1733 Expression* obj_;
1734 Expression* key_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001735 const BailoutId load_id_;
1736 int property_feedback_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001737
Ben Murdoch69a99ed2011-11-30 16:03:39 +00001738 SmallMapList receiver_types_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001739 bool is_for_call_ : 1;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001740 bool is_uninitialized_ : 1;
Steve Block44f0eee2011-05-26 01:26:41 +01001741 bool is_string_access_ : 1;
Steve Blocka7e24c12009-10-30 11:49:00 +00001742};
1743
1744
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001745class Call FINAL : public Expression, public FeedbackSlotInterface {
Steve Blocka7e24c12009-10-30 11:49:00 +00001746 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001747 DECLARE_NODE_TYPE(Call)
Steve Blocka7e24c12009-10-30 11:49:00 +00001748
1749 Expression* expression() const { return expression_; }
1750 ZoneList<Expression*>* arguments() const { return arguments_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001751
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001752 // Type feedback information.
1753 virtual int ComputeFeedbackSlotCount() { return 1; }
1754 virtual void SetFirstFeedbackSlot(int slot) {
1755 call_feedback_slot_ = slot;
1756 }
1757
1758 bool HasCallFeedbackSlot() const {
1759 return call_feedback_slot_ != kInvalidFeedbackSlot;
1760 }
1761 int CallFeedbackSlot() const { return call_feedback_slot_; }
1762
1763 virtual SmallMapList* GetReceiverTypes() OVERRIDE {
1764 if (expression()->IsProperty()) {
1765 return expression()->AsProperty()->GetReceiverTypes();
1766 }
1767 return NULL;
1768 }
1769
1770 virtual bool IsMonomorphic() OVERRIDE {
1771 if (expression()->IsProperty()) {
1772 return expression()->AsProperty()->IsMonomorphic();
1773 }
1774 return !target_.is_null();
1775 }
1776
1777 bool global_call() const {
1778 VariableProxy* proxy = expression_->AsVariableProxy();
1779 return proxy != NULL && proxy->var()->IsUnallocated();
1780 }
1781
1782 bool known_global_function() const {
1783 return global_call() && !target_.is_null();
1784 }
1785
Ben Murdochb0fe1622011-05-05 13:52:32 +01001786 Handle<JSFunction> target() { return target_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001787
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001788 Handle<Cell> cell() { return cell_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01001789
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001790 Handle<AllocationSite> allocation_site() { return allocation_site_; }
1791
1792 void set_target(Handle<JSFunction> target) { target_ = target; }
1793 void set_allocation_site(Handle<AllocationSite> site) {
1794 allocation_site_ = site;
1795 }
1796 bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it);
1797
1798 BailoutId ReturnId() const { return return_id_; }
1799
1800 enum CallType {
1801 POSSIBLY_EVAL_CALL,
1802 GLOBAL_CALL,
1803 LOOKUP_SLOT_CALL,
1804 PROPERTY_CALL,
1805 OTHER_CALL
1806 };
1807
1808 // Helpers to determine how to handle the call.
1809 CallType GetCallType(Isolate* isolate) const;
1810 bool IsUsingCallFeedbackSlot(Isolate* isolate) const;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001811
Ben Murdochb0fe1622011-05-05 13:52:32 +01001812#ifdef DEBUG
1813 // Used to assert that the FullCodeGenerator records the return site.
1814 bool return_is_recorded_;
1815#endif
1816
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001817 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001818 Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
1819 int pos, IdGen* id_gen)
1820 : Expression(zone, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001821 expression_(expression),
1822 arguments_(arguments),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001823 call_feedback_slot_(kInvalidFeedbackSlot),
1824 return_id_(id_gen->GetNextId()) {
1825 if (expression->IsProperty()) {
1826 expression->AsProperty()->mark_for_call();
1827 }
1828 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001829
Steve Blocka7e24c12009-10-30 11:49:00 +00001830 private:
1831 Expression* expression_;
1832 ZoneList<Expression*>* arguments_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001833
Ben Murdochb0fe1622011-05-05 13:52:32 +01001834 Handle<JSFunction> target_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001835 Handle<Cell> cell_;
1836 Handle<AllocationSite> allocation_site_;
1837 int call_feedback_slot_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01001838
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001839 const BailoutId return_id_;
Steve Block44f0eee2011-05-26 01:26:41 +01001840};
Ben Murdochb0fe1622011-05-05 13:52:32 +01001841
Steve Block44f0eee2011-05-26 01:26:41 +01001842
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001843class CallNew FINAL : public Expression, public FeedbackSlotInterface {
Steve Blocka7e24c12009-10-30 11:49:00 +00001844 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001845 DECLARE_NODE_TYPE(CallNew)
1846
1847 Expression* expression() const { return expression_; }
1848 ZoneList<Expression*>* arguments() const { return arguments_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001849
1850 // Type feedback information.
1851 virtual int ComputeFeedbackSlotCount() {
1852 return FLAG_pretenuring_call_new ? 2 : 1;
1853 }
1854 virtual void SetFirstFeedbackSlot(int slot) {
1855 callnew_feedback_slot_ = slot;
1856 }
1857
1858 int CallNewFeedbackSlot() {
1859 DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
1860 return callnew_feedback_slot_;
1861 }
1862 int AllocationSiteFeedbackSlot() {
1863 DCHECK(callnew_feedback_slot_ != kInvalidFeedbackSlot);
1864 DCHECK(FLAG_pretenuring_call_new);
1865 return callnew_feedback_slot_ + 1;
1866 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001867
1868 void RecordTypeFeedback(TypeFeedbackOracle* oracle);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001869 virtual bool IsMonomorphic() OVERRIDE { return is_monomorphic_; }
1870 Handle<JSFunction> target() const { return target_; }
1871 ElementsKind elements_kind() const { return elements_kind_; }
1872 Handle<AllocationSite> allocation_site() const {
1873 return allocation_site_;
1874 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001875
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001876 static int feedback_slots() { return 1; }
1877
1878 BailoutId ReturnId() const { return return_id_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001879
1880 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001881 CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
1882 int pos, IdGen* id_gen)
1883 : Expression(zone, pos, id_gen),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001884 expression_(expression),
1885 arguments_(arguments),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001886 is_monomorphic_(false),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001887 elements_kind_(GetInitialFastElementsKind()),
1888 callnew_feedback_slot_(kInvalidFeedbackSlot),
1889 return_id_(id_gen->GetNextId()) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001890
1891 private:
1892 Expression* expression_;
1893 ZoneList<Expression*>* arguments_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001894
1895 bool is_monomorphic_;
1896 Handle<JSFunction> target_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001897 ElementsKind elements_kind_;
1898 Handle<AllocationSite> allocation_site_;
1899 int callnew_feedback_slot_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001900
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001901 const BailoutId return_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001902};
1903
1904
1905// The CallRuntime class does not represent any official JavaScript
1906// language construct. Instead it is used to call a C or JS function
1907// with a set of arguments. This is used from the builtins that are
1908// implemented in JavaScript (see "v8natives.js").
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001909class CallRuntime FINAL : public Expression, public FeedbackSlotInterface {
Steve Blocka7e24c12009-10-30 11:49:00 +00001910 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001911 DECLARE_NODE_TYPE(CallRuntime)
1912
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001913 Handle<String> name() const { return raw_name_->string(); }
1914 const AstRawString* raw_name() const { return raw_name_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001915 const Runtime::Function* function() const { return function_; }
1916 ZoneList<Expression*>* arguments() const { return arguments_; }
1917 bool is_jsruntime() const { return function_ == NULL; }
1918
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001919 // Type feedback information.
1920 virtual int ComputeFeedbackSlotCount() {
1921 return (FLAG_vector_ics && is_jsruntime()) ? 1 : 0;
1922 }
1923 virtual void SetFirstFeedbackSlot(int slot) {
1924 callruntime_feedback_slot_ = slot;
1925 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001926
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001927 int CallRuntimeFeedbackSlot() {
1928 DCHECK(!is_jsruntime() ||
1929 callruntime_feedback_slot_ != kInvalidFeedbackSlot);
1930 return callruntime_feedback_slot_;
1931 }
1932
1933 TypeFeedbackId CallRuntimeFeedbackId() const { return reuse(id()); }
1934
1935 protected:
1936 CallRuntime(Zone* zone, const AstRawString* name,
Steve Block44f0eee2011-05-26 01:26:41 +01001937 const Runtime::Function* function,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001938 ZoneList<Expression*>* arguments, int pos, IdGen* id_gen)
1939 : Expression(zone, pos, id_gen),
1940 raw_name_(name),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00001941 function_(function),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001942 arguments_(arguments) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00001943
Steve Blocka7e24c12009-10-30 11:49:00 +00001944 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001945 const AstRawString* raw_name_;
Steve Block44f0eee2011-05-26 01:26:41 +01001946 const Runtime::Function* function_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001947 ZoneList<Expression*>* arguments_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001948 int callruntime_feedback_slot_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001949};
1950
1951
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001952class UnaryOperation FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001953 public:
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001954 DECLARE_NODE_TYPE(UnaryOperation)
1955
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001956 Token::Value op() const { return op_; }
1957 Expression* expression() const { return expression_; }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01001958
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001959 BailoutId MaterializeTrueId() { return materialize_true_id_; }
1960 BailoutId MaterializeFalseId() { return materialize_false_id_; }
1961
1962 virtual void RecordToBooleanTypeFeedback(
1963 TypeFeedbackOracle* oracle) OVERRIDE;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001964
1965 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001966 UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos,
1967 IdGen* id_gen)
1968 : Expression(zone, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001969 op_(op),
1970 expression_(expression),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001971 materialize_true_id_(id_gen->GetNextId()),
1972 materialize_false_id_(id_gen->GetNextId()) {
1973 DCHECK(Token::IsUnaryOp(op));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001974 }
1975
Steve Blocka7e24c12009-10-30 11:49:00 +00001976 private:
1977 Token::Value op_;
1978 Expression* expression_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001979
1980 // For unary not (Token::NOT), the AST ids where true and false will
1981 // actually be materialized, respectively.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001982 const BailoutId materialize_true_id_;
1983 const BailoutId materialize_false_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001984};
1985
1986
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001987class BinaryOperation FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00001988 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01001989 DECLARE_NODE_TYPE(BinaryOperation)
Steve Blocka7e24c12009-10-30 11:49:00 +00001990
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001991 virtual bool ResultOverwriteAllowed() const OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00001992
Steve Blocka7e24c12009-10-30 11:49:00 +00001993 Token::Value op() const { return op_; }
1994 Expression* left() const { return left_; }
1995 Expression* right() const { return right_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001996 Handle<AllocationSite> allocation_site() const { return allocation_site_; }
1997 void set_allocation_site(Handle<AllocationSite> allocation_site) {
1998 allocation_site_ = allocation_site;
1999 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002000
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002001 BailoutId RightId() const { return right_id_; }
2002
2003 TypeFeedbackId BinaryOperationFeedbackId() const { return reuse(id()); }
2004 Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
2005 void set_fixed_right_arg(Maybe<int> arg) { fixed_right_arg_ = arg; }
2006
2007 virtual void RecordToBooleanTypeFeedback(
2008 TypeFeedbackOracle* oracle) OVERRIDE;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002009
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002010 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002011 BinaryOperation(Zone* zone, Token::Value op, Expression* left,
2012 Expression* right, int pos, IdGen* id_gen)
2013 : Expression(zone, pos, id_gen),
2014 op_(op),
2015 left_(left),
2016 right_(right),
2017 right_id_(id_gen->GetNextId()) {
2018 DCHECK(Token::IsBinaryOp(op));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002019 }
2020
Steve Blocka7e24c12009-10-30 11:49:00 +00002021 private:
2022 Token::Value op_;
2023 Expression* left_;
2024 Expression* right_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002025 Handle<AllocationSite> allocation_site_;
2026
2027 // TODO(rossberg): the fixed arg should probably be represented as a Constant
2028 // type for the RHS.
2029 Maybe<int> fixed_right_arg_;
2030
2031 // The short-circuit logical operations need an AST ID for their
Ben Murdochb0fe1622011-05-05 13:52:32 +01002032 // right-hand subexpression.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002033 const BailoutId right_id_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002034};
2035
2036
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002037class CountOperation FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002038 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002039 DECLARE_NODE_TYPE(CountOperation)
Steve Block6ded16b2010-05-10 14:33:55 +01002040
Steve Blocka7e24c12009-10-30 11:49:00 +00002041 bool is_prefix() const { return is_prefix_; }
2042 bool is_postfix() const { return !is_prefix_; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002043
Ben Murdoch8b112d22011-06-08 16:22:53 +01002044 Token::Value op() const { return op_; }
Leon Clarkee46be812010-01-19 14:06:41 +00002045 Token::Value binary_op() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002046 return (op() == Token::INC) ? Token::ADD : Token::SUB;
Leon Clarkee46be812010-01-19 14:06:41 +00002047 }
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002048
Ben Murdoch8b112d22011-06-08 16:22:53 +01002049 Expression* expression() const { return expression_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002050
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002051 virtual bool IsMonomorphic() OVERRIDE {
2052 return receiver_types_.length() == 1;
2053 }
2054 virtual SmallMapList* GetReceiverTypes() OVERRIDE {
2055 return &receiver_types_;
2056 }
2057 virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
2058 return store_mode_;
2059 }
2060 Type* type() const { return type_; }
2061 void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
2062 void set_type(Type* type) { type_ = type; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002063
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002064 BailoutId AssignmentId() const { return assignment_id_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +01002065
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002066 TypeFeedbackId CountBinOpFeedbackId() const { return count_id_; }
2067 TypeFeedbackId CountStoreFeedbackId() const { return reuse(id()); }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002068
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002069 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002070 CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
2071 int pos, IdGen* id_gen)
2072 : Expression(zone, pos, id_gen),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002073 op_(op),
2074 is_prefix_(is_prefix),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002075 store_mode_(STANDARD_STORE),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002076 expression_(expr),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002077 assignment_id_(id_gen->GetNextId()),
2078 count_id_(id_gen->GetNextId()) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002079
Steve Blocka7e24c12009-10-30 11:49:00 +00002080 private:
Ben Murdoch8b112d22011-06-08 16:22:53 +01002081 Token::Value op_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002082 bool is_prefix_ : 1;
2083 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
2084 // must have extra bit.
2085 Type* type_;
2086
Ben Murdoch8b112d22011-06-08 16:22:53 +01002087 Expression* expression_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002088 const BailoutId assignment_id_;
2089 const TypeFeedbackId count_id_;
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002090 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002091};
2092
2093
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002094class CompareOperation FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002095 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002096 DECLARE_NODE_TYPE(CompareOperation)
2097
2098 Token::Value op() const { return op_; }
2099 Expression* left() const { return left_; }
2100 Expression* right() const { return right_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002101
2102 // Type feedback information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002103 TypeFeedbackId CompareOperationFeedbackId() const { return reuse(id()); }
2104 Type* combined_type() const { return combined_type_; }
2105 void set_combined_type(Type* type) { combined_type_ = type; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002106
2107 // Match special cases.
2108 bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002109 bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002110 bool IsLiteralCompareNull(Expression** expr);
2111
2112 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002113 CompareOperation(Zone* zone, Token::Value op, Expression* left,
2114 Expression* right, int pos, IdGen* id_gen)
2115 : Expression(zone, pos, id_gen),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002116 op_(op),
2117 left_(left),
2118 right_(right),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002119 combined_type_(Type::None(zone)) {
2120 DCHECK(Token::IsCompareOp(op));
Steve Blocka7e24c12009-10-30 11:49:00 +00002121 }
2122
Steve Blocka7e24c12009-10-30 11:49:00 +00002123 private:
2124 Token::Value op_;
2125 Expression* left_;
2126 Expression* right_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002127
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002128 Type* combined_type_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +01002129};
2130
2131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002132class Conditional FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002133 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002134 DECLARE_NODE_TYPE(Conditional)
2135
2136 Expression* condition() const { return condition_; }
2137 Expression* then_expression() const { return then_expression_; }
2138 Expression* else_expression() const { return else_expression_; }
2139
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002140 BailoutId ThenId() const { return then_id_; }
2141 BailoutId ElseId() const { return else_id_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002142
2143 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002144 Conditional(Zone* zone, Expression* condition, Expression* then_expression,
2145 Expression* else_expression, int position, IdGen* id_gen)
2146 : Expression(zone, position, id_gen),
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002147 condition_(condition),
Steve Blocka7e24c12009-10-30 11:49:00 +00002148 then_expression_(then_expression),
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002149 else_expression_(else_expression),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002150 then_id_(id_gen->GetNextId()),
2151 else_id_(id_gen->GetNextId()) {}
Ben Murdoch7f4d5bd2010-06-15 11:15:29 +01002152
Steve Blocka7e24c12009-10-30 11:49:00 +00002153 private:
2154 Expression* condition_;
2155 Expression* then_expression_;
2156 Expression* else_expression_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002157 const BailoutId then_id_;
2158 const BailoutId else_id_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002159};
2160
2161
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002162class Assignment FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002163 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002164 DECLARE_NODE_TYPE(Assignment)
Steve Blocka7e24c12009-10-30 11:49:00 +00002165
Steve Block6ded16b2010-05-10 14:33:55 +01002166 Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }
2167
Steve Blocka7e24c12009-10-30 11:49:00 +00002168 Token::Value binary_op() const;
2169
2170 Token::Value op() const { return op_; }
2171 Expression* target() const { return target_; }
2172 Expression* value() const { return value_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002173 BinaryOperation* binary_operation() const { return binary_operation_; }
2174
Leon Clarkee46be812010-01-19 14:06:41 +00002175 // This check relies on the definition order of token in token.h.
2176 bool is_compound() const { return op() > Token::ASSIGN; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002177
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002178 BailoutId AssignmentId() const { return assignment_id_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002179
Ben Murdochb0fe1622011-05-05 13:52:32 +01002180 // Type feedback information.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002181 TypeFeedbackId AssignmentFeedbackId() { return reuse(id()); }
2182 virtual bool IsMonomorphic() OVERRIDE {
2183 return receiver_types_.length() == 1;
2184 }
2185 bool IsUninitialized() { return is_uninitialized_; }
2186 bool HasNoTypeInformation() {
2187 return is_uninitialized_;
2188 }
2189 virtual SmallMapList* GetReceiverTypes() OVERRIDE {
2190 return &receiver_types_;
2191 }
2192 virtual KeyedAccessStoreMode GetStoreMode() OVERRIDE {
2193 return store_mode_;
2194 }
2195 void set_is_uninitialized(bool b) { is_uninitialized_ = b; }
2196 void set_store_mode(KeyedAccessStoreMode mode) { store_mode_ = mode; }
Ben Murdochb0fe1622011-05-05 13:52:32 +01002197
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002198 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002199 Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
2200 int pos, IdGen* id_gen);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002201
2202 template<class Visitor>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002203 void Init(Zone* zone, AstNodeFactory<Visitor>* factory) {
2204 DCHECK(Token::IsAssignmentOp(op_));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002205 if (is_compound()) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002206 binary_operation_ = factory->NewBinaryOperation(
2207 binary_op(), target_, value_, position() + 1);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002208 }
2209 }
2210
Steve Blocka7e24c12009-10-30 11:49:00 +00002211 private:
2212 Token::Value op_;
2213 Expression* target_;
2214 Expression* value_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002215 BinaryOperation* binary_operation_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002216 const BailoutId assignment_id_;
Ben Murdochb0fe1622011-05-05 13:52:32 +01002217
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002218 bool is_uninitialized_ : 1;
2219 KeyedAccessStoreMode store_mode_ : 5; // Windows treats as signed,
2220 // must have extra bit.
Ben Murdoch69a99ed2011-11-30 16:03:39 +00002221 SmallMapList receiver_types_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002222};
2223
2224
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002225class Yield FINAL : public Expression, public FeedbackSlotInterface {
2226 public:
2227 DECLARE_NODE_TYPE(Yield)
2228
2229 enum Kind {
2230 kInitial, // The initial yield that returns the unboxed generator object.
2231 kSuspend, // A normal yield: { value: EXPRESSION, done: false }
2232 kDelegating, // A yield*.
2233 kFinal // A return: { value: EXPRESSION, done: true }
2234 };
2235
2236 Expression* generator_object() const { return generator_object_; }
2237 Expression* expression() const { return expression_; }
2238 Kind yield_kind() const { return yield_kind_; }
2239
2240 // Delegating yield surrounds the "yield" in a "try/catch". This index
2241 // locates the catch handler in the handler table, and is equivalent to
2242 // TryCatchStatement::index().
2243 int index() const {
2244 DCHECK_EQ(kDelegating, yield_kind());
2245 return index_;
2246 }
2247 void set_index(int index) {
2248 DCHECK_EQ(kDelegating, yield_kind());
2249 index_ = index;
2250 }
2251
2252 // Type feedback information.
2253 virtual int ComputeFeedbackSlotCount() {
2254 return (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0;
2255 }
2256 virtual void SetFirstFeedbackSlot(int slot) {
2257 yield_first_feedback_slot_ = slot;
2258 }
2259
2260 int KeyedLoadFeedbackSlot() {
2261 DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
2262 return yield_first_feedback_slot_;
2263 }
2264
2265 int DoneFeedbackSlot() {
2266 DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
2267 return yield_first_feedback_slot_ + 1;
2268 }
2269
2270 int ValueFeedbackSlot() {
2271 DCHECK(yield_first_feedback_slot_ != kInvalidFeedbackSlot);
2272 return yield_first_feedback_slot_ + 2;
2273 }
2274
2275 protected:
2276 Yield(Zone* zone, Expression* generator_object, Expression* expression,
2277 Kind yield_kind, int pos, IdGen* id_gen)
2278 : Expression(zone, pos, id_gen),
2279 generator_object_(generator_object),
2280 expression_(expression),
2281 yield_kind_(yield_kind),
2282 index_(-1),
2283 yield_first_feedback_slot_(kInvalidFeedbackSlot) {}
2284
2285 private:
2286 Expression* generator_object_;
2287 Expression* expression_;
2288 Kind yield_kind_;
2289 int index_;
2290 int yield_first_feedback_slot_;
2291};
2292
2293
2294class Throw FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002295 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002296 DECLARE_NODE_TYPE(Throw)
Steve Block6ded16b2010-05-10 14:33:55 +01002297
Steve Blocka7e24c12009-10-30 11:49:00 +00002298 Expression* exception() const { return exception_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002299
2300 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002301 Throw(Zone* zone, Expression* exception, int pos, IdGen* id_gen)
2302 : Expression(zone, pos, id_gen), exception_(exception) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002303
2304 private:
2305 Expression* exception_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002306};
2307
2308
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002309class FunctionLiteral FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002310 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002311 enum FunctionType {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002312 ANONYMOUS_EXPRESSION,
2313 NAMED_EXPRESSION,
2314 DECLARATION
2315 };
2316
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002317 enum ParameterFlag {
2318 kNoDuplicateParameters = 0,
2319 kHasDuplicateParameters = 1
2320 };
2321
2322 enum IsFunctionFlag {
2323 kGlobalOrEval,
2324 kIsFunction
2325 };
Steve Blocka7e24c12009-10-30 11:49:00 +00002326
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002327 enum IsParenthesizedFlag {
2328 kIsParenthesized,
2329 kNotParenthesized
2330 };
2331
2332 enum ArityRestriction {
2333 NORMAL_ARITY,
2334 GETTER_ARITY,
2335 SETTER_ARITY
2336 };
2337
Ben Murdochf87a2032010-10-22 12:50:53 +01002338 DECLARE_NODE_TYPE(FunctionLiteral)
Steve Blocka7e24c12009-10-30 11:49:00 +00002339
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002340 Handle<String> name() const { return raw_name_->string(); }
2341 const AstRawString* raw_name() const { return raw_name_; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +01002342 Scope* scope() const { return scope_; }
2343 ZoneList<Statement*>* body() const { return body_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002344 void set_function_token_position(int pos) { function_token_position_ = pos; }
2345 int function_token_position() const { return function_token_position_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002346 int start_position() const;
2347 int end_position() const;
2348 int SourceSize() const { return end_position() - start_position(); }
2349 bool is_expression() const { return IsExpression::decode(bitfield_); }
2350 bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002351 StrictMode strict_mode() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00002352
2353 int materialized_literal_count() { return materialized_literal_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002354 int expected_property_count() { return expected_property_count_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002355 int handler_count() { return handler_count_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002356 int parameter_count() { return parameter_count_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002357
2358 bool AllowsLazyCompilation();
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002359 bool AllowsLazyCompilationWithoutContext();
2360
2361 void InitializeSharedInfo(Handle<Code> code);
Steve Blocka7e24c12009-10-30 11:49:00 +00002362
Ben Murdochf87a2032010-10-22 12:50:53 +01002363 Handle<String> debug_name() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002364 if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
2365 return raw_name_->string();
2366 }
Ben Murdochf87a2032010-10-22 12:50:53 +01002367 return inferred_name();
2368 }
2369
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002370 Handle<String> inferred_name() const {
2371 if (!inferred_name_.is_null()) {
2372 DCHECK(raw_inferred_name_ == NULL);
2373 return inferred_name_;
2374 }
2375 if (raw_inferred_name_ != NULL) {
2376 return raw_inferred_name_->string();
2377 }
2378 UNREACHABLE();
2379 return Handle<String>();
Steve Blocka7e24c12009-10-30 11:49:00 +00002380 }
2381
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002382 // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2383 void set_inferred_name(Handle<String> inferred_name) {
2384 DCHECK(!inferred_name.is_null());
2385 inferred_name_ = inferred_name;
2386 DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
2387 raw_inferred_name_ = NULL;
2388 }
2389
2390 void set_raw_inferred_name(const AstString* raw_inferred_name) {
2391 DCHECK(raw_inferred_name != NULL);
2392 raw_inferred_name_ = raw_inferred_name;
2393 DCHECK(inferred_name_.is_null());
2394 inferred_name_ = Handle<String>();
2395 }
2396
2397 // shared_info may be null if it's not cached in full code.
2398 Handle<SharedFunctionInfo> shared_info() { return shared_info_; }
2399
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002400 bool pretenure() { return Pretenure::decode(bitfield_); }
2401 void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -08002402
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002403 bool has_duplicate_parameters() {
2404 return HasDuplicateParameters::decode(bitfield_);
2405 }
2406
2407 bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }
2408
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002409 // This is used as a heuristic on when to eagerly compile a function
2410 // literal. We consider the following constructs as hints that the
2411 // function will be called immediately:
2412 // - (function() { ... })();
2413 // - var x = function() { ... }();
2414 bool is_parenthesized() {
2415 return IsParenthesized::decode(bitfield_) == kIsParenthesized;
2416 }
2417 void set_parenthesized() {
2418 bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized);
2419 }
2420
2421 FunctionKind kind() { return FunctionKindBits::decode(bitfield_); }
2422 bool is_arrow() {
2423 return IsArrowFunction(FunctionKindBits::decode(bitfield_));
2424 }
2425 bool is_generator() {
2426 return IsGeneratorFunction(FunctionKindBits::decode(bitfield_));
2427 }
2428 bool is_concise_method() {
2429 return IsConciseMethod(FunctionKindBits::decode(bitfield_));
2430 }
2431
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002432 int ast_node_count() { return ast_properties_.node_count(); }
2433 AstProperties::Flags* flags() { return ast_properties_.flags(); }
2434 void set_ast_properties(AstProperties* ast_properties) {
2435 ast_properties_ = *ast_properties;
2436 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002437 int slot_count() {
2438 return ast_properties_.feedback_slots();
2439 }
2440 bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
2441 BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
2442 void set_dont_optimize_reason(BailoutReason reason) {
2443 dont_optimize_reason_ = reason;
2444 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002445
2446 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002447 FunctionLiteral(Zone* zone, const AstRawString* name,
2448 AstValueFactory* ast_value_factory, Scope* scope,
2449 ZoneList<Statement*>* body, int materialized_literal_count,
2450 int expected_property_count, int handler_count,
2451 int parameter_count, FunctionType function_type,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002452 ParameterFlag has_duplicate_parameters,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002453 IsFunctionFlag is_function,
2454 IsParenthesizedFlag is_parenthesized, FunctionKind kind,
2455 int position, IdGen* id_gen)
2456 : Expression(zone, position, id_gen),
2457 raw_name_(name),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002458 scope_(scope),
2459 body_(body),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002460 raw_inferred_name_(ast_value_factory->empty_string()),
2461 dont_optimize_reason_(kNoReason),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002462 materialized_literal_count_(materialized_literal_count),
2463 expected_property_count_(expected_property_count),
2464 handler_count_(handler_count),
2465 parameter_count_(parameter_count),
2466 function_token_position_(RelocInfo::kNoPosition) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002467 bitfield_ = IsExpression::encode(function_type != DECLARATION) |
2468 IsAnonymous::encode(function_type == ANONYMOUS_EXPRESSION) |
2469 Pretenure::encode(false) |
2470 HasDuplicateParameters::encode(has_duplicate_parameters) |
2471 IsFunction::encode(is_function) |
2472 IsParenthesized::encode(is_parenthesized) |
2473 FunctionKindBits::encode(kind);
2474 DCHECK(IsValidFunctionKind(kind));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002475 }
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +01002476
Steve Blocka7e24c12009-10-30 11:49:00 +00002477 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002478 const AstRawString* raw_name_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002479 Handle<String> name_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002480 Handle<SharedFunctionInfo> shared_info_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002481 Scope* scope_;
2482 ZoneList<Statement*>* body_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002483 const AstString* raw_inferred_name_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002484 Handle<String> inferred_name_;
2485 AstProperties ast_properties_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002486 BailoutReason dont_optimize_reason_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002487
Steve Blocka7e24c12009-10-30 11:49:00 +00002488 int materialized_literal_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002489 int expected_property_count_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002490 int handler_count_;
2491 int parameter_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002492 int function_token_position_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002493
2494 unsigned bitfield_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002495 class IsExpression : public BitField<bool, 0, 1> {};
2496 class IsAnonymous : public BitField<bool, 1, 1> {};
2497 class Pretenure : public BitField<bool, 2, 1> {};
2498 class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {};
2499 class IsFunction : public BitField<IsFunctionFlag, 4, 1> {};
2500 class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {};
2501 class FunctionKindBits : public BitField<FunctionKind, 6, 3> {};
Steve Blocka7e24c12009-10-30 11:49:00 +00002502};
2503
2504
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002505class ClassLiteral FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002506 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002507 typedef ObjectLiteralProperty Property;
Ben Murdochf87a2032010-10-22 12:50:53 +01002508
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002509 DECLARE_NODE_TYPE(ClassLiteral)
2510
2511 Handle<String> name() const { return raw_name_->string(); }
2512 const AstRawString* raw_name() const { return raw_name_; }
2513 Expression* extends() const { return extends_; }
2514 Expression* constructor() const { return constructor_; }
2515 ZoneList<Property*>* properties() const { return properties_; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002516
2517 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002518 ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
2519 Expression* constructor, ZoneList<Property*>* properties,
2520 int position, IdGen* id_gen)
2521 : Expression(zone, position, id_gen),
2522 raw_name_(name),
2523 extends_(extends),
2524 constructor_(constructor),
2525 properties_(properties) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002526
Steve Blocka7e24c12009-10-30 11:49:00 +00002527 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002528 const AstRawString* raw_name_;
2529 Expression* extends_;
2530 Expression* constructor_;
2531 ZoneList<Property*>* properties_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002532};
2533
2534
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002535class NativeFunctionLiteral FINAL : public Expression {
2536 public:
2537 DECLARE_NODE_TYPE(NativeFunctionLiteral)
2538
2539 Handle<String> name() const { return name_->string(); }
2540 v8::Extension* extension() const { return extension_; }
2541
2542 protected:
2543 NativeFunctionLiteral(Zone* zone, const AstRawString* name,
2544 v8::Extension* extension, int pos, IdGen* id_gen)
2545 : Expression(zone, pos, id_gen), name_(name), extension_(extension) {}
2546
2547 private:
2548 const AstRawString* name_;
2549 v8::Extension* extension_;
2550};
2551
2552
2553class ThisFunction FINAL : public Expression {
Steve Blocka7e24c12009-10-30 11:49:00 +00002554 public:
Ben Murdochf87a2032010-10-22 12:50:53 +01002555 DECLARE_NODE_TYPE(ThisFunction)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002556
2557 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002558 ThisFunction(Zone* zone, int pos, IdGen* id_gen)
2559 : Expression(zone, pos, id_gen) {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002560};
2561
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002562
2563class SuperReference FINAL : public Expression {
2564 public:
2565 DECLARE_NODE_TYPE(SuperReference)
2566
2567 VariableProxy* this_var() const { return this_var_; }
2568
2569 TypeFeedbackId HomeObjectFeedbackId() { return reuse(id()); }
2570
2571 protected:
2572 SuperReference(Zone* zone, VariableProxy* this_var, int pos, IdGen* id_gen)
2573 : Expression(zone, pos, id_gen), this_var_(this_var) {
2574 DCHECK(this_var->is_this());
2575 }
2576
2577 VariableProxy* this_var_;
2578};
2579
2580
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002581#undef DECLARE_NODE_TYPE
2582
Steve Blocka7e24c12009-10-30 11:49:00 +00002583
2584// ----------------------------------------------------------------------------
2585// Regular expressions
2586
2587
2588class RegExpVisitor BASE_EMBEDDED {
2589 public:
2590 virtual ~RegExpVisitor() { }
2591#define MAKE_CASE(Name) \
2592 virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
2593 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
2594#undef MAKE_CASE
2595};
2596
2597
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002598class RegExpTree : public ZoneObject {
Steve Blocka7e24c12009-10-30 11:49:00 +00002599 public:
2600 static const int kInfinity = kMaxInt;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002601 virtual ~RegExpTree() {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002602 virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
2603 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2604 RegExpNode* on_success) = 0;
2605 virtual bool IsTextElement() { return false; }
Ben Murdochf87a2032010-10-22 12:50:53 +01002606 virtual bool IsAnchoredAtStart() { return false; }
2607 virtual bool IsAnchoredAtEnd() { return false; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002608 virtual int min_match() = 0;
2609 virtual int max_match() = 0;
2610 // Returns the interval of registers used for captures within this
2611 // expression.
2612 virtual Interval CaptureRegisters() { return Interval::Empty(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002613 virtual void AppendToText(RegExpText* text, Zone* zone);
2614 OStream& Print(OStream& os, Zone* zone); // NOLINT
Steve Blocka7e24c12009-10-30 11:49:00 +00002615#define MAKE_ASTYPE(Name) \
2616 virtual RegExp##Name* As##Name(); \
2617 virtual bool Is##Name();
2618 FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
2619#undef MAKE_ASTYPE
2620};
2621
2622
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002623class RegExpDisjunction FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002624 public:
2625 explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002626 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002627 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002628 RegExpNode* on_success) OVERRIDE;
2629 virtual RegExpDisjunction* AsDisjunction() OVERRIDE;
2630 virtual Interval CaptureRegisters() OVERRIDE;
2631 virtual bool IsDisjunction() OVERRIDE;
2632 virtual bool IsAnchoredAtStart() OVERRIDE;
2633 virtual bool IsAnchoredAtEnd() OVERRIDE;
2634 virtual int min_match() OVERRIDE { return min_match_; }
2635 virtual int max_match() OVERRIDE { return max_match_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002636 ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
2637 private:
2638 ZoneList<RegExpTree*>* alternatives_;
2639 int min_match_;
2640 int max_match_;
2641};
2642
2643
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002644class RegExpAlternative FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002645 public:
2646 explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002647 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002648 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002649 RegExpNode* on_success) OVERRIDE;
2650 virtual RegExpAlternative* AsAlternative() OVERRIDE;
2651 virtual Interval CaptureRegisters() OVERRIDE;
2652 virtual bool IsAlternative() OVERRIDE;
2653 virtual bool IsAnchoredAtStart() OVERRIDE;
2654 virtual bool IsAnchoredAtEnd() OVERRIDE;
2655 virtual int min_match() OVERRIDE { return min_match_; }
2656 virtual int max_match() OVERRIDE { return max_match_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002657 ZoneList<RegExpTree*>* nodes() { return nodes_; }
2658 private:
2659 ZoneList<RegExpTree*>* nodes_;
2660 int min_match_;
2661 int max_match_;
2662};
2663
2664
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002665class RegExpAssertion FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002666 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002667 enum AssertionType {
Steve Blocka7e24c12009-10-30 11:49:00 +00002668 START_OF_LINE,
2669 START_OF_INPUT,
2670 END_OF_LINE,
2671 END_OF_INPUT,
2672 BOUNDARY,
2673 NON_BOUNDARY
2674 };
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002675 explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
2676 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002677 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002678 RegExpNode* on_success) OVERRIDE;
2679 virtual RegExpAssertion* AsAssertion() OVERRIDE;
2680 virtual bool IsAssertion() OVERRIDE;
2681 virtual bool IsAnchoredAtStart() OVERRIDE;
2682 virtual bool IsAnchoredAtEnd() OVERRIDE;
2683 virtual int min_match() OVERRIDE { return 0; }
2684 virtual int max_match() OVERRIDE { return 0; }
2685 AssertionType assertion_type() { return assertion_type_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002686 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002687 AssertionType assertion_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002688};
2689
2690
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002691class CharacterSet FINAL BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00002692 public:
2693 explicit CharacterSet(uc16 standard_set_type)
2694 : ranges_(NULL),
2695 standard_set_type_(standard_set_type) {}
2696 explicit CharacterSet(ZoneList<CharacterRange>* ranges)
2697 : ranges_(ranges),
2698 standard_set_type_(0) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002699 ZoneList<CharacterRange>* ranges(Zone* zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00002700 uc16 standard_set_type() { return standard_set_type_; }
2701 void set_standard_set_type(uc16 special_set_type) {
2702 standard_set_type_ = special_set_type;
2703 }
2704 bool is_standard() { return standard_set_type_ != 0; }
Leon Clarkee46be812010-01-19 14:06:41 +00002705 void Canonicalize();
Steve Blocka7e24c12009-10-30 11:49:00 +00002706 private:
2707 ZoneList<CharacterRange>* ranges_;
2708 // If non-zero, the value represents a standard set (e.g., all whitespace
2709 // characters) without having to expand the ranges.
2710 uc16 standard_set_type_;
2711};
2712
2713
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002714class RegExpCharacterClass FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002715 public:
2716 RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2717 : set_(ranges),
2718 is_negated_(is_negated) { }
2719 explicit RegExpCharacterClass(uc16 type)
2720 : set_(type),
2721 is_negated_(false) { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002722 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002723 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002724 RegExpNode* on_success) OVERRIDE;
2725 virtual RegExpCharacterClass* AsCharacterClass() OVERRIDE;
2726 virtual bool IsCharacterClass() OVERRIDE;
2727 virtual bool IsTextElement() OVERRIDE { return true; }
2728 virtual int min_match() OVERRIDE { return 1; }
2729 virtual int max_match() OVERRIDE { return 1; }
2730 virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002731 CharacterSet character_set() { return set_; }
2732 // TODO(lrn): Remove need for complex version if is_standard that
2733 // recognizes a mangled standard set and just do { return set_.is_special(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002734 bool is_standard(Zone* zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00002735 // Returns a value representing the standard character set if is_standard()
2736 // returns true.
2737 // Currently used values are:
2738 // s : unicode whitespace
2739 // S : unicode non-whitespace
2740 // w : ASCII word character (digit, letter, underscore)
2741 // W : non-ASCII word character
2742 // d : ASCII digit
2743 // D : non-ASCII digit
2744 // . : non-unicode non-newline
2745 // * : All characters
2746 uc16 standard_type() { return set_.standard_set_type(); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002747 ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002748 bool is_negated() { return is_negated_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002749
Steve Blocka7e24c12009-10-30 11:49:00 +00002750 private:
2751 CharacterSet set_;
2752 bool is_negated_;
2753};
2754
2755
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002756class RegExpAtom FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002757 public:
2758 explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002759 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002760 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002761 RegExpNode* on_success) OVERRIDE;
2762 virtual RegExpAtom* AsAtom() OVERRIDE;
2763 virtual bool IsAtom() OVERRIDE;
2764 virtual bool IsTextElement() OVERRIDE { return true; }
2765 virtual int min_match() OVERRIDE { return data_.length(); }
2766 virtual int max_match() OVERRIDE { return data_.length(); }
2767 virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002768 Vector<const uc16> data() { return data_; }
2769 int length() { return data_.length(); }
2770 private:
2771 Vector<const uc16> data_;
2772};
2773
2774
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002775class RegExpText FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002776 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002777 explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
2778 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002779 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002780 RegExpNode* on_success) OVERRIDE;
2781 virtual RegExpText* AsText() OVERRIDE;
2782 virtual bool IsText() OVERRIDE;
2783 virtual bool IsTextElement() OVERRIDE { return true; }
2784 virtual int min_match() OVERRIDE { return length_; }
2785 virtual int max_match() OVERRIDE { return length_; }
2786 virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
2787 void AddElement(TextElement elm, Zone* zone) {
2788 elements_.Add(elm, zone);
Steve Blocka7e24c12009-10-30 11:49:00 +00002789 length_ += elm.length();
Iain Merrick9ac36c92010-09-13 15:29:50 +01002790 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002791 ZoneList<TextElement>* elements() { return &elements_; }
2792 private:
2793 ZoneList<TextElement> elements_;
2794 int length_;
2795};
2796
2797
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002798class RegExpQuantifier FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002799 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002800 enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
2801 RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
Leon Clarkee46be812010-01-19 14:06:41 +00002802 : body_(body),
2803 min_(min),
Steve Blocka7e24c12009-10-30 11:49:00 +00002804 max_(max),
Leon Clarkee46be812010-01-19 14:06:41 +00002805 min_match_(min * body->min_match()),
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002806 quantifier_type_(type) {
Steve Blocka7e24c12009-10-30 11:49:00 +00002807 if (max > 0 && body->max_match() > kInfinity / max) {
2808 max_match_ = kInfinity;
2809 } else {
2810 max_match_ = max * body->max_match();
2811 }
2812 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002813 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002814 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002815 RegExpNode* on_success) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002816 static RegExpNode* ToNode(int min,
2817 int max,
2818 bool is_greedy,
2819 RegExpTree* body,
2820 RegExpCompiler* compiler,
2821 RegExpNode* on_success,
2822 bool not_at_start = false);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002823 virtual RegExpQuantifier* AsQuantifier() OVERRIDE;
2824 virtual Interval CaptureRegisters() OVERRIDE;
2825 virtual bool IsQuantifier() OVERRIDE;
2826 virtual int min_match() OVERRIDE { return min_match_; }
2827 virtual int max_match() OVERRIDE { return max_match_; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002828 int min() { return min_; }
2829 int max() { return max_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002830 bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
2831 bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
2832 bool is_greedy() { return quantifier_type_ == GREEDY; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002833 RegExpTree* body() { return body_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002834
Steve Blocka7e24c12009-10-30 11:49:00 +00002835 private:
Leon Clarkee46be812010-01-19 14:06:41 +00002836 RegExpTree* body_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002837 int min_;
2838 int max_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002839 int min_match_;
2840 int max_match_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002841 QuantifierType quantifier_type_;
Steve Blocka7e24c12009-10-30 11:49:00 +00002842};
2843
2844
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002845class RegExpCapture FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002846 public:
2847 explicit RegExpCapture(RegExpTree* body, int index)
2848 : body_(body), index_(index) { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002849 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002850 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002851 RegExpNode* on_success) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002852 static RegExpNode* ToNode(RegExpTree* body,
2853 int index,
2854 RegExpCompiler* compiler,
2855 RegExpNode* on_success);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002856 virtual RegExpCapture* AsCapture() OVERRIDE;
2857 virtual bool IsAnchoredAtStart() OVERRIDE;
2858 virtual bool IsAnchoredAtEnd() OVERRIDE;
2859 virtual Interval CaptureRegisters() OVERRIDE;
2860 virtual bool IsCapture() OVERRIDE;
2861 virtual int min_match() OVERRIDE { return body_->min_match(); }
2862 virtual int max_match() OVERRIDE { return body_->max_match(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002863 RegExpTree* body() { return body_; }
2864 int index() { return index_; }
2865 static int StartRegister(int index) { return index * 2; }
2866 static int EndRegister(int index) { return index * 2 + 1; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002867
Steve Blocka7e24c12009-10-30 11:49:00 +00002868 private:
2869 RegExpTree* body_;
2870 int index_;
2871};
2872
2873
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002874class RegExpLookahead FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002875 public:
2876 RegExpLookahead(RegExpTree* body,
2877 bool is_positive,
2878 int capture_count,
2879 int capture_from)
2880 : body_(body),
2881 is_positive_(is_positive),
2882 capture_count_(capture_count),
2883 capture_from_(capture_from) { }
2884
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002885 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002886 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002887 RegExpNode* on_success) OVERRIDE;
2888 virtual RegExpLookahead* AsLookahead() OVERRIDE;
2889 virtual Interval CaptureRegisters() OVERRIDE;
2890 virtual bool IsLookahead() OVERRIDE;
2891 virtual bool IsAnchoredAtStart() OVERRIDE;
2892 virtual int min_match() OVERRIDE { return 0; }
2893 virtual int max_match() OVERRIDE { return 0; }
Steve Blocka7e24c12009-10-30 11:49:00 +00002894 RegExpTree* body() { return body_; }
2895 bool is_positive() { return is_positive_; }
2896 int capture_count() { return capture_count_; }
2897 int capture_from() { return capture_from_; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +00002898
Steve Blocka7e24c12009-10-30 11:49:00 +00002899 private:
2900 RegExpTree* body_;
2901 bool is_positive_;
2902 int capture_count_;
2903 int capture_from_;
2904};
2905
2906
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002907class RegExpBackReference FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002908 public:
2909 explicit RegExpBackReference(RegExpCapture* capture)
2910 : capture_(capture) { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002911 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002912 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002913 RegExpNode* on_success) OVERRIDE;
2914 virtual RegExpBackReference* AsBackReference() OVERRIDE;
2915 virtual bool IsBackReference() OVERRIDE;
2916 virtual int min_match() OVERRIDE { return 0; }
2917 virtual int max_match() OVERRIDE { return capture_->max_match(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00002918 int index() { return capture_->index(); }
2919 RegExpCapture* capture() { return capture_; }
2920 private:
2921 RegExpCapture* capture_;
2922};
2923
2924
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002925class RegExpEmpty FINAL : public RegExpTree {
Steve Blocka7e24c12009-10-30 11:49:00 +00002926 public:
2927 RegExpEmpty() { }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002928 virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
Steve Blocka7e24c12009-10-30 11:49:00 +00002929 virtual RegExpNode* ToNode(RegExpCompiler* compiler,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002930 RegExpNode* on_success) OVERRIDE;
2931 virtual RegExpEmpty* AsEmpty() OVERRIDE;
2932 virtual bool IsEmpty() OVERRIDE;
2933 virtual int min_match() OVERRIDE { return 0; }
2934 virtual int max_match() OVERRIDE { return 0; }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002935 static RegExpEmpty* GetInstance() {
2936 static RegExpEmpty* instance = ::new RegExpEmpty();
2937 return instance;
2938 }
Steve Blocka7e24c12009-10-30 11:49:00 +00002939};
2940
2941
2942// ----------------------------------------------------------------------------
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002943// Out-of-line inline constructors (to side-step cyclic dependencies).
2944
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002945inline ModuleVariable::ModuleVariable(Zone* zone, VariableProxy* proxy, int pos)
2946 : Module(zone, proxy->interface(), pos),
Ben Murdoch3ef787d2012-04-12 10:51:47 +01002947 proxy_(proxy) {
2948}
2949
2950
2951// ----------------------------------------------------------------------------
Steve Blocka7e24c12009-10-30 11:49:00 +00002952// Basic visitor
2953// - leaf node visitors are abstract.
2954
2955class AstVisitor BASE_EMBEDDED {
2956 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002957 AstVisitor() {}
2958 virtual ~AstVisitor() {}
Steve Blocka7e24c12009-10-30 11:49:00 +00002959
Steve Block6ded16b2010-05-10 14:33:55 +01002960 // Stack overflow check and dynamic dispatch.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002961 virtual void Visit(AstNode* node) = 0;
Steve Blocka7e24c12009-10-30 11:49:00 +00002962
Steve Block6ded16b2010-05-10 14:33:55 +01002963 // Iteration left-to-right.
Steve Block3ce2e202009-11-05 08:53:23 +00002964 virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
Steve Blocka7e24c12009-10-30 11:49:00 +00002965 virtual void VisitStatements(ZoneList<Statement*>* statements);
2966 virtual void VisitExpressions(ZoneList<Expression*>* expressions);
2967
Ben Murdochb0fe1622011-05-05 13:52:32 +01002968 // Individual AST nodes.
Steve Blocka7e24c12009-10-30 11:49:00 +00002969#define DEF_VISIT(type) \
2970 virtual void Visit##type(type* node) = 0;
2971 AST_NODE_LIST(DEF_VISIT)
2972#undef DEF_VISIT
Steve Blocka7e24c12009-10-30 11:49:00 +00002973};
2974
Steve Block44f0eee2011-05-26 01:26:41 +01002975
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002976#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS() \
2977public: \
2978 virtual void Visit(AstNode* node) FINAL OVERRIDE { \
2979 if (!CheckStackOverflow()) node->Accept(this); \
2980 } \
2981 \
2982 void SetStackOverflow() { stack_overflow_ = true; } \
2983 void ClearStackOverflow() { stack_overflow_ = false; } \
2984 bool HasStackOverflow() const { return stack_overflow_; } \
2985 \
2986 bool CheckStackOverflow() { \
2987 if (stack_overflow_) return true; \
2988 StackLimitCheck check(zone_->isolate()); \
2989 if (!check.HasOverflowed()) return false; \
2990 return (stack_overflow_ = true); \
2991 } \
2992 \
2993private: \
2994 void InitializeAstVisitor(Zone* zone) { \
2995 zone_ = zone; \
2996 stack_overflow_ = false; \
2997 } \
2998 Zone* zone() { return zone_; } \
2999 Isolate* isolate() { return zone_->isolate(); } \
3000 \
3001 Zone* zone_; \
3002 bool stack_overflow_
3003
3004
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003005// ----------------------------------------------------------------------------
3006// Construction time visitor.
3007
3008class AstConstructionVisitor BASE_EMBEDDED {
3009 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003010 AstConstructionVisitor()
3011 : dont_crankshaft_reason_(kNoReason), dont_turbofan_reason_(kNoReason) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003012
3013 AstProperties* ast_properties() { return &properties_; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003014 BailoutReason dont_optimize_reason() {
3015 if (dont_turbofan_reason_ != kNoReason) {
3016 return dont_turbofan_reason_;
3017 } else {
3018 return dont_crankshaft_reason_;
3019 }
3020 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003021
3022 private:
3023 template<class> friend class AstNodeFactory;
3024
3025 // Node visitors.
3026#define DEF_VISIT(type) \
3027 void Visit##type(type* node);
3028 AST_NODE_LIST(DEF_VISIT)
3029#undef DEF_VISIT
3030
3031 void increase_node_count() { properties_.add_node_count(1); }
3032 void add_flag(AstPropertiesFlag flag) { properties_.flags()->Add(flag); }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003033 void set_dont_crankshaft_reason(BailoutReason reason) {
3034 dont_crankshaft_reason_ = reason;
3035 }
3036 void set_dont_turbofan_reason(BailoutReason reason) {
3037 dont_turbofan_reason_ = reason;
3038 }
3039
3040 void add_slot_node(FeedbackSlotInterface* slot_node) {
3041 int count = slot_node->ComputeFeedbackSlotCount();
3042 if (count > 0) {
3043 slot_node->SetFirstFeedbackSlot(properties_.feedback_slots());
3044 properties_.increase_feedback_slots(count);
3045 }
3046 }
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003047
3048 AstProperties properties_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003049 BailoutReason dont_crankshaft_reason_;
3050 BailoutReason dont_turbofan_reason_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003051};
3052
3053
3054class AstNullVisitor BASE_EMBEDDED {
3055 public:
3056 // Node visitors.
3057#define DEF_VISIT(type) \
3058 void Visit##type(type* node) {}
3059 AST_NODE_LIST(DEF_VISIT)
3060#undef DEF_VISIT
3061};
3062
3063
3064
3065// ----------------------------------------------------------------------------
3066// AstNode factory
3067
3068template<class Visitor>
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003069class AstNodeFactory FINAL BASE_EMBEDDED {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003070 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003071 AstNodeFactory(Zone* zone, AstValueFactory* ast_value_factory,
3072 AstNode::IdGen* id_gen)
3073 : zone_(zone), ast_value_factory_(ast_value_factory), id_gen_(id_gen) {}
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003074
3075 Visitor* visitor() { return &visitor_; }
3076
3077#define VISIT_AND_RETURN(NodeType, node) \
3078 visitor_.Visit##NodeType((node)); \
3079 return node;
3080
3081 VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
3082 VariableMode mode,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003083 Scope* scope,
3084 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003085 VariableDeclaration* decl =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003086 new(zone_) VariableDeclaration(zone_, proxy, mode, scope, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003087 VISIT_AND_RETURN(VariableDeclaration, decl)
3088 }
3089
3090 FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
3091 VariableMode mode,
3092 FunctionLiteral* fun,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003093 Scope* scope,
3094 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003095 FunctionDeclaration* decl =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003096 new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003097 VISIT_AND_RETURN(FunctionDeclaration, decl)
3098 }
3099
3100 ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
3101 Module* module,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003102 Scope* scope,
3103 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003104 ModuleDeclaration* decl =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003105 new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003106 VISIT_AND_RETURN(ModuleDeclaration, decl)
3107 }
3108
3109 ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
3110 Module* module,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003111 Scope* scope,
3112 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003113 ImportDeclaration* decl =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003114 new(zone_) ImportDeclaration(zone_, proxy, module, scope, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003115 VISIT_AND_RETURN(ImportDeclaration, decl)
3116 }
3117
3118 ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003119 Scope* scope,
3120 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003121 ExportDeclaration* decl =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003122 new(zone_) ExportDeclaration(zone_, proxy, scope, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003123 VISIT_AND_RETURN(ExportDeclaration, decl)
3124 }
3125
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003126 ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface, int pos) {
3127 ModuleLiteral* module =
3128 new(zone_) ModuleLiteral(zone_, body, interface, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003129 VISIT_AND_RETURN(ModuleLiteral, module)
3130 }
3131
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003132 ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
3133 ModuleVariable* module = new(zone_) ModuleVariable(zone_, proxy, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003134 VISIT_AND_RETURN(ModuleVariable, module)
3135 }
3136
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003137 ModulePath* NewModulePath(Module* origin, const AstRawString* name, int pos) {
3138 ModulePath* module = new (zone_) ModulePath(zone_, origin, name, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003139 VISIT_AND_RETURN(ModulePath, module)
3140 }
3141
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003142 ModuleUrl* NewModuleUrl(Handle<String> url, int pos) {
3143 ModuleUrl* module = new(zone_) ModuleUrl(zone_, url, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003144 VISIT_AND_RETURN(ModuleUrl, module)
3145 }
3146
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003147 Block* NewBlock(ZoneList<const AstRawString*>* labels,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003148 int capacity,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003149 bool is_initializer_block,
3150 int pos) {
3151 Block* block = new (zone_)
3152 Block(zone_, labels, capacity, is_initializer_block, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003153 VISIT_AND_RETURN(Block, block)
3154 }
3155
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003156#define STATEMENT_WITH_LABELS(NodeType) \
3157 NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
3158 NodeType* stmt = new (zone_) NodeType(zone_, labels, pos, id_gen_); \
3159 VISIT_AND_RETURN(NodeType, stmt); \
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003160 }
3161 STATEMENT_WITH_LABELS(DoWhileStatement)
3162 STATEMENT_WITH_LABELS(WhileStatement)
3163 STATEMENT_WITH_LABELS(ForStatement)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003164 STATEMENT_WITH_LABELS(SwitchStatement)
3165#undef STATEMENT_WITH_LABELS
3166
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003167 ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3168 ZoneList<const AstRawString*>* labels,
3169 int pos) {
3170 switch (visit_mode) {
3171 case ForEachStatement::ENUMERATE: {
3172 ForInStatement* stmt =
3173 new (zone_) ForInStatement(zone_, labels, pos, id_gen_);
3174 VISIT_AND_RETURN(ForInStatement, stmt);
3175 }
3176 case ForEachStatement::ITERATE: {
3177 ForOfStatement* stmt =
3178 new (zone_) ForOfStatement(zone_, labels, pos, id_gen_);
3179 VISIT_AND_RETURN(ForOfStatement, stmt);
3180 }
3181 }
3182 UNREACHABLE();
3183 return NULL;
3184 }
3185
3186 ModuleStatement* NewModuleStatement(
3187 VariableProxy* proxy, Block* body, int pos) {
3188 ModuleStatement* stmt = new(zone_) ModuleStatement(zone_, proxy, body, pos);
3189 VISIT_AND_RETURN(ModuleStatement, stmt)
3190 }
3191
3192 ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3193 ExpressionStatement* stmt =
3194 new(zone_) ExpressionStatement(zone_, expression, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003195 VISIT_AND_RETURN(ExpressionStatement, stmt)
3196 }
3197
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003198 ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3199 ContinueStatement* stmt = new(zone_) ContinueStatement(zone_, target, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003200 VISIT_AND_RETURN(ContinueStatement, stmt)
3201 }
3202
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003203 BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3204 BreakStatement* stmt = new(zone_) BreakStatement(zone_, target, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003205 VISIT_AND_RETURN(BreakStatement, stmt)
3206 }
3207
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003208 ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3209 ReturnStatement* stmt = new(zone_) ReturnStatement(zone_, expression, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003210 VISIT_AND_RETURN(ReturnStatement, stmt)
3211 }
3212
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003213 WithStatement* NewWithStatement(Scope* scope,
3214 Expression* expression,
3215 Statement* statement,
3216 int pos) {
3217 WithStatement* stmt = new(zone_) WithStatement(
3218 zone_, scope, expression, statement, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003219 VISIT_AND_RETURN(WithStatement, stmt)
3220 }
3221
3222 IfStatement* NewIfStatement(Expression* condition,
3223 Statement* then_statement,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003224 Statement* else_statement,
3225 int pos) {
3226 IfStatement* stmt = new (zone_) IfStatement(
3227 zone_, condition, then_statement, else_statement, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003228 VISIT_AND_RETURN(IfStatement, stmt)
3229 }
3230
3231 TryCatchStatement* NewTryCatchStatement(int index,
3232 Block* try_block,
3233 Scope* scope,
3234 Variable* variable,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003235 Block* catch_block,
3236 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003237 TryCatchStatement* stmt = new(zone_) TryCatchStatement(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003238 zone_, index, try_block, scope, variable, catch_block, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003239 VISIT_AND_RETURN(TryCatchStatement, stmt)
3240 }
3241
3242 TryFinallyStatement* NewTryFinallyStatement(int index,
3243 Block* try_block,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003244 Block* finally_block,
3245 int pos) {
3246 TryFinallyStatement* stmt = new(zone_) TryFinallyStatement(
3247 zone_, index, try_block, finally_block, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003248 VISIT_AND_RETURN(TryFinallyStatement, stmt)
3249 }
3250
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003251 DebuggerStatement* NewDebuggerStatement(int pos) {
3252 DebuggerStatement* stmt =
3253 new (zone_) DebuggerStatement(zone_, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003254 VISIT_AND_RETURN(DebuggerStatement, stmt)
3255 }
3256
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003257 EmptyStatement* NewEmptyStatement(int pos) {
3258 return new(zone_) EmptyStatement(zone_, pos);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003259 }
3260
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003261 CaseClause* NewCaseClause(
3262 Expression* label, ZoneList<Statement*>* statements, int pos) {
3263 CaseClause* clause =
3264 new (zone_) CaseClause(zone_, label, statements, pos, id_gen_);
3265 VISIT_AND_RETURN(CaseClause, clause)
3266 }
3267
3268 Literal* NewStringLiteral(const AstRawString* string, int pos) {
3269 Literal* lit = new (zone_)
3270 Literal(zone_, ast_value_factory_->NewString(string), pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003271 VISIT_AND_RETURN(Literal, lit)
3272 }
3273
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003274 // A JavaScript symbol (ECMA-262 edition 6).
3275 Literal* NewSymbolLiteral(const char* name, int pos) {
3276 Literal* lit = new (zone_)
3277 Literal(zone_, ast_value_factory_->NewSymbol(name), pos, id_gen_);
3278 VISIT_AND_RETURN(Literal, lit)
3279 }
3280
3281 Literal* NewNumberLiteral(double number, int pos) {
3282 Literal* lit = new (zone_)
3283 Literal(zone_, ast_value_factory_->NewNumber(number), pos, id_gen_);
3284 VISIT_AND_RETURN(Literal, lit)
3285 }
3286
3287 Literal* NewSmiLiteral(int number, int pos) {
3288 Literal* lit = new (zone_)
3289 Literal(zone_, ast_value_factory_->NewSmi(number), pos, id_gen_);
3290 VISIT_AND_RETURN(Literal, lit)
3291 }
3292
3293 Literal* NewBooleanLiteral(bool b, int pos) {
3294 Literal* lit = new (zone_)
3295 Literal(zone_, ast_value_factory_->NewBoolean(b), pos, id_gen_);
3296 VISIT_AND_RETURN(Literal, lit)
3297 }
3298
3299 Literal* NewStringListLiteral(ZoneList<const AstRawString*>* strings,
3300 int pos) {
3301 Literal* lit = new (zone_) Literal(
3302 zone_, ast_value_factory_->NewStringList(strings), pos, id_gen_);
3303 VISIT_AND_RETURN(Literal, lit)
3304 }
3305
3306 Literal* NewNullLiteral(int pos) {
3307 Literal* lit =
3308 new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos, id_gen_);
3309 VISIT_AND_RETURN(Literal, lit)
3310 }
3311
3312 Literal* NewUndefinedLiteral(int pos) {
3313 Literal* lit = new (zone_)
3314 Literal(zone_, ast_value_factory_->NewUndefined(), pos, id_gen_);
3315 VISIT_AND_RETURN(Literal, lit)
3316 }
3317
3318 Literal* NewTheHoleLiteral(int pos) {
3319 Literal* lit = new (zone_)
3320 Literal(zone_, ast_value_factory_->NewTheHole(), pos, id_gen_);
3321 VISIT_AND_RETURN(Literal, lit)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003322 }
3323
3324 ObjectLiteral* NewObjectLiteral(
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003325 ZoneList<ObjectLiteral::Property*>* properties,
3326 int literal_index,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003327 int boilerplate_properties,
3328 bool has_function,
3329 int pos) {
3330 ObjectLiteral* lit = new (zone_)
3331 ObjectLiteral(zone_, properties, literal_index, boilerplate_properties,
3332 has_function, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003333 VISIT_AND_RETURN(ObjectLiteral, lit)
3334 }
3335
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003336 ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key,
3337 Expression* value,
3338 bool is_static) {
3339 return new (zone_) ObjectLiteral::Property(zone_, ast_value_factory_, key,
3340 value, is_static);
3341 }
3342
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003343 ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003344 FunctionLiteral* value,
3345 int pos, bool is_static) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003346 ObjectLiteral::Property* prop =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003347 new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static);
3348 prop->set_key(NewStringLiteral(value->raw_name(), pos));
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003349 return prop; // Not an AST node, will not be visited.
3350 }
3351
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003352 RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
3353 const AstRawString* flags,
3354 int literal_index,
3355 int pos) {
3356 RegExpLiteral* lit = new (zone_)
3357 RegExpLiteral(zone_, pattern, flags, literal_index, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003358 VISIT_AND_RETURN(RegExpLiteral, lit);
3359 }
3360
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003361 ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003362 int literal_index,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003363 int pos) {
3364 ArrayLiteral* lit =
3365 new (zone_) ArrayLiteral(zone_, values, literal_index, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003366 VISIT_AND_RETURN(ArrayLiteral, lit)
3367 }
3368
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003369 VariableProxy* NewVariableProxy(Variable* var,
3370 int pos = RelocInfo::kNoPosition) {
3371 VariableProxy* proxy = new (zone_) VariableProxy(zone_, var, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003372 VISIT_AND_RETURN(VariableProxy, proxy)
3373 }
3374
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003375 VariableProxy* NewVariableProxy(const AstRawString* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003376 bool is_this,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003377 Interface* interface = Interface::NewValue(),
3378 int position = RelocInfo::kNoPosition) {
3379 VariableProxy* proxy = new (zone_)
3380 VariableProxy(zone_, name, is_this, interface, position, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003381 VISIT_AND_RETURN(VariableProxy, proxy)
3382 }
3383
3384 Property* NewProperty(Expression* obj, Expression* key, int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003385 Property* prop = new (zone_) Property(zone_, obj, key, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003386 VISIT_AND_RETURN(Property, prop)
3387 }
3388
3389 Call* NewCall(Expression* expression,
3390 ZoneList<Expression*>* arguments,
3391 int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003392 Call* call = new (zone_) Call(zone_, expression, arguments, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003393 VISIT_AND_RETURN(Call, call)
3394 }
3395
3396 CallNew* NewCallNew(Expression* expression,
3397 ZoneList<Expression*>* arguments,
3398 int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003399 CallNew* call =
3400 new (zone_) CallNew(zone_, expression, arguments, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003401 VISIT_AND_RETURN(CallNew, call)
3402 }
3403
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003404 CallRuntime* NewCallRuntime(const AstRawString* name,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003405 const Runtime::Function* function,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003406 ZoneList<Expression*>* arguments,
3407 int pos) {
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003408 CallRuntime* call =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003409 new (zone_) CallRuntime(zone_, name, function, arguments, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003410 VISIT_AND_RETURN(CallRuntime, call)
3411 }
3412
3413 UnaryOperation* NewUnaryOperation(Token::Value op,
3414 Expression* expression,
3415 int pos) {
3416 UnaryOperation* node =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003417 new (zone_) UnaryOperation(zone_, op, expression, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003418 VISIT_AND_RETURN(UnaryOperation, node)
3419 }
3420
3421 BinaryOperation* NewBinaryOperation(Token::Value op,
3422 Expression* left,
3423 Expression* right,
3424 int pos) {
3425 BinaryOperation* node =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003426 new (zone_) BinaryOperation(zone_, op, left, right, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003427 VISIT_AND_RETURN(BinaryOperation, node)
3428 }
3429
3430 CountOperation* NewCountOperation(Token::Value op,
3431 bool is_prefix,
3432 Expression* expr,
3433 int pos) {
3434 CountOperation* node =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003435 new (zone_) CountOperation(zone_, op, is_prefix, expr, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003436 VISIT_AND_RETURN(CountOperation, node)
3437 }
3438
3439 CompareOperation* NewCompareOperation(Token::Value op,
3440 Expression* left,
3441 Expression* right,
3442 int pos) {
3443 CompareOperation* node =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003444 new (zone_) CompareOperation(zone_, op, left, right, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003445 VISIT_AND_RETURN(CompareOperation, node)
3446 }
3447
3448 Conditional* NewConditional(Expression* condition,
3449 Expression* then_expression,
3450 Expression* else_expression,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003451 int position) {
3452 Conditional* cond = new (zone_) Conditional(
3453 zone_, condition, then_expression, else_expression, position, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003454 VISIT_AND_RETURN(Conditional, cond)
3455 }
3456
3457 Assignment* NewAssignment(Token::Value op,
3458 Expression* target,
3459 Expression* value,
3460 int pos) {
3461 Assignment* assign =
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003462 new (zone_) Assignment(zone_, op, target, value, pos, id_gen_);
3463 assign->Init(zone_, this);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003464 VISIT_AND_RETURN(Assignment, assign)
3465 }
3466
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003467 Yield* NewYield(Expression *generator_object,
3468 Expression* expression,
3469 Yield::Kind yield_kind,
3470 int pos) {
3471 if (!expression) expression = NewUndefinedLiteral(pos);
3472 Yield* yield = new (zone_)
3473 Yield(zone_, generator_object, expression, yield_kind, pos, id_gen_);
3474 VISIT_AND_RETURN(Yield, yield)
3475 }
3476
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003477 Throw* NewThrow(Expression* exception, int pos) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003478 Throw* t = new (zone_) Throw(zone_, exception, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003479 VISIT_AND_RETURN(Throw, t)
3480 }
3481
3482 FunctionLiteral* NewFunctionLiteral(
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003483 const AstRawString* name, AstValueFactory* ast_value_factory,
3484 Scope* scope, ZoneList<Statement*>* body, int materialized_literal_count,
3485 int expected_property_count, int handler_count, int parameter_count,
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003486 FunctionLiteral::ParameterFlag has_duplicate_parameters,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003487 FunctionLiteral::FunctionType function_type,
3488 FunctionLiteral::IsFunctionFlag is_function,
3489 FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
3490 int position) {
3491 FunctionLiteral* lit = new (zone_) FunctionLiteral(
3492 zone_, name, ast_value_factory, scope, body, materialized_literal_count,
3493 expected_property_count, handler_count, parameter_count, function_type,
3494 has_duplicate_parameters, is_function, is_parenthesized, kind, position,
3495 id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003496 // Top-level literal doesn't count for the AST's properties.
3497 if (is_function == FunctionLiteral::kIsFunction) {
3498 visitor_.VisitFunctionLiteral(lit);
3499 }
3500 return lit;
3501 }
3502
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003503 ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends,
3504 Expression* constructor,
3505 ZoneList<ObjectLiteral::Property*>* properties,
3506 int position) {
3507 ClassLiteral* lit = new (zone_) ClassLiteral(
3508 zone_, name, extends, constructor, properties, position, id_gen_);
3509 VISIT_AND_RETURN(ClassLiteral, lit)
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003510 }
3511
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003512 NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
3513 v8::Extension* extension,
3514 int pos) {
3515 NativeFunctionLiteral* lit =
3516 new (zone_) NativeFunctionLiteral(zone_, name, extension, pos, id_gen_);
3517 VISIT_AND_RETURN(NativeFunctionLiteral, lit)
3518 }
3519
3520 ThisFunction* NewThisFunction(int pos) {
3521 ThisFunction* fun = new (zone_) ThisFunction(zone_, pos, id_gen_);
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003522 VISIT_AND_RETURN(ThisFunction, fun)
3523 }
3524
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003525 SuperReference* NewSuperReference(VariableProxy* this_var, int pos) {
3526 SuperReference* super =
3527 new (zone_) SuperReference(zone_, this_var, pos, id_gen_);
3528 VISIT_AND_RETURN(SuperReference, super);
3529 }
3530
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003531#undef VISIT_AND_RETURN
3532
3533 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003534 Zone* zone_;
3535 Visitor visitor_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00003536 AstValueFactory* ast_value_factory_;
3537 AstNode::IdGen* id_gen_;
Ben Murdoch3ef787d2012-04-12 10:51:47 +01003538};
3539
3540
Steve Blocka7e24c12009-10-30 11:49:00 +00003541} } // namespace v8::internal
3542
3543#endif // V8_AST_H_