ast.h 115 KB
Newer Older
1
// Copyright 2012 the V8 project authors. All rights reserved.
2 3
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
4 5 6 7

#ifndef V8_AST_H_
#define V8_AST_H_

8
#include "src/v8.h"
9

10
#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/interface.h"
15 16 17
#include "src/isolate.h"
#include "src/jsregexp.h"
#include "src/list-inl.h"
18
#include "src/runtime/runtime.h"
19 20 21 22 23 24 25
#include "src/small-pointer-list.h"
#include "src/smart-pointers.h"
#include "src/token.h"
#include "src/types.h"
#include "src/utils.h"
#include "src/variables.h"
#include "src/zone-inl.h"
26

27 28
namespace v8 {
namespace internal {
29 30 31 32 33 34 35 36 37 38 39 40 41 42

// The abstract syntax tree is an intermediate, light-weight
// representation of the parsed JavaScript code suitable for
// compilation to native code.

// Nodes are allocated in a separate zone, which allows faster
// allocation and constant-time deallocation of the entire syntax
// tree.


// ----------------------------------------------------------------------------
// Nodes of the abstract syntax tree. Only concrete classes are
// enumerated here.

arv@chromium.org's avatar
arv@chromium.org committed
43 44 45 46 47 48
#define DECLARATION_NODE_LIST(V) \
  V(VariableDeclaration)         \
  V(FunctionDeclaration)         \
  V(ModuleDeclaration)           \
  V(ImportDeclaration)           \
  V(ExportDeclaration)
49 50 51 52 53 54

#define MODULE_NODE_LIST(V)                     \
  V(ModuleLiteral)                              \
  V(ModuleVariable)                             \
  V(ModulePath)                                 \
  V(ModuleUrl)
55

56
#define STATEMENT_NODE_LIST(V)                  \
57
  V(Block)                                      \
58
  V(ModuleStatement)                            \
59 60 61 62 63 64
  V(ExpressionStatement)                        \
  V(EmptyStatement)                             \
  V(IfStatement)                                \
  V(ContinueStatement)                          \
  V(BreakStatement)                             \
  V(ReturnStatement)                            \
65
  V(WithStatement)                              \
66
  V(SwitchStatement)                            \
67 68 69
  V(DoWhileStatement)                           \
  V(WhileStatement)                             \
  V(ForStatement)                               \
70
  V(ForInStatement)                             \
71
  V(ForOfStatement)                             \
72 73
  V(TryCatchStatement)                          \
  V(TryFinallyStatement)                        \
74 75
  V(DebuggerStatement)

arv@chromium.org's avatar
arv@chromium.org committed
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98
#define EXPRESSION_NODE_LIST(V) \
  V(FunctionLiteral)            \
  V(ClassLiteral)               \
  V(NativeFunctionLiteral)      \
  V(Conditional)                \
  V(VariableProxy)              \
  V(Literal)                    \
  V(RegExpLiteral)              \
  V(ObjectLiteral)              \
  V(ArrayLiteral)               \
  V(Assignment)                 \
  V(Yield)                      \
  V(Throw)                      \
  V(Property)                   \
  V(Call)                       \
  V(CallNew)                    \
  V(CallRuntime)                \
  V(UnaryOperation)             \
  V(CountOperation)             \
  V(BinaryOperation)            \
  V(CompareOperation)           \
  V(ThisFunction)               \
  V(SuperReference)             \
99 100
  V(CaseClause)

101
#define AST_NODE_LIST(V)                        \
102
  DECLARATION_NODE_LIST(V)                      \
103
  MODULE_NODE_LIST(V)                           \
104
  STATEMENT_NODE_LIST(V)                        \
105
  EXPRESSION_NODE_LIST(V)
106

107
// Forward declarations
108 109
class AstConstructionVisitor;
template<class> class AstNodeFactory;
110
class AstVisitor;
111
class Declaration;
112
class Module;
113 114 115
class BreakableStatement;
class Expression;
class IterationStatement;
116
class MaterializedLiteral;
117
class Statement;
118 119
class TargetCollector;
class TypeFeedbackOracle;
120

121 122 123 124 125 126 127 128 129 130 131 132 133
class RegExpAlternative;
class RegExpAssertion;
class RegExpAtom;
class RegExpBackReference;
class RegExpCapture;
class RegExpCharacterClass;
class RegExpCompiler;
class RegExpDisjunction;
class RegExpEmpty;
class RegExpLookahead;
class RegExpQuantifier;
class RegExpText;

134
#define DEF_FORWARD_DECLARATION(type) class type;
135
AST_NODE_LIST(DEF_FORWARD_DECLARATION)
136 137 138 139 140 141
#undef DEF_FORWARD_DECLARATION


// Typedef only introduced to avoid unreadable code.
// Please do appreciate the required space in "> >".
typedef ZoneList<Handle<String> > ZoneStringList;
142
typedef ZoneList<Handle<Object> > ZoneObjectList;
143 144


145
#define DECLARE_NODE_TYPE(type)                                 \
146 147
  virtual void Accept(AstVisitor* v) OVERRIDE;                  \
  virtual AstNode::NodeType node_type() const FINAL OVERRIDE {  \
148 149
    return AstNode::k##type;                                    \
  }                                                             \
150
  template<class> friend class AstNodeFactory;
151 152 153 154


enum AstPropertiesFlag {
  kDontSelfOptimize,
155 156
  kDontSoftInline,
  kDontCache
157 158 159
};


160 161 162 163 164 165 166 167 168 169 170 171 172 173
class FeedbackVectorRequirements {
 public:
  FeedbackVectorRequirements(int slots, int ic_slots)
      : slots_(slots), ic_slots_(ic_slots) {}

  int slots() const { return slots_; }
  int ic_slots() const { return ic_slots_; }

 private:
  int slots_;
  int ic_slots_;
};


174
class AstProperties FINAL BASE_EMBEDDED {
175 176 177
 public:
  class Flags : public EnumSet<AstPropertiesFlag, int> {};

178
  AstProperties() : node_count_(0), feedback_slots_(0), ic_feedback_slots_(0) {}
179 180 181 182 183

  Flags* flags() { return &flags_; }
  int node_count() { return node_count_; }
  void add_node_count(int count) { node_count_ += count; }

184 185 186 187 188
  int feedback_slots() const { return feedback_slots_; }
  void increase_feedback_slots(int count) {
    feedback_slots_ += count;
  }

189 190 191
  int ic_feedback_slots() const { return ic_feedback_slots_; }
  void increase_ic_feedback_slots(int count) { ic_feedback_slots_ += count; }

192 193 194
 private:
  Flags flags_;
  int node_count_;
195
  int feedback_slots_;
196
  int ic_feedback_slots_;
197 198 199
};


200
class AstNode: public ZoneObject {
201
 public:
202
#define DECLARE_TYPE_ENUM(type) k##type,
203
  enum NodeType {
204 205 206 207 208
    AST_NODE_LIST(DECLARE_TYPE_ENUM)
    kInvalid = -1
  };
#undef DECLARE_TYPE_ENUM

209
  void* operator new(size_t size, Zone* zone) {
vitalyr@chromium.org's avatar
vitalyr@chromium.org committed
210
    return zone->New(static_cast<int>(size));
211
  }
212

213
  explicit AstNode(int position): position_(position) {}
214
  virtual ~AstNode() {}
215

216
  virtual void Accept(AstVisitor* v) = 0;
217
  virtual NodeType node_type() const = 0;
218
  int position() const { return position_; }
219 220

  // Type testing & conversion functions overridden by concrete subclasses.
221 222 223 224 225 226 227 228
#define DECLARE_NODE_FUNCTIONS(type) \
  bool Is##type() const { return node_type() == AstNode::k##type; } \
  type* As##type() { \
    return Is##type() ? reinterpret_cast<type*>(this) : NULL; \
  } \
  const type* As##type() const { \
    return Is##type() ? reinterpret_cast<const type*>(this) : NULL; \
  }
229 230
  AST_NODE_LIST(DECLARE_NODE_FUNCTIONS)
#undef DECLARE_NODE_FUNCTIONS
231

232
  virtual TargetCollector* AsTargetCollector() { return NULL; }
233 234
  virtual BreakableStatement* AsBreakableStatement() { return NULL; }
  virtual IterationStatement* AsIterationStatement() { return NULL; }
235
  virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
236

237 238 239 240
  // The interface for feedback slots, with default no-op implementations for
  // node types which don't actually have this. Note that this is conceptually
  // not really nice, but multiple inheritance would introduce yet another
  // vtable entry per node, something we don't want for space reasons.
241 242
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() {
    return FeedbackVectorRequirements(0, 0);
243
  }
244
  virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) { UNREACHABLE(); }
245 246 247
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) {
    UNREACHABLE();
  }
248

249 250 251 252 253
 private:
  // Hidden to prevent accidental usage. It would have to load the
  // current zone from the TLS.
  void* operator new(size_t size);

254
  friend class CaseClause;  // Generates AST IDs.
255 256

  int position_;
257 258 259
};


260
class Statement : public AstNode {
261
 public:
262
  explicit Statement(Zone* zone, int position) : AstNode(position) {}
263

264
  bool IsEmpty() { return AsEmptyStatement() != NULL; }
265
  virtual bool IsJump() const { return false; }
266 267 268
};


269
class SmallMapList FINAL {
270 271
 public:
  SmallMapList() {}
272
  SmallMapList(int capacity, Zone* zone) : list_(capacity, zone) {}
273

274
  void Reserve(int capacity, Zone* zone) { list_.Reserve(capacity, zone); }
275
  void Clear() { list_.Clear(); }
276
  void Sort() { list_.Sort(); }
277 278 279 280

  bool is_empty() const { return list_.is_empty(); }
  int length() const { return list_.length(); }

281
  void AddMapIfMissing(Handle<Map> map, Zone* zone) {
282
    if (!Map::TryUpdate(map).ToHandle(&map)) return;
283 284 285 286 287 288
    for (int i = 0; i < length(); ++i) {
      if (at(i).is_identical_to(map)) return;
    }
    Add(map, zone);
  }

289 290 291 292 293 294 295 296
  void FilterForPossibleTransitions(Map* root_map) {
    for (int i = list_.length() - 1; i >= 0; i--) {
      if (at(i)->FindRootMap() != root_map) {
        list_.RemoveElement(list_.at(i));
      }
    }
  }

297 298
  void Add(Handle<Map> handle, Zone* zone) {
    list_.Add(handle.location(), zone);
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315
  }

  Handle<Map> at(int i) const {
    return Handle<Map>(list_.at(i));
  }

  Handle<Map> first() const { return at(0); }
  Handle<Map> last() const { return at(length() - 1); }

 private:
  // The list stores pointers to Map*, that is Map**, so it's GC safe.
  SmallPointerList<Map*> list_;

  DISALLOW_COPY_AND_ASSIGN(SmallMapList);
};


316
class Expression : public AstNode {
317
 public:
318 319 320 321 322 323 324 325 326 327 328 329
  enum Context {
    // Not assigned a context yet, or else will not be visited during
    // code generation.
    kUninitialized,
    // Evaluated for its side effects.
    kEffect,
    // Evaluated for its value (and side effects).
    kValue,
    // Evaluated for control flow (and side effects).
    kTest
  };

330
  virtual bool IsValidReferenceExpression() const { return false; }
331

332
  // Helpers for ToBoolean conversion.
333 334
  virtual bool ToBooleanIsTrue() const { return false; }
  virtual bool ToBooleanIsFalse() const { return false; }
335

336 337 338
  // Symbols that cannot be parsed as array indices are considered property
  // names.  We do not treat symbols that can be array indexes as property
  // names because [] for string objects is handled only by keyed ICs.
339
  virtual bool IsPropertyName() const { return false; }
340

341 342
  // True iff the result can be safely overwritten (to avoid allocation).
  // False for operations that can return one of their operands.
343
  virtual bool ResultOverwriteAllowed() const { return false; }
344

345
  // True iff the expression is a literal represented as a smi.
346
  bool IsSmiLiteral() const;
347

348
  // True iff the expression is a string literal.
349
  bool IsStringLiteral() const;
350 351

  // True iff the expression is the null literal.
352
  bool IsNullLiteral() const;
353

354
  // True if we can prove that the expression is the undefined literal.
355
  bool IsUndefinedLiteral(Isolate* isolate) const;
356

357
  // Expression type bounds
358
  Bounds bounds() const { return bounds_; }
359
  void set_bounds(Bounds bounds) { bounds_ = bounds; }
360

361
  // Whether the expression is parenthesized
362 363 364 365 366 367
  bool is_parenthesized() const {
    return IsParenthesizedField::decode(bit_field_);
  }
  bool is_multi_parenthesized() const {
    return IsMultiParenthesizedField::decode(bit_field_);
  }
368
  void increase_parenthesization_level() {
369 370 371
    bit_field_ =
        IsMultiParenthesizedField::update(bit_field_, is_parenthesized());
    bit_field_ = IsParenthesizedField::update(bit_field_, true);
372
  }
373

374 375 376 377 378
  // Type feedback information for assignments and properties.
  virtual bool IsMonomorphic() {
    UNREACHABLE();
    return false;
  }
379
  virtual SmallMapList* GetReceiverTypes() {
380 381 382
    UNREACHABLE();
    return NULL;
  }
383
  virtual KeyedAccessStoreMode GetStoreMode() const {
384 385 386
    UNREACHABLE();
    return STANDARD_STORE;
  }
387
  virtual IcCheckType GetKeyType() const {
388 389 390
    UNREACHABLE();
    return ELEMENT;
  }
391

392
  // TODO(rossberg): this should move to its own AST node eventually.
393
  virtual void RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle);
394 395 396
  byte to_boolean_types() const {
    return ToBooleanTypesField::decode(bit_field_);
  }
397

398 399 400 401
  void set_base_id(int id) { base_id_ = id; }
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId id() const { return BailoutId(local_id(0)); }
  TypeFeedbackId test_id() const { return TypeFeedbackId(local_id(1)); }
402

403
 protected:
404
  Expression(Zone* zone, int pos)
405
      : AstNode(pos),
406
        base_id_(BailoutId::None().ToInt()),
407
        bounds_(Bounds::Unbounded(zone)),
408
        bit_field_(0) {}
409
  static int parent_num_ids() { return 0; }
410 411 412
  void set_to_boolean_types(byte types) {
    bit_field_ = ToBooleanTypesField::update(bit_field_, types);
  }
413

414 415 416 417
  int base_id() const {
    DCHECK(!BailoutId(base_id_).IsNone());
    return base_id_;
  }
418

419
 private:
420 421 422
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

  int base_id_;
423
  Bounds bounds_;
424 425 426 427 428 429
  class ToBooleanTypesField : public BitField16<byte, 0, 8> {};
  class IsParenthesizedField : public BitField16<bool, 8, 1> {};
  class IsMultiParenthesizedField : public BitField16<bool, 9, 1> {};
  uint16_t bit_field_;
  // Ends with 16-bit field; deriving classes in turn begin with
  // 16-bit fields for optimum packing efficiency.
430 431 432
};


433
class BreakableStatement : public Statement {
434
 public:
435
  enum BreakableType {
436 437 438 439 440 441
    TARGET_FOR_ANONYMOUS,
    TARGET_FOR_NAMED_ONLY
  };

  // The labels associated with this statement. May be NULL;
  // if it is != NULL, guaranteed to contain at least one entry.
442
  ZoneList<const AstRawString*>* labels() const { return labels_; }
443 444

  // Type testing & conversion.
445
  virtual BreakableStatement* AsBreakableStatement() FINAL OVERRIDE {
446 447
    return this;
  }
448 449

  // Code generation
450
  Label* break_target() { return &break_target_; }
451 452

  // Testers.
453 454 455
  bool is_target_for_anonymous() const {
    return breakable_type_ == TARGET_FOR_ANONYMOUS;
  }
456

457 458 459 460
  void set_base_id(int id) { base_id_ = id; }
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId EntryId() const { return BailoutId(local_id(0)); }
  BailoutId ExitId() const { return BailoutId(local_id(1)); }
461

462
 protected:
463
  BreakableStatement(Zone* zone, ZoneList<const AstRawString*>* labels,
464
                     BreakableType breakable_type, int position)
465
      : Statement(zone, position),
466
        labels_(labels),
467
        breakable_type_(breakable_type),
468
        base_id_(BailoutId::None().ToInt()) {
469
    DCHECK(labels == NULL || labels->length() > 0);
470
  }
471
  static int parent_num_ids() { return 0; }
472

473 474 475 476
  int base_id() const {
    DCHECK(!BailoutId(base_id_).IsNone());
    return base_id_;
  }
477 478

 private:
479 480
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

481
  ZoneList<const AstRawString*>* labels_;
482
  BreakableType breakable_type_;
483
  Label break_target_;
484
  int base_id_;
485 486 487
};


488
class Block FINAL : public BreakableStatement {
489
 public:
490
  DECLARE_NODE_TYPE(Block)
491

492 493 494
  void AddStatement(Statement* statement, Zone* zone) {
    statements_.Add(statement, zone);
  }
495 496

