OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 // Only call immediately after adding an atom or character! | 198 // Only call immediately after adding an atom or character! |
199 UNREACHABLE(); | 199 UNREACHABLE(); |
200 return; | 200 return; |
201 } | 201 } |
202 terms_.Add( | 202 terms_.Add( |
203 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); | 203 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); |
204 LAST(ADD_TERM); | 204 LAST(ADD_TERM); |
205 } | 205 } |
206 | 206 |
207 | 207 |
208 Handle<String> Parser::LookupSymbol(int symbol_id) { | |
209 // If there is no preparser symbol data, a negative number will be passed. In | |
210 // that case, we'll just read the literal from Scanner. This also guards | |
211 // against corrupt preparse data where the symbol id is larger than the symbol | |
212 // count. | |
213 if (symbol_id < 0 || | |
214 (pre_parse_data_ && symbol_id >= pre_parse_data_->symbol_count())) { | |
215 return scanner()->AllocateInternalizedString(isolate_); | |
216 } | |
217 return LookupCachedSymbol(symbol_id); | |
218 } | |
219 | |
220 | |
221 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { | 208 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { |
222 // Make sure the cache is large enough to hold the symbol identifier. | 209 // Make sure the cache is large enough to hold the symbol identifier. |
223 if (symbol_cache_.length() <= symbol_id) { | 210 if (symbol_cache_.length() <= symbol_id) { |
224 // Increase length to index + 1. | 211 // Increase length to index + 1. |
225 symbol_cache_.AddBlock(Handle<String>::null(), | 212 symbol_cache_.AddBlock(Handle<String>::null(), |
226 symbol_id + 1 - symbol_cache_.length(), zone()); | 213 symbol_id + 1 - symbol_cache_.length(), zone()); |
227 } | 214 } |
228 Handle<String> result = symbol_cache_.at(symbol_id); | 215 Handle<String> result = symbol_cache_.at(symbol_id); |
229 if (result.is_null()) { | 216 if (result.is_null()) { |
230 result = scanner()->AllocateInternalizedString(isolate_); | 217 result = scanner()->AllocateInternalizedString(isolate_); |
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
593 } | 580 } |
594 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 581 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
595 Handle<Object> result = is_reference_error | 582 Handle<Object> result = is_reference_error |
596 ? factory->NewReferenceError(message, array) | 583 ? factory->NewReferenceError(message, array) |
597 : factory->NewSyntaxError(message, array); | 584 : factory->NewSyntaxError(message, array); |
598 parser_->isolate()->Throw(*result, &location); | 585 parser_->isolate()->Throw(*result, &location); |
599 } | 586 } |
600 | 587 |
601 | 588 |
602 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { | 589 Handle<String> ParserTraits::GetSymbol(Scanner* scanner) { |
603 int symbol_id = -1; | 590 if (parser_->cached_data_mode() == CONSUME_CACHED_DATA) { |
604 if (parser_->pre_parse_data() != NULL) { | 591 int symbol_id = (*parser_->cached_data())->GetSymbolIdentifier(); |
605 symbol_id = parser_->pre_parse_data()->GetSymbolIdentifier(); | 592 // If there is no symbol data, -1 will be returned. |
| 593 if (symbol_id >= 0 && |
| 594 symbol_id < (*parser_->cached_data())->symbol_count()) { |
| 595 return parser_->LookupCachedSymbol(symbol_id); |
| 596 } |
| 597 } else if (parser_->cached_data_mode() == PRODUCE_CACHED_DATA) { |
| 598 if (parser_->log_->ShouldLogSymbols()) { |
| 599 parser_->scanner()->LogSymbol(parser_->log_, parser_->position()); |
| 600 } |
606 } | 601 } |
607 return parser_->LookupSymbol(symbol_id); | 602 return parser_->scanner()->AllocateInternalizedString(parser_->isolate_); |
608 } | 603 } |
609 | 604 |
610 | 605 |
611 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, | 606 Handle<String> ParserTraits::NextLiteralString(Scanner* scanner, |
612 PretenureFlag tenured) { | 607 PretenureFlag tenured) { |
613 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); | 608 return scanner->AllocateNextLiteralString(parser_->isolate(), tenured); |
614 } | 609 } |
615 | 610 |
616 | 611 |
617 Expression* ParserTraits::ThisExpression( | 612 Expression* ParserTraits::ThisExpression( |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
695 | 690 |
696 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { | 691 Expression* ParserTraits::ParseUnaryExpression(bool* ok) { |
697 return parser_->ParseUnaryExpression(ok); | 692 return parser_->ParseUnaryExpression(ok); |
698 } | 693 } |
699 | 694 |
700 | 695 |
701 Parser::Parser(CompilationInfo* info) | 696 Parser::Parser(CompilationInfo* info) |
702 : ParserBase<ParserTraits>(&scanner_, | 697 : ParserBase<ParserTraits>(&scanner_, |
703 info->isolate()->stack_guard()->real_climit(), | 698 info->isolate()->stack_guard()->real_climit(), |
704 info->extension(), | 699 info->extension(), |
| 700 NULL, |
705 info->zone(), | 701 info->zone(), |
706 this), | 702 this), |
707 isolate_(info->isolate()), | 703 isolate_(info->isolate()), |
708 symbol_cache_(0, info->zone()), | 704 symbol_cache_(0, info->zone()), |
709 script_(info->script()), | 705 script_(info->script()), |
710 scanner_(isolate_->unicode_cache()), | 706 scanner_(isolate_->unicode_cache()), |
711 reusable_preparser_(NULL), | 707 reusable_preparser_(NULL), |
712 original_scope_(NULL), | 708 original_scope_(NULL), |
713 target_stack_(NULL), | 709 target_stack_(NULL), |
714 pre_parse_data_(NULL), | 710 cached_data_(NULL), |
| 711 cached_data_mode_(NO_CACHED_DATA), |
715 info_(info) { | 712 info_(info) { |
716 ASSERT(!script_.is_null()); | 713 ASSERT(!script_.is_null()); |
717 isolate_->set_ast_node_id(0); | 714 isolate_->set_ast_node_id(0); |
718 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 715 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
719 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 716 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
720 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 717 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
721 set_allow_lazy(false); // Must be explicitly enabled. | 718 set_allow_lazy(false); // Must be explicitly enabled. |
722 set_allow_generators(FLAG_harmony_generators); | 719 set_allow_generators(FLAG_harmony_generators); |
723 set_allow_for_of(FLAG_harmony_iteration); | 720 set_allow_for_of(FLAG_harmony_iteration); |
724 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 721 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
725 } | 722 } |
726 | 723 |
727 | 724 |
728 FunctionLiteral* Parser::ParseProgram() { | 725 FunctionLiteral* Parser::ParseProgram() { |
729 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 726 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
730 // see comment for HistogramTimerScope class. | 727 // see comment for HistogramTimerScope class. |
731 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 728 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
732 Handle<String> source(String::cast(script_->source())); | 729 Handle<String> source(String::cast(script_->source())); |
733 isolate()->counters()->total_parse_size()->Increment(source->length()); | 730 isolate()->counters()->total_parse_size()->Increment(source->length()); |
734 ElapsedTimer timer; | 731 ElapsedTimer timer; |
735 if (FLAG_trace_parse) { | 732 if (FLAG_trace_parse) { |
736 timer.Start(); | 733 timer.Start(); |
737 } | 734 } |
738 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); | 735 fni_ = new(zone()) FuncNameInferrer(isolate(), zone()); |
739 | 736 |
740 // Initialize parser state. | 737 // Initialize parser state. |
| 738 CompleteParserRecorder recorder; |
| 739 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 740 log_ = &recorder; |
| 741 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
| 742 (*cached_data_)->Initialize(); |
| 743 } |
| 744 |
741 source->TryFlatten(); | 745 source->TryFlatten(); |
742 FunctionLiteral* result; | 746 FunctionLiteral* result; |
743 if (source->IsExternalTwoByteString()) { | 747 if (source->IsExternalTwoByteString()) { |
744 // Notice that the stream is destroyed at the end of the branch block. | 748 // Notice that the stream is destroyed at the end of the branch block. |
745 // The last line of the blocks can't be moved outside, even though they're | 749 // The last line of the blocks can't be moved outside, even though they're |
746 // identical calls. | 750 // identical calls. |
747 ExternalTwoByteStringUtf16CharacterStream stream( | 751 ExternalTwoByteStringUtf16CharacterStream stream( |
748 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 752 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
749 scanner_.Initialize(&stream); | 753 scanner_.Initialize(&stream); |
750 result = DoParseProgram(info(), source); | 754 result = DoParseProgram(info(), source); |
751 } else { | 755 } else { |
752 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 756 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
753 scanner_.Initialize(&stream); | 757 scanner_.Initialize(&stream); |
754 result = DoParseProgram(info(), source); | 758 result = DoParseProgram(info(), source); |
755 } | 759 } |
756 | 760 |
757 if (FLAG_trace_parse && result != NULL) { | 761 if (FLAG_trace_parse && result != NULL) { |
758 double ms = timer.Elapsed().InMillisecondsF(); | 762 double ms = timer.Elapsed().InMillisecondsF(); |
759 if (info()->is_eval()) { | 763 if (info()->is_eval()) { |
760 PrintF("[parsing eval"); | 764 PrintF("[parsing eval"); |
761 } else if (info()->script()->name()->IsString()) { | 765 } else if (info()->script()->name()->IsString()) { |
762 String* name = String::cast(info()->script()->name()); | 766 String* name = String::cast(info()->script()->name()); |
763 SmartArrayPointer<char> name_chars = name->ToCString(); | 767 SmartArrayPointer<char> name_chars = name->ToCString(); |
764 PrintF("[parsing script: %s", name_chars.get()); | 768 PrintF("[parsing script: %s", name_chars.get()); |
765 } else { | 769 } else { |
766 PrintF("[parsing script"); | 770 PrintF("[parsing script"); |
767 } | 771 } |
768 PrintF(" - took %0.3f ms]\n", ms); | 772 PrintF(" - took %0.3f ms]\n", ms); |
769 } | 773 } |
| 774 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 775 Vector<unsigned> store = recorder.ExtractData(); |
| 776 *cached_data_ = new ScriptDataImpl(store); |
| 777 log_ = NULL; |
| 778 } |
770 return result; | 779 return result; |
771 } | 780 } |
772 | 781 |
773 | 782 |
774 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 783 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
775 Handle<String> source) { | 784 Handle<String> source) { |
776 ASSERT(scope_ == NULL); | 785 ASSERT(scope_ == NULL); |
777 ASSERT(target_stack_ == NULL); | 786 ASSERT(target_stack_ == NULL); |
778 if (pre_parse_data_ != NULL) pre_parse_data_->Initialize(); | |
779 | 787 |
780 Handle<String> no_name = isolate()->factory()->empty_string(); | 788 Handle<String> no_name = isolate()->factory()->empty_string(); |
781 | 789 |
782 FunctionLiteral* result = NULL; | 790 FunctionLiteral* result = NULL; |
783 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); | 791 { Scope* scope = NewScope(scope_, GLOBAL_SCOPE); |
784 info->SetGlobalScope(scope); | 792 info->SetGlobalScope(scope); |
785 if (!info->context().is_null()) { | 793 if (!info->context().is_null()) { |
786 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); | 794 scope = Scope::DeserializeScopeChain(*info->context(), scope, zone()); |
787 } | 795 } |
788 original_scope_ = scope; | 796 original_scope_ = scope; |
(...skipping 2784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3573 // To make this additional case work, both Parser and PreParser implement a | 3581 // To make this additional case work, both Parser and PreParser implement a |
3574 // logic where only top-level functions will be parsed lazily. | 3582 // logic where only top-level functions will be parsed lazily. |
3575 bool is_lazily_parsed = (mode() == PARSE_LAZILY && | 3583 bool is_lazily_parsed = (mode() == PARSE_LAZILY && |
3576 scope_->AllowsLazyCompilation() && | 3584 scope_->AllowsLazyCompilation() && |
3577 !parenthesized_function_); | 3585 !parenthesized_function_); |
3578 parenthesized_function_ = false; // The bit was set for this function only. | 3586 parenthesized_function_ = false; // The bit was set for this function only. |
3579 | 3587 |
3580 if (is_lazily_parsed) { | 3588 if (is_lazily_parsed) { |
3581 int function_block_pos = position(); | 3589 int function_block_pos = position(); |
3582 FunctionEntry entry; | 3590 FunctionEntry entry; |
3583 if (pre_parse_data_ != NULL) { | 3591 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
3584 // If we have pre_parse_data_, we use it to skip parsing the function | 3592 // If we have cached data, we use it to skip parsing the function body. |
3585 // body. The preparser data contains the information we need to | 3593 // The data contains the information we need to construct the lazy |
3586 // construct the lazy function. | 3594 // function. |
3587 entry = pre_parse_data()->GetFunctionEntry(function_block_pos); | 3595 entry = (*cached_data())->GetFunctionEntry(function_block_pos); |
3588 if (entry.is_valid()) { | 3596 if (entry.is_valid()) { |
3589 if (entry.end_pos() <= function_block_pos) { | 3597 if (entry.end_pos() <= function_block_pos) { |
3590 // End position greater than end of stream is safe, and hard | 3598 // End position greater than end of stream is safe, and hard |
3591 // to check. | 3599 // to check. |
3592 ReportInvalidPreparseData(function_name, CHECK_OK); | 3600 ReportInvalidPreparseData(function_name, CHECK_OK); |
3593 } | 3601 } |
3594 scanner()->SeekForward(entry.end_pos() - 1); | 3602 scanner()->SeekForward(entry.end_pos() - 1); |
3595 | 3603 |
3596 scope->set_end_position(entry.end_pos()); | 3604 scope->set_end_position(entry.end_pos()); |
3597 Expect(Token::RBRACE, CHECK_OK); | 3605 Expect(Token::RBRACE, CHECK_OK); |
3598 isolate()->counters()->total_preparse_skipped()->Increment( | 3606 isolate()->counters()->total_preparse_skipped()->Increment( |
3599 scope->end_position() - function_block_pos); | 3607 scope->end_position() - function_block_pos); |
3600 materialized_literal_count = entry.literal_count(); | 3608 materialized_literal_count = entry.literal_count(); |
3601 expected_property_count = entry.property_count(); | 3609 expected_property_count = entry.property_count(); |
3602 scope_->SetStrictMode(entry.strict_mode()); | 3610 scope_->SetStrictMode(entry.strict_mode()); |
3603 } else { | 3611 } else { |
3604 // This case happens when we have preparse data but it doesn't contain | 3612 // This case happens when we have preparse data but it doesn't contain |
3605 // an entry for the function. As a safety net, fall back to eager | 3613 // an entry for the function. As a safety net, fall back to eager |
3606 // parsing. It is unclear whether PreParser's laziness analysis can | 3614 // parsing. It is unclear whether PreParser's laziness analysis can |
3607 // produce different results than the Parser's laziness analysis (see | 3615 // produce different results than the Parser's laziness analysis (see |
3608 // https://codereview.chromium.org/7565003 ). This safety net is | 3616 // https://codereview.chromium.org/7565003 ). In this case, we must |
3609 // guarding against the case where Parser thinks a function should be | 3617 // discard all the preparse data, since the symbol data will be wrong. |
3610 // lazily parsed, but PreParser thinks it should be eagerly parsed -- | |
3611 // in that case we fall back to eager parsing in Parser, too. Note | |
3612 // that the opposite case is worse: if PreParser thinks a function | |
3613 // should be lazily parsed, but Parser thinks it should be eagerly | |
3614 // parsed, it will never advance the preparse data beyond that | |
3615 // function and all further laziness will fail (all functions will be | |
3616 // parsed eagerly). | |
3617 is_lazily_parsed = false; | 3618 is_lazily_parsed = false; |
| 3619 cached_data_mode_ = NO_CACHED_DATA; |
3618 } | 3620 } |
3619 } else { | 3621 } else { |
3620 // With no preparser data, we partially parse the function, without | 3622 // With no cached data, we partially parse the function, without |
3621 // building an AST. This gathers the data needed to build a lazy | 3623 // building an AST. This gathers the data needed to build a lazy |
3622 // function. | 3624 // function. |
| 3625 // FIXME(marja): Now the PreParser doesn't need to log functions / |
| 3626 // symbols; only errors -> clean that up. |
3623 SingletonLogger logger; | 3627 SingletonLogger logger; |
3624 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); | 3628 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
3625 if (result == PreParser::kPreParseStackOverflow) { | 3629 if (result == PreParser::kPreParseStackOverflow) { |
3626 // Propagate stack overflow. | 3630 // Propagate stack overflow. |
3627 set_stack_overflow(); | 3631 set_stack_overflow(); |
3628 *ok = false; | 3632 *ok = false; |
3629 return NULL; | 3633 return NULL; |
3630 } | 3634 } |
3631 if (logger.has_error()) { | 3635 if (logger.has_error()) { |
3632 const char* arg = logger.argument_opt(); | 3636 const char* arg = logger.argument_opt(); |
3633 Vector<const char*> args; | 3637 Vector<const char*> args; |
3634 if (arg != NULL) { | 3638 if (arg != NULL) { |
3635 args = Vector<const char*>(&arg, 1); | 3639 args = Vector<const char*>(&arg, 1); |
3636 } | 3640 } |
3637 ParserTraits::ReportMessageAt( | 3641 ParserTraits::ReportMessageAt( |
3638 Scanner::Location(logger.start(), logger.end()), | 3642 Scanner::Location(logger.start(), logger.end()), |
3639 logger.message(), | 3643 logger.message(), |
3640 args); | 3644 args); |
3641 *ok = false; | 3645 *ok = false; |
3642 return NULL; | 3646 return NULL; |
3643 } | 3647 } |
3644 scope->set_end_position(logger.end()); | 3648 scope->set_end_position(logger.end()); |
3645 Expect(Token::RBRACE, CHECK_OK); | 3649 Expect(Token::RBRACE, CHECK_OK); |
3646 isolate()->counters()->total_preparse_skipped()->Increment( | 3650 isolate()->counters()->total_preparse_skipped()->Increment( |
3647 scope->end_position() - function_block_pos); | 3651 scope->end_position() - function_block_pos); |
3648 materialized_literal_count = logger.literals(); | 3652 materialized_literal_count = logger.literals(); |
3649 expected_property_count = logger.properties(); | 3653 expected_property_count = logger.properties(); |
3650 scope_->SetStrictMode(logger.strict_mode()); | 3654 scope_->SetStrictMode(logger.strict_mode()); |
| 3655 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { |
| 3656 ASSERT(log_); |
| 3657 // Position right after terminal '}'. |
| 3658 int body_end = scanner()->location().end_pos; |
| 3659 log_->LogFunction(function_block_pos, body_end, |
| 3660 materialized_literal_count, |
| 3661 expected_property_count, |
| 3662 scope_->strict_mode()); |
| 3663 } |
3651 } | 3664 } |
3652 } | 3665 } |
3653 | 3666 |
3654 if (!is_lazily_parsed) { | 3667 if (!is_lazily_parsed) { |
3655 // Everything inside an eagerly parsed function will be parsed eagerly | 3668 // Everything inside an eagerly parsed function will be parsed eagerly |
3656 // (see comment above). | 3669 // (see comment above). |
3657 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 3670 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
3658 body = new(zone()) ZoneList<Statement*>(8, zone()); | 3671 body = new(zone()) ZoneList<Statement*>(8, zone()); |
3659 if (fvar != NULL) { | 3672 if (fvar != NULL) { |
3660 VariableProxy* fproxy = scope_->NewUnresolved( | 3673 VariableProxy* fproxy = scope_->NewUnresolved( |
(...skipping 1254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4915 ASSERT(info()->function() == NULL); | 4928 ASSERT(info()->function() == NULL); |
4916 FunctionLiteral* result = NULL; | 4929 FunctionLiteral* result = NULL; |
4917 if (info()->is_lazy()) { | 4930 if (info()->is_lazy()) { |
4918 ASSERT(!info()->is_eval()); | 4931 ASSERT(!info()->is_eval()); |
4919 if (info()->shared_info()->is_function()) { | 4932 if (info()->shared_info()->is_function()) { |
4920 result = ParseLazy(); | 4933 result = ParseLazy(); |
4921 } else { | 4934 } else { |
4922 result = ParseProgram(); | 4935 result = ParseProgram(); |
4923 } | 4936 } |
4924 } else { | 4937 } else { |
4925 ScriptDataImpl* pre_parse_data = info()->pre_parse_data(); | 4938 SetCachedData(info()->cached_data(), info()->cached_data_mode()); |
4926 set_pre_parse_data(pre_parse_data); | 4939 if (info()->cached_data_mode() == CONSUME_CACHED_DATA && |
4927 if (pre_parse_data != NULL && pre_parse_data->has_error()) { | 4940 (*info()->cached_data())->has_error()) { |
4928 Scanner::Location loc = pre_parse_data->MessageLocation(); | 4941 ScriptDataImpl* cached_data = *(info()->cached_data()); |
4929 const char* message = pre_parse_data->BuildMessage(); | 4942 Scanner::Location loc = cached_data->MessageLocation(); |
4930 Vector<const char*> args = pre_parse_data->BuildArgs(); | 4943 const char* message = cached_data->BuildMessage(); |
| 4944 Vector<const char*> args = cached_data->BuildArgs(); |
4931 ParserTraits::ReportMessageAt(loc, message, args); | 4945 ParserTraits::ReportMessageAt(loc, message, args); |
4932 DeleteArray(message); | 4946 DeleteArray(message); |
4933 for (int i = 0; i < args.length(); i++) { | 4947 for (int i = 0; i < args.length(); i++) { |
4934 DeleteArray(args[i]); | 4948 DeleteArray(args[i]); |
4935 } | 4949 } |
4936 DeleteArray(args.start()); | 4950 DeleteArray(args.start()); |
4937 ASSERT(info()->isolate()->has_pending_exception()); | 4951 ASSERT(info()->isolate()->has_pending_exception()); |
4938 } else { | 4952 } else { |
4939 result = ParseProgram(); | 4953 result = ParseProgram(); |
4940 } | 4954 } |
4941 } | 4955 } |
4942 info()->SetFunction(result); | 4956 info()->SetFunction(result); |
4943 return (result != NULL); | 4957 return (result != NULL); |
4944 } | 4958 } |
4945 | 4959 |
4946 } } // namespace v8::internal | 4960 } } // namespace v8::internal |
OLD | NEW |