| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/api.h" | 7 #include "src/api.h" |
| 8 #include "src/ast.h" | 8 #include "src/ast.h" |
| 9 #include "src/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
| 10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
| (...skipping 721 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 732 FunctionLiteral::FunctionType type, | 732 FunctionLiteral::FunctionType type, |
| 733 FunctionLiteral::ArityRestriction arity_restriction, | 733 FunctionLiteral::ArityRestriction arity_restriction, |
| 734 bool* ok) { | 734 bool* ok) { |
| 735 return parser_->ParseFunctionLiteral(name, function_name_location, | 735 return parser_->ParseFunctionLiteral(name, function_name_location, |
| 736 name_is_strict_reserved, is_generator, | 736 name_is_strict_reserved, is_generator, |
| 737 function_token_position, type, | 737 function_token_position, type, |
| 738 arity_restriction, ok); | 738 arity_restriction, ok); |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 Parser::Parser(CompilationInfo* info) | 742 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info) |
| 743 : ParserBase<ParserTraits>( | 743 : ParserBase<ParserTraits>(&scanner_, parse_info->stack_limit, |
| 744 &scanner_, info->isolate()->stack_guard()->real_climit(), | 744 info->extension(), NULL, info->zone(), |
| 745 info->extension(), NULL, info->zone(), info->ast_node_id_gen(), this), | 745 info->ast_node_id_gen(), this), |
| 746 isolate_(info->isolate()), | 746 isolate_(info->isolate()), |
| 747 script_(info->script()), | 747 script_(info->script()), |
| 748 scanner_(isolate_->unicode_cache()), | 748 scanner_(parse_info->unicode_cache), |
| 749 reusable_preparser_(NULL), | 749 reusable_preparser_(NULL), |
| 750 original_scope_(NULL), | 750 original_scope_(NULL), |
| 751 target_stack_(NULL), | 751 target_stack_(NULL), |
| 752 cached_parse_data_(NULL), | 752 cached_parse_data_(NULL), |
| 753 ast_value_factory_(NULL), | 753 ast_value_factory_(info->ast_value_factory()), |
| 754 info_(info), | 754 info_(info), |
| 755 has_pending_error_(false), | 755 has_pending_error_(false), |
| 756 pending_error_message_(NULL), | 756 pending_error_message_(NULL), |
| 757 pending_error_arg_(NULL), | 757 pending_error_arg_(NULL), |
| 758 pending_error_char_arg_(NULL) { | 758 pending_error_char_arg_(NULL), |
| 759 total_preparse_skipped_(0), |
| 760 pre_parse_timer_(NULL) { |
| 759 DCHECK(!script_.is_null()); | 761 DCHECK(!script_.is_null()); |
| 760 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 762 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
| 761 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 763 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
| 762 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); | 764 set_allow_natives_syntax(FLAG_allow_natives_syntax || info->is_native()); |
| 763 set_allow_lazy(false); // Must be explicitly enabled. | 765 set_allow_lazy(false); // Must be explicitly enabled. |
| 764 set_allow_generators(FLAG_harmony_generators); | 766 set_allow_generators(FLAG_harmony_generators); |
| 765 set_allow_arrow_functions(FLAG_harmony_arrow_functions); | 767 set_allow_arrow_functions(FLAG_harmony_arrow_functions); |
| 766 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 768 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
| 767 set_allow_classes(FLAG_harmony_classes); | 769 set_allow_classes(FLAG_harmony_classes); |
| 768 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 770 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 769 ++feature) { | 771 ++feature) { |
| 770 use_counts_[feature] = 0; | 772 use_counts_[feature] = 0; |
| 771 } | 773 } |
| 774 if (ast_value_factory_ == NULL) { |
| 775 ast_value_factory_ = new AstValueFactory(zone(), parse_info->hash_seed); |
| 776 } |
| 772 } | 777 } |
| 773 | 778 |
| 774 | 779 |
| 775 FunctionLiteral* Parser::ParseProgram() { | 780 FunctionLiteral* Parser::ParseProgram() { |
| 776 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 781 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
| 777 // see comment for HistogramTimerScope class. | 782 // see comment for HistogramTimerScope class. |
| 783 |
| 784 // It's OK to use the counters here, since this function is only called in |
| 785 // the main thread. |
| 778 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 786 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); |
| 779 Handle<String> source(String::cast(script_->source())); | 787 Handle<String> source(String::cast(script_->source())); |
| 780 isolate()->counters()->total_parse_size()->Increment(source->length()); | 788 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 781 base::ElapsedTimer timer; | 789 base::ElapsedTimer timer; |
| 782 if (FLAG_trace_parse) { | 790 if (FLAG_trace_parse) { |
| 783 timer.Start(); | 791 timer.Start(); |
| 784 } | 792 } |
| 785 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 793 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
| 786 | 794 |
| 787 // Initialize parser state. | 795 // Initialize parser state. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 801 // identical calls. | 809 // identical calls. |
| 802 ExternalTwoByteStringUtf16CharacterStream stream( | 810 ExternalTwoByteStringUtf16CharacterStream stream( |
| 803 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 811 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
| 804 scanner_.Initialize(&stream); | 812 scanner_.Initialize(&stream); |
| 805 result = DoParseProgram(info(), source); | 813 result = DoParseProgram(info(), source); |
| 806 } else { | 814 } else { |
| 807 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 815 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
| 808 scanner_.Initialize(&stream); | 816 scanner_.Initialize(&stream); |
| 809 result = DoParseProgram(info(), source); | 817 result = DoParseProgram(info(), source); |
| 810 } | 818 } |
| 819 HandleSourceURLComments(); |
| 811 | 820 |
| 812 if (FLAG_trace_parse && result != NULL) { | 821 if (FLAG_trace_parse && result != NULL) { |
| 813 double ms = timer.Elapsed().InMillisecondsF(); | 822 double ms = timer.Elapsed().InMillisecondsF(); |
| 814 if (info()->is_eval()) { | 823 if (info()->is_eval()) { |
| 815 PrintF("[parsing eval"); | 824 PrintF("[parsing eval"); |
| 816 } else if (info()->script()->name()->IsString()) { | 825 } else if (info()->script()->name()->IsString()) { |
| 817 String* name = String::cast(info()->script()->name()); | 826 String* name = String::cast(info()->script()->name()); |
| 818 SmartArrayPointer<char> name_chars = name->ToCString(); | 827 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 819 PrintF("[parsing script: %s", name_chars.get()); | 828 PrintF("[parsing script: %s", name_chars.get()); |
| 820 } else { | 829 } else { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 // Enters 'scope'. | 878 // Enters 'scope'. |
| 870 FunctionState function_state(&function_state_, &scope_, scope, zone(), | 879 FunctionState function_state(&function_state_, &scope_, scope, zone(), |
| 871 ast_value_factory_, info->ast_node_id_gen()); | 880 ast_value_factory_, info->ast_node_id_gen()); |
| 872 | 881 |
| 873 scope_->SetStrictMode(info->strict_mode()); | 882 scope_->SetStrictMode(info->strict_mode()); |
| 874 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); | 883 ZoneList<Statement*>* body = new(zone()) ZoneList<Statement*>(16, zone()); |
| 875 bool ok = true; | 884 bool ok = true; |
| 876 int beg_pos = scanner()->location().beg_pos; | 885 int beg_pos = scanner()->location().beg_pos; |
| 877 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); | 886 ParseSourceElements(body, Token::EOS, info->is_eval(), true, &ok); |
| 878 | 887 |
| 879 HandleSourceURLComments(); | |
| 880 | |
| 881 if (ok && strict_mode() == STRICT) { | 888 if (ok && strict_mode() == STRICT) { |
| 882 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); | 889 CheckOctalLiteral(beg_pos, scanner()->location().end_pos, &ok); |
| 883 } | 890 } |
| 884 | 891 |
| 885 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { | 892 if (ok && allow_harmony_scoping() && strict_mode() == STRICT) { |
| 886 CheckConflictingVarDeclarations(scope_, &ok); | 893 CheckConflictingVarDeclarations(scope_, &ok); |
| 887 } | 894 } |
| 888 | 895 |
| 889 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { | 896 if (ok && info->parse_restriction() == ONLY_SINGLE_FUNCTION_LITERAL) { |
| 890 if (body->length() != 1 || | 897 if (body->length() != 1 || |
| 891 !body->at(0)->IsExpressionStatement() || | 898 !body->at(0)->IsExpressionStatement() || |
| 892 !body->at(0)->AsExpressionStatement()-> | 899 !body->at(0)->AsExpressionStatement()-> |
| 893 expression()->IsFunctionLiteral()) { | 900 expression()->IsFunctionLiteral()) { |
| 894 ReportMessage("single_function_literal"); | 901 ReportMessage("single_function_literal"); |
| 895 ok = false; | 902 ok = false; |
| 896 } | 903 } |
| 897 } | 904 } |
| 898 | 905 |
| 899 ast_value_factory_->Internalize(isolate()); | |
| 900 if (ok) { | 906 if (ok) { |
| 901 result = factory()->NewFunctionLiteral( | 907 result = factory()->NewFunctionLiteral( |
| 902 ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, | 908 ast_value_factory_->empty_string(), ast_value_factory_, scope_, body, |
| 903 function_state.materialized_literal_count(), | 909 function_state.materialized_literal_count(), |
| 904 function_state.expected_property_count(), | 910 function_state.expected_property_count(), |
| 905 function_state.handler_count(), 0, | 911 function_state.handler_count(), 0, |
| 906 FunctionLiteral::kNoDuplicateParameters, | 912 FunctionLiteral::kNoDuplicateParameters, |
| 907 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, | 913 FunctionLiteral::ANONYMOUS_EXPRESSION, FunctionLiteral::kGlobalOrEval, |
| 908 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNormalFunction, | 914 FunctionLiteral::kNotParenthesized, FunctionLiteral::kNormalFunction, |
| 909 0); | 915 0); |
| 910 result->set_ast_properties(factory()->visitor()->ast_properties()); | 916 result->set_ast_properties(factory()->visitor()->ast_properties()); |
| 911 result->set_dont_optimize_reason( | 917 result->set_dont_optimize_reason( |
| 912 factory()->visitor()->dont_optimize_reason()); | 918 factory()->visitor()->dont_optimize_reason()); |
| 913 } else if (stack_overflow()) { | |
| 914 isolate()->StackOverflow(); | |
| 915 } else { | |
| 916 ThrowPendingError(); | |
| 917 } | 919 } |
| 918 } | 920 } |
| 919 | 921 |
| 920 // Make sure the target stack is empty. | 922 // Make sure the target stack is empty. |
| 921 DCHECK(target_stack_ == NULL); | 923 DCHECK(target_stack_ == NULL); |
| 922 | 924 |
| 923 return result; | 925 return result; |
| 924 } | 926 } |
| 925 | 927 |
| 926 | 928 |
| 927 FunctionLiteral* Parser::ParseLazy() { | 929 FunctionLiteral* Parser::ParseLazy() { |
| 930 // It's OK to use the counters here, since this function is only called in |
| 931 // the main thread. |
| 928 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 932 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); |
| 929 Handle<String> source(String::cast(script_->source())); | 933 Handle<String> source(String::cast(script_->source())); |
| 930 isolate()->counters()->total_parse_size()->Increment(source->length()); | 934 isolate()->counters()->total_parse_size()->Increment(source->length()); |
| 931 base::ElapsedTimer timer; | 935 base::ElapsedTimer timer; |
| 932 if (FLAG_trace_parse) { | 936 if (FLAG_trace_parse) { |
| 933 timer.Start(); | 937 timer.Start(); |
| 934 } | 938 } |
| 935 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 939 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); |
| 936 | 940 |
| 937 // Initialize parser state. | 941 // Initialize parser state. |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1010 function_type, | 1014 function_type, |
| 1011 FunctionLiteral::NORMAL_ARITY, &ok); | 1015 FunctionLiteral::NORMAL_ARITY, &ok); |
| 1012 } | 1016 } |
| 1013 // Make sure the results agree. | 1017 // Make sure the results agree. |
| 1014 DCHECK(ok == (result != NULL)); | 1018 DCHECK(ok == (result != NULL)); |
| 1015 } | 1019 } |
| 1016 | 1020 |
| 1017 // Make sure the target stack is empty. | 1021 // Make sure the target stack is empty. |
| 1018 DCHECK(target_stack_ == NULL); | 1022 DCHECK(target_stack_ == NULL); |
| 1019 | 1023 |
| 1020 ast_value_factory_->Internalize(isolate()); | 1024 if (result != NULL) { |
| 1021 if (result == NULL) { | |
| 1022 if (stack_overflow()) { | |
| 1023 isolate()->StackOverflow(); | |
| 1024 } else { | |
| 1025 ThrowPendingError(); | |
| 1026 } | |
| 1027 } else { | |
| 1028 Handle<String> inferred_name(shared_info->inferred_name()); | 1025 Handle<String> inferred_name(shared_info->inferred_name()); |
| 1029 result->set_inferred_name(inferred_name); | 1026 result->set_inferred_name(inferred_name); |
| 1030 } | 1027 } |
| 1031 return result; | 1028 return result; |
| 1032 } | 1029 } |
| 1033 | 1030 |
| 1034 | 1031 |
| 1035 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, | 1032 void* Parser::ParseSourceElements(ZoneList<Statement*>* processor, |
| 1036 int end_token, | 1033 int end_token, |
| 1037 bool is_eval, | 1034 bool is_eval, |
| (...skipping 2609 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3647 CHECK(entry.is_valid()); | 3644 CHECK(entry.is_valid()); |
| 3648 // End position greater than end of stream is safe, and hard to check. | 3645 // End position greater than end of stream is safe, and hard to check. |
| 3649 CHECK(entry.end_pos() > function_block_pos); | 3646 CHECK(entry.end_pos() > function_block_pos); |
| 3650 scanner()->SeekForward(entry.end_pos() - 1); | 3647 scanner()->SeekForward(entry.end_pos() - 1); |
| 3651 | 3648 |
| 3652 scope_->set_end_position(entry.end_pos()); | 3649 scope_->set_end_position(entry.end_pos()); |
| 3653 Expect(Token::RBRACE, ok); | 3650 Expect(Token::RBRACE, ok); |
| 3654 if (!*ok) { | 3651 if (!*ok) { |
| 3655 return; | 3652 return; |
| 3656 } | 3653 } |
| 3657 isolate()->counters()->total_preparse_skipped()->Increment( | 3654 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3658 scope_->end_position() - function_block_pos); | |
| 3659 *materialized_literal_count = entry.literal_count(); | 3655 *materialized_literal_count = entry.literal_count(); |
| 3660 *expected_property_count = entry.property_count(); | 3656 *expected_property_count = entry.property_count(); |
| 3661 scope_->SetStrictMode(entry.strict_mode()); | 3657 scope_->SetStrictMode(entry.strict_mode()); |
| 3662 } else { | 3658 } else { |
| 3663 // With no cached data, we partially parse the function, without building an | 3659 // With no cached data, we partially parse the function, without building an |
| 3664 // AST. This gathers the data needed to build a lazy function. | 3660 // AST. This gathers the data needed to build a lazy function. |
| 3665 SingletonLogger logger; | 3661 SingletonLogger logger; |
| 3666 PreParser::PreParseResult result = | 3662 PreParser::PreParseResult result = |
| 3667 ParseLazyFunctionBodyWithPreParser(&logger); | 3663 ParseLazyFunctionBodyWithPreParser(&logger); |
| 3668 if (result == PreParser::kPreParseStackOverflow) { | 3664 if (result == PreParser::kPreParseStackOverflow) { |
| 3669 // Propagate stack overflow. | 3665 // Propagate stack overflow. |
| 3670 set_stack_overflow(); | 3666 set_stack_overflow(); |
| 3671 *ok = false; | 3667 *ok = false; |
| 3672 return; | 3668 return; |
| 3673 } | 3669 } |
| 3674 if (logger.has_error()) { | 3670 if (logger.has_error()) { |
| 3675 ParserTraits::ReportMessageAt( | 3671 ParserTraits::ReportMessageAt( |
| 3676 Scanner::Location(logger.start(), logger.end()), | 3672 Scanner::Location(logger.start(), logger.end()), |
| 3677 logger.message(), logger.argument_opt(), logger.is_reference_error()); | 3673 logger.message(), logger.argument_opt(), logger.is_reference_error()); |
| 3678 *ok = false; | 3674 *ok = false; |
| 3679 return; | 3675 return; |
| 3680 } | 3676 } |
| 3681 scope_->set_end_position(logger.end()); | 3677 scope_->set_end_position(logger.end()); |
| 3682 Expect(Token::RBRACE, ok); | 3678 Expect(Token::RBRACE, ok); |
| 3683 if (!*ok) { | 3679 if (!*ok) { |
| 3684 return; | 3680 return; |
| 3685 } | 3681 } |
| 3686 isolate()->counters()->total_preparse_skipped()->Increment( | 3682 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3687 scope_->end_position() - function_block_pos); | |
| 3688 *materialized_literal_count = logger.literals(); | 3683 *materialized_literal_count = logger.literals(); |
| 3689 *expected_property_count = logger.properties(); | 3684 *expected_property_count = logger.properties(); |
| 3690 scope_->SetStrictMode(logger.strict_mode()); | 3685 scope_->SetStrictMode(logger.strict_mode()); |
| 3691 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3686 if (compile_options() == ScriptCompiler::kProduceParserCache) { |
| 3692 DCHECK(log_); | 3687 DCHECK(log_); |
| 3693 // Position right after terminal '}'. | 3688 // Position right after terminal '}'. |
| 3694 int body_end = scanner()->location().end_pos; | 3689 int body_end = scanner()->location().end_pos; |
| 3695 log_->LogFunction(function_block_pos, body_end, | 3690 log_->LogFunction(function_block_pos, body_end, |
| 3696 *materialized_literal_count, | 3691 *materialized_literal_count, |
| 3697 *expected_property_count, | 3692 *expected_property_count, |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3755 | 3750 |
| 3756 Expect(Token::RBRACE, CHECK_OK); | 3751 Expect(Token::RBRACE, CHECK_OK); |
| 3757 scope_->set_end_position(scanner()->location().end_pos); | 3752 scope_->set_end_position(scanner()->location().end_pos); |
| 3758 | 3753 |
| 3759 return body; | 3754 return body; |
| 3760 } | 3755 } |
| 3761 | 3756 |
| 3762 | 3757 |
| 3763 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3758 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
| 3764 SingletonLogger* logger) { | 3759 SingletonLogger* logger) { |
| 3765 HistogramTimerScope preparse_scope(isolate()->counters()->pre_parse()); | 3760 // This function may be called on a background thread too; record only the |
| 3761 // main thread preparse times. |
| 3762 if (pre_parse_timer_ != NULL) { |
| 3763 pre_parse_timer_->Start(); |
| 3764 } |
| 3766 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 3765 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
| 3767 | 3766 |
| 3768 if (reusable_preparser_ == NULL) { | 3767 if (reusable_preparser_ == NULL) { |
| 3769 intptr_t stack_limit = isolate()->stack_guard()->real_climit(); | 3768 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit_); |
| 3770 reusable_preparser_ = new PreParser(&scanner_, NULL, stack_limit); | |
| 3771 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 3769 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
| 3772 reusable_preparser_->set_allow_modules(allow_modules()); | 3770 reusable_preparser_->set_allow_modules(allow_modules()); |
| 3773 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); | 3771 reusable_preparser_->set_allow_natives_syntax(allow_natives_syntax()); |
| 3774 reusable_preparser_->set_allow_lazy(true); | 3772 reusable_preparser_->set_allow_lazy(true); |
| 3775 reusable_preparser_->set_allow_generators(allow_generators()); | 3773 reusable_preparser_->set_allow_generators(allow_generators()); |
| 3776 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); | 3774 reusable_preparser_->set_allow_arrow_functions(allow_arrow_functions()); |
| 3777 reusable_preparser_->set_allow_harmony_numeric_literals( | 3775 reusable_preparser_->set_allow_harmony_numeric_literals( |
| 3778 allow_harmony_numeric_literals()); | 3776 allow_harmony_numeric_literals()); |
| 3779 reusable_preparser_->set_allow_classes(allow_classes()); | 3777 reusable_preparser_->set_allow_classes(allow_classes()); |
| 3780 } | 3778 } |
| 3781 PreParser::PreParseResult result = | 3779 PreParser::PreParseResult result = |
| 3782 reusable_preparser_->PreParseLazyFunction(strict_mode(), | 3780 reusable_preparser_->PreParseLazyFunction(strict_mode(), |
| 3783 is_generator(), | 3781 is_generator(), |
| 3784 logger); | 3782 logger); |
| 3783 if (pre_parse_timer_ != NULL) { |
| 3784 pre_parse_timer_->Stop(); |
| 3785 } |
| 3785 return result; | 3786 return result; |
| 3786 } | 3787 } |
| 3787 | 3788 |
| 3788 | 3789 |
| 3789 Expression* Parser::ParseV8Intrinsic(bool* ok) { | 3790 Expression* Parser::ParseV8Intrinsic(bool* ok) { |
| 3790 // CallRuntime :: | 3791 // CallRuntime :: |
| 3791 // '%' Identifier Arguments | 3792 // '%' Identifier Arguments |
| 3792 | 3793 |
| 3793 int pos = peek_position(); | 3794 int pos = peek_position(); |
| 3794 Expect(Token::MOD, CHECK_OK); | 3795 Expect(Token::MOD, CHECK_OK); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3958 Handle<Object> error; | 3959 Handle<Object> error; |
| 3959 MaybeHandle<Object> maybe_error = | 3960 MaybeHandle<Object> maybe_error = |
| 3960 pending_error_is_reference_error_ | 3961 pending_error_is_reference_error_ |
| 3961 ? factory->NewReferenceError(pending_error_message_, array) | 3962 ? factory->NewReferenceError(pending_error_message_, array) |
| 3962 : factory->NewSyntaxError(pending_error_message_, array); | 3963 : factory->NewSyntaxError(pending_error_message_, array); |
| 3963 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); | 3964 if (maybe_error.ToHandle(&error)) isolate()->Throw(*error, &location); |
| 3964 } | 3965 } |
| 3965 } | 3966 } |
| 3966 | 3967 |
| 3967 | 3968 |
| 3968 void Parser::InternalizeUseCounts() { | 3969 void Parser::Internalize() { |
| 3970 // Internalize strings. |
| 3971 ast_value_factory_->Internalize(isolate()); |
| 3972 |
| 3973 // Error processing. |
| 3974 if (info()->function() == NULL) { |
| 3975 if (stack_overflow()) { |
| 3976 isolate()->StackOverflow(); |
| 3977 } else { |
| 3978 ThrowPendingError(); |
| 3979 } |
| 3980 } |
| 3981 |
| 3982 // Move statistics to Isolate. |
| 3969 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 3983 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
| 3970 ++feature) { | 3984 ++feature) { |
| 3971 for (int i = 0; i < use_counts_[feature]; ++i) { | 3985 for (int i = 0; i < use_counts_[feature]; ++i) { |
| 3972 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 3986 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
| 3973 } | 3987 } |
| 3974 } | 3988 } |
| 3989 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3990 total_preparse_skipped_); |
| 3975 } | 3991 } |
| 3976 | 3992 |
| 3977 | 3993 |
| 3978 // ---------------------------------------------------------------------------- | 3994 // ---------------------------------------------------------------------------- |
| 3979 // Regular expressions | 3995 // Regular expressions |
| 3980 | 3996 |
| 3981 | 3997 |
| 3982 RegExpParser::RegExpParser(FlatStringReader* in, | 3998 RegExpParser::RegExpParser(FlatStringReader* in, |
| 3983 Handle<String>* error, | 3999 Handle<String>* error, |
| 3984 bool multiline, | 4000 bool multiline, |
| (...skipping 817 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4802 result->contains_anchor = parser.contains_anchor(); | 4818 result->contains_anchor = parser.contains_anchor(); |
| 4803 result->capture_count = capture_count; | 4819 result->capture_count = capture_count; |
| 4804 } | 4820 } |
| 4805 return !parser.failed(); | 4821 return !parser.failed(); |
| 4806 } | 4822 } |
| 4807 | 4823 |
| 4808 | 4824 |
| 4809 bool Parser::Parse() { | 4825 bool Parser::Parse() { |
| 4810 DCHECK(info()->function() == NULL); | 4826 DCHECK(info()->function() == NULL); |
| 4811 FunctionLiteral* result = NULL; | 4827 FunctionLiteral* result = NULL; |
| 4812 ast_value_factory_ = info()->ast_value_factory(); | 4828 pre_parse_timer_ = isolate()->counters()->pre_parse(); |
| 4813 if (ast_value_factory_ == NULL) { | |
| 4814 ast_value_factory_ = | |
| 4815 new AstValueFactory(zone(), isolate()->heap()->HashSeed()); | |
| 4816 } | |
| 4817 if (allow_natives_syntax() || extension_ != NULL) { | 4829 if (allow_natives_syntax() || extension_ != NULL) { |
| 4818 // If intrinsics are allowed, the Parser cannot operate independent of the | 4830 // If intrinsics are allowed, the Parser cannot operate independent of the |
| 4819 // V8 heap because of Rumtime. Tell the string table to internalize strings | 4831 // V8 heap because of Runtime. Tell the string table to internalize strings |
| 4820 // and values right after they're created. | 4832 // and values right after they're created. |
| 4821 ast_value_factory_->Internalize(isolate()); | 4833 ast_value_factory_->Internalize(isolate()); |
| 4822 } | 4834 } |
| 4823 | 4835 |
| 4824 if (info()->is_lazy()) { | 4836 if (info()->is_lazy()) { |
| 4825 DCHECK(!info()->is_eval()); | 4837 DCHECK(!info()->is_eval()); |
| 4826 if (info()->shared_info()->is_function()) { | 4838 if (info()->shared_info()->is_function()) { |
| 4827 result = ParseLazy(); | 4839 result = ParseLazy(); |
| 4828 } else { | 4840 } else { |
| 4829 result = ParseProgram(); | 4841 result = ParseProgram(); |
| 4830 } | 4842 } |
| 4831 } else { | 4843 } else { |
| 4832 SetCachedData(); | 4844 SetCachedData(); |
| 4833 result = ParseProgram(); | 4845 result = ParseProgram(); |
| 4834 } | 4846 } |
| 4835 info()->SetFunction(result); | 4847 info()->SetFunction(result); |
| 4848 |
| 4849 Internalize(); |
| 4836 DCHECK(ast_value_factory_->IsInternalized()); | 4850 DCHECK(ast_value_factory_->IsInternalized()); |
| 4837 // info takes ownership of ast_value_factory_. | 4851 // info takes ownership of ast_value_factory_. |
| 4838 if (info()->ast_value_factory() == NULL) { | 4852 if (info()->ast_value_factory() == NULL) { |
| 4839 info()->SetAstValueFactory(ast_value_factory_); | 4853 info()->SetAstValueFactory(ast_value_factory_); |
| 4840 } | 4854 } |
| 4841 ast_value_factory_ = NULL; | 4855 ast_value_factory_ = NULL; |
| 4842 | |
| 4843 InternalizeUseCounts(); | |
| 4844 | |
| 4845 return (result != NULL); | 4856 return (result != NULL); |
| 4846 } | 4857 } |
| 4847 | 4858 |
| 4848 } } // namespace v8::internal | 4859 } } // namespace v8::internal |
| OLD | NEW |