  ZoneList<Statement*>* statements() { return &statements_; }
497
  bool is_initializer_block() const { return is_initializer_block_; }
498

499 500
  static int num_ids() { return parent_num_ids() + 1; }
  BailoutId DeclsId() const { return BailoutId(local_id(0)); }
501

502
  virtual bool IsJump() const OVERRIDE {
503 504 505 506
    return !statements_.is_empty() && statements_.last()->IsJump()
        && labels() == NULL;  // Good enough as an approximation...
  }

507 508
  Scope* scope() const { return scope_; }
  void set_scope(Scope* scope) { scope_ = scope; }
509

510
 protected:
511
  Block(Zone* zone, ZoneList<const AstRawString*>* labels, int capacity,
512 513
        bool is_initializer_block, int pos)
      : BreakableStatement(zone, labels, TARGET_FOR_NAMED_ONLY, pos),
514
        statements_(capacity, zone),
515
        is_initializer_block_(is_initializer_block),
516
        scope_(NULL) {}
517
  static int parent_num_ids() { return BreakableStatement::num_ids(); }
518

519
 private:
520 521
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

522 523
  ZoneList<Statement*> statements_;
  bool is_initializer_block_;
524
  Scope* scope_;
525 526 527
};


528
class Declaration : public AstNode {
529
 public:
530 531 532
  VariableProxy* proxy() const { return proxy_; }
  VariableMode mode() const { return mode_; }
  Scope* scope() const { return scope_; }
533
  virtual InitializationFlag initialization() const = 0;
534
  virtual bool IsInlineable() const;
535

536
 protected:
537
  Declaration(Zone* zone, VariableProxy* proxy, VariableMode mode, Scope* scope,
538
              int pos)
539
      : AstNode(pos), mode_(mode), proxy_(proxy), scope_(scope) {
540
    DCHECK(IsDeclaredVariableMode(mode));
541 542 543
  }

 private:
544
  VariableMode mode_;
545
  VariableProxy* proxy_;
546 547 548

  // Nested scope from which the declaration originated.
  Scope* scope_;
549 550 551
};


552
class VariableDeclaration FINAL : public Declaration {
553 554 555
 public:
  DECLARE_NODE_TYPE(VariableDeclaration)

556
  virtual InitializationFlag initialization() const OVERRIDE {
557 558 559 560
    return mode() == VAR ? kCreatedInitialized : kNeedsInitialization;
  }

 protected:
561 562
  VariableDeclaration(Zone* zone,
                      VariableProxy* proxy,
563
                      VariableMode mode,
564 565
                      Scope* scope,
                      int pos)
566
      : Declaration(zone, proxy, mode, scope, pos) {
567 568 569
  }
};

570

571
class FunctionDeclaration FINAL : public Declaration {
572 573 574 575
 public:
  DECLARE_NODE_TYPE(FunctionDeclaration)

  FunctionLiteral* fun() const { return fun_; }
576
  virtual InitializationFlag initialization() const OVERRIDE {
577 578
    return kCreatedInitialized;
  }
579
  virtual bool IsInlineable() const OVERRIDE;
580 581

 protected:
582 583
  FunctionDeclaration(Zone* zone,
                      VariableProxy* proxy,
584 585
                      VariableMode mode,
                      FunctionLiteral* fun,
586 587
                      Scope* scope,
                      int pos)
588
      : Declaration(zone, proxy, mode, scope, pos),
589
        fun_(fun) {
590
    // At the moment there are no "const functions" in JavaScript...
591 592
    DCHECK(mode == VAR || mode == LET);
    DCHECK(fun != NULL);
593 594 595 596 597 598 599
  }

 private:
  FunctionLiteral* fun_;
};


600
class ModuleDeclaration FINAL : public Declaration {
601 602 603 604
 public:
  DECLARE_NODE_TYPE(ModuleDeclaration)

  Module* module() const { return module_; }
605
  virtual InitializationFlag initialization() const OVERRIDE {
606 607
    return kCreatedInitialized;
  }
608 609

 protected:
610 611
  ModuleDeclaration(Zone* zone,
                    VariableProxy* proxy,
612
                    Module* module,
613 614
                    Scope* scope,
                    int pos)
615
      : Declaration(zone, proxy, MODULE, scope, pos),
616 617 618 619 620 621 622 623
        module_(module) {
  }

 private:
  Module* module_;
};


624
class ImportDeclaration FINAL : public Declaration {
625 626 627 628
 public:
  DECLARE_NODE_TYPE(ImportDeclaration)

  Module* module() const { return module_; }
629
  virtual InitializationFlag initialization() const OVERRIDE {
630 631 632 633
    return kCreatedInitialized;
  }

 protected:
634 635
  ImportDeclaration(Zone* zone,
                    VariableProxy* proxy,
636
                    Module* module,
637 638
                    Scope* scope,
                    int pos)
639
      : Declaration(zone, proxy, LET, scope, pos),
640 641 642 643 644 645 646 647
        module_(module) {
  }

 private:
  Module* module_;
};


648
class ExportDeclaration FINAL : public Declaration {
649 650 651
 public:
  DECLARE_NODE_TYPE(ExportDeclaration)

652
  virtual InitializationFlag initialization() const OVERRIDE {
653 654 655 656
    return kCreatedInitialized;
  }

 protected:
657 658
  ExportDeclaration(Zone* zone, VariableProxy* proxy, Scope* scope, int pos)
      : Declaration(zone, proxy, LET, scope, pos) {}
659 660 661
};


662
class Module : public AstNode {
663 664
 public:
  Interface* interface() const { return interface_; }
665
  Block* body() const { return body_; }
666

667
 protected:
668 669 670
  Module(Zone* zone, int pos)
      : AstNode(pos),
        interface_(Interface::NewModule(zone)),
671
        body_(NULL) {}
672
  Module(Zone* zone, Interface* interface, int pos, Block* body = NULL)
673 674
      : AstNode(pos),
        interface_(interface),
675
        body_(body) {}
676 677 678

 private:
  Interface* interface_;
679
  Block* body_;
680 681 682
};


683
class ModuleLiteral FINAL : public Module {
684 685 686 687
 public:
  DECLARE_NODE_TYPE(ModuleLiteral)

 protected:
688 689
  ModuleLiteral(Zone* zone, Block* body, Interface* interface, int pos)
      : Module(zone, interface, pos, body) {}
690 691 692
};


693
class ModuleVariable FINAL : public Module {
694 695 696
 public:
  DECLARE_NODE_TYPE(ModuleVariable)

697
  VariableProxy* proxy() const { return proxy_; }
698 699

 protected:
700
  inline ModuleVariable(Zone* zone, VariableProxy* proxy, int pos);
701 702

 private:
703
  VariableProxy* proxy_;
704 705 706
};


707
class ModulePath FINAL : public Module {
708 709 710 711
 public:
  DECLARE_NODE_TYPE(ModulePath)

  Module* module() const { return module_; }
712
  Handle<String> name() const { return name_->string(); }
713 714

 protected:
715 716
  ModulePath(Zone* zone, Module* module, const AstRawString* name, int pos)
      : Module(zone, pos), module_(module), name_(name) {}
717 718 719

 private:
  Module* module_;
720
  const AstRawString* name_;
721 722 723
};


724
class ModuleUrl FINAL : public Module {
725 726 727 728 729 730
 public:
  DECLARE_NODE_TYPE(ModuleUrl)

  Handle<String> url() const { return url_; }

 protected:
731
  ModuleUrl(Zone* zone, Handle<String> url, int pos)
732
      : Module(zone, pos), url_(url) {
733 734 735 736 737 738 739
  }

 private:
  Handle<String> url_;
};


740
class ModuleStatement FINAL : public Statement {
741 742 743 744 745 746 747
 public:
  DECLARE_NODE_TYPE(ModuleStatement)

  VariableProxy* proxy() const { return proxy_; }
  Block* body() const { return body_; }

 protected:
748 749
  ModuleStatement(Zone* zone, VariableProxy* proxy, Block* body, int pos)
      : Statement(zone, pos),
750
        proxy_(proxy),
751 752 753 754 755 756 757 758 759
        body_(body) {
  }

 private:
  VariableProxy* proxy_;
  Block* body_;
};


760
class IterationStatement : public BreakableStatement {
761 762
 public:
  // Type testing & conversion.
763
  virtual IterationStatement* AsIterationStatement() FINAL OVERRIDE {
764 765
    return this;
  }
766 767 768

  Statement* body() const { return body_; }

769 770
  static int num_ids() { return parent_num_ids() + 1; }
  BailoutId OsrEntryId() const { return BailoutId(local_id(0)); }
771 772
  virtual BailoutId ContinueId() const = 0;
  virtual BailoutId StackCheckId() const = 0;
773

774
  // Code generation
775
  Label* continue_target()  { return &continue_target_; }
776 777

 protected:
778 779
  IterationStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
780
        body_(NULL) {}
781 782
  static int parent_num_ids() { return BreakableStatement::num_ids(); }
  void Initialize(Statement* body) { body_ = body; }
783

784
 private:
785 786
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

787
  Statement* body_;
788
  Label continue_target_;
789 790 791
};


792
class DoWhileStatement FINAL : public IterationStatement {
793
 public:
794 795
  DECLARE_NODE_TYPE(DoWhileStatement)

796 797 798 799
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
    cond_ = cond;
  }
800

801 802
  Expression* cond() const { return cond_; }

803
  static int num_ids() { return parent_num_ids() + 2; }
804
  virtual BailoutId ContinueId() const OVERRIDE {
805
    return BailoutId(local_id(0));
806 807
  }
  virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
808
  BailoutId BackEdgeId() const { return BailoutId(local_id(1)); }
809

810
 protected:
811 812 813
  DoWhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : IterationStatement(zone, labels, pos), cond_(NULL) {}
  static int parent_num_ids() { return IterationStatement::num_ids(); }
814

815
 private:
816 817
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

818 819 820 821
  Expression* cond_;
};


822
class WhileStatement FINAL : public IterationStatement {
823
 public:
824 825
  DECLARE_NODE_TYPE(WhileStatement)

826 827 828 829 830 831 832
  void Initialize(Expression* cond, Statement* body) {
    IterationStatement::Initialize(body);
    cond_ = cond;
  }

  Expression* cond() const { return cond_; }

833
  static int num_ids() { return parent_num_ids() + 1; }
834
  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
835
  virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
836
  BailoutId BodyId() const { return BailoutId(local_id(0)); }
837

838
 protected:
839
  WhileStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
840
      : IterationStatement(zone, labels, pos), cond_(NULL) {}
841
  static int parent_num_ids() { return IterationStatement::num_ids(); }
842

843
 private:
844 845
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

846 847 848 849
  Expression* cond_;
};


850
class ForStatement FINAL : public IterationStatement {
851
 public:
852
  DECLARE_NODE_TYPE(ForStatement)
853 854 855 856 857 858 859 860 861 862 863

  void Initialize(Statement* init,
                  Expression* cond,
                  Statement* next,
                  Statement* body) {
    IterationStatement::Initialize(body);
    init_ = init;
    cond_ = cond;
    next_ = next;
  }

864 865 866
  Statement* init() const { return init_; }
  Expression* cond() const { return cond_; }
  Statement* next() const { return next_; }
867

868
  static int num_ids() { return parent_num_ids() + 2; }
869
  virtual BailoutId ContinueId() const OVERRIDE {
870
    return BailoutId(local_id(0));
871 872
  }
  virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
873
  BailoutId BodyId() const { return BailoutId(local_id(1)); }
874

875
 protected:
876 877
  ForStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : IterationStatement(zone, labels, pos),
878 879
        init_(NULL),
        cond_(NULL),
880
        next_(NULL) {}
881
  static int parent_num_ids() { return IterationStatement::num_ids(); }
882

883
 private:
884 885
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

886 887 888 889 890 891
  Statement* init_;
  Expression* cond_;
  Statement* next_;
};


892
class ForEachStatement : public IterationStatement {
893
 public:
894 895 896 897
  enum VisitMode {
    ENUMERATE,   // for (each in subject) body;
    ITERATE      // for (each of subject) body;
  };
898

899
  void Initialize(Expression* each, Expression* subject, Statement* body) {
900 901
    IterationStatement::Initialize(body);
    each_ = each;
902
    subject_ = subject;
903 904 905
  }

  Expression* each() const { return each_; }
906
  Expression* subject() const { return subject_; }
907

908
 protected:
909 910
  ForEachStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : IterationStatement(zone, labels, pos), each_(NULL), subject_(NULL) {}
911

912 913
 private:
  Expression* each_;
914 915 916 917
  Expression* subject_;
};


918
class ForInStatement FINAL : public ForEachStatement {
919 920 921 922 923 924 925
 public:
  DECLARE_NODE_TYPE(ForInStatement)

  Expression* enumerable() const {
    return subject();
  }

926
  // Type feedback information.
927
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
928 929
    return FeedbackVectorRequirements(1, 0);
  }
930
  virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
931 932
    for_in_feedback_slot_ = slot;
  }
933

934 935
  FeedbackVectorSlot ForInFeedbackSlot() {
    DCHECK(!for_in_feedback_slot_.IsInvalid());
936 937 938
    return for_in_feedback_slot_;
  }

939 940
  enum ForInType { FAST_FOR_IN, SLOW_FOR_IN };
  ForInType for_in_type() const { return for_in_type_; }
941
  void set_for_in_type(ForInType type) { for_in_type_ = type; }
942

943
  static int num_ids() { return parent_num_ids() + 4; }
944 945
  BailoutId BodyId() const { return BailoutId(local_id(0)); }
  BailoutId PrepareId() const { return BailoutId(local_id(1)); }
946 947
  BailoutId EnumId() const { return BailoutId(local_id(2)); }
  BailoutId ToObjectId() const { return BailoutId(local_id(3)); }
948
  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
949
  virtual BailoutId StackCheckId() const OVERRIDE { return BodyId(); }
950

951
 protected:
952 953
  ForInStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : ForEachStatement(zone, labels, pos),
954
        for_in_type_(SLOW_FOR_IN),
955
        for_in_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
956
  static int parent_num_ids() { return ForEachStatement::num_ids(); }
957

958
 private:
959 960
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

961
  ForInType for_in_type_;
962
  FeedbackVectorSlot for_in_feedback_slot_;
963
};
964

965

966
class ForOfStatement FINAL : public ForEachStatement {
967 968 969
 public:
  DECLARE_NODE_TYPE(ForOfStatement)

970 971 972 973 974 975 976 977 978 979 980 981 982 983
  void Initialize(Expression* each,
                  Expression* subject,
                  Statement* body,
                  Expression* assign_iterator,
                  Expression* next_result,
                  Expression* result_done,
                  Expression* assign_each) {
    ForEachStatement::Initialize(each, subject, body);
    assign_iterator_ = assign_iterator;
    next_result_ = next_result;
    result_done_ = result_done;
    assign_each_ = assign_each;
  }

984 985 986 987
  Expression* iterable() const {
    return subject();
  }

988
  // var iterator = subject[Symbol.iterator]();
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007
  Expression* assign_iterator() const {
    return assign_iterator_;
  }

  // var result = iterator.next();
  Expression* next_result() const {
    return next_result_;
  }

  // result.done
  Expression* result_done() const {
    return result_done_;
  }

  // each = result.value
  Expression* assign_each() const {
    return assign_each_;
  }

1008 1009
  virtual BailoutId ContinueId() const OVERRIDE { return EntryId(); }
  virtual BailoutId StackCheckId() const OVERRIDE { return BackEdgeId(); }
1010

1011 1012
  static int num_ids() { return parent_num_ids() + 1; }
  BailoutId BackEdgeId() const { return BailoutId(local_id(0)); }
1013

1014
 protected:
1015 1016
  ForOfStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : ForEachStatement(zone, labels, pos),
1017 1018 1019
        assign_iterator_(NULL),
        next_result_(NULL),
        result_done_(NULL),
1020
        assign_each_(NULL) {}
1021
  static int parent_num_ids() { return ForEachStatement::num_ids(); }
1022

1023
 private:
1024 1025
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1026 1027 1028 1029
  Expression* assign_iterator_;
  Expression* next_result_;
  Expression* result_done_;
  Expression* assign_each_;
1030 1031 1032
};


1033
class ExpressionStatement FINAL : public Statement {
1034
 public:
1035
  DECLARE_NODE_TYPE(ExpressionStatement)
1036 1037

  void set_expression(Expression* e) { expression_ = e; }
1038
  Expression* expression() const { return expression_; }
1039
  virtual bool IsJump() const OVERRIDE { return expression_->IsThrow(); }
1040

1041
 protected:
1042 1043
  ExpressionStatement(Zone* zone, Expression* expression, int pos)
      : Statement(zone, pos), expression_(expression) { }
1044

1045 1046 1047 1048 1049
 private:
  Expression* expression_;
};


1050
class JumpStatement : public Statement {
1051
 public:
1052
  virtual bool IsJump() const FINAL OVERRIDE { return true; }
1053 1054

 protected:
1055
  explicit JumpStatement(Zone* zone, int pos) : Statement(zone, pos) {}
1056 1057 1058
};


1059
class ContinueStatement FINAL : public JumpStatement {
1060
 public:
1061
  DECLARE_NODE_TYPE(ContinueStatement)
1062

1063
  IterationStatement* target() const { return target_; }
1064 1065

 protected:
1066 1067
  explicit ContinueStatement(Zone* zone, IterationStatement* target, int pos)
      : JumpStatement(zone, pos), target_(target) { }
1068 1069 1070 1071 1072 1073

 private:
  IterationStatement* target_;
};


