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