| 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 |