1074
class BreakStatement FINAL : public JumpStatement {
1075
 public:
1076
  DECLARE_NODE_TYPE(BreakStatement)
1077

1078
  BreakableStatement* target() const { return target_; }
1079 1080

 protected:
1081 1082
  explicit BreakStatement(Zone* zone, BreakableStatement* target, int pos)
      : JumpStatement(zone, pos), target_(target) { }
1083 1084 1085 1086 1087 1088

 private:
  BreakableStatement* target_;
};


1089
class ReturnStatement FINAL : public JumpStatement {
1090
 public:
1091
  DECLARE_NODE_TYPE(ReturnStatement)
1092

1093
  Expression* expression() const { return expression_; }
1094 1095

 protected:
1096 1097
  explicit ReturnStatement(Zone* zone, Expression* expression, int pos)
      : JumpStatement(zone, pos), expression_(expression) { }
1098 1099 1100 1101 1102 1103

 private:
  Expression* expression_;
};


1104
class WithStatement FINAL : public Statement {
1105
 public:
1106
  DECLARE_NODE_TYPE(WithStatement)
1107

1108
  Scope* scope() { return scope_; }
1109
  Expression* expression() const { return expression_; }
1110
  Statement* statement() const { return statement_; }
1111

1112
 protected:
1113
  WithStatement(
1114 1115 1116
      Zone* zone, Scope* scope,
      Expression* expression, Statement* statement, int pos)
      : Statement(zone, pos),
1117
        scope_(scope),
1118
        expression_(expression),
1119
        statement_(statement) { }
1120

1121
 private:
1122
  Scope* scope_;
1123
  Expression* expression_;
1124
  Statement* statement_;
1125 1126 1127
};


1128
class CaseClause FINAL : public Expression {
1129
 public:
1130
  DECLARE_NODE_TYPE(CaseClause)
1131

1132 1133
  bool is_default() const { return label_ == NULL; }
  Expression* label() const {
1134 1135 1136
    CHECK(!is_default());
    return label_;
  }
1137
  Label* body_target() { return &body_target_; }
1138
  ZoneList<Statement*>* statements() const { return statements_; }
1139

1140 1141 1142
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId EntryId() const { return BailoutId(local_id(0)); }
  TypeFeedbackId CompareId() { return TypeFeedbackId(local_id(1)); }
1143

1144 1145
  Type* compare_type() { return compare_type_; }
  void set_compare_type(Type* type) { compare_type_ = type; }
1146

1147 1148 1149
 protected:
  static int parent_num_ids() { return Expression::num_ids(); }

1150
 private:
1151
  CaseClause(Zone* zone, Expression* label, ZoneList<Statement*>* statements,
1152 1153
             int pos);
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1154

1155
  Expression* label_;
1156
  Label body_target_;
1157
  ZoneList<Statement*>* statements_;
1158
  Type* compare_type_;
1159 1160 1161
};


1162
class SwitchStatement FINAL : public BreakableStatement {
1163
 public:
1164 1165
  DECLARE_NODE_TYPE(SwitchStatement)

1166 1167 1168 1169 1170
  void Initialize(Expression* tag, ZoneList<CaseClause*>* cases) {
    tag_ = tag;
    cases_ = cases;
  }

1171 1172
  Expression* tag() const { return tag_; }
  ZoneList<CaseClause*>* cases() const { return cases_; }
1173 1174

 protected:
1175 1176
  SwitchStatement(Zone* zone, ZoneList<const AstRawString*>* labels, int pos)
      : BreakableStatement(zone, labels, TARGET_FOR_ANONYMOUS, pos),
1177
        tag_(NULL),
1178
        cases_(NULL) {}
1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190

 private:
  Expression* tag_;
  ZoneList<CaseClause*>* cases_;
};


// If-statements always have non-null references to their then- and
// else-parts. When parsing if-statements with no explicit else-part,
// the parser implicitly creates an empty statement. Use the
// HasThenStatement() and HasElseStatement() functions to check if a
// given if-statement has a then- or an else-part containing code.
1191
class IfStatement FINAL : public Statement {
1192
 public:
1193
  DECLARE_NODE_TYPE(IfStatement)
1194 1195 1196 1197 1198 1199 1200 1201

  bool HasThenStatement() const { return !then_statement()->IsEmpty(); }
  bool HasElseStatement() const { return !else_statement()->IsEmpty(); }

  Expression* condition() const { return condition_; }
  Statement* then_statement() const { return then_statement_; }
  Statement* else_statement() const { return else_statement_; }

1202
  virtual bool IsJump() const OVERRIDE {
1203 1204 1205 1206
    return HasThenStatement() && then_statement()->IsJump()
        && HasElseStatement() && else_statement()->IsJump();
  }

1207 1208 1209 1210 1211
  void set_base_id(int id) { base_id_ = id; }
  static int num_ids() { return parent_num_ids() + 3; }
  BailoutId IfId() const { return BailoutId(local_id(0)); }
  BailoutId ThenId() const { return BailoutId(local_id(1)); }
  BailoutId ElseId() const { return BailoutId(local_id(2)); }
1212

1213
 protected:
1214
  IfStatement(Zone* zone, Expression* condition, Statement* then_statement,
1215
              Statement* else_statement, int pos)
1216
      : Statement(zone, pos),
1217
        condition_(condition),
1218 1219
        then_statement_(then_statement),
        else_statement_(else_statement),
1220 1221
        base_id_(BailoutId::None().ToInt()) {}
  static int parent_num_ids() { return 0; }
1222

1223 1224 1225 1226
  int base_id() const {
    DCHECK(!BailoutId(base_id_).IsNone());
    return base_id_;
  }
1227

1228
 private:
1229 1230
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1231 1232 1233
  Expression* condition_;
  Statement* then_statement_;
  Statement* else_statement_;
1234
  int base_id_;
1235 1236 1237
};


1238
// NOTE: TargetCollectors are represented as nodes to fit in the target
1239
// stack in the compiler; this should probably be reworked.
1240
class TargetCollector FINAL : public AstNode {
1241
 public:
1242 1243
  explicit TargetCollector(Zone* zone)
      : AstNode(RelocInfo::kNoPosition), targets_(0, zone) { }
1244

1245 1246 1247
  // Adds a jump target to the collector. The collector stores a pointer not
  // a copy of the target to make binding work, so make sure not to pass in
  // references to something on the stack.
1248
  void AddTarget(Label* target, Zone* zone);
1249

1250
  // Virtual behaviour. TargetCollectors are never part of the AST.
1251 1252 1253
  virtual void Accept(AstVisitor* v) OVERRIDE { UNREACHABLE(); }
  virtual NodeType node_type() const OVERRIDE { return kInvalid; }
  virtual TargetCollector* AsTargetCollector() OVERRIDE { return this; }
1254

1255
  ZoneList<Label*>* targets() { return &targets_; }
1256 1257

 private:
1258
  ZoneList<Label*> targets_;
1259 1260 1261
};


1262
class TryStatement : public Statement {
1263
 public:
1264
  void set_escaping_targets(ZoneList<Label*>* targets) {
1265
    escaping_targets_ = targets;
1266 1267
  }

1268
  int index() const { return index_; }
1269
  Block* try_block() const { return try_block_; }
1270
  ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
1271 1272

 protected:
1273 1274
  TryStatement(Zone* zone, int index, Block* try_block, int pos)
      : Statement(zone, pos),
1275
        index_(index),
1276 1277
        try_block_(try_block),
        escaping_targets_(NULL) { }
1278 1279

 private:
1280 1281 1282
  // Unique (per-function) index of this handler.  This is not an AST ID.
  int index_;

1283
  Block* try_block_;
1284
  ZoneList<Label*>* escaping_targets_;
1285 1286 1287
};


1288
class TryCatchStatement FINAL : public TryStatement {
1289
 public:
1290 1291 1292 1293 1294 1295 1296
  DECLARE_NODE_TYPE(TryCatchStatement)

  Scope* scope() { return scope_; }
  Variable* variable() { return variable_; }
  Block* catch_block() const { return catch_block_; }

 protected:
1297 1298
  TryCatchStatement(Zone* zone,
                    int index,
1299
                    Block* try_block,
1300 1301
                    Scope* scope,
                    Variable* variable,
1302 1303
                    Block* catch_block,
                    int pos)
1304
      : TryStatement(zone, index, try_block, pos),
1305 1306
        scope_(scope),
        variable_(variable),
1307 1308 1309 1310
        catch_block_(catch_block) {
  }

 private:
1311 1312
  Scope* scope_;
  Variable* variable_;
1313 1314 1315 1316
  Block* catch_block_;
};


1317
class TryFinallyStatement FINAL : public TryStatement {
1318
 public:
1319
  DECLARE_NODE_TYPE(TryFinallyStatement)
1320 1321

  Block* finally_block() const { return finally_block_; }
1322 1323

 protected:
1324
  TryFinallyStatement(
1325 1326
      Zone* zone, int index, Block* try_block, Block* finally_block, int pos)
      : TryStatement(zone, index, try_block, pos),
1327
        finally_block_(finally_block) { }
1328 1329 1330 1331 1332 1333

 private:
  Block* finally_block_;
};


1334
class DebuggerStatement FINAL : public Statement {
1335
 public:
1336
  DECLARE_NODE_TYPE(DebuggerStatement)
1337

1338 1339 1340
  void set_base_id(int id) { base_id_ = id; }
  static int num_ids() { return parent_num_ids() + 1; }
  BailoutId DebugBreakId() const { return BailoutId(local_id(0)); }
1341

1342
 protected:
1343 1344 1345
  explicit DebuggerStatement(Zone* zone, int pos)
      : Statement(zone, pos), base_id_(BailoutId::None().ToInt()) {}
  static int parent_num_ids() { return 0; }
1346

1347 1348 1349 1350
  int base_id() const {
    DCHECK(!BailoutId(base_id_).IsNone());
    return base_id_;
  }
1351 1352

 private:
1353 1354 1355
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

  int base_id_;
1356 1357 1358
};


1359
class EmptyStatement FINAL : public Statement {
1360
 public:
1361
  DECLARE_NODE_TYPE(EmptyStatement)
1362

1363
 protected:
1364
  explicit EmptyStatement(Zone* zone, int pos): Statement(zone, pos) {}
1365 1366 1367
};


1368
class Literal FINAL : public Expression {
1369
 public:
1370 1371
  DECLARE_NODE_TYPE(Literal)

1372
  virtual bool IsPropertyName() const OVERRIDE {
1373
    return value_->IsPropertyName();
1374 1375
  }

1376
  Handle<String> AsPropertyName() {
1377
    DCHECK(IsPropertyName());
1378 1379 1380 1381
    return Handle<String>::cast(value());
  }

  const AstRawString* AsRawPropertyName() {
1382
    DCHECK(IsPropertyName());
1383
    return value_->AsString();
1384 1385
  }

1386
  virtual bool ToBooleanIsTrue() const OVERRIDE {
1387
    return value()->BooleanValue();
1388
  }
1389
  virtual bool ToBooleanIsFalse() const OVERRIDE {
1390
    return !value()->BooleanValue();
1391
  }
1392

1393 1394
  Handle<Object> value() const { return value_->value(); }
  const AstValue* raw_value() const { return value_; }
1395

1396 1397
  // Support for using Literal as a HashMap key. NOTE: Currently, this works
  // only for string and number literals!
1398 1399
  uint32_t Hash();
  static bool Match(void* literal1, void* literal2);
1400

1401
  static int num_ids() { return parent_num_ids() + 1; }
1402
  TypeFeedbackId LiteralFeedbackId() const {
1403
    return TypeFeedbackId(local_id(0));
1404
  }
1405

1406
 protected:
1407 1408 1409
  Literal(Zone* zone, const AstValue* value, int position)
      : Expression(zone, position), value_(value) {}
  static int parent_num_ids() { return Expression::num_ids(); }
1410

1411
 private:
1412 1413
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1414
  const AstValue* value_;
1415 1416 1417 1418
};


// Base class for literals that needs space in the corresponding JSFunction.
1419
class MaterializedLiteral : public Expression {
1420
 public:
1421 1422
  virtual MaterializedLiteral* AsMaterializedLiteral() { return this; }

1423
  int literal_index() { return literal_index_; }
1424

1425 1426
  int depth() const {
    // only callable after initialization.
1427
    DCHECK(depth_ >= 1);
1428 1429 1430
    return depth_;
  }

1431
 protected:
1432 1433
  MaterializedLiteral(Zone* zone, int literal_index, int pos)
      : Expression(zone, pos),
1434
        literal_index_(literal_index),
1435 1436
        is_simple_(false),
        depth_(0) {}
1437 1438 1439 1440 1441 1442 1443

  // A materialized literal is simple if the values consist of only
  // constants and simple object and array literals.
  bool is_simple() const { return is_simple_; }
  void set_is_simple(bool is_simple) { is_simple_ = is_simple; }
  friend class CompileTimeValue;

1444
  void set_depth(int depth) {
1445
    DCHECK(depth >= 1);
1446 1447 1448
    depth_ = depth;
  }

1449
  // Populate the constant properties/elements fixed array.
1450
  void BuildConstants(Isolate* isolate);
1451 1452 1453 1454 1455 1456 1457 1458 1459
  friend class ArrayLiteral;
  friend class ObjectLiteral;

  // If the expression is a literal, return the literal value;
  // if the expression is a materialized literal and is simple return a
  // compile time value as encoded by CompileTimeValue::GetValue().
  // Otherwise, return undefined literal as the placeholder
  // in the object literal boilerplate.
  Handle<Object> GetBoilerplateValue(Expression* expression, Isolate* isolate);
1460

1461 1462
 private:
  int literal_index_;
1463
  bool is_simple_;
1464
  int depth_;
1465 1466 1467
};


1468 1469 1470
// Property is used for passing information
// about an object literal's properties from the parser
// to the code generator.
1471
class ObjectLiteralProperty FINAL : public ZoneObject {
1472 1473 1474 1475 1476 1477 1478 1479 1480
 public:
  enum Kind {
    CONSTANT,              // Property with constant value (compile time).
    COMPUTED,              // Property with computed value (execution time).
    MATERIALIZED_LITERAL,  // Property value is a materialized literal.
    GETTER, SETTER,        // Property is an accessor function.
    PROTOTYPE              // Property is __proto__.
  };

1481
  ObjectLiteralProperty(Zone* zone, AstValueFactory* ast_value_factory,
arv@chromium.org's avatar
arv@chromium.org committed
1482
                        Literal* key, Expression* value, bool is_static);
1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497

  Literal* key() { return key_; }
  Expression* value() { return value_; }
  Kind kind() { return kind_; }

  // Type feedback information.
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
  bool IsMonomorphic() { return !receiver_type_.is_null(); }
  Handle<Map> GetReceiverType() { return receiver_type_; }

  bool IsCompileTimeValue();

  void set_emit_store(bool emit_store);
  bool emit_store();

1498 1499
  bool is_static() const { return is_static_; }

1500 1501 1502
 protected:
  template<class> friend class AstNodeFactory;

arv@chromium.org's avatar
arv@chromium.org committed
1503 1504
  ObjectLiteralProperty(Zone* zone, bool is_getter, FunctionLiteral* value,
                        bool is_static);
1505 1506 1507 1508 1509 1510 1511
  void set_key(Literal* key) { key_ = key; }

 private:
  Literal* key_;
  Expression* value_;
  Kind kind_;
  bool emit_store_;
arv@chromium.org's avatar
arv@chromium.org committed
1512
  bool is_static_;
1513 1514 1515 1516
  Handle<Map> receiver_type_;
};


1517 1518
// An object literal has a boilerplate object that is used
// for minimizing the work when constructing it at runtime.
1519
class ObjectLiteral FINAL : public MaterializedLiteral {
1520
 public:
1521
  typedef ObjectLiteralProperty Property;
1522

1523
  DECLARE_NODE_TYPE(ObjectLiteral)
1524 1525 1526 1527 1528

  Handle<FixedArray> constant_properties() const {
    return constant_properties_;
  }
  ZoneList<Property*>* properties() const { return properties_; }
1529
  bool fast_elements() const { return fast_elements_; }
1530 1531
  bool may_store_doubles() const { return may_store_doubles_; }
  bool has_function() const { return has_function_; }
1532

1533 1534 1535 1536
  // Decide if a property should be in the object boilerplate.
  static bool IsBoilerplateProperty(Property* property);

  // Populate the constant properties fixed array.
1537
  void BuildConstantProperties(Isolate* isolate);
1538

1539 1540 1541
  // Mark all computed expressions that are bound to a key that
  // is shadowed by a later occurrence of the same key. For the
  // marked expressions, no store code is emitted.
1542
  void CalculateEmitStore(Zone* zone);
1543

1544 1545 1546 1547 1548 1549 1550
  // Assemble bitfield of flags for the CreateObjectLiteral helper.
  int ComputeFlags() const {
    int flags = fast_elements() ? kFastElements : kNoFlags;
    flags |= has_function() ? kHasFunction : kNoFlags;
    return flags;
  }

1551 1552 1553 1554 1555 1556
  enum Flags {
    kNoFlags = 0,
    kFastElements = 1,
    kHasFunction = 1 << 1
  };

1557
  struct Accessors: public ZoneObject {
1558
    Accessors() : getter(NULL), setter(NULL) {}
1559 1560 1561 1562
    Expression* getter;
    Expression* setter;
  };

1563 1564 1565 1566
  BailoutId CreateLiteralId() const { return BailoutId(local_id(0)); }

