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 512 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
783 ClassLiteral* ParserTraits::ParseClassLiteral( | 783 ClassLiteral* ParserTraits::ParseClassLiteral( |
784 const AstRawString* name, Scanner::Location class_name_location, | 784 const AstRawString* name, Scanner::Location class_name_location, |
785 bool name_is_strict_reserved, int pos, bool* ok) { | 785 bool name_is_strict_reserved, int pos, bool* ok) { |
786 return parser_->ParseClassLiteral(name, class_name_location, | 786 return parser_->ParseClassLiteral(name, class_name_location, |
787 name_is_strict_reserved, pos, ok); | 787 name_is_strict_reserved, pos, ok); |
788 } | 788 } |
789 | 789 |
790 | 790 |
791 Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, | 791 Parser::Parser(CompilationInfo* info, uintptr_t stack_limit, uint32_t hash_seed, |
792 UnicodeCache* unicode_cache) | 792 UnicodeCache* unicode_cache) |
793 : ParserBase<ParserTraits>(info->isolate(), info->zone(), &scanner_, | 793 : ParserBase<ParserTraits>(info->zone(), &scanner_, stack_limit, |
794 stack_limit, info->extension(), | 794 info->extension(), info->ast_value_factory(), |
795 info->ast_value_factory(), NULL, this), | 795 NULL, this), |
796 scanner_(unicode_cache), | 796 scanner_(unicode_cache), |
797 reusable_preparser_(NULL), | 797 reusable_preparser_(NULL), |
798 original_scope_(NULL), | 798 original_scope_(NULL), |
799 target_stack_(NULL), | 799 target_stack_(NULL), |
| 800 compile_options_(info->compile_options()), |
800 cached_parse_data_(NULL), | 801 cached_parse_data_(NULL), |
801 info_(info), | |
802 parsing_lazy_arrow_parameters_(false), | 802 parsing_lazy_arrow_parameters_(false), |
803 has_pending_error_(false), | 803 has_pending_error_(false), |
804 pending_error_message_(NULL), | 804 pending_error_message_(NULL), |
805 pending_error_arg_(NULL), | 805 pending_error_arg_(NULL), |
806 pending_error_char_arg_(NULL), | 806 pending_error_char_arg_(NULL), |
807 total_preparse_skipped_(0), | 807 total_preparse_skipped_(0), |
808 pre_parse_timer_(NULL) { | 808 pre_parse_timer_(NULL), |
809 DCHECK(!script().is_null() || info->source_stream() != NULL); | 809 parsing_on_main_thread_(true) { |
| 810 // Even though we were passed CompilationInfo, we should not store it in |
| 811 // Parser - this makes sure that Isolate is not accidentally accessed via |
| 812 // CompilationInfo during background parsing. |
| 813 DCHECK(!info->script().is_null() || info->source_stream() != NULL); |
810 set_allow_lazy(false); // Must be explicitly enabled. | 814 set_allow_lazy(false); // Must be explicitly enabled. |
811 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); | 815 set_allow_natives(FLAG_allow_natives_syntax || info->is_native()); |
812 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 816 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
813 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); | 817 set_allow_harmony_modules(!info->is_native() && FLAG_harmony_modules); |
814 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); | 818 set_allow_harmony_arrow_functions(FLAG_harmony_arrow_functions); |
815 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); | 819 set_allow_harmony_numeric_literals(FLAG_harmony_numeric_literals); |
816 set_allow_harmony_classes(FLAG_harmony_classes); | 820 set_allow_harmony_classes(FLAG_harmony_classes); |
817 set_allow_harmony_object_literals(FLAG_harmony_object_literals); | 821 set_allow_harmony_object_literals(FLAG_harmony_object_literals); |
818 set_allow_harmony_templates(FLAG_harmony_templates); | 822 set_allow_harmony_templates(FLAG_harmony_templates); |
819 set_allow_harmony_sloppy(FLAG_harmony_sloppy); | 823 set_allow_harmony_sloppy(FLAG_harmony_sloppy); |
820 set_allow_harmony_unicode(FLAG_harmony_unicode); | 824 set_allow_harmony_unicode(FLAG_harmony_unicode); |
821 set_allow_harmony_computed_property_names( | 825 set_allow_harmony_computed_property_names( |
822 FLAG_harmony_computed_property_names); | 826 FLAG_harmony_computed_property_names); |
823 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); | 827 set_allow_harmony_rest_params(FLAG_harmony_rest_parameters); |
824 set_allow_strong_mode(FLAG_strong_mode); | 828 set_allow_strong_mode(FLAG_strong_mode); |
825 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 829 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
826 ++feature) { | 830 ++feature) { |
827 use_counts_[feature] = 0; | 831 use_counts_[feature] = 0; |
828 } | 832 } |
829 if (info->ast_value_factory() == NULL) { | 833 if (info->ast_value_factory() == NULL) { |
830 // info takes ownership of AstValueFactory. | 834 // info takes ownership of AstValueFactory. |
831 info->SetAstValueFactory(new AstValueFactory(zone(), hash_seed)); | 835 info->SetAstValueFactory(new AstValueFactory(zone(), hash_seed)); |
832 ast_value_factory_ = info->ast_value_factory(); | 836 ast_value_factory_ = info->ast_value_factory(); |
833 } | 837 } |
834 } | 838 } |
835 | 839 |
836 | 840 |
837 FunctionLiteral* Parser::ParseProgram() { | 841 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { |
838 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 842 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
839 // see comment for HistogramTimerScope class. | 843 // see comment for HistogramTimerScope class. |
840 | 844 |
841 // It's OK to use the counters here, since this function is only called in | 845 // It's OK to use the Isolate & counters here, since this function is only |
842 // the main thread. | 846 // called in the main thread. |
843 HistogramTimerScope timer_scope(isolate()->counters()->parse(), true); | 847 DCHECK(parsing_on_main_thread_); |
844 Handle<String> source(String::cast(script()->source())); | 848 |
845 isolate()->counters()->total_parse_size()->Increment(source->length()); | 849 Isolate* isolate = info->isolate(); |
| 850 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); |
| 851 Handle<String> source(String::cast(info->script()->source())); |
| 852 isolate->counters()->total_parse_size()->Increment(source->length()); |
846 base::ElapsedTimer timer; | 853 base::ElapsedTimer timer; |
847 if (FLAG_trace_parse) { | 854 if (FLAG_trace_parse) { |
848 timer.Start(); | 855 timer.Start(); |
849 } | 856 } |
850 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 857 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
851 | 858 |
852 // Initialize parser state. | 859 // Initialize parser state. |
853 CompleteParserRecorder recorder; | 860 CompleteParserRecorder recorder; |
854 | 861 |
855 if (produce_cached_parse_data()) { | 862 if (produce_cached_parse_data()) { |
856 log_ = &recorder; | 863 log_ = &recorder; |
857 } else if (consume_cached_parse_data()) { | 864 } else if (consume_cached_parse_data()) { |
858 cached_parse_data_->Initialize(); | 865 cached_parse_data_->Initialize(); |
859 } | 866 } |
860 | 867 |
861 source = String::Flatten(source); | 868 source = String::Flatten(source); |
862 FunctionLiteral* result; | 869 FunctionLiteral* result; |
863 | 870 |
864 Scope* top_scope = NULL; | 871 Scope* top_scope = NULL; |
865 Scope* eval_scope = NULL; | 872 Scope* eval_scope = NULL; |
866 if (source->IsExternalTwoByteString()) { | 873 if (source->IsExternalTwoByteString()) { |
867 // Notice that the stream is destroyed at the end of the branch block. | 874 // Notice that the stream is destroyed at the end of the branch block. |
868 // The last line of the blocks can't be moved outside, even though they're | 875 // The last line of the blocks can't be moved outside, even though they're |
869 // identical calls. | 876 // identical calls. |
870 ExternalTwoByteStringUtf16CharacterStream stream( | 877 ExternalTwoByteStringUtf16CharacterStream stream( |
871 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 878 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
872 scanner_.Initialize(&stream); | 879 scanner_.Initialize(&stream); |
873 result = DoParseProgram(info(), &top_scope, &eval_scope); | 880 result = DoParseProgram(info, &top_scope, &eval_scope); |
874 } else { | 881 } else { |
875 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 882 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
876 scanner_.Initialize(&stream); | 883 scanner_.Initialize(&stream); |
877 result = DoParseProgram(info(), &top_scope, &eval_scope); | 884 result = DoParseProgram(info, &top_scope, &eval_scope); |
878 } | 885 } |
879 top_scope->set_end_position(source->length()); | 886 top_scope->set_end_position(source->length()); |
880 if (eval_scope != NULL) { | 887 if (eval_scope != NULL) { |
881 eval_scope->set_end_position(source->length()); | 888 eval_scope->set_end_position(source->length()); |
882 } | 889 } |
883 HandleSourceURLComments(); | 890 HandleSourceURLComments(info); |
884 | 891 |
885 if (FLAG_trace_parse && result != NULL) { | 892 if (FLAG_trace_parse && result != NULL) { |
886 double ms = timer.Elapsed().InMillisecondsF(); | 893 double ms = timer.Elapsed().InMillisecondsF(); |
887 if (info()->is_eval()) { | 894 if (info->is_eval()) { |
888 PrintF("[parsing eval"); | 895 PrintF("[parsing eval"); |
889 } else if (info()->script()->name()->IsString()) { | 896 } else if (info->script()->name()->IsString()) { |
890 String* name = String::cast(info()->script()->name()); | 897 String* name = String::cast(info->script()->name()); |
891 SmartArrayPointer<char> name_chars = name->ToCString(); | 898 SmartArrayPointer<char> name_chars = name->ToCString(); |
892 PrintF("[parsing script: %s", name_chars.get()); | 899 PrintF("[parsing script: %s", name_chars.get()); |
893 } else { | 900 } else { |
894 PrintF("[parsing script"); | 901 PrintF("[parsing script"); |
895 } | 902 } |
896 PrintF(" - took %0.3f ms]\n", ms); | 903 PrintF(" - took %0.3f ms]\n", ms); |
897 } | 904 } |
898 if (produce_cached_parse_data()) { | 905 if (produce_cached_parse_data()) { |
899 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 906 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
900 log_ = NULL; | 907 log_ = NULL; |
901 } | 908 } |
902 return result; | 909 return result; |
903 } | 910 } |
904 | 911 |
905 | 912 |
906 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, | 913 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, |
907 Scope** eval_scope) { | 914 Scope** eval_scope) { |
| 915 // Note that this function can be called from the main thread or from a |
| 916 // background thread. We should not access anything Isolate / heap dependent |
| 917 // via CompilationInfo, and also not pass it forward. |
908 DCHECK(scope_ == NULL); | 918 DCHECK(scope_ == NULL); |
909 DCHECK(target_stack_ == NULL); | 919 DCHECK(target_stack_ == NULL); |
910 | 920 |
911 FunctionLiteral* result = NULL; | 921 FunctionLiteral* result = NULL; |
912 { | 922 { |
913 *scope = NewScope(scope_, SCRIPT_SCOPE); | 923 *scope = NewScope(scope_, SCRIPT_SCOPE); |
914 info->SetScriptScope(*scope); | 924 info->SetScriptScope(*scope); |
915 if (!info->context().is_null() && !info->context()->IsNativeContext()) { | 925 if (!info->context().is_null() && !info->context()->IsNativeContext()) { |
916 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 926 *scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
917 *info->context(), *scope); | 927 *info->context(), *scope); |
918 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this | 928 // The Scope is backed up by ScopeInfo (which is in the V8 heap); this |
919 // means the Parser cannot operate independent of the V8 heap. Tell the | 929 // means the Parser cannot operate independent of the V8 heap. Tell the |
920 // string table to internalize strings and values right after they're | 930 // string table to internalize strings and values right after they're |
921 // created. | 931 // created. This kind of parsing can only be done in the main thread. |
922 ast_value_factory()->Internalize(isolate()); | 932 DCHECK(parsing_on_main_thread_); |
| 933 ast_value_factory()->Internalize(info->isolate()); |
923 } | 934 } |
924 original_scope_ = *scope; | 935 original_scope_ = *scope; |
925 if (info->is_eval()) { | 936 if (info->is_eval()) { |
926 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { | 937 if (!(*scope)->is_script_scope() || is_strict(info->language_mode())) { |
927 *scope = NewScope(*scope, EVAL_SCOPE); | 938 *scope = NewScope(*scope, EVAL_SCOPE); |
928 } | 939 } |
929 } else if (info->is_global()) { | 940 } else if (info->is_global()) { |
930 *scope = NewScope(*scope, SCRIPT_SCOPE); | 941 *scope = NewScope(*scope, SCRIPT_SCOPE); |
931 } | 942 } |
932 (*scope)->set_start_position(0); | 943 (*scope)->set_start_position(0); |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
989 } | 1000 } |
990 } | 1001 } |
991 | 1002 |
992 // Make sure the target stack is empty. | 1003 // Make sure the target stack is empty. |
993 DCHECK(target_stack_ == NULL); | 1004 DCHECK(target_stack_ == NULL); |
994 | 1005 |
995 return result; | 1006 return result; |
996 } | 1007 } |
997 | 1008 |
998 | 1009 |
999 FunctionLiteral* Parser::ParseLazy() { | 1010 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { |
1000 // It's OK to use the counters here, since this function is only called in | 1011 // It's OK to use the Isolate & counters here, since this function is only |
1001 // the main thread. | 1012 // called in the main thread. |
1002 HistogramTimerScope timer_scope(isolate()->counters()->parse_lazy()); | 1013 DCHECK(parsing_on_main_thread_); |
1003 Handle<String> source(String::cast(script()->source())); | 1014 HistogramTimerScope timer_scope(info->isolate()->counters()->parse_lazy()); |
1004 isolate()->counters()->total_parse_size()->Increment(source->length()); | 1015 Handle<String> source(String::cast(info->script()->source())); |
| 1016 info->isolate()->counters()->total_parse_size()->Increment(source->length()); |
1005 base::ElapsedTimer timer; | 1017 base::ElapsedTimer timer; |
1006 if (FLAG_trace_parse) { | 1018 if (FLAG_trace_parse) { |
1007 timer.Start(); | 1019 timer.Start(); |
1008 } | 1020 } |
1009 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 1021 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
1010 | 1022 |
1011 // Initialize parser state. | 1023 // Initialize parser state. |
1012 source = String::Flatten(source); | 1024 source = String::Flatten(source); |
1013 FunctionLiteral* result; | 1025 FunctionLiteral* result; |
1014 if (source->IsExternalTwoByteString()) { | 1026 if (source->IsExternalTwoByteString()) { |
1015 ExternalTwoByteStringUtf16CharacterStream stream( | 1027 ExternalTwoByteStringUtf16CharacterStream stream( |
1016 Handle<ExternalTwoByteString>::cast(source), | 1028 Handle<ExternalTwoByteString>::cast(source), |
1017 shared_info->start_position(), | 1029 shared_info->start_position(), |
1018 shared_info->end_position()); | 1030 shared_info->end_position()); |
1019 result = ParseLazy(&stream); | 1031 result = ParseLazy(info, &stream); |
1020 } else { | 1032 } else { |
1021 GenericStringUtf16CharacterStream stream(source, | 1033 GenericStringUtf16CharacterStream stream(source, |
1022 shared_info->start_position(), | 1034 shared_info->start_position(), |
1023 shared_info->end_position()); | 1035 shared_info->end_position()); |
1024 result = ParseLazy(&stream); | 1036 result = ParseLazy(info, &stream); |
1025 } | 1037 } |
1026 | 1038 |
1027 if (FLAG_trace_parse && result != NULL) { | 1039 if (FLAG_trace_parse && result != NULL) { |
1028 double ms = timer.Elapsed().InMillisecondsF(); | 1040 double ms = timer.Elapsed().InMillisecondsF(); |
1029 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 1041 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
1030 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 1042 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
1031 } | 1043 } |
1032 return result; | 1044 return result; |
1033 } | 1045 } |
1034 | 1046 |
1035 | 1047 |
1036 FunctionLiteral* Parser::ParseLazy(Utf16CharacterStream* source) { | 1048 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, |
1037 Handle<SharedFunctionInfo> shared_info = info()->shared_info(); | 1049 Utf16CharacterStream* source) { |
| 1050 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
1038 scanner_.Initialize(source); | 1051 scanner_.Initialize(source); |
1039 DCHECK(scope_ == NULL); | 1052 DCHECK(scope_ == NULL); |
1040 DCHECK(target_stack_ == NULL); | 1053 DCHECK(target_stack_ == NULL); |
1041 | 1054 |
1042 Handle<String> name(String::cast(shared_info->name())); | 1055 Handle<String> name(String::cast(shared_info->name())); |
1043 DCHECK(ast_value_factory()); | 1056 DCHECK(ast_value_factory()); |
1044 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 1057 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
1045 const AstRawString* raw_name = ast_value_factory()->GetString(name); | 1058 const AstRawString* raw_name = ast_value_factory()->GetString(name); |
1046 fni_->PushEnclosingName(raw_name); | 1059 fni_->PushEnclosingName(raw_name); |
1047 | 1060 |
1048 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1061 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1049 | 1062 |
1050 // Place holder for the result. | 1063 // Place holder for the result. |
1051 FunctionLiteral* result = NULL; | 1064 FunctionLiteral* result = NULL; |
1052 | 1065 |
1053 { | 1066 { |
1054 // Parse the function literal. | 1067 // Parse the function literal. |
1055 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 1068 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
1056 info()->SetScriptScope(scope); | 1069 info->SetScriptScope(scope); |
1057 if (!info()->closure().is_null()) { | 1070 if (!info->closure().is_null()) { |
1058 scope = Scope::DeserializeScopeChain(isolate(), zone(), | 1071 // Ok to use Isolate here, since lazy function parsing is only done in the |
1059 info()->closure()->context(), scope); | 1072 // main thread. |
| 1073 DCHECK(parsing_on_main_thread_); |
| 1074 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), |
| 1075 info->closure()->context(), scope); |
1060 } | 1076 } |
1061 original_scope_ = scope; | 1077 original_scope_ = scope; |
1062 AstNodeFactory function_factory(ast_value_factory()); | 1078 AstNodeFactory function_factory(ast_value_factory()); |
1063 FunctionState function_state(&function_state_, &scope_, scope, | 1079 FunctionState function_state(&function_state_, &scope_, scope, |
1064 shared_info->kind(), &function_factory); | 1080 shared_info->kind(), &function_factory); |
1065 DCHECK(is_sloppy(scope->language_mode()) || | 1081 DCHECK(is_sloppy(scope->language_mode()) || |
1066 is_strict(info()->language_mode())); | 1082 is_strict(info->language_mode())); |
1067 DCHECK(info()->language_mode() == shared_info->language_mode()); | 1083 DCHECK(info->language_mode() == shared_info->language_mode()); |
1068 scope->SetLanguageMode(shared_info->language_mode()); | 1084 scope->SetLanguageMode(shared_info->language_mode()); |
1069 FunctionLiteral::FunctionType function_type = shared_info->is_expression() | 1085 FunctionLiteral::FunctionType function_type = shared_info->is_expression() |
1070 ? (shared_info->is_anonymous() | 1086 ? (shared_info->is_anonymous() |
1071 ? FunctionLiteral::ANONYMOUS_EXPRESSION | 1087 ? FunctionLiteral::ANONYMOUS_EXPRESSION |
1072 : FunctionLiteral::NAMED_EXPRESSION) | 1088 : FunctionLiteral::NAMED_EXPRESSION) |
1073 : FunctionLiteral::DECLARATION; | 1089 : FunctionLiteral::DECLARATION; |
1074 bool ok = true; | 1090 bool ok = true; |
1075 | 1091 |
1076 if (shared_info->is_arrow()) { | 1092 if (shared_info->is_arrow()) { |
1077 // The first expression being parsed is the parameter list of the arrow | 1093 // The first expression being parsed is the parameter list of the arrow |
(...skipping 2924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4002 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( | 4018 PreParser::PreParseResult Parser::ParseLazyFunctionBodyWithPreParser( |
4003 SingletonLogger* logger) { | 4019 SingletonLogger* logger) { |
4004 // This function may be called on a background thread too; record only the | 4020 // This function may be called on a background thread too; record only the |
4005 // main thread preparse times. | 4021 // main thread preparse times. |
4006 if (pre_parse_timer_ != NULL) { | 4022 if (pre_parse_timer_ != NULL) { |
4007 pre_parse_timer_->Start(); | 4023 pre_parse_timer_->Start(); |
4008 } | 4024 } |
4009 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); | 4025 DCHECK_EQ(Token::LBRACE, scanner()->current_token()); |
4010 | 4026 |
4011 if (reusable_preparser_ == NULL) { | 4027 if (reusable_preparser_ == NULL) { |
4012 reusable_preparser_ = new PreParser( | 4028 reusable_preparser_ = new PreParser(zone(), &scanner_, ast_value_factory(), |
4013 isolate(), zone(), &scanner_, ast_value_factory(), NULL, stack_limit_); | 4029 NULL, stack_limit_); |
4014 reusable_preparser_->set_allow_lazy(true); | 4030 reusable_preparser_->set_allow_lazy(true); |
4015 reusable_preparser_->set_allow_natives(allow_natives()); | 4031 reusable_preparser_->set_allow_natives(allow_natives()); |
4016 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); | 4032 reusable_preparser_->set_allow_harmony_scoping(allow_harmony_scoping()); |
4017 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); | 4033 reusable_preparser_->set_allow_harmony_modules(allow_harmony_modules()); |
4018 reusable_preparser_->set_allow_harmony_arrow_functions( | 4034 reusable_preparser_->set_allow_harmony_arrow_functions( |
4019 allow_harmony_arrow_functions()); | 4035 allow_harmony_arrow_functions()); |
4020 reusable_preparser_->set_allow_harmony_numeric_literals( | 4036 reusable_preparser_->set_allow_harmony_numeric_literals( |
4021 allow_harmony_numeric_literals()); | 4037 allow_harmony_numeric_literals()); |
4022 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); | 4038 reusable_preparser_->set_allow_harmony_classes(allow_harmony_classes()); |
4023 reusable_preparser_->set_allow_harmony_object_literals( | 4039 reusable_preparser_->set_allow_harmony_object_literals( |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4243 | 4259 |
4244 DCHECK(stat->is_target_for_anonymous()); | 4260 DCHECK(stat->is_target_for_anonymous()); |
4245 if (anonymous || ContainsLabel(stat->labels(), label)) { | 4261 if (anonymous || ContainsLabel(stat->labels(), label)) { |
4246 return stat; | 4262 return stat; |
4247 } | 4263 } |
4248 } | 4264 } |
4249 return NULL; | 4265 return NULL; |
4250 } | 4266 } |
4251 | 4267 |
4252 | 4268 |
4253 void Parser::HandleSourceURLComments() { | 4269 void Parser::HandleSourceURLComments(CompilationInfo* info) { |
4254 if (scanner_.source_url()->length() > 0) { | 4270 if (scanner_.source_url()->length() > 0) { |
4255 Handle<String> source_url = scanner_.source_url()->Internalize(isolate()); | 4271 Handle<String> source_url = |
4256 info_->script()->set_source_url(*source_url); | 4272 scanner_.source_url()->Internalize(info->isolate()); |
| 4273 info->script()->set_source_url(*source_url); |
4257 } | 4274 } |
4258 if (scanner_.source_mapping_url()->length() > 0) { | 4275 if (scanner_.source_mapping_url()->length() > 0) { |
4259 Handle<String> source_mapping_url = | 4276 Handle<String> source_mapping_url = |
4260 scanner_.source_mapping_url()->Internalize(isolate()); | 4277 scanner_.source_mapping_url()->Internalize(info->isolate()); |
4261 info_->script()->set_source_mapping_url(*source_mapping_url); | 4278 info->script()->set_source_mapping_url(*source_mapping_url); |
4262 } | 4279 } |
4263 } | 4280 } |
4264 | 4281 |
4265 | 4282 |
4266 void Parser::ThrowPendingError() { | 4283 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { |
4267 DCHECK(ast_value_factory()->IsInternalized()); | 4284 DCHECK(ast_value_factory()->IsInternalized()); |
4268 if (has_pending_error_) { | 4285 if (has_pending_error_) { |
4269 MessageLocation location(script(), pending_error_location_.beg_pos, | 4286 MessageLocation location(script, pending_error_location_.beg_pos, |
4270 pending_error_location_.end_pos); | 4287 pending_error_location_.end_pos); |
4271 Factory* factory = isolate()->factory(); | 4288 Factory* factory = isolate->factory(); |
4272 bool has_arg = | 4289 bool has_arg = |
4273 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; | 4290 pending_error_arg_ != NULL || pending_error_char_arg_ != NULL; |
4274 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); | 4291 Handle<FixedArray> elements = factory->NewFixedArray(has_arg ? 1 : 0); |
4275 if (pending_error_arg_ != NULL) { | 4292 if (pending_error_arg_ != NULL) { |
4276 Handle<String> arg_string = pending_error_arg_->string(); | 4293 Handle<String> arg_string = pending_error_arg_->string(); |
4277 elements->set(0, *arg_string); | 4294 elements->set(0, *arg_string); |
4278 } else if (pending_error_char_arg_ != NULL) { | 4295 } else if (pending_error_char_arg_ != NULL) { |
4279 Handle<String> arg_string = | 4296 Handle<String> arg_string = |
4280 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) | 4297 factory->NewStringFromUtf8(CStrVector(pending_error_char_arg_)) |
4281 .ToHandleChecked(); | 4298 .ToHandleChecked(); |
4282 elements->set(0, *arg_string); | 4299 elements->set(0, *arg_string); |
4283 } | 4300 } |
4284 isolate()->debug()->OnCompileError(script()); | 4301 isolate->debug()->OnCompileError(script); |
4285 | 4302 |
4286 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); | 4303 Handle<JSArray> array = factory->NewJSArrayWithElements(elements); |
4287 Handle<Object> error; | 4304 Handle<Object> error; |
4288 MaybeHandle<Object> maybe_error = | 4305 MaybeHandle<Object> maybe_error = |
4289 pending_error_is_reference_error_ | 4306 pending_error_is_reference_error_ |
4290 ? factory->NewReferenceError(pending_error_message_, array) | 4307 ? factory->NewReferenceError(pending_error_message_, array) |
4291 : factory->NewSyntaxError(pending_error_message_, array); | 4308 : factory->NewSyntaxError(pending_error_message_, array); |
4292 | 4309 |
4293 if (maybe_error.ToHandle(&error)) { | 4310 if (maybe_error.ToHandle(&error)) { |
4294 Handle<JSObject> jserror = Handle<JSObject>::cast(error); | 4311 Handle<JSObject> jserror = Handle<JSObject>::cast(error); |
4295 | 4312 |
4296 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); | 4313 Handle<Name> key_start_pos = factory->error_start_pos_symbol(); |
4297 JSObject::SetProperty( | 4314 JSObject::SetProperty(jserror, key_start_pos, |
4298 jserror, key_start_pos, | 4315 handle(Smi::FromInt(location.start_pos()), isolate), |
4299 handle(Smi::FromInt(location.start_pos()), isolate()), | 4316 SLOPPY).Check(); |
4300 SLOPPY).Check(); | |
4301 | 4317 |
4302 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); | 4318 Handle<Name> key_end_pos = factory->error_end_pos_symbol(); |
4303 JSObject::SetProperty(jserror, key_end_pos, | 4319 JSObject::SetProperty(jserror, key_end_pos, |
4304 handle(Smi::FromInt(location.end_pos()), isolate()), | 4320 handle(Smi::FromInt(location.end_pos()), isolate), |
4305 SLOPPY).Check(); | 4321 SLOPPY).Check(); |
4306 | 4322 |
4307 Handle<Name> key_script = factory->error_script_symbol(); | 4323 Handle<Name> key_script = factory->error_script_symbol(); |
4308 JSObject::SetProperty(jserror, key_script, script(), SLOPPY).Check(); | 4324 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); |
4309 | 4325 |
4310 isolate()->Throw(*error, &location); | 4326 isolate->Throw(*error, &location); |
4311 } | 4327 } |
4312 } | 4328 } |
4313 } | 4329 } |
4314 | 4330 |
4315 | 4331 |
4316 void Parser::Internalize() { | 4332 void Parser::Internalize(CompilationInfo* info) { |
4317 // Internalize strings. | 4333 // Internalize strings. |
4318 ast_value_factory()->Internalize(isolate()); | 4334 ast_value_factory()->Internalize(info->isolate()); |
4319 | 4335 |
4320 // Error processing. | 4336 // Error processing. |
4321 if (info()->function() == NULL) { | 4337 if (info->function() == NULL) { |
4322 if (stack_overflow()) { | 4338 if (stack_overflow()) { |
4323 isolate()->StackOverflow(); | 4339 info->isolate()->StackOverflow(); |
4324 } else { | 4340 } else { |
4325 ThrowPendingError(); | 4341 ThrowPendingError(info->isolate(), info->script()); |
4326 } | 4342 } |
4327 } | 4343 } |
4328 | 4344 |
4329 // Move statistics to Isolate. | 4345 // Move statistics to Isolate. |
4330 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 4346 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
4331 ++feature) { | 4347 ++feature) { |
4332 for (int i = 0; i < use_counts_[feature]; ++i) { | 4348 for (int i = 0; i < use_counts_[feature]; ++i) { |
4333 isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 4349 info->isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
4334 } | 4350 } |
4335 } | 4351 } |
4336 isolate()->counters()->total_preparse_skipped()->Increment( | 4352 info->isolate()->counters()->total_preparse_skipped()->Increment( |
4337 total_preparse_skipped_); | 4353 total_preparse_skipped_); |
4338 } | 4354 } |
4339 | 4355 |
4340 | 4356 |
4341 // ---------------------------------------------------------------------------- | 4357 // ---------------------------------------------------------------------------- |
4342 // Regular expressions | 4358 // Regular expressions |
4343 | 4359 |
4344 | 4360 |
4345 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, | 4361 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, |
4346 bool multiline, bool unicode, Isolate* isolate, | 4362 bool multiline, bool unicode, Isolate* isolate, |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5244 result->tree = tree; | 5260 result->tree = tree; |
5245 int capture_count = parser.captures_started(); | 5261 int capture_count = parser.captures_started(); |
5246 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; | 5262 result->simple = tree->IsAtom() && parser.simple() && capture_count == 0; |
5247 result->contains_anchor = parser.contains_anchor(); | 5263 result->contains_anchor = parser.contains_anchor(); |
5248 result->capture_count = capture_count; | 5264 result->capture_count = capture_count; |
5249 } | 5265 } |
5250 return !parser.failed(); | 5266 return !parser.failed(); |
5251 } | 5267 } |
5252 | 5268 |
5253 | 5269 |
5254 bool Parser::Parse(CompilationInfo* info, bool allow_lazy) { | 5270 bool Parser::ParseStatic(CompilationInfo* info, bool allow_lazy) { |
5255 Parser parser(info, info->isolate()->stack_guard()->real_climit(), | 5271 Parser parser(info, info->isolate()->stack_guard()->real_climit(), |
5256 info->isolate()->heap()->HashSeed(), | 5272 info->isolate()->heap()->HashSeed(), |
5257 info->isolate()->unicode_cache()); | 5273 info->isolate()->unicode_cache()); |
5258 parser.set_allow_lazy(allow_lazy); | 5274 parser.set_allow_lazy(allow_lazy); |
5259 if (parser.Parse()) { | 5275 if (parser.Parse(info)) { |
5260 info->SetLanguageMode(info->function()->language_mode()); | 5276 info->SetLanguageMode(info->function()->language_mode()); |
5261 return true; | 5277 return true; |
5262 } | 5278 } |
5263 return false; | 5279 return false; |
5264 } | 5280 } |
5265 | 5281 |
5266 | 5282 |
5267 bool Parser::Parse() { | 5283 bool Parser::Parse(CompilationInfo* info) { |
5268 DCHECK(info()->function() == NULL); | 5284 DCHECK(info->function() == NULL); |
5269 FunctionLiteral* result = NULL; | 5285 FunctionLiteral* result = NULL; |
5270 pre_parse_timer_ = isolate()->counters()->pre_parse(); | 5286 // Ok to use Isolate here; this function is only called in the main thread. |
| 5287 DCHECK(parsing_on_main_thread_); |
| 5288 Isolate* isolate = info->isolate(); |
| 5289 pre_parse_timer_ = isolate->counters()->pre_parse(); |
5271 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { | 5290 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { |
5272 // If intrinsics are allowed, the Parser cannot operate independent of the | 5291 // If intrinsics are allowed, the Parser cannot operate independent of the |
5273 // V8 heap because of Runtime. Tell the string table to internalize strings | 5292 // V8 heap because of Runtime. Tell the string table to internalize strings |
5274 // and values right after they're created. | 5293 // and values right after they're created. |
5275 ast_value_factory()->Internalize(isolate()); | 5294 ast_value_factory()->Internalize(isolate); |
5276 } | 5295 } |
5277 | 5296 |
5278 if (info()->is_lazy()) { | 5297 if (info->is_lazy()) { |
5279 DCHECK(!info()->is_eval()); | 5298 DCHECK(!info->is_eval()); |
5280 if (info()->shared_info()->is_function()) { | 5299 if (info->shared_info()->is_function()) { |
5281 result = ParseLazy(); | 5300 result = ParseLazy(info); |
5282 } else { | 5301 } else { |
5283 result = ParseProgram(); | 5302 result = ParseProgram(info); |
5284 } | 5303 } |
5285 } else { | 5304 } else { |
5286 SetCachedData(); | 5305 SetCachedData(info); |
5287 result = ParseProgram(); | 5306 result = ParseProgram(info); |
5288 } | 5307 } |
5289 info()->SetFunction(result); | 5308 info->SetFunction(result); |
5290 | 5309 |
5291 Internalize(); | 5310 Internalize(info); |
5292 DCHECK(ast_value_factory()->IsInternalized()); | 5311 DCHECK(ast_value_factory()->IsInternalized()); |
5293 return (result != NULL); | 5312 return (result != NULL); |
5294 } | 5313 } |
5295 | 5314 |
5296 | 5315 |
5297 void Parser::ParseOnBackground() { | 5316 void Parser::ParseOnBackground(CompilationInfo* info) { |
5298 DCHECK(info()->function() == NULL); | 5317 parsing_on_main_thread_ = false; |
| 5318 |
| 5319 DCHECK(info->function() == NULL); |
5299 FunctionLiteral* result = NULL; | 5320 FunctionLiteral* result = NULL; |
5300 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 5321 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
5301 | 5322 |
5302 CompleteParserRecorder recorder; | 5323 CompleteParserRecorder recorder; |
5303 if (produce_cached_parse_data()) log_ = &recorder; | 5324 if (produce_cached_parse_data()) log_ = &recorder; |
5304 | 5325 |
5305 DCHECK(info()->source_stream() != NULL); | 5326 DCHECK(info->source_stream() != NULL); |
5306 ExternalStreamingStream stream(info()->source_stream(), | 5327 ExternalStreamingStream stream(info->source_stream(), |
5307 info()->source_stream_encoding()); | 5328 info->source_stream_encoding()); |
5308 scanner_.Initialize(&stream); | 5329 scanner_.Initialize(&stream); |
5309 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); | 5330 DCHECK(info->context().is_null() || info->context()->IsNativeContext()); |
5310 | 5331 |
5311 // When streaming, we don't know the length of the source until we have parsed | 5332 // When streaming, we don't know the length of the source until we have parsed |
5312 // it. The raw data can be UTF-8, so we wouldn't know the source length until | 5333 // it. The raw data can be UTF-8, so we wouldn't know the source length until |
5313 // we have decoded it anyway even if we knew the raw data length (which we | 5334 // we have decoded it anyway even if we knew the raw data length (which we |
5314 // don't). We work around this by storing all the scopes which need their end | 5335 // don't). We work around this by storing all the scopes which need their end |
5315 // position set at the end of the script (the top scope and possible eval | 5336 // position set at the end of the script (the top scope and possible eval |
5316 // scopes) and set their end position after we know the script length. | 5337 // scopes) and set their end position after we know the script length. |
5317 Scope* top_scope = NULL; | 5338 Scope* top_scope = NULL; |
5318 Scope* eval_scope = NULL; | 5339 Scope* eval_scope = NULL; |
5319 result = DoParseProgram(info(), &top_scope, &eval_scope); | 5340 result = DoParseProgram(info, &top_scope, &eval_scope); |
5320 | 5341 |
5321 top_scope->set_end_position(scanner()->location().end_pos); | 5342 top_scope->set_end_position(scanner()->location().end_pos); |
5322 if (eval_scope != NULL) { | 5343 if (eval_scope != NULL) { |
5323 eval_scope->set_end_position(scanner()->location().end_pos); | 5344 eval_scope->set_end_position(scanner()->location().end_pos); |
5324 } | 5345 } |
5325 | 5346 |
5326 info()->SetFunction(result); | 5347 info->SetFunction(result); |
5327 | 5348 |
5328 // We cannot internalize on a background thread; a foreground task will take | 5349 // We cannot internalize on a background thread; a foreground task will take |
5329 // care of calling Parser::Internalize just before compilation. | 5350 // care of calling Parser::Internalize just before compilation. |
5330 | 5351 |
5331 if (produce_cached_parse_data()) { | 5352 if (produce_cached_parse_data()) { |
5332 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 5353 if (result != NULL) *info->cached_data() = recorder.GetScriptData(); |
5333 log_ = NULL; | 5354 log_ = NULL; |
5334 } | 5355 } |
5335 } | 5356 } |
5336 | 5357 |
5337 | 5358 |
5338 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { | 5359 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
5339 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); | 5360 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); |
5340 } | 5361 } |
5341 | 5362 |
5342 | 5363 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5449 } else { | 5470 } else { |
5450 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5471 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5451 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5472 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5452 raw_string->length()); | 5473 raw_string->length()); |
5453 } | 5474 } |
5454 } | 5475 } |
5455 | 5476 |
5456 return running_hash; | 5477 return running_hash; |
5457 } | 5478 } |
5458 } } // namespace v8::internal | 5479 } } // namespace v8::internal |
OLD | NEW |