1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // 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 31 #include "allocation.h" 32 #include "ast.h" 33 #include "preparse-data-format.h" 34 #include "preparse-data.h" 35 #include "scopes.h" 36 #include "preparser.h" 37 38 namespace v8 { 39 namespace internal { 40 41 class CompilationInfo; 42 class FuncNameInferrer; 43 class ParserLog; 44 class PositionStack; 45 class Target; 46 47 template <typename T> class ZoneListWrapper; 48 49 50 class 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 68 class FunctionEntry BASE_EMBEDDED { 69 public: 70 enum { 71 kStartPositionIndex, 72 kEndPositionIndex, 73 kLiteralCountIndex, 74 kPropertyCountIndex, 75 kLanguageModeIndex, 76 kSize 77 }; 78 79 explicit FunctionEntry(Vector<unsigned> backing) 80 : backing_(backing) { } 81 82 FunctionEntry() : backing_() { } 83 84 int start_pos() { return backing_[kStartPositionIndex]; } 85 int end_pos() { return backing_[kEndPositionIndex]; } 86 int literal_count() { return backing_[kLiteralCountIndex]; } 87 int property_count() { return backing_[kPropertyCountIndex]; } 88 LanguageMode language_mode() { 89 ASSERT(backing_[kLanguageModeIndex] == CLASSIC_MODE || 90 backing_[kLanguageModeIndex] == STRICT_MODE || 91 backing_[kLanguageModeIndex] == EXTENDED_MODE); 92 return static_cast<LanguageMode>(backing_[kLanguageModeIndex]); 93 } 94 95 bool is_valid() { return !backing_.is_empty(); } 96 97 private: 98 Vector<unsigned> backing_; 99 }; 100 101 102 class ScriptDataImpl : public ScriptData { 103 public: 104 explicit ScriptDataImpl(Vector<unsigned> store) 105 : store_(store), 106 owns_store_(true) { } 107 108 // Create an empty ScriptDataImpl that is guaranteed to not satisfy 109 // a SanityCheck. 110 ScriptDataImpl() : owns_store_(false) { } 111 112 virtual ~ScriptDataImpl(); 113 virtual int Length(); 114 virtual const char* Data(); 115 virtual bool HasError(); 116 117 void Initialize(); 118 void ReadNextSymbolPosition(); 119 120 FunctionEntry GetFunctionEntry(int start); 121 int GetSymbolIdentifier(); 122 bool SanityCheck(); 123 124 Scanner::Location MessageLocation(); 125 const char* BuildMessage(); 126 Vector<const char*> BuildArgs(); 127 128 int symbol_count() { 129 return (store_.length() > PreparseDataConstants::kHeaderSize) 130 ? store_[PreparseDataConstants::kSymbolCountOffset] 131 : 0; 132 } 133 // The following functions should only be called if SanityCheck has 134 // returned true. 135 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; } 136 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; } 137 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; } 138 139 private: 140 Vector<unsigned> store_; 141 unsigned char* symbol_data_; 142 unsigned char* symbol_data_end_; 143 int function_index_; 144 bool owns_store_; 145 146 unsigned Read(int position); 147 unsigned* ReadAddress(int position); 148 // Reads a number from the current symbols 149 int ReadNumber(byte** source); 150 151 ScriptDataImpl(const char* backing_store, int length) 152 : store_(reinterpret_cast<unsigned*>(const_cast<char*>(backing_store)), 153 length / static_cast<int>(sizeof(unsigned))), 154 owns_store_(false) { 155 ASSERT_EQ(0, static_cast<int>( 156 reinterpret_cast<intptr_t>(backing_store) % sizeof(unsigned))); 157 } 158 159 // Read strings written by ParserRecorder::WriteString. 160 static const char* ReadString(unsigned* start, int* chars); 161 162 friend class ScriptData; 163 }; 164 165 166 class PreParserApi { 167 public: 168 // Pre-parse a character stream and return full preparse data. 169 // 170 // This interface is here instead of in preparser.h because it instantiates a 171 // preparser recorder object that is suited to the parser's purposes. Also, 172 // the preparser doesn't know about ScriptDataImpl. 173 static ScriptDataImpl* PreParse(Utf16CharacterStream* source); 174 }; 175 176 177 // ---------------------------------------------------------------------------- 178 // REGEXP PARSING 179 180 // A BufferedZoneList is an automatically growing list, just like (and backed 181 // by) a ZoneList, that is optimized for the case of adding and removing 182 // a single element. The last element added is stored outside the backing list, 183 // and if no more than one element is ever added, the ZoneList isn't even 184 // allocated. 185 // Elements must not be NULL pointers. 186 template <typename T, int initial_size> 187 class BufferedZoneList { 188 public: 189 BufferedZoneList() : list_(NULL), last_(NULL) {} 190 191 // Adds element at end of list. This element is buffered and can 192 // be read using last() or removed using RemoveLast until a new Add or until 193 // RemoveLast or GetList has been called. 194 void Add(T* value, Zone* zone) { 195 if (last_ != NULL) { 196 if (list_ == NULL) { 197 list_ = new(zone) ZoneList<T*>(initial_size, zone); 198 } 199 list_->Add(last_, zone); 200 } 201 last_ = value; 202 } 203 204 T* last() { 205 ASSERT(last_ != NULL); 206 return last_; 207 } 208 209 T* RemoveLast() { 210 ASSERT(last_ != NULL); 211 T* result = last_; 212 if ((list_ != NULL) && (list_->length() > 0)) 213 last_ = list_->RemoveLast(); 214 else 215 last_ = NULL; 216 return result; 217 } 218 219 T* Get(int i) { 220 ASSERT((0 <= i) && (i < length())); 221 if (list_ == NULL) { 222 ASSERT_EQ(0, i); 223 return last_; 224 } else { 225 if (i == list_->length()) { 226 ASSERT(last_ != NULL); 227 return last_; 228 } else { 229 return list_->at(i); 230 } 231 } 232 } 233 234 void Clear() { 235 list_ = NULL; 236 last_ = NULL; 237 } 238 239 int length() { 240 int length = (list_ == NULL) ? 0 : list_->length(); 241 return length + ((last_ == NULL) ? 0 : 1); 242 } 243 244 ZoneList<T*>* GetList(Zone* zone) { 245 if (list_ == NULL) { 246 list_ = new(zone) ZoneList<T*>(initial_size, zone); 247 } 248 if (last_ != NULL) { 249 list_->Add(last_, zone); 250 last_ = NULL; 251 } 252 return list_; 253 } 254 255 private: 256 ZoneList<T*>* list_; 257 T* last_; 258 }; 259 260 261 // Accumulates RegExp atoms and assertions into lists of terms and alternatives. 262 class RegExpBuilder: public ZoneObject { 263 public: 264 explicit RegExpBuilder(Zone* zone); 265 void AddCharacter(uc16 character); 266 // "Adds" an empty expression. Does nothing except consume a 267 // following quantifier 268 void AddEmpty(); 269 void AddAtom(RegExpTree* tree); 270 void AddAssertion(RegExpTree* tree); 271 void NewAlternative(); // '|' 272 void AddQuantifierToAtom( 273 int min, int max, RegExpQuantifier::QuantifierType type); 274 RegExpTree* ToRegExp(); 275 276 private: 277 void FlushCharacters(); 278 void FlushText(); 279 void FlushTerms(); 280 Zone* zone() const { return zone_; } 281 282 Zone* zone_; 283 bool pending_empty_; 284 ZoneList<uc16>* characters_; 285 BufferedZoneList<RegExpTree, 2> terms_; 286 BufferedZoneList<RegExpTree, 2> text_; 287 BufferedZoneList<RegExpTree, 2> alternatives_; 288 #ifdef DEBUG 289 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_; 290 #define LAST(x) last_added_ = x; 291 #else 292 #define LAST(x) 293 #endif 294 }; 295 296 297 class RegExpParser BASE_EMBEDDED { 298 public: 299 RegExpParser(FlatStringReader* in, 300 Handle<String>* error, 301 bool multiline_mode, 302 Zone* zone); 303 304 static bool ParseRegExp(FlatStringReader* input, 305 bool multiline, 306 RegExpCompileData* result, 307 Zone* zone); 308 309 RegExpTree* ParsePattern(); 310 RegExpTree* ParseDisjunction(); 311 RegExpTree* ParseGroup(); 312 RegExpTree* ParseCharacterClass(); 313 314 // Parses a {...,...} quantifier and stores the range in the given 315 // out parameters. 316 bool ParseIntervalQuantifier(int* min_out, int* max_out); 317 318 // Parses and returns a single escaped character. The character 319 // must not be 'b' or 'B' since they are usually handle specially. 320 uc32 ParseClassCharacterEscape(); 321 322 // Checks whether the following is a length-digit hexadecimal number, 323 // and sets the value if it is. 324 bool ParseHexEscape(int length, uc32* value); 325 326 uc32 ParseOctalLiteral(); 327 328 // Tries to parse the input as a back reference. If successful it 329 // stores the result in the output parameter and returns true. If 330 // it fails it will push back the characters read so the same characters 331 // can be reparsed. 332 bool ParseBackReferenceIndex(int* index_out); 333 334 CharacterRange ParseClassAtom(uc16* char_class); 335 RegExpTree* ReportError(Vector<const char> message); 336 void Advance(); 337 void Advance(int dist); 338 void Reset(int pos); 339 340 // Reports whether the pattern might be used as a literal search string. 341 // Only use if the result of the parse is a single atom node. 342 bool simple(); 343 bool contains_anchor() { return contains_anchor_; } 344 void set_contains_anchor() { contains_anchor_ = true; } 345 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } 346 int position() { return next_pos_ - 1; } 347 bool failed() { return failed_; } 348 349 static const int kMaxCaptures = 1 << 16; 350 static const uc32 kEndMarker = (1 << 21); 351 352 private: 353 enum SubexpressionType { 354 INITIAL, 355 CAPTURE, // All positive values represent captures. 356 POSITIVE_LOOKAHEAD, 357 NEGATIVE_LOOKAHEAD, 358 GROUPING 359 }; 360 361 class RegExpParserState : public ZoneObject { 362 public: 363 RegExpParserState(RegExpParserState* previous_state, 364 SubexpressionType group_type, 365 int disjunction_capture_index, 366 Zone* zone) 367 : previous_state_(previous_state), 368 builder_(new(zone) RegExpBuilder(zone)), 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 394 Isolate* isolate() { return isolate_; } 395 Zone* zone() const { return zone_; } 396 397 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 404 Isolate* isolate_; 405 Zone* zone_; 406 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 424 // Forward declaration. 425 class SingletonLogger; 426 427 class Parser BASE_EMBEDDED { 428 public: 429 explicit Parser(CompilationInfo* info); 430 ~Parser() { 431 delete reusable_preparser_; 432 reusable_preparser_ = NULL; 433 } 434 435 bool allow_natives_syntax() const { return allow_natives_syntax_; } 436 bool allow_lazy() const { return allow_lazy_; } 437 bool allow_modules() { return scanner().HarmonyModules(); } 438 bool allow_harmony_scoping() { return scanner().HarmonyScoping(); } 439 bool allow_generators() const { return allow_generators_; } 440 bool allow_for_of() const { return allow_for_of_; } 441 bool allow_harmony_numeric_literals() { 442 return scanner().HarmonyNumericLiterals(); 443 } 444 445 void set_allow_natives_syntax(bool allow) { allow_natives_syntax_ = allow; } 446 void set_allow_lazy(bool allow) { allow_lazy_ = allow; } 447 void set_allow_modules(bool allow) { scanner().SetHarmonyModules(allow); } 448 void set_allow_harmony_scoping(bool allow) { 449 scanner().SetHarmonyScoping(allow); 450 } 451 void set_allow_generators(bool allow) { allow_generators_ = allow; } 452 void set_allow_for_of(bool allow) { allow_for_of_ = allow; } 453 void set_allow_harmony_numeric_literals(bool allow) { 454 scanner().SetHarmonyNumericLiterals(allow); 455 } 456 457 // Parses the source code represented by the compilation info and sets its 458 // function literal. Returns false (and deallocates any allocated AST 459 // nodes) if parsing failed. 460 static bool Parse(CompilationInfo* info) { return Parser(info).Parse(); } 461 bool Parse(); 462 463 // Returns NULL if parsing failed. 464 FunctionLiteral* ParseProgram(); 465 466 void ReportMessageAt(Scanner::Location loc, 467 const char* message, 468 Vector<const char*> args); 469 void ReportMessageAt(Scanner::Location loc, 470 const char* message, 471 Vector<Handle<String> > args); 472 473 private: 474 static const int kMaxNumFunctionLocals = 131071; // 2^17-1 475 476 enum Mode { 477 PARSE_LAZILY, 478 PARSE_EAGERLY 479 }; 480 481 enum VariableDeclarationContext { 482 kModuleElement, 483 kBlockElement, 484 kStatement, 485 kForStatement 486 }; 487 488 // If a list of variable declarations includes any initializers. 489 enum VariableDeclarationProperties { 490 kHasInitializers, 491 kHasNoInitializers 492 }; 493 494 class BlockState; 495 496 class FunctionState BASE_EMBEDDED { 497 public: 498 FunctionState(Parser* parser, 499 Scope* scope, 500 Isolate* isolate); 501 ~FunctionState(); 502 503 int NextMaterializedLiteralIndex() { 504 return next_materialized_literal_index_++; 505 } 506 int materialized_literal_count() { 507 return next_materialized_literal_index_ - JSFunction::kLiteralsPrefixSize; 508 } 509 510 int NextHandlerIndex() { return next_handler_index_++; } 511 int handler_count() { return next_handler_index_; } 512 513 void AddProperty() { expected_property_count_++; } 514 int expected_property_count() { return expected_property_count_; } 515 516 void set_generator_object_variable(Variable *variable) { 517 ASSERT(variable != NULL); 518 ASSERT(!is_generator()); 519 generator_object_variable_ = variable; 520 } 521 Variable* generator_object_variable() const { 522 return generator_object_variable_; 523 } 524 bool is_generator() const { 525 return generator_object_variable_ != NULL; 526 } 527 528 AstNodeFactory<AstConstructionVisitor>* factory() { return &factory_; } 529 530 private: 531 // Used to assign an index to each literal that needs materialization in 532 // the function. Includes regexp literals, and boilerplate for object and 533 // array literals. 534 int next_materialized_literal_index_; 535 536 // Used to assign a per-function index to try and catch handlers. 537 int next_handler_index_; 538 539 // Properties count estimation. 540 int expected_property_count_; 541 542 // For generators, the variable that holds the generator object. This 543 // variable is used by yield expressions and return statements. NULL 544 // indicates that this function is not a generator. 545 Variable* generator_object_variable_; 546 547 Parser* parser_; 548 FunctionState* outer_function_state_; 549 Scope* outer_scope_; 550 int saved_ast_node_id_; 551 AstNodeFactory<AstConstructionVisitor> factory_; 552 }; 553 554 class ParsingModeScope BASE_EMBEDDED { 555 public: 556 ParsingModeScope(Parser* parser, Mode mode) 557 : parser_(parser), 558 old_mode_(parser->mode()) { 559 parser_->mode_ = mode; 560 } 561 ~ParsingModeScope() { 562 parser_->mode_ = old_mode_; 563 } 564 565 private: 566 Parser* parser_; 567 Mode old_mode_; 568 }; 569 570 FunctionLiteral* ParseLazy(); 571 FunctionLiteral* ParseLazy(Utf16CharacterStream* source); 572 573 Isolate* isolate() { return isolate_; } 574 Zone* zone() const { return zone_; } 575 CompilationInfo* info() const { return info_; } 576 577 // Called by ParseProgram after setting up the scanner. 578 FunctionLiteral* DoParseProgram(CompilationInfo* info, 579 Handle<String> source); 580 581 // Report syntax error 582 void ReportUnexpectedToken(Token::Value token); 583 void ReportInvalidPreparseData(Handle<String> name, bool* ok); 584 void ReportMessage(const char* message, Vector<const char*> args); 585 void ReportMessage(const char* message, Vector<Handle<String> > args); 586 587 void set_pre_parse_data(ScriptDataImpl *data) { 588 pre_parse_data_ = data; 589 symbol_cache_.Initialize(data ? data->symbol_count() : 0, zone()); 590 } 591 592 bool inside_with() const { return top_scope_->inside_with(); } 593 Scanner& scanner() { return scanner_; } 594 Mode mode() const { return mode_; } 595 ScriptDataImpl* pre_parse_data() const { return pre_parse_data_; } 596 bool is_extended_mode() { 597 ASSERT(top_scope_ != NULL); 598 return top_scope_->is_extended_mode(); 599 } 600 Scope* DeclarationScope(VariableMode mode) { 601 return IsLexicalVariableMode(mode) 602 ? top_scope_ : top_scope_->DeclarationScope(); 603 } 604 605 // Check if the given string is 'eval' or 'arguments'. 606 bool IsEvalOrArguments(Handle<String> string); 607 608 // All ParseXXX functions take as the last argument an *ok parameter 609 // which is set to false if parsing failed; it is unchanged otherwise. 610 // By making the 'exception handling' explicit, we are forced to check 611 // for failure at the call sites. 612 void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token, 613 bool is_eval, bool is_global, bool* ok); 614 Statement* ParseModuleElement(ZoneStringList* labels, bool* ok); 615 Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok); 616 Module* ParseModule(bool* ok); 617 Module* ParseModuleLiteral(bool* ok); 618 Module* ParseModulePath(bool* ok); 619 Module* ParseModuleVariable(bool* ok); 620 Module* ParseModuleUrl(bool* ok); 621 Module* ParseModuleSpecifier(bool* ok); 622 Block* ParseImportDeclaration(bool* ok); 623 Statement* ParseExportDeclaration(bool* ok); 624 Statement* ParseBlockElement(ZoneStringList* labels, bool* ok); 625 Statement* ParseStatement(ZoneStringList* labels, bool* ok); 626 Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok); 627 Statement* ParseNativeDeclaration(bool* ok); 628 Block* ParseBlock(ZoneStringList* labels, bool* ok); 629 Block* ParseVariableStatement(VariableDeclarationContext var_context, 630 ZoneStringList* names, 631 bool* ok); 632 Block* ParseVariableDeclarations(VariableDeclarationContext var_context, 633 VariableDeclarationProperties* decl_props, 634 ZoneStringList* names, 635 Handle<String>* out, 636 bool* ok); 637 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels, 638 bool* ok); 639 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok); 640 Statement* ParseContinueStatement(bool* ok); 641 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok); 642 Statement* ParseReturnStatement(bool* ok); 643 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok); 644 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok); 645 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok); 646 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok); 647 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok); 648 Statement* ParseForStatement(ZoneStringList* labels, bool* ok); 649 Statement* ParseThrowStatement(bool* ok); 650 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value); 651 TryStatement* ParseTryStatement(bool* ok); 652 DebuggerStatement* ParseDebuggerStatement(bool* ok); 653 654 // Support for hamony block scoped bindings. 655 Block* ParseScopedBlock(ZoneStringList* labels, bool* ok); 656 657 Expression* ParseExpression(bool accept_IN, bool* ok); 658 Expression* ParseAssignmentExpression(bool accept_IN, bool* ok); 659 Expression* ParseYieldExpression(bool* ok); 660 Expression* ParseConditionalExpression(bool accept_IN, bool* ok); 661 Expression* ParseBinaryExpression(int prec, bool accept_IN, bool* ok); 662 Expression* ParseUnaryExpression(bool* ok); 663 Expression* ParsePostfixExpression(bool* ok); 664 Expression* ParseLeftHandSideExpression(bool* ok); 665 Expression* ParseNewExpression(bool* ok); 666 Expression* ParseMemberExpression(bool* ok); 667 Expression* ParseNewPrefix(PositionStack* stack, bool* ok); 668 Expression* ParseMemberWithNewPrefixesExpression(PositionStack* stack, 669 bool* ok); 670 Expression* ParsePrimaryExpression(bool* ok); 671 Expression* ParseArrayLiteral(bool* ok); 672 Expression* ParseObjectLiteral(bool* ok); 673 ObjectLiteral::Property* ParseObjectLiteralGetSet(bool is_getter, bool* ok); 674 Expression* ParseRegExpLiteral(bool seen_equal, bool* ok); 675 676 // Populate the constant properties fixed array for a materialized object 677 // literal. 678 void BuildObjectLiteralConstantProperties( 679 ZoneList<ObjectLiteral::Property*>* properties, 680 Handle<FixedArray> constants, 681 bool* is_simple, 682 bool* fast_elements, 683 int* depth, 684 bool* may_store_doubles); 685 686 // Decide if a property should be in the object boilerplate. 687 bool IsBoilerplateProperty(ObjectLiteral::Property* property); 688 // If the expression is a literal, return the literal value; 689 // if the expression is a materialized literal and is simple return a 690 // compile time value as encoded by CompileTimeValue::GetValue(). 691 // Otherwise, return undefined literal as the placeholder 692 // in the object literal boilerplate. 693 Handle<Object> GetBoilerplateValue(Expression* expression); 694 695 // Initialize the components of a for-in / for-of statement. 696 void InitializeForEachStatement(ForEachStatement* stmt, 697 Expression* each, 698 Expression* subject, 699 Statement* body); 700 701 ZoneList<Expression*>* ParseArguments(bool* ok); 702 FunctionLiteral* ParseFunctionLiteral(Handle<String> var_name, 703 bool name_is_reserved, 704 bool is_generator, 705 int function_token_position, 706 FunctionLiteral::FunctionType type, 707 bool* ok); 708 709 710 // Magical syntax support. 711 Expression* ParseV8Intrinsic(bool* ok); 712 713 INLINE(Token::Value peek()) { 714 if (stack_overflow_) return Token::ILLEGAL; 715 return scanner().peek(); 716 } 717 718 INLINE(Token::Value Next()) { 719 // BUG 1215673: Find a thread safe way to set a stack limit in 720 // pre-parse mode. Otherwise, we cannot safely pre-parse from other 721 // threads. 722 if (stack_overflow_) { 723 return Token::ILLEGAL; 724 } 725 if (StackLimitCheck(isolate()).HasOverflowed()) { 726 // Any further calls to Next or peek will return the illegal token. 727 // The current call must return the next token, which might already 728 // have been peek'ed. 729 stack_overflow_ = true; 730 } 731 return scanner().Next(); 732 } 733 734 bool is_generator() const { return current_function_state_->is_generator(); } 735 736 bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode); 737 738 bool peek_any_identifier(); 739 740 INLINE(void Consume(Token::Value token)); 741 void Expect(Token::Value token, bool* ok); 742 bool Check(Token::Value token); 743 void ExpectSemicolon(bool* ok); 744 bool CheckContextualKeyword(Vector<const char> keyword); 745 void ExpectContextualKeyword(Vector<const char> keyword, bool* ok); 746 747 Handle<String> LiteralString(PretenureFlag tenured) { 748 if (scanner().is_literal_ascii()) { 749 return isolate_->factory()->NewStringFromAscii( 750 scanner().literal_ascii_string(), tenured); 751 } else { 752 return isolate_->factory()->NewStringFromTwoByte( 753 scanner().literal_utf16_string(), tenured); 754 } 755 } 756 757 Handle<String> NextLiteralString(PretenureFlag tenured) { 758 if (scanner().is_next_literal_ascii()) { 759 return isolate_->factory()->NewStringFromAscii( 760 scanner().next_literal_ascii_string(), tenured); 761 } else { 762 return isolate_->factory()->NewStringFromTwoByte( 763 scanner().next_literal_utf16_string(), tenured); 764 } 765 } 766 767 Handle<String> GetSymbol(); 768 769 // Get odd-ball literals. 770 Literal* GetLiteralUndefined(); 771 Literal* GetLiteralTheHole(); 772 773 Handle<String> ParseIdentifier(bool* ok); 774 Handle<String> ParseIdentifierOrStrictReservedWord( 775 bool* is_strict_reserved, bool* ok); 776 Handle<String> ParseIdentifierName(bool* ok); 777 Handle<String> ParseIdentifierNameOrGetOrSet(bool* is_get, 778 bool* is_set, 779 bool* ok); 780 781 // Determine if the expression is a variable proxy and mark it as being used 782 // in an assignment or with a increment/decrement operator. This is currently 783 // used on for the statically checking assignments to harmony const bindings. 784 void MarkAsLValue(Expression* expression); 785 786 // Strict mode validation of LValue expressions 787 void CheckStrictModeLValue(Expression* expression, 788 const char* error, 789 bool* ok); 790 791 // Strict mode octal literal validation. 792 void CheckOctalLiteral(int beg_pos, int end_pos, bool* ok); 793 794 // For harmony block scoping mode: Check if the scope has conflicting var/let 795 // declarations from different scopes. It covers for example 796 // 797 // function f() { { { var x; } let x; } } 798 // function g() { { var x; let x; } } 799 // 800 // The var declarations are hoisted to the function scope, but originate from 801 // a scope where the name has also been let bound or the var declaration is 802 // hoisted over such a scope. 803 void CheckConflictingVarDeclarations(Scope* scope, bool* ok); 804 805 // Parser support 806 VariableProxy* NewUnresolved(Handle<String> name, 807 VariableMode mode, 808 Interface* interface); 809 void Declare(Declaration* declaration, bool resolve, bool* ok); 810 811 bool TargetStackContainsLabel(Handle<String> label); 812 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); 813 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok); 814 815 void RegisterTargetUse(Label* target, Target* stop); 816 817 // Factory methods. 818 819 Scope* NewScope(Scope* parent, ScopeType type); 820 821 Handle<String> LookupSymbol(int symbol_id); 822 823 Handle<String> LookupCachedSymbol(int symbol_id); 824 825 // Generate AST node that throw a ReferenceError with the given type. 826 Expression* NewThrowReferenceError(Handle<String> type); 827 828 // Generate AST node that throw a SyntaxError with the given 829 // type. The first argument may be null (in the handle sense) in 830 // which case no arguments are passed to the constructor. 831 Expression* NewThrowSyntaxError(Handle<String> type, Handle<Object> first); 832 833 // Generate AST node that throw a TypeError with the given 834 // type. Both arguments must be non-null (in the handle sense). 835 Expression* NewThrowTypeError(Handle<String> type, 836 Handle<Object> first, 837 Handle<Object> second); 838 839 // Generic AST generator for throwing errors from compiled code. 840 Expression* NewThrowError(Handle<String> constructor, 841 Handle<String> type, 842 Vector< Handle<Object> > arguments); 843 844 preparser::PreParser::PreParseResult LazyParseFunctionLiteral( 845 SingletonLogger* logger); 846 847 AstNodeFactory<AstConstructionVisitor>* factory() { 848 return current_function_state_->factory(); 849 } 850 851 Isolate* isolate_; 852 ZoneList<Handle<String> > symbol_cache_; 853 854 Handle<Script> script_; 855 Scanner scanner_; 856 preparser::PreParser* reusable_preparser_; 857 Scope* top_scope_; 858 FunctionState* current_function_state_; 859 Target* target_stack_; // for break, continue statements 860 v8::Extension* extension_; 861 ScriptDataImpl* pre_parse_data_; 862 FuncNameInferrer* fni_; 863 864 Mode mode_; 865 bool allow_natives_syntax_; 866 bool allow_lazy_; 867 bool allow_generators_; 868 bool allow_for_of_; 869 bool stack_overflow_; 870 // If true, the next (and immediately following) function literal is 871 // preceded by a parenthesis. 872 // Heuristically that means that the function will be called immediately, 873 // so never lazily compile it. 874 bool parenthesized_function_; 875 876 Zone* zone_; 877 CompilationInfo* info_; 878 friend class BlockState; 879 friend class FunctionState; 880 }; 881 882 883 // Support for handling complex values (array and object literals) that 884 // can be fully handled at compile time. 885 class CompileTimeValue: public AllStatic { 886 public: 887 enum LiteralType { 888 OBJECT_LITERAL_FAST_ELEMENTS, 889 OBJECT_LITERAL_SLOW_ELEMENTS, 890 ARRAY_LITERAL 891 }; 892 893 static bool IsCompileTimeValue(Expression* expression); 894 895 // Get the value as a compile time value. 896 static Handle<FixedArray> GetValue(Expression* expression); 897 898 // Get the type of a compile time value returned by GetValue(). 899 static LiteralType GetLiteralType(Handle<FixedArray> value); 900 901 // Get the elements array of a compile time value returned by GetValue(). 902 static Handle<FixedArray> GetElements(Handle<FixedArray> value); 903 904 private: 905 static const int kLiteralTypeSlot = 0; 906 static const int kElementsSlot = 1; 907 908 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); 909 }; 910 911 } } // namespace v8::internal 912 913 #endif // V8_PARSER_H_ 914