  static int num_ids() { return parent_num_ids() + 1; }

1567
 protected:
1568
  ObjectLiteral(Zone* zone, ZoneList<Property*>* properties, int literal_index,
1569 1570
                int boilerplate_properties, bool has_function, int pos)
      : MaterializedLiteral(zone, literal_index, pos),
1571
        properties_(properties),
1572 1573 1574
        boilerplate_properties_(boilerplate_properties),
        fast_elements_(false),
        may_store_doubles_(false),
1575
        has_function_(has_function) {}
1576
  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1577

1578
 private:
1579
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }
1580 1581
  Handle<FixedArray> constant_properties_;
  ZoneList<Property*>* properties_;
1582
  int boilerplate_properties_;
1583
  bool fast_elements_;
1584
  bool may_store_doubles_;
1585
  bool has_function_;
1586 1587 1588 1589
};


// Node for capturing a regexp literal.
1590
class RegExpLiteral FINAL : public MaterializedLiteral {
1591
 public:
1592 1593
  DECLARE_NODE_TYPE(RegExpLiteral)

1594 1595
  Handle<String> pattern() const { return pattern_->string(); }
  Handle<String> flags() const { return flags_->string(); }
1596 1597

 protected:
1598
  RegExpLiteral(Zone* zone, const AstRawString* pattern,
1599 1600
                const AstRawString* flags, int literal_index, int pos)
      : MaterializedLiteral(zone, literal_index, pos),
1601
        pattern_(pattern),
1602 1603 1604
        flags_(flags) {
    set_depth(1);
  }
1605 1606

 private:
1607 1608
  const AstRawString* pattern_;
  const AstRawString* flags_;
1609 1610
};

1611

1612
// An array literal has a literals object that is used
1613
// for minimizing the work when constructing it at runtime.
1614
class ArrayLiteral FINAL : public MaterializedLiteral {
1615
 public:
1616 1617 1618 1619 1620
  DECLARE_NODE_TYPE(ArrayLiteral)

  Handle<FixedArray> constant_elements() const { return constant_elements_; }
  ZoneList<Expression*>* values() const { return values_; }

1621 1622 1623 1624
  // Unlike other AST nodes, this number of bailout IDs allocated for an
  // ArrayLiteral can vary, so num_ids() is not a static method.
  int num_ids() const { return parent_num_ids() + values()->length(); }

1625
  // Return an AST id for an element that is used in simulate instructions.
1626
  BailoutId GetIdForElement(int i) { return BailoutId(local_id(i)); }
1627

1628
  // Populate the constant elements fixed array.
1629
  void BuildConstantElements(Isolate* isolate);
1630

1631 1632 1633 1634 1635 1636 1637
  // Assemble bitfield of flags for the CreateArrayLiteral helper.
  int ComputeFlags() const {
    int flags = depth() == 1 ? kShallowElements : kNoFlags;
    flags |= ArrayLiteral::kDisableMementos;
    return flags;
  }

1638 1639 1640 1641 1642 1643
  enum Flags {
    kNoFlags = 0,
    kShallowElements = 1,
    kDisableMementos = 1 << 1
  };

1644
 protected:
1645
  ArrayLiteral(Zone* zone, ZoneList<Expression*>* values, int literal_index,
1646 1647 1648
               int pos)
      : MaterializedLiteral(zone, literal_index, pos), values_(values) {}
  static int parent_num_ids() { return MaterializedLiteral::num_ids(); }
1649

1650
 private:
1651 1652
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1653
  Handle<FixedArray> constant_elements_;
1654 1655 1656 1657
  ZoneList<Expression*>* values_;
};


1658
class VariableProxy FINAL : public Expression {
1659
 public:
1660
  DECLARE_NODE_TYPE(VariableProxy)
1661

1662
  virtual bool IsValidReferenceExpression() const OVERRIDE {
1663
    return !is_resolved() || var()->IsValidReference();
1664
  }
1665

1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681
  bool IsArguments() const { return is_resolved() && var()->is_arguments(); }

  Handle<String> name() const { return raw_name()->string(); }
  const AstRawString* raw_name() const {
    return is_resolved() ? var_->raw_name() : raw_name_;
  }

  Variable* var() const {
    DCHECK(is_resolved());
    return var_;
  }
  void set_var(Variable* v) {
    DCHECK(!is_resolved());
    DCHECK_NOT_NULL(v);
    var_ = v;
  }
1682

1683
  bool is_this() const { return IsThisField::decode(bit_field_); }
1684

1685 1686 1687 1688
  bool is_assigned() const { return IsAssignedField::decode(bit_field_); }
  void set_is_assigned() {
    bit_field_ = IsAssignedField::update(bit_field_, true);
  }
1689

1690 1691 1692 1693
  bool is_resolved() const { return IsResolvedField::decode(bit_field_); }
  void set_is_resolved() {
    bit_field_ = IsResolvedField::update(bit_field_, true);
  }
1694 1695 1696

  Interface* interface() const { return interface_; }

1697
  // Bind this proxy to the variable var. Interfaces must match.
1698 1699
  void BindTo(Variable* var);

1700
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
1701 1702
    return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
  }
1703
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
1704 1705 1706
    variable_feedback_slot_ = slot;
  }

1707 1708 1709
  FeedbackVectorICSlot VariableFeedbackSlot() {
    return variable_feedback_slot_;
  }
1710

1711
 protected:
1712
  VariableProxy(Zone* zone, Variable* var, int position);
1713

1714
  VariableProxy(Zone* zone, const AstRawString* name, bool is_this,
1715
                Interface* interface, int position);
1716

1717 1718 1719 1720 1721 1722 1723
  class IsThisField : public BitField8<bool, 0, 1> {};
  class IsAssignedField : public BitField8<bool, 1, 1> {};
  class IsResolvedField : public BitField8<bool, 2, 1> {};

  // Start with 16-bit (or smaller) field, which should get packed together
  // with Expression's trailing 16-bit field.
  uint8_t bit_field_;
1724
  FeedbackVectorICSlot variable_feedback_slot_;
1725 1726 1727 1728
  union {
    const AstRawString* raw_name_;  // if !is_resolved_
    Variable* var_;                 // if is_resolved_
  };
1729
  Interface* interface_;
1730 1731 1732
};


1733
class Property FINAL : public Expression {
1734
 public:
1735
  DECLARE_NODE_TYPE(Property)
1736

1737
  virtual bool IsValidReferenceExpression() const OVERRIDE { return true; }
1738 1739 1740 1741

  Expression* obj() const { return obj_; }
  Expression* key() const { return key_; }

1742 1743 1744
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId LoadId() const { return BailoutId(local_id(0)); }
  TypeFeedbackId PropertyFeedbackId() { return TypeFeedbackId(local_id(1)); }
1745

1746 1747 1748
  bool IsStringAccess() const {
    return IsStringAccessField::decode(bit_field_);
  }
1749

1750
  // Type feedback information.
1751
  virtual bool IsMonomorphic() OVERRIDE {
1752 1753
    return receiver_types_.length() == 1;
  }
1754
  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
1755 1756
    return &receiver_types_;
  }
1757
  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
1758 1759
    return STANDARD_STORE;
  }
1760
  virtual IcCheckType GetKeyType() const OVERRIDE {
1761 1762 1763
    // PROPERTY key types currently aren't implemented for KeyedLoadICs.
    return ELEMENT;
  }
1764 1765 1766 1767 1768 1769 1770 1771
  bool IsUninitialized() const {
    return !is_for_call() && HasNoTypeInformation();
  }
  bool HasNoTypeInformation() const {
    return IsUninitializedField::decode(bit_field_);
  }
  void set_is_uninitialized(bool b) {
    bit_field_ = IsUninitializedField::update(bit_field_, b);
1772
  }
1773 1774 1775 1776 1777 1778 1779
  void set_is_string_access(bool b) {
    bit_field_ = IsStringAccessField::update(bit_field_, b);
  }
  void mark_for_call() {
    bit_field_ = IsForCallField::update(bit_field_, true);
  }
  bool is_for_call() const { return IsForCallField::decode(bit_field_); }
1780

1781 1782 1783 1784
  bool IsSuperAccess() {
    return obj()->IsSuperReference();
  }

1785
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
1786 1787
    return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
  }
1788
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
1789 1790 1791
    property_feedback_slot_ = slot;
  }

1792
  FeedbackVectorICSlot PropertyFeedbackSlot() const {
1793 1794
    return property_feedback_slot_;
  }
1795

1796
 protected:
1797 1798
  Property(Zone* zone, Expression* obj, Expression* key, int pos)
      : Expression(zone, pos),
1799 1800 1801
        bit_field_(IsForCallField::encode(false) |
                   IsUninitializedField::encode(false) |
                   IsStringAccessField::encode(false)),
1802
        property_feedback_slot_(FeedbackVectorICSlot::Invalid()),
1803 1804
        obj_(obj),
        key_(key) {}
1805
  static int parent_num_ids() { return Expression::num_ids(); }
1806

1807
 private:
1808 1809
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1810 1811 1812 1813
  class IsForCallField : public BitField8<bool, 0, 1> {};
  class IsUninitializedField : public BitField8<bool, 1, 1> {};
  class IsStringAccessField : public BitField8<bool, 2, 1> {};
  uint8_t bit_field_;
1814
  FeedbackVectorICSlot property_feedback_slot_;
1815 1816 1817
  Expression* obj_;
  Expression* key_;
  SmallMapList receiver_types_;
1818 1819 1820
};


1821
class Call FINAL : public Expression {
1822
 public:
1823
  DECLARE_NODE_TYPE(Call)
1824 1825 1826 1827

  Expression* expression() const { return expression_; }
  ZoneList<Expression*>* arguments() const { return arguments_; }

1828
  // Type feedback information.
1829
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
1830 1831
    return FeedbackVectorRequirements(0, 1);
  }
1832
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
1833 1834 1835
    call_feedback_slot_ = slot;
  }

1836
  bool HasCallFeedbackSlot() const { return !call_feedback_slot_.IsInvalid(); }
1837
  FeedbackVectorICSlot CallFeedbackSlot() const { return call_feedback_slot_; }
1838

1839
  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
verwaest@chromium.org's avatar
verwaest@chromium.org committed
1840 1841 1842 1843
    if (expression()->IsProperty()) {
      return expression()->AsProperty()->GetReceiverTypes();
    }
    return NULL;
1844 1845
  }

1846
  virtual bool IsMonomorphic() OVERRIDE {
verwaest@chromium.org's avatar
verwaest@chromium.org committed
1847 1848 1849 1850
    if (expression()->IsProperty()) {
      return expression()->AsProperty()->IsMonomorphic();
    }
    return !target_.is_null();
1851 1852
  }

1853 1854 1855 1856 1857 1858 1859 1860 1861
  bool global_call() const {
    VariableProxy* proxy = expression_->AsVariableProxy();
    return proxy != NULL && proxy->var()->IsUnallocated();
  }

  bool known_global_function() const {
    return global_call() && !target_.is_null();
  }

1862
  Handle<JSFunction> target() { return target_; }
1863

1864
  Handle<Cell> cell() { return cell_; }
1865

1866 1867
  Handle<AllocationSite> allocation_site() { return allocation_site_; }

verwaest@chromium.org's avatar
verwaest@chromium.org committed
1868
  void set_target(Handle<JSFunction> target) { target_ = target; }
1869 1870 1871
  void set_allocation_site(Handle<AllocationSite> site) {
    allocation_site_ = site;
  }
1872
  bool ComputeGlobalTarget(Handle<GlobalObject> global, LookupIterator* it);
1873

1874 1875 1876
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
  BailoutId EvalOrLookupId() const { return BailoutId(local_id(1)); }
1877

1878 1879 1880 1881 1882
  enum CallType {
    POSSIBLY_EVAL_CALL,
    GLOBAL_CALL,
    LOOKUP_SLOT_CALL,
    PROPERTY_CALL,
1883
    SUPER_CALL,
1884 1885 1886 1887 1888
    OTHER_CALL
  };

  // Helpers to determine how to handle the call.
  CallType GetCallType(Isolate* isolate) const;
1889
  bool IsUsingCallFeedbackSlot(Isolate* isolate) const;
1890

1891 1892 1893 1894 1895
#ifdef DEBUG
  // Used to assert that the FullCodeGenerator records the return site.
  bool return_is_recorded_;
#endif

1896
 protected:
1897
  Call(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
1898 1899
       int pos)
      : Expression(zone, pos),
1900
        call_feedback_slot_(FeedbackVectorICSlot::Invalid()),
1901
        expression_(expression),
1902
        arguments_(arguments) {
verwaest@chromium.org's avatar
verwaest@chromium.org committed
1903 1904 1905 1906
    if (expression->IsProperty()) {
      expression->AsProperty()->mark_for_call();
    }
  }
1907
  static int parent_num_ids() { return Expression::num_ids(); }
1908

1909
 private:
1910 1911
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1912
  FeedbackVectorICSlot call_feedback_slot_;
1913 1914
  Expression* expression_;
  ZoneList<Expression*>* arguments_;
1915
  Handle<JSFunction> target_;
1916
  Handle<Cell> cell_;
1917
  Handle<AllocationSite> allocation_site_;
1918
};
1919

1920

1921
class CallNew FINAL : public Expression {
1922
 public:
1923 1924 1925 1926 1927
  DECLARE_NODE_TYPE(CallNew)

  Expression* expression() const { return expression_; }
  ZoneList<Expression*>* arguments() const { return arguments_; }

1928
  // Type feedback information.
1929
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
1930
    return FeedbackVectorRequirements(FLAG_pretenuring_call_new ? 2 : 1, 0);
1931
  }
1932
  virtual void SetFirstFeedbackSlot(FeedbackVectorSlot slot) OVERRIDE {
1933 1934 1935
    callnew_feedback_slot_ = slot;
  }

1936 1937
  FeedbackVectorSlot CallNewFeedbackSlot() { return callnew_feedback_slot_; }
  FeedbackVectorSlot AllocationSiteFeedbackSlot() {
1938
    DCHECK(FLAG_pretenuring_call_new);
1939
    return CallNewFeedbackSlot().next();
1940
  }
1941

1942
  void RecordTypeFeedback(TypeFeedbackOracle* oracle);
1943
  virtual bool IsMonomorphic() OVERRIDE { return is_monomorphic_; }
1944
  Handle<JSFunction> target() const { return target_; }
1945 1946
  Handle<AllocationSite> allocation_site() const {
    return allocation_site_;
1947
  }
1948

1949
  static int num_ids() { return parent_num_ids() + 1; }
1950
  static int feedback_slots() { return 1; }
1951
  BailoutId ReturnId() const { return BailoutId(local_id(0)); }
1952

1953
 protected:
1954
  CallNew(Zone* zone, Expression* expression, ZoneList<Expression*>* arguments,
1955 1956
          int pos)
      : Expression(zone, pos),
1957 1958
        expression_(expression),
        arguments_(arguments),
1959
        is_monomorphic_(false),
1960
        callnew_feedback_slot_(FeedbackVectorSlot::Invalid()) {}
1961

1962
  static int parent_num_ids() { return Expression::num_ids(); }
1963

1964
 private:
1965 1966
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

1967 1968
  Expression* expression_;
  ZoneList<Expression*>* arguments_;
1969 1970
  bool is_monomorphic_;
  Handle<JSFunction> target_;
1971
  Handle<AllocationSite> allocation_site_;
1972
  FeedbackVectorSlot callnew_feedback_slot_;
1973 1974 1975
};


1976 1977 1978 1979
// The CallRuntime class does not represent any official JavaScript
// language construct. Instead it is used to call a C or JS function
// with a set of arguments. This is used from the builtins that are
// implemented in JavaScript (see "v8natives.js").
1980
class CallRuntime FINAL : public Expression {
1981
 public:
1982 1983
  DECLARE_NODE_TYPE(CallRuntime)

1984 1985
  Handle<String> name() const { return raw_name_->string(); }
  const AstRawString* raw_name() const { return raw_name_; }
1986 1987 1988 1989
  const Runtime::Function* function() const { return function_; }
  ZoneList<Expression*>* arguments() const { return arguments_; }
  bool is_jsruntime() const { return function_ == NULL; }

1990
  // Type feedback information.
1991
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
1992 1993
    return FeedbackVectorRequirements(
        0, (FLAG_vector_ics && is_jsruntime()) ? 1 : 0);
1994
  }
1995
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
1996 1997 1998
    callruntime_feedback_slot_ = slot;
  }

1999
  FeedbackVectorICSlot CallRuntimeFeedbackSlot() {
2000 2001 2002
    return callruntime_feedback_slot_;
  }

2003
  static int num_ids() { return parent_num_ids() + 1; }
2004
  TypeFeedbackId CallRuntimeFeedbackId() const {
2005
    return TypeFeedbackId(local_id(0));
2006
  }
2007

2008
 protected:
2009
  CallRuntime(Zone* zone, const AstRawString* name,
2010
              const Runtime::Function* function,
2011 2012
              ZoneList<Expression*>* arguments, int pos)
      : Expression(zone, pos),
2013
        raw_name_(name),
2014
        function_(function),
2015
        arguments_(arguments),
2016
        callruntime_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
