| 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 |