Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/parser.cc

Issue 908173003: Parsing: Make Parser not know about Isolate during background parsing. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: main thread check Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/preparser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698