2017
  static int parent_num_ids() { return Expression::num_ids(); }
2018

2019
 private:
2020 2021
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2022
  const AstRawString* raw_name_;
2023
  const Runtime::Function* function_;
2024
  ZoneList<Expression*>* arguments_;
2025
  FeedbackVectorICSlot callruntime_feedback_slot_;
2026 2027 2028
};


2029
class UnaryOperation FINAL : public Expression {
2030
 public:
2031 2032 2033 2034 2035
  DECLARE_NODE_TYPE(UnaryOperation)

  Token::Value op() const { return op_; }
  Expression* expression() const { return expression_; }

2036 2037
  // For unary not (Token::NOT), the AST ids where true and false will
  // actually be materialized, respectively.
2038 2039 2040
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId MaterializeTrueId() const { return BailoutId(local_id(0)); }
  BailoutId MaterializeFalseId() const { return BailoutId(local_id(1)); }
2041

2042
  virtual void RecordToBooleanTypeFeedback(
2043
      TypeFeedbackOracle* oracle) OVERRIDE;
2044

2045
 protected:
2046 2047
  UnaryOperation(Zone* zone, Token::Value op, Expression* expression, int pos)
      : Expression(zone, pos), op_(op), expression_(expression) {
2048
    DCHECK(Token::IsUnaryOp(op));
2049
  }
2050
  static int parent_num_ids() { return Expression::num_ids(); }
2051

2052
 private:
2053 2054
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2055 2056 2057 2058 2059
  Token::Value op_;
  Expression* expression_;
};


2060
class BinaryOperation FINAL : public Expression {
2061
 public:
2062
  DECLARE_NODE_TYPE(BinaryOperation)
2063

2064
  virtual bool ResultOverwriteAllowed() const OVERRIDE;
2065

2066
  Token::Value op() const { return static_cast<Token::Value>(op_); }
2067 2068
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }
2069 2070 2071 2072
  Handle<AllocationSite> allocation_site() const { return allocation_site_; }
  void set_allocation_site(Handle<AllocationSite> allocation_site) {
    allocation_site_ = allocation_site;
  }
2073

2074 2075
  // The short-circuit logical operations need an AST ID for their
  // right-hand subexpression.
2076 2077
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId RightId() const { return BailoutId(local_id(0)); }
2078

2079
  TypeFeedbackId BinaryOperationFeedbackId() const {
2080
    return TypeFeedbackId(local_id(1));
2081
  }
2082 2083 2084 2085 2086 2087 2088 2089
  Maybe<int> fixed_right_arg() const {
    return has_fixed_right_arg_ ? Maybe<int>(fixed_right_arg_value_)
                                : Maybe<int>();
  }
  void set_fixed_right_arg(Maybe<int> arg) {
    has_fixed_right_arg_ = arg.has_value;
    if (arg.has_value) fixed_right_arg_value_ = arg.value;
  }
2090

2091
  virtual void RecordToBooleanTypeFeedback(
2092
      TypeFeedbackOracle* oracle) OVERRIDE;
2093

2094
 protected:
2095
  BinaryOperation(Zone* zone, Token::Value op, Expression* left,
2096 2097
                  Expression* right, int pos)
      : Expression(zone, pos),
2098
        op_(static_cast<byte>(op)),
2099 2100
        has_fixed_right_arg_(false),
        fixed_right_arg_value_(0),
2101
        left_(left),
2102
        right_(right) {
2103
    DCHECK(Token::IsBinaryOp(op));
2104
  }
2105
  static int parent_num_ids() { return Expression::num_ids(); }
2106

2107
 private:
2108 2109
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2110 2111 2112 2113 2114
  const byte op_;  // actually Token::Value
  // TODO(rossberg): the fixed arg should probably be represented as a Constant
  // type for the RHS. Currenty it's actually a Maybe<int>
  bool has_fixed_right_arg_;
  int fixed_right_arg_value_;
2115 2116
  Expression* left_;
  Expression* right_;
2117
  Handle<AllocationSite> allocation_site_;
2118 2119 2120
};


2121
class CountOperation FINAL : public Expression {
2122
 public:
2123
  DECLARE_NODE_TYPE(CountOperation)
2124

2125 2126
  bool is_prefix() const { return IsPrefixField::decode(bit_field_); }
  bool is_postfix() const { return !is_prefix(); }
2127

2128
  Token::Value op() const { return TokenField::decode(bit_field_); }
2129
  Token::Value binary_op() {
2130
    return (op() == Token::INC) ? Token::ADD : Token::SUB;
2131
  }
2132

2133
  Expression* expression() const { return expression_; }
2134

2135
  virtual bool IsMonomorphic() OVERRIDE {
2136 2137
    return receiver_types_.length() == 1;
  }
2138
  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
2139 2140
    return &receiver_types_;
  }
2141 2142 2143 2144 2145
  virtual IcCheckType GetKeyType() const OVERRIDE {
    return KeyTypeField::decode(bit_field_);
  }
  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
    return StoreModeField::decode(bit_field_);
2146
  }
2147
  Type* type() const { return type_; }
2148 2149 2150 2151 2152 2153
  void set_key_type(IcCheckType type) {
    bit_field_ = KeyTypeField::update(bit_field_, type);
  }
  void set_store_mode(KeyedAccessStoreMode mode) {
    bit_field_ = StoreModeField::update(bit_field_, mode);
  }
2154
  void set_type(Type* type) { type_ = type; }
2155

2156 2157
  static int num_ids() { return parent_num_ids() + 3; }
  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2158
  TypeFeedbackId CountBinOpFeedbackId() const {
2159
    return TypeFeedbackId(local_id(1));
2160 2161
  }
  TypeFeedbackId CountStoreFeedbackId() const {
2162
    return TypeFeedbackId(local_id(2));
2163
  }
2164

2165
 protected:
2166
  CountOperation(Zone* zone, Token::Value op, bool is_prefix, Expression* expr,
2167 2168
                 int pos)
      : Expression(zone, pos),
2169 2170 2171 2172 2173
        bit_field_(IsPrefixField::encode(is_prefix) |
                   KeyTypeField::encode(ELEMENT) |
                   StoreModeField::encode(STANDARD_STORE) |
                   TokenField::encode(op)),
        type_(NULL),
2174
        expression_(expr) {}
2175
  static int parent_num_ids() { return Expression::num_ids(); }
2176

2177
 private:
2178 2179
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2180 2181 2182 2183 2184 2185 2186 2187
  class IsPrefixField : public BitField16<bool, 0, 1> {};
  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
  class TokenField : public BitField16<Token::Value, 6, 8> {};

  // Starts with 16-bit field, which should get packed together with
  // Expression's trailing 16-bit field.
  uint16_t bit_field_;
2188
  Type* type_;
2189
  Expression* expression_;
2190
  SmallMapList receiver_types_;
2191 2192 2193
};


2194
class CompareOperation FINAL : public Expression {
2195
 public:
2196
  DECLARE_NODE_TYPE(CompareOperation)
2197 2198 2199 2200 2201

  Token::Value op() const { return op_; }
  Expression* left() const { return left_; }
  Expression* right() const { return right_; }

2202
  // Type feedback information.
2203
  static int num_ids() { return parent_num_ids() + 1; }
2204
  TypeFeedbackId CompareOperationFeedbackId() const {
2205
    return TypeFeedbackId(local_id(0));
2206
  }
2207 2208
  Type* combined_type() const { return combined_type_; }
  void set_combined_type(Type* type) { combined_type_ = type; }
2209

2210 2211
  // Match special cases.
  bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
2212
  bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
2213
  bool IsLiteralCompareNull(Expression** expr);
2214

2215
 protected:
2216
  CompareOperation(Zone* zone, Token::Value op, Expression* left,
2217 2218
                   Expression* right, int pos)
      : Expression(zone, pos),
2219 2220 2221
        op_(op),
        left_(left),
        right_(right),
2222
        combined_type_(Type::None(zone)) {
2223
    DCHECK(Token::IsCompareOp(op));
2224
  }
2225
  static int parent_num_ids() { return Expression::num_ids(); }
2226

2227
 private:
2228 2229
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2230 2231 2232
  Token::Value op_;
  Expression* left_;
  Expression* right_;
2233

2234
  Type* combined_type_;
2235 2236 2237
};


2238
class Conditional FINAL : public Expression {
2239
 public:
2240 2241 2242 2243 2244 2245
  DECLARE_NODE_TYPE(Conditional)

  Expression* condition() const { return condition_; }
  Expression* then_expression() const { return then_expression_; }
  Expression* else_expression() const { return else_expression_; }

2246 2247 2248
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId ThenId() const { return BailoutId(local_id(0)); }
  BailoutId ElseId() const { return BailoutId(local_id(1)); }
2249 2250

 protected:
2251
  Conditional(Zone* zone, Expression* condition, Expression* then_expression,
2252 2253
              Expression* else_expression, int position)
      : Expression(zone, position),
2254
        condition_(condition),
2255
        then_expression_(then_expression),
2256
        else_expression_(else_expression) {}
2257
  static int parent_num_ids() { return Expression::num_ids(); }
2258

2259
 private:
2260 2261
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2262 2263 2264 2265 2266 2267
  Expression* condition_;
  Expression* then_expression_;
  Expression* else_expression_;
};


2268
class Assignment FINAL : public Expression {
2269
 public:
2270
  DECLARE_NODE_TYPE(Assignment)
2271

2272 2273
  Assignment* AsSimpleAssignment() { return !is_compound() ? this : NULL; }

2274 2275
  Token::Value binary_op() const;

2276
  Token::Value op() const { return TokenField::decode(bit_field_); }
2277 2278
  Expression* target() const { return target_; }
  Expression* value() const { return value_; }
2279 2280
  BinaryOperation* binary_operation() const { return binary_operation_; }

2281 2282
  // This check relies on the definition order of token in token.h.
  bool is_compound() const { return op() > Token::ASSIGN; }
2283

2284 2285
  static int num_ids() { return parent_num_ids() + 2; }
  BailoutId AssignmentId() const { return BailoutId(local_id(0)); }
2286

2287
  // Type feedback information.
2288
  TypeFeedbackId AssignmentFeedbackId() { return TypeFeedbackId(local_id(1)); }
2289
  virtual bool IsMonomorphic() OVERRIDE {
2290 2291
    return receiver_types_.length() == 1;
  }
2292 2293 2294
  bool IsUninitialized() const {
    return IsUninitializedField::decode(bit_field_);
  }
2295
  bool HasNoTypeInformation() {
2296
    return IsUninitializedField::decode(bit_field_);
2297
  }
2298
  virtual SmallMapList* GetReceiverTypes() OVERRIDE {
2299 2300
    return &receiver_types_;
  }
2301 2302 2303 2304 2305 2306 2307 2308 2309 2310 2311 2312 2313 2314
  virtual IcCheckType GetKeyType() const OVERRIDE {
    return KeyTypeField::decode(bit_field_);
  }
  virtual KeyedAccessStoreMode GetStoreMode() const OVERRIDE {
    return StoreModeField::decode(bit_field_);
  }
  void set_is_uninitialized(bool b) {
    bit_field_ = IsUninitializedField::update(bit_field_, b);
  }
  void set_key_type(IcCheckType key_type) {
    bit_field_ = KeyTypeField::update(bit_field_, key_type);
  }
  void set_store_mode(KeyedAccessStoreMode mode) {
    bit_field_ = StoreModeField::update(bit_field_, mode);
2315
  }
2316

2317
 protected:
2318
  Assignment(Zone* zone, Token::Value op, Expression* target, Expression* value,
2319 2320
             int pos);
  static int parent_num_ids() { return Expression::num_ids(); }
2321

2322 2323
  template <class Visitor>
  void Init(AstNodeFactory<Visitor>* factory) {
2324
    DCHECK(Token::IsAssignmentOp(op()));
2325
    if (is_compound()) {
2326 2327
      binary_operation_ = factory->NewBinaryOperation(
          binary_op(), target_, value_, position() + 1);
2328 2329 2330
    }
  }

2331
 private:
2332 2333
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2334 2335 2336 2337 2338 2339 2340 2341
  class IsUninitializedField : public BitField16<bool, 0, 1> {};
  class KeyTypeField : public BitField16<IcCheckType, 1, 1> {};
  class StoreModeField : public BitField16<KeyedAccessStoreMode, 2, 4> {};
  class TokenField : public BitField16<Token::Value, 6, 8> {};

  // Starts with 16-bit field, which should get packed together with
  // Expression's trailing 16-bit field.
  uint16_t bit_field_;
2342 2343 2344
  Expression* target_;
  Expression* value_;
  BinaryOperation* binary_operation_;
2345
  SmallMapList receiver_types_;
2346 2347 2348
};


2349
class Yield FINAL : public Expression {
2350 2351 2352
 public:
  DECLARE_NODE_TYPE(Yield)

2353
  enum Kind {
2354 2355 2356 2357
    kInitial,  // The initial yield that returns the unboxed generator object.
    kSuspend,  // A normal yield: { value: EXPRESSION, done: false }
    kDelegating,  // A yield*.
    kFinal        // A return: { value: EXPRESSION, done: true }
2358 2359
  };

2360
  Expression* generator_object() const { return generator_object_; }
2361
  Expression* expression() const { return expression_; }
2362
  Kind yield_kind() const { return yield_kind_; }
2363

2364 2365 2366 2367
  // Delegating yield surrounds the "yield" in a "try/catch".  This index
  // locates the catch handler in the handler table, and is equivalent to
  // TryCatchStatement::index().
  int index() const {
2368
    DCHECK_EQ(kDelegating, yield_kind());
2369 2370 2371
    return index_;
  }
  void set_index(int index) {
2372
    DCHECK_EQ(kDelegating, yield_kind());
2373 2374 2375
    index_ = index;
  }

2376
  // Type feedback information.
2377
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
2378 2379
    return FeedbackVectorRequirements(
        0, (FLAG_vector_ics && yield_kind() == kDelegating) ? 3 : 0);
2380
  }
2381
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
2382 2383 2384
    yield_first_feedback_slot_ = slot;
  }

2385
  FeedbackVectorICSlot KeyedLoadFeedbackSlot() {
2386 2387 2388
    return yield_first_feedback_slot_;
  }

2389
  FeedbackVectorICSlot DoneFeedbackSlot() {
2390
    return KeyedLoadFeedbackSlot().next();
2391 2392
  }

2393
  FeedbackVectorICSlot ValueFeedbackSlot() { return DoneFeedbackSlot().next(); }
2394

2395
 protected:
2396
  Yield(Zone* zone, Expression* generator_object, Expression* expression,
2397 2398
        Kind yield_kind, int pos)
      : Expression(zone, pos),
2399
        generator_object_(generator_object),
2400
        expression_(expression),
2401
        yield_kind_(yield_kind),
2402
        index_(-1),
2403
        yield_first_feedback_slot_(FeedbackVectorICSlot::Invalid()) {}
2404 2405

 private:
2406
  Expression* generator_object_;
2407
  Expression* expression_;
2408
  Kind yield_kind_;
2409
  int index_;
2410
  FeedbackVectorICSlot yield_first_feedback_slot_;
2411 2412 2413
};


2414
class Throw FINAL : public Expression {
2415
 public:
2416
  DECLARE_NODE_TYPE(Throw)
2417

2418
  Expression* exception() const { return exception_; }
2419 2420

 protected:
2421 2422
  Throw(Zone* zone, Expression* exception, int pos)
      : Expression(zone, pos), exception_(exception) {}
2423 2424 2425 2426 2427 2428

 private:
  Expression* exception_;
};


2429
class FunctionLiteral FINAL : public Expression {
2430
 public:
2431
  enum FunctionType {
2432 2433 2434 2435 2436
    ANONYMOUS_EXPRESSION,
    NAMED_EXPRESSION,
    DECLARATION
  };

2437 2438 2439 2440 2441 2442 2443 2444 2445 2446
  enum ParameterFlag {
    kNoDuplicateParameters = 0,
    kHasDuplicateParameters = 1
  };

  enum IsFunctionFlag {
    kGlobalOrEval,
    kIsFunction
  };

2447 2448 2449 2450 2451
  enum IsParenthesizedFlag {
    kIsParenthesized,
    kNotParenthesized
  };

2452 2453 2454 2455 2456 2457
  enum ArityRestriction {
    NORMAL_ARITY,
    GETTER_ARITY,
    SETTER_ARITY
  };

2458
  DECLARE_NODE_TYPE(FunctionLiteral)
2459

2460 2461
  Handle<String> name() const { return raw_name_->string(); }
  const AstRawString* raw_name() const { return raw_name_; }
2462 2463
  Scope* scope() const { return scope_; }
  ZoneList<Statement*>* body() const { return body_; }
2464 2465
  void set_function_token_position(int pos) { function_token_position_ = pos; }
  int function_token_position() const { return function_token_position_; }
2466 2467
  int start_position() const;
  int end_position() const;
2468
  int SourceSize() const { return end_position() - start_position(); }
2469 2470
  bool is_expression() const { return IsExpression::decode(bitfield_); }
  bool is_anonymous() const { return IsAnonymous::decode(bitfield_); }
2471
  StrictMode strict_mode() const;
2472
  bool uses_super() const;
2473 2474 2475

  static bool NeedsHomeObject(Expression* literal) {
    return literal != NULL && literal->IsFunctionLiteral() &&
2476
           literal->AsFunctionLiteral()->uses_super();
2477
  }
2478 2479 2480

