blob: 535b63945cc4d0e944db3dcc96f309732befd658 [file] [log] [blame]
Ben Murdoch8b112d22011-06-08 16:22:53 +01001// Copyright 2011 the V8 project authors. All rights reserved.
Steve Blocka7e24c12009-10-30 11:49:00 +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
Steve Blocka7e24c12009-10-30 11:49:00 +000031#include "allocation.h"
Ben Murdochf87a2032010-10-22 12:50:53 +010032#include "ast.h"
33#include "scanner.h"
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -080034#include "scopes.h"
Ben Murdoch257744e2011-11-30 15:57:28 +000035#include "preparse-data-format.h"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080036#include "preparse-data.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000037
38namespace v8 {
39namespace internal {
40
Ben Murdochf87a2032010-10-22 12:50:53 +010041class CompilationInfo;
42class FuncNameInferrer;
Ben Murdochf87a2032010-10-22 12:50:53 +010043class ParserLog;
44class PositionStack;
45class Target;
Steve Block44f0eee2011-05-26 01:26:41 +010046class LexicalScope;
Ben Murdochf87a2032010-10-22 12:50:53 +010047
48template <typename T> class ZoneListWrapper;
49
Steve Blocka7e24c12009-10-30 11:49:00 +000050
51class ParserMessage : public Malloced {
52 public:
53 ParserMessage(Scanner::Location loc, const char* message,
54 Vector<const char*> args)
55 : loc_(loc),
56 message_(message),
57 args_(args) { }
58 ~ParserMessage();
59 Scanner::Location location() { return loc_; }
60 const char* message() { return message_; }
61 Vector<const char*> args() { return args_; }
62 private:
63 Scanner::Location loc_;
64 const char* message_;
65 Vector<const char*> args_;
66};
67
68
69class FunctionEntry BASE_EMBEDDED {
70 public:
71 explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { }
72 FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
73
74 int start_pos() { return backing_[kStartPosOffset]; }
Steve Blocka7e24c12009-10-30 11:49:00 +000075 int end_pos() { return backing_[kEndPosOffset]; }
Steve Blocka7e24c12009-10-30 11:49:00 +000076 int literal_count() { return backing_[kLiteralCountOffset]; }
Steve Blocka7e24c12009-10-30 11:49:00 +000077 int property_count() { return backing_[kPropertyCountOffset]; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000078 bool strict_mode() { return backing_[kStrictModeOffset] != 0; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +010079
Steve Blocka7e24c12009-10-30 11:49:00 +000080 bool is_valid() { return backing_.length() > 0; }
81
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000082 static const int kSize = 5;
Steve Blocka7e24c12009-10-30 11:49:00 +000083
84 private:
85 Vector<unsigned> backing_;
86 static const int kStartPosOffset = 0;
87 static const int kEndPosOffset = 1;
88 static const int kLiteralCountOffset = 2;
89 static const int kPropertyCountOffset = 3;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +000090 static const int kStrictModeOffset = 4;
Steve Blocka7e24c12009-10-30 11:49:00 +000091};
92
93
94class ScriptDataImpl : public ScriptData {
95 public:
96 explicit ScriptDataImpl(Vector<unsigned> store)
97 : store_(store),
Kristian Monsen0d5e1162010-09-30 15:31:59 +010098 owns_store_(true) { }
Iain Merrick9ac36c92010-09-13 15:29:50 +010099
100 // Create an empty ScriptDataImpl that is guaranteed to not satisfy
101 // a SanityCheck.
102 ScriptDataImpl() : store_(Vector<unsigned>()), owns_store_(false) { }
103
Steve Blocka7e24c12009-10-30 11:49:00 +0000104 virtual ~ScriptDataImpl();
105 virtual int Length();
Leon Clarkef7060e22010-06-03 12:02:55 +0100106 virtual const char* Data();
Leon Clarkee46be812010-01-19 14:06:41 +0000107 virtual bool HasError();
Iain Merrick9ac36c92010-09-13 15:29:50 +0100108
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100109 void Initialize();
110 void ReadNextSymbolPosition();
111
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100112 FunctionEntry GetFunctionEntry(int start);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100113 int GetSymbolIdentifier();
Steve Blocka7e24c12009-10-30 11:49:00 +0000114 bool SanityCheck();
115
116 Scanner::Location MessageLocation();
117 const char* BuildMessage();
118 Vector<const char*> BuildArgs();
119
Iain Merrick9ac36c92010-09-13 15:29:50 +0100120 int symbol_count() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800121 return (store_.length() > PreparseDataConstants::kHeaderSize)
122 ? store_[PreparseDataConstants::kSymbolCountOffset]
123 : 0;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100124 }
125 // The following functions should only be called if SanityCheck has
126 // returned true.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800127 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
128 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
129 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100130
Steve Blocka7e24c12009-10-30 11:49:00 +0000131 private:
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100132 Vector<unsigned> store_;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100133 unsigned char* symbol_data_;
134 unsigned char* symbol_data_end_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100135 int function_index_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100136 bool owns_store_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100137
Steve Blocka7e24c12009-10-30 11:49:00 +0000138 unsigned Read(int position);
139 unsigned* ReadAddress(int position);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100140 // Reads a number from the current symbols
141 int ReadNumber(byte** source);
Steve Blocka7e24c12009-10-30 11:49:00 +0000142
Iain Merrick9ac36c92010-09-13 15:29:50 +0100143 ScriptDataImpl(const char* backing_store, int length)
144 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
Ben Murdochf87a2032010-10-22 12:50:53 +0100145 length / static_cast<int>(sizeof(unsigned))),
Iain Merrick9ac36c92010-09-13 15:29:50 +0100146 owns_store_(false) {
Ben Murdochf87a2032010-10-22 12:50:53 +0100147 ASSERT_EQ(0, static_cast<int>(
148 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
Iain Merrick9ac36c92010-09-13 15:29:50 +0100149 }
150
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100151 // Read strings written by ParserRecorder::WriteString.
152 static const char* ReadString(unsigned* start, int* chars);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100153
154 friend class ScriptData;
Steve Blocka7e24c12009-10-30 11:49:00 +0000155};
156
157
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800158class ParserApi {
159 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100160 // Parses the source code represented by the compilation info and sets its
161 // function literal. Returns false (and deallocates any allocated AST
162 // nodes) if parsing failed.
163 static bool Parse(CompilationInfo* info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000164
Ben Murdochf87a2032010-10-22 12:50:53 +0100165 // Generic preparser generating full preparse data.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100166 static ScriptDataImpl* PreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100167 v8::Extension* extension);
168
169 // Preparser that only does preprocessing that makes sense if only used
170 // immediately after.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100171 static ScriptDataImpl* PartialPreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100172 v8::Extension* extension);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800173};
174
175// ----------------------------------------------------------------------------
176// REGEXP PARSING
177
178// A BuffferedZoneList is an automatically growing list, just like (and backed
179// by) a ZoneList, that is optimized for the case of adding and removing
180// a single element. The last element added is stored outside the backing list,
181// and if no more than one element is ever added, the ZoneList isn't even
182// allocated.
183// Elements must not be NULL pointers.
184template <typename T, int initial_size>
185class BufferedZoneList {
186 public:
187 BufferedZoneList() : list_(NULL), last_(NULL) {}
188
189 // Adds element at end of list. This element is buffered and can
190 // be read using last() or removed using RemoveLast until a new Add or until
191 // RemoveLast or GetList has been called.
192 void Add(T* value) {
193 if (last_ != NULL) {
194 if (list_ == NULL) {
195 list_ = new ZoneList<T*>(initial_size);
196 }
197 list_->Add(last_);
198 }
199 last_ = value;
200 }
201
202 T* last() {
203 ASSERT(last_ != NULL);
204 return last_;
205 }
206
207 T* RemoveLast() {
208 ASSERT(last_ != NULL);
209 T* result = last_;
210 if ((list_ != NULL) && (list_->length() > 0))
211 last_ = list_->RemoveLast();
212 else
213 last_ = NULL;
214 return result;
215 }
216
217 T* Get(int i) {
218 ASSERT((0 <= i) && (i < length()));
219 if (list_ == NULL) {
220 ASSERT_EQ(0, i);
221 return last_;
222 } else {
223 if (i == list_->length()) {
224 ASSERT(last_ != NULL);
225 return last_;
226 } else {
227 return list_->at(i);
228 }
229 }
230 }
231
232 void Clear() {
233 list_ = NULL;
234 last_ = NULL;
235 }
236
237 int length() {
238 int length = (list_ == NULL) ? 0 : list_->length();
239 return length + ((last_ == NULL) ? 0 : 1);
240 }
241
242 ZoneList<T*>* GetList() {
243 if (list_ == NULL) {
244 list_ = new ZoneList<T*>(initial_size);
245 }
246 if (last_ != NULL) {
247 list_->Add(last_);
248 last_ = NULL;
249 }
250 return list_;
251 }
252
253 private:
254 ZoneList<T*>* list_;
255 T* last_;
256};
257
258
259// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
260class RegExpBuilder: public ZoneObject {
261 public:
262 RegExpBuilder();
263 void AddCharacter(uc16 character);
264 // "Adds" an empty expression. Does nothing except consume a
265 // following quantifier
266 void AddEmpty();
267 void AddAtom(RegExpTree* tree);
268 void AddAssertion(RegExpTree* tree);
269 void NewAlternative(); // '|'
270 void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
271 RegExpTree* ToRegExp();
272
273 private:
274 void FlushCharacters();
275 void FlushText();
276 void FlushTerms();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100277 Zone* zone() { return zone_; }
278
279 Zone* zone_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800280 bool pending_empty_;
281 ZoneList<uc16>* characters_;
282 BufferedZoneList<RegExpTree, 2> terms_;
283 BufferedZoneList<RegExpTree, 2> text_;
284 BufferedZoneList<RegExpTree, 2> alternatives_;
285#ifdef DEBUG
286 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
287#define LAST(x) last_added_ = x;
288#else
289#define LAST(x)
290#endif
291};
292
293
294class RegExpParser {
295 public:
296 RegExpParser(FlatStringReader* in,
297 Handle<String>* error,
298 bool multiline_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100299
300 static bool ParseRegExp(FlatStringReader* input,
301 bool multiline,
302 RegExpCompileData* result);
303
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800304 RegExpTree* ParsePattern();
305 RegExpTree* ParseDisjunction();
306 RegExpTree* ParseGroup();
307 RegExpTree* ParseCharacterClass();
Ben Murdochf87a2032010-10-22 12:50:53 +0100308
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800309 // Parses a {...,...} quantifier and stores the range in the given
310 // out parameters.
311 bool ParseIntervalQuantifier(int* min_out, int* max_out);
Steve Block59151502010-09-22 15:07:15 +0100312
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800313 // Parses and returns a single escaped character. The character
314 // must not be 'b' or 'B' since they are usually handle specially.
315 uc32 ParseClassCharacterEscape();
316
317 // Checks whether the following is a length-digit hexadecimal number,
318 // and sets the value if it is.
319 bool ParseHexEscape(int length, uc32* value);
320
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800321 uc32 ParseOctalLiteral();
322
323 // Tries to parse the input as a back reference. If successful it
324 // stores the result in the output parameter and returns true. If
325 // it fails it will push back the characters read so the same characters
326 // can be reparsed.
327 bool ParseBackReferenceIndex(int* index_out);
328
329 CharacterRange ParseClassAtom(uc16* char_class);
330 RegExpTree* ReportError(Vector<const char> message);
331 void Advance();
332 void Advance(int dist);
333 void Reset(int pos);
334
335 // Reports whether the pattern might be used as a literal search string.
336 // Only use if the result of the parse is a single atom node.
337 bool simple();
338 bool contains_anchor() { return contains_anchor_; }
339 void set_contains_anchor() { contains_anchor_ = true; }
340 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
341 int position() { return next_pos_ - 1; }
342 bool failed() { return failed_; }
343
344 static const int kMaxCaptures = 1 << 16;
345 static const uc32 kEndMarker = (1 << 21);
346
347 private:
348 enum SubexpressionType {
349 INITIAL,
350 CAPTURE, // All positive values represent captures.
351 POSITIVE_LOOKAHEAD,
352 NEGATIVE_LOOKAHEAD,
353 GROUPING
354 };
355
356 class RegExpParserState : public ZoneObject {
357 public:
358 RegExpParserState(RegExpParserState* previous_state,
359 SubexpressionType group_type,
360 int disjunction_capture_index)
361 : previous_state_(previous_state),
362 builder_(new RegExpBuilder()),
363 group_type_(group_type),
364 disjunction_capture_index_(disjunction_capture_index) {}
365 // Parser state of containing expression, if any.
366 RegExpParserState* previous_state() { return previous_state_; }
367 bool IsSubexpression() { return previous_state_ != NULL; }
368 // RegExpBuilder building this regexp's AST.
369 RegExpBuilder* builder() { return builder_; }
370 // Type of regexp being parsed (parenthesized group or entire regexp).
371 SubexpressionType group_type() { return group_type_; }
372 // Index in captures array of first capture in this sub-expression, if any.
373 // Also the capture index of this sub-expression itself, if group_type
374 // is CAPTURE.
375 int capture_index() { return disjunction_capture_index_; }
376
377 private:
378 // Linked list implementation of stack of states.
379 RegExpParserState* previous_state_;
380 // Builder for the stored disjunction.
381 RegExpBuilder* builder_;
382 // Stored disjunction type (capture, look-ahead or grouping), if any.
383 SubexpressionType group_type_;
384 // Stored disjunction's capture index (if any).
385 int disjunction_capture_index_;
386 };
387
Steve Block44f0eee2011-05-26 01:26:41 +0100388 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100389 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100390
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800391 uc32 current() { return current_; }
392 bool has_more() { return has_more_; }
393 bool has_next() { return next_pos_ < in()->length(); }
394 uc32 Next();
395 FlatStringReader* in() { return in_; }
396 void ScanForCaptures();
397
Steve Block44f0eee2011-05-26 01:26:41 +0100398 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800399 Handle<String>* error_;
400 ZoneList<RegExpCapture*>* captures_;
401 FlatStringReader* in_;
402 uc32 current_;
403 int next_pos_;
404 // The capture count is only valid after we have scanned for captures.
405 int capture_count_;
406 bool has_more_;
407 bool multiline_;
408 bool simple_;
409 bool contains_anchor_;
410 bool is_scanned_for_captures_;
411 bool failed_;
412};
413
414// ----------------------------------------------------------------------------
415// JAVASCRIPT PARSING
416
417class Parser {
418 public:
419 Parser(Handle<Script> script,
420 bool allow_natives_syntax,
421 v8::Extension* extension,
422 ScriptDataImpl* pre_data);
423 virtual ~Parser() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000424
Ben Murdochf87a2032010-10-22 12:50:53 +0100425 // Returns NULL if parsing failed.
426 FunctionLiteral* ParseProgram(Handle<String> source,
Steve Block1e0659c2011-05-24 12:43:12 +0100427 bool in_global_context,
428 StrictModeFlag strict_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100429
Steve Block44f0eee2011-05-26 01:26:41 +0100430 FunctionLiteral* ParseLazy(CompilationInfo* info);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800431
432 void ReportMessageAt(Scanner::Location loc,
433 const char* message,
434 Vector<const char*> args);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100435 void ReportMessageAt(Scanner::Location loc,
436 const char* message,
437 Vector<Handle<String> > args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100438
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000439 private:
Steve Block1e0659c2011-05-24 12:43:12 +0100440 // Limit on number of function parameters is chosen arbitrarily.
441 // Code::Flags uses only the low 17 bits of num-parameters to
442 // construct a hashable id, so if more than 2^17 are allowed, this
443 // should be checked.
444 static const int kMaxNumFunctionParameters = 32766;
Steve Block053d10c2011-06-13 19:13:29 +0100445 static const int kMaxNumFunctionLocals = 32767;
Steve Block44f0eee2011-05-26 01:26:41 +0100446 FunctionLiteral* ParseLazy(CompilationInfo* info,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100447 UC16CharacterStream* source,
448 ZoneScope* zone_scope);
Ben Murdochf87a2032010-10-22 12:50:53 +0100449 enum Mode {
450 PARSE_LAZILY,
451 PARSE_EAGERLY
452 };
453
Steve Block44f0eee2011-05-26 01:26:41 +0100454 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100455 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100456
Ben Murdochb0fe1622011-05-05 13:52:32 +0100457 // Called by ParseProgram after setting up the scanner.
458 FunctionLiteral* DoParseProgram(Handle<String> source,
459 bool in_global_context,
Steve Block1e0659c2011-05-24 12:43:12 +0100460 StrictModeFlag strict_mode,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100461 ZoneScope* zone_scope);
462
Ben Murdochf87a2032010-10-22 12:50:53 +0100463 // Report syntax error
464 void ReportUnexpectedToken(Token::Value token);
465 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800466 void ReportMessage(const char* message, Vector<const char*> args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100467
468 bool inside_with() const { return with_nesting_level_ > 0; }
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000469 JavaScriptScanner& scanner() { return scanner_; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100470 Mode mode() const { return mode_; }
471 ScriptDataImpl* pre_data() const { return pre_data_; }
472
Steve Block44f0eee2011-05-26 01:26:41 +0100473 // Check if the given string is 'eval' or 'arguments'.
474 bool IsEvalOrArguments(Handle<String> string);
475
Ben Murdochf87a2032010-10-22 12:50:53 +0100476 // All ParseXXX functions take as the last argument an *ok parameter
477 // which is set to false if parsing failed; it is unchanged otherwise.
478 // By making the 'exception handling' explicit, we are forced to check
479 // for failure at the call sites.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800480 void* ParseSourceElements(ZoneList<Statement*>* processor,
Ben Murdochf87a2032010-10-22 12:50:53 +0100481 int end_token, bool* ok);
482 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
483 Statement* ParseFunctionDeclaration(bool* ok);
484 Statement* ParseNativeDeclaration(bool* ok);
485 Block* ParseBlock(ZoneStringList* labels, bool* ok);
486 Block* ParseVariableStatement(bool* ok);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000487 Block* ParseVariableDeclarations(bool accept_IN,
488 Handle<String>* out,
489 bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100490 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
491 bool* ok);
492 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
493 Statement* ParseContinueStatement(bool* ok);
494 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
495 Statement* ParseReturnStatement(bool* ok);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000496 Block* WithHelper(Expression* obj, ZoneStringList* labels, bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100497 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
498 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
499 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
500 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
501 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
502 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
503 Statement* ParseThrowStatement(bool* ok);
504 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
505 TryStatement* ParseTryStatement(bool* ok);
506 DebuggerStatement* ParseDebuggerStatement(bool* ok);
507
508 Expression* ParseExpression(bool accept_IN, bool* ok);
509 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
510 Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
511 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
512 Expression* ParseUnaryExpression(bool* ok);
513 Expression* ParsePostfixExpression(bool* ok);
514 Expression* ParseLeftHandSideExpression(bool* ok);
515 Expression* ParseNewExpression(bool* ok);
516 Expression* ParseMemberExpression(bool* ok);
517 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
518 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
519 bool* ok);
520 Expression* ParsePrimaryExpression(bool* ok);
521 Expression* ParseArrayLiteral(bool* ok);
522 Expression* ParseObjectLiteral(bool* ok);
523 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
524 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
525
526 Expression* NewCompareNode(Token::Value op,
527 Expression* x,
528 Expression* y,
529 int position);
530
531 // Populate the constant properties fixed array for a materialized object
532 // literal.
533 void BuildObjectLiteralConstantProperties(
534 ZoneList<ObjectLiteral::Property*>* properties,
535 Handle<FixedArray> constants,
536 bool* is_simple,
537 bool* fast_elements,
538 int* depth);
539
540 // Populate the literals fixed array for a materialized array literal.
541 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
542 Handle<FixedArray> constants,
543 bool* is_simple,
544 int* depth);
545
546 // Decide if a property should be in the object boilerplate.
547 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
548 // If the expression is a literal, return the literal value;
549 // if the expression is a materialized literal and is simple return a
550 // compile time value as encoded by CompileTimeValue::GetValue().
551 // Otherwise, return undefined literal as the placeholder
552 // in the object literal boilerplate.
553 Handle<Object> GetBoilerplateValue(Expression* expression);
554
Ben Murdochf87a2032010-10-22 12:50:53 +0100555 ZoneList<Expression*>* ParseArguments(bool* ok);
556 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
Steve Block1e0659c2011-05-24 12:43:12 +0100557 bool name_is_reserved,
Ben Murdochf87a2032010-10-22 12:50:53 +0100558 int function_token_position,
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000559 FunctionLiteral::Type type,
Ben Murdochf87a2032010-10-22 12:50:53 +0100560 bool* ok);
Steve Blocka7e24c12009-10-30 11:49:00 +0000561
562
Ben Murdochf87a2032010-10-22 12:50:53 +0100563 // Magical syntax support.
564 Expression* ParseV8Intrinsic(bool* ok);
565
Ben Murdochb0fe1622011-05-05 13:52:32 +0100566 INLINE(Token::Value peek()) {
567 if (stack_overflow_) return Token::ILLEGAL;
568 return scanner().peek();
569 }
570
571 INLINE(Token::Value Next()) {
572 // BUG 1215673: Find a thread safe way to set a stack limit in
573 // pre-parse mode. Otherwise, we cannot safely pre-parse from other
574 // threads.
575 if (stack_overflow_) {
576 return Token::ILLEGAL;
577 }
Steve Block44f0eee2011-05-26 01:26:41 +0100578 if (StackLimitCheck(isolate()).HasOverflowed()) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100579 // Any further calls to Next or peek will return the illegal token.
580 // The current call must return the next token, which might already
581 // have been peek'ed.
582 stack_overflow_ = true;
583 }
584 return scanner().Next();
585 }
586
Steve Block1e0659c2011-05-24 12:43:12 +0100587 bool peek_any_identifier();
588
Ben Murdochf87a2032010-10-22 12:50:53 +0100589 INLINE(void Consume(Token::Value token));
590 void Expect(Token::Value token, bool* ok);
591 bool Check(Token::Value token);
592 void ExpectSemicolon(bool* ok);
593
Steve Block9fac8402011-05-12 15:51:54 +0100594 Handle<String> LiteralString(PretenureFlag tenured) {
595 if (scanner().is_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100596 return isolate_->factory()->NewStringFromAscii(
597 scanner().literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100598 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100599 return isolate_->factory()->NewStringFromTwoByte(
600 scanner().literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100601 }
602 }
603
604 Handle<String> NextLiteralString(PretenureFlag tenured) {
605 if (scanner().is_next_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100606 return isolate_->factory()->NewStringFromAscii(
607 scanner().next_literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100608 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100609 return isolate_->factory()->NewStringFromTwoByte(
610 scanner().next_literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100611 }
612 }
613
Ben Murdochf87a2032010-10-22 12:50:53 +0100614 Handle<String> GetSymbol(bool* ok);
615
616 // Get odd-ball literals.
617 Literal* GetLiteralUndefined();
618 Literal* GetLiteralTheHole();
619 Literal* GetLiteralNumber(double value);
620
621 Handle<String> ParseIdentifier(bool* ok);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000622 Handle<String> ParseIdentifierOrStrictReservedWord(
623 bool* is_strict_reserved, bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100624 Handle<String> ParseIdentifierName(bool* ok);
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000625 Handle<String> ParseIdentifierNameOrGetOrSet(bool* is_get,
626 bool* is_set,
627 bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100628
Steve Block1e0659c2011-05-24 12:43:12 +0100629 // Strict mode validation of LValue expressions
630 void CheckStrictModeLValue(Expression* expression,
631 const char* error,
632 bool* ok);
633
634 // Strict mode octal literal validation.
635 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
636
Ben Murdochf87a2032010-10-22 12:50:53 +0100637 // Parser support
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800638 VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
639 FunctionLiteral* fun,
640 bool resolve,
641 bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100642
643 bool TargetStackContainsLabel(Handle<String> label);
644 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
645 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
646
Ben Murdoch8b112d22011-06-08 16:22:53 +0100647 void RegisterTargetUse(Label* target, Target* stop);
Ben Murdochf87a2032010-10-22 12:50:53 +0100648
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800649 // Factory methods.
650
651 Statement* EmptyStatement() {
652 static v8::internal::EmptyStatement empty;
653 return &empty;
654 }
655
656 Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
657
Steve Block9fac8402011-05-12 15:51:54 +0100658 Handle<String> LookupSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800659
Steve Block9fac8402011-05-12 15:51:54 +0100660 Handle<String> LookupCachedSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800661
662 Expression* NewCall(Expression* expression,
663 ZoneList<Expression*>* arguments,
664 int pos) {
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000665 return new(zone()) Call(isolate(), expression, arguments, pos);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800666 }
667
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000668 inline Literal* NewLiteral(Handle<Object> handle) {
669 return new(zone()) Literal(isolate(), handle);
670 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800671
Ben Murdochf87a2032010-10-22 12:50:53 +0100672 // Create a number literal.
673 Literal* NewNumberLiteral(double value);
674
675 // Generate AST node that throw a ReferenceError with the given type.
676 Expression* NewThrowReferenceError(Handle<String> type);
677
678 // Generate AST node that throw a SyntaxError with the given
679 // type. The first argument may be null (in the handle sense) in
680 // which case no arguments are passed to the constructor.
681 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
682
683 // Generate AST node that throw a TypeError with the given
684 // type. Both arguments must be non-null (in the handle sense).
685 Expression* NewThrowTypeError(Handle<String> type,
686 Handle<Object> first,
687 Handle<Object> second);
688
689 // Generic AST generator for throwing errors from compiled code.
690 Expression* NewThrowError(Handle<String> constructor,
691 Handle<String> type,
692 Vector< Handle<Object> > arguments);
693
Steve Block44f0eee2011-05-26 01:26:41 +0100694 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800695 ZoneList<Handle<String> > symbol_cache_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100696
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800697 Handle<Script> script_;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000698 JavaScriptScanner scanner_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100699
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800700 Scope* top_scope_;
701 int with_nesting_level_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100702
Steve Block44f0eee2011-05-26 01:26:41 +0100703 LexicalScope* lexical_scope_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800704 Mode mode_;
705
706 Target* target_stack_; // for break, continue statements
707 bool allow_natives_syntax_;
708 v8::Extension* extension_;
709 bool is_pre_parsing_;
710 ScriptDataImpl* pre_data_;
711 FuncNameInferrer* fni_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100712 bool stack_overflow_;
Ben Murdochb8e0da22011-05-16 14:20:40 +0100713 // If true, the next (and immediately following) function literal is
714 // preceded by a parenthesis.
715 // Heuristically that means that the function will be called immediately,
716 // so never lazily compile it.
717 bool parenthesized_function_;
Steve Block44f0eee2011-05-26 01:26:41 +0100718
719 friend class LexicalScope;
Ben Murdochf87a2032010-10-22 12:50:53 +0100720};
Steve Blocka7e24c12009-10-30 11:49:00 +0000721
722
723// Support for handling complex values (array and object literals) that
724// can be fully handled at compile time.
725class CompileTimeValue: public AllStatic {
726 public:
727 enum Type {
Steve Block6ded16b2010-05-10 14:33:55 +0100728 OBJECT_LITERAL_FAST_ELEMENTS,
729 OBJECT_LITERAL_SLOW_ELEMENTS,
Steve Blocka7e24c12009-10-30 11:49:00 +0000730 ARRAY_LITERAL
731 };
732
733 static bool IsCompileTimeValue(Expression* expression);
734
Iain Merrick75681382010-08-19 15:07:18 +0100735 static bool ArrayLiteralElementNeedsInitialization(Expression* value);
736
Steve Blocka7e24c12009-10-30 11:49:00 +0000737 // Get the value as a compile time value.
738 static Handle<FixedArray> GetValue(Expression* expression);
739
740 // Get the type of a compile time value returned by GetValue().
741 static Type GetType(Handle<FixedArray> value);
742
743 // Get the elements array of a compile time value returned by GetValue().
744 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
745
746 private:
747 static const int kTypeSlot = 0;
748 static const int kElementsSlot = 1;
749
750 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
751};
752
Steve Blocka7e24c12009-10-30 11:49:00 +0000753} } // namespace v8::internal
754
755#endif // V8_PARSER_H_