1 // Copyright 2012 the V8 project authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef V8_PARSER_H_ 6 #define V8_PARSER_H_ 7 8 #include "src/allocation.h" 9 #include "src/ast.h" 10 #include "src/compiler.h" // For CachedDataMode 11 #include "src/preparse-data-format.h" 12 #include "src/preparse-data.h" 13 #include "src/scopes.h" 14 #include "src/preparser.h" 15 16 namespace v8 { 17 class ScriptCompiler; 18 19 namespace internal { 20 21 class CompilationInfo; 22 class ParserLog; 23 class PositionStack; 24 class Target; 25 26 template <typename T> class ZoneListWrapper; 27 28 29 class FunctionEntry BASE_EMBEDDED { 30 public: 31 enum { 32 kStartPositionIndex, 33 kEndPositionIndex, 34 kLiteralCountIndex, 35 kPropertyCountIndex, 36 kStrictModeIndex, 37 kSize 38 }; 39 FunctionEntry(Vector<unsigned> backing)40 explicit FunctionEntry(Vector<unsigned> backing) 41 : backing_(backing) { } 42 FunctionEntry()43 FunctionEntry() : backing_() { } 44 start_pos()45 int start_pos() { return backing_[kStartPositionIndex]; } end_pos()46 int end_pos() { return backing_[kEndPositionIndex]; } literal_count()47 int literal_count() { return backing_[kLiteralCountIndex]; } property_count()48 int property_count() { return backing_[kPropertyCountIndex]; } strict_mode()49 StrictMode strict_mode() { 50 ASSERT(backing_[kStrictModeIndex] == SLOPPY || 51 backing_[kStrictModeIndex] == STRICT); 52 return static_cast<StrictMode>(backing_[kStrictModeIndex]); 53 } 54 is_valid()55 bool is_valid() { return !backing_.is_empty(); } 56 57 private: 58 Vector<unsigned> backing_; 59 }; 60 61 62 class ScriptData { 63 public: ScriptData(Vector<unsigned> store)64 explicit ScriptData(Vector<unsigned> store) 65 : store_(store), 66 owns_store_(true) { } 67 ScriptData(Vector<unsigned> store,bool owns_store)68 ScriptData(Vector<unsigned> store, bool owns_store) 69 : store_(store), 70 owns_store_(owns_store) { } 71 72 // The created ScriptData won't take ownership of the data. If the alignment 73 // is not correct, this will copy the data (and the created ScriptData will 74 // take ownership of the copy). 75 static ScriptData* New(const char* data, int length); 76 77 virtual ~ScriptData(); 78 virtual int Length(); 79 virtual const char* Data(); 80 virtual bool HasError(); 81 82 void Initialize(); 83 void ReadNextSymbolPosition(); 84 85 FunctionEntry GetFunctionEntry(int start); 86 int GetSymbolIdentifier(); 87 bool SanityCheck(); 88 89 Scanner::Location MessageLocation() const; 90 bool IsReferenceError() const; 91 const char* BuildMessage() const; 92 const char* BuildArg() const; 93 function_count()94 int function_count() { 95 int functions_size = 96 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]); 97 if (functions_size < 0) return 0; 98 if (functions_size % FunctionEntry::kSize != 0) return 0; 99 return functions_size / FunctionEntry::kSize; 100 } 101 // The following functions should only be called if SanityCheck has 102 // returned true. has_error()103 bool has_error() { return store_[PreparseDataConstants::kHasErrorOffset]; } magic()104 unsigned magic() { return store_[PreparseDataConstants::kMagicOffset]; } version()105 unsigned version() { return store_[PreparseDataConstants::kVersionOffset]; } 106 107 private: 108 // Disable copying and assigning; because of owns_store they won't be correct. 109 ScriptData(const ScriptData&); 110 ScriptData& operator=(const ScriptData&); 111 112 friend class v8::ScriptCompiler; 113 Vector<unsigned> store_; 114 unsigned char* symbol_data_; 115 unsigned char* symbol_data_end_; 116 int function_index_; 117 bool owns_store_; 118 119 unsigned Read(int position) const; 120 unsigned* ReadAddress(int position) const; 121 // Reads a number from the current symbols 122 int ReadNumber(byte** source); 123 124 // Read strings written by ParserRecorder::WriteString. 125 static const char* ReadString(unsigned* start, int* chars); 126 }; 127 128 129 // ---------------------------------------------------------------------------- 130 // REGEXP PARSING 131 132 // A BufferedZoneList is an automatically growing list, just like (and backed 133 // by) a ZoneList, that is optimized for the case of adding and removing 134 // a single element. The last element added is stored outside the backing list, 135 // and if no more than one element is ever added, the ZoneList isn't even 136 // allocated. 137 // Elements must not be NULL pointers. 138 template <typename T, int initial_size> 139 class BufferedZoneList { 140 public: BufferedZoneList()141 BufferedZoneList() : list_(NULL), last_(NULL) {} 142 143 // Adds element at end of list. This element is buffered and can 144 // be read using last() or removed using RemoveLast until a new Add or until 145 // RemoveLast or GetList has been called. Add(T * value,Zone * zone)146 void Add(T* value, Zone* zone) { 147 if (last_ != NULL) { 148 if (list_ == NULL) { 149 list_ = new(zone) ZoneList<T*>(initial_size, zone); 150 } 151 list_->Add(last_, zone); 152 } 153 last_ = value; 154 } 155 last()156 T* last() { 157 ASSERT(last_ != NULL); 158 return last_; 159 } 160 RemoveLast()161 T* RemoveLast() { 162 ASSERT(last_ != NULL); 163 T* result = last_; 164 if ((list_ != NULL) && (list_->length() > 0)) 165 last_ = list_->RemoveLast(); 166 else 167 last_ = NULL; 168 return result; 169 } 170 Get(int i)171 T* Get(int i) { 172 ASSERT((0 <= i) && (i < length())); 173 if (list_ == NULL) { 174 ASSERT_EQ(0, i); 175 return last_; 176 } else { 177 if (i == list_->length()) { 178 ASSERT(last_ != NULL); 179 return last_; 180 } else { 181 return list_->at(i); 182 } 183 } 184 } 185 Clear()186 void Clear() { 187 list_ = NULL; 188 last_ = NULL; 189 } 190 length()191 int length() { 192 int length = (list_ == NULL) ? 0 : list_->length(); 193 return length + ((last_ == NULL) ? 0 : 1); 194 } 195 GetList(Zone * zone)196 ZoneList<T*>* GetList(Zone* zone) { 197 if (list_ == NULL) { 198 list_ = new(zone) ZoneList<T*>(initial_size, zone); 199 } 200 if (last_ != NULL) { 201 list_->Add(last_, zone); 202 last_ = NULL; 203 } 204 return list_; 205 } 206 207 private: 208 ZoneList<T*>* list_; 209 T* last_; 210 }; 211 212 213 // Accumulates RegExp atoms and assertions into lists of terms and alternatives. 214 class RegExpBuilder: public ZoneObject { 215 public: 216 explicit RegExpBuilder(Zone* zone); 217 void AddCharacter(uc16 character); 218 // "Adds" an empty expression. Does nothing except consume a 219 // following quantifier 220 void AddEmpty(); 221 void AddAtom(RegExpTree* tree); 222 void AddAssertion(RegExpTree* tree); 223 void NewAlternative(); // '|' 224 void AddQuantifierToAtom( 225 int min, int max, RegExpQuantifier::QuantifierType type); 226 RegExpTree* ToRegExp(); 227 228 private: 229 void FlushCharacters(); 230 void FlushText(); 231 void FlushTerms(); zone()232 Zone* zone() const { return zone_; } 233 234 Zone* zone_; 235 bool pending_empty_; 236 ZoneList<uc16>* characters_; 237 BufferedZoneList<RegExpTree, 2> terms_; 238 BufferedZoneList<RegExpTree, 2> text_; 239 BufferedZoneList<RegExpTree, 2> alternatives_; 240 #ifdef DEBUG 241 enum {ADD_NONE, ADD_CHAR, ADD_TERM, ADD_ASSERT, ADD_ATOM} last_added_; 242 #define LAST(x) last_added_ = x; 243 #else 244 #define LAST(x) 245 #endif 246 }; 247 248 249 class RegExpParser BASE_EMBEDDED { 250 public: 251 RegExpParser(FlatStringReader* in, 252 Handle<String>* error, 253 bool multiline_mode, 254 Zone* zone); 255 256 static bool ParseRegExp(FlatStringReader* input, 257 bool multiline, 258 RegExpCompileData* result, 259 Zone* zone); 260 261 RegExpTree* ParsePattern(); 262 RegExpTree* ParseDisjunction(); 263 RegExpTree* ParseGroup(); 264 RegExpTree* ParseCharacterClass(); 265 266 // Parses a {...,...} quantifier and stores the range in the given 267 // out parameters. 268 bool ParseIntervalQuantifier(int* min_out, int* max_out); 269 270 // Parses and returns a single escaped character. The character 271 // must not be 'b' or 'B' since they are usually handle specially. 272 uc32 ParseClassCharacterEscape(); 273 274 // Checks whether the following is a length-digit hexadecimal number, 275 // and sets the value if it is. 276 bool ParseHexEscape(int length, uc32* value); 277 278 uc32 ParseOctalLiteral(); 279 280 // Tries to parse the input as a back reference. If successful it 281 // stores the result in the output parameter and returns true. If 282 // it fails it will push back the characters read so the same characters 283 // can be reparsed. 284 bool ParseBackReferenceIndex(int* index_out); 285 286 CharacterRange ParseClassAtom(uc16* char_class); 287 RegExpTree* ReportError(Vector<const char> message); 288 void Advance(); 289 void Advance(int dist); 290 void Reset(int pos); 291 292 // Reports whether the pattern might be used as a literal search string. 293 // Only use if the result of the parse is a single atom node. 294 bool simple(); contains_anchor()295 bool contains_anchor() { return contains_anchor_; } set_contains_anchor()296 void set_contains_anchor() { contains_anchor_ = true; } captures_started()297 int captures_started() { return captures_ == NULL ? 0 : captures_->length(); } position()298 int position() { return next_pos_ - 1; } failed()299 bool failed() { return failed_; } 300 301 static const int kMaxCaptures = 1 << 16; 302 static const uc32 kEndMarker = (1 << 21); 303 304 private: 305 enum SubexpressionType { 306 INITIAL, 307 CAPTURE, // All positive values represent captures. 308 POSITIVE_LOOKAHEAD, 309 NEGATIVE_LOOKAHEAD, 310 GROUPING 311 }; 312 313 class RegExpParserState : public ZoneObject { 314 public: RegExpParserState(RegExpParserState * previous_state,SubexpressionType group_type,int disjunction_capture_index,Zone * zone)315 RegExpParserState(RegExpParserState* previous_state, 316 SubexpressionType group_type, 317 int disjunction_capture_index, 318 Zone* zone) 319 : previous_state_(previous_state), 320 builder_(new(zone) RegExpBuilder(zone)), 321 group_type_(group_type), 322 disjunction_capture_index_(disjunction_capture_index) {} 323 // Parser state of containing expression, if any. previous_state()324 RegExpParserState* previous_state() { return previous_state_; } IsSubexpression()325 bool IsSubexpression() { return previous_state_ != NULL; } 326 // RegExpBuilder building this regexp's AST. builder()327 RegExpBuilder* builder() { return builder_; } 328 // Type of regexp being parsed (parenthesized group or entire regexp). group_type()329 SubexpressionType group_type() { return group_type_; } 330 // Index in captures array of first capture in this sub-expression, if any. 331 // Also the capture index of this sub-expression itself, if group_type 332 // is CAPTURE. capture_index()333 int capture_index() { return disjunction_capture_index_; } 334 335 private: 336 // Linked list implementation of stack of states. 337 RegExpParserState* previous_state_; 338 // Builder for the stored disjunction. 339 RegExpBuilder* builder_; 340 // Stored disjunction type (capture, look-ahead or grouping), if any. 341 SubexpressionType group_type_; 342 // Stored disjunction's capture index (if any). 343 int disjunction_capture_index_; 344 }; 345 isolate()346 Isolate* isolate() { return isolate_; } zone()347 Zone* zone() const { return zone_; } 348 current()349 uc32 current() { return current_; } has_more()350 bool has_more() { return has_more_; } has_next()351 bool has_next() { return next_pos_ < in()->length(); } 352 uc32 Next(); in()353 FlatStringReader* in() { return in_; } 354 void ScanForCaptures(); 355 356 Isolate* isolate_; 357 Zone* zone_; 358 Handle<String>* error_; 359 ZoneList<RegExpCapture*>* captures_; 360 FlatStringReader* in_; 361 uc32 current_; 362 int next_pos_; 363 // The capture count is only valid after we have scanned for captures. 364 int capture_count_; 365 bool has_more_; 366 bool multiline_; 367 bool simple_; 368 bool contains_anchor_; 369 bool is_scanned_for_captures_; 370 bool failed_; 371 }; 372 373 // ---------------------------------------------------------------------------- 374 // JAVASCRIPT PARSING 375 376 class Parser; 377 class SingletonLogger; 378 379 class ParserTraits { 380 public: 381 struct Type { 382 // TODO(marja): To be removed. The Traits object should contain all the data 383 // it needs. 384 typedef v8::internal::Parser* Parser; 385 386 // Used by FunctionState and BlockState. 387 typedef v8::internal::Scope Scope; 388 typedef Variable GeneratorVariable; 389 typedef v8::internal::Zone Zone; 390 391 // Return types for traversing functions. 392 typedef Handle<String> Identifier; 393 typedef v8::internal::Expression* Expression; 394 typedef Yield* YieldExpression; 395 typedef v8::internal::FunctionLiteral* FunctionLiteral; 396 typedef v8::internal::Literal* Literal; 397 typedef ObjectLiteral::Property* ObjectLiteralProperty; 398 typedef ZoneList<v8::internal::Expression*>* ExpressionList; 399 typedef ZoneList<ObjectLiteral::Property*>* PropertyList; 400 typedef ZoneList<v8::internal::Statement*>* StatementList; 401 402 // For constructing objects returned by the traversing functions. 403 typedef AstNodeFactory<AstConstructionVisitor> Factory; 404 }; 405 ParserTraits(Parser * parser)406 explicit ParserTraits(Parser* parser) : parser_(parser) {} 407 408 // Custom operations executed when FunctionStates are created and destructed. 409 template<typename FunctionState> SetUpFunctionState(FunctionState * function_state,Zone * zone)410 static void SetUpFunctionState(FunctionState* function_state, Zone* zone) { 411 Isolate* isolate = zone->isolate(); 412 function_state->saved_ast_node_id_ = isolate->ast_node_id(); 413 isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt()); 414 } 415 416 template<typename FunctionState> TearDownFunctionState(FunctionState * function_state,Zone * zone)417 static void TearDownFunctionState(FunctionState* function_state, Zone* zone) { 418 if (function_state->outer_function_state_ != NULL) { 419 zone->isolate()->set_ast_node_id(function_state->saved_ast_node_id_); 420 } 421 } 422 423 // Helper functions for recursive descent. 424 bool IsEvalOrArguments(Handle<String> identifier) const; 425 426 // Returns true if the expression is of type "this.foo". 427 static bool IsThisProperty(Expression* expression); 428 429 static bool IsIdentifier(Expression* expression); 430 AsIdentifier(Expression * expression)431 static Handle<String> AsIdentifier(Expression* expression) { 432 ASSERT(IsIdentifier(expression)); 433 return expression->AsVariableProxy()->name(); 434 } 435 IsBoilerplateProperty(ObjectLiteral::Property * property)436 static bool IsBoilerplateProperty(ObjectLiteral::Property* property) { 437 return ObjectLiteral::IsBoilerplateProperty(property); 438 } 439 IsArrayIndex(Handle<String> string,uint32_t * index)440 static bool IsArrayIndex(Handle<String> string, uint32_t* index) { 441 return !string.is_null() && string->AsArrayIndex(index); 442 } 443 444 // Functions for encapsulating the differences between parsing and preparsing; 445 // operations interleaved with the recursive descent. PushLiteralName(FuncNameInferrer * fni,Handle<String> id)446 static void PushLiteralName(FuncNameInferrer* fni, Handle<String> id) { 447 fni->PushLiteralName(id); 448 } 449 void PushPropertyName(FuncNameInferrer* fni, Expression* expression); 450 CheckFunctionLiteralInsideTopLevelObjectLiteral(Scope * scope,Expression * value,bool * has_function)451 static void CheckFunctionLiteralInsideTopLevelObjectLiteral( 452 Scope* scope, Expression* value, bool* has_function) { 453 if (scope->DeclarationScope()->is_global_scope() && 454 value->AsFunctionLiteral() != NULL) { 455 *has_function = true; 456 value->AsFunctionLiteral()->set_pretenure(); 457 } 458 } 459 460 // If we assign a function literal to a property we pretenure the 461 // literal so it can be added as a constant function property. 462 static void CheckAssigningFunctionLiteralToProperty(Expression* left, 463 Expression* right); 464 465 // Keep track of eval() calls since they disable all local variable 466 // optimizations. This checks if expression is an eval call, and if yes, 467 // forwards the information to scope. 468 void CheckPossibleEvalCall(Expression* expression, Scope* scope); 469 470 // Determine if the expression is a variable proxy and mark it as being used 471 // in an assignment or with a increment/decrement operator. This is currently 472 // used on for the statically checking assignments to harmony const bindings. 473 static Expression* MarkExpressionAsLValue(Expression* expression); 474 475 // Returns true if we have a binary expression between two numeric 476 // literals. In that case, *x will be changed to an expression which is the 477 // computed value. 478 bool ShortcutNumericLiteralBinaryExpression( 479 Expression** x, Expression* y, Token::Value op, int pos, 480 AstNodeFactory<AstConstructionVisitor>* factory); 481 482 // Rewrites the following types of unary expressions: 483 // not <literal> -> true / false 484 // + <numeric literal> -> <numeric literal> 485 // - <numeric literal> -> <numeric literal with value negated> 486 // ! <literal> -> true / false 487 // The following rewriting rules enable the collection of type feedback 488 // without any special stub and the multiplication is removed later in 489 // Crankshaft's canonicalization pass. 490 // + foo -> foo * 1 491 // - foo -> foo * (-1) 492 // ~ foo -> foo ^(~0) 493 Expression* BuildUnaryExpression( 494 Expression* expression, Token::Value op, int pos, 495 AstNodeFactory<AstConstructionVisitor>* factory); 496 497 // Generate AST node that throws a ReferenceError with the given type. 498 Expression* NewThrowReferenceError(const char* type, int pos); 499 500 // Generate AST node that throws a SyntaxError with the given 501 // type. The first argument may be null (in the handle sense) in 502 // which case no arguments are passed to the constructor. 503 Expression* NewThrowSyntaxError( 504 const char* type, Handle<Object> arg, int pos); 505 506 // Generate AST node that throws a TypeError with the given 507 // type. Both arguments must be non-null (in the handle sense). 508 Expression* NewThrowTypeError(const char* type, Handle<Object> arg, int pos); 509 510 // Generic AST generator for throwing errors from compiled code. 511 Expression* NewThrowError( 512 Handle<String> constructor, const char* type, 513 Vector<Handle<Object> > arguments, int pos); 514 515 // Reporting errors. 516 void ReportMessageAt(Scanner::Location source_location, 517 const char* message, 518 const char* arg, 519 bool is_reference_error = false); 520 void ReportMessage(const char* message, 521 MaybeHandle<String> arg, 522 bool is_reference_error = false); 523 void ReportMessageAt(Scanner::Location source_location, 524 const char* message, 525 MaybeHandle<String> arg, 526 bool is_reference_error = false); 527 528 // "null" return type creators. EmptyIdentifier()529 static Handle<String> EmptyIdentifier() { 530 return Handle<String>(); 531 } EmptyExpression()532 static Expression* EmptyExpression() { 533 return NULL; 534 } EmptyLiteral()535 static Literal* EmptyLiteral() { 536 return NULL; 537 } 538 // Used in error return values. NullExpressionList()539 static ZoneList<Expression*>* NullExpressionList() { 540 return NULL; 541 } 542 543 // Odd-ball literal creators. 544 Literal* GetLiteralTheHole(int position, 545 AstNodeFactory<AstConstructionVisitor>* factory); 546 547 // Producing data during the recursive descent. 548 Handle<String> GetSymbol(Scanner* scanner = NULL); 549 Handle<String> NextLiteralString(Scanner* scanner, 550 PretenureFlag tenured); 551 Expression* ThisExpression(Scope* scope, 552 AstNodeFactory<AstConstructionVisitor>* factory); 553 Literal* ExpressionFromLiteral( 554 Token::Value token, int pos, Scanner* scanner, 555 AstNodeFactory<AstConstructionVisitor>* factory); 556 Expression* ExpressionFromIdentifier( 557 Handle<String> name, int pos, Scope* scope, 558 AstNodeFactory<AstConstructionVisitor>* factory); 559 Expression* ExpressionFromString( 560 int pos, Scanner* scanner, 561 AstNodeFactory<AstConstructionVisitor>* factory); NewExpressionList(int size,Zone * zone)562 ZoneList<v8::internal::Expression*>* NewExpressionList(int size, Zone* zone) { 563 return new(zone) ZoneList<v8::internal::Expression*>(size, zone); 564 } NewPropertyList(int size,Zone * zone)565 ZoneList<ObjectLiteral::Property*>* NewPropertyList(int size, Zone* zone) { 566 return new(zone) ZoneList<ObjectLiteral::Property*>(size, zone); 567 } NewStatementList(int size,Zone * zone)568 ZoneList<v8::internal::Statement*>* NewStatementList(int size, Zone* zone) { 569 return new(zone) ZoneList<v8::internal::Statement*>(size, zone); 570 } 571 572 // Temporary glue; these functions will move to ParserBase. 573 Expression* ParseV8Intrinsic(bool* ok); 574 FunctionLiteral* ParseFunctionLiteral( 575 Handle<String> name, 576 Scanner::Location function_name_location, 577 bool name_is_strict_reserved, 578 bool is_generator, 579 int function_token_position, 580 FunctionLiteral::FunctionType type, 581 FunctionLiteral::ArityRestriction arity_restriction, 582 bool* ok); 583 584 private: 585 Parser* parser_; 586 }; 587 588 589 class Parser : public ParserBase<ParserTraits> { 590 public: 591 explicit Parser(CompilationInfo* info); ~Parser()592 ~Parser() { 593 delete reusable_preparser_; 594 reusable_preparser_ = NULL; 595 } 596 597 // Parses the source code represented by the compilation info and sets its 598 // function literal. Returns false (and deallocates any allocated AST 599 // nodes) if parsing failed. 600 static bool Parse(CompilationInfo* info, 601 bool allow_lazy = false) { 602 Parser parser(info); 603 parser.set_allow_lazy(allow_lazy); 604 return parser.Parse(); 605 } 606 bool Parse(); 607 608 private: 609 friend class ParserTraits; 610 611 // Limit the allowed number of local variables in a function. The hard limit 612 // is that offsets computed by FullCodeGenerator::StackOperand and similar 613 // functions are ints, and they should not overflow. In addition, accessing 614 // local variables creates user-controlled constants in the generated code, 615 // and we don't want too much user-controlled memory inside the code (this was 616 // the reason why this limit was introduced in the first place; see 617 // https://codereview.chromium.org/7003030/ ). 618 static const int kMaxNumFunctionLocals = 4194303; // 2^22-1 619 620 enum VariableDeclarationContext { 621 kModuleElement, 622 kBlockElement, 623 kStatement, 624 kForStatement 625 }; 626 627 // If a list of variable declarations includes any initializers. 628 enum VariableDeclarationProperties { 629 kHasInitializers, 630 kHasNoInitializers 631 }; 632 633 // Returns NULL if parsing failed. 634 FunctionLiteral* ParseProgram(); 635 636 FunctionLiteral* ParseLazy(); 637 FunctionLiteral* ParseLazy(Utf16CharacterStream* source); 638 isolate()639 Isolate* isolate() { return isolate_; } info()640 CompilationInfo* info() const { return info_; } 641 642 // Called by ParseProgram after setting up the scanner. 643 FunctionLiteral* DoParseProgram(CompilationInfo* info, 644 Handle<String> source); 645 646 // Report syntax error 647 void ReportInvalidCachedData(Handle<String> name, bool* ok); 648 SetCachedData(ScriptData ** data,CachedDataMode cached_data_mode)649 void SetCachedData(ScriptData** data, 650 CachedDataMode cached_data_mode) { 651 cached_data_mode_ = cached_data_mode; 652 if (cached_data_mode == NO_CACHED_DATA) { 653 cached_data_ = NULL; 654 } else { 655 ASSERT(data != NULL); 656 cached_data_ = data; 657 } 658 } 659 inside_with()660 bool inside_with() const { return scope_->inside_with(); } cached_data()661 ScriptData** cached_data() const { return cached_data_; } cached_data_mode()662 CachedDataMode cached_data_mode() const { return cached_data_mode_; } DeclarationScope(VariableMode mode)663 Scope* DeclarationScope(VariableMode mode) { 664 return IsLexicalVariableMode(mode) 665 ? scope_ : scope_->DeclarationScope(); 666 } 667 668 // All ParseXXX functions take as the last argument an *ok parameter 669 // which is set to false if parsing failed; it is unchanged otherwise. 670 // By making the 'exception handling' explicit, we are forced to check 671 // for failure at the call sites. 672 void* ParseSourceElements(ZoneList<Statement*>* processor, int end_token, 673 bool is_eval, bool is_global, bool* ok); 674 Statement* ParseModuleElement(ZoneStringList* labels, bool* ok); 675 Statement* ParseModuleDeclaration(ZoneStringList* names, bool* ok); 676 Module* ParseModule(bool* ok); 677 Module* ParseModuleLiteral(bool* ok); 678 Module* ParseModulePath(bool* ok); 679 Module* ParseModuleVariable(bool* ok); 680 Module* ParseModuleUrl(bool* ok); 681 Module* ParseModuleSpecifier(bool* ok); 682 Block* ParseImportDeclaration(bool* ok); 683 Statement* ParseExportDeclaration(bool* ok); 684 Statement* ParseBlockElement(ZoneStringList* labels, bool* ok); 685 Statement* ParseStatement(ZoneStringList* labels, bool* ok); 686 Statement* ParseFunctionDeclaration(ZoneStringList* names, bool* ok); 687 Statement* ParseNativeDeclaration(bool* ok); 688 Block* ParseBlock(ZoneStringList* labels, bool* ok); 689 Block* ParseVariableStatement(VariableDeclarationContext var_context, 690 ZoneStringList* names, 691 bool* ok); 692 Block* ParseVariableDeclarations(VariableDeclarationContext var_context, 693 VariableDeclarationProperties* decl_props, 694 ZoneStringList* names, 695 Handle<String>* out, 696 bool* ok); 697 Statement* ParseExpressionOrLabelledStatement(ZoneStringList* labels, 698 bool* ok); 699 IfStatement* ParseIfStatement(ZoneStringList* labels, bool* ok); 700 Statement* ParseContinueStatement(bool* ok); 701 Statement* ParseBreakStatement(ZoneStringList* labels, bool* ok); 702 Statement* ParseReturnStatement(bool* ok); 703 Statement* ParseWithStatement(ZoneStringList* labels, bool* ok); 704 CaseClause* ParseCaseClause(bool* default_seen_ptr, bool* ok); 705 SwitchStatement* ParseSwitchStatement(ZoneStringList* labels, bool* ok); 706 DoWhileStatement* ParseDoWhileStatement(ZoneStringList* labels, bool* ok); 707 WhileStatement* ParseWhileStatement(ZoneStringList* labels, bool* ok); 708 Statement* ParseForStatement(ZoneStringList* labels, bool* ok); 709 Statement* ParseThrowStatement(bool* ok); 710 Expression* MakeCatchContext(Handle<String> id, VariableProxy* value); 711 TryStatement* ParseTryStatement(bool* ok); 712 DebuggerStatement* ParseDebuggerStatement(bool* ok); 713 714 // Support for hamony block scoped bindings. 715 Block* ParseScopedBlock(ZoneStringList* labels, bool* ok); 716 717 // Initialize the components of a for-in / for-of statement. 718 void InitializeForEachStatement(ForEachStatement* stmt, 719 Expression* each, 720 Expression* subject, 721 Statement* body); 722 Statement* DesugarLetBindingsInForStatement( 723 Scope* inner_scope, ZoneStringList* names, ForStatement* loop, 724 Statement* init, Expression* cond, Statement* next, Statement* body, 725 bool* ok); 726 727 FunctionLiteral* ParseFunctionLiteral( 728 Handle<String> name, 729 Scanner::Location function_name_location, 730 bool name_is_strict_reserved, 731 bool is_generator, 732 int function_token_position, 733 FunctionLiteral::FunctionType type, 734 FunctionLiteral::ArityRestriction arity_restriction, 735 bool* ok); 736 737 // Magical syntax support. 738 Expression* ParseV8Intrinsic(bool* ok); 739 740 bool CheckInOrOf(bool accept_OF, ForEachStatement::VisitMode* visit_mode); 741 742 // Get odd-ball literals. 743 Literal* GetLiteralUndefined(int position); 744 745 // For harmony block scoping mode: Check if the scope has conflicting var/let 746 // declarations from different scopes. It covers for example 747 // 748 // function f() { { { var x; } let x; } } 749 // function g() { { var x; let x; } } 750 // 751 // The var declarations are hoisted to the function scope, but originate from 752 // a scope where the name has also been let bound or the var declaration is 753 // hoisted over such a scope. 754 void CheckConflictingVarDeclarations(Scope* scope, bool* ok); 755 756 // Parser support 757 VariableProxy* NewUnresolved(Handle<String> name, 758 VariableMode mode, 759 Interface* interface); 760 void Declare(Declaration* declaration, bool resolve, bool* ok); 761 762 bool TargetStackContainsLabel(Handle<String> label); 763 BreakableStatement* LookupBreakTarget(Handle<String> label, bool* ok); 764 IterationStatement* LookupContinueTarget(Handle<String> label, bool* ok); 765 766 void RegisterTargetUse(Label* target, Target* stop); 767 768 // Factory methods. 769 770 Scope* NewScope(Scope* parent, ScopeType type); 771 772 // Skip over a lazy function, either using cached data if we have it, or 773 // by parsing the function with PreParser. Consumes the ending }. 774 void SkipLazyFunctionBody(Handle<String> function_name, 775 int* materialized_literal_count, 776 int* expected_property_count, 777 bool* ok); 778 779 PreParser::PreParseResult ParseLazyFunctionBodyWithPreParser( 780 SingletonLogger* logger); 781 782 // Consumes the ending }. 783 ZoneList<Statement*>* ParseEagerFunctionBody(Handle<String> function_name, 784 int pos, 785 Variable* fvar, 786 Token::Value fvar_init_op, 787 bool is_generator, 788 bool* ok); 789 790 void ThrowPendingError(); 791 792 Isolate* isolate_; 793 794 Handle<Script> script_; 795 Scanner scanner_; 796 PreParser* reusable_preparser_; 797 Scope* original_scope_; // for ES5 function declarations in sloppy eval 798 Target* target_stack_; // for break, continue statements 799 ScriptData** cached_data_; 800 CachedDataMode cached_data_mode_; 801 802 CompilationInfo* info_; 803 804 // Pending errors. 805 bool has_pending_error_; 806 Scanner::Location pending_error_location_; 807 const char* pending_error_message_; 808 MaybeHandle<String> pending_error_arg_; 809 const char* pending_error_char_arg_; 810 bool pending_error_is_reference_error_; 811 }; 812 813 814 // Support for handling complex values (array and object literals) that 815 // can be fully handled at compile time. 816 class CompileTimeValue: public AllStatic { 817 public: 818 enum LiteralType { 819 OBJECT_LITERAL_FAST_ELEMENTS, 820 OBJECT_LITERAL_SLOW_ELEMENTS, 821 ARRAY_LITERAL 822 }; 823 824 static bool IsCompileTimeValue(Expression* expression); 825 826 // Get the value as a compile time value. 827 static Handle<FixedArray> GetValue(Isolate* isolate, Expression* expression); 828 829 // Get the type of a compile time value returned by GetValue(). 830 static LiteralType GetLiteralType(Handle<FixedArray> value); 831 832 // Get the elements array of a compile time value returned by GetValue(). 833 static Handle<FixedArray> GetElements(Handle<FixedArray> value); 834 835 private: 836 static const int kLiteralTypeSlot = 0; 837 static const int kElementsSlot = 1; 838 839 DISALLOW_IMPLICIT_CONSTRUCTORS(CompileTimeValue); 840 }; 841 842 } } // namespace v8::internal 843 844 #endif // V8_PARSER_H_ 845