  int materialized_literal_count() { return materialized_literal_count_; }
  int expected_property_count() { return expected_property_count_; }
2481
  int handler_count() { return handler_count_; }
2482
  int parameter_count() { return parameter_count_; }
2483 2484

  bool AllowsLazyCompilation();
2485
  bool AllowsLazyCompilationWithoutContext();
2486

2487 2488
  void InitializeSharedInfo(Handle<Code> code);

2489
  Handle<String> debug_name() const {
2490 2491 2492
    if (raw_name_ != NULL && !raw_name_->IsEmpty()) {
      return raw_name_->string();
    }
2493 2494 2495
    return inferred_name();
  }

2496 2497
  Handle<String> inferred_name() const {
    if (!inferred_name_.is_null()) {
2498
      DCHECK(raw_inferred_name_ == NULL);
2499 2500 2501 2502 2503 2504 2505 2506 2507 2508
      return inferred_name_;
    }
    if (raw_inferred_name_ != NULL) {
      return raw_inferred_name_->string();
    }
    UNREACHABLE();
    return Handle<String>();
  }

  // Only one of {set_inferred_name, set_raw_inferred_name} should be called.
2509
  void set_inferred_name(Handle<String> inferred_name) {
2510
    DCHECK(!inferred_name.is_null());
2511
    inferred_name_ = inferred_name;
2512
    DCHECK(raw_inferred_name_== NULL || raw_inferred_name_->IsEmpty());
2513 2514 2515 2516
    raw_inferred_name_ = NULL;
  }

  void set_raw_inferred_name(const AstString* raw_inferred_name) {
2517
    DCHECK(raw_inferred_name != NULL);
2518
    raw_inferred_name_ = raw_inferred_name;
2519
    DCHECK(inferred_name_.is_null());
2520
    inferred_name_ = Handle<String>();
2521 2522
  }

2523 2524 2525
  // shared_info may be null if it's not cached in full code.
  Handle<SharedFunctionInfo> shared_info() { return shared_info_; }

2526 2527
  bool pretenure() { return Pretenure::decode(bitfield_); }
  void set_pretenure() { bitfield_ |= Pretenure::encode(true); }
2528

2529 2530 2531
  bool has_duplicate_parameters() {
    return HasDuplicateParameters::decode(bitfield_);
  }
2532

2533 2534
  bool is_function() { return IsFunction::decode(bitfield_) == kIsFunction; }

2535 2536 2537 2538 2539
  // This is used as a heuristic on when to eagerly compile a function
  // literal. We consider the following constructs as hints that the
  // function will be called immediately:
  // - (function() { ... })();
  // - var x = function() { ... }();
2540 2541 2542
  bool is_parenthesized() {
    return IsParenthesized::decode(bitfield_) == kIsParenthesized;
  }
2543 2544 2545
  void set_parenthesized() {
    bitfield_ = IsParenthesized::update(bitfield_, kIsParenthesized);
  }
2546

2547 2548 2549 2550 2551 2552 2553 2554 2555 2556
  FunctionKind kind() { return FunctionKindBits::decode(bitfield_); }
  bool is_arrow() {
    return IsArrowFunction(FunctionKindBits::decode(bitfield_));
  }
  bool is_generator() {
    return IsGeneratorFunction(FunctionKindBits::decode(bitfield_));
  }
  bool is_concise_method() {
    return IsConciseMethod(FunctionKindBits::decode(bitfield_));
  }
2557 2558 2559
  bool is_default_constructor() {
    return IsDefaultConstructor(FunctionKindBits::decode(bitfield_));
  }
2560

2561 2562 2563 2564 2565
  int ast_node_count() { return ast_properties_.node_count(); }
  AstProperties::Flags* flags() { return ast_properties_.flags(); }
  void set_ast_properties(AstProperties* ast_properties) {
    ast_properties_ = *ast_properties;
  }
2566
  int slot_count() {
2567
    return ast_properties_.feedback_slots();
2568
  }
2569
  int ic_slot_count() { return ast_properties_.ic_feedback_slots(); }
2570 2571 2572 2573 2574 2575
  bool dont_optimize() { return dont_optimize_reason_ != kNoReason; }
  BailoutReason dont_optimize_reason() { return dont_optimize_reason_; }
  void set_dont_optimize_reason(BailoutReason reason) {
    dont_optimize_reason_ = reason;
  }

2576
 protected:
2577 2578 2579 2580 2581
  FunctionLiteral(Zone* zone, const AstRawString* name,
                  AstValueFactory* ast_value_factory, Scope* scope,
                  ZoneList<Statement*>* body, int materialized_literal_count,
                  int expected_property_count, int handler_count,
                  int parameter_count, FunctionType function_type,
2582
                  ParameterFlag has_duplicate_parameters,
2583
                  IsFunctionFlag is_function,
2584
                  IsParenthesizedFlag is_parenthesized, FunctionKind kind,
2585 2586
                  int position)
      : Expression(zone, position),
2587
        raw_name_(name),
2588 2589
        scope_(scope),
        body_(body),
2590
        raw_inferred_name_(ast_value_factory->empty_string()),
2591
        dont_optimize_reason_(kNoReason),
2592 2593 2594 2595 2596
        materialized_literal_count_(materialized_literal_count),
        expected_property_count_(expected_property_count),
        handler_count_(handler_count),
        parameter_count_(parameter_count),
        function_token_position_(RelocInfo::kNoPosition) {
2597 2598 2599 2600 2601 2602
    bitfield_ = IsExpression::encode(function_type != DECLARATION) |
                IsAnonymous::encode(function_type == ANONYMOUS_EXPRESSION) |
                Pretenure::encode(false) |
                HasDuplicateParameters::encode(has_duplicate_parameters) |
                IsFunction::encode(is_function) |
                IsParenthesized::encode(is_parenthesized) |
2603 2604
                FunctionKindBits::encode(kind);
    DCHECK(IsValidFunctionKind(kind));
2605 2606
  }

2607
 private:
2608
  const AstRawString* raw_name_;
2609
  Handle<String> name_;
2610
  Handle<SharedFunctionInfo> shared_info_;
2611 2612
  Scope* scope_;
  ZoneList<Statement*>* body_;
2613
  const AstString* raw_inferred_name_;
2614
  Handle<String> inferred_name_;
2615
  AstProperties ast_properties_;
2616
  BailoutReason dont_optimize_reason_;
2617

2618 2619
  int materialized_literal_count_;
  int expected_property_count_;
2620
  int handler_count_;
2621
  int parameter_count_;
2622
  int function_token_position_;
2623 2624

  unsigned bitfield_;
2625 2626 2627 2628 2629 2630
  class IsExpression : public BitField<bool, 0, 1> {};
  class IsAnonymous : public BitField<bool, 1, 1> {};
  class Pretenure : public BitField<bool, 2, 1> {};
  class HasDuplicateParameters : public BitField<ParameterFlag, 3, 1> {};
  class IsFunction : public BitField<IsFunctionFlag, 4, 1> {};
  class IsParenthesized : public BitField<IsParenthesizedFlag, 5, 1> {};
2631
  class FunctionKindBits : public BitField<FunctionKind, 6, 4> {};
2632 2633 2634
};


arv@chromium.org's avatar
arv@chromium.org committed
2635 2636 2637 2638 2639 2640 2641 2642 2643
class ClassLiteral FINAL : public Expression {
 public:
  typedef ObjectLiteralProperty Property;

  DECLARE_NODE_TYPE(ClassLiteral)

  Handle<String> name() const { return raw_name_->string(); }
  const AstRawString* raw_name() const { return raw_name_; }
  Expression* extends() const { return extends_; }
2644
  Expression* constructor() const { return constructor_; }
arv@chromium.org's avatar
arv@chromium.org committed
2645
  ZoneList<Property*>* properties() const { return properties_; }
2646 2647
  int start_position() const { return position(); }
  int end_position() const { return end_position_; }
arv@chromium.org's avatar
arv@chromium.org committed
2648 2649 2650

 protected:
  ClassLiteral(Zone* zone, const AstRawString* name, Expression* extends,
2651
               Expression* constructor, ZoneList<Property*>* properties,
2652 2653
               int start_position, int end_position)
      : Expression(zone, start_position),
arv@chromium.org's avatar
arv@chromium.org committed
2654 2655 2656
        raw_name_(name),
        extends_(extends),
        constructor_(constructor),
2657 2658
        properties_(properties),
        end_position_(end_position) {}
arv@chromium.org's avatar
arv@chromium.org committed
2659 2660 2661 2662

 private:
  const AstRawString* raw_name_;
  Expression* extends_;
2663
  Expression* constructor_;
arv@chromium.org's avatar
arv@chromium.org committed
2664
  ZoneList<Property*>* properties_;
2665
  int end_position_;
arv@chromium.org's avatar
arv@chromium.org committed
2666 2667 2668
};


2669
class NativeFunctionLiteral FINAL : public Expression {
2670
 public:
2671
  DECLARE_NODE_TYPE(NativeFunctionLiteral)
2672

2673
  Handle<String> name() const { return name_->string(); }
2674
  v8::Extension* extension() const { return extension_; }
2675 2676

 protected:
2677
  NativeFunctionLiteral(Zone* zone, const AstRawString* name,
2678 2679
                        v8::Extension* extension, int pos)
      : Expression(zone, pos), name_(name), extension_(extension) {}
2680 2681

 private:
2682
  const AstRawString* name_;
2683
  v8::Extension* extension_;
2684 2685 2686
};


2687
class ThisFunction FINAL : public Expression {
2688
 public:
2689
  DECLARE_NODE_TYPE(ThisFunction)
2690 2691

 protected:
2692
  ThisFunction(Zone* zone, int pos) : Expression(zone, pos) {}
2693 2694
};

2695

2696
class SuperReference FINAL : public Expression {
2697 2698 2699 2700 2701
 public:
  DECLARE_NODE_TYPE(SuperReference)

  VariableProxy* this_var() const { return this_var_; }

2702 2703
  static int num_ids() { return parent_num_ids() + 1; }
  TypeFeedbackId HomeObjectFeedbackId() { return TypeFeedbackId(local_id(0)); }
2704

2705
  // Type feedback information.
2706
  virtual FeedbackVectorRequirements ComputeFeedbackRequirements() OVERRIDE {
2707 2708
    return FeedbackVectorRequirements(0, FLAG_vector_ics ? 1 : 0);
  }
2709
  virtual void SetFirstFeedbackICSlot(FeedbackVectorICSlot slot) OVERRIDE {
2710 2711 2712
    homeobject_feedback_slot_ = slot;
  }

2713
  FeedbackVectorICSlot HomeObjectFeedbackSlot() {
2714
    DCHECK(!FLAG_vector_ics || !homeobject_feedback_slot_.IsInvalid());
2715 2716 2717
    return homeobject_feedback_slot_;
  }

2718
 protected:
2719 2720
  SuperReference(Zone* zone, VariableProxy* this_var, int pos)
      : Expression(zone, pos),
2721
        this_var_(this_var),
2722
        homeobject_feedback_slot_(FeedbackVectorICSlot::Invalid()) {
2723
    DCHECK(this_var->is_this());
2724
  }
2725
  static int parent_num_ids() { return Expression::num_ids(); }
2726

2727
 private:
2728 2729
  int local_id(int n) const { return base_id() + parent_num_ids() + n; }

2730
  VariableProxy* this_var_;
2731
  FeedbackVectorICSlot homeobject_feedback_slot_;
2732 2733 2734
};


2735 2736
#undef DECLARE_NODE_TYPE

2737

2738 2739 2740 2741
// ----------------------------------------------------------------------------
// Regular expressions


2742 2743 2744 2745 2746 2747 2748 2749 2750 2751
class RegExpVisitor BASE_EMBEDDED {
 public:
  virtual ~RegExpVisitor() { }
#define MAKE_CASE(Name)                                              \
  virtual void* Visit##Name(RegExp##Name*, void* data) = 0;
  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
#undef MAKE_CASE
};


2752
class RegExpTree : public ZoneObject {
2753
 public:
2754
  static const int kInfinity = kMaxInt;
2755
  virtual ~RegExpTree() {}
2756 2757
  virtual void* Accept(RegExpVisitor* visitor, void* data) = 0;
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
erik.corry@gmail.com's avatar
erik.corry@gmail.com committed
2758
                             RegExpNode* on_success) = 0;
2759
  virtual bool IsTextElement() { return false; }
2760 2761
  virtual bool IsAnchoredAtStart() { return false; }
  virtual bool IsAnchoredAtEnd() { return false; }
2762 2763
  virtual int min_match() = 0;
  virtual int max_match() = 0;
2764 2765 2766
  // Returns the interval of registers used for captures within this
  // expression.
  virtual Interval CaptureRegisters() { return Interval::Empty(); }
2767
  virtual void AppendToText(RegExpText* text, Zone* zone);
2768
  std::ostream& Print(std::ostream& os, Zone* zone);  // NOLINT
2769 2770 2771 2772 2773 2774 2775 2776
#define MAKE_ASTYPE(Name)                                                  \
  virtual RegExp##Name* As##Name();                                        \
  virtual bool Is##Name();
  FOR_EACH_REG_EXP_TREE_TYPE(MAKE_ASTYPE)
#undef MAKE_ASTYPE
};


2777
class RegExpDisjunction FINAL : public RegExpTree {
2778
 public:
2779
  explicit RegExpDisjunction(ZoneList<RegExpTree*>* alternatives);
2780
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2781
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2782 2783 2784 2785 2786 2787 2788 2789
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpDisjunction* AsDisjunction() OVERRIDE;
  virtual Interval CaptureRegisters() OVERRIDE;
  virtual bool IsDisjunction() OVERRIDE;
  virtual bool IsAnchoredAtStart() OVERRIDE;
  virtual bool IsAnchoredAtEnd() OVERRIDE;
  virtual int min_match() OVERRIDE { return min_match_; }
  virtual int max_match() OVERRIDE { return max_match_; }
2790 2791 2792
  ZoneList<RegExpTree*>* alternatives() { return alternatives_; }
 private:
  ZoneList<RegExpTree*>* alternatives_;
2793 2794
  int min_match_;
  int max_match_;
2795 2796 2797
};


2798
class RegExpAlternative FINAL : public RegExpTree {
2799
 public:
2800
  explicit RegExpAlternative(ZoneList<RegExpTree*>* nodes);
2801
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2802
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2803 2804 2805 2806 2807 2808 2809 2810
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpAlternative* AsAlternative() OVERRIDE;
  virtual Interval CaptureRegisters() OVERRIDE;
  virtual bool IsAlternative() OVERRIDE;
  virtual bool IsAnchoredAtStart() OVERRIDE;
  virtual bool IsAnchoredAtEnd() OVERRIDE;
  virtual int min_match() OVERRIDE { return min_match_; }
  virtual int max_match() OVERRIDE { return max_match_; }
2811 2812 2813
  ZoneList<RegExpTree*>* nodes() { return nodes_; }
 private:
  ZoneList<RegExpTree*>* nodes_;
2814 2815
  int min_match_;
  int max_match_;
2816 2817 2818
};


2819
class RegExpAssertion FINAL : public RegExpTree {
2820
 public:
2821
  enum AssertionType {
2822 2823 2824 2825 2826 2827
    START_OF_LINE,
    START_OF_INPUT,
    END_OF_LINE,
    END_OF_INPUT,
    BOUNDARY,
    NON_BOUNDARY
2828
  };
2829
  explicit RegExpAssertion(AssertionType type) : assertion_type_(type) { }
2830
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2831
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2832 2833 2834 2835 2836 2837 2838
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpAssertion* AsAssertion() OVERRIDE;
  virtual bool IsAssertion() OVERRIDE;
  virtual bool IsAnchoredAtStart() OVERRIDE;
  virtual bool IsAnchoredAtEnd() OVERRIDE;
  virtual int min_match() OVERRIDE { return 0; }
  virtual int max_match() OVERRIDE { return 0; }
2839
  AssertionType assertion_type() { return assertion_type_; }
2840
 private:
2841
  AssertionType assertion_type_;
2842 2843 2844
};


2845
class CharacterSet FINAL BASE_EMBEDDED {
2846 2847 2848 2849 2850 2851 2852
 public:
  explicit CharacterSet(uc16 standard_set_type)
      : ranges_(NULL),
        standard_set_type_(standard_set_type) {}
  explicit CharacterSet(ZoneList<CharacterRange>* ranges)
      : ranges_(ranges),
        standard_set_type_(0) {}
2853
  ZoneList<CharacterRange>* ranges(Zone* zone);
2854 2855 2856 2857 2858
  uc16 standard_set_type() { return standard_set_type_; }
  void set_standard_set_type(uc16 special_set_type) {
    standard_set_type_ = special_set_type;
  }
  bool is_standard() { return standard_set_type_ != 0; }
2859
  void Canonicalize();
2860 2861 2862 2863 2864 2865 2866 2867
 private:
  ZoneList<CharacterRange>* ranges_;
  // If non-zero, the value represents a standard set (e.g., all whitespace
  // characters) without having to expand the ranges.
  uc16 standard_set_type_;
};


