Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(216)

Side by Side Diff: src/parser.cc

Issue 4112012: Stand-alone parser template. (Closed)
Patch Set: Addressed review comments. Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | src/preparser.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698