| 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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 | 195 |
| 196 int ParseData::FunctionCount() { | 196 int ParseData::FunctionCount() { |
| 197 int functions_size = FunctionsSize(); | 197 int functions_size = FunctionsSize(); |
| 198 if (functions_size < 0) return 0; | 198 if (functions_size < 0) return 0; |
| 199 if (functions_size % FunctionEntry::kSize != 0) return 0; | 199 if (functions_size % FunctionEntry::kSize != 0) return 0; |
| 200 return functions_size / FunctionEntry::kSize; | 200 return functions_size / FunctionEntry::kSize; |
| 201 } | 201 } |
| 202 | 202 |
| 203 | 203 |
| 204 bool ParseData::IsSane() { | 204 bool ParseData::IsSane() { |
| 205 if (!IsAligned(script_data_->length(), sizeof(unsigned))) return false; |
| 205 // Check that the header data is valid and doesn't specify | 206 // Check that the header data is valid and doesn't specify |
| 206 // point to positions outside the store. | 207 // point to positions outside the store. |
| 207 int data_length = Length(); | 208 int data_length = Length(); |
| 208 if (data_length < PreparseDataConstants::kHeaderSize) return false; | 209 if (data_length < PreparseDataConstants::kHeaderSize) return false; |
| 209 if (Magic() != PreparseDataConstants::kMagicNumber) return false; | 210 if (Magic() != PreparseDataConstants::kMagicNumber) return false; |
| 210 if (Version() != PreparseDataConstants::kCurrentVersion) return false; | 211 if (Version() != PreparseDataConstants::kCurrentVersion) return false; |
| 211 if (HasError()) return false; | 212 if (HasError()) return false; |
| 212 // Check that the space allocated for function entries is sane. | 213 // Check that the space allocated for function entries is sane. |
| 213 int functions_size = FunctionsSize(); | 214 int functions_size = FunctionsSize(); |
| 214 if (functions_size < 0) return false; | 215 if (functions_size < 0) return false; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 249 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); | 250 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); |
| 250 } | 251 } |
| 251 | 252 |
| 252 | 253 |
| 253 void Parser::SetCachedData() { | 254 void Parser::SetCachedData() { |
| 254 if (compile_options() == ScriptCompiler::kNoCompileOptions) { | 255 if (compile_options() == ScriptCompiler::kNoCompileOptions) { |
| 255 cached_parse_data_ = NULL; | 256 cached_parse_data_ = NULL; |
| 256 } else { | 257 } else { |
| 257 DCHECK(info_->cached_data() != NULL); | 258 DCHECK(info_->cached_data() != NULL); |
| 258 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 259 if (compile_options() == ScriptCompiler::kConsumeParserCache) { |
| 259 cached_parse_data_ = new ParseData(*info_->cached_data()); | 260 cached_parse_data_ = ParseData::FromCachedData(*info_->cached_data()); |
| 260 } | 261 } |
| 261 } | 262 } |
| 262 } | 263 } |
| 263 | 264 |
| 264 | 265 |
| 265 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 266 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
| 266 DCHECK(ast_value_factory()); | 267 DCHECK(ast_value_factory()); |
| 267 Scope* result = | 268 Scope* result = |
| 268 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone()); | 269 new (zone()) Scope(parent, scope_type, ast_value_factory(), zone()); |
| 269 result->Initialize(); | 270 result->Initialize(); |
| (...skipping 557 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 base::ElapsedTimer timer; | 828 base::ElapsedTimer timer; |
| 828 if (FLAG_trace_parse) { | 829 if (FLAG_trace_parse) { |
| 829 timer.Start(); | 830 timer.Start(); |
| 830 } | 831 } |
| 831 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 832 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
| 832 | 833 |
| 833 // Initialize parser state. | 834 // Initialize parser state. |
| 834 CompleteParserRecorder recorder; | 835 CompleteParserRecorder recorder; |
| 835 | 836 |
| 836 debug_saved_compile_options_ = compile_options(); | 837 debug_saved_compile_options_ = compile_options(); |
| 837 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 838 if (produce_cached_parse_data()) { |
| 838 log_ = &recorder; | 839 log_ = &recorder; |
| 839 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 840 } else if (consume_cached_parse_data()) { |
| 840 cached_parse_data_->Initialize(); | 841 cached_parse_data_->Initialize(); |
| 841 } | 842 } |
| 842 | 843 |
| 843 source = String::Flatten(source); | 844 source = String::Flatten(source); |
| 844 FunctionLiteral* result; | 845 FunctionLiteral* result; |
| 845 | 846 |
| 846 Scope* top_scope = NULL; | 847 Scope* top_scope = NULL; |
| 847 Scope* eval_scope = NULL; | 848 Scope* eval_scope = NULL; |
| 848 if (source->IsExternalTwoByteString()) { | 849 if (source->IsExternalTwoByteString()) { |
| 849 // Notice that the stream is destroyed at the end of the branch block. | 850 // Notice that the stream is destroyed at the end of the branch block. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 870 PrintF("[parsing eval"); | 871 PrintF("[parsing eval"); |
| 871 } else if (info()->script()->name()->IsString()) { | 872 } else if (info()->script()->name()->IsString()) { |
| 872 String* name = String::cast(info()->script()->name()); | 873 String* name = String::cast(info()->script()->name()); |
| 873 SmartArrayPointer<char> name_chars = name->ToCString(); | 874 SmartArrayPointer<char> name_chars = name->ToCString(); |
| 874 PrintF("[parsing script: %s", name_chars.get()); | 875 PrintF("[parsing script: %s", name_chars.get()); |
| 875 } else { | 876 } else { |
| 876 PrintF("[parsing script"); | 877 PrintF("[parsing script"); |
| 877 } | 878 } |
| 878 PrintF(" - took %0.3f ms]\n", ms); | 879 PrintF(" - took %0.3f ms]\n", ms); |
| 879 } | 880 } |
| 880 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 881 if (produce_cached_parse_data()) { |
| 881 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 882 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
| 882 log_ = NULL; | 883 log_ = NULL; |
| 883 } | 884 } |
| 884 return result; | 885 return result; |
| 885 } | 886 } |
| 886 | 887 |
| 887 | 888 |
| 888 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, | 889 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, |
| 889 Scope** eval_scope) { | 890 Scope** eval_scope) { |
| 890 DCHECK(scope_ == NULL); | 891 DCHECK(scope_ == NULL); |
| (...skipping 2911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3802 int* materialized_literal_count, | 3803 int* materialized_literal_count, |
| 3803 int* expected_property_count, | 3804 int* expected_property_count, |
| 3804 bool* ok) { | 3805 bool* ok) { |
| 3805 // Temporary debugging code for tracking down a mystery crash which should | 3806 // Temporary debugging code for tracking down a mystery crash which should |
| 3806 // never happen. The crash happens on the line where we log the function in | 3807 // never happen. The crash happens on the line where we log the function in |
| 3807 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once | 3808 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once |
| 3808 // done. | 3809 // done. |
| 3809 CHECK(materialized_literal_count); | 3810 CHECK(materialized_literal_count); |
| 3810 CHECK(expected_property_count); | 3811 CHECK(expected_property_count); |
| 3811 CHECK(debug_saved_compile_options_ == compile_options()); | 3812 CHECK(debug_saved_compile_options_ == compile_options()); |
| 3812 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3813 if (produce_cached_parse_data()) CHECK(log_); |
| 3813 CHECK(log_); | |
| 3814 } | |
| 3815 | 3814 |
| 3816 int function_block_pos = position(); | 3815 int function_block_pos = position(); |
| 3817 if (compile_options() == ScriptCompiler::kConsumeParserCache) { | 3816 if (consume_cached_parse_data()) { |
| 3818 // If we have cached data, we use it to skip parsing the function body. The | 3817 // If we have cached data, we use it to skip parsing the function body. The |
| 3819 // data contains the information we need to construct the lazy function. | 3818 // data contains the information we need to construct the lazy function. |
| 3820 FunctionEntry entry = | 3819 FunctionEntry entry = |
| 3821 cached_parse_data_->GetFunctionEntry(function_block_pos); | 3820 cached_parse_data_->GetFunctionEntry(function_block_pos); |
| 3822 // Check that cached data is valid. | 3821 // Check that cached data is valid. |
| 3823 CHECK(entry.is_valid()); | 3822 CHECK(entry.is_valid()); |
| 3824 // End position greater than end of stream is safe, and hard to check. | 3823 // End position greater than end of stream is safe, and hard to check. |
| 3825 CHECK(entry.end_pos() > function_block_pos); | 3824 CHECK(entry.end_pos() > function_block_pos); |
| 3826 scanner()->SeekForward(entry.end_pos() - 1); | 3825 scanner()->SeekForward(entry.end_pos() - 1); |
| 3827 | 3826 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 3855 } | 3854 } |
| 3856 scope_->set_end_position(logger.end()); | 3855 scope_->set_end_position(logger.end()); |
| 3857 Expect(Token::RBRACE, ok); | 3856 Expect(Token::RBRACE, ok); |
| 3858 if (!*ok) { | 3857 if (!*ok) { |
| 3859 return; | 3858 return; |
| 3860 } | 3859 } |
| 3861 total_preparse_skipped_ += scope_->end_position() - function_block_pos; | 3860 total_preparse_skipped_ += scope_->end_position() - function_block_pos; |
| 3862 *materialized_literal_count = logger.literals(); | 3861 *materialized_literal_count = logger.literals(); |
| 3863 *expected_property_count = logger.properties(); | 3862 *expected_property_count = logger.properties(); |
| 3864 scope_->SetStrictMode(logger.strict_mode()); | 3863 scope_->SetStrictMode(logger.strict_mode()); |
| 3865 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 3864 if (produce_cached_parse_data()) { |
| 3866 DCHECK(log_); | 3865 DCHECK(log_); |
| 3867 // Position right after terminal '}'. | 3866 // Position right after terminal '}'. |
| 3868 int body_end = scanner()->location().end_pos; | 3867 int body_end = scanner()->location().end_pos; |
| 3869 log_->LogFunction(function_block_pos, body_end, | 3868 log_->LogFunction(function_block_pos, body_end, |
| 3870 *materialized_literal_count, | 3869 *materialized_literal_count, |
| 3871 *expected_property_count, | 3870 *expected_property_count, |
| 3872 scope_->strict_mode()); | 3871 scope_->strict_mode()); |
| 3873 } | 3872 } |
| 3874 } | 3873 } |
| 3875 } | 3874 } |
| (...skipping 1240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5116 } | 5115 } |
| 5117 | 5116 |
| 5118 | 5117 |
| 5119 void Parser::ParseOnBackground() { | 5118 void Parser::ParseOnBackground() { |
| 5120 DCHECK(info()->function() == NULL); | 5119 DCHECK(info()->function() == NULL); |
| 5121 FunctionLiteral* result = NULL; | 5120 FunctionLiteral* result = NULL; |
| 5122 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); | 5121 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); |
| 5123 | 5122 |
| 5124 CompleteParserRecorder recorder; | 5123 CompleteParserRecorder recorder; |
| 5125 debug_saved_compile_options_ = compile_options(); | 5124 debug_saved_compile_options_ = compile_options(); |
| 5126 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 5125 if (produce_cached_parse_data()) log_ = &recorder; |
| 5127 log_ = &recorder; | |
| 5128 } | |
| 5129 | 5126 |
| 5130 DCHECK(info()->source_stream() != NULL); | 5127 DCHECK(info()->source_stream() != NULL); |
| 5131 ExternalStreamingStream stream(info()->source_stream(), | 5128 ExternalStreamingStream stream(info()->source_stream(), |
| 5132 info()->source_stream_encoding()); | 5129 info()->source_stream_encoding()); |
| 5133 scanner_.Initialize(&stream); | 5130 scanner_.Initialize(&stream); |
| 5134 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); | 5131 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); |
| 5135 | 5132 |
| 5136 // When streaming, we don't know the length of the source until we have parsed | 5133 // When streaming, we don't know the length of the source until we have parsed |
| 5137 // it. The raw data can be UTF-8, so we wouldn't know the source length until | 5134 // it. The raw data can be UTF-8, so we wouldn't know the source length until |
| 5138 // we have decoded it anyway even if we knew the raw data length (which we | 5135 // we have decoded it anyway even if we knew the raw data length (which we |
| 5139 // don't). We work around this by storing all the scopes which need their end | 5136 // don't). We work around this by storing all the scopes which need their end |
| 5140 // position set at the end of the script (the top scope and possible eval | 5137 // position set at the end of the script (the top scope and possible eval |
| 5141 // scopes) and set their end position after we know the script length. | 5138 // scopes) and set their end position after we know the script length. |
| 5142 Scope* top_scope = NULL; | 5139 Scope* top_scope = NULL; |
| 5143 Scope* eval_scope = NULL; | 5140 Scope* eval_scope = NULL; |
| 5144 result = DoParseProgram(info(), &top_scope, &eval_scope); | 5141 result = DoParseProgram(info(), &top_scope, &eval_scope); |
| 5145 | 5142 |
| 5146 top_scope->set_end_position(scanner()->location().end_pos); | 5143 top_scope->set_end_position(scanner()->location().end_pos); |
| 5147 if (eval_scope != NULL) { | 5144 if (eval_scope != NULL) { |
| 5148 eval_scope->set_end_position(scanner()->location().end_pos); | 5145 eval_scope->set_end_position(scanner()->location().end_pos); |
| 5149 } | 5146 } |
| 5150 | 5147 |
| 5151 info()->SetFunction(result); | 5148 info()->SetFunction(result); |
| 5152 | 5149 |
| 5153 // We cannot internalize on a background thread; a foreground task will take | 5150 // We cannot internalize on a background thread; a foreground task will take |
| 5154 // care of calling Parser::Internalize just before compilation. | 5151 // care of calling Parser::Internalize just before compilation. |
| 5155 | 5152 |
| 5156 if (compile_options() == ScriptCompiler::kProduceParserCache) { | 5153 if (produce_cached_parse_data()) { |
| 5157 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); | 5154 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
| 5158 log_ = NULL; | 5155 log_ = NULL; |
| 5159 } | 5156 } |
| 5160 } | 5157 } |
| 5161 | 5158 |
| 5162 | 5159 |
| 5163 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { | 5160 ParserTraits::TemplateLiteralState Parser::OpenTemplateLiteral(int pos) { |
| 5164 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); | 5161 return new (zone()) ParserTraits::TemplateLiteral(zone(), pos); |
| 5165 } | 5162 } |
| 5166 | 5163 |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5289 | 5286 |
| 5290 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( | 5287 const AstRawString* raw_str = ast_value_factory()->GetOneByteString( |
| 5291 OneByteVector(raw_chars.get(), to_index)); | 5288 OneByteVector(raw_chars.get(), to_index)); |
| 5292 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); | 5289 Literal* raw_lit = factory()->NewStringLiteral(raw_str, span_start - 1); |
| 5293 raw_strings->Add(raw_lit, zone()); | 5290 raw_strings->Add(raw_lit, zone()); |
| 5294 } | 5291 } |
| 5295 | 5292 |
| 5296 return raw_strings; | 5293 return raw_strings; |
| 5297 } | 5294 } |
| 5298 } } // namespace v8::internal | 5295 } } // namespace v8::internal |
| OLD | NEW |