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