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/bailout-reason.h" | 9 #include "src/bailout-reason.h" |
10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
244 unsigned ParseData::Version() { | 244 unsigned ParseData::Version() { |
245 return Data()[PreparseDataConstants::kVersionOffset]; | 245 return Data()[PreparseDataConstants::kVersionOffset]; |
246 } | 246 } |
247 | 247 |
248 | 248 |
249 int ParseData::FunctionsSize() { | 249 int ParseData::FunctionsSize() { |
250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); | 250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); |
251 } | 251 } |
252 | 252 |
253 | 253 |
254 void Parser::SetCachedData() { | 254 void Parser::SetCachedData(CompilationInfo* info) { |
255 if (compile_options() == ScriptCompiler::kNoCompileOptions) { | 255 if (compile_options_ == ScriptCompiler::kNoCompileOptions) { |
256 cached_parse_data_ = NULL; | 256 cached_parse_data_ = NULL; |
257 } else { | 257 } else { |
258 DCHECK(info_->cached_data() != NULL); | 258 DCHECK(info->cached_data() != NULL); |
259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 259 if (compile_options_ == ScriptCompiler::kConsumeParserCache) { |
260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); | 260 cached_parse_data_ = ParseData::FromCachedData(*info->cached_data()); |
261 } | 261 } |
262 } | 262 } |
263 } | 263 } |
264 | 264 |
265 | 265 |
266 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, | 266 FunctionLiteral* Parser::DefaultConstructor(bool call_super, Scope* scope, |
267 int pos, int end_pos) { | 267 int pos, int end_pos) { |
268 int materialized_literal_count = -1; | 268 int materialized_literal_count = -1; |
269 int expected_property_count = -1; | 269 int expected_property_count = -1; |
270 int handler_count = 0; | 270 int handler_count = 0; |
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
771 | 771 |
772 ClassLiteral* ParserTraits::ParseClassLiteral( | 772 ClassLiteral* ParserTraits::ParseClassLiteral( |
773 const AstRawString* name, Scanner::Location class_name_location, | 773 const AstRawString* name, Scanner::Location class_name_location, |
774 bool name_is_strict_reserved, int pos, bool* ok) { | 774 bool name_is_strict_reserved, int pos, bool* ok) { |
775 return parser_->ParseClassLiteral(name, class_name_location, | 775 return parser_->ParseClassLiteral(name, class_name_location, |
776 name_is_strict_reserved, pos, ok); | 776 name_is_strict_reserved, pos, ok); |
777 } | 777 } |
778 | 778 |
779 | 779 |
780 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info) | 780 Parser::Parser(CompilationInfo* info, ParseInfo* parse_info) |
781 : ParserBase<ParserTraits>(info->isolate(), info->zone(), &scanner_, | 781 : ParserBase<ParserTraits>(info->zone(), &scanner_, parse_info->stack_limit, |
782 parse_info->stack_limit, info->extension(), | 782 info->extension(), info->ast_value_factory(), |
783 info->ast_value_factory(), NULL, this), | 783 NULL, this), |
784 scanner_(parse_info->unicode_cache), | 784 scanner_(parse_info->unicode_cache), |
785 reusable_preparser_(NULL), | 785 reusable_preparser_(NULL), |
786 original_scope_(NULL), | 786 original_scope_(NULL), |
787 target_stack_(NULL), | 787 target_stack_(NULL), |
788 compile_options_(info->compile_options()), | |
788 cached_parse_data_(NULL), | 789 cached_parse_data_(NULL), |
789 info_(info), | |
790 parsing_lazy_arrow_parameters_(false), | 790 parsing_lazy_arrow_parameters_(false), |
791 has_pending_error_(false), | 791 has_pending_error_(false), |
792 pending_error_message_(NULL), | 792 pending_error_message_(NULL), |
793 pending_error_arg_(NULL), | 793 pending_error_arg_(NULL), |
794 pending_error_char_arg_(NULL), | 794 pending_error_char_arg_(NULL), |
795 total_preparse_skipped_(0), | 795 total_preparse_skipped_(0), |
796 pre_parse_timer_(NULL) { | 796 pre_parse_timer_(NULL) { |
797 DCHECK(!script().is_null() || info->source_stream() != NULL); | 797 // Even though we were passed CompilationInfo, we should not store it in |
798 // Parser - this makes sure that Isolate is not accidentally accessed via | |
799 // CompilationInfo during background parsing. | |
800 DCHECK(!info->script().is_null() || info->source_stream() != NULL); | |
798 set_allow_lazy(false); // Must be explicitly enabled. | 801 set_allow_lazy(false); // Must be explicitly enabled. |
799 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 802 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
800 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 803 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
801 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); | 804 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); |
802 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); | 805 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); |
803 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 806 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
804 set_allow_harmony_classes(FLAG_harmony_classes); | 807 set_allow_harmony_classes(FLAG_harmony_classes); |
805 set_allow_harmony_object_literals(FLAG_harmony_object_literals); | 808 set_allow_harmony_object_literals(FLAG_harmony_object_literals); |
806 set_allow_harmony_templates(FLAG_harmony_templates); | 809 set_allow_harmony_templates(FLAG_harmony_templates); |
807 set_allow_harmony_sloppy(FLAG_harmony_sloppy); | 810 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
808 set_allow_harmony_unicode(FLAG_harmony_unicode); | 811 set_allow_harmony_unicode(FLAG_harmony_unicode); |
809 set_allow_harmony_computed_property_names( | 812 set_allow_harmony_computed_property_names( |
810 FLAG_harmony_computed_property_names); | 813 FLAG_harmony_computed_property_names); |
811 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); | 814 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); |
812 set_allow_strong_mode(FLAG_strong_mode); | 815 set_allow_strong_mode(FLAG_strong_mode); |
813 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 816 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
814 ++feature) { | 817 ++feature) { |
815 use_counts_[feature] = 0; | 818 use_counts_[feature] = 0; |
816 } | 819 } |
817 if (info->ast_value_factory() == NULL) { | 820 if (info->ast_value_factory() == NULL) { |
818 // info takes ownership of AstValueFactory. | 821 // info takes ownership of AstValueFactory. |
819 info->SetAstValueFactory( | 822 info->SetAstValueFactory( |
820 new AstValueFactory(zone(), parse_info->hash_seed)); | 823 new AstValueFactory(zone(), parse_info->hash_seed)); |
821 ast_value_factory_ = info->ast_value_factory(); | 824 ast_value_factory_ = info->ast_value_factory(); |
822 } | 825 } |
823 } | 826 } |
824 | 827 |
825 | 828 |
826 FunctionLiteral* Parser::ParseProgram() { | 829 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { |
827 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 830 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
828 // see comment for HistogramTimerScope class. | 831 // see comment for HistogramTimerScope class. |
829 | 832 |
830 // It's OK to use the counters here, since this function is only called in | 833 // It's OK to use the Isolate & counters here, since this function is only |
831 // the main thread. | 834 // called in the main thread. |
832 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 835 Isolate* isolate = info->isolate(); |
833 Handle<String> source(String::cast(script()->source())); | 836 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); |
834 isolate()->counters()->total_parse_size()->Increment(source->length()); | 837 Handle<String> source(String::cast(info->script()->source())); |
838 isolate->counters()->total_parse_size()->Increment(source->length()); | |
835 base::ElapsedTimer timer; | 839 base::ElapsedTimer timer; |
836 if (FLAG_trace_parse) { | 840 if (FLAG_trace_parse) { |
837 timer.Start(); | 841 timer.Start(); |
838 } | 842 } |
839 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 843 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
840 | 844 |
841 // Initialize parser state. | 845 // Initialize parser state. |
842 CompleteParserRecorder recorder; | 846 CompleteParserRecorder recorder; |
843 | 847 |
844 if (produce_cached_parse_data()) { | 848 if (produce_cached_parse_data()) { |
845 log_ = &recorder; | 849 log_ = &recorder; |
846 } else if (consume_cached_parse_data()) { | 850 } else if (consume_cached_parse_data()) { |
847 cached_parse_data_->Initialize(); | 851 cached_parse_data_->Initialize(); |
848 } | 852 } |
849 | 853 |
850 source = String::Flatten(source); | 854 source = String::Flatten(source); |
851 FunctionLiteral* result; | 855 FunctionLiteral* result; |
852 | 856 |
853 Scope* top_scope = NULL; | 857 Scope* top_scope = NULL; |
854 Scope* eval_scope = NULL; | 858 Scope* eval_scope = NULL; |
855 if (source->IsExternalTwoByteString()) { | 859 if (source->IsExternalTwoByteString()) { |
856 // Notice that the stream is destroyed at the end of the branch block. | 860 // Notice that the stream is destroyed at the end of the branch block. |
857 // The last line of the blocks can't be moved outside, even though they're | 861 // The last line of the blocks can't be moved outside, even though they're |
858 // identical calls. | 862 // identical calls. |
859 ExternalTwoByteStringUtf16CharacterStream stream( | 863 ExternalTwoByteStringUtf16CharacterStream stream( |
860 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 864 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
861 scanner_.Initialize(&stream); | 865 scanner_.Initialize(&stream); |
862 result = DoParseProgram(info(), &top_scope, &eval_scope); | 866 result = DoParseProgram(info, &top_scope, &eval_scope); |
863 } else { | 867 } else { |
864 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 868 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
865 scanner_.Initialize(&stream); | 869 scanner_.Initialize(&stream); |
866 result = DoParseProgram(info(), &top_scope, &eval_scope); | 870 result = DoParseProgram(info, &top_scope, &eval_scope); |
867 } | 871 } |
868 top_scope->set_end_position(source->length()); | 872 top_scope->set_end_position(source->length()); |
869 if (eval_scope != NULL) { | 873 if (eval_scope != NULL) { |
870 eval_scope->set_end_position(source->length()); | 874 eval_scope->set_end_position(source->length()); |
871 } | 875 } |
872 HandleSourceURLComments(); | 876 HandleSourceURLComments(info); |
873 | 877 |
874 if (FLAG_trace_parse && result != NULL) { | 878 if (FLAG_trace_parse && result != NULL) { |
875 double ms = timer.Elapsed().InMillisecondsF(); | 879 double ms = timer.Elapsed().InMillisecondsF(); |
876 if (info()->is_eval()) { | 880 if (info->is_eval()) { |
877 PrintF("[parsing eval"); | 881 PrintF("[parsing eval"); |
878 } else if (info()->script()->name()->IsString()) { | 882 } else if (info->script()->name()->IsString()) { |
879 String* name = String::cast(info()->script()->name()); | 883 String* name = String::cast(info->script()->name()); |
880 SmartArrayPointer<char> name_chars = name->ToCString(); | 884 SmartArrayPointer<char> name_chars = name->ToCString(); |
881 PrintF("[parsing script: %s", name_chars.get()); | 885 PrintF("[parsing script: %s", name_chars.get()); |
882 } else { | 886 } else { |
883 PrintF("[parsing script"); | 887 PrintF("[parsing script"); |
884 } | 888 } |
885 PrintF(" - took %0.3f ms]\n", ms); | 889 PrintF(" - took %0.3f ms]\n", ms); |
886 } | 890 } |
887 if (produce_cached_parse_data()) { | 891 if (produce_cached_parse_data()) { |
888 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 892 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
889 log_ = NULL; | 893 log_ = NULL; |
890 } | 894 } |
891 return result; | 895 return result; |
892 } | 896 } |
893 | 897 |
894 | 898 |
895 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, | 899 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, |
896 Scope** eval_scope) { | 900 Scope** eval_scope) { |
901 // Note that this function can be called from the main thread or from a | |
902 // background thread. We should not access anything Isolate / heap dependent | |
903 // via CompilationInfo, and also not pass it forward. | |
897 DCHECK(scope_ == NULL); | 904 DCHECK(scope_ == NULL); |
898 DCHECK(target_stack_ == NULL); | 905 DCHECK(target_stack_ == NULL); |
899 | 906 |
900 FunctionLiteral* result = NULL; | 907 FunctionLiteral* result = NULL; |
901 { | 908 { |
902 *scope = NewScope(scope_, SCRIPT_SCOPE); | 909 *scope = NewScope(scope_, SCRIPT_SCOPE); |
903 info->SetScriptScope(*scope); | 910 info->SetScriptScope(*scope); |
904 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 911 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
905 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 912 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
906 *info->context(), *scope); | 913 *info->context(), *scope); |
907 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 914 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
908 // means the Parser cannot operate independent of the V8 heap. Tell the | 915 // means the Parser cannot operate independent of the V8 heap. Tell the |
909 // string table to internalize strings and values right after they're | 916 // string table to internalize strings and values right after they're |
910 // created. | 917 // created. This kind of parsing can only be done in the main thread. |
rossberg
2015/02/12 10:31:29
Is there a way to DCHECK that here?
marja
2015/02/12 12:37:31
I added a bool parsing_on_main_thread_ which Parse
| |
911 ast_value_factory()->Internalize(isolate()); | 918 ast_value_factory()->Internalize(info->isolate()); |
912 } | 919 } |
913 original_scope_ = *scope; | 920 original_scope_ = *scope; |
914 if (info->is_eval()) { | 921 if (info->is_eval()) { |
915 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { | 922 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { |
916 *scope = NewScope(*scope, EVAL_SCOPE); | 923 *scope = NewScope(*scope, EVAL_SCOPE); |
917 } | 924 } |
918 } else if (info->is_global()) { | 925 } else if (info->is_global()) { |
919 *scope = NewScope(*scope, SCRIPT_SCOPE); | 926 *scope = NewScope(*scope, SCRIPT_SCOPE); |
920 } | 927 } |
921 (*scope)->set_start_position(0); | 928 (*scope)->set_start_position(0); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
978 } | 985 } |
979 } | 986 } |
980 | 987 |
981 // Make sure the target stack is empty. | 988 // Make sure the target stack is empty. |
982 DCHECK(target_stack_ == NULL); | 989 DCHECK(target_stack_ == NULL); |
983 | 990 |
984 return result; | 991 return result; |
985 } | 992 } |
986 | 993 |
987 | 994 |
988 FunctionLiteral* Parser::ParseLazy() { | 995 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { |
989 // It's OK to use the counters here, since this function is only called in | 996 // It's OK to use the Isolate & counters here, since this function is only |
990 // the main thread. | 997 // called in the main thread. |
991 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 998 HistogramTimerScope timer_scope(info->isolate()->counters()->parse_lazy()); |
992 Handle<String> source(String::cast(script()->source())); | 999 Handle<String> source(String::cast(info->script()->source())); |
993 isolate()->counters()->total_parse_size()->Increment(source->length()); | 1000 info->isolate()->counters()->total_parse_size()->Increment(source->length()); |
994 base::ElapsedTimer timer; | 1001 base::ElapsedTimer timer; |
995 if (FLAG_trace_parse) { | 1002 if (FLAG_trace_parse) { |
996 timer.Start(); | 1003 timer.Start(); |
997 } | 1004 } |
998 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 1005 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
999 | 1006 |
1000 // Initialize parser state. | 1007 // Initialize parser state. |
1001 source = String::Flatten(source); | 1008 source = String::Flatten(source); |
1002 FunctionLiteral* result; | 1009 FunctionLiteral* result; |
1003 if (source->IsExternalTwoByteString()) { | 1010 if (source->IsExternalTwoByteString()) { |
1004 ExternalTwoByteStringUtf16CharacterStream stream( | 1011 ExternalTwoByteStringUtf16CharacterStream stream( |
1005 Handle<ExternalTwoByteString>::cast(source), | 1012 Handle<ExternalTwoByteString>::cast(source), |
1006 shared_info->start_position(), | 1013 shared_info->start_position(), |
1007 shared_info->end_position()); | 1014 shared_info->end_position()); |
1008 result = ParseLazy(&stream); | 1015 result = ParseLazy(info, &stream); |
1009 } else { | 1016 } else { |
1010 GenericStringUtf16CharacterStream stream(source, | 1017 GenericStringUtf16CharacterStream stream(source, |
1011 shared_info->start_position(), | 1018 shared_info->start_position(), |
1012 shared_info->end_position()); | 1019 shared_info->end_position()); |
1013 result = ParseLazy(&stream); | 1020 result = ParseLazy(info, &stream); |
1014 } | 1021 } |
1015 | 1022 |
1016 if (FLAG_trace_parse && result != NULL) { | 1023 if (FLAG_trace_parse && result != NULL) { |
1017 double ms = timer.Elapsed().InMillisecondsF(); | 1024 double ms = timer.Elapsed().InMillisecondsF(); |
1018 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 1025 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
1019 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 1026 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
1020 } | 1027 } |
1021 return result; | 1028 return result; |
1022 } | 1029 } |
1023 | 1030 |
1024 | 1031 |
1025 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 1032 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
1026 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 1033 Utf16CharacterStream* source) { |
1034 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | |
1027 scanner_.Initialize(source); | 1035 scanner_.Initialize(source); |
1028 DCHECK(scope_ == NULL); | 1036 DCHECK(scope_ == NULL); |
1029 DCHECK(target_stack_ == NULL); | 1037 DCHECK(target_stack_ == NULL); |
1030 | 1038 |
1031 Handle<String> name(String::cast(shared_info->name())); | 1039 Handle<String> name(String::cast(shared_info->name())); |
1032 DCHECK(ast_value_factory()); | 1040 DCHECK(ast_value_factory()); |
1033 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 1041 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
1034 const AstRawString* raw_name = ast_value_factory()->GetString(name); | 1042 const AstRawString* raw_name = ast_value_factory()->GetString(name); |
1035 fni_->PushEnclosingName(raw_name); | 1043 fni_->PushEnclosingName(raw_name); |
1036 | 1044 |
1037 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1045 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1038 | 1046 |
1039 // Place holder for the result. | 1047 // Place holder for the result. |
1040 FunctionLiteral* result = NULL; | 1048 FunctionLiteral* result = NULL; |
1041 | 1049 |
1042 { | 1050 { |
1043 // Parse the function literal. | 1051 // Parse the function literal. |
1044 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 1052 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
1045 info()->SetScriptScope(scope); | 1053 info->SetScriptScope(scope); |
1046 if (!info()->closure().is_null()) { | 1054 if (!info->closure().is_null()) { |
1047 scope = Scope::DeserializeScopeChain(isolate(), zone(), | 1055 // Ok to use Isolate here, since lazy function parsing is only done in the |
1048 info()->closure()->context(), scope); | 1056 // main thread. |
1057 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | |
1058 info->closure()->context(), scope); | |
1049 } | 1059 } |
1050 original_scope_ = scope; | 1060 original_scope_ = scope; |
1051 AstNodeFactory function_factory(ast_value_factory()); | 1061 AstNodeFactory function_factory(ast_value_factory()); |
1052 FunctionState function_state(&function_state_, &scope_, scope, | 1062 FunctionState function_state(&function_state_, &scope_, scope, |
1053 shared_info->kind(), &function_factory); | 1063 shared_info->kind(), &function_factory); |
1054 DCHECK(is_sloppy(scope->language_mode()) || | 1064 DCHECK(is_sloppy(scope->language_mode()) || |
1055 is_strict(info()->language_mode())); | 1065 is_strict(info->language_mode())); |
1056 DCHECK(info()->language_mode() == shared_info->language_mode()); | 1066 DCHECK(info->language_mode() == shared_info->language_mode()); |
1057 scope->SetLanguageMode(shared_info->language_mode()); | 1067 scope->SetLanguageMode(shared_info->language_mode()); |
1058 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1068 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1059 ? (shared_info->is_anonymous() | 1069 ? (shared_info->is_anonymous() |
1060 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1070 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1061 : FunctionLiteral::NAMED_EXPRESSION) | 1071 : FunctionLiteral::NAMED_EXPRESSION) |
1062 : FunctionLiteral::DECLARATION; | 1072 : FunctionLiteral::DECLARATION; |
1063 bool ok = true; | 1073 bool ok = true; |
1064 | 1074 |
1065 if (shared_info->is_arrow()) { | 1075 if (shared_info->is_arrow()) { |
1066 // The first expression being parsed is the parameter list of the arrow | 1076 // The first expression being parsed is the parameter list of the arrow |
(...skipping 2918 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3985 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 3995 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
3986 SingletonLogger* logger) { | 3996 SingletonLogger* logger) { |
3987 // This function may be called on a background thread too; record only the | 3997 // This function may be called on a background thread too; record only the |
3988 // main thread preparse times. | 3998 // main thread preparse times. |
3989 if (pre_parse_timer_ != NULL) { | 3999 if (pre_parse_timer_ != NULL) { |
3990 pre_parse_timer_->Start(); | 4000 pre_parse_timer_->Start(); |
3991 } | 4001 } |
3992 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 4002 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
3993 | 4003 |
3994 if (reusable_preparser_ == NULL) { | 4004 if (reusable_preparser_ == NULL) { |
3995 reusable_preparser_ = new PreParser( | 4005 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
3996 isolate(), zone(), &scanner_, ast_value_factory(), NULL, stack_limit_); | 4006 NULL, stack_limit_); |
3997 reusable_preparser_->set_allow_lazy(true); | 4007 reusable_preparser_->set_allow_lazy(true); |
3998 reusable_preparser_->set_allow_natives(allow_natives()); | 4008 reusable_preparser_->set_allow_natives(allow_natives()); |
3999 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4009 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4000 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); | 4010 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); |
4001 reusable_preparser_->set_allow_harmony_arrow_functions( | 4011 reusable_preparser_->set_allow_harmony_arrow_functions( |
4002 allow_harmony_arrow_functions()); | 4012 allow_harmony_arrow_functions()); |
4003 reusable_preparser_->set_allow_harmony_numeric_literals( | 4013 reusable_preparser_->set_allow_harmony_numeric_literals( |
4004 allow_harmony_numeric_literals()); | 4014 allow_harmony_numeric_literals()); |
4005 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); | 4015 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); |
4006 reusable_preparser_->set_allow_harmony_object_literals( | 4016 reusable_preparser_->set_allow_harmony_object_literals( |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4226 | 4236 |
4227 DCHECK(stat->is_target_for_anonymous()); | 4237 DCHECK(stat->is_target_for_anonymous()); |
4228 if (anonymous || ContainsLabel(stat->labels(), label)) { | 4238 if (anonymous || ContainsLabel(stat->labels(), label)) { |
4229 return stat; | 4239 return stat; |
4230 } | 4240 } |
4231 } | 4241 } |
4232 return NULL; | 4242 return NULL; |
4233 } | 4243 } |
4234 | 4244 |
4235 | 4245 |
4236 void Parser::HandleSourceURLComments() { | 4246 void Parser::HandleSourceURLComments(CompilationInfo* info) { |
4237 if (scanner_.source_url()->length() > 0) { | 4247 if (scanner_.source_url()->length() > 0) { |
4238 Handle<String> source_url = scanner_.source_url()->Internalize(isolate()); | 4248 Handle<String> source_url = |
4239 info_->script()->set_source_url(*source_url); | 4249 scanner_.source_url()->Internalize(info->isolate()); |
4250 info->script()->set_source_url(*source_url); | |
4240 } | 4251 } |
4241 if (scanner_.source_mapping_url()->length() > 0) { | 4252 if (scanner_.source_mapping_url()->length() > 0) { |
4242 Handle<String> source_mapping_url = | 4253 Handle<String> source_mapping_url = |
4243 scanner_.source_mapping_url()->Internalize(isolate()); | 4254 scanner_.source_mapping_url()->Internalize(info->isolate()); |
4244 info_->script()->set_source_mapping_url(*source_mapping_url); | 4255 info->script()->set_source_mapping_url(*source_mapping_url); |
4245 } | 4256 } |
4246 } | 4257 } |
4247 | 4258 |
4248 | 4259 |
4249 void Parser::ThrowPendingError() { | 4260 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { |
4250 DCHECK(ast_value_factory()->IsInternalized()); | 4261 DCHECK(ast_value_factory()->IsInternalized()); |
4251 if (has_pending_error_) { | 4262 if (has_pending_error_) { |
4252 MessageLocation location(script(), pending_error_location_.beg_pos, | 4263 MessageLocation location(script, pending_error_location_.beg_pos, |
4253 pending_error_location_.end_pos); | 4264 pending_error_location_.end_pos); |
4254 Factory* factory = isolate()->factory(); | 4265 Factory* factory = isolate->factory(); |
4255 bool has_arg = | 4266 bool has_arg = |
4256 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | 4267 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
4257 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 4268 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
4258 if (pending_error_arg_ != NULL) { | 4269 if (pending_error_arg_ != NULL) { |
4259 Handle<String> arg_string = pending_error_arg_->string(); | 4270 Handle<String> arg_string = pending_error_arg_->string(); |
4260 elements->set(0, *arg_string); | 4271 elements->set(0, *arg_string); |
4261 } else if (pending_error_char_arg_ != NULL) { | 4272 } else if (pending_error_char_arg_ != NULL) { |
4262 Handle<String> arg_string = | 4273 Handle<String> arg_string = |
4263 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 4274 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
4264 .ToHandleChecked(); | 4275 .ToHandleChecked(); |
4265 elements->set(0, *arg_string); | 4276 elements->set(0, *arg_string); |
4266 } | 4277 } |
4267 isolate()->debug()->OnCompileError(script()); | 4278 isolate->debug()->OnCompileError(script); |
4268 | 4279 |
4269 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 4280 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
4270 Handle<Object> error; | 4281 Handle<Object> error; |
4271 MaybeHandle<Object> maybe_error = | 4282 MaybeHandle<Object> maybe_error = |
4272 pending_error_is_reference_error_ | 4283 pending_error_is_reference_error_ |
4273 ? factory->NewReferenceError(pending_error_message_, array) | 4284 ? factory->NewReferenceError(pending_error_message_, array) |
4274 : factory->NewSyntaxError(pending_error_message_, array); | 4285 : factory->NewSyntaxError(pending_error_message_, array); |
4275 | 4286 |
4276 if (maybe_error.ToHandle(&error)) { | 4287 if (maybe_error.ToHandle(&error)) { |
4277 Handle<JSObject> jserror = Handle<JSObject>::cast(error); | 4288 Handle<JSObject> jserror = Handle<JSObject>::cast(error); |
4278 | 4289 |
4279 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); | 4290 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); |
4280 JSObject::SetProperty( | 4291 JSObject::SetProperty(jserror, key_start_pos, |
4281 jserror, key_start_pos, | 4292 handle(Smi::FromInt(location.start_pos()), isolate), |
4282 handle(Smi::FromInt(location.start_pos()), isolate()), | 4293 SLOPPY).Check(); |
4283 SLOPPY).Check(); | |
4284 | 4294 |
4285 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); | 4295 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); |
4286 JSObject::SetProperty(jserror, key_end_pos, | 4296 JSObject::SetProperty(jserror, key_end_pos, |
4287 handle(Smi::FromInt(location.end_pos()), isolate()), | 4297 handle(Smi::FromInt(location.end_pos()), isolate), |
4288 SLOPPY).Check(); | 4298 SLOPPY).Check(); |
4289 | 4299 |
4290 Handle<Name> key_script = factory->error_script_symbol(); | 4300 Handle<Name> key_script = factory->error_script_symbol(); |
4291 JSObject::SetProperty(jserror, key_script, script(), SLOPPY).Check(); | 4301 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); |
4292 | 4302 |
4293 isolate()->Throw(*error, &location); | 4303 isolate->Throw(*error, &location); |
4294 } | 4304 } |
4295 } | 4305 } |
4296 } | 4306 } |
4297 | 4307 |
4298 | 4308 |
4299 void Parser::Internalize() { | 4309 void Parser::Internalize(CompilationInfo* info) { |
4300 // Internalize strings. | 4310 // Internalize strings. |
4301 ast_value_factory()->Internalize(isolate()); | 4311 ast_value_factory()->Internalize(info->isolate()); |
4302 | 4312 |
4303 // Error processing. | 4313 // Error processing. |
4304 if (info()->function() == NULL) { | 4314 if (info->function() == NULL) { |
4305 if (stack_overflow()) { | 4315 if (stack_overflow()) { |
4306 isolate()->StackOverflow(); | 4316 info->isolate()->StackOverflow(); |
4307 } else { | 4317 } else { |
4308 ThrowPendingError(); | 4318 ThrowPendingError(info->isolate(), info->script()); |
4309 } | 4319 } |
4310 } | 4320 } |
4311 | 4321 |
4312 // Move statistics to Isolate. | 4322 // Move statistics to Isolate. |
4313 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 4323 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
4314 ++feature) { | 4324 ++feature) { |
4315 for (int i = 0; i < use_counts_[feature]; ++i) { | 4325 for (int i = 0; i < use_counts_[feature]; ++i) { |
4316 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 4326 info->isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
4317 } | 4327 } |
4318 } | 4328 } |
4319 isolate()->counters()->total_preparse_skipped()->Increment( | 4329 info->isolate()->counters()->total_preparse_skipped()->Increment( |
4320 total_preparse_skipped_); | 4330 total_preparse_skipped_); |
4321 } | 4331 } |
4322 | 4332 |
4323 | 4333 |
4324 // ---------------------------------------------------------------------------- | 4334 // ---------------------------------------------------------------------------- |
4325 // Regular expressions | 4335 // Regular expressions |
4326 | 4336 |
4327 | 4337 |
4328 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, | 4338 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, |
4329 bool multiline, bool unicode, Isolate* isolate, | 4339 bool multiline, bool unicode, Isolate* isolate, |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5227 result->tree = tree; | 5237 result->tree = tree; |
5228 int capture_count = parser.captures_started(); | 5238 int capture_count = parser.captures_started(); |
5229 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5239 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
5230 result->contains_anchor = parser.contains_anchor(); | 5240 result->contains_anchor = parser.contains_anchor(); |
5231 result->capture_count = capture_count; | 5241 result->capture_count = capture_count; |
5232 } | 5242 } |
5233 return !parser.failed(); | 5243 return !parser.failed(); |
5234 } | 5244 } |
5235 | 5245 |
5236 | 5246 |
5237 bool Parser::Parse() { | 5247 bool Parser::ParseOnMainThread(CompilationInfo* info) { |
5238 DCHECK(info()->function() == NULL); | 5248 DCHECK(info->function() == NULL); |
5239 FunctionLiteral* result = NULL; | 5249 FunctionLiteral* result = NULL; |
5240 pre_parse_timer_ = isolate()->counters()->pre_parse(); | 5250 // Ok to use Isolate here; this function is only called in the main thread. |
5251 Isolate* isolate = info->isolate(); | |
5252 pre_parse_timer_ = isolate->counters()->pre_parse(); | |
5241 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { | 5253 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { |
5242 // If intrinsics are allowed, the Parser cannot operate independent of the | 5254 // If intrinsics are allowed, the Parser cannot operate independent of the |
5243 // V8 heap because of Runtime. Tell the string table to internalize strings | 5255 // V8 heap because of Runtime. Tell the string table to internalize strings |
5244 // and values right after they're created. | 5256 // and values right after they're created. |
5245 ast_value_factory()->Internalize(isolate()); | 5257 ast_value_factory()->Internalize(isolate); |
5246 } | 5258 } |
5247 | 5259 |
5248 if (info()->is_lazy()) { | 5260 if (info->is_lazy()) { |
5249 DCHECK(!info()->is_eval()); | 5261 DCHECK(!info->is_eval()); |
5250 if (info()->shared_info()->is_function()) { | 5262 if (info->shared_info()->is_function()) { |
5251 result = ParseLazy(); | 5263 result = ParseLazy(info); |
5252 } else { | 5264 } else { |
5253 result = ParseProgram(); | 5265 result = ParseProgram(info); |
5254 } | 5266 } |
5255 } else { | 5267 } else { |
5256 SetCachedData(); | 5268 SetCachedData(info); |
5257 result = ParseProgram(); | 5269 result = ParseProgram(info); |
5258 } | 5270 } |
5259 info()->SetFunction(result); | 5271 info->SetFunction(result); |
5260 | 5272 |
5261 Internalize(); | 5273 Internalize(info); |
5262 DCHECK(ast_value_factory()->IsInternalized()); | 5274 DCHECK(ast_value_factory()->IsInternalized()); |
5263 return (result != NULL); | 5275 return (result != NULL); |
5264 } | 5276 } |
5265 | 5277 |
5266 | 5278 |
5267 void Parser::ParseOnBackground() { | 5279 void Parser::ParseOnBackground(CompilationInfo* info) { |
5268 DCHECK(info()->function() == NULL); | 5280 DCHECK(info->function() == NULL); |
5269 FunctionLiteral* result = NULL; | 5281 FunctionLiteral* result = NULL; |
5270 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 5282 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
5271 | 5283 |
5272 CompleteParserRecorder recorder; | 5284 CompleteParserRecorder recorder; |
5273 if (produce_cached_parse_data()) log_ = &recorder; | 5285 if (produce_cached_parse_data()) log_ = &recorder; |
5274 | 5286 |
5275 DCHECK(info()->source_stream() != NULL); | 5287 DCHECK(info->source_stream() != NULL); |
5276 ExternalStreamingStream stream(info()->source_stream(), | 5288 ExternalStreamingStream stream(info->source_stream(), |
5277 info()->source_stream_encoding()); | 5289 info->source_stream_encoding()); |
5278 scanner_.Initialize(&stream); | 5290 scanner_.Initialize(&stream); |
5279 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); | 5291 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); |
5280 | 5292 |
5281 // When streaming, we don't know the length of the source until we have parsed | 5293 // When streaming, we don't know the length of the source until we have parsed |
5282 // it. The raw data can be UTF-8, so we wouldn't know the source length until | 5294 // it. The raw data can be UTF-8, so we wouldn't know the source length until |
5283 // we have decoded it anyway even if we knew the raw data length (which we | 5295 // we have decoded it anyway even if we knew the raw data length (which we |
5284 // don't). We work around this by storing all the scopes which need their end | 5296 // don't). We work around this by storing all the scopes which need their end |
5285 // position set at the end of the script (the top scope and possible eval | 5297 // position set at the end of the script (the top scope and possible eval |
5286 // scopes) and set their end position after we know the script length. | 5298 // scopes) and set their end position after we know the script length. |
5287 Scope* top_scope = NULL; | 5299 Scope* top_scope = NULL; |
5288 Scope* eval_scope = NULL; | 5300 Scope* eval_scope = NULL; |
5289 result = DoParseProgram(info(), &top_scope, &eval_scope); | 5301 result = DoParseProgram(info, &top_scope, &eval_scope); |
5290 | 5302 |
5291 top_scope->set_end_position(scanner()->location().end_pos); | 5303 top_scope->set_end_position(scanner()->location().end_pos); |
5292 if (eval_scope != NULL) { | 5304 if (eval_scope != NULL) { |
5293 eval_scope->set_end_position(scanner()->location().end_pos); | 5305 eval_scope->set_end_position(scanner()->location().end_pos); |
5294 } | 5306 } |
5295 | 5307 |
5296 info()->SetFunction(result); | 5308 info->SetFunction(result); |
5297 | 5309 |
5298 // We cannot internalize on a background thread; a foreground task will take | 5310 // We cannot internalize on a background thread; a foreground task will take |
5299 // care of calling Parser::Internalize just before compilation. | 5311 // care of calling Parser::Internalize just before compilation. |
5300 | 5312 |
5301 if (produce_cached_parse_data()) { | 5313 if (produce_cached_parse_data()) { |
5302 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 5314 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
5303 log_ = NULL; | 5315 log_ = NULL; |
5304 } | 5316 } |
5305 } | 5317 } |
5306 | 5318 |
5307 | 5319 |
5308 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { | 5320 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
5309 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); | 5321 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); |
5310 } | 5322 } |
5311 | 5323 |
5312 | 5324 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5419 } else { | 5431 } else { |
5420 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5432 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5421 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5433 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5422 raw_string->length()); | 5434 raw_string->length()); |
5423 } | 5435 } |
5424 } | 5436 } |
5425 | 5437 |
5426 return running_hash; | 5438 return running_hash; |
5427 } | 5439 } |
5428 } } // namespace v8::internal | 5440 } } // namespace v8::internal |
OLD | NEW |