1b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org// Copyright 2012 the V8 project authors. All rights reserved.
23484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// Use of this source code is governed by a BSD-style license that can be
33484964a86451e86dcf04be9bd8c0d76ee04f081rossberg@chromium.org// found in the LICENSE file.
443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#ifndef V8_PARSER_H_
643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#define V8_PARSER_H_
743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
8196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/allocation.h"
9196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/ast.h"
10196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/compiler.h"  // For CachedDataMode
11196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/preparse-data.h"
124b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/preparse-data-format.h"
13196eb601290dc49c3754da728dc58700dff2de1bmachenbach@chromium.org#include "src/preparser.h"
144b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org#include "src/scopes.h"
1543d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
1671affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace v8 {
1769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.orgclass ScriptCompiler;
1869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
1971affb54842da76b24f0bb3184e9f0960523f89dkasperl@chromium.orgnamespace internal {
2043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
21b61a0d13e9690ef4c2de424bbe82a38884d981a6ager@chromium.orgclass CompilationInfo;
22eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgclass ParserLog;
23eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgclass PositionStack;
24eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgclass Target;
25eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
26eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.orgtemplate <typename T> class ZoneListWrapper;
27eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
2843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
2943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansenclass FunctionEntry BASE_EMBEDDED {
3043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
31c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  enum {
32c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    kStartPositionIndex,
33c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    kEndPositionIndex,
34c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    kLiteralCountIndex,
35c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    kPropertyCountIndex,
36486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    kStrictModeIndex,
37c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org    kSize
38c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  };
39c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
401b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  explicit FunctionEntry(Vector<unsigned> backing)
411b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org    : backing_(backing) { }
421b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  FunctionEntry() : backing_() { }
4443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
45c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int start_pos() { return backing_[kStartPositionIndex]; }
46c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int end_pos() { return backing_[kEndPositionIndex]; }
47c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int literal_count() { return backing_[kLiteralCountIndex]; }
48c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  int property_count() { return backing_[kPropertyCountIndex]; }
49486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  StrictMode strict_mode() {
50e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(backing_[kStrictModeIndex] == SLOPPY ||
51486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org           backing_[kStrictModeIndex] == STRICT);
52486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return static_cast<StrictMode>(backing_[kStrictModeIndex]);
536e28b5694dd5a29d2f37d56d5a005e7cfdd952d1erik.corry@gmail.com  }
54d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
55c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org  bool is_valid() { return !backing_.is_empty(); }
5643d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
5743d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
5843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen  Vector<unsigned> backing_;
5943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen};
6043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
6270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org// Wrapper around ScriptData to provide parser-specific functionality.
6370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.orgclass ParseData {
6443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen public:
6570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  explicit ParseData(ScriptData* script_data) : script_data_(script_data) {
6670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    CHECK(IsAligned(script_data->length(), sizeof(unsigned)));
6770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    CHECK(IsSane());
6870d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  }
69d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com  void Initialize();
70d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org  FunctionEntry GetFunctionEntry(int start);
7170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int FunctionCount();
7270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org
7370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  bool HasError();
7470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org
7570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  unsigned* Data() {  // Writable data as unsigned int array.
7670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    return reinterpret_cast<unsigned*>(const_cast<byte*>(script_data_->data()));
778f8fe81d7a9cced7a0d30e56124c0428d1a6d229machenbach@chromium.org  }
78d88afa260e45de10e729b05a20146184a488aff7erik.corry@gmail.com
7943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen private:
8070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  bool IsSane();
8170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  unsigned Magic();
8270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  unsigned Version();
8370d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int FunctionsSize();
8470d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int Length() const {
8570d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    // Script data length is already checked to be a multiple of unsigned size.
8670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    return script_data_->length() / sizeof(unsigned);
8770d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  }
88d236f4d96b5dd21acc5ec57f4e50fa97cdd97bb6ricow@chromium.org
8970d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  ScriptData* script_data_;
9070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  int function_index_;
9143d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
9270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  DISALLOW_COPY_AND_ASSIGN(ParseData);
93e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org};
94e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
95fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// ----------------------------------------------------------------------------
96fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// REGEXP PARSING
97e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
982efb900e7350b14be905abdeab077f3a64c583cfulan@chromium.org// A BufferedZoneList is an automatically growing list, just like (and backed
99e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// by) a ZoneList, that is optimized for the case of adding and removing
100e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// a single element. The last element added is stored outside the backing list,
101e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// and if no more than one element is ever added, the ZoneList isn't even
102e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// allocated.
103e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Elements must not be NULL pointers.
104e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgtemplate <typename T, int initial_size>
105e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgclass BufferedZoneList {
106e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org public:
107e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  BufferedZoneList() : list_(NULL), last_(NULL) {}
108e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
109e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Adds element at end of list. This element is buffered and can
110e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // be read using last() or removed using RemoveLast until a new Add or until
111e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // RemoveLast or GetList has been called.
1127028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  void Add(T* value, Zone* zone) {
113e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    if (last_ != NULL) {
114e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      if (list_ == NULL) {
1157028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org        list_ = new(zone) ZoneList<T*>(initial_size, zone);
116e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      }
1177028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      list_->Add(last_, zone);
118e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    }
119e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    last_ = value;
120e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
121e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
122e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  T* last() {
123e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_ != NULL);
124e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    return last_;
125e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
126e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
127e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  T* RemoveLast() {
128e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(last_ != NULL);
129e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    T* result = last_;
130e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    if ((list_ != NULL) && (list_->length() > 0))
131e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      last_ = list_->RemoveLast();
132e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    else
133e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      last_ = NULL;
134e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    return result;
135e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
136e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
137e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  T* Get(int i) {
138e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK((0 <= i) && (i < length()));
139e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    if (list_ == NULL) {
140e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org      DCHECK_EQ(0, i);
141e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      return last_;
142e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    } else {
143e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      if (i == list_->length()) {
144e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org        DCHECK(last_ != NULL);
145e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org        return last_;
146e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      } else {
147e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org        return list_->at(i);
148e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      }
149e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    }
150e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
151e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
152e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void Clear() {
153e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    list_ = NULL;
154e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    last_ = NULL;
155e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
156e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
157e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  int length() {
158e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    int length = (list_ == NULL) ? 0 : list_->length();
159e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    return length + ((last_ == NULL) ? 0 : 1);
160e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
161e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
1627028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  ZoneList<T*>* GetList(Zone* zone) {
163e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    if (list_ == NULL) {
1647028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      list_ = new(zone) ZoneList<T*>(initial_size, zone);
165e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    }
166e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    if (last_ != NULL) {
1677028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org      list_->Add(last_, zone);
168e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org      last_ = NULL;
169e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    }
170e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    return list_;
171e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  }
172e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
173e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org private:
174e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  ZoneList<T*>* list_;
175e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  T* last_;
176e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org};
177e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
178e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
179e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
180e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.orgclass RegExpBuilder: public ZoneObject {
181e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org public:
182400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org  explicit RegExpBuilder(Zone* zone);
183e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void AddCharacter(uc16 character);
184e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // "Adds" an empty expression. Does nothing except consume a
185e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // following quantifier
186e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void AddEmpty();
187e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void AddAtom(RegExpTree* tree);
188e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void AddAssertion(RegExpTree* tree);
189e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void NewAlternative();  // '|'
190dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  void AddQuantifierToAtom(
191dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org      int min, int max, RegExpQuantifier::QuantifierType type);
192e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ToRegExp();
193e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
194e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org private:
195e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void FlushCharacters();
196e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void FlushText();
197e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void FlushTerms();
1987028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org  Zone* zone() const { return zone_; }
199c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org
200c36ce6e8979bbbd43539f0a0effc87ea20dd65cckmillikin@chromium.org  Zone* zone_;
201e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool pending_empty_;
202e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  ZoneList<uc16>* characters_;
203e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  BufferedZoneList<RegExpTree, 2> terms_;
204e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  BufferedZoneList<RegExpTree, 2> text_;
205e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  BufferedZoneList<RegExpTree, 2> alternatives_;
206e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org#ifdef DEBUG
207e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
208e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org#define LAST(x) last_added_ = x;
209e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org#else
210e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org#define LAST(x)
211e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org#endif
212e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org};
213e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
214e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
215e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.orgclass RegExpParser BASE_EMBEDDED {
216e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org public:
217e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpParser(FlatStringReader* in,
218e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org               Handle<String>* error,
2195a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org               bool multiline_mode,
2205a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org               Zone* zone);
221eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
222eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  static bool ParseRegExp(FlatStringReader* input,
223eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org                          bool multiline,
2245a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                          RegExpCompileData* result,
2255a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org                          Zone* zone);
226eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
227e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ParsePattern();
228e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ParseDisjunction();
229e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ParseGroup();
230e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ParseCharacterClass();
231e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
232e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Parses a {...,...} quantifier and stores the range in the given
233e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // out parameters.
234e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool ParseIntervalQuantifier(int* min_out, int* max_out);
235e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
236e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Parses and returns a single escaped character.  The character
237e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // must not be 'b' or 'B' since they are usually handle specially.
238e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  uc32 ParseClassCharacterEscape();
239e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
240e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Checks whether the following is a length-digit hexadecimal number,
241e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // and sets the value if it is.
242e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool ParseHexEscape(int length, uc32* value);
243e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
244e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  uc32 ParseOctalLiteral();
245e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
246e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Tries to parse the input as a back reference.  If successful it
247e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // stores the result in the output parameter and returns true.  If
248e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // it fails it will push back the characters read so the same characters
249e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // can be reparsed.
250e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool ParseBackReferenceIndex(int* index_out);
251e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
252e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  CharacterRange ParseClassAtom(uc16* char_class);
253e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  RegExpTree* ReportError(Vector<const char> message);
254e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void Advance();
255e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void Advance(int dist);
256e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void Reset(int pos);
257e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
258e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Reports whether the pattern might be used as a literal search string.
259e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  // Only use if the result of the parse is a single atom node.
260e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool simple();
261e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool contains_anchor() { return contains_anchor_; }
262e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void set_contains_anchor() { contains_anchor_ = true; }
263e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
264e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  int position() { return next_pos_ - 1; }
265e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool failed() { return failed_; }
266e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
267e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  static const int kMaxCaptures = 1 << 16;
268e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  static const uc32 kEndMarker = (1 << 21);
269e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
270e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org private:
271e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  enum SubexpressionType {
272e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    INITIAL,
273e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    CAPTURE,  // All positive values represent captures.
274e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    POSITIVE_LOOKAHEAD,
275e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    NEGATIVE_LOOKAHEAD,
276e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    GROUPING
277e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  };
278e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
279e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  class RegExpParserState : public ZoneObject {
280e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org   public:
281e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    RegExpParserState(RegExpParserState* previous_state,
282e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org                      SubexpressionType group_type,
283400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                      int disjunction_capture_index,
284400388edd471bd4d4a97b21c52c1024cd1cc5708rossberg@chromium.org                      Zone* zone)
285e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org        : previous_state_(previous_state),
2867028c05c1c71b9d5c5fe1bca01f2461d17a2dda7mmassi@chromium.org          builder_(new(zone) RegExpBuilder(zone)),
287e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org          group_type_(group_type),
288e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org          disjunction_capture_index_(disjunction_capture_index) {}
289e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Parser state of containing expression, if any.
290e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    RegExpParserState* previous_state() { return previous_state_; }
291e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    bool IsSubexpression() { return previous_state_ != NULL; }
292e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // RegExpBuilder building this regexp's AST.
293e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    RegExpBuilder* builder() { return builder_; }
294e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Type of regexp being parsed (parenthesized group or entire regexp).
295e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    SubexpressionType group_type() { return group_type_; }
296e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Index in captures array of first capture in this sub-expression, if any.
297e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Also the capture index of this sub-expression itself, if group_type
298e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // is CAPTURE.
299e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    int capture_index() { return disjunction_capture_index_; }
300e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
301e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org   private:
302e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Linked list implementation of stack of states.
303e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    RegExpParserState* previous_state_;
304e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Builder for the stored disjunction.
305e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    RegExpBuilder* builder_;
306e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Stored disjunction type (capture, look-ahead or grouping), if any.
307e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    SubexpressionType group_type_;
308e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    // Stored disjunction's capture index (if any).
309e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org    int disjunction_capture_index_;
310e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  };
311e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
312ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate() { return isolate_; }
3135a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Zone* zone() const { return zone_; }
314ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
315e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  uc32 current() { return current_; }
316e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool has_more() { return has_more_; }
317e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool has_next() { return next_pos_ < in()->length(); }
318e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  uc32 Next();
319e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  FlatStringReader* in() { return in_; }
320e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  void ScanForCaptures();
321fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
322ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org  Isolate* isolate_;
3235a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  Zone* zone_;
324fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Handle<String>* error_;
325fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  ZoneList<RegExpCapture*>* captures_;
326fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  FlatStringReader* in_;
327e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  uc32 current_;
328fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  int next_pos_;
329fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // The capture count is only valid after we have scanned for captures.
330fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  int capture_count_;
331e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool has_more_;
332e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool multiline_;
333e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool simple_;
334e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool contains_anchor_;
335e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool is_scanned_for_captures_;
336e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org  bool failed_;
337e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org};
338e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
339fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// ----------------------------------------------------------------------------
340fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org// JAVASCRIPT PARSING
341e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
342f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass Parser;
3431b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.orgclass SingletonLogger;
3441b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
345f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass ParserTraits {
346f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org public:
347f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  struct Type {
34897b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // TODO(marja): To be removed. The Traits object should contain all the data
34997b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // it needs.
350f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef v8::internal::Parser* Parser;
351f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
35297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // Used by FunctionState and BlockState.
353f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef v8::internal::Scope Scope;
3549bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    typedef v8::internal::Scope* ScopePtr;
355f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef Variable GeneratorVariable;
356f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef v8::internal::Zone Zone;
357f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
3589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    typedef v8::internal::AstProperties AstProperties;
3599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    typedef Vector<VariableProxy*> ParameterIdentifierVector;
3609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
361f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    // Return types for traversing functions.
36208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    typedef const AstRawString* Identifier;
363f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef v8::internal::Expression* Expression;
3646b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org    typedef Yield* YieldExpression;
365486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    typedef v8::internal::FunctionLiteral* FunctionLiteral;
366a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    typedef v8::internal::ClassLiteral* ClassLiteral;
367486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    typedef v8::internal::Literal* Literal;
368486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    typedef ObjectLiteral::Property* ObjectLiteralProperty;
369f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    typedef ZoneList<v8::internal::Expression*>* ExpressionList;
370486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    typedef ZoneList<ObjectLiteral::Property*>* PropertyList;
371865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    typedef ZoneList<v8::internal::Statement*>* StatementList;
37297b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org
37397b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    // For constructing objects returned by the traversing functions.
37497b98c9169c85693801d4d59089450695ad82e2dmachenbach@chromium.org    typedef AstNodeFactory<AstConstructionVisitor> Factory;
375f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  };
376f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
377f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org  class Checkpoint;
378f1a5a1dc668380a183184ee7629703846eefcfaemachenbach@chromium.org
379f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  explicit ParserTraits(Parser* parser) : parser_(parser) {}
380f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
381f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Custom operations executed when FunctionStates are created and destructed.
382a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  template <typename FunctionState>
383a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static void SetUpFunctionState(FunctionState* function_state) {
384a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    function_state->saved_id_gen_ = *function_state->ast_node_id_gen_;
385a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org    *function_state->ast_node_id_gen_ =
386a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org        AstNode::IdGen(BailoutId::FirstUsable().ToInt());
387f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
388f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
389a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  template <typename FunctionState>
390a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  static void TearDownFunctionState(FunctionState* function_state) {
391f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    if (function_state->outer_function_state_ != NULL) {
392a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org      *function_state->ast_node_id_gen_ = function_state->saved_id_gen_;
393f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    }
394f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
395f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
396f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Helper functions for recursive descent.
39708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  bool IsEvalOrArguments(const AstRawString* identifier) const;
3989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE bool IsFutureStrictReserved(const AstRawString* identifier) const;
399f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
4006b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // Returns true if the expression is of type "this.foo".
4016b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  static bool IsThisProperty(Expression* expression);
4026b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
40369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  static bool IsIdentifier(Expression* expression);
40469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
405a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  bool IsPrototype(const AstRawString* identifier) const;
406a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
407a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  bool IsConstructor(const AstRawString* identifier) const;
408a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
40908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  static const AstRawString* AsIdentifier(Expression* expression) {
410e3c177a423baa3c30225c4e422b6f6c76d38b951machenbach@chromium.org    DCHECK(IsIdentifier(expression));
41108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    return expression->AsVariableProxy()->raw_name();
4124edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  }
4134edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
414486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  static bool IsBoilerplateProperty(ObjectLiteral::Property* property) {
415486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return ObjectLiteral::IsBoilerplateProperty(property);
416486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
417486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
41808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  static bool IsArrayIndex(const AstRawString* string, uint32_t* index) {
41908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    return string->AsArrayIndex(index);
420486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
421486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
4226b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // Functions for encapsulating the differences between parsing and preparsing;
4236b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // operations interleaved with the recursive descent.
42408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  static void PushLiteralName(FuncNameInferrer* fni, const AstRawString* id) {
425486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    fni->PushLiteralName(id);
426486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
427fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  void PushPropertyName(FuncNameInferrer* fni, Expression* expression);
4289d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  static void InferFunctionName(FuncNameInferrer* fni,
4299d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                                FunctionLiteral* func_to_infer) {
4309d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org    fni->AddFunction(func_to_infer);
4319d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org  }
432486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
433486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  static void CheckFunctionLiteralInsideTopLevelObjectLiteral(
434e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      Scope* scope, ObjectLiteralProperty* property, bool* has_function) {
435e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    Expression* value = property->value();
436486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    if (scope->DeclarationScope()->is_global_scope() &&
437486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org        value->AsFunctionLiteral() != NULL) {
438486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      *has_function = true;
439486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org      value->AsFunctionLiteral()->set_pretenure();
440486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    }
441486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
442486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org
4436b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // If we assign a function literal to a property we pretenure the
4446b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // literal so it can be added as a constant function property.
4456b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  static void CheckAssigningFunctionLiteralToProperty(Expression* left,
4466b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org                                                      Expression* right);
4476b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
448fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // Keep track of eval() calls since they disable all local variable
449fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // optimizations. This checks if expression is an eval call, and if yes,
450fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // forwards the information to scope.
451fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  void CheckPossibleEvalCall(Expression* expression, Scope* scope);
4526b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4536b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org  // Determine if the expression is a variable proxy and mark it as being used
454248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  // in an assignment or with a increment/decrement operator.
455248dd43badb99ffce44eae2d767cda3cefaad521machenbach@chromium.org  static Expression* MarkExpressionAsAssigned(Expression* expression);
4566b6df382019a622ba20133e47bbe2e6f323b013bdslomov@chromium.org
4572904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // Returns true if we have a binary expression between two numeric
4582904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // literals. In that case, *x will be changed to an expression which is the
4592904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  // computed value.
4602904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  bool ShortcutNumericLiteralBinaryExpression(
4612904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      Expression** x, Expression* y, Token::Value op, int pos,
4622904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org      AstNodeFactory<AstConstructionVisitor>* factory);
4632904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org
46469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // Rewrites the following types of unary expressions:
46569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // not <literal> -> true / false
46669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // + <numeric literal> -> <numeric literal>
46769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // - <numeric literal> -> <numeric literal with value negated>
46869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // ! <literal> -> true / false
46969f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // The following rewriting rules enable the collection of type feedback
47069f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // without any special stub and the multiplication is removed later in
47169f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // Crankshaft's canonicalization pass.
47269f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // + foo -> foo * 1
47369f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // - foo -> foo * (-1)
47469f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  // ~ foo -> foo ^(~0)
47569f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org  Expression* BuildUnaryExpression(
47669f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      Expression* expression, Token::Value op, int pos,
47769f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org      AstNodeFactory<AstConstructionVisitor>* factory);
47869f64b1a8bfa6f5418b7c1f71d4e0833f76e93edmachenbach@chromium.org
4794edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Generate AST node that throws a ReferenceError with the given type.
4804edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Expression* NewThrowReferenceError(const char* type, int pos);
4814edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
4824edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Generate AST node that throws a SyntaxError with the given
4834edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // type. The first argument may be null (in the handle sense) in
4844edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // which case no arguments are passed to the constructor.
4854edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Expression* NewThrowSyntaxError(
48608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const char* type, const AstRawString* arg, int pos);
4874edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
4884edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Generate AST node that throws a TypeError with the given
4894edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // type. Both arguments must be non-null (in the handle sense).
49008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Expression* NewThrowTypeError(const char* type, const AstRawString* arg,
49108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                int pos);
4924edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
4934edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  // Generic AST generator for throwing errors from compiled code.
4944edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org  Expression* NewThrowError(
49508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const AstRawString* constructor, const char* type,
49608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const AstRawString* arg, int pos);
4974edebd5691ee147fa134ad8aaf6cc3c939831b93machenbach@chromium.org
498f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Reporting errors.
499f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void ReportMessageAt(Scanner::Location source_location,
500f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                       const char* message,
5014b0feeef5d01dbc2948080b4f69daa37e1083461machenbach@chromium.org                       const char* arg = NULL,
5022904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                       bool is_reference_error = false);
5032904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org  void ReportMessage(const char* message,
50408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                     const char* arg = NULL,
50508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                     bool is_reference_error = false);
50608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  void ReportMessage(const char* message,
50708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                     const AstRawString* arg,
5082904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                     bool is_reference_error = false);
509f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  void ReportMessageAt(Scanner::Location source_location,
510f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                       const char* message,
51108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                       const AstRawString* arg,
5122904d1a42292be3056c2dd3f98822f8e1470fa72machenbach@chromium.org                       bool is_reference_error = false);
513f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
514f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // "null" return type creators.
51508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  static const AstRawString* EmptyIdentifier() {
51608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org    return NULL;
517f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
518f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  static Expression* EmptyExpression() {
519f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return NULL;
520f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
5219bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  static Expression* EmptyArrowParamList() { return NULL; }
522486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  static Literal* EmptyLiteral() {
523486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return NULL;
524486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
525e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  static ObjectLiteralProperty* EmptyObjectLiteralProperty() { return NULL; }
526a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  static FunctionLiteral* EmptyFunctionLiteral() { return NULL; }
5279bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
528fa0c3c69b9d632e5730bdd9c745c375beef5e54dmachenbach@chromium.org  // Used in error return values.
529486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  static ZoneList<Expression*>* NullExpressionList() {
530486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return NULL;
531486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
532f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
5339bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  // Non-NULL empty string.
5349bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE const AstRawString* EmptyIdentifierString();
5359bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
536f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Odd-ball literal creators.
537f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Literal* GetLiteralTheHole(int position,
538f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org                             AstNodeFactory<AstConstructionVisitor>* factory);
539f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
540f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Producing data during the recursive descent.
54108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* GetSymbol(Scanner* scanner);
54208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* GetNextSymbol(Scanner* scanner);
543a8702c210b949f35c64d8e4aa01bb6d525086c85machenbach@chromium.org  const AstRawString* GetNumberAsSymbol(Scanner* scanner);
54408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org
545f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Expression* ThisExpression(Scope* scope,
5469d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                             AstNodeFactory<AstConstructionVisitor>* factory,
5479d1a7a8cdb664730cf5703185e85a4716748c564machenbach@chromium.org                             int pos = RelocInfo::kNoPosition);
5485e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org  Expression* SuperReference(Scope* scope,
5495e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                             AstNodeFactory<AstConstructionVisitor>* factory,
5505e57059e20217fd540b60c237d326414afe2171emachenbach@chromium.org                             int pos = RelocInfo::kNoPosition);
551a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Expression* ClassLiteral(const AstRawString* name, Expression* extends,
552a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                           Expression* constructor,
553a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                           ZoneList<ObjectLiteral::Property*>* properties,
554a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                           int pos,
555a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                           AstNodeFactory<AstConstructionVisitor>* factory);
556a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
557486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  Literal* ExpressionFromLiteral(
558f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      Token::Value token, int pos, Scanner* scanner,
559f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      AstNodeFactory<AstConstructionVisitor>* factory);
560f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Expression* ExpressionFromIdentifier(
56108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const AstRawString* name, int pos, Scope* scope,
562f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      AstNodeFactory<AstConstructionVisitor>* factory);
563f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Expression* ExpressionFromString(
564f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      int pos, Scanner* scanner,
565f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org      AstNodeFactory<AstConstructionVisitor>* factory);
5663e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org  Expression* GetIterator(Expression* iterable,
5673e3d253bd8018d7627422bf55a5c7bb7e7d6ad7emachenbach@chromium.org                          AstNodeFactory<AstConstructionVisitor>* factory);
568f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) {
569f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org    return new(zone) ZoneList<v8::internal::Expression*>(size, zone);
570f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  }
571486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) {
572486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org    return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone);
573486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  }
574865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) {
575865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org    return new(zone) ZoneList<v8::internal::Statement*>(size, zone);
576865f51ff8c94f86f4c97636d70addc0f29e79674machenbach@chromium.org  }
5779bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE Scope* NewScope(Scope* parent_scope, ScopeType scope_type);
5789bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
5799bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  // Utility functions
5809bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  int DeclareArrowParametersFromExpression(Expression* expression, Scope* scope,
5819bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                           Scanner::Location* dupe_loc,
5829bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                           bool* ok);
5839bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE AstValueFactory* ast_value_factory();
584f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
585f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  // Temporary glue; these functions will move to ParserBase.
586f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Expression* ParseV8Intrinsic(bool* ok);
587486536df718553960f9700559e80e5b10b0d5994dslomov@chromium.org  FunctionLiteral* ParseFunctionLiteral(
5882c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      const AstRawString* name, Scanner::Location function_name_location,
5892c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      bool name_is_strict_reserved, FunctionKind kind,
5902c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      int function_token_position, FunctionLiteral::FunctionType type,
5912c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
5929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE void SkipLazyFunctionBody(const AstRawString* name,
5939bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                      int* materialized_literal_count,
5949bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                      int* expected_property_count, bool* ok);
5959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE ZoneList<Statement*>* ParseEagerFunctionBody(
5969bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      const AstRawString* name, int pos, Variable* fvar,
5979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      Token::Value fvar_init_op, bool is_generator, bool* ok);
5989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  V8_INLINE void CheckConflictingVarDeclarations(v8::internal::Scope* scope,
5999bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                                 bool* ok);
600f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
601f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org private:
602f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  Parser* parser_;
603f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org};
604f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
605f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
606f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.orgclass Parser : public ParserBase<ParserTraits> {
607e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org public:
60821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // Note that the hash seed in ParseInfo must be the hash seed from the
60921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // Isolate's heap, otherwise the heap will be in an inconsistent state once
61021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // the strings created by the Parser are internalized.
61121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  struct ParseInfo {
61221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    uintptr_t stack_limit;
61321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    uint32_t hash_seed;
61421d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    UnicodeCache* unicode_cache;
61521d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  };
61621d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org
61721d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  Parser(CompilationInfo* info, ParseInfo* parse_info);
618e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  ~Parser() {
619b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    delete reusable_preparser_;
620b1df11df5b7bdcc201852bfcdce0a8eace33b011svenpanne@chromium.org    reusable_preparser_ = NULL;
62170d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    delete cached_parse_data_;
62270d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org    cached_parse_data_ = NULL;
6231b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org  }
624e03fb64ef23331755b7986d2560bc4c00ba3e67bfschneider@chromium.org
625e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // Parses the source code represented by the compilation info and sets its
626e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // function literal.  Returns false (and deallocates any allocated AST
627e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  // nodes) if parsing failed.
6284954674151afa960af66efb4831df06bde727333yangguo@chromium.org  static bool Parse(CompilationInfo* info,
6294954674151afa960af66efb4831df06bde727333yangguo@chromium.org                    bool allow_lazy = false) {
63021d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    ParseInfo parse_info = {info->isolate()->stack_guard()->real_climit(),
63121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org                            info->isolate()->heap()->HashSeed(),
63221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org                            info->isolate()->unicode_cache()};
63321d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org    Parser parser(info, &parse_info);
6344954674151afa960af66efb4831df06bde727333yangguo@chromium.org    parser.set_allow_lazy(allow_lazy);
635a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    if (parser.Parse()) {
636a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      info->SetStrictMode(info->function()->strict_mode());
637a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      return true;
638a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    }
639a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    return false;
6404954674151afa960af66efb4831df06bde727333yangguo@chromium.org  }
641e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  bool Parse();
642b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void ParseOnBackground();
643b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
644b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // Handle errors detected during parsing, move statistics to Isolate,
645b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  // internalize strings (move them to the heap).
646b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void Internalize();
647e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
6484f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org private:
649f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  friend class ParserTraits;
650f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org
6517010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // Limit the allowed number of local variables in a function. The hard limit
6527010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // is that offsets computed by FullCodeGenerator::StackOperand and similar
6537010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // functions are ints, and they should not overflow. In addition, accessing
6547010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // local variables creates user-controlled constants in the generated code,
6557010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // and we don't want too much user-controlled memory inside the code (this was
6567010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // the reason why this limit was introduced in the first place; see
6577010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  // https://codereview.chromium.org/7003030/ ).
6587010a2d84de67daace72568ffcde315a3e510ab5machenbach@chromium.org  static const int kMaxNumFunctionLocals = 4194303;  // 2^22-1
659c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
660b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  enum VariableDeclarationContext {
661f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    kModuleElement,
662f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org    kBlockElement,
663b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    kStatement,
664b645116853c677aca8a316381b87441ba6004f67danno@chromium.org    kForStatement
665b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  };
666b645116853c677aca8a316381b87441ba6004f67danno@chromium.org
667394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // If a list of variable declarations includes any initializers.
668394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  enum VariableDeclarationProperties {
669394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    kHasInitializers,
670394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com    kHasNoInitializers
671394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  };
672394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
673fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  // Returns NULL if parsing failed.
674fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org  FunctionLiteral* ParseProgram();
675fb7a7c4ffde9a4d060f5f989371e2ce964ee5831jkummerow@chromium.org
676e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org  FunctionLiteral* ParseLazy();
6771510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org  FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
678c612e0211bdb8821cbd7886e15b0273ed82d2e9edanno@chromium.org
6796313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Isolate* isolate() { return info_->isolate(); }
6805a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CompilationInfo* info() const { return info_; }
6816313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  Handle<Script> script() const { return info_->script(); }
6826313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  AstValueFactory* ast_value_factory() const {
6836313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org    return info_->ast_value_factory();
6846313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  }
685ea88ce93dcb41a9200ec8747ae7642a5db1f4ce7sgjesse@chromium.org
6865f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org  // Called by ParseProgram after setting up the scanner.
687b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  FunctionLiteral* DoParseProgram(CompilationInfo* info, Scope** scope,
688b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                                  Scope** ad_hoc_eval_scope);
6895f0c45f2cacb31d36a8f80c31f17bda7751a3644ager@chromium.org
69070d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  void SetCachedData();
691e27d617298263725e8a48c2aa14029759b952623mstarzinger@chromium.org
692f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org  bool inside_with() const { return scope_->inside_with(); }
6934c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  ScriptCompiler::CompileOptions compile_options() const {
6944c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org    return info_->compile_options();
6954c3ce7c3fd2802da8f91c6516a9c9aea3cd93f1emachenbach@chromium.org  }
696812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Scope* DeclarationScope(VariableMode mode) {
697355cfd19c23ac613f2738a40e356ea48297f7d5eyangguo@chromium.org    return IsLexicalVariableMode(mode)
698f5a24546072ecdbbd6372c85c42157e01e913561titzer@chromium.org        ? scope_ : scope_->DeclarationScope();
699812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  }
700eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
701eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // All ParseXXX functions take as the last argument an *ok parameter
702eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // which is set to false if parsing failed; it is unchanged otherwise.
703eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // By making the 'exception handling' explicit, we are forced to check
704eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // for failure at the call sites.
70533e09c8efd078308de3c77a88301566f65c07befverwaest@chromium.org  void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
706b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                            bool is_eval, bool is_global,
707b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                            Scope** ad_hoc_eval_scope, bool* ok);
70808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseModuleElement(ZoneList<const AstRawString*>* labels,
70908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                bool* ok);
71008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseModuleDeclaration(ZoneList<const AstRawString*>* names,
71108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                    bool* ok);
712f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* ParseModule(bool* ok);
713f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* ParseModuleLiteral(bool* ok);
714f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* ParseModulePath(bool* ok);
715f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* ParseModuleVariable(bool* ok);
716f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Module* ParseModuleUrl(bool* ok);
717812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Module* ParseModuleSpecifier(bool* ok);
718f7a588466d1e61e14fec951e5f10c7cec501b3b4jkummerow@chromium.org  Block* ParseImportDeclaration(bool* ok);
719812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  Statement* ParseExportDeclaration(bool* ok);
72008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseBlockElement(ZoneList<const AstRawString*>* labels, bool* ok);
72108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseStatement(ZoneList<const AstRawString*>* labels, bool* ok);
72208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseFunctionDeclaration(ZoneList<const AstRawString*>* names,
72308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      bool* ok);
724a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Statement* ParseClassDeclaration(ZoneList<const AstRawString*>* names,
725a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                   bool* ok);
726eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Statement* ParseNativeDeclaration(bool* ok);
72708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Block* ParseBlock(ZoneList<const AstRawString*>* labels, bool* ok);
728b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Block* ParseVariableStatement(VariableDeclarationContext var_context,
72908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                ZoneList<const AstRawString*>* names,
730b645116853c677aca8a316381b87441ba6004f67danno@chromium.org                                bool* ok);
731b645116853c677aca8a316381b87441ba6004f67danno@chromium.org  Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
732394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com                                   VariableDeclarationProperties* decl_props,
73308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                   ZoneList<const AstRawString*>* names,
73408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                   const AstRawString** out,
7354f693d6b99ffdbc05e5e211e08ed5039e13279d2ricow@chromium.org                                   bool* ok);
73608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseExpressionOrLabelledStatement(
73708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ZoneList<const AstRawString*>* labels, bool* ok);
73808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  IfStatement* ParseIfStatement(ZoneList<const AstRawString*>* labels,
73908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                bool* ok);
740eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Statement* ParseContinueStatement(bool* ok);
74108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseBreakStatement(ZoneList<const AstRawString*>* labels,
74208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                 bool* ok);
743eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Statement* ParseReturnStatement(bool* ok);
74408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseWithStatement(ZoneList<const AstRawString*>* labels,
74508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                bool* ok);
746eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
74708e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  SwitchStatement* ParseSwitchStatement(ZoneList<const AstRawString*>* labels,
74808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                        bool* ok);
74908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  DoWhileStatement* ParseDoWhileStatement(ZoneList<const AstRawString*>* labels,
75008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                          bool* ok);
75108e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  WhileStatement* ParseWhileStatement(ZoneList<const AstRawString*>* labels,
75208e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org                                      bool* ok);
75308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Statement* ParseForStatement(ZoneList<const AstRawString*>* labels, bool* ok);
754eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Statement* ParseThrowStatement(bool* ok);
755eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
756eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  TryStatement* ParseTryStatement(bool* ok);
757eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  DebuggerStatement* ParseDebuggerStatement(bool* ok);
758eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
759394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  // Support for hamony block scoped bindings.
76008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  Block* ParseScopedBlock(ZoneList<const AstRawString*>* labels, bool* ok);
761394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com
7621fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  // Initialize the components of a for-in / for-of statement.
7631fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org  void InitializeForEachStatement(ForEachStatement* stmt,
7641fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                  Expression* each,
7651fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                  Expression* subject,
7661fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org                                  Statement* body);
7677e6132b924829c353864933f29124419916db550machenbach@chromium.org  Statement* DesugarLetBindingsInForStatement(
76808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      Scope* inner_scope, ZoneList<const AstRawString*>* names,
76908e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      ForStatement* loop, Statement* init, Expression* cond, Statement* next,
77008e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      Statement* body, bool* ok);
7711fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
7720a7303680fa9f3dc3945763aaa7c5a3859a7f855machenbach@chromium.org  FunctionLiteral* ParseFunctionLiteral(
7732c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      const AstRawString* name, Scanner::Location function_name_location,
7742c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      bool name_is_strict_reserved, FunctionKind kind,
7752c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      int function_token_position, FunctionLiteral::FunctionType type,
7762c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      FunctionLiteral::ArityRestriction arity_restriction, bool* ok);
777eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
778eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Magical syntax support.
779eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  Expression* ParseV8Intrinsic(bool* ok);
780eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
78141728483f231e098a8dd85f109b5a30e6ccc3c39danno@chromium.org  bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
7821fd77d58ca66b2711f09cdea32c0c2d1a01b3ae5danno@chromium.org
783eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Get odd-ball literals.
784a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  Literal* GetLiteralUndefined(int position);
785eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
7861805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // For harmony block scoping mode: Check if the scope has conflicting var/let
7871805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // declarations from different scopes. It covers for example
7881805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  //
7891805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // function f() { { { var x; } let x; } }
7901805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // function g() { { var x; let x; } }
7911805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  //
7921805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // The var declarations are hoisted to the function scope, but originate from
7931805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // a scope where the name has also been let bound or the var declaration is
7941805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  // hoisted over such a scope.
7951805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org  void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
7961805e21b0aece8c05f4960a5c0751c4463557891fschneider@chromium.org
797eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org  // Parser support
79808e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  VariableProxy* NewUnresolved(const AstRawString* name,
799bbceb57d27ec53f6d6212e690ead3174192ea3f9erik.corry@gmail.com                               VariableMode mode,
80028583c92ca8f528df625800519088ac88996d504jkummerow@chromium.org                               Interface* interface);
801812308e1488cd8261e4dbbda1d8022642d522b9bulan@chromium.org  void Declare(Declaration* declaration, bool resolve, bool* ok);
802eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
80308e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  bool TargetStackContainsLabel(const AstRawString* label);
80408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  BreakableStatement* LookupBreakTarget(const AstRawString* label, bool* ok);
80508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  IterationStatement* LookupContinueTarget(const AstRawString* label, bool* ok);
806eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
80744bc7080a85cc25bff3b9b77cd53f7beffab711bkarlklose@chromium.org  void RegisterTargetUse(Label* target, Target* stop);
808eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org
809fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  // Factory methods.
810fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
811394dbcf9009cf5203b6d85e8b515fcff072040f3erik.corry@gmail.com  Scope* NewScope(Scope* parent, ScopeType type);
812fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org
813e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Skip over a lazy function, either using cached data if we have it, or
814e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // by parsing the function with PreParser. Consumes the ending }.
81508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  void SkipLazyFunctionBody(const AstRawString* function_name,
816e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            int* materialized_literal_count,
817e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            int* expected_property_count,
818e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org                            bool* ok);
819e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
820e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser(
821e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org      SingletonLogger* logger);
822e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org
823e9fd6580f52407c94d77bfcb4be04207f2ebb2f1machenbach@chromium.org  // Consumes the ending }.
82408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  ZoneList<Statement*>* ParseEagerFunctionBody(
82508e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      const AstRawString* function_name, int pos, Variable* fvar,
82608e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org      Token::Value fvar_init_op, bool is_generator, bool* ok);
8271b3afd1cab9087ca3c4e585d3da77d374d65c082mstarzinger@chromium.org
828d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org  void HandleSourceURLComments();
829d0bddc653152f270a27fe32d5d7b0f5c0fa3b00cmachenbach@chromium.org
8306a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  void ThrowPendingError();
8316a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
832c3b37129d6387b2db313f9100256d2d5f60dd9a8jkummerow@chromium.org  Scanner scanner_;
833a2e1a40f85577979749d4c0d6de30e992d996659mstarzinger@chromium.org  PreParser* reusable_preparser_;
8341e8da746019f818a22dfdc6f691dbc0447048cadjkummerow@chromium.org  Scope* original_scope_;  // for ES5 function declarations in sloppy eval
835fa943b736b1d996084393011529d568165bb5d83lrn@chromium.org  Target* target_stack_;  // for break, continue statements
83670d29e1ad7a6f1c163f625252ca32ecc522cb155machenbach@chromium.org  ParseData* cached_parse_data_;
83704e4f1e9e1291ac270e1cb7d8384b2af2fd2d685jkummerow@chromium.org
8385a11aaf63fdb7843c9b116fdb84ee35b0a980ea6yangguo@chromium.org  CompilationInfo* info_;
8396a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org
8406a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  // Pending errors.
8416a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  bool has_pending_error_;
8426a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  Scanner::Location pending_error_location_;
8436a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  const char* pending_error_message_;
84408e7569a10f8edbb47b8fe70a6e160a4e0c9cd30machenbach@chromium.org  const AstRawString* pending_error_arg_;
8456a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  const char* pending_error_char_arg_;
8466a4d394882dba70a85567fb90ffd4f428a9eb170machenbach@chromium.org  bool pending_error_is_reference_error_;
8475de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org
84821d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // Other information which will be stored in Parser and moved to Isolate after
84921d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  // parsing.
8505de0074a922429f5e0ec2cf140c2d2989bf88140yangguo@chromium.org  int use_counts_[v8::Isolate::kUseCounterFeatureCount];
85121d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  int total_preparse_skipped_;
85221d700eedcdd6570eff22ece724b63a5eefe78cbmachenbach@chromium.org  HistogramTimer* pre_parse_timer_;
853eb7c144137bd7d461d4996f752f1353a0856fac1ricow@chromium.org};
85443d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
855bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
8569bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgbool ParserTraits::IsFutureStrictReserved(
8579bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    const AstRawString* identifier) const {
8589bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  return identifier->IsOneByteEqualTo("yield") ||
8599bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org         parser_->scanner()->IdentifierIsFutureStrictReserved(identifier);
8609bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8619bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8629bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8639bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgScope* ParserTraits::NewScope(Scope* parent_scope, ScopeType scope_type) {
8649bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  return parser_->NewScope(parent_scope, scope_type);
8659bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8669bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8679bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8689bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgconst AstRawString* ParserTraits::EmptyIdentifierString() {
8696313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return parser_->ast_value_factory()->empty_string();
8709bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8719bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8729bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8739bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgvoid ParserTraits::SkipLazyFunctionBody(const AstRawString* function_name,
8749bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                        int* materialized_literal_count,
8759bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                        int* expected_property_count,
8769bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                        bool* ok) {
8779bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  return parser_->SkipLazyFunctionBody(
8789bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org      function_name, materialized_literal_count, expected_property_count, ok);
8799bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8809bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8819bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8829bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgZoneList<Statement*>* ParserTraits::ParseEagerFunctionBody(
8839bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    const AstRawString* name, int pos, Variable* fvar,
8849bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org    Token::Value fvar_init_op, bool is_generator, bool* ok) {
8859bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  return parser_->ParseEagerFunctionBody(name, pos, fvar, fvar_init_op,
8869bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                         is_generator, ok);
8879bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8889bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8899bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgvoid ParserTraits::CheckConflictingVarDeclarations(v8::internal::Scope* scope,
8909bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org                                                   bool* ok) {
8919bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org  parser_->CheckConflictingVarDeclarations(scope, ok);
8929bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8939bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8949bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8959bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.orgAstValueFactory* ParserTraits::ast_value_factory() {
8966313e220249748eb26e1ddcee2bbe857fef03b42machenbach@chromium.org  return parser_->ast_value_factory();
8979bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org}
8989bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
8999bf7aff6cc5ed8807b7b2abc11b6cf77b928ded1machenbach@chromium.org
900bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// Support for handling complex values (array and object literals) that
901bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org// can be fully handled at compile time.
902bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.orgclass CompileTimeValue: public AllStatic {
903bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org public:
904dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  enum LiteralType {
905f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    OBJECT_LITERAL_FAST_ELEMENTS,
906f837290e142d49c9e1332841ec2c49ee2f09584avegorov@chromium.org    OBJECT_LITERAL_SLOW_ELEMENTS,
907bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org    ARRAY_LITERAL
908bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  };
909bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
910bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  static bool IsCompileTimeValue(Expression* expression);
911bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
912bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Get the value as a compile time value.
9133d00d0a753cf5e5091f883517e6612ece769f999jkummerow@chromium.org  static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression);
914bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
915bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Get the type of a compile time value returned by GetValue().
916dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  static LiteralType GetLiteralType(Handle<FixedArray> value);
917bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
918bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  // Get the elements array of a compile time value returned by GetValue().
919bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  static Handle<FixedArray> GetElements(Handle<FixedArray> value);
920bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
921bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org private:
922dfe53073738bbf16023d96fce5118358a1037fd3ulan@chromium.org  static const int kLiteralTypeSlot = 0;
923bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  static const int kElementsSlot = 1;
924bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
925bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org  DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
926bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org};
927bb29dc9819bb6f495ab6eddd2543965eb97a8e43ager@chromium.org
92843d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen} }  // namespace v8::internal
92943d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen
93043d26ecc3563a46f62a0224030667c8f8f3f6cebchristian.plesner.hansen#endif  // V8_PARSER_H_
931