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 |