| OLD | NEW |
| 1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 | 29 |
| 30 #include "api.h" | 30 #include "api.h" |
| 31 #include "ast.h" | 31 #include "ast.h" |
| 32 #include "bootstrapper.h" | 32 #include "bootstrapper.h" |
| 33 #include "codegen.h" | 33 #include "codegen.h" |
| 34 #include "compiler.h" | 34 #include "compiler.h" |
| 35 #include "func-name-inferrer.h" | 35 #include "func-name-inferrer.h" |
| 36 #include "messages.h" | 36 #include "messages.h" |
| 37 #include "parser.h" | 37 #include "parser.h" |
| 38 #include "platform.h" | 38 #include "platform.h" |
| 39 #include "preparser.h" |
| 39 #include "runtime.h" | 40 #include "runtime.h" |
| 40 #include "scopeinfo.h" | 41 #include "scopeinfo.h" |
| 41 #include "scopes.h" | 42 #include "scopes.h" |
| 42 #include "string-stream.h" | 43 #include "string-stream.h" |
| 43 | 44 |
| 44 #include "ast-inl.h" | 45 #include "ast-inl.h" |
| 45 #include "jump-target-inl.h" | 46 #include "jump-target-inl.h" |
| 46 | 47 |
| 47 namespace v8 { | 48 namespace v8 { |
| 48 namespace internal { | 49 namespace internal { |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 383 | 384 |
| 384 template <typename T> ZoneListWrapper<T> NewList(int size) { | 385 template <typename T> ZoneListWrapper<T> NewList(int size) { |
| 385 return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size); | 386 return is_pre_parsing_ ? ZoneListWrapper<T>() : ZoneListWrapper<T>(size); |
| 386 } | 387 } |
| 387 | 388 |
| 388 private: | 389 private: |
| 389 bool is_pre_parsing_; | 390 bool is_pre_parsing_; |
| 390 }; | 391 }; |
| 391 | 392 |
| 392 | 393 |
| 393 class ParserLog BASE_EMBEDDED { | |
| 394 public: | |
| 395 virtual ~ParserLog() { } | |
| 396 | |
| 397 // Records the occurrence of a function. | |
| 398 virtual FunctionEntry LogFunction(int start) { return FunctionEntry(); } | |
| 399 virtual void LogSymbol(int start, Vector<const char> symbol) {} | |
| 400 virtual void LogError() { } | |
| 401 // Return the current position in the function entry log. | |
| 402 virtual int function_position() { return 0; } | |
| 403 virtual int symbol_position() { return 0; } | |
| 404 virtual int symbol_ids() { return 0; } | |
| 405 virtual void PauseRecording() {} | |
| 406 virtual void ResumeRecording() {} | |
| 407 virtual Vector<unsigned> ExtractData() { | |
| 408 return Vector<unsigned>(); | |
| 409 }; | |
| 410 }; | |
| 411 | |
| 412 | |
| 413 | |
| 414 class ConditionalLogPauseScope { | 394 class ConditionalLogPauseScope { |
| 415 public: | 395 public: |
| 416 ConditionalLogPauseScope(bool pause, ParserLog* log) | 396 ConditionalLogPauseScope(bool pause, ParserLog* log) |
| 417 : log_(log), pause_(pause) { | 397 : log_(log), pause_(pause) { |
| 418 if (pause) log->PauseRecording(); | 398 if (pause) log->PauseRecording(); |
| 419 } | 399 } |
| 420 ~ConditionalLogPauseScope() { | 400 ~ConditionalLogPauseScope() { |
| 421 if (pause_) log_->ResumeRecording(); | 401 if (pause_) log_->ResumeRecording(); |
| 422 } | 402 } |
| 423 private: | 403 private: |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 477 int pos) { | 457 int pos) { |
| 478 return new Call(expression, arguments, pos); | 458 return new Call(expression, arguments, pos); |
| 479 } | 459 } |
| 480 | 460 |
| 481 virtual Statement* EmptyStatement(); | 461 virtual Statement* EmptyStatement(); |
| 482 private: | 462 private: |
| 483 List<Handle<String> > symbol_cache_; | 463 List<Handle<String> > symbol_cache_; |
| 484 }; | 464 }; |
| 485 | 465 |
| 486 | 466 |
| 487 // Record only functions. | 467 Vector<unsigned> PartialParserRecorder::ExtractData() { |
| 488 class PartialParserRecorder: public ParserLog { | 468 int function_size = function_store_.size(); |
| 489 public: | 469 int total_size = ScriptDataImpl::kHeaderSize + function_size; |
| 490 PartialParserRecorder(); | 470 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 491 virtual FunctionEntry LogFunction(int start); | 471 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 492 | 472 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 493 virtual int function_position() { return function_store_.size(); } | 473 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 494 | 474 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 495 virtual void LogError() { } | 475 if (function_size > 0) { |
| 496 | 476 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 497 virtual void LogMessage(Scanner::Location loc, | 477 symbol_start)); |
| 498 const char* message, | |
| 499 Vector<const char*> args); | |
| 500 | |
| 501 virtual Vector<unsigned> ExtractData() { | |
| 502 int function_size = function_store_.size(); | |
| 503 int total_size = ScriptDataImpl::kHeaderSize + function_size; | |
| 504 Vector<unsigned> data = Vector<unsigned>::New(total_size); | |
| 505 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | |
| 506 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; | |
| 507 memcpy(data.start(), preamble_, sizeof(preamble_)); | |
| 508 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | |
| 509 if (function_size > 0) { | |
| 510 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | |
| 511 symbol_start)); | |
| 512 } | |
| 513 return data; | |
| 514 } | 478 } |
| 515 | 479 return data; |
| 516 virtual void PauseRecording() { | 480 } |
| 517 pause_count_++; | |
| 518 is_recording_ = false; | |
| 519 } | |
| 520 | |
| 521 virtual void ResumeRecording() { | |
| 522 ASSERT(pause_count_ > 0); | |
| 523 if (--pause_count_ == 0) is_recording_ = !has_error(); | |
| 524 } | |
| 525 | |
| 526 protected: | |
| 527 bool has_error() { | |
| 528 return static_cast<bool>(preamble_[ScriptDataImpl::kHasErrorOffset]); | |
| 529 } | |
| 530 bool is_recording() { | |
| 531 return is_recording_; | |
| 532 } | |
| 533 | |
| 534 void WriteString(Vector<const char> str); | |
| 535 | |
| 536 Collector<unsigned> function_store_; | |
| 537 unsigned preamble_[ScriptDataImpl::kHeaderSize]; | |
| 538 bool is_recording_; | |
| 539 int pause_count_; | |
| 540 | |
| 541 #ifdef DEBUG | |
| 542 int prev_start; | |
| 543 #endif | |
| 544 }; | |
| 545 | 481 |
| 546 | 482 |
| 547 // Record both functions and symbols. | 483 void CompleteParserRecorder::LogSymbol(int start, Vector<const char> literal) { |
| 548 class CompleteParserRecorder: public PartialParserRecorder { | 484 if (!is_recording_) return; |
| 549 public: | |
| 550 CompleteParserRecorder(); | |
| 551 | 485 |
| 552 virtual void LogSymbol(int start, Vector<const char> literal) { | 486 int hash = vector_hash(literal); |
| 553 if (!is_recording_) return; | 487 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); |
| 554 int hash = vector_hash(literal); | 488 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); |
| 555 HashMap::Entry* entry = symbol_table_.Lookup(&literal, hash, true); | 489 if (id == 0) { |
| 556 int id = static_cast<int>(reinterpret_cast<intptr_t>(entry->value)); | 490 // Put (symbol_id_ + 1) into entry and increment it. |
| 557 if (id == 0) { | 491 id = ++symbol_id_; |
| 558 // Put (symbol_id_ + 1) into entry and increment it. | 492 entry->value = reinterpret_cast<void*>(id); |
| 559 id = ++symbol_id_; | 493 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); |
| 560 entry->value = reinterpret_cast<void*>(id); | 494 entry->key = &symbol[0]; |
| 561 Vector<Vector<const char> > symbol = symbol_entries_.AddBlock(1, literal); | |
| 562 entry->key = &symbol[0]; | |
| 563 } | |
| 564 WriteNumber(id - 1); | |
| 565 } | 495 } |
| 496 WriteNumber(id - 1); |
| 497 } |
| 566 | 498 |
| 567 virtual Vector<unsigned> ExtractData() { | 499 |
| 568 int function_size = function_store_.size(); | 500 Vector<unsigned> CompleteParserRecorder::ExtractData() { |
| 569 // Add terminator to symbols, then pad to unsigned size. | 501 int function_size = function_store_.size(); |
| 570 int symbol_size = symbol_store_.size(); | 502 // Add terminator to symbols, then pad to unsigned size. |
| 571 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); | 503 int symbol_size = symbol_store_.size(); |
| 572 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator); | 504 int padding = sizeof(unsigned) - (symbol_size % sizeof(unsigned)); |
| 573 symbol_size += padding; | 505 symbol_store_.AddBlock(padding, ScriptDataImpl::kNumberTerminator); |
| 574 int total_size = ScriptDataImpl::kHeaderSize + function_size | 506 symbol_size += padding; |
| 575 + (symbol_size / sizeof(unsigned)); | 507 int total_size = ScriptDataImpl::kHeaderSize + function_size |
| 576 Vector<unsigned> data = Vector<unsigned>::New(total_size); | 508 + (symbol_size / sizeof(unsigned)); |
| 577 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; | 509 Vector<unsigned> data = Vector<unsigned>::New(total_size); |
| 578 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; | 510 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = function_size; |
| 579 memcpy(data.start(), preamble_, sizeof(preamble_)); | 511 preamble_[ScriptDataImpl::kSymbolCountOffset] = symbol_id_; |
| 580 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; | 512 memcpy(data.start(), preamble_, sizeof(preamble_)); |
| 581 if (function_size > 0) { | 513 int symbol_start = ScriptDataImpl::kHeaderSize + function_size; |
| 582 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, | 514 if (function_size > 0) { |
| 583 symbol_start)); | 515 function_store_.WriteTo(data.SubVector(ScriptDataImpl::kHeaderSize, |
| 584 } | 516 symbol_start)); |
| 585 if (!has_error()) { | |
| 586 symbol_store_.WriteTo( | |
| 587 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); | |
| 588 } | |
| 589 return data; | |
| 590 } | 517 } |
| 518 if (!has_error()) { |
| 519 symbol_store_.WriteTo( |
| 520 Vector<byte>::cast(data.SubVector(symbol_start, total_size))); |
| 521 } |
| 522 return data; |
| 523 } |
| 591 | 524 |
| 592 virtual int symbol_position() { return symbol_store_.size(); } | |
| 593 virtual int symbol_ids() { return symbol_id_; } | |
| 594 private: | |
| 595 static int vector_hash(Vector<const char> string) { | |
| 596 int hash = 0; | |
| 597 for (int i = 0; i < string.length(); i++) { | |
| 598 int c = string[i]; | |
| 599 hash += c; | |
| 600 hash += (hash << 10); | |
| 601 hash ^= (hash >> 6); | |
| 602 } | |
| 603 return hash; | |
| 604 } | |
| 605 | 525 |
| 606 static bool vector_compare(void* a, void* b) { | |
| 607 Vector<const char>* string1 = reinterpret_cast<Vector<const char>* >(a); | |
| 608 Vector<const char>* string2 = reinterpret_cast<Vector<const char>* >(b); | |
| 609 int length = string1->length(); | |
| 610 if (string2->length() != length) return false; | |
| 611 return memcmp(string1->start(), string2->start(), length) == 0; | |
| 612 } | |
| 613 | |
| 614 // Write a non-negative number to the symbol store. | |
| 615 void WriteNumber(int number); | |
| 616 | |
| 617 Collector<byte> symbol_store_; | |
| 618 Collector<Vector<const char> > symbol_entries_; | |
| 619 HashMap symbol_table_; | |
| 620 int symbol_id_; | |
| 621 }; | |
| 622 | 526 |
| 623 | 527 |
| 624 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { | 528 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { |
| 625 // The current pre-data entry must be a FunctionEntry with the given | 529 // The current pre-data entry must be a FunctionEntry with the given |
| 626 // start position. | 530 // start position. |
| 627 if ((function_index_ + FunctionEntry::kSize <= store_.length()) | 531 if ((function_index_ + FunctionEntry::kSize <= store_.length()) |
| 628 && (static_cast<int>(store_[function_index_]) == start)) { | 532 && (static_cast<int>(store_[function_index_]) == start)) { |
| 629 int index = function_index_; | 533 int index = function_index_; |
| 630 function_index_ += FunctionEntry::kSize; | 534 function_index_ += FunctionEntry::kSize; |
| 631 return FunctionEntry(store_.SubVector(index, | 535 return FunctionEntry(store_.SubVector(index, |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 is_recording_(true), | 588 is_recording_(true), |
| 685 pause_count_(0) { | 589 pause_count_(0) { |
| 686 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; | 590 preamble_[ScriptDataImpl::kMagicOffset] = ScriptDataImpl::kMagicNumber; |
| 687 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; | 591 preamble_[ScriptDataImpl::kVersionOffset] = ScriptDataImpl::kCurrentVersion; |
| 688 preamble_[ScriptDataImpl::kHasErrorOffset] = false; | 592 preamble_[ScriptDataImpl::kHasErrorOffset] = false; |
| 689 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; | 593 preamble_[ScriptDataImpl::kFunctionsSizeOffset] = 0; |
| 690 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; | 594 preamble_[ScriptDataImpl::kSymbolCountOffset] = 0; |
| 691 preamble_[ScriptDataImpl::kSizeOffset] = 0; | 595 preamble_[ScriptDataImpl::kSizeOffset] = 0; |
| 692 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); | 596 ASSERT_EQ(6, ScriptDataImpl::kHeaderSize); |
| 693 #ifdef DEBUG | 597 #ifdef DEBUG |
| 694 prev_start = -1; | 598 prev_start_ = -1; |
| 695 #endif | 599 #endif |
| 696 } | 600 } |
| 697 | 601 |
| 698 | 602 |
| 699 CompleteParserRecorder::CompleteParserRecorder() | 603 CompleteParserRecorder::CompleteParserRecorder() |
| 700 : PartialParserRecorder(), | 604 : PartialParserRecorder(), |
| 701 symbol_store_(0), | 605 symbol_store_(0), |
| 702 symbol_entries_(0), | 606 symbol_entries_(0), |
| 703 symbol_table_(vector_compare), | 607 symbol_table_(vector_compare), |
| 704 symbol_id_(0) { | 608 symbol_id_(0) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 735 for (int i = 0; i < length; i++) { | 639 for (int i = 0; i < length; i++) { |
| 736 result[i] = start[i + 1]; | 640 result[i] = start[i + 1]; |
| 737 } | 641 } |
| 738 result[length] = '\0'; | 642 result[length] = '\0'; |
| 739 if (chars != NULL) *chars = length; | 643 if (chars != NULL) *chars = length; |
| 740 return result; | 644 return result; |
| 741 } | 645 } |
| 742 | 646 |
| 743 | 647 |
| 744 void PartialParserRecorder::LogMessage(Scanner::Location loc, | 648 void PartialParserRecorder::LogMessage(Scanner::Location loc, |
| 745 const char* message, | 649 const char* message, |
| 746 Vector<const char*> args) { | 650 Vector<const char*> args) { |
| 747 if (has_error()) return; | 651 if (has_error()) return; |
| 748 preamble_[ScriptDataImpl::kHasErrorOffset] = true; | 652 preamble_[ScriptDataImpl::kHasErrorOffset] = true; |
| 749 function_store_.Reset(); | 653 function_store_.Reset(); |
| 750 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); | 654 STATIC_ASSERT(ScriptDataImpl::kMessageStartPos == 0); |
| 751 function_store_.Add(loc.beg_pos); | 655 function_store_.Add(loc.beg_pos); |
| 752 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); | 656 STATIC_ASSERT(ScriptDataImpl::kMessageEndPos == 1); |
| 753 function_store_.Add(loc.end_pos); | 657 function_store_.Add(loc.end_pos); |
| 754 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); | 658 STATIC_ASSERT(ScriptDataImpl::kMessageArgCountPos == 2); |
| 755 function_store_.Add(args.length()); | 659 function_store_.Add(args.length()); |
| 756 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); | 660 STATIC_ASSERT(ScriptDataImpl::kMessageTextPos == 3); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 793 unsigned ScriptDataImpl::Read(int position) { | 697 unsigned ScriptDataImpl::Read(int position) { |
| 794 return store_[ScriptDataImpl::kHeaderSize + position]; | 698 return store_[ScriptDataImpl::kHeaderSize + position]; |
| 795 } | 699 } |
| 796 | 700 |
| 797 | 701 |
| 798 unsigned* ScriptDataImpl::ReadAddress(int position) { | 702 unsigned* ScriptDataImpl::ReadAddress(int position) { |
| 799 return &store_[ScriptDataImpl::kHeaderSize + position]; | 703 return &store_[ScriptDataImpl::kHeaderSize + position]; |
| 800 } | 704 } |
| 801 | 705 |
| 802 | 706 |
| 803 FunctionEntry PartialParserRecorder::LogFunction(int start) { | |
| 804 #ifdef DEBUG | |
| 805 ASSERT(start > prev_start); | |
| 806 prev_start = start; | |
| 807 #endif | |
| 808 if (!is_recording_) return FunctionEntry(); | |
| 809 FunctionEntry result(function_store_.AddBlock(FunctionEntry::kSize, 0)); | |
| 810 result.set_start_pos(start); | |
| 811 return result; | |
| 812 } | |
| 813 | |
| 814 | |
| 815 class AstBuildingParser : public Parser { | 707 class AstBuildingParser : public Parser { |
| 816 public: | 708 public: |
| 817 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, | 709 AstBuildingParser(Handle<Script> script, bool allow_natives_syntax, |
| 818 v8::Extension* extension, ScriptDataImpl* pre_data) | 710 v8::Extension* extension, ScriptDataImpl* pre_data) |
| 819 : Parser(script, | 711 : Parser(script, |
| 820 allow_natives_syntax, | 712 allow_natives_syntax, |
| 821 extension, | 713 extension, |
| 822 PARSE, | 714 PARSE, |
| 823 factory(), | 715 factory(), |
| 824 log(), | 716 log(), |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1029 allow_natives_syntax_(allow_natives_syntax), | 921 allow_natives_syntax_(allow_natives_syntax), |
| 1030 extension_(extension), | 922 extension_(extension), |
| 1031 factory_(factory), | 923 factory_(factory), |
| 1032 log_(log), | 924 log_(log), |
| 1033 is_pre_parsing_(is_pre_parsing == PREPARSE), | 925 is_pre_parsing_(is_pre_parsing == PREPARSE), |
| 1034 pre_data_(pre_data), | 926 pre_data_(pre_data), |
| 1035 fni_(NULL) { | 927 fni_(NULL) { |
| 1036 } | 928 } |
| 1037 | 929 |
| 1038 | 930 |
| 1039 bool Parser::PreParseProgram(Handle<String> source, | |
| 1040 unibrow::CharacterStream* stream) { | |
| 1041 HistogramTimerScope timer(&Counters::pre_parse); | |
| 1042 AssertNoZoneAllocation assert_no_zone_allocation; | |
| 1043 AssertNoAllocation assert_no_allocation; | |
| 1044 NoHandleAllocation no_handle_allocation; | |
| 1045 scanner_.Initialize(source, stream, JAVASCRIPT); | |
| 1046 ASSERT(target_stack_ == NULL); | |
| 1047 mode_ = FLAG_lazy ? PARSE_LAZILY : PARSE_EAGERLY; | |
| 1048 if (allow_natives_syntax_ || extension_ != NULL) mode_ = PARSE_EAGERLY; | |
| 1049 DummyScope top_scope; | |
| 1050 LexicalScope scope(&this->top_scope_, &this->with_nesting_level_, &top_scope); | |
| 1051 TemporaryScope temp_scope(&this->temp_scope_); | |
| 1052 ZoneListWrapper<Statement> processor; | |
| 1053 bool ok = true; | |
| 1054 ParseSourceElements(&processor, Token::EOS, &ok); | |
| 1055 return !scanner().stack_overflow(); | |
| 1056 } | |
| 1057 | |
| 1058 | |
| 1059 FunctionLiteral* Parser::ParseProgram(Handle<String> source, | 931 FunctionLiteral* Parser::ParseProgram(Handle<String> source, |
| 1060 bool in_global_context) { | 932 bool in_global_context) { |
| 1061 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); | 933 CompilationZoneScope zone_scope(DONT_DELETE_ON_EXIT); |
| 1062 | 934 |
| 1063 HistogramTimerScope timer(&Counters::parse); | 935 HistogramTimerScope timer(&Counters::parse); |
| 1064 Counters::total_parse_size.Increment(source->length()); | 936 Counters::total_parse_size.Increment(source->length()); |
| 1065 fni_ = new FuncNameInferrer(); | 937 fni_ = new FuncNameInferrer(); |
| 1066 | 938 |
| 1067 // Initialize parser state. | 939 // Initialize parser state. |
| 1068 source->TryFlatten(); | 940 source->TryFlatten(); |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1733 } | 1605 } |
| 1734 | 1606 |
| 1735 Expect(Token::NATIVE, CHECK_OK); | 1607 Expect(Token::NATIVE, CHECK_OK); |
| 1736 Expect(Token::FUNCTION, CHECK_OK); | 1608 Expect(Token::FUNCTION, CHECK_OK); |
| 1737 Handle<String> name = ParseIdentifier(CHECK_OK); | 1609 Handle<String> name = ParseIdentifier(CHECK_OK); |
| 1738 Expect(Token::LPAREN, CHECK_OK); | 1610 Expect(Token::LPAREN, CHECK_OK); |
| 1739 bool done = (peek() == Token::RPAREN); | 1611 bool done = (peek() == Token::RPAREN); |
| 1740 while (!done) { | 1612 while (!done) { |
| 1741 ParseIdentifier(CHECK_OK); | 1613 ParseIdentifier(CHECK_OK); |
| 1742 done = (peek() == Token::RPAREN); | 1614 done = (peek() == Token::RPAREN); |
| 1743 if (!done) Expect(Token::COMMA, CHECK_OK); | 1615 if (!done) { |
| 1616 Expect(Token::COMMA, CHECK_OK); |
| 1617 } |
| 1744 } | 1618 } |
| 1745 Expect(Token::RPAREN, CHECK_OK); | 1619 Expect(Token::RPAREN, CHECK_OK); |
| 1746 Expect(Token::SEMICOLON, CHECK_OK); | 1620 Expect(Token::SEMICOLON, CHECK_OK); |
| 1747 | 1621 |
| 1748 if (is_pre_parsing_) return NULL; | 1622 if (is_pre_parsing_) return NULL; |
| 1749 | 1623 |
| 1750 // Make sure that the function containing the native declaration | 1624 // Make sure that the function containing the native declaration |
| 1751 // isn't lazily compiled. The extension structures are only | 1625 // isn't lazily compiled. The extension structures are only |
| 1752 // accessible while parsing the first time not when reparsing | 1626 // accessible while parsing the first time not when reparsing |
| 1753 // because of lazy compilation. | 1627 // because of lazy compilation. |
| (...skipping 1959 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3713 } | 3587 } |
| 3714 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); | 3588 Counters::total_preparse_skipped.Increment(end_pos - function_block_pos); |
| 3715 scanner_.SeekForward(end_pos); | 3589 scanner_.SeekForward(end_pos); |
| 3716 materialized_literal_count = entry.literal_count(); | 3590 materialized_literal_count = entry.literal_count(); |
| 3717 expected_property_count = entry.property_count(); | 3591 expected_property_count = entry.property_count(); |
| 3718 only_simple_this_property_assignments = false; | 3592 only_simple_this_property_assignments = false; |
| 3719 this_property_assignments = Factory::empty_fixed_array(); | 3593 this_property_assignments = Factory::empty_fixed_array(); |
| 3720 Expect(Token::RBRACE, CHECK_OK); | 3594 Expect(Token::RBRACE, CHECK_OK); |
| 3721 } else { | 3595 } else { |
| 3722 FunctionEntry entry; | 3596 FunctionEntry entry; |
| 3723 if (is_lazily_compiled) entry = log()->LogFunction(function_block_pos); | |
| 3724 { | 3597 { |
| 3725 ConditionalLogPauseScope pause_if(is_lazily_compiled, log()); | 3598 ConditionalLogPauseScope pause_if(is_lazily_compiled, log()); |
| 3726 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); | 3599 ParseSourceElements(&body, Token::RBRACE, CHECK_OK); |
| 3727 } | 3600 } |
| 3728 materialized_literal_count = temp_scope.materialized_literal_count(); | 3601 materialized_literal_count = temp_scope.materialized_literal_count(); |
| 3729 expected_property_count = temp_scope.expected_property_count(); | 3602 expected_property_count = temp_scope.expected_property_count(); |
| 3730 only_simple_this_property_assignments = | 3603 only_simple_this_property_assignments = |
| 3731 temp_scope.only_simple_this_property_assignments(); | 3604 temp_scope.only_simple_this_property_assignments(); |
| 3732 this_property_assignments = temp_scope.this_property_assignments(); | 3605 this_property_assignments = temp_scope.this_property_assignments(); |
| 3733 | 3606 |
| 3734 Expect(Token::RBRACE, CHECK_OK); | 3607 Expect(Token::RBRACE, CHECK_OK); |
| 3735 end_pos = scanner_.location().end_pos; | 3608 end_pos = scanner_.location().end_pos; |
| 3736 if (entry.is_valid()) { | 3609 if (is_pre_parsing_ && is_lazily_compiled) { |
| 3737 ASSERT(is_lazily_compiled); | |
| 3738 ASSERT(is_pre_parsing_); | 3610 ASSERT(is_pre_parsing_); |
| 3739 entry.set_end_pos(end_pos); | 3611 log()->LogFunction(function_block_pos, end_pos, |
| 3740 entry.set_literal_count(materialized_literal_count); | 3612 materialized_literal_count, |
| 3741 entry.set_property_count(expected_property_count); | 3613 expected_property_count); |
| 3742 } | 3614 } |
| 3743 } | 3615 } |
| 3744 | 3616 |
| 3745 FunctionLiteral* function_literal = | 3617 FunctionLiteral* function_literal = |
| 3746 NEW(FunctionLiteral(name, | 3618 NEW(FunctionLiteral(name, |
| 3747 top_scope_, | 3619 top_scope_, |
| 3748 body.elements(), | 3620 body.elements(), |
| 3749 materialized_literal_count, | 3621 materialized_literal_count, |
| 3750 expected_property_count, | 3622 expected_property_count, |
| 3751 only_simple_this_property_assignments, | 3623 only_simple_this_property_assignments, |
| (...skipping 1244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4996 const char* ScriptDataImpl::Data() { | 4868 const char* ScriptDataImpl::Data() { |
| 4997 return reinterpret_cast<const char*>(store_.start()); | 4869 return reinterpret_cast<const char*>(store_.start()); |
| 4998 } | 4870 } |
| 4999 | 4871 |
| 5000 | 4872 |
| 5001 bool ScriptDataImpl::HasError() { | 4873 bool ScriptDataImpl::HasError() { |
| 5002 return has_error(); | 4874 return has_error(); |
| 5003 } | 4875 } |
| 5004 | 4876 |
| 5005 | 4877 |
| 5006 // Preparse, but only collect data that is immediately useful, | |
| 5007 // even if the preparser data is only used once. | |
| 5008 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, | |
| 5009 unibrow::CharacterStream* stream, | |
| 5010 v8::Extension* extension) { | |
| 5011 Handle<Script> no_script; | |
| 5012 bool allow_natives_syntax = | |
| 5013 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | |
| 5014 PartialPreParser parser(no_script, allow_natives_syntax, extension); | |
| 5015 if (!parser.PreParseProgram(source, stream)) return NULL; | |
| 5016 // Extract the accumulated data from the recorder as a single | |
| 5017 // contiguous vector that we are responsible for disposing. | |
| 5018 Vector<unsigned> store = parser.recorder()->ExtractData(); | |
| 5019 return new ScriptDataImpl(store); | |
| 5020 } | |
| 5021 | |
| 5022 | |
| 5023 void ScriptDataImpl::Initialize() { | 4878 void ScriptDataImpl::Initialize() { |
| 5024 // Prepares state for use. | 4879 // Prepares state for use. |
| 5025 if (store_.length() >= kHeaderSize) { | 4880 if (store_.length() >= kHeaderSize) { |
| 5026 function_index_ = kHeaderSize; | 4881 function_index_ = kHeaderSize; |
| 5027 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; | 4882 int symbol_data_offset = kHeaderSize + store_[kFunctionsSizeOffset]; |
| 5028 if (store_.length() > symbol_data_offset) { | 4883 if (store_.length() > symbol_data_offset) { |
| 5029 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); | 4884 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); |
| 5030 } else { | 4885 } else { |
| 5031 // Partial preparse causes no symbol information. | 4886 // Partial preparse causes no symbol information. |
| 5032 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); | 4887 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5056 if (data >= symbol_data_end_) return -1; | 4911 if (data >= symbol_data_end_) return -1; |
| 5057 input = *data; | 4912 input = *data; |
| 5058 result = (result << 7) | (input & 0x7f); | 4913 result = (result << 7) | (input & 0x7f); |
| 5059 data++; | 4914 data++; |
| 5060 } | 4915 } |
| 5061 *source = data; | 4916 *source = data; |
| 5062 return result; | 4917 return result; |
| 5063 } | 4918 } |
| 5064 | 4919 |
| 5065 | 4920 |
| 4921 // Preparse, but only collect data that is immediately useful, |
| 4922 // even if the preparser data is only used once. |
| 4923 ScriptDataImpl* ParserApi::PartialPreParse(Handle<String> source, |
| 4924 unibrow::CharacterStream* stream, |
| 4925 v8::Extension* extension) { |
| 4926 Handle<Script> no_script; |
| 4927 preparser::PreParser<Scanner, PartialParserRecorder> parser; |
| 4928 Scanner scanner; |
| 4929 scanner.Initialize(source, stream, JAVASCRIPT); |
| 4930 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4931 PartialParserRecorder recorder; |
| 4932 if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { |
| 4933 Top::StackOverflow(); |
| 4934 return NULL; |
| 4935 } |
| 4936 |
| 4937 // Extract the accumulated data from the recorder as a single |
| 4938 // contiguous vector that we are responsible for disposing. |
| 4939 Vector<unsigned> store = recorder.ExtractData(); |
| 4940 return new ScriptDataImpl(store); |
| 4941 } |
| 4942 |
| 4943 |
| 5066 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, | 4944 ScriptDataImpl* ParserApi::PreParse(Handle<String> source, |
| 5067 unibrow::CharacterStream* stream, | 4945 unibrow::CharacterStream* stream, |
| 5068 v8::Extension* extension) { | 4946 v8::Extension* extension) { |
| 5069 Handle<Script> no_script; | 4947 Handle<Script> no_script; |
| 5070 bool allow_natives_syntax = | 4948 preparser::PreParser<Scanner, CompleteParserRecorder> parser; |
| 5071 FLAG_allow_natives_syntax || Bootstrapper::IsActive(); | 4949 Scanner scanner; |
| 5072 CompletePreParser parser(no_script, allow_natives_syntax, extension); | 4950 scanner.Initialize(source, stream, JAVASCRIPT); |
| 5073 if (!parser.PreParseProgram(source, stream)) return NULL; | 4951 bool allow_lazy = FLAG_lazy && (extension == NULL); |
| 4952 CompleteParserRecorder recorder; |
| 4953 if (!parser.PreParseProgram(&scanner, &recorder, allow_lazy)) { |
| 4954 Top::StackOverflow(); |
| 4955 return NULL; |
| 4956 } |
| 5074 // Extract the accumulated data from the recorder as a single | 4957 // Extract the accumulated data from the recorder as a single |
| 5075 // contiguous vector that we are responsible for disposing. | 4958 // contiguous vector that we are responsible for disposing. |
| 5076 Vector<unsigned> store = parser.recorder()->ExtractData(); | 4959 Vector<unsigned> store = recorder.ExtractData(); |
| 5077 return new ScriptDataImpl(store); | 4960 return new ScriptDataImpl(store); |
| 5078 } | 4961 } |
| 5079 | 4962 |
| 5080 | 4963 |
| 5081 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4964 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
| 5082 bool multiline, | 4965 bool multiline, |
| 5083 RegExpCompileData* result) { | 4966 RegExpCompileData* result) { |
| 5084 ASSERT(result != NULL); | 4967 ASSERT(result != NULL); |
| 5085 RegExpParser parser(input, &result->error, multiline); | 4968 RegExpParser parser(input, &result->error, multiline); |
| 5086 RegExpTree* tree = parser.ParsePattern(); | 4969 RegExpTree* tree = parser.ParsePattern(); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5130 } | 5013 } |
| 5131 } | 5014 } |
| 5132 | 5015 |
| 5133 info->SetFunction(result); | 5016 info->SetFunction(result); |
| 5134 return (result != NULL); | 5017 return (result != NULL); |
| 5135 } | 5018 } |
| 5136 | 5019 |
| 5137 #undef NEW | 5020 #undef NEW |
| 5138 | 5021 |
| 5139 } } // namespace v8::internal | 5022 } } // namespace v8::internal |
| OLD | NEW |