blob: a63651afbc61def37afdb432f694231f9548f3b6 [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"
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -080035#include "preparse-data.h"
Steve Blocka7e24c12009-10-30 11:49:00 +000036
37namespace v8 {
38namespace internal {
39
Ben Murdochf87a2032010-10-22 12:50:53 +010040class CompilationInfo;
41class FuncNameInferrer;
Ben Murdochf87a2032010-10-22 12:50:53 +010042class ParserLog;
43class PositionStack;
44class Target;
Steve Block44f0eee2011-05-26 01:26:41 +010045class LexicalScope;
Ben Murdochf87a2032010-10-22 12:50:53 +010046
47template <typename T> class ZoneListWrapper;
48
Steve Blocka7e24c12009-10-30 11:49:00 +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:
70 explicit FunctionEntry(Vector<unsigned> backing) : backing_(backing) { }
71 FunctionEntry() : backing_(Vector<unsigned>::empty()) { }
72
73 int start_pos() { return backing_[kStartPosOffset]; }
74 void set_start_pos(int value) { backing_[kStartPosOffset] = value; }
75
76 int end_pos() { return backing_[kEndPosOffset]; }
77 void set_end_pos(int value) { backing_[kEndPosOffset] = value; }
78
79 int literal_count() { return backing_[kLiteralCountOffset]; }
80 void set_literal_count(int value) { backing_[kLiteralCountOffset] = value; }
81
82 int property_count() { return backing_[kPropertyCountOffset]; }
Kristian Monsen80d68ea2010-09-08 11:05:35 +010083 void set_property_count(int value) {
84 backing_[kPropertyCountOffset] = value;
85 }
86
Steve Blocka7e24c12009-10-30 11:49:00 +000087 bool is_valid() { return backing_.length() > 0; }
88
Ben Murdochf87a2032010-10-22 12:50:53 +010089 static const int kSize = 4;
Steve Blocka7e24c12009-10-30 11:49:00 +000090
91 private:
92 Vector<unsigned> backing_;
93 static const int kStartPosOffset = 0;
94 static const int kEndPosOffset = 1;
95 static const int kLiteralCountOffset = 2;
96 static const int kPropertyCountOffset = 3;
Steve Blocka7e24c12009-10-30 11:49:00 +000097};
98
99
100class ScriptDataImpl : public ScriptData {
101 public:
102 explicit ScriptDataImpl(Vector<unsigned> store)
103 : store_(store),
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100104 owns_store_(true) { }
Iain Merrick9ac36c92010-09-13 15:29:50 +0100105
106 // Create an empty ScriptDataImpl that is guaranteed to not satisfy
107 // a SanityCheck.
108 ScriptDataImpl() : store_(Vector<unsigned>()), owns_store_(false) { }
109
Steve Blocka7e24c12009-10-30 11:49:00 +0000110 virtual ~ScriptDataImpl();
111 virtual int Length();
Leon Clarkef7060e22010-06-03 12:02:55 +0100112 virtual const char* Data();
Leon Clarkee46be812010-01-19 14:06:41 +0000113 virtual bool HasError();
Iain Merrick9ac36c92010-09-13 15:29:50 +0100114
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100115 void Initialize();
116 void ReadNextSymbolPosition();
117
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100118 FunctionEntry GetFunctionEntry(int start);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100119 int GetSymbolIdentifier();
Steve Blocka7e24c12009-10-30 11:49:00 +0000120 bool SanityCheck();
121
122 Scanner::Location MessageLocation();
123 const char* BuildMessage();
124 Vector<const char*> BuildArgs();
125
Iain Merrick9ac36c92010-09-13 15:29:50 +0100126 int symbol_count() {
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800127 return (store_.length() > PreparseDataConstants::kHeaderSize)
128 ? store_[PreparseDataConstants::kSymbolCountOffset]
129 : 0;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100130 }
131 // The following functions should only be called if SanityCheck has
132 // returned true.
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800133 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; }
134 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; }
135 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100136
Steve Blocka7e24c12009-10-30 11:49:00 +0000137 private:
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100138 Vector<unsigned> store_;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100139 unsigned char* symbol_data_;
140 unsigned char* symbol_data_end_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100141 int function_index_;
Iain Merrick9ac36c92010-09-13 15:29:50 +0100142 bool owns_store_;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100143
Steve Blocka7e24c12009-10-30 11:49:00 +0000144 unsigned Read(int position);
145 unsigned* ReadAddress(int position);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100146 // Reads a number from the current symbols
147 int ReadNumber(byte** source);
Steve Blocka7e24c12009-10-30 11:49:00 +0000148
Iain Merrick9ac36c92010-09-13 15:29:50 +0100149 ScriptDataImpl(const char* backing_store, int length)
150 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)),
Ben Murdochf87a2032010-10-22 12:50:53 +0100151 length / static_cast<int>(sizeof(unsigned))),
Iain Merrick9ac36c92010-09-13 15:29:50 +0100152 owns_store_(false) {
Ben Murdochf87a2032010-10-22 12:50:53 +0100153 ASSERT_EQ(0, static_cast<int>(
154 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned)));
Iain Merrick9ac36c92010-09-13 15:29:50 +0100155 }
156
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100157 // Read strings written by ParserRecorder::WriteString.
158 static const char* ReadString(unsigned* start, int* chars);
Iain Merrick9ac36c92010-09-13 15:29:50 +0100159
160 friend class ScriptData;
Steve Blocka7e24c12009-10-30 11:49:00 +0000161};
162
163
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800164class ParserApi {
165 public:
Ben Murdochf87a2032010-10-22 12:50:53 +0100166 // Parses the source code represented by the compilation info and sets its
167 // function literal. Returns false (and deallocates any allocated AST
168 // nodes) if parsing failed.
169 static bool Parse(CompilationInfo* info);
Steve Blocka7e24c12009-10-30 11:49:00 +0000170
Ben Murdochf87a2032010-10-22 12:50:53 +0100171 // Generic preparser generating full preparse data.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100172 static ScriptDataImpl* PreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100173 v8::Extension* extension);
174
175 // Preparser that only does preprocessing that makes sense if only used
176 // immediately after.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100177 static ScriptDataImpl* PartialPreParse(UC16CharacterStream* source,
Ben Murdochf87a2032010-10-22 12:50:53 +0100178 v8::Extension* extension);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800179};
180
181// ----------------------------------------------------------------------------
182// REGEXP PARSING
183
184// A BuffferedZoneList is an automatically growing list, just like (and backed
185// by) a ZoneList, that is optimized for the case of adding and removing
186// a single element. The last element added is stored outside the backing list,
187// and if no more than one element is ever added, the ZoneList isn't even
188// allocated.
189// Elements must not be NULL pointers.
190template <typename T, int initial_size>
191class BufferedZoneList {
192 public:
193 BufferedZoneList() : list_(NULL), last_(NULL) {}
194
195 // Adds element at end of list. This element is buffered and can
196 // be read using last() or removed using RemoveLast until a new Add or until
197 // RemoveLast or GetList has been called.
198 void Add(T* value) {
199 if (last_ != NULL) {
200 if (list_ == NULL) {
201 list_ = new ZoneList<T*>(initial_size);
202 }
203 list_->Add(last_);
204 }
205 last_ = value;
206 }
207
208 T* last() {
209 ASSERT(last_ != NULL);
210 return last_;
211 }
212
213 T* RemoveLast() {
214 ASSERT(last_ != NULL);
215 T* result = last_;
216 if ((list_ != NULL) && (list_->length() > 0))
217 last_ = list_->RemoveLast();
218 else
219 last_ = NULL;
220 return result;
221 }
222
223 T* Get(int i) {
224 ASSERT((0 <= i) && (i < length()));
225 if (list_ == NULL) {
226 ASSERT_EQ(0, i);
227 return last_;
228 } else {
229 if (i == list_->length()) {
230 ASSERT(last_ != NULL);
231 return last_;
232 } else {
233 return list_->at(i);
234 }
235 }
236 }
237
238 void Clear() {
239 list_ = NULL;
240 last_ = NULL;
241 }
242
243 int length() {
244 int length = (list_ == NULL) ? 0 : list_->length();
245 return length + ((last_ == NULL) ? 0 : 1);
246 }
247
248 ZoneList<T*>* GetList() {
249 if (list_ == NULL) {
250 list_ = new ZoneList<T*>(initial_size);
251 }
252 if (last_ != NULL) {
253 list_->Add(last_);
254 last_ = NULL;
255 }
256 return list_;
257 }
258
259 private:
260 ZoneList<T*>* list_;
261 T* last_;
262};
263
264
265// Accumulates RegExp atoms and assertions into lists of terms and alternatives.
266class RegExpBuilder: public ZoneObject {
267 public:
268 RegExpBuilder();
269 void AddCharacter(uc16 character);
270 // "Adds" an empty expression. Does nothing except consume a
271 // following quantifier
272 void AddEmpty();
273 void AddAtom(RegExpTree* tree);
274 void AddAssertion(RegExpTree* tree);
275 void NewAlternative(); // '|'
276 void AddQuantifierToAtom(int min, int max, RegExpQuantifier::Type type);
277 RegExpTree* ToRegExp();
278
279 private:
280 void FlushCharacters();
281 void FlushText();
282 void FlushTerms();
Ben Murdoch8b112d22011-06-08 16:22:53 +0100283 Zone* zone() { return zone_; }
284
285 Zone* zone_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800286 bool pending_empty_;
287 ZoneList<uc16>* characters_;
288 BufferedZoneList<RegExpTree, 2> terms_;
289 BufferedZoneList<RegExpTree, 2> text_;
290 BufferedZoneList<RegExpTree, 2> alternatives_;
291#ifdef DEBUG
292 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_;
293#define LAST(x) last_added_ = x;
294#else
295#define LAST(x)
296#endif
297};
298
299
300class RegExpParser {
301 public:
302 RegExpParser(FlatStringReader* in,
303 Handle<String>* error,
304 bool multiline_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100305
306 static bool ParseRegExp(FlatStringReader* input,
307 bool multiline,
308 RegExpCompileData* result);
309
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800310 RegExpTree* ParsePattern();
311 RegExpTree* ParseDisjunction();
312 RegExpTree* ParseGroup();
313 RegExpTree* ParseCharacterClass();
Ben Murdochf87a2032010-10-22 12:50:53 +0100314
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800315 // Parses a {...,...} quantifier and stores the range in the given
316 // out parameters.
317 bool ParseIntervalQuantifier(int* min_out, int* max_out);
Steve Block59151502010-09-22 15:07:15 +0100318
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800319 // Parses and returns a single escaped character. The character
320 // must not be 'b' or 'B' since they are usually handle specially.
321 uc32 ParseClassCharacterEscape();
322
323 // Checks whether the following is a length-digit hexadecimal number,
324 // and sets the value if it is.
325 bool ParseHexEscape(int length, uc32* value);
326
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800327 uc32 ParseOctalLiteral();
328
329 // Tries to parse the input as a back reference. If successful it
330 // stores the result in the output parameter and returns true. If
331 // it fails it will push back the characters read so the same characters
332 // can be reparsed.
333 bool ParseBackReferenceIndex(int* index_out);
334
335 CharacterRange ParseClassAtom(uc16* char_class);
336 RegExpTree* ReportError(Vector<const char> message);
337 void Advance();
338 void Advance(int dist);
339 void Reset(int pos);
340
341 // Reports whether the pattern might be used as a literal search string.
342 // Only use if the result of the parse is a single atom node.
343 bool simple();
344 bool contains_anchor() { return contains_anchor_; }
345 void set_contains_anchor() { contains_anchor_ = true; }
346 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); }
347 int position() { return next_pos_ - 1; }
348 bool failed() { return failed_; }
349
350 static const int kMaxCaptures = 1 << 16;
351 static const uc32 kEndMarker = (1 << 21);
352
353 private:
354 enum SubexpressionType {
355 INITIAL,
356 CAPTURE, // All positive values represent captures.
357 POSITIVE_LOOKAHEAD,
358 NEGATIVE_LOOKAHEAD,
359 GROUPING
360 };
361
362 class RegExpParserState : public ZoneObject {
363 public:
364 RegExpParserState(RegExpParserState* previous_state,
365 SubexpressionType group_type,
366 int disjunction_capture_index)
367 : previous_state_(previous_state),
368 builder_(new RegExpBuilder()),
369 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
Steve Block44f0eee2011-05-26 01:26:41 +0100394 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100395 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100396
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800397 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();
403
Steve Block44f0eee2011-05-26 01:26:41 +0100404 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800405 Handle<String>* error_;
406 ZoneList<RegExpCapture*>* captures_;
407 FlatStringReader* in_;
408 uc32 current_;
409 int next_pos_;
410 // The capture count is only valid after we have scanned for captures.
411 int capture_count_;
412 bool has_more_;
413 bool multiline_;
414 bool simple_;
415 bool contains_anchor_;
416 bool is_scanned_for_captures_;
417 bool failed_;
418};
419
420// ----------------------------------------------------------------------------
421// JAVASCRIPT PARSING
422
423class Parser {
424 public:
425 Parser(Handle<Script> script,
426 bool allow_natives_syntax,
427 v8::Extension* extension,
428 ScriptDataImpl* pre_data);
429 virtual ~Parser() { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000430
Ben Murdochf87a2032010-10-22 12:50:53 +0100431 // Returns NULL if parsing failed.
432 FunctionLiteral* ParseProgram(Handle<String> source,
Steve Block1e0659c2011-05-24 12:43:12 +0100433 bool in_global_context,
434 StrictModeFlag strict_mode);
Ben Murdochf87a2032010-10-22 12:50:53 +0100435
Steve Block44f0eee2011-05-26 01:26:41 +0100436 FunctionLiteral* ParseLazy(CompilationInfo* info);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800437
438 void ReportMessageAt(Scanner::Location loc,
439 const char* message,
440 Vector<const char*> args);
Ben Murdochb8e0da22011-05-16 14:20:40 +0100441 void ReportMessageAt(Scanner::Location loc,
442 const char* message,
443 Vector<Handle<String> > args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100444
445 protected:
Steve Block1e0659c2011-05-24 12:43:12 +0100446 // Limit on number of function parameters is chosen arbitrarily.
447 // Code::Flags uses only the low 17 bits of num-parameters to
448 // construct a hashable id, so if more than 2^17 are allowed, this
449 // should be checked.
450 static const int kMaxNumFunctionParameters = 32766;
Steve Block44f0eee2011-05-26 01:26:41 +0100451 FunctionLiteral* ParseLazy(CompilationInfo* info,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100452 UC16CharacterStream* source,
453 ZoneScope* zone_scope);
Ben Murdochf87a2032010-10-22 12:50:53 +0100454 enum Mode {
455 PARSE_LAZILY,
456 PARSE_EAGERLY
457 };
458
Steve Block44f0eee2011-05-26 01:26:41 +0100459 Isolate* isolate() { return isolate_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100460 Zone* zone() { return isolate_->zone(); }
Steve Block44f0eee2011-05-26 01:26:41 +0100461
Ben Murdochb0fe1622011-05-05 13:52:32 +0100462 // Called by ParseProgram after setting up the scanner.
463 FunctionLiteral* DoParseProgram(Handle<String> source,
464 bool in_global_context,
Steve Block1e0659c2011-05-24 12:43:12 +0100465 StrictModeFlag strict_mode,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100466 ZoneScope* zone_scope);
467
Ben Murdochf87a2032010-10-22 12:50:53 +0100468 // Report syntax error
469 void ReportUnexpectedToken(Token::Value token);
470 void ReportInvalidPreparseData(Handle<String> name, bool* ok);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800471 void ReportMessage(const char* message, Vector<const char*> args);
Ben Murdochf87a2032010-10-22 12:50:53 +0100472
473 bool inside_with() const { return with_nesting_level_ > 0; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100474 V8JavaScriptScanner& scanner() { return scanner_; }
Ben Murdochf87a2032010-10-22 12:50:53 +0100475 Mode mode() const { return mode_; }
476 ScriptDataImpl* pre_data() const { return pre_data_; }
477
Steve Block44f0eee2011-05-26 01:26:41 +0100478 // Check if the given string is 'eval' or 'arguments'.
479 bool IsEvalOrArguments(Handle<String> string);
480
Ben Murdochf87a2032010-10-22 12:50:53 +0100481 // All ParseXXX functions take as the last argument an *ok parameter
482 // which is set to false if parsing failed; it is unchanged otherwise.
483 // By making the 'exception handling' explicit, we are forced to check
484 // for failure at the call sites.
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800485 void* ParseSourceElements(ZoneList<Statement*>* processor,
Ben Murdochf87a2032010-10-22 12:50:53 +0100486 int end_token, bool* ok);
487 Statement* ParseStatement(ZoneStringList* labels, bool* ok);
488 Statement* ParseFunctionDeclaration(bool* ok);
489 Statement* ParseNativeDeclaration(bool* ok);
490 Block* ParseBlock(ZoneStringList* labels, bool* ok);
491 Block* ParseVariableStatement(bool* ok);
492 Block* ParseVariableDeclarations(bool accept_IN, Expression** var, bool* ok);
493 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels,
494 bool* ok);
495 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok);
496 Statement* ParseContinueStatement(bool* ok);
497 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok);
498 Statement* ParseReturnStatement(bool* ok);
499 Block* WithHelper(Expression* obj,
500 ZoneStringList* labels,
501 bool is_catch_block,
502 bool* ok);
503 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok);
504 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok);
505 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok);
506 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok);
507 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok);
508 Statement* ParseForStatement(ZoneStringList* labels, bool* ok);
509 Statement* ParseThrowStatement(bool* ok);
510 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value);
511 TryStatement* ParseTryStatement(bool* ok);
512 DebuggerStatement* ParseDebuggerStatement(bool* ok);
513
514 Expression* ParseExpression(bool accept_IN, bool* ok);
515 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok);
516 Expression* ParseConditionalExpression(bool accept_IN, bool* ok);
517 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok);
518 Expression* ParseUnaryExpression(bool* ok);
519 Expression* ParsePostfixExpression(bool* ok);
520 Expression* ParseLeftHandSideExpression(bool* ok);
521 Expression* ParseNewExpression(bool* ok);
522 Expression* ParseMemberExpression(bool* ok);
523 Expression* ParseNewPrefix(PositionStack* stack, bool* ok);
524 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack,
525 bool* ok);
526 Expression* ParsePrimaryExpression(bool* ok);
527 Expression* ParseArrayLiteral(bool* ok);
528 Expression* ParseObjectLiteral(bool* ok);
529 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok);
530 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok);
531
532 Expression* NewCompareNode(Token::Value op,
533 Expression* x,
534 Expression* y,
535 int position);
536
537 // Populate the constant properties fixed array for a materialized object
538 // literal.
539 void BuildObjectLiteralConstantProperties(
540 ZoneList<ObjectLiteral::Property*>* properties,
541 Handle<FixedArray> constants,
542 bool* is_simple,
543 bool* fast_elements,
544 int* depth);
545
546 // Populate the literals fixed array for a materialized array literal.
547 void BuildArrayLiteralBoilerplateLiterals(ZoneList<Expression*>* properties,
548 Handle<FixedArray> constants,
549 bool* is_simple,
550 int* depth);
551
552 // Decide if a property should be in the object boilerplate.
553 bool IsBoilerplateProperty(ObjectLiteral::Property* property);
554 // If the expression is a literal, return the literal value;
555 // if the expression is a materialized literal and is simple return a
556 // compile time value as encoded by CompileTimeValue::GetValue().
557 // Otherwise, return undefined literal as the placeholder
558 // in the object literal boilerplate.
559 Handle<Object> GetBoilerplateValue(Expression* expression);
560
561 enum FunctionLiteralType {
562 EXPRESSION,
563 DECLARATION,
564 NESTED
565 };
566
567 ZoneList<Expression*>* ParseArguments(bool* ok);
568 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name,
Steve Block1e0659c2011-05-24 12:43:12 +0100569 bool name_is_reserved,
Ben Murdochf87a2032010-10-22 12:50:53 +0100570 int function_token_position,
571 FunctionLiteralType type,
572 bool* ok);
Steve Blocka7e24c12009-10-30 11:49:00 +0000573
574
Ben Murdochf87a2032010-10-22 12:50:53 +0100575 // Magical syntax support.
576 Expression* ParseV8Intrinsic(bool* ok);
577
Ben Murdochb0fe1622011-05-05 13:52:32 +0100578 INLINE(Token::Value peek()) {
579 if (stack_overflow_) return Token::ILLEGAL;
580 return scanner().peek();
581 }
582
583 INLINE(Token::Value Next()) {
584 // BUG 1215673: Find a thread safe way to set a stack limit in
585 // pre-parse mode. Otherwise, we cannot safely pre-parse from other
586 // threads.
587 if (stack_overflow_) {
588 return Token::ILLEGAL;
589 }
Steve Block44f0eee2011-05-26 01:26:41 +0100590 if (StackLimitCheck(isolate()).HasOverflowed()) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100591 // Any further calls to Next or peek will return the illegal token.
592 // The current call must return the next token, which might already
593 // have been peek'ed.
594 stack_overflow_ = true;
595 }
596 return scanner().Next();
597 }
598
Steve Block1e0659c2011-05-24 12:43:12 +0100599 bool peek_any_identifier();
600
Ben Murdochf87a2032010-10-22 12:50:53 +0100601 INLINE(void Consume(Token::Value token));
602 void Expect(Token::Value token, bool* ok);
603 bool Check(Token::Value token);
604 void ExpectSemicolon(bool* ok);
605
Steve Block9fac8402011-05-12 15:51:54 +0100606 Handle<String> LiteralString(PretenureFlag tenured) {
607 if (scanner().is_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100608 return isolate_->factory()->NewStringFromAscii(
609 scanner().literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100610 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100611 return isolate_->factory()->NewStringFromTwoByte(
612 scanner().literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100613 }
614 }
615
616 Handle<String> NextLiteralString(PretenureFlag tenured) {
617 if (scanner().is_next_literal_ascii()) {
Steve Block44f0eee2011-05-26 01:26:41 +0100618 return isolate_->factory()->NewStringFromAscii(
619 scanner().next_literal_ascii_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100620 } else {
Steve Block44f0eee2011-05-26 01:26:41 +0100621 return isolate_->factory()->NewStringFromTwoByte(
622 scanner().next_literal_uc16_string(), tenured);
Steve Block9fac8402011-05-12 15:51:54 +0100623 }
624 }
625
Ben Murdochf87a2032010-10-22 12:50:53 +0100626 Handle<String> GetSymbol(bool* ok);
627
628 // Get odd-ball literals.
629 Literal* GetLiteralUndefined();
630 Literal* GetLiteralTheHole();
631 Literal* GetLiteralNumber(double value);
632
633 Handle<String> ParseIdentifier(bool* ok);
Steve Block1e0659c2011-05-24 12:43:12 +0100634 Handle<String> ParseIdentifierOrReservedWord(bool* is_reserved, bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100635 Handle<String> ParseIdentifierName(bool* ok);
636 Handle<String> ParseIdentifierOrGetOrSet(bool* is_get,
637 bool* is_set,
638 bool* ok);
639
Steve Block1e0659c2011-05-24 12:43:12 +0100640 // Strict mode validation of LValue expressions
641 void CheckStrictModeLValue(Expression* expression,
642 const char* error,
643 bool* ok);
644
645 // Strict mode octal literal validation.
646 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok);
647
Ben Murdochf87a2032010-10-22 12:50:53 +0100648 // Parser support
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800649 VariableProxy* Declare(Handle<String> name, Variable::Mode mode,
650 FunctionLiteral* fun,
651 bool resolve,
652 bool* ok);
Ben Murdochf87a2032010-10-22 12:50:53 +0100653
654 bool TargetStackContainsLabel(Handle<String> label);
655 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok);
656 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok);
657
Ben Murdoch8b112d22011-06-08 16:22:53 +0100658 void RegisterTargetUse(Label* target, Target* stop);
Ben Murdochf87a2032010-10-22 12:50:53 +0100659
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800660 // Factory methods.
661
662 Statement* EmptyStatement() {
663 static v8::internal::EmptyStatement empty;
664 return &empty;
665 }
666
667 Scope* NewScope(Scope* parent, Scope::Type type, bool inside_with);
668
Steve Block9fac8402011-05-12 15:51:54 +0100669 Handle<String> LookupSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800670
Steve Block9fac8402011-05-12 15:51:54 +0100671 Handle<String> LookupCachedSymbol(int symbol_id);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800672
673 Expression* NewCall(Expression* expression,
674 ZoneList<Expression*>* arguments,
675 int pos) {
676 return new Call(expression, arguments, pos);
677 }
678
679
Ben Murdochf87a2032010-10-22 12:50:53 +0100680 // Create a number literal.
681 Literal* NewNumberLiteral(double value);
682
683 // Generate AST node that throw a ReferenceError with the given type.
684 Expression* NewThrowReferenceError(Handle<String> type);
685
686 // Generate AST node that throw a SyntaxError with the given
687 // type. The first argument may be null (in the handle sense) in
688 // which case no arguments are passed to the constructor.
689 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first);
690
691 // Generate AST node that throw a TypeError with the given
692 // type. Both arguments must be non-null (in the handle sense).
693 Expression* NewThrowTypeError(Handle<String> type,
694 Handle<Object> first,
695 Handle<Object> second);
696
697 // Generic AST generator for throwing errors from compiled code.
698 Expression* NewThrowError(Handle<String> constructor,
699 Handle<String> type,
700 Vector< Handle<Object> > arguments);
701
Steve Block44f0eee2011-05-26 01:26:41 +0100702 Isolate* isolate_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800703 ZoneList<Handle<String> > symbol_cache_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100704
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800705 Handle<Script> script_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800706 V8JavaScriptScanner scanner_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100707
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800708 Scope* top_scope_;
709 int with_nesting_level_;
Ben Murdochf87a2032010-10-22 12:50:53 +0100710
Steve Block44f0eee2011-05-26 01:26:41 +0100711 LexicalScope* lexical_scope_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800712 Mode mode_;
713
714 Target* target_stack_; // for break, continue statements
715 bool allow_natives_syntax_;
716 v8::Extension* extension_;
717 bool is_pre_parsing_;
718 ScriptDataImpl* pre_data_;
719 FuncNameInferrer* fni_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100720 bool stack_overflow_;
Ben Murdochb8e0da22011-05-16 14:20:40 +0100721 // If true, the next (and immediately following) function literal is
722 // preceded by a parenthesis.
723 // Heuristically that means that the function will be called immediately,
724 // so never lazily compile it.
725 bool parenthesized_function_;
Steve Block44f0eee2011-05-26 01:26:41 +0100726
727 friend class LexicalScope;
Ben Murdochf87a2032010-10-22 12:50:53 +0100728};
Steve Blocka7e24c12009-10-30 11:49:00 +0000729
730
731// Support for handling complex values (array and object literals) that
732// can be fully handled at compile time.
733class CompileTimeValue: public AllStatic {
734 public:
735 enum Type {
Steve Block6ded16b2010-05-10 14:33:55 +0100736 OBJECT_LITERAL_FAST_ELEMENTS,
737 OBJECT_LITERAL_SLOW_ELEMENTS,
Steve Blocka7e24c12009-10-30 11:49:00 +0000738 ARRAY_LITERAL
739 };
740
741 static bool IsCompileTimeValue(Expression* expression);
742
Iain Merrick75681382010-08-19 15:07:18 +0100743 static bool ArrayLiteralElementNeedsInitialization(Expression* value);
744
Steve Blocka7e24c12009-10-30 11:49:00 +0000745 // Get the value as a compile time value.
746 static Handle<FixedArray> GetValue(Expression* expression);
747
748 // Get the type of a compile time value returned by GetValue().
749 static Type GetType(Handle<FixedArray> value);
750
751 // Get the elements array of a compile time value returned by GetValue().
752 static Handle<FixedArray> GetElements(Handle<FixedArray> value);
753
754 private:
755 static const int kTypeSlot = 0;
756 static const int kElementsSlot = 1;
757
758 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue);
759};
760
761
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800762// ----------------------------------------------------------------------------
763// JSON PARSING
764
765// JSON is a subset of JavaScript, as specified in, e.g., the ECMAScript 5
766// specification section 15.12.1 (and appendix A.8).
767// The grammar is given section 15.12.1.2 (and appendix A.8.2).
768class JsonParser BASE_EMBEDDED {
769 public:
770 // Parse JSON input as a single JSON value.
771 // Returns null handle and sets exception if parsing failed.
772 static Handle<Object> Parse(Handle<String> source) {
Ben Murdochb0fe1622011-05-05 13:52:32 +0100773 if (source->IsExternalTwoByteString()) {
774 ExternalTwoByteStringUC16CharacterStream stream(
775 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
776 return JsonParser().ParseJson(source, &stream);
777 } else {
778 GenericStringUC16CharacterStream stream(source, 0, source->length());
779 return JsonParser().ParseJson(source, &stream);
780 }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800781 }
782
783 private:
Steve Block44f0eee2011-05-26 01:26:41 +0100784 JsonParser()
785 : isolate_(Isolate::Current()),
Ben Murdoch8b112d22011-06-08 16:22:53 +0100786 scanner_(isolate_->unicode_cache()) { }
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800787 ~JsonParser() { }
788
Steve Block44f0eee2011-05-26 01:26:41 +0100789 Isolate* isolate() { return isolate_; }
790
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800791 // Parse a string containing a single JSON value.
Ben Murdochb0fe1622011-05-05 13:52:32 +0100792 Handle<Object> ParseJson(Handle<String> script, UC16CharacterStream* source);
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800793 // Parse a single JSON value from input (grammar production JSONValue).
794 // A JSON value is either a (double-quoted) string literal, a number literal,
795 // one of "true", "false", or "null", or an object or array literal.
796 Handle<Object> ParseJsonValue();
797 // Parse a JSON object literal (grammar production JSONObject).
798 // An object literal is a squiggly-braced and comma separated sequence
799 // (possibly empty) of key/value pairs, where the key is a JSON string
800 // literal, the value is a JSON value, and the two are separated by a colon.
801 // A JSON array dosn't allow numbers and identifiers as keys, like a
802 // JavaScript array.
803 Handle<Object> ParseJsonObject();
804 // Parses a JSON array literal (grammar production JSONArray). An array
805 // literal is a square-bracketed and comma separated sequence (possibly empty)
806 // of JSON values.
807 // A JSON array doesn't allow leaving out values from the sequence, nor does
808 // it allow a terminal comma, like a JavaScript array does.
809 Handle<Object> ParseJsonArray();
810
811 // Mark that a parsing error has happened at the current token, and
812 // return a null handle. Primarily for readability.
813 Handle<Object> ReportUnexpectedToken() { return Handle<Object>::null(); }
814 // Converts the currently parsed literal to a JavaScript String.
815 Handle<String> GetString();
816
Steve Block44f0eee2011-05-26 01:26:41 +0100817 Isolate* isolate_;
Shimeng (Simon) Wang8a31eba2010-12-06 19:01:33 -0800818 JsonScanner scanner_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100819 bool stack_overflow_;
Teng-Hui Zhu3e5fa292010-11-09 16:16:48 -0800820};
Steve Blocka7e24c12009-10-30 11:49:00 +0000821} } // namespace v8::internal
822
823#endif // V8_PARSER_H_