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 804 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
815 use_counts_[feature] = 0; | 815 use_counts_[feature] = 0; |
816 } | 816 } |
817 if (info->ast_value_factory() == NULL) { | 817 if (info->ast_value_factory() == NULL) { |
818 // info takes ownership of AstValueFactory. | 818 // info takes ownership of AstValueFactory. |
819 info->SetAstValueFactory(new AstValueFactory(zone(), hash_seed)); | 819 info->SetAstValueFactory(new AstValueFactory(zone(), hash_seed)); |
820 ast_value_factory_ = info->ast_value_factory(); | 820 ast_value_factory_ = info->ast_value_factory(); |
821 } | 821 } |
822 } | 822 } |
823 | 823 |
824 | 824 |
825 FunctionLiteral* Parser::ParseProgram(CompilationInfo* info) { | 825 FunctionLiteral* Parser::ParseProgram(Isolate* isolate, CompilationInfo* info) { |
826 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, | 826 // TODO(bmeurer): We temporarily need to pass allow_nesting = true here, |
827 // see comment for HistogramTimerScope class. | 827 // see comment for HistogramTimerScope class. |
828 | 828 |
829 // It's OK to use the Isolate & counters here, since this function is only | 829 // It's OK to use the Isolate & counters here, since this function is only |
830 // called in the main thread. | 830 // called in the main thread. |
831 DCHECK(parsing_on_main_thread_); | 831 DCHECK(parsing_on_main_thread_); |
832 | 832 |
833 Isolate* isolate = info->isolate(); | |
834 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); | 833 HistogramTimerScope timer_scope(isolate->counters()->parse(), true); |
835 Handle<String> source(String::cast(info->script()->source())); | 834 Handle<String> source(String::cast(info->script()->source())); |
836 isolate->counters()->total_parse_size()->Increment(source->length()); | 835 isolate->counters()->total_parse_size()->Increment(source->length()); |
837 base::ElapsedTimer timer; | 836 base::ElapsedTimer timer; |
838 if (FLAG_trace_parse) { | 837 if (FLAG_trace_parse) { |
839 timer.Start(); | 838 timer.Start(); |
840 } | 839 } |
841 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 840 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
842 | 841 |
843 // Initialize parser state. | 842 // Initialize parser state. |
(...skipping 20 matching lines...) Expand all Loading... |
864 result = DoParseProgram(info, &top_scope, &eval_scope); | 863 result = DoParseProgram(info, &top_scope, &eval_scope); |
865 } else { | 864 } else { |
866 GenericStringUtf16CharacterStream stream(source, 0, source->length()); | 865 GenericStringUtf16CharacterStream stream(source, 0, source->length()); |
867 scanner_.Initialize(&stream); | 866 scanner_.Initialize(&stream); |
868 result = DoParseProgram(info, &top_scope, &eval_scope); | 867 result = DoParseProgram(info, &top_scope, &eval_scope); |
869 } | 868 } |
870 top_scope->set_end_position(source->length()); | 869 top_scope->set_end_position(source->length()); |
871 if (eval_scope != NULL) { | 870 if (eval_scope != NULL) { |
872 eval_scope->set_end_position(source->length()); | 871 eval_scope->set_end_position(source->length()); |
873 } | 872 } |
874 HandleSourceURLComments(info); | 873 HandleSourceURLComments(isolate, info->script()); |
875 | 874 |
876 if (FLAG_trace_parse && result != NULL) { | 875 if (FLAG_trace_parse && result != NULL) { |
877 double ms = timer.Elapsed().InMillisecondsF(); | 876 double ms = timer.Elapsed().InMillisecondsF(); |
878 if (info->is_eval()) { | 877 if (info->is_eval()) { |
879 PrintF("[parsing eval"); | 878 PrintF("[parsing eval"); |
880 } else if (info->script()->name()->IsString()) { | 879 } else if (info->script()->name()->IsString()) { |
881 String* name = String::cast(info->script()->name()); | 880 String* name = String::cast(info->script()->name()); |
882 SmartArrayPointer<char> name_chars = name->ToCString(); | 881 SmartArrayPointer<char> name_chars = name->ToCString(); |
883 PrintF("[parsing script: %s", name_chars.get()); | 882 PrintF("[parsing script: %s", name_chars.get()); |
884 } else { | 883 } else { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
984 } | 983 } |
985 } | 984 } |
986 | 985 |
987 // Make sure the target stack is empty. | 986 // Make sure the target stack is empty. |
988 DCHECK(target_stack_ == NULL); | 987 DCHECK(target_stack_ == NULL); |
989 | 988 |
990 return result; | 989 return result; |
991 } | 990 } |
992 | 991 |
993 | 992 |
994 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { | 993 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, CompilationInfo* info) { |
995 // It's OK to use the Isolate & counters here, since this function is only | 994 // It's OK to use the Isolate & counters here, since this function is only |
996 // called in the main thread. | 995 // called in the main thread. |
997 DCHECK(parsing_on_main_thread_); | 996 DCHECK(parsing_on_main_thread_); |
998 HistogramTimerScope timer_scope(info->isolate()->counters()->parse_lazy()); | 997 HistogramTimerScope timer_scope(isolate->counters()->parse_lazy()); |
999 Handle<String> source(String::cast(info->script()->source())); | 998 Handle<String> source(String::cast(info->script()->source())); |
1000 info->isolate()->counters()->total_parse_size()->Increment(source->length()); | 999 isolate->counters()->total_parse_size()->Increment(source->length()); |
1001 base::ElapsedTimer timer; | 1000 base::ElapsedTimer timer; |
1002 if (FLAG_trace_parse) { | 1001 if (FLAG_trace_parse) { |
1003 timer.Start(); | 1002 timer.Start(); |
1004 } | 1003 } |
1005 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 1004 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
1006 | 1005 |
1007 // Initialize parser state. | 1006 // Initialize parser state. |
1008 source = String::Flatten(source); | 1007 source = String::Flatten(source); |
1009 FunctionLiteral* result; | 1008 FunctionLiteral* result; |
1010 if (source->IsExternalTwoByteString()) { | 1009 if (source->IsExternalTwoByteString()) { |
1011 ExternalTwoByteStringUtf16CharacterStream stream( | 1010 ExternalTwoByteStringUtf16CharacterStream stream( |
1012 Handle<ExternalTwoByteString>::cast(source), | 1011 Handle<ExternalTwoByteString>::cast(source), |
1013 shared_info->start_position(), | 1012 shared_info->start_position(), |
1014 shared_info->end_position()); | 1013 shared_info->end_position()); |
1015 result = ParseLazy(info, &stream); | 1014 result = ParseLazy(isolate, info, &stream); |
1016 } else { | 1015 } else { |
1017 GenericStringUtf16CharacterStream stream(source, | 1016 GenericStringUtf16CharacterStream stream(source, |
1018 shared_info->start_position(), | 1017 shared_info->start_position(), |
1019 shared_info->end_position()); | 1018 shared_info->end_position()); |
1020 result = ParseLazy(info, &stream); | 1019 result = ParseLazy(isolate, info, &stream); |
1021 } | 1020 } |
1022 | 1021 |
1023 if (FLAG_trace_parse && result != NULL) { | 1022 if (FLAG_trace_parse && result != NULL) { |
1024 double ms = timer.Elapsed().InMillisecondsF(); | 1023 double ms = timer.Elapsed().InMillisecondsF(); |
1025 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); | 1024 SmartArrayPointer<char> name_chars = result->debug_name()->ToCString(); |
1026 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); | 1025 PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms); |
1027 } | 1026 } |
1028 return result; | 1027 return result; |
1029 } | 1028 } |
1030 | 1029 |
1031 | 1030 |
1032 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, | 1031 FunctionLiteral* Parser::ParseLazy(Isolate* isolate, CompilationInfo* info, |
1033 Utf16CharacterStream* source) { | 1032 Utf16CharacterStream* source) { |
1034 Handle<SharedFunctionInfo> shared_info = info->shared_info(); | 1033 Handle<SharedFunctionInfo> shared_info = info->shared_info(); |
1035 scanner_.Initialize(source); | 1034 scanner_.Initialize(source); |
1036 DCHECK(scope_ == NULL); | 1035 DCHECK(scope_ == NULL); |
1037 DCHECK(target_stack_ == NULL); | 1036 DCHECK(target_stack_ == NULL); |
1038 | 1037 |
1039 Handle<String> name(String::cast(shared_info->name())); | 1038 Handle<String> name(String::cast(shared_info->name())); |
1040 DCHECK(ast_value_factory()); | 1039 DCHECK(ast_value_factory()); |
1041 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 1040 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
1042 const AstRawString* raw_name = ast_value_factory()->GetString(name); | 1041 const AstRawString* raw_name = ast_value_factory()->GetString(name); |
1043 fni_->PushEnclosingName(raw_name); | 1042 fni_->PushEnclosingName(raw_name); |
1044 | 1043 |
1045 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); | 1044 ParsingModeScope parsing_mode(this, PARSE_EAGERLY); |
1046 | 1045 |
1047 // Place holder for the result. | 1046 // Place holder for the result. |
1048 FunctionLiteral* result = NULL; | 1047 FunctionLiteral* result = NULL; |
1049 | 1048 |
1050 { | 1049 { |
1051 // Parse the function literal. | 1050 // Parse the function literal. |
1052 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); | 1051 Scope* scope = NewScope(scope_, SCRIPT_SCOPE); |
1053 info->SetScriptScope(scope); | 1052 info->SetScriptScope(scope); |
1054 if (!info->closure().is_null()) { | 1053 if (!info->closure().is_null()) { |
1055 // Ok to use Isolate here, since lazy function parsing is only done in the | 1054 // Ok to use Isolate here, since lazy function parsing is only done in the |
1056 // main thread. | 1055 // main thread. |
1057 DCHECK(parsing_on_main_thread_); | 1056 DCHECK(parsing_on_main_thread_); |
1058 scope = Scope::DeserializeScopeChain(info->isolate(), zone(), | 1057 scope = Scope::DeserializeScopeChain(isolate, zone(), |
1059 info->closure()->context(), scope); | 1058 info->closure()->context(), scope); |
1060 } | 1059 } |
1061 original_scope_ = scope; | 1060 original_scope_ = scope; |
1062 AstNodeFactory function_factory(ast_value_factory()); | 1061 AstNodeFactory function_factory(ast_value_factory()); |
1063 FunctionState function_state(&function_state_, &scope_, scope, | 1062 FunctionState function_state(&function_state_, &scope_, scope, |
1064 shared_info->kind(), &function_factory); | 1063 shared_info->kind(), &function_factory); |
1065 DCHECK(is_sloppy(scope->language_mode()) || | 1064 DCHECK(is_sloppy(scope->language_mode()) || |
1066 is_strict(info->language_mode())); | 1065 is_strict(info->language_mode())); |
1067 DCHECK(info->language_mode() == shared_info->language_mode()); | 1066 DCHECK(info->language_mode() == shared_info->language_mode()); |
1068 scope->SetLanguageMode(shared_info->language_mode()); | 1067 scope->SetLanguageMode(shared_info->language_mode()); |
(...skipping 3160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4229 | 4228 |
4230 DCHECK(stat->is_target_for_anonymous()); | 4229 DCHECK(stat->is_target_for_anonymous()); |
4231 if (anonymous || ContainsLabel(stat->labels(), label)) { | 4230 if (anonymous || ContainsLabel(stat->labels(), label)) { |
4232 return stat; | 4231 return stat; |
4233 } | 4232 } |
4234 } | 4233 } |
4235 return NULL; | 4234 return NULL; |
4236 } | 4235 } |
4237 | 4236 |
4238 | 4237 |
4239 void Parser::HandleSourceURLComments(CompilationInfo* info) { | 4238 void Parser::HandleSourceURLComments(Isolate* isolate, Handle<Script> script) { |
4240 if (scanner_.source_url()->length() > 0) { | 4239 if (scanner_.source_url()->length() > 0) { |
4241 Handle<String> source_url = | 4240 Handle<String> source_url = scanner_.source_url()->Internalize(isolate); |
4242 scanner_.source_url()->Internalize(info->isolate()); | 4241 script->set_source_url(*source_url); |
4243 info->script()->set_source_url(*source_url); | |
4244 } | 4242 } |
4245 if (scanner_.source_mapping_url()->length() > 0) { | 4243 if (scanner_.source_mapping_url()->length() > 0) { |
4246 Handle<String> source_mapping_url = | 4244 Handle<String> source_mapping_url = |
4247 scanner_.source_mapping_url()->Internalize(info->isolate()); | 4245 scanner_.source_mapping_url()->Internalize(isolate); |
4248 info->script()->set_source_mapping_url(*source_mapping_url); | 4246 script->set_source_mapping_url(*source_mapping_url); |
4249 } | 4247 } |
4250 } | 4248 } |
4251 | 4249 |
4252 | 4250 |
4253 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { | 4251 void Parser::ThrowPendingError(Isolate* isolate, Handle<Script> script) { |
4254 DCHECK(ast_value_factory()->IsInternalized()); | 4252 DCHECK(ast_value_factory()->IsInternalized()); |
4255 if (has_pending_error_) { | 4253 if (has_pending_error_) { |
4256 MessageLocation location(script, pending_error_location_.beg_pos, | 4254 MessageLocation location(script, pending_error_location_.beg_pos, |
4257 pending_error_location_.end_pos); | 4255 pending_error_location_.end_pos); |
4258 Factory* factory = isolate->factory(); | 4256 Factory* factory = isolate->factory(); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4292 | 4290 |
4293 Handle<Name> key_script = factory->error_script_symbol(); | 4291 Handle<Name> key_script = factory->error_script_symbol(); |
4294 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); | 4292 JSObject::SetProperty(jserror, key_script, script, SLOPPY).Check(); |
4295 | 4293 |
4296 isolate->Throw(*error, &location); | 4294 isolate->Throw(*error, &location); |
4297 } | 4295 } |
4298 } | 4296 } |
4299 } | 4297 } |
4300 | 4298 |
4301 | 4299 |
4302 void Parser::Internalize(CompilationInfo* info) { | 4300 void Parser::Internalize(Isolate* isolate, Handle<Script> script, bool error) { |
4303 // Internalize strings. | 4301 // Internalize strings. |
4304 ast_value_factory()->Internalize(info->isolate()); | 4302 ast_value_factory()->Internalize(isolate); |
4305 | 4303 |
4306 // Error processing. | 4304 // Error processing. |
4307 if (info->function() == NULL) { | 4305 if (error) { |
4308 if (stack_overflow()) { | 4306 if (stack_overflow()) { |
4309 info->isolate()->StackOverflow(); | 4307 isolate->StackOverflow(); |
4310 } else { | 4308 } else { |
4311 ThrowPendingError(info->isolate(), info->script()); | 4309 ThrowPendingError(isolate, script); |
4312 } | 4310 } |
4313 } | 4311 } |
4314 | 4312 |
4315 // Move statistics to Isolate. | 4313 // Move statistics to Isolate. |
4316 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; | 4314 for (int feature = 0; feature < v8::Isolate::kUseCounterFeatureCount; |
4317 ++feature) { | 4315 ++feature) { |
4318 for (int i = 0; i < use_counts_[feature]; ++i) { | 4316 for (int i = 0; i < use_counts_[feature]; ++i) { |
4319 info->isolate()->CountUsage(v8::Isolate::UseCounterFeature(feature)); | 4317 isolate->CountUsage(v8::Isolate::UseCounterFeature(feature)); |
4320 } | 4318 } |
4321 } | 4319 } |
4322 info->isolate()->counters()->total_preparse_skipped()->Increment( | 4320 isolate->counters()->total_preparse_skipped()->Increment( |
4323 total_preparse_skipped_); | 4321 total_preparse_skipped_); |
4324 } | 4322 } |
4325 | 4323 |
4326 | 4324 |
4327 // ---------------------------------------------------------------------------- | 4325 // ---------------------------------------------------------------------------- |
4328 // Regular expressions | 4326 // Regular expressions |
4329 | 4327 |
4330 | 4328 |
4331 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, | 4329 RegExpParser::RegExpParser(FlatStringReader* in, Handle<String>* error, |
4332 bool multiline, bool unicode, Isolate* isolate, | 4330 bool multiline, bool unicode, Isolate* isolate, |
(...skipping 927 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5260 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { | 5258 if (FLAG_trace_parse || allow_natives() || extension_ != NULL) { |
5261 // If intrinsics are allowed, the Parser cannot operate independent of the | 5259 // If intrinsics are allowed, the Parser cannot operate independent of the |
5262 // V8 heap because of Runtime. Tell the string table to internalize strings | 5260 // V8 heap because of Runtime. Tell the string table to internalize strings |
5263 // and values right after they're created. | 5261 // and values right after they're created. |
5264 ast_value_factory()->Internalize(isolate); | 5262 ast_value_factory()->Internalize(isolate); |
5265 } | 5263 } |
5266 | 5264 |
5267 if (info->is_lazy()) { | 5265 if (info->is_lazy()) { |
5268 DCHECK(!info->is_eval()); | 5266 DCHECK(!info->is_eval()); |
5269 if (info->shared_info()->is_function()) { | 5267 if (info->shared_info()->is_function()) { |
5270 result = ParseLazy(info); | 5268 result = ParseLazy(isolate, info); |
5271 } else { | 5269 } else { |
5272 result = ParseProgram(info); | 5270 result = ParseProgram(isolate, info); |
5273 } | 5271 } |
5274 } else { | 5272 } else { |
5275 SetCachedData(info); | 5273 SetCachedData(info); |
5276 result = ParseProgram(info); | 5274 result = ParseProgram(isolate, info); |
5277 } | 5275 } |
5278 info->SetFunction(result); | 5276 info->SetFunction(result); |
5279 | 5277 |
5280 Internalize(info); | 5278 Internalize(isolate, info->script(), result == NULL); |
5281 DCHECK(ast_value_factory()->IsInternalized()); | 5279 DCHECK(ast_value_factory()->IsInternalized()); |
5282 return (result != NULL); | 5280 return (result != NULL); |
5283 } | 5281 } |
5284 | 5282 |
5285 | 5283 |
5286 void Parser::ParseOnBackground(CompilationInfo* info) { | 5284 void Parser::ParseOnBackground(CompilationInfo* info) { |
5287 parsing_on_main_thread_ = false; | 5285 parsing_on_main_thread_ = false; |
5288 | 5286 |
5289 DCHECK(info->function() == NULL); | 5287 DCHECK(info->function() == NULL); |
5290 FunctionLiteral* result = NULL; | 5288 FunctionLiteral* result = NULL; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5440 } else { | 5438 } else { |
5441 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); | 5439 const uc16* data = reinterpret_cast<const uc16*>(raw_string->raw_data()); |
5442 running_hash = StringHasher::ComputeRunningHash(running_hash, data, | 5440 running_hash = StringHasher::ComputeRunningHash(running_hash, data, |
5443 raw_string->length()); | 5441 raw_string->length()); |
5444 } | 5442 } |
5445 } | 5443 } |
5446 | 5444 |
5447 return running_hash; | 5445 return running_hash; |
5448 } | 5446 } |
5449 } } // namespace v8::internal | 5447 } } // namespace v8::internal |
OLD | NEW |