2868
class RegExpCharacterClass FINAL : public RegExpTree {
2869 2870
 public:
  RegExpCharacterClass(ZoneList<CharacterRange>* ranges, bool is_negated)
2871
      : set_(ranges),
2872
        is_negated_(is_negated) { }
2873
  explicit RegExpCharacterClass(uc16 type)
2874 2875
      : set_(type),
        is_negated_(false) { }
2876
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2877
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2878 2879 2880 2881 2882 2883 2884
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpCharacterClass* AsCharacterClass() OVERRIDE;
  virtual bool IsCharacterClass() OVERRIDE;
  virtual bool IsTextElement() OVERRIDE { return true; }
  virtual int min_match() OVERRIDE { return 1; }
  virtual int max_match() OVERRIDE { return 1; }
  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
2885 2886 2887
  CharacterSet character_set() { return set_; }
  // TODO(lrn): Remove need for complex version if is_standard that
  // recognizes a mangled standard set and just do { return set_.is_special(); }
2888
  bool is_standard(Zone* zone);
2889 2890 2891 2892 2893 2894 2895 2896 2897
  // Returns a value representing the standard character set if is_standard()
  // returns true.
  // Currently used values are:
  // s : unicode whitespace
  // S : unicode non-whitespace
  // w : ASCII word character (digit, letter, underscore)
  // W : non-ASCII word character
  // d : ASCII digit
  // D : non-ASCII digit
2898
  // . : non-unicode non-newline
2899 2900
  // * : All characters
  uc16 standard_type() { return set_.standard_set_type(); }
2901
  ZoneList<CharacterRange>* ranges(Zone* zone) { return set_.ranges(zone); }
2902
  bool is_negated() { return is_negated_; }
2903

2904
 private:
2905
  CharacterSet set_;
2906 2907 2908 2909
  bool is_negated_;
};


2910
class RegExpAtom FINAL : public RegExpTree {
2911 2912
 public:
  explicit RegExpAtom(Vector<const uc16> data) : data_(data) { }
2913
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2914
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2915 2916 2917 2918 2919 2920 2921
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpAtom* AsAtom() OVERRIDE;
  virtual bool IsAtom() OVERRIDE;
  virtual bool IsTextElement() OVERRIDE { return true; }
  virtual int min_match() OVERRIDE { return data_.length(); }
  virtual int max_match() OVERRIDE { return data_.length(); }
  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
2922
  Vector<const uc16> data() { return data_; }
2923
  int length() { return data_.length(); }
2924 2925 2926 2927 2928
 private:
  Vector<const uc16> data_;
};


2929
class RegExpText FINAL : public RegExpTree {
2930
 public:
2931
  explicit RegExpText(Zone* zone) : elements_(2, zone), length_(0) {}
2932
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2933
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2934 2935 2936 2937 2938 2939 2940
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpText* AsText() OVERRIDE;
  virtual bool IsText() OVERRIDE;
  virtual bool IsTextElement() OVERRIDE { return true; }
  virtual int min_match() OVERRIDE { return length_; }
  virtual int max_match() OVERRIDE { return length_; }
  virtual void AppendToText(RegExpText* text, Zone* zone) OVERRIDE;
2941 2942
  void AddElement(TextElement elm, Zone* zone)  {
    elements_.Add(elm, zone);
2943
    length_ += elm.length();
2944
  }
2945 2946 2947 2948 2949 2950 2951
  ZoneList<TextElement>* elements() { return &elements_; }
 private:
  ZoneList<TextElement> elements_;
  int length_;
};


2952
class RegExpQuantifier FINAL : public RegExpTree {
2953
 public:
2954 2955
  enum QuantifierType { GREEDY, NON_GREEDY, POSSESSIVE };
  RegExpQuantifier(int min, int max, QuantifierType type, RegExpTree* body)
2956 2957
      : body_(body),
        min_(min),
2958
        max_(max),
2959
        min_match_(min * body->min_match()),
2960
        quantifier_type_(type) {
2961 2962 2963 2964 2965 2966
    if (max > 0 && body->max_match() > kInfinity / max) {
      max_match_ = kInfinity;
    } else {
      max_match_ = max * body->max_match();
    }
  }
2967
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
2968
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
2969
                             RegExpNode* on_success) OVERRIDE;
2970 2971 2972 2973 2974
  static RegExpNode* ToNode(int min,
                            int max,
                            bool is_greedy,
                            RegExpTree* body,
                            RegExpCompiler* compiler,
2975 2976
                            RegExpNode* on_success,
                            bool not_at_start = false);
2977 2978 2979 2980 2981
  virtual RegExpQuantifier* AsQuantifier() OVERRIDE;
  virtual Interval CaptureRegisters() OVERRIDE;
  virtual bool IsQuantifier() OVERRIDE;
  virtual int min_match() OVERRIDE { return min_match_; }
  virtual int max_match() OVERRIDE { return max_match_; }
2982 2983
  int min() { return min_; }
  int max() { return max_; }
2984 2985 2986
  bool is_possessive() { return quantifier_type_ == POSSESSIVE; }
  bool is_non_greedy() { return quantifier_type_ == NON_GREEDY; }
  bool is_greedy() { return quantifier_type_ == GREEDY; }
2987
  RegExpTree* body() { return body_; }
2988

2989
 private:
2990
  RegExpTree* body_;
2991 2992
  int min_;
  int max_;
2993 2994
  int min_match_;
  int max_match_;
2995
  QuantifierType quantifier_type_;
2996 2997 2998
};


2999
class RegExpCapture FINAL : public RegExpTree {
3000 3001
 public:
  explicit RegExpCapture(RegExpTree* body, int index)
3002
      : body_(body), index_(index) { }
3003
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
3004
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
3005
                             RegExpNode* on_success) OVERRIDE;
3006 3007 3008
  static RegExpNode* ToNode(RegExpTree* body,
                            int index,
                            RegExpCompiler* compiler,
erik.corry@gmail.com's avatar
erik.corry@gmail.com committed
3009
                            RegExpNode* on_success);
3010 3011 3012 3013 3014 3015 3016
  virtual RegExpCapture* AsCapture() OVERRIDE;
  virtual bool IsAnchoredAtStart() OVERRIDE;
  virtual bool IsAnchoredAtEnd() OVERRIDE;
  virtual Interval CaptureRegisters() OVERRIDE;
  virtual bool IsCapture() OVERRIDE;
  virtual int min_match() OVERRIDE { return body_->min_match(); }
  virtual int max_match() OVERRIDE { return body_->max_match(); }
3017 3018 3019 3020
  RegExpTree* body() { return body_; }
  int index() { return index_; }
  static int StartRegister(int index) { return index * 2; }
  static int EndRegister(int index) { return index * 2 + 1; }
3021

3022 3023 3024 3025 3026 3027
 private:
  RegExpTree* body_;
  int index_;
};


3028
class RegExpLookahead FINAL : public RegExpTree {
3029
 public:
3030 3031 3032 3033
  RegExpLookahead(RegExpTree* body,
                  bool is_positive,
                  int capture_count,
                  int capture_from)
3034
      : body_(body),
3035 3036 3037 3038
        is_positive_(is_positive),
        capture_count_(capture_count),
        capture_from_(capture_from) { }

3039
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
3040
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
3041 3042 3043 3044 3045 3046 3047
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpLookahead* AsLookahead() OVERRIDE;
  virtual Interval CaptureRegisters() OVERRIDE;
  virtual bool IsLookahead() OVERRIDE;
  virtual bool IsAnchoredAtStart() OVERRIDE;
  virtual int min_match() OVERRIDE { return 0; }
  virtual int max_match() OVERRIDE { return 0; }
3048 3049
  RegExpTree* body() { return body_; }
  bool is_positive() { return is_positive_; }
3050 3051
  int capture_count() { return capture_count_; }
  int capture_from() { return capture_from_; }
3052

3053 3054 3055
 private:
  RegExpTree* body_;
  bool is_positive_;
3056 3057
  int capture_count_;
  int capture_from_;
3058 3059 3060
};


3061
class RegExpBackReference FINAL : public RegExpTree {
3062 3063
 public:
  explicit RegExpBackReference(RegExpCapture* capture)
3064
      : capture_(capture) { }
3065
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
3066
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
3067 3068 3069 3070 3071
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpBackReference* AsBackReference() OVERRIDE;
  virtual bool IsBackReference() OVERRIDE;
  virtual int min_match() OVERRIDE { return 0; }
  virtual int max_match() OVERRIDE { return capture_->max_match(); }
3072 3073 3074 3075 3076 3077 3078
  int index() { return capture_->index(); }
  RegExpCapture* capture() { return capture_; }
 private:
  RegExpCapture* capture_;
};


3079
class RegExpEmpty FINAL : public RegExpTree {
3080 3081
 public:
  RegExpEmpty() { }
3082
  virtual void* Accept(RegExpVisitor* visitor, void* data) OVERRIDE;
3083
  virtual RegExpNode* ToNode(RegExpCompiler* compiler,
3084 3085 3086 3087 3088
                             RegExpNode* on_success) OVERRIDE;
  virtual RegExpEmpty* AsEmpty() OVERRIDE;
  virtual bool IsEmpty() OVERRIDE;
  virtual int min_match() OVERRIDE { return 0; }
  virtual int max_match() OVERRIDE { return 0; }
3089 3090 3091
};


3092 3093 3094
// ----------------------------------------------------------------------------
// Out-of-line inline constructors (to side-step cyclic dependencies).

3095 3096
inline ModuleVariable::ModuleVariable(Zone* zone, VariableProxy* proxy, int pos)
    : Module(zone, proxy->interface(), pos),
3097 3098 3099 3100
      proxy_(proxy) {
}


3101 3102 3103 3104
// ----------------------------------------------------------------------------
// Basic visitor
// - leaf node visitors are abstract.

3105
class AstVisitor BASE_EMBEDDED {
3106
 public:
3107
  AstVisitor() {}
3108
  virtual ~AstVisitor() {}
3109

3110
  // Stack overflow check and dynamic dispatch.
3111
  virtual void Visit(AstNode* node) = 0;
3112

3113
  // Iteration left-to-right.
3114
  virtual void VisitDeclarations(ZoneList<Declaration*>* declarations);
3115 3116 3117
  virtual void VisitStatements(ZoneList<Statement*>* statements);
  virtual void VisitExpressions(ZoneList<Expression*>* expressions);

3118
  // Individual AST nodes.
3119 3120
#define DEF_VISIT(type)                         \
  virtual void Visit##type(type* node) = 0;
3121
  AST_NODE_LIST(DEF_VISIT)
3122
#undef DEF_VISIT
3123
};
3124

3125

3126 3127
#define DEFINE_AST_VISITOR_SUBCLASS_MEMBERS()                       \
public:                                                             \
3128
  virtual void Visit(AstNode* node) FINAL OVERRIDE {          \
3129 3130 3131 3132 3133 3134 3135 3136 3137
    if (!CheckStackOverflow()) node->Accept(this);                  \
  }                                                                 \
                                                                    \
  void SetStackOverflow() { stack_overflow_ = true; }               \
  void ClearStackOverflow() { stack_overflow_ = false; }            \
  bool HasStackOverflow() const { return stack_overflow_; }         \
                                                                    \
  bool CheckStackOverflow() {                                       \
    if (stack_overflow_) return true;                               \
3138
    StackLimitCheck check(zone_->isolate());                        \
3139 3140 3141 3142 3143
    if (!check.HasOverflowed()) return false;                       \
    return (stack_overflow_ = true);                                \
  }                                                                 \
                                                                    \
private:                                                            \
3144 3145
  void InitializeAstVisitor(Zone* zone) {                           \
    zone_ = zone;                                                   \
3146 3147
    stack_overflow_ = false;                                        \
  }                                                                 \
3148 3149
  Zone* zone() { return zone_; }                                    \
  Isolate* isolate() { return zone_->isolate(); }                   \
3150
                                                                    \
3151
  Zone* zone_;                                                      \
3152
  bool stack_overflow_
3153

3154

3155 3156 3157 3158 3159
// ----------------------------------------------------------------------------
// Construction time visitor.

class AstConstructionVisitor BASE_EMBEDDED {
 public:
3160
  AstConstructionVisitor() {}
3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172

  AstProperties* ast_properties() { return &properties_; }

 private:
  template<class> friend class AstNodeFactory;

  // Node visitors.
#define DEF_VISIT(type) \
  void Visit##type(type* node);
  AST_NODE_LIST(DEF_VISIT)
#undef DEF_VISIT

3173
  void add_slot_node(AstNode* slot_node) {
3174 3175
    FeedbackVectorRequirements reqs = slot_node->ComputeFeedbackRequirements();
    if (reqs.slots() > 0) {
3176 3177
      slot_node->SetFirstFeedbackSlot(
          FeedbackVectorSlot(properties_.feedback_slots()));
3178 3179 3180 3181 3182 3183
      properties_.increase_feedback_slots(reqs.slots());
    }
    if (reqs.ic_slots() > 0) {
      slot_node->SetFirstFeedbackICSlot(
          FeedbackVectorICSlot(properties_.ic_feedback_slots()));
      properties_.increase_ic_feedback_slots(reqs.ic_slots());
3184
    }
3185 3186
  }

3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205
  AstProperties properties_;
};


class AstNullVisitor BASE_EMBEDDED {
 public:
  // Node visitors.
#define DEF_VISIT(type) \
  void Visit##type(type* node) {}
  AST_NODE_LIST(DEF_VISIT)
#undef DEF_VISIT
};



// ----------------------------------------------------------------------------
// AstNode factory

template<class Visitor>
3206
class AstNodeFactory FINAL BASE_EMBEDDED {
3207
 public:
3208 3209 3210
  explicit AstNodeFactory(AstValueFactory* ast_value_factory)
      : zone_(ast_value_factory->zone()),
        ast_value_factory_(ast_value_factory) {}
3211 3212 3213 3214 3215 3216 3217

  Visitor* visitor() { return &visitor_; }

#define VISIT_AND_RETURN(NodeType, node) \
  visitor_.Visit##NodeType((node)); \
  return node;

3218 3219
  VariableDeclaration* NewVariableDeclaration(VariableProxy* proxy,
                                              VariableMode mode,
3220 3221
                                              Scope* scope,
                                              int pos) {
3222
    VariableDeclaration* decl =
3223
        new(zone_) VariableDeclaration(zone_, proxy, mode, scope, pos);
3224 3225 3226
    VISIT_AND_RETURN(VariableDeclaration, decl)
  }

3227 3228 3229
  FunctionDeclaration* NewFunctionDeclaration(VariableProxy* proxy,
                                              VariableMode mode,
                                              FunctionLiteral* fun,
3230 3231
                                              Scope* scope,
                                              int pos) {
3232
    FunctionDeclaration* decl =
3233
        new(zone_) FunctionDeclaration(zone_, proxy, mode, fun, scope, pos);
3234 3235 3236
    VISIT_AND_RETURN(FunctionDeclaration, decl)
  }

3237 3238
  ModuleDeclaration* NewModuleDeclaration(VariableProxy* proxy,
                                          Module* module,
3239 3240
                                          Scope* scope,
                                          int pos) {
3241
    ModuleDeclaration* decl =
3242
        new(zone_) ModuleDeclaration(zone_, proxy, module, scope, pos);
3243 3244 3245
    VISIT_AND_RETURN(ModuleDeclaration, decl)
  }

3246 3247
  ImportDeclaration* NewImportDeclaration(VariableProxy* proxy,
                                          Module* module,
3248 3249
                                          Scope* scope,
                                          int pos) {
3250
    ImportDeclaration* decl =
3251
        new(zone_) ImportDeclaration(zone_, proxy, module, scope, pos);
3252 3253 3254 3255
    VISIT_AND_RETURN(ImportDeclaration, decl)
  }

  ExportDeclaration* NewExportDeclaration(VariableProxy* proxy,
3256 3257
                                          Scope* scope,
                                          int pos) {
3258
    ExportDeclaration* decl =
3259
        new(zone_) ExportDeclaration(zone_, proxy, scope, pos);
3260 3261 3262
    VISIT_AND_RETURN(ExportDeclaration, decl)
  }

3263
  ModuleLiteral* NewModuleLiteral(Block* body, Interface* interface, int pos) {
3264 3265
    ModuleLiteral* module =
        new(zone_) ModuleLiteral(zone_, body, interface, pos);
3266 3267 3268
    VISIT_AND_RETURN(ModuleLiteral, module)
  }

3269
  ModuleVariable* NewModuleVariable(VariableProxy* proxy, int pos) {
3270
    ModuleVariable* module = new(zone_) ModuleVariable(zone_, proxy, pos);
3271
    VISIT_AND_RETURN(ModuleVariable, module)
3272 3273
  }

3274 3275
  ModulePath* NewModulePath(Module* origin, const AstRawString* name, int pos) {
    ModulePath* module = new (zone_) ModulePath(zone_, origin, name, pos);
3276
    VISIT_AND_RETURN(ModulePath, module)
3277 3278
  }

3279
  ModuleUrl* NewModuleUrl(Handle<String> url, int pos) {
3280
    ModuleUrl* module = new(zone_) ModuleUrl(zone_, url, pos);
3281
    VISIT_AND_RETURN(ModuleUrl, module)
3282 3283
  }

3284
  Block* NewBlock(ZoneList<const AstRawString*>* labels,
3285
                  int capacity,
3286 3287
                  bool is_initializer_block,
                  int pos) {
3288 3289
    Block* block =
        new (zone_) Block(zone_, labels, capacity, is_initializer_block, pos);
3290 3291 3292
    VISIT_AND_RETURN(Block, block)
  }

3293
#define STATEMENT_WITH_LABELS(NodeType)                                     \
3294
  NodeType* New##NodeType(ZoneList<const AstRawString*>* labels, int pos) { \
3295
    NodeType* stmt = new (zone_) NodeType(zone_, labels, pos);              \
3296
    VISIT_AND_RETURN(NodeType, stmt);                                       \
3297 3298 3299 3300 3301 3302 3303
  }
  STATEMENT_WITH_LABELS(DoWhileStatement)
  STATEMENT_WITH_LABELS(WhileStatement)
  STATEMENT_WITH_LABELS(ForStatement)
  STATEMENT_WITH_LABELS(SwitchStatement)
