blob: a7132ce240a3c3650801102438adf4781844cc76 [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]; }
75 void set_start_pos(int value) { backing_[kStartPosOffset] = value; }
76
77 int end_pos() { return backing_[kEndPosOffset]; }
78 void set_end_pos(int value) { backing_[kEndPosOffset] = value; }
79
80 int literal_count() { return backing_[kLiteralCountOffset]; }
81 void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; }
82
83 int property_count() { return backing_[kPropertyCountOffset]; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +010084 void set_property_count(int value) {
85 backing_[kPropertyCountOffset] = value;
86 }
87
Steve Blocka7e24c12009-10-30 11:49:00 +000088 bool is_valid() { return backing_.length() > 0; }
89
Ben Murdochf87a2032010-10-22 12:50:53 +010090 static const int kSize = 4;
Steve Blocka7e24c12009-10-30 11:49:00 +000091
92 private:
93 Vector<unsigned> backing_;
94 static const int kStartPosOffset = 0;
95 static const int kEndPosOffset = 1;
96 static const int kLiteralCountOffset = 2;
97 static const int kPropertyCountOffset = 3;
Steve Blocka7e24c12009-10-30 11:49:00 +000098};
99
100
101class ScriptDataImpl : public ScriptData {
102 public:
103 explicit ScriptDataImpl(Vector<unsigned> store)
104 : store_(store),
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100105 owns_store_(true) { }
Iain Merrick9ac36c92010-09-13 15:29:50 +0100106
107 // Create an empty ScriptDataImpl that is guaranteed to not satisfy
108 // a SanityCheck.
109 ScriptDataImpl() : store_(Vector<unsigned>()), owns_store_(false) { }
110
Steve Blocka7e24c12009-10-30 11:49:00 +0000111 virtual ~ScriptDataImpl();
112 virtual int Length();
Leon Clarkef7060e22010-06-03 12:02:55 +0100113 virtual const char* Data();
Leon Clarkee46be812010-01-19 14:06:41 +0000114 virtual bool HasError();
Iain Merrick9ac36c92010-09-13 15:29:50 +0100115
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100116 void Initialize();
117 void ReadNextSymbolPosition();
118
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100119 FunctionEntry GetFunctionEntry(int start);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100120 int GetSymbolIdentifier();
Steve Blocka7e24c12009-10-30 11:49:00 +0000121 bool SanityCheck();
122
123 Scanner::Location MessageLocation();
124 const char* BuildMessage();
125 Vector<const char*> BuildArgs();
126
Iain Merrick9ac36c92010-09-13 15:29:50 +0100127 int symbol_count() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800128 return (store_.length() > PreparseDataConstants::kHeaderSize)
129 ? store_[PreparseDataConstants::kSymbolCountOffset]
130 : 0;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100131 }
132 // The following functions should only be called if SanityCheck has
133 // returned true.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800134 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
135 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
136 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100137
Steve Blocka7e24c12009-10-30 11:49:00 +0000138 private:
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100139 Vector<unsigned> store_;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100140 unsigned char* symbol_data_;
141 unsigned char* symbol_data_end_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100142 int function_index_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100143 bool owns_store_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100144
Steve Blocka7e24c12009-10-30 11:49:00 +0000145 unsigned Read(int position);
146 unsigned* ReadAddress(int position);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100147 // Reads a number from the current symbols
148 int ReadNumber(byte** source);
Steve Blocka7e24c12009-10-30 11:49:00 +0000149
Iain Merrick9ac36c92010-09-13 15:29:50 +0100150 ScriptDataImpl(const char* backing_store, int length)
151 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
Ben Murdochf87a2032010-10-22 12:50:53 +0100152 length / static_cast<int>(sizeof(unsigned))),
Iain Merrick9ac36c92010-09-13 15:29:50 +0100153 owns_store_(false) {
Ben Murdochf87a2032010-10-22 12:50:53 +0100154 ASSERT_EQ(0, static_cast<int>(
155 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
Iain Merrick9ac36c92010-09-13 15:29:50 +0100156 }
157
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100158 // Read strings written by ParserRecorder::WriteString.
159 static const char* ReadString(unsigned* start, int* chars);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100160
161 friend class ScriptData;
Steve Blocka7e24c12009-10-30 11:49:00 +0000162};
163
164
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800165class ParserApi {
166 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100167 // Parses the source code represented by the compilation info and sets its
168 // function literal. Returns false (and deallocates any allocated AST
169 // nodes) if parsing failed.
170 static bool Parse(CompilationInfo* info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000171
Ben Murdochf87a2032010-10-22 12:50:53 +0100172 // Generic preparser generating full preparse data.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100173 static ScriptDataImpl* PreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100174 v8::Extension* extension);
175
176 // Preparser that only does preprocessing that makes sense if only used
177 // immediately after.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100178 static ScriptDataImpl* PartialPreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100179 v8::Extension* extension);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800180};
181
182// ----------------------------------------------------------------------------
183// REGEXP PARSING
184
185// A BuffferedZoneList is an automatically growing list, just like (and backed
186// by) a ZoneList, that is optimized for the case of adding and removing
187// a single element. The last element added is stored outside the backing list,
188// and if no more than one element is ever added, the ZoneList isn't even
189// allocated.
190// Elements must not be NULL pointers.
191template <typename T, int initial_size>
192class BufferedZoneList {
193 public:
194 BufferedZoneList() : list_(NULL), last_(NULL) {}
195
196 // Adds element at end of list. This element is buffered and can
197 // be read using last() or removed using RemoveLast until a new Add or until
198 // RemoveLast or GetList has been called.
199 void Add(T* value) {
200 if (last_ != NULL) {
201 if (list_ == NULL) {
202 list_ = new ZoneList<T*>(initial_size);
203 }
204 list_->Add(last_);
205 }
206 last_ = value;
207 }
208
209 T* last() {
210 ASSERT(last_ != NULL);
211 return last_;
212 }
213
214 T* RemoveLast() {
215 ASSERT(last_ != NULL);
216 T* result = last_;
217 if ((list_ != NULL) && (list_->length() > 0))
218 last_ = list_->RemoveLast();
219 else
220 last_ = NULL;
221 return result;
222 }
223
224 T* Get(int i) {
225 ASSERT((0 <= i) && (i < length()));
226 if (list_ == NULL) {
227 ASSERT_EQ(0, i);
228 return last_;
229 } else {
230 if (i == list_->length()) {
231 ASSERT(last_ != NULL);
232 return last_;
233 } else {
234 return list_->at(i);
235 }
236 }
237 }
238
239 void Clear() {
240 list_ = NULL;
241 last_ = NULL;
242 }
243
244 int length() {
245 int length = (list_ == NULL) ? 0 : list_->length();
246 return length + ((last_ == NULL) ? 0 : 1);
247 }
248
249 ZoneList<T*>* GetList() {
250 if (list_ == NULL) {
251 list_ = new ZoneList<T*>(initial_size);
252 }
253 if (last_ != NULL) {
254 list_->Add(last_);
255 last_ = NULL;
256 }
257 return list_;
258 }
259
260 private:
261 ZoneList<T*>* list_;
262 T* last_;
263};
264
265
266// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
267class RegExpBuilder: public ZoneObject {
268 public:
269 RegExpBuilder();
270 void AddCharacter(uc16 character);
271 // "Adds" an empty expression. Does nothing except consume a
272 // following quantifier
273 void AddEmpty();
274 void AddAtom(RegExpTree* tree);
275 void AddAssertion(RegExpTree* tree);
276 void NewAlternative(); // '|'
277 void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
278 RegExpTree* ToRegExp();
279
280 private:
281 void FlushCharacters();
282 void FlushText();
283 void FlushTerms();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100284 Zone* zone() { return zone_; }
285
286 Zone* zone_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800287 bool pending_empty_;
288 ZoneList<uc16>* characters_;
289 BufferedZoneList<RegExpTree, 2> terms_;
290 BufferedZoneList<RegExpTree, 2> text_;
291 BufferedZoneList<RegExpTree, 2> alternatives_;
292#ifdef DEBUG
293 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
294#define LAST(x) last_added_ = x;
295#else
296#define LAST(x)
297#endif
298};
299
300
301class RegExpParser {
302 public:
303 RegExpParser(FlatStringReader* in,
304 Handle<String>* error,
305 bool multiline_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100306
307 static bool ParseRegExp(FlatStringReader* input,
308 bool multiline,
309 RegExpCompileData* result);
310
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800311 RegExpTree* ParsePattern();
312 RegExpTree* ParseDisjunction();
313 RegExpTree* ParseGroup();
314 RegExpTree* ParseCharacterClass();
Ben Murdochf87a2032010-10-22 12:50:53 +0100315
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800316 // Parses a {...,...} quantifier and stores the range in the given
317 // out parameters.
318 bool ParseIntervalQuantifier(int* min_out, int* max_out);
Steve Block59151502010-09-22 15:07:15 +0100319
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800320 // Parses and returns a single escaped character. The character
321 // must not be 'b' or 'B' since they are usually handle specially.
322 uc32 ParseClassCharacterEscape();
323
324 // Checks whether the following is a length-digit hexadecimal number,
325 // and sets the value if it is.
326 bool ParseHexEscape(int length, uc32* value);
327
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800328 uc32 ParseOctalLiteral();
329
330 // Tries to parse the input as a back reference. If successful it
331 // stores the result in the output parameter and returns true. If
332 // it fails it will push back the characters read so the same characters
333 // can be reparsed.
334 bool ParseBackReferenceIndex(int* index_out);
335
336 CharacterRange ParseClassAtom(uc16* char_class);
337 RegExpTree* ReportError(Vector<const char> message);
338 void Advance();
339 void Advance(int dist);
340 void Reset(int pos);
341
342 // Reports whether the pattern might be used as a literal search string.
343 // Only use if the result of the parse is a single atom node.
344 bool simple();
345 bool contains_anchor() { return contains_anchor_; }
346 void set_contains_anchor() { contains_anchor_ = true; }
347 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
348 int position() { return next_pos_ - 1; }
349 bool failed() { return failed_; }
350
351 static const int kMaxCaptures = 1 << 16;
352 static const uc32 kEndMarker = (1 << 21);
353
354 private:
355 enum SubexpressionType {
356 INITIAL,
357 CAPTURE, // All positive values represent captures.
358 POSITIVE_LOOKAHEAD,
359 NEGATIVE_LOOKAHEAD,
360 GROUPING
361 };
362
363 class RegExpParserState : public ZoneObject {
364 public:
365 RegExpParserState(RegExpParserState* previous_state,
366 SubexpressionType group_type,
367 int disjunction_capture_index)
368 : previous_state_(previous_state),
369 builder_(new RegExpBuilder()),
370 group_type_(group_type),
371 disjunction_capture_index_(disjunction_capture_index) {}
372 // Parser state of containing expression, if any.
373 RegExpParserState* previous_state() { return previous_state_; }
374 bool IsSubexpression() { return previous_state_ != NULL; }
375 // RegExpBuilder building this regexp's AST.
376 RegExpBuilder* builder() { return builder_; }
377 // Type of regexp being parsed (parenthesized group or entire regexp).
378 SubexpressionType group_type() { return group_type_; }
379 // Index in captures array of first capture in this sub-expression, if any.
380 // Also the capture index of this sub-expression itself, if group_type
381 // is CAPTURE.
382 int capture_index() { return disjunction_capture_index_; }
383
384 private:
385 // Linked list implementation of stack of states.
386 RegExpParserState* previous_state_;
387 // Builder for the stored disjunction.
388 RegExpBuilder* builder_;
389 // Stored disjunction type (capture, look-ahead or grouping), if any.
390 SubexpressionType group_type_;
391 // Stored disjunction's capture index (if any).
392 int disjunction_capture_index_;
393 };
394
Steve Block44f0eee2011-05-26 01:26:41 +0100395 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100396 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100397
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800398 uc32 current() { return current_; }
399 bool has_more() { return has_more_; }
400 bool has_next() { return next_pos_ < in()->length(); }
401 uc32 Next();
402 FlatStringReader* in() { return in_; }
403 void ScanForCaptures();
404
Steve Block44f0eee2011-05-26 01:26:41 +0100405 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800406 Handle<String>* error_;
407 ZoneList<RegExpCapture*>* captures_;
408 FlatStringReader* in_;
409 uc32 current_;
410 int next_pos_;
411 // The capture count is only valid after we have scanned for captures.
412 int capture_count_;
413 bool has_more_;
414 bool multiline_;
415 bool simple_;
416 bool contains_anchor_;
417 bool is_scanned_for_captures_;
418 bool failed_;
419};
420
421// ----------------------------------------------------------------------------
422// JAVASCRIPT PARSING
423
424class Parser {
425 public:
426 Parser(Handle<Script> script,
427 bool allow_natives_syntax,
428 v8::Extension* extension,
429 ScriptDataImpl* pre_data);
430 virtual ~Parser() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000431
Ben Murdochf87a2032010-10-22 12:50:53 +0100432 // Returns NULL if parsing failed.
433 FunctionLiteral* ParseProgram(Handle<String> source,
Steve Block1e0659c2011-05-24 12:43:12 +0100434 bool in_global_context,
435 StrictModeFlag strict_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100436
Steve Block44f0eee2011-05-26 01:26:41 +0100437 FunctionLiteral* ParseLazy(CompilationInfo* info);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800438
439 void ReportMessageAt(Scanner::Location loc,
440 const char* message,
441 Vector<const char*> args);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100442 void ReportMessageAt(Scanner::Location loc,
443 const char* message,
444 Vector<Handle<String> > args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100445
446 protected:
Steve Block1e0659c2011-05-24 12:43:12 +0100447 // Limit on number of function parameters is chosen arbitrarily.
448 // Code::Flags uses only the low 17 bits of num-parameters to
449 // construct a hashable id, so if more than 2^17 are allowed, this
450 // should be checked.
451 static const int kMaxNumFunctionParameters = 32766;
Steve Block053d10c2011-06-13 19:13:29 +0100452 static const int kMaxNumFunctionLocals = 32767;
Steve Block44f0eee2011-05-26 01:26:41 +0100453 FunctionLiteral* ParseLazy(CompilationInfo* info,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100454 UC16CharacterStream* source,
455 ZoneScope* zone_scope);
Ben Murdochf87a2032010-10-22 12:50:53 +0100456 enum Mode {
457 PARSE_LAZILY,
458 PARSE_EAGERLY
459 };
460
Steve Block44f0eee2011-05-26 01:26:41 +0100461 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100462 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100463
Ben Murdochb0fe1622011-05-05 13:52:32 +0100464 // Called by ParseProgram after setting up the scanner.
465 FunctionLiteral* DoParseProgram(Handle<String> source,
466 bool in_global_context,
Steve Block1e0659c2011-05-24 12:43:12 +0100467 StrictModeFlag strict_mode,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100468 ZoneScope* zone_scope);
469
Ben Murdochf87a2032010-10-22 12:50:53 +0100470 // Report syntax error
471 void ReportUnexpectedToken(Token::Value token);
472 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800473 void ReportMessage(const char* message, Vector<const char*> args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100474
475 bool inside_with() const { return with_nesting_level_ > 0; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100476 V8JavaScriptScanner& scanner() { return scanner_; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100477 Mode mode() const { return mode_; }
478 ScriptDataImpl* pre_data() const { return pre_data_; }
479
Steve Block44f0eee2011-05-26 01:26:41 +0100480 // Check if the given string is 'eval' or 'arguments'.
481 bool IsEvalOrArguments(Handle<String> string);
482
Ben Murdochf87a2032010-10-22 12:50:53 +0100483 // All ParseXXX functions take as the last argument an *ok parameter
484 // which is set to false if parsing failed; it is unchanged otherwise.
485 // By making the 'exception handling' explicit, we are forced to check
486 // for failure at the call sites.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800487 void* ParseSourceElements(ZoneList<Statement*>* processor,
Ben Murdochf87a2032010-10-22 12:50:53 +0100488 int end_token, bool* ok);
489 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
490 Statement* ParseFunctionDeclaration(bool* ok);
491 Statement* ParseNativeDeclaration(bool* ok);
492 Block* ParseBlock(ZoneStringList* labels, bool* ok);
493 Block* ParseVariableStatement(bool* ok);
494 Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
495 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
496 bool* ok);
497 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
498 Statement* ParseContinueStatement(bool* ok);
499 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
500 Statement* ParseReturnStatement(bool* ok);
501 Block* WithHelper(Expression* obj,
502 ZoneStringList* labels,
503 bool is_catch_block,
504 bool* ok);
505 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
506 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
507 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
508 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
509 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
510 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
511 Statement* ParseThrowStatement(bool* ok);
512 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
513 TryStatement* ParseTryStatement(bool* ok);
514 DebuggerStatement* ParseDebuggerStatement(bool* ok);
515
516 Expression* ParseExpression(bool accept_IN, bool* ok);
517 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
518 Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
519 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
520 Expression* ParseUnaryExpression(bool* ok);
521 Expression* ParsePostfixExpression(bool* ok);
522 Expression* ParseLeftHandSideExpression(bool* ok);
523 Expression* ParseNewExpression(bool* ok);
524 Expression* ParseMemberExpression(bool* ok);
525 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
526 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
527 bool* ok);
528 Expression* ParsePrimaryExpression(bool* ok);
529 Expression* ParseArrayLiteral(bool* ok);
530 Expression* ParseObjectLiteral(bool* ok);
531 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
532 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
533
534 Expression* NewCompareNode(Token::Value op,
535 Expression* x,
536 Expression* y,
537 int position);
538
539 // Populate the constant properties fixed array for a materialized object
540 // literal.
541 void BuildObjectLiteralConstantProperties(
542 ZoneList<ObjectLiteral::Property*>* properties,
543 Handle<FixedArray> constants,
544 bool* is_simple,
545 bool* fast_elements,
546 int* depth);
547
548 // Populate the literals fixed array for a materialized array literal.
549 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
550 Handle<FixedArray> constants,
551 bool* is_simple,
552 int* depth);
553
554 // Decide if a property should be in the object boilerplate.
555 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
556 // If the expression is a literal, return the literal value;
557 // if the expression is a materialized literal and is simple return a
558 // compile time value as encoded by CompileTimeValue::GetValue().
559 // Otherwise, return undefined literal as the placeholder
560 // in the object literal boilerplate.
561 Handle<Object> GetBoilerplateValue(Expression* expression);
562
563 enum FunctionLiteralType {
564 EXPRESSION,
565 DECLARATION,
566 NESTED
567 };
568
569 ZoneList<Expression*>* ParseArguments(bool* ok);
570 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
Steve Block1e0659c2011-05-24 12:43:12 +0100571 bool name_is_reserved,
Ben Murdochf87a2032010-10-22 12:50:53 +0100572 int function_token_position,
573 FunctionLiteralType type,
574 bool* ok);
Steve Blocka7e24c12009-10-30 11:49:00 +0000575
576
Ben Murdochf87a2032010-10-22 12:50:53 +0100577 // Magical syntax support.
578 Expression* ParseV8Intrinsic(bool* ok);
579
Ben Murdochb0fe1622011-05-05 13:52:32 +0100580 INLINE(Token::Value peek()) {
581 if (stack_overflow_) return Token::ILLEGAL;
582 return scanner().peek();
583 }
584
585 INLINE(Token::Value Next()) {
586 // BUG 1215673: Find a thread safe way to set a stack limit in
587 // pre-parse mode. Otherwise, we cannot safely pre-parse from other
588 // threads.
589 if (stack_overflow_) {
590 return Token::ILLEGAL;
591 }
Steve Block44f0eee2011-05-26 01:26:41 +0100592 if (StackLimitCheck(isolate()).HasOverflowed()) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100593 // Any further calls to Next or peek will return the illegal token.
594 // The current call must return the next token, which might already
595 // have been peek'ed.
596 stack_overflow_ = true;
597 }
598 return scanner().Next();
599 }
600
Steve Block1e0659c2011-05-24 12:43:12 +0100601 bool peek_any_identifier();
602
Ben Murdochf87a2032010-10-22 12:50:53 +0100603 INLINE(void Consume(Token::Value token));
604 void Expect(Token::Value token, bool* ok);
605 bool Check(Token::Value token);
606 void ExpectSemicolon(bool* ok);
607
Steve Block9fac8402011-05-12 15:51:54 +0100608 Handle<String> LiteralString(PretenureFlag tenured) {
609 if (scanner().is_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100610 return isolate_->factory()->NewStringFromAscii(
611 scanner().literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100612 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100613 return isolate_->factory()->NewStringFromTwoByte(
614 scanner().literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100615 }
616 }
617
618 Handle<String> NextLiteralString(PretenureFlag tenured) {
619 if (scanner().is_next_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100620 return isolate_->factory()->NewStringFromAscii(
621 scanner().next_literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100622 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100623 return isolate_->factory()->NewStringFromTwoByte(
624 scanner().next_literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100625 }
626 }
627
Ben Murdochf87a2032010-10-22 12:50:53 +0100628 Handle<String> GetSymbol(bool* ok);
629
630 // Get odd-ball literals.
631 Literal* GetLiteralUndefined();
632 Literal* GetLiteralTheHole();
633 Literal* GetLiteralNumber(double value);
634
635 Handle<String> ParseIdentifier(bool* ok);
Steve Block1e0659c2011-05-24 12:43:12 +0100636 Handle<String> ParseIdentifierOrReservedWord(bool* is_reserved, bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100637 Handle<String> ParseIdentifierName(bool* ok);
638 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
639 bool* is_set,
640 bool* ok);
641
Steve Block1e0659c2011-05-24 12:43:12 +0100642 // Strict mode validation of LValue expressions
643 void CheckStrictModeLValue(Expression* expression,
644 const char* error,
645 bool* ok);
646
647 // Strict mode octal literal validation.
648 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
649
Ben Murdochf87a2032010-10-22 12:50:53 +0100650 // Parser support
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800651 VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
652 FunctionLiteral* fun,
653 bool resolve,
654 bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100655
656 bool TargetStackContainsLabel(Handle<String> label);
657 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
658 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
659
Ben Murdoch8b112d22011-06-08 16:22:53 +0100660 void RegisterTargetUse(Label* target, Target* stop);
Ben Murdochf87a2032010-10-22 12:50:53 +0100661
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800662 // Factory methods.
663
664 Statement* EmptyStatement() {
665 static v8::internal::EmptyStatement empty;
666 return &empty;
667 }
668
669 Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
670
Steve Block9fac8402011-05-12 15:51:54 +0100671 Handle<String> LookupSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800672
Steve Block9fac8402011-05-12 15:51:54 +0100673 Handle<String> LookupCachedSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800674
675 Expression* NewCall(Expression* expression,
676 ZoneList<Expression*>* arguments,
677 int pos) {
678 return new Call(expression, arguments, pos);
679 }
680
681
Ben Murdochf87a2032010-10-22 12:50:53 +0100682 // Create a number literal.
683 Literal* NewNumberLiteral(double value);
684
685 // Generate AST node that throw a ReferenceError with the given type.
686 Expression* NewThrowReferenceError(Handle<String> type);
687
688 // Generate AST node that throw a SyntaxError with the given
689 // type. The first argument may be null (in the handle sense) in
690 // which case no arguments are passed to the constructor.
691 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
692
693 // Generate AST node that throw a TypeError with the given
694 // type. Both arguments must be non-null (in the handle sense).
695 Expression* NewThrowTypeError(Handle<String> type,
696 Handle<Object> first,
697 Handle<Object> second);
698
699 // Generic AST generator for throwing errors from compiled code.
700 Expression* NewThrowError(Handle<String> constructor,
701 Handle<String> type,
702 Vector< Handle<Object> > arguments);
703
Steve Block44f0eee2011-05-26 01:26:41 +0100704 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800705 ZoneList<Handle<String> > symbol_cache_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100706
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800707 Handle<Script> script_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800708 V8JavaScriptScanner scanner_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100709
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800710 Scope* top_scope_;
711 int with_nesting_level_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100712
Steve Block44f0eee2011-05-26 01:26:41 +0100713 LexicalScope* lexical_scope_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800714 Mode mode_;
715
716 Target* target_stack_; // for break, continue statements
717 bool allow_natives_syntax_;
718 v8::Extension* extension_;
719 bool is_pre_parsing_;
720 ScriptDataImpl* pre_data_;
721 FuncNameInferrer* fni_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100722 bool stack_overflow_;
Ben Murdochb8e0da22011-05-16 14:20:40 +0100723 // If true, the next (and immediately following) function literal is
724 // preceded by a parenthesis.
725 // Heuristically that means that the function will be called immediately,
726 // so never lazily compile it.
727 bool parenthesized_function_;
Steve Block44f0eee2011-05-26 01:26:41 +0100728
729 friend class LexicalScope;
Ben Murdochf87a2032010-10-22 12:50:53 +0100730};
Steve Blocka7e24c12009-10-30 11:49:00 +0000731
732
733// Support for handling complex values (array and object literals) that
734// can be fully handled at compile time.
735class CompileTimeValue: public AllStatic {
736 public:
737 enum Type {
Steve Block6ded16b2010-05-10 14:33:55 +0100738 OBJECT_LITERAL_FAST_ELEMENTS,
739 OBJECT_LITERAL_SLOW_ELEMENTS,
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 ARRAY_LITERAL
741 };
742
743 static bool IsCompileTimeValue(Expression* expression);
744
Iain Merrick75681382010-08-19 15:07:18 +0100745 static bool ArrayLiteralElementNeedsInitialization(Expression* value);
746
Steve Blocka7e24c12009-10-30 11:49:00 +0000747 // Get the value as a compile time value.
748 static Handle<FixedArray> GetValue(Expression* expression);
749
750 // Get the type of a compile time value returned by GetValue().
751 static Type GetType(Handle<FixedArray> value);
752
753 // Get the elements array of a compile time value returned by GetValue().
754 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
755
756 private:
757 static const int kTypeSlot = 0;
758 static const int kElementsSlot = 1;
759
760 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
761};
762
Steve Blocka7e24c12009-10-30 11:49:00 +0000763} } // namespace v8::internal
764
765#endif // V8_PARSER_H_