blob: c3a7edfd9cbe46d8f7445fb631d551c06f23bd88 [file] [log] [blame]
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_PARSER_H_
29#define V8_PARSER_H_
30
ager@chromium.orgbb29dc92009-03-24 13:25:23 +000031#include "allocation.h"
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000032#include "ast.h"
lrn@chromium.org1c092762011-05-09 09:42:16 +000033#include "preparse-data-format.h"
ager@chromium.orgbeb25712010-11-29 08:02:25 +000034#include "preparse-data.h"
ricow@chromium.org55ee8072011-09-08 16:33:10 +000035#include "scopes.h"
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000036#include "preparser.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
kasperl@chromium.org71affb52009-05-26 05:44:31 +000038namespace v8 {
39namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040
ager@chromium.orgb61a0d12010-10-13 08:35:23 +000041class CompilationInfo;
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000042class FuncNameInferrer;
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000043class ParserLog;
44class PositionStack;
45class Target;
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +000046
47template <typename T> class ZoneListWrapper;
48
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50class ParserMessage : public Malloced {
51 public:
52 ParserMessage(Scanner::Location loc, const char* message,
53 Vector<const char*> args)
54 : loc_(loc),
55 message_(message),
56 args_(args) { }
57 ~ParserMessage();
58 Scanner::Location location() { return loc_; }
59 const char* message() { return message_; }
60 Vector<const char*> args() { return args_; }
61 private:
62 Scanner::Location loc_;
63 const char* message_;
64 Vector<const char*> args_;
65};
66
67
68class FunctionEntry BASE_EMBEDDED {
69 public:
danno@chromium.orgc612e022011-11-10 11:38:15 +000070 enum {
71 kStartPositionIndex,
72 kEndPositionIndex,
73 kLiteralCountIndex,
74 kPropertyCountIndex,
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000075 kLanguageModeIndex,
danno@chromium.orgc612e022011-11-10 11:38:15 +000076 kSize
77 };
78
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000079 explicit FunctionEntry(Vector<unsigned> backing)
80 : backing_(backing) { }
81
82 FunctionEntry() : backing_() { }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000083
danno@chromium.orgc612e022011-11-10 11:38:15 +000084 int start_pos() { return backing_[kStartPositionIndex]; }
85 int end_pos() { return backing_[kEndPositionIndex]; }
86 int literal_count() { return backing_[kLiteralCountIndex]; }
87 int property_count() { return backing_[kPropertyCountIndex]; }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +000088 LanguageMode language_mode() {
89 ASSERT(backing_[kLanguageModeIndex] == CLASSIC_MODE ||
90 backing_[kLanguageModeIndex] == STRICT_MODE ||
91 backing_[kLanguageModeIndex] == EXTENDED_MODE);
92 return static_cast<LanguageMode>(backing_[kLanguageModeIndex]);
erik.corry@gmail.com6e28b562011-10-27 14:20:17 +000093 }
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000094
danno@chromium.orgc612e022011-11-10 11:38:15 +000095 bool is_valid() { return !backing_.is_empty(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000096
97 private:
98 Vector<unsigned> backing_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000099};
100
101
102class ScriptDataImpl : public ScriptData {
103 public:
104 explicit ScriptDataImpl(Vector<unsigned> store)
105 : store_(store),
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000106 owns_store_(true) { }
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000107
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000108 // Create an empty ScriptDataImpl that is guaranteed to not satisfy
109 // a SanityCheck.
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000110 ScriptDataImpl() : owns_store_(false) { }
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000111
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 virtual ~ScriptDataImpl();
113 virtual int Length();
kmillikin@chromium.org9155e252010-05-26 13:27:57 +0000114 virtual const char* Data();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000115 virtual bool HasError();
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000116
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000117 void Initialize();
118 void ReadNextSymbolPosition();
119
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000120 FunctionEntry GetFunctionEntry(int start);
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000121 int GetSymbolIdentifier();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000122 bool SanityCheck();
123
124 Scanner::Location MessageLocation();
125 const char* BuildMessage();
126 Vector<const char*> BuildArgs();
127
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000128 int symbol_count() {
ager@chromium.orgbeb25712010-11-29 08:02:25 +0000129 return (store_.length() > PreparseDataConstants::kHeaderSize)
130 ? store_[PreparseDataConstants::kSymbolCountOffset]
131 : 0;
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000132 }
133 // The following functions should only be called if SanityCheck has
134 // returned true.
ager@chromium.orgbeb25712010-11-29 08:02:25 +0000135 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
136 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
137 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139 private:
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000140 Vector<unsigned> store_;
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000141 unsigned char* symbol_data_;
142 unsigned char* symbol_data_end_;
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000143 int function_index_;
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000144 bool owns_store_;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146 unsigned Read(int position);
147 unsigned* ReadAddress(int position);
erik.corry@gmail.comd88afa22010-09-15 12:33:05 +0000148 // Reads a number from the current symbols
149 int ReadNumber(byte** source);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000151 ScriptDataImpl(const char* backing_store, int length)
152 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000153 length / static_cast<int>(sizeof(unsigned))),
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000154 owns_store_(false) {
kmillikin@chromium.orgf05f2912010-09-30 10:07:24 +0000155 ASSERT_EQ(0, static_cast<int>(
156 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000157 }
158
ricow@chromium.org65fae842010-08-25 15:26:24 +0000159 // Read strings written by ParserRecorder::WriteString.
160 static const char* ReadString(unsigned* start, int* chars);
ager@chromium.org5b2fbee2010-09-08 06:38:15 +0000161
162 friend class ScriptData;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163};
164
165
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000166class PreParserApi {
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000167 public:
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000168 // Pre-parse a character stream and return full preparse data.
169 //
170 // This interface is here instead of in preparser.h because it instantiates a
171 // preparser recorder object that is suited to the parser's purposes. Also,
172 // the preparser doesn't know about ScriptDataImpl.
173 static ScriptDataImpl* PreParse(Utf16CharacterStream* source);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000174};
175
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000176
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000177// ----------------------------------------------------------------------------
178// REGEXP PARSING
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000179
ulan@chromium.org2efb9002012-01-19 15:36:35 +0000180// A BufferedZoneList is an automatically growing list, just like (and backed
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000181// by) a ZoneList, that is optimized for the case of adding and removing
182// a single element. The last element added is stored outside the backing list,
183// and if no more than one element is ever added, the ZoneList isn't even
184// allocated.
185// Elements must not be NULL pointers.
186template <typename T, int initial_size>
187class BufferedZoneList {
188 public:
189 BufferedZoneList() : list_(NULL), last_(NULL) {}
190
191 // Adds element at end of list. This element is buffered and can
192 // be read using last() or removed using RemoveLast until a new Add or until
193 // RemoveLast or GetList has been called.
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000194 void Add(T* value, Zone* zone) {
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000195 if (last_ != NULL) {
196 if (list_ == NULL) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000197 list_ = new(zone) ZoneList<T*>(initial_size, zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000198 }
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000199 list_->Add(last_, zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000200 }
201 last_ = value;
202 }
203
204 T* last() {
205 ASSERT(last_ != NULL);
206 return last_;
207 }
208
209 T* RemoveLast() {
210 ASSERT(last_ != NULL);
211 T* result = last_;
212 if ((list_ != NULL) && (list_->length() > 0))
213 last_ = list_->RemoveLast();
214 else
215 last_ = NULL;
216 return result;
217 }
218
219 T* Get(int i) {
220 ASSERT((0 <= i) && (i < length()));
221 if (list_ == NULL) {
222 ASSERT_EQ(0, i);
223 return last_;
224 } else {
225 if (i == list_->length()) {
226 ASSERT(last_ != NULL);
227 return last_;
228 } else {
229 return list_->at(i);
230 }
231 }
232 }
233
234 void Clear() {
235 list_ = NULL;
236 last_ = NULL;
237 }
238
239 int length() {
240 int length = (list_ == NULL) ? 0 : list_->length();
241 return length + ((last_ == NULL) ? 0 : 1);
242 }
243
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000244 ZoneList<T*>* GetList(Zone* zone) {
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000245 if (list_ == NULL) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000246 list_ = new(zone) ZoneList<T*>(initial_size, zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000247 }
248 if (last_ != NULL) {
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000249 list_->Add(last_, zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000250 last_ = NULL;
251 }
252 return list_;
253 }
254
255 private:
256 ZoneList<T*>* list_;
257 T* last_;
258};
259
260
261// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
262class RegExpBuilder: public ZoneObject {
263 public:
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000264 explicit RegExpBuilder(Zone* zone);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000265 void AddCharacter(uc16 character);
266 // "Adds" an empty expression. Does nothing except consume a
267 // following quantifier
268 void AddEmpty();
269 void AddAtom(RegExpTree* tree);
270 void AddAssertion(RegExpTree* tree);
271 void NewAlternative(); // '|'
ulan@chromium.orgdfe53072013-06-06 14:14:51 +0000272 void AddQuantifierToAtom(
273 int min, int max, RegExpQuantifier::QuantifierType type);
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000274 RegExpTree* ToRegExp();
275
276 private:
277 void FlushCharacters();
278 void FlushText();
279 void FlushTerms();
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000280 Zone* zone() const { return zone_; }
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000281
282 Zone* zone_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000283 bool pending_empty_;
284 ZoneList<uc16>* characters_;
285 BufferedZoneList<RegExpTree, 2> terms_;
286 BufferedZoneList<RegExpTree, 2> text_;
287 BufferedZoneList<RegExpTree, 2> alternatives_;
288#ifdef DEBUG
289 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
290#define LAST(x) last_added_ = x;
291#else
292#define LAST(x)
293#endif
294};
295
296
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000297class RegExpParser BASE_EMBEDDED {
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000298 public:
299 RegExpParser(FlatStringReader* in,
300 Handle<String>* error,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000301 bool multiline_mode,
302 Zone* zone);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000303
304 static bool ParseRegExp(FlatStringReader* input,
305 bool multiline,
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000306 RegExpCompileData* result,
307 Zone* zone);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000308
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000309 RegExpTree* ParsePattern();
310 RegExpTree* ParseDisjunction();
311 RegExpTree* ParseGroup();
312 RegExpTree* ParseCharacterClass();
313
314 // Parses a {...,...} quantifier and stores the range in the given
315 // out parameters.
316 bool ParseIntervalQuantifier(int* min_out, int* max_out);
317
318 // Parses and returns a single escaped character. The character
319 // must not be 'b' or 'B' since they are usually handle specially.
320 uc32 ParseClassCharacterEscape();
321
322 // Checks whether the following is a length-digit hexadecimal number,
323 // and sets the value if it is.
324 bool ParseHexEscape(int length, uc32* value);
325
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000326 uc32 ParseOctalLiteral();
327
328 // Tries to parse the input as a back reference. If successful it
329 // stores the result in the output parameter and returns true. If
330 // it fails it will push back the characters read so the same characters
331 // can be reparsed.
332 bool ParseBackReferenceIndex(int* index_out);
333
334 CharacterRange ParseClassAtom(uc16* char_class);
335 RegExpTree* ReportError(Vector<const char> message);
336 void Advance();
337 void Advance(int dist);
338 void Reset(int pos);
339
340 // Reports whether the pattern might be used as a literal search string.
341 // Only use if the result of the parse is a single atom node.
342 bool simple();
343 bool contains_anchor() { return contains_anchor_; }
344 void set_contains_anchor() { contains_anchor_ = true; }
345 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
346 int position() { return next_pos_ - 1; }
347 bool failed() { return failed_; }
348
349 static const int kMaxCaptures = 1 << 16;
350 static const uc32 kEndMarker = (1 << 21);
351
352 private:
353 enum SubexpressionType {
354 INITIAL,
355 CAPTURE, // All positive values represent captures.
356 POSITIVE_LOOKAHEAD,
357 NEGATIVE_LOOKAHEAD,
358 GROUPING
359 };
360
361 class RegExpParserState : public ZoneObject {
362 public:
363 RegExpParserState(RegExpParserState* previous_state,
364 SubexpressionType group_type,
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000365 int disjunction_capture_index,
366 Zone* zone)
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000367 : previous_state_(previous_state),
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000368 builder_(new(zone) RegExpBuilder(zone)),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000369 group_type_(group_type),
370 disjunction_capture_index_(disjunction_capture_index) {}
371 // Parser state of containing expression, if any.
372 RegExpParserState* previous_state() { return previous_state_; }
373 bool IsSubexpression() { return previous_state_ != NULL; }
374 // RegExpBuilder building this regexp's AST.
375 RegExpBuilder* builder() { return builder_; }
376 // Type of regexp being parsed (parenthesized group or entire regexp).
377 SubexpressionType group_type() { return group_type_; }
378 // Index in captures array of first capture in this sub-expression, if any.
379 // Also the capture index of this sub-expression itself, if group_type
380 // is CAPTURE.
381 int capture_index() { return disjunction_capture_index_; }
382
383 private:
384 // Linked list implementation of stack of states.
385 RegExpParserState* previous_state_;
386 // Builder for the stored disjunction.
387 RegExpBuilder* builder_;
388 // Stored disjunction type (capture, look-ahead or grouping), if any.
389 SubexpressionType group_type_;
390 // Stored disjunction's capture index (if any).
391 int disjunction_capture_index_;
392 };
393
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000394 Isolate* isolate() { return isolate_; }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000395 Zone* zone() const { return zone_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000396
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000397 uc32 current() { return current_; }
398 bool has_more() { return has_more_; }
399 bool has_next() { return next_pos_ < in()->length(); }
400 uc32 Next();
401 FlatStringReader* in() { return in_; }
402 void ScanForCaptures();
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000403
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000404 Isolate* isolate_;
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000405 Zone* zone_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000406 Handle<String>* error_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000407 ZoneList<RegExpCapture*>* captures_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000408 FlatStringReader* in_;
409 uc32 current_;
410 int next_pos_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000411 // The capture count is only valid after we have scanned for captures.
412 int capture_count_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000413 bool has_more_;
414 bool multiline_;
415 bool simple_;
416 bool contains_anchor_;
417 bool is_scanned_for_captures_;
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000418 bool failed_;
419};
420
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000421// ----------------------------------------------------------------------------
422// JAVASCRIPT PARSING
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000423
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000424// Forward declaration.
425class SingletonLogger;
426
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000427class Parser BASE_EMBEDDED {
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000428 public:
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000429 explicit Parser(CompilationInfo* info);
430 ~Parser() {
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000431 delete reusable_preparser_;
432 reusable_preparser_ = NULL;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000433 }
fschneider@chromium.orge03fb642010-11-01 12:34:09 +0000434
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000435 bool allow_natives_syntax() const { return allow_natives_syntax_; }
436 bool allow_lazy() const { return allow_lazy_; }
437 bool allow_modules() { return scanner().HarmonyModules(); }
438 bool allow_harmony_scoping() { return scanner().HarmonyScoping(); }
439 bool allow_generators() const { return allow_generators_; }
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000440 bool allow_for_of() const { return allow_for_of_; }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000441
442 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; }
443 void set_allow_lazy(bool allow) { allow_lazy_ = allow; }
444 void set_allow_modules(bool allow) { scanner().SetHarmonyModules(allow); }
445 void set_allow_harmony_scoping(bool allow) {
446 scanner().SetHarmonyScoping(allow);
447 }
448 void set_allow_generators(bool allow) { allow_generators_ = allow; }
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000449 void set_allow_for_of(bool allow) { allow_for_of_ = allow; }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000450
451 // Parses the source code represented by the compilation info and sets its
452 // function literal. Returns false (and deallocates any allocated AST
453 // nodes) if parsing failed.
454 static bool Parse(CompilationInfo* info) { return Parser(info).Parse(); }
455 bool Parse();
456
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000457 // Returns NULL if parsing failed.
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000458 FunctionLiteral* ParseProgram();
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000459
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000460 void ReportMessageAt(Scanner::Location loc,
461 const char* message,
462 Vector<const char*> args);
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000463 void ReportMessageAt(Scanner::Location loc,
464 const char* message,
465 Vector<Handle<String> > args);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000466
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000467 private:
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000468 static const int kMaxNumFunctionLocals = 131071; // 2^17-1
danno@chromium.orgc612e022011-11-10 11:38:15 +0000469
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000470 enum Mode {
471 PARSE_LAZILY,
472 PARSE_EAGERLY
473 };
474
danno@chromium.orgb6451162011-08-17 14:33:23 +0000475 enum VariableDeclarationContext {
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000476 kModuleElement,
477 kBlockElement,
danno@chromium.orgb6451162011-08-17 14:33:23 +0000478 kStatement,
479 kForStatement
480 };
481
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000482 // If a list of variable declarations includes any initializers.
483 enum VariableDeclarationProperties {
484 kHasInitializers,
485 kHasNoInitializers
486 };
487
danno@chromium.orgc612e022011-11-10 11:38:15 +0000488 class BlockState;
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000489
490 class FunctionState BASE_EMBEDDED {
491 public:
492 FunctionState(Parser* parser,
493 Scope* scope,
494 Isolate* isolate);
495 ~FunctionState();
496
497 int NextMaterializedLiteralIndex() {
498 return next_materialized_literal_index_++;
499 }
500 int materialized_literal_count() {
501 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize;
502 }
503
504 int NextHandlerIndex() { return next_handler_index_++; }
505 int handler_count() { return next_handler_index_; }
506
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000507 void AddProperty() { expected_property_count_++; }
508 int expected_property_count() { return expected_property_count_; }
509
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000510 void set_generator_object_variable(Variable *variable) {
511 ASSERT(variable != NULL);
512 ASSERT(!is_generator());
513 generator_object_variable_ = variable;
514 }
515 Variable* generator_object_variable() const {
516 return generator_object_variable_;
517 }
518 bool is_generator() const {
519 return generator_object_variable_ != NULL;
520 }
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000521
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000522 AstNodeFactory<AstConstructionVisitor>* factory() { return &factory_; }
523
524 private:
525 // Used to assign an index to each literal that needs materialization in
526 // the function. Includes regexp literals, and boilerplate for object and
527 // array literals.
528 int next_materialized_literal_index_;
529
530 // Used to assign a per-function index to try and catch handlers.
531 int next_handler_index_;
532
533 // Properties count estimation.
534 int expected_property_count_;
535
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000536 // For generators, the variable that holds the generator object. This
537 // variable is used by yield expressions and return statements. NULL
538 // indicates that this function is not a generator.
539 Variable* generator_object_variable_;
540
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000541 Parser* parser_;
542 FunctionState* outer_function_state_;
543 Scope* outer_scope_;
544 int saved_ast_node_id_;
545 AstNodeFactory<AstConstructionVisitor> factory_;
546 };
547
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000548 class ParsingModeScope BASE_EMBEDDED {
549 public:
550 ParsingModeScope(Parser* parser, Mode mode)
551 : parser_(parser),
552 old_mode_(parser->mode()) {
553 parser_->mode_ = mode;
554 }
555 ~ParsingModeScope() {
556 parser_->mode_ = old_mode_;
557 }
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000558
mstarzinger@chromium.org471f2f12012-08-10 14:46:33 +0000559 private:
560 Parser* parser_;
561 Mode old_mode_;
562 };
danno@chromium.orgc612e022011-11-10 11:38:15 +0000563
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000564 FunctionLiteral* ParseLazy();
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000565 FunctionLiteral* ParseLazy(Utf16CharacterStream* source);
danno@chromium.orgc612e022011-11-10 11:38:15 +0000566
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000567 Isolate* isolate() { return isolate_; }
mmassi@chromium.org7028c052012-06-13 11:51:58 +0000568 Zone* zone() const { return zone_; }
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000569 CompilationInfo* info() const { return info_; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000570
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000571 // Called by ParseProgram after setting up the scanner.
ricow@chromium.org27bf2882011-11-17 08:34:43 +0000572 FunctionLiteral* DoParseProgram(CompilationInfo* info,
mstarzinger@chromium.org1510d582013-06-28 14:00:48 +0000573 Handle<String> source);
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000574
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000575 // Report syntax error
576 void ReportUnexpectedToken(Token::Value token);
577 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000578 void ReportMessage(const char* message, Vector<const char*> args);
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000579 void ReportMessage(const char* message, Vector<Handle<String> > args);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000580
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000581 void set_pre_parse_data(ScriptDataImpl *data) {
582 pre_parse_data_ = data;
583 symbol_cache_.Initialize(data ? data->symbol_count() : 0, zone());
584 }
585
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000586 bool inside_with() const { return top_scope_->inside_with(); }
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000587 Scanner& scanner() { return scanner_; }
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000588 Mode mode() const { return mode_; }
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000589 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; }
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000590 bool is_extended_mode() {
591 ASSERT(top_scope_ != NULL);
592 return top_scope_->is_extended_mode();
593 }
ulan@chromium.org812308e2012-02-29 15:58:45 +0000594 Scope* DeclarationScope(VariableMode mode) {
yangguo@chromium.org355cfd12012-08-29 15:32:24 +0000595 return IsLexicalVariableMode(mode)
ulan@chromium.org812308e2012-02-29 15:58:45 +0000596 ? top_scope_ : top_scope_->DeclarationScope();
597 }
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000598
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000599 // Check if the given string is 'eval' or 'arguments'.
600 bool IsEvalOrArguments(Handle<String> string);
601
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000602 // All ParseXXX functions take as the last argument an *ok parameter
603 // which is set to false if parsing failed; it is unchanged otherwise.
604 // By making the 'exception handling' explicit, we are forced to check
605 // for failure at the call sites.
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000606 void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token,
607 bool is_eval, bool is_global, bool* ok);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000608 Statement* ParseModuleElement(ZoneStringList* labels, bool* ok);
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000609 Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000610 Module* ParseModule(bool* ok);
611 Module* ParseModuleLiteral(bool* ok);
612 Module* ParseModulePath(bool* ok);
613 Module* ParseModuleVariable(bool* ok);
614 Module* ParseModuleUrl(bool* ok);
ulan@chromium.org812308e2012-02-29 15:58:45 +0000615 Module* ParseModuleSpecifier(bool* ok);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000616 Block* ParseImportDeclaration(bool* ok);
ulan@chromium.org812308e2012-02-29 15:58:45 +0000617 Statement* ParseExportDeclaration(bool* ok);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +0000618 Statement* ParseBlockElement(ZoneStringList* labels, bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000619 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
ulan@chromium.org812308e2012-02-29 15:58:45 +0000620 Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000621 Statement* ParseNativeDeclaration(bool* ok);
622 Block* ParseBlock(ZoneStringList* labels, bool* ok);
danno@chromium.orgb6451162011-08-17 14:33:23 +0000623 Block* ParseVariableStatement(VariableDeclarationContext var_context,
ulan@chromium.org812308e2012-02-29 15:58:45 +0000624 ZoneStringList* names,
danno@chromium.orgb6451162011-08-17 14:33:23 +0000625 bool* ok);
626 Block* ParseVariableDeclarations(VariableDeclarationContext var_context,
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000627 VariableDeclarationProperties* decl_props,
ulan@chromium.org812308e2012-02-29 15:58:45 +0000628 ZoneStringList* names,
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000629 Handle<String>* out,
630 bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000631 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
632 bool* ok);
633 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
634 Statement* ParseContinueStatement(bool* ok);
635 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
636 Statement* ParseReturnStatement(bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000637 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
638 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
639 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
640 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
641 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
642 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
643 Statement* ParseThrowStatement(bool* ok);
644 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
645 TryStatement* ParseTryStatement(bool* ok);
646 DebuggerStatement* ParseDebuggerStatement(bool* ok);
647
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000648 // Support for hamony block scoped bindings.
649 Block* ParseScopedBlock(ZoneStringList* labels, bool* ok);
650
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000651 Expression* ParseExpression(bool accept_IN, bool* ok);
652 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000653 Expression* ParseYieldExpression(bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000654 Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
655 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
656 Expression* ParseUnaryExpression(bool* ok);
657 Expression* ParsePostfixExpression(bool* ok);
658 Expression* ParseLeftHandSideExpression(bool* ok);
659 Expression* ParseNewExpression(bool* ok);
660 Expression* ParseMemberExpression(bool* ok);
661 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
662 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
663 bool* ok);
664 Expression* ParsePrimaryExpression(bool* ok);
665 Expression* ParseArrayLiteral(bool* ok);
666 Expression* ParseObjectLiteral(bool* ok);
667 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
668 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
669
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000670 // Populate the constant properties fixed array for a materialized object
671 // literal.
672 void BuildObjectLiteralConstantProperties(
673 ZoneList<ObjectLiteral::Property*>* properties,
674 Handle<FixedArray> constants,
675 bool* is_simple,
676 bool* fast_elements,
ulan@chromium.org57ff8812013-05-10 08:16:55 +0000677 int* depth,
678 bool* may_store_doubles);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000679
680 // Decide if a property should be in the object boilerplate.
681 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
682 // If the expression is a literal, return the literal value;
683 // if the expression is a materialized literal and is simple return a
684 // compile time value as encoded by CompileTimeValue::GetValue().
685 // Otherwise, return undefined literal as the placeholder
686 // in the object literal boilerplate.
687 Handle<Object> GetBoilerplateValue(Expression* expression);
688
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000689 // Initialize the components of a for-in / for-of statement.
690 void InitializeForEachStatement(ForEachStatement* stmt,
691 Expression* each,
692 Expression* subject,
693 Statement* body);
694
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000695 ZoneList<Expression*>* ParseArguments(bool* ok);
696 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000697 bool name_is_reserved,
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000698 bool is_generator,
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000699 int function_token_position,
ulan@chromium.orgdfe53072013-06-06 14:14:51 +0000700 FunctionLiteral::FunctionType type,
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000701 bool* ok);
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000702
703
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000704 // Magical syntax support.
705 Expression* ParseV8Intrinsic(bool* ok);
706
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000707 INLINE(Token::Value peek()) {
708 if (stack_overflow_) return Token::ILLEGAL;
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000709 return scanner().peek();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000710 }
711
712 INLINE(Token::Value Next()) {
713 // BUG 1215673: Find a thread safe way to set a stack limit in
714 // pre-parse mode. Otherwise, we cannot safely pre-parse from other
715 // threads.
716 if (stack_overflow_) {
717 return Token::ILLEGAL;
718 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000719 if (StackLimitCheck(isolate()).HasOverflowed()) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000720 // Any further calls to Next or peek will return the illegal token.
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000721 // The current call must return the next token, which might already
722 // have been peek'ed.
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000723 stack_overflow_ = true;
724 }
ager@chromium.org5f0c45f2010-12-17 08:51:21 +0000725 return scanner().Next();
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000726 }
727
mstarzinger@chromium.orgf705b502013-04-04 11:38:09 +0000728 bool is_generator() const { return current_function_state_->is_generator(); }
729
danno@chromium.org41728482013-06-12 22:31:22 +0000730 bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode);
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000731
ricow@chromium.org83aa5492011-02-07 12:42:56 +0000732 bool peek_any_identifier();
733
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000734 INLINE(void Consume(Token::Value token));
735 void Expect(Token::Value token, bool* ok);
736 bool Check(Token::Value token);
737 void ExpectSemicolon(bool* ok);
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000738 bool CheckContextualKeyword(Vector<const char> keyword);
739 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000740
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000741 Handle<String> LiteralString(PretenureFlag tenured) {
742 if (scanner().is_literal_ascii()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000743 return isolate_->factory()->NewStringFromAscii(
744 scanner().literal_ascii_string(), tenured);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000745 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000746 return isolate_->factory()->NewStringFromTwoByte(
yangguo@chromium.org154ff992012-03-13 08:09:54 +0000747 scanner().literal_utf16_string(), tenured);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000748 }
749 }
750
751 Handle<String> NextLiteralString(PretenureFlag tenured) {
752 if (scanner().is_next_literal_ascii()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000753 return isolate_->factory()->NewStringFromAscii(
754 scanner().next_literal_ascii_string(), tenured);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000755 } else {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return isolate_->factory()->NewStringFromTwoByte(
yangguo@chromium.org154ff992012-03-13 08:09:54 +0000757 scanner().next_literal_utf16_string(), tenured);
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000758 }
759 }
760
ulan@chromium.orgbf9432e2013-05-22 14:05:23 +0000761 Handle<String> GetSymbol();
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000762
763 // Get odd-ball literals.
764 Literal* GetLiteralUndefined();
765 Literal* GetLiteralTheHole();
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000766
767 Handle<String> ParseIdentifier(bool* ok);
ager@chromium.org04921a82011-06-27 13:21:41 +0000768 Handle<String> ParseIdentifierOrStrictReservedWord(
769 bool* is_strict_reserved, bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000770 Handle<String> ParseIdentifierName(bool* ok);
ager@chromium.org04921a82011-06-27 13:21:41 +0000771 Handle<String> ParseIdentifierNameOrGetOrSet(bool* is_get,
772 bool* is_set,
773 bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000774
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +0000775 // Determine if the expression is a variable proxy and mark it as being used
776 // in an assignment or with a increment/decrement operator. This is currently
777 // used on for the statically checking assignments to harmony const bindings.
778 void MarkAsLValue(Expression* expression);
779
ager@chromium.org378b34e2011-01-28 08:04:38 +0000780 // Strict mode validation of LValue expressions
781 void CheckStrictModeLValue(Expression* expression,
782 const char* error,
783 bool* ok);
784
ager@chromium.org0ee099b2011-01-25 14:06:47 +0000785 // Strict mode octal literal validation.
786 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
787
fschneider@chromium.org1805e212011-09-05 10:49:12 +0000788 // For harmony block scoping mode: Check if the scope has conflicting var/let
789 // declarations from different scopes. It covers for example
790 //
791 // function f() { { { var x; } let x; } }
792 // function g() { { var x; let x; } }
793 //
794 // The var declarations are hoisted to the function scope, but originate from
795 // a scope where the name has also been let bound or the var declaration is
796 // hoisted over such a scope.
797 void CheckConflictingVarDeclarations(Scope* scope, bool* ok);
798
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000799 // Parser support
erik.corry@gmail.combbceb572012-03-09 10:52:05 +0000800 VariableProxy* NewUnresolved(Handle<String> name,
801 VariableMode mode,
jkummerow@chromium.org28583c92012-07-16 11:31:55 +0000802 Interface* interface);
ulan@chromium.org812308e2012-02-29 15:58:45 +0000803 void Declare(Declaration* declaration, bool resolve, bool* ok);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000804
805 bool TargetStackContainsLabel(Handle<String> label);
806 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
807 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
808
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000809 void RegisterTargetUse(Label* target, Target* stop);
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000810
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000811 // Factory methods.
812
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000813 Scope* NewScope(Scope* parent, ScopeType type);
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000814
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000815 Handle<String> LookupSymbol(int symbol_id);
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000816
fschneider@chromium.org9e3e0b62011-01-03 10:16:46 +0000817 Handle<String> LookupCachedSymbol(int symbol_id);
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000818
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000819 // Generate AST node that throw a ReferenceError with the given type.
820 Expression* NewThrowReferenceError(Handle<String> type);
821
822 // Generate AST node that throw a SyntaxError with the given
823 // type. The first argument may be null (in the handle sense) in
824 // which case no arguments are passed to the constructor.
825 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
826
827 // Generate AST node that throw a TypeError with the given
828 // type. Both arguments must be non-null (in the handle sense).
829 Expression* NewThrowTypeError(Handle<String> type,
830 Handle<Object> first,
831 Handle<Object> second);
832
833 // Generic AST generator for throwing errors from compiled code.
834 Expression* NewThrowError(Handle<String> constructor,
835 Handle<String> type,
836 Vector< Handle<Object> > arguments);
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000837
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000838 preparser::PreParser::PreParseResult LazyParseFunctionLiteral(
839 SingletonLogger* logger);
840
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +0000841 AstNodeFactory<AstConstructionVisitor>* factory() {
842 return current_function_state_->factory();
843 }
844
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 Isolate* isolate_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000846 ZoneList<Handle<String> > symbol_cache_;
847
848 Handle<Script> script_;
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000849 Scanner scanner_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000850 preparser::PreParser* reusable_preparser_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000851 Scope* top_scope_;
danno@chromium.orgc612e022011-11-10 11:38:15 +0000852 FunctionState* current_function_state_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000853 Target* target_stack_; // for break, continue statements
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000854 v8::Extension* extension_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000855 ScriptDataImpl* pre_parse_data_;
lrn@chromium.orgfa943b72010-11-03 08:14:36 +0000856 FuncNameInferrer* fni_;
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000857
858 Mode mode_;
859 bool allow_natives_syntax_;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +0000860 bool allow_lazy_;
mstarzinger@chromium.orge27d6172013-04-17 11:51:44 +0000861 bool allow_generators_;
danno@chromium.org1fd77d52013-06-07 16:01:45 +0000862 bool allow_for_of_;
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000863 bool stack_overflow_;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000864 // If true, the next (and immediately following) function literal is
865 // preceded by a parenthesis.
866 // Heuristically that means that the function will be called immediately,
867 // so never lazily compile it.
868 bool parenthesized_function_;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000869
rossberg@chromium.org400388e2012-06-06 09:29:22 +0000870 Zone* zone_;
yangguo@chromium.org5a11aaf2012-06-20 11:29:00 +0000871 CompilationInfo* info_;
danno@chromium.orgc612e022011-11-10 11:38:15 +0000872 friend class BlockState;
873 friend class FunctionState;
ricow@chromium.orgeb7c1442010-10-04 08:54:21 +0000874};
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000876
877// Support for handling complex values (array and object literals) that
878// can be fully handled at compile time.
879class CompileTimeValue: public AllStatic {
880 public:
ulan@chromium.orgdfe53072013-06-06 14:14:51 +0000881 enum LiteralType {
vegorov@chromium.orgf8372902010-03-15 10:26:20 +0000882 OBJECT_LITERAL_FAST_ELEMENTS,
883 OBJECT_LITERAL_SLOW_ELEMENTS,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000884 ARRAY_LITERAL
885 };
886
887 static bool IsCompileTimeValue(Expression* expression);
888
889 // Get the value as a compile time value.
890 static Handle<FixedArray> GetValue(Expression* expression);
891
892 // Get the type of a compile time value returned by GetValue().
ulan@chromium.orgdfe53072013-06-06 14:14:51 +0000893 static LiteralType GetLiteralType(Handle<FixedArray> value);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000894
895 // Get the elements array of a compile time value returned by GetValue().
896 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
897
898 private:
ulan@chromium.orgdfe53072013-06-06 14:14:51 +0000899 static const int kLiteralTypeSlot = 0;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000900 static const int kElementsSlot = 1;
901
902 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
903};
904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000905} } // namespace v8::internal
906
907#endif // V8_PARSER_H_