#undef STATEMENT_WITH_LABELS

3304
  ForEachStatement* NewForEachStatement(ForEachStatement::VisitMode visit_mode,
3305
                                        ZoneList<const AstRawString*>* labels,
3306
                                        int pos) {
3307 3308
    switch (visit_mode) {
      case ForEachStatement::ENUMERATE: {
3309
        ForInStatement* stmt = new (zone_) ForInStatement(zone_, labels, pos);
3310 3311 3312
        VISIT_AND_RETURN(ForInStatement, stmt);
      }
      case ForEachStatement::ITERATE: {
3313
        ForOfStatement* stmt = new (zone_) ForOfStatement(zone_, labels, pos);
3314 3315 3316 3317 3318 3319 3320
        VISIT_AND_RETURN(ForOfStatement, stmt);
      }
    }
    UNREACHABLE();
    return NULL;
  }

3321 3322
  ModuleStatement* NewModuleStatement(
      VariableProxy* proxy, Block* body, int pos) {
3323
    ModuleStatement* stmt = new(zone_) ModuleStatement(zone_, proxy, body, pos);
3324 3325 3326
    VISIT_AND_RETURN(ModuleStatement, stmt)
  }

3327
  ExpressionStatement* NewExpressionStatement(Expression* expression, int pos) {
3328 3329
    ExpressionStatement* stmt =
        new(zone_) ExpressionStatement(zone_, expression, pos);
3330 3331 3332
    VISIT_AND_RETURN(ExpressionStatement, stmt)
  }

3333
  ContinueStatement* NewContinueStatement(IterationStatement* target, int pos) {
3334
    ContinueStatement* stmt = new(zone_) ContinueStatement(zone_, target, pos);
3335 3336 3337
    VISIT_AND_RETURN(ContinueStatement, stmt)
  }

3338
  BreakStatement* NewBreakStatement(BreakableStatement* target, int pos) {
3339
    BreakStatement* stmt = new(zone_) BreakStatement(zone_, target, pos);
3340 3341 3342
    VISIT_AND_RETURN(BreakStatement, stmt)
  }

3343
  ReturnStatement* NewReturnStatement(Expression* expression, int pos) {
3344
    ReturnStatement* stmt = new(zone_) ReturnStatement(zone_, expression, pos);
3345 3346 3347
    VISIT_AND_RETURN(ReturnStatement, stmt)
  }

3348 3349
  WithStatement* NewWithStatement(Scope* scope,
                                  Expression* expression,
3350 3351
                                  Statement* statement,
                                  int pos) {
3352
    WithStatement* stmt = new(zone_) WithStatement(
3353
        zone_, scope, expression, statement, pos);
3354 3355 3356 3357 3358
    VISIT_AND_RETURN(WithStatement, stmt)
  }

  IfStatement* NewIfStatement(Expression* condition,
                              Statement* then_statement,
3359 3360
                              Statement* else_statement,
                              int pos) {
3361 3362
    IfStatement* stmt = new (zone_)
        IfStatement(zone_, condition, then_statement, else_statement, pos);
3363 3364 3365 3366 3367 3368 3369
    VISIT_AND_RETURN(IfStatement, stmt)
  }

  TryCatchStatement* NewTryCatchStatement(int index,
                                          Block* try_block,
                                          Scope* scope,
                                          Variable* variable,
3370 3371
                                          Block* catch_block,
                                          int pos) {
3372
    TryCatchStatement* stmt = new(zone_) TryCatchStatement(
3373
        zone_, index, try_block, scope, variable, catch_block, pos);
3374 3375 3376 3377 3378
    VISIT_AND_RETURN(TryCatchStatement, stmt)
  }

  TryFinallyStatement* NewTryFinallyStatement(int index,
                                              Block* try_block,
3379 3380
                                              Block* finally_block,
                                              int pos) {
3381 3382
    TryFinallyStatement* stmt = new(zone_) TryFinallyStatement(
        zone_, index, try_block, finally_block, pos);
3383 3384 3385
    VISIT_AND_RETURN(TryFinallyStatement, stmt)
  }

3386
  DebuggerStatement* NewDebuggerStatement(int pos) {
3387
    DebuggerStatement* stmt = new (zone_) DebuggerStatement(zone_, pos);
3388 3389 3390
    VISIT_AND_RETURN(DebuggerStatement, stmt)
  }

3391
  EmptyStatement* NewEmptyStatement(int pos) {
3392
    return new(zone_) EmptyStatement(zone_, pos);
3393 3394
  }

3395 3396
  CaseClause* NewCaseClause(
      Expression* label, ZoneList<Statement*>* statements, int pos) {
3397
    CaseClause* clause = new (zone_) CaseClause(zone_, label, statements, pos);
3398 3399 3400
    VISIT_AND_RETURN(CaseClause, clause)
  }

3401
  Literal* NewStringLiteral(const AstRawString* string, int pos) {
3402 3403
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewString(string), pos);
3404 3405 3406 3407 3408
    VISIT_AND_RETURN(Literal, lit)
  }

  // A JavaScript symbol (ECMA-262 edition 6).
  Literal* NewSymbolLiteral(const char* name, int pos) {
3409 3410
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewSymbol(name), pos);
3411 3412 3413
    VISIT_AND_RETURN(Literal, lit)
  }

3414
  Literal* NewNumberLiteral(double number, int pos) {
3415 3416
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewNumber(number), pos);
3417 3418 3419 3420
    VISIT_AND_RETURN(Literal, lit)
  }

  Literal* NewSmiLiteral(int number, int pos) {
3421 3422
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewSmi(number), pos);
3423 3424 3425 3426
    VISIT_AND_RETURN(Literal, lit)
  }

  Literal* NewBooleanLiteral(bool b, int pos) {
3427 3428
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewBoolean(b), pos);
3429 3430 3431 3432 3433
    VISIT_AND_RETURN(Literal, lit)
  }

  Literal* NewNullLiteral(int pos) {
    Literal* lit =
3434
        new (zone_) Literal(zone_, ast_value_factory_->NewNull(), pos);
3435 3436 3437 3438
    VISIT_AND_RETURN(Literal, lit)
  }

  Literal* NewUndefinedLiteral(int pos) {
3439 3440
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewUndefined(), pos);
3441 3442 3443 3444
    VISIT_AND_RETURN(Literal, lit)
  }

  Literal* NewTheHoleLiteral(int pos) {
3445 3446
    Literal* lit =
        new (zone_) Literal(zone_, ast_value_factory_->NewTheHole(), pos);
3447
    VISIT_AND_RETURN(Literal, lit)
3448 3449 3450 3451 3452
  }

  ObjectLiteral* NewObjectLiteral(
      ZoneList<ObjectLiteral::Property*>* properties,
      int literal_index,
3453
      int boilerplate_properties,
3454 3455
      bool has_function,
      int pos) {
3456 3457 3458
    ObjectLiteral* lit =
        new (zone_) ObjectLiteral(zone_, properties, literal_index,
                                  boilerplate_properties, has_function, pos);
3459 3460 3461
    VISIT_AND_RETURN(ObjectLiteral, lit)
  }

3462
  ObjectLiteral::Property* NewObjectLiteralProperty(Literal* key,
arv@chromium.org's avatar
arv@chromium.org committed
3463 3464 3465 3466
                                                    Expression* value,
                                                    bool is_static) {
    return new (zone_) ObjectLiteral::Property(zone_, ast_value_factory_, key,
                                               value, is_static);
3467 3468
  }

3469
  ObjectLiteral::Property* NewObjectLiteralProperty(bool is_getter,
3470
                                                    FunctionLiteral* value,
arv@chromium.org's avatar
arv@chromium.org committed
3471
                                                    int pos, bool is_static) {
3472
    ObjectLiteral::Property* prop =
arv@chromium.org's avatar
arv@chromium.org committed
3473
        new (zone_) ObjectLiteral::Property(zone_, is_getter, value, is_static);
3474
    prop->set_key(NewStringLiteral(value->raw_name(), pos));
3475 3476 3477
    return prop;  // Not an AST node, will not be visited.
  }

3478 3479
  RegExpLiteral* NewRegExpLiteral(const AstRawString* pattern,
                                  const AstRawString* flags,
3480 3481
                                  int literal_index,
                                  int pos) {
3482 3483
    RegExpLiteral* lit =
        new (zone_) RegExpLiteral(zone_, pattern, flags, literal_index, pos);
3484 3485 3486
    VISIT_AND_RETURN(RegExpLiteral, lit);
  }

3487
  ArrayLiteral* NewArrayLiteral(ZoneList<Expression*>* values,
3488
                                int literal_index,
3489
                                int pos) {
3490
    ArrayLiteral* lit =
3491
        new (zone_) ArrayLiteral(zone_, values, literal_index, pos);
3492 3493 3494
    VISIT_AND_RETURN(ArrayLiteral, lit)
  }

3495 3496
  VariableProxy* NewVariableProxy(Variable* var,
                                  int pos = RelocInfo::kNoPosition) {
3497
    VariableProxy* proxy = new (zone_) VariableProxy(zone_, var, pos);
3498 3499 3500
    VISIT_AND_RETURN(VariableProxy, proxy)
  }

3501
  VariableProxy* NewVariableProxy(const AstRawString* name,
3502
                                  bool is_this,
3503 3504
                                  Interface* interface = Interface::NewValue(),
                                  int position = RelocInfo::kNoPosition) {
3505 3506
    VariableProxy* proxy =
        new (zone_) VariableProxy(zone_, name, is_this, interface, position);
3507 3508 3509 3510
    VISIT_AND_RETURN(VariableProxy, proxy)
  }

  Property* NewProperty(Expression* obj, Expression* key, int pos) {
3511
    Property* prop = new (zone_) Property(zone_, obj, key, pos);
3512 3513 3514 3515 3516 3517
    VISIT_AND_RETURN(Property, prop)
  }

  Call* NewCall(Expression* expression,
                ZoneList<Expression*>* arguments,
                int pos) {
3518
    Call* call = new (zone_) Call(zone_, expression, arguments, pos);
3519 3520 3521 3522 3523 3524
    VISIT_AND_RETURN(Call, call)
  }

  CallNew* NewCallNew(Expression* expression,
                      ZoneList<Expression*>* arguments,
                      int pos) {
3525
    CallNew* call = new (zone_) CallNew(zone_, expression, arguments, pos);
3526 3527 3528
    VISIT_AND_RETURN(CallNew, call)
  }

3529
  CallRuntime* NewCallRuntime(const AstRawString* name,
3530
                              const Runtime::Function* function,
3531 3532
                              ZoneList<Expression*>* arguments,
                              int pos) {
3533
    CallRuntime* call =
3534
        new (zone_) CallRuntime(zone_, name, function, arguments, pos);
3535 3536 3537 3538 3539 3540 3541
    VISIT_AND_RETURN(CallRuntime, call)
  }

  UnaryOperation* NewUnaryOperation(Token::Value op,
                                    Expression* expression,
                                    int pos) {
    UnaryOperation* node =
3542
        new (zone_) UnaryOperation(zone_, op, expression, pos);
3543 3544 3545 3546 3547 3548 3549 3550
    VISIT_AND_RETURN(UnaryOperation, node)
  }

  BinaryOperation* NewBinaryOperation(Token::Value op,
                                      Expression* left,
                                      Expression* right,
                                      int pos) {
    BinaryOperation* node =
3551
        new (zone_) BinaryOperation(zone_, op, left, right, pos);
3552 3553 3554 3555 3556 3557 3558 3559
    VISIT_AND_RETURN(BinaryOperation, node)
  }

  CountOperation* NewCountOperation(Token::Value op,
                                    bool is_prefix,
                                    Expression* expr,
                                    int pos) {
    CountOperation* node =
3560
        new (zone_) CountOperation(zone_, op, is_prefix, expr, pos);
3561 3562 3563 3564 3565 3566 3567 3568
    VISIT_AND_RETURN(CountOperation, node)
  }

  CompareOperation* NewCompareOperation(Token::Value op,
                                        Expression* left,
                                        Expression* right,
                                        int pos) {
    CompareOperation* node =
3569
        new (zone_) CompareOperation(zone_, op, left, right, pos);
3570 3571 3572 3573 3574 3575
    VISIT_AND_RETURN(CompareOperation, node)
  }

  Conditional* NewConditional(Expression* condition,
                              Expression* then_expression,
                              Expression* else_expression,
3576
                              int position) {
3577
    Conditional* cond = new (zone_) Conditional(
3578
        zone_, condition, then_expression, else_expression, position);
3579 3580 3581 3582 3583 3584 3585
    VISIT_AND_RETURN(Conditional, cond)
  }

  Assignment* NewAssignment(Token::Value op,
                            Expression* target,
                            Expression* value,
                            int pos) {
3586 3587
    Assignment* assign = new (zone_) Assignment(zone_, op, target, value, pos);
    assign->Init(this);
3588 3589 3590
    VISIT_AND_RETURN(Assignment, assign)
  }

3591 3592
  Yield* NewYield(Expression *generator_object,
                  Expression* expression,
3593
                  Yield::Kind yield_kind,
3594
                  int pos) {
3595
    if (!expression) expression = NewUndefinedLiteral(pos);
3596 3597
    Yield* yield =
        new (zone_) Yield(zone_, generator_object, expression, yield_kind, pos);
3598 3599 3600
    VISIT_AND_RETURN(Yield, yield)
  }

3601
  Throw* NewThrow(Expression* exception, int pos) {
3602
    Throw* t = new (zone_) Throw(zone_, exception, pos);
3603 3604 3605 3606
    VISIT_AND_RETURN(Throw, t)
  }

  FunctionLiteral* NewFunctionLiteral(
3607 3608 3609
      const AstRawString* name, AstValueFactory* ast_value_factory,
      Scope* scope, ZoneList<Statement*>* body, int materialized_literal_count,
      int expected_property_count, int handler_count, int parameter_count,
3610
      FunctionLiteral::ParameterFlag has_duplicate_parameters,
3611
      FunctionLiteral::FunctionType function_type,
3612
      FunctionLiteral::IsFunctionFlag is_function,
3613 3614
      FunctionLiteral::IsParenthesizedFlag is_parenthesized, FunctionKind kind,
      int position) {
3615 3616 3617
    FunctionLiteral* lit = new (zone_) FunctionLiteral(
        zone_, name, ast_value_factory, scope, body, materialized_literal_count,
        expected_property_count, handler_count, parameter_count, function_type,
3618 3619
        has_duplicate_parameters, is_function, is_parenthesized, kind,
        position);
3620 3621
    // Top-level literal doesn't count for the AST's properties.
    if (is_function == FunctionLiteral::kIsFunction) {
3622 3623 3624 3625 3626
      visitor_.VisitFunctionLiteral(lit);
    }
    return lit;
  }

arv@chromium.org's avatar
arv@chromium.org committed
3627
  ClassLiteral* NewClassLiteral(const AstRawString* name, Expression* extends,
3628
                                Expression* constructor,
arv@chromium.org's avatar
arv@chromium.org committed
3629
                                ZoneList<ObjectLiteral::Property*>* properties,
3630 3631 3632
                                int start_position, int end_position) {
    ClassLiteral* lit =
        new (zone_) ClassLiteral(zone_, name, extends, constructor, properties,
3633
                                 start_position, end_position);
arv@chromium.org's avatar
arv@chromium.org committed
3634 3635 3636
    VISIT_AND_RETURN(ClassLiteral, lit)
  }

3637 3638 3639
  NativeFunctionLiteral* NewNativeFunctionLiteral(const AstRawString* name,
                                                  v8::Extension* extension,
                                                  int pos) {
3640
    NativeFunctionLiteral* lit =
3641
        new (zone_) NativeFunctionLiteral(zone_, name, extension, pos);
3642
    VISIT_AND_RETURN(NativeFunctionLiteral, lit)
3643 3644
  }

3645
  ThisFunction* NewThisFunction(int pos) {
3646
    ThisFunction* fun = new (zone_) ThisFunction(zone_, pos);
3647 3648 3649
    VISIT_AND_RETURN(ThisFunction, fun)
  }

3650
  SuperReference* NewSuperReference(VariableProxy* this_var, int pos) {
3651
    SuperReference* super = new (zone_) SuperReference(zone_, this_var, pos);
3652 3653 3654
    VISIT_AND_RETURN(SuperReference, super);
  }

3655 3656 3657 3658 3659
#undef VISIT_AND_RETURN

 private:
  Zone* zone_;
  Visitor visitor_;
3660
  AstValueFactory* ast_value_factory_;
3661 3662 3663
};


3664 3665 3666
} }  // namespace v8::internal

#endif  // V8_AST_H_