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

Side by Side Diff: src/parser.cc

Issue 724023002: Soft fail for invalid cache data. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: use flag to indicate rejection Created 6 years, 1 month 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
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 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
837 base::ElapsedTimer timer; 838 base::ElapsedTimer timer;
838 if (FLAG_trace_parse) { 839 if (FLAG_trace_parse) {
839 timer.Start(); 840 timer.Start();
840 } 841 }
841 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 842 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
842 843
843 // Initialize parser state. 844 // Initialize parser state.
844 CompleteParserRecorder recorder; 845 CompleteParserRecorder recorder;
845 846
846 debug_saved_compile_options_ = compile_options(); 847 debug_saved_compile_options_ = compile_options();
847 if (compile_options() == ScriptCompiler::kProduceParserCache) { 848 if (produce_cached_parse_data()) {
848 log_ = &recorder; 849 log_ = &recorder;
849 } else if (compile_options() == ScriptCompiler::kConsumeParserCache) { 850 } else if (consume_cached_parse_data()) {
850 cached_parse_data_->Initialize(); 851 cached_parse_data_->Initialize();
851 } 852 }
852 853
853 source = String::Flatten(source); 854 source = String::Flatten(source);
854 FunctionLiteral* result; 855 FunctionLiteral* result;
855 856
856 Scope* top_scope = NULL; 857 Scope* top_scope = NULL;
857 Scope* eval_scope = NULL; 858 Scope* eval_scope = NULL;
858 if (source->IsExternalTwoByteString()) { 859 if (source->IsExternalTwoByteString()) {
859 // Notice that the stream is destroyed at the end of the branch block. 860 // Notice that the stream is destroyed at the end of the branch block.
(...skipping 20 matching lines...) Expand all
880 PrintF("[parsing eval"); 881 PrintF("[parsing eval");
881 } else if (info()->script()->name()->IsString()) { 882 } else if (info()->script()->name()->IsString()) {
882 String* name = String::cast(info()->script()->name()); 883 String* name = String::cast(info()->script()->name());
883 SmartArrayPointer<char> name_chars = name->ToCString(); 884 SmartArrayPointer<char> name_chars = name->ToCString();
884 PrintF("[parsing script: %s", name_chars.get()); 885 PrintF("[parsing script: %s", name_chars.get());
885 } else { 886 } else {
886 PrintF("[parsing script"); 887 PrintF("[parsing script");
887 } 888 }
888 PrintF(" - took %0.3f ms]\n", ms); 889 PrintF(" - took %0.3f ms]\n", ms);
889 } 890 }
890 if (compile_options() == ScriptCompiler::kProduceParserCache) { 891 if (produce_cached_parse_data()) {
891 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 892 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
892 log_ = NULL; 893 log_ = NULL;
893 } 894 }
894 return result; 895 return result;
895 } 896 }
896 897
897 898
898 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope, 899 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, Scope** scope,
899 Scope** eval_scope) { 900 Scope** eval_scope) {
900 DCHECK(scope_ == NULL); 901 DCHECK(scope_ == NULL);
(...skipping 2853 matching lines...) Expand 10 before | Expand all | Expand 10 after
3754 int* materialized_literal_count, 3755 int* materialized_literal_count,
3755 int* expected_property_count, 3756 int* expected_property_count,
3756 bool* ok) { 3757 bool* ok) {
3757 // Temporary debugging code for tracking down a mystery crash which should 3758 // Temporary debugging code for tracking down a mystery crash which should
3758 // never happen. The crash happens on the line where we log the function in 3759 // never happen. The crash happens on the line where we log the function in
3759 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once 3760 // the preparse data: log_->LogFunction(...). TODO(marja): remove this once
3760 // done. 3761 // done.
3761 CHECK(materialized_literal_count); 3762 CHECK(materialized_literal_count);
3762 CHECK(expected_property_count); 3763 CHECK(expected_property_count);
3763 CHECK(debug_saved_compile_options_ == compile_options()); 3764 CHECK(debug_saved_compile_options_ == compile_options());
3764 if (compile_options() == ScriptCompiler::kProduceParserCache) { 3765 if (produce_cached_parse_data()) CHECK(log_);
3765 CHECK(log_);
3766 }
3767 3766
3768 int function_block_pos = position(); 3767 int function_block_pos = position();
3769 if (compile_options() == ScriptCompiler::kConsumeParserCache) { 3768 if (consume_cached_parse_data()) {
3770 // If we have cached data, we use it to skip parsing the function body. The 3769 // If we have cached data, we use it to skip parsing the function body. The
3771 // data contains the information we need to construct the lazy function. 3770 // data contains the information we need to construct the lazy function.
3772 FunctionEntry entry = 3771 FunctionEntry entry =
3773 cached_parse_data_->GetFunctionEntry(function_block_pos); 3772 cached_parse_data_->GetFunctionEntry(function_block_pos);
3774 // Check that cached data is valid. 3773 // Check that cached data is valid.
3775 CHECK(entry.is_valid()); 3774 CHECK(entry.is_valid());
3776 // End position greater than end of stream is safe, and hard to check. 3775 // End position greater than end of stream is safe, and hard to check.
3777 CHECK(entry.end_pos() > function_block_pos); 3776 CHECK(entry.end_pos() > function_block_pos);
3778 scanner()->SeekForward(entry.end_pos() - 1); 3777 scanner()->SeekForward(entry.end_pos() - 1);
3779 3778
(...skipping 27 matching lines...) Expand all
3807 } 3806 }
3808 scope_->set_end_position(logger.end()); 3807 scope_->set_end_position(logger.end());
3809 Expect(Token::RBRACE, ok); 3808 Expect(Token::RBRACE, ok);
3810 if (!*ok) { 3809 if (!*ok) {
3811 return; 3810 return;
3812 } 3811 }
3813 total_preparse_skipped_ += scope_->end_position() - function_block_pos; 3812 total_preparse_skipped_ += scope_->end_position() - function_block_pos;
3814 *materialized_literal_count = logger.literals(); 3813 *materialized_literal_count = logger.literals();
3815 *expected_property_count = logger.properties(); 3814 *expected_property_count = logger.properties();
3816 scope_->SetStrictMode(logger.strict_mode()); 3815 scope_->SetStrictMode(logger.strict_mode());
3817 if (compile_options() == ScriptCompiler::kProduceParserCache) { 3816 if (produce_cached_parse_data()) {
3818 DCHECK(log_); 3817 DCHECK(log_);
3819 // Position right after terminal '}'. 3818 // Position right after terminal '}'.
3820 int body_end = scanner()->location().end_pos; 3819 int body_end = scanner()->location().end_pos;
3821 log_->LogFunction(function_block_pos, body_end, 3820 log_->LogFunction(function_block_pos, body_end,
3822 *materialized_literal_count, 3821 *materialized_literal_count,
3823 *expected_property_count, 3822 *expected_property_count,
3824 scope_->strict_mode()); 3823 scope_->strict_mode());
3825 } 3824 }
3826 } 3825 }
3827 } 3826 }
(...skipping 1155 matching lines...) Expand 10 before | Expand all | Expand 10 after
4983 } 4982 }
4984 4983
4985 4984
4986 void Parser::ParseOnBackground() { 4985 void Parser::ParseOnBackground() {
4987 DCHECK(info()->function() == NULL); 4986 DCHECK(info()->function() == NULL);
4988 FunctionLiteral* result = NULL; 4987 FunctionLiteral* result = NULL;
4989 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone()); 4988 fni_ = new (zone()) FuncNameInferrer(ast_value_factory(), zone());
4990 4989
4991 CompleteParserRecorder recorder; 4990 CompleteParserRecorder recorder;
4992 debug_saved_compile_options_ = compile_options(); 4991 debug_saved_compile_options_ = compile_options();
4993 if (compile_options() == ScriptCompiler::kProduceParserCache) { 4992 if (produce_cached_parse_data()) log_ = &recorder;
4994 log_ = &recorder;
4995 }
4996 4993
4997 DCHECK(info()->source_stream() != NULL); 4994 DCHECK(info()->source_stream() != NULL);
4998 ExternalStreamingStream stream(info()->source_stream(), 4995 ExternalStreamingStream stream(info()->source_stream(),
4999 info()->source_stream_encoding()); 4996 info()->source_stream_encoding());
5000 scanner_.Initialize(&stream); 4997 scanner_.Initialize(&stream);
5001 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext()); 4998 DCHECK(info()->context().is_null() || info()->context()->IsNativeContext());
5002 4999
5003 // When streaming, we don't know the length of the source until we have parsed 5000 // When streaming, we don't know the length of the source until we have parsed
5004 // it. The raw data can be UTF-8, so we wouldn't know the source length until 5001 // it. The raw data can be UTF-8, so we wouldn't know the source length until
5005 // we have decoded it anyway even if we knew the raw data length (which we 5002 // we have decoded it anyway even if we knew the raw data length (which we
5006 // don't). We work around this by storing all the scopes which need their end 5003 // don't). We work around this by storing all the scopes which need their end
5007 // position set at the end of the script (the top scope and possible eval 5004 // position set at the end of the script (the top scope and possible eval
5008 // scopes) and set their end position after we know the script length. 5005 // scopes) and set their end position after we know the script length.
5009 Scope* top_scope = NULL; 5006 Scope* top_scope = NULL;
5010 Scope* eval_scope = NULL; 5007 Scope* eval_scope = NULL;
5011 result = DoParseProgram(info(), &top_scope, &eval_scope); 5008 result = DoParseProgram(info(), &top_scope, &eval_scope);
5012 5009
5013 top_scope->set_end_position(scanner()->location().end_pos); 5010 top_scope->set_end_position(scanner()->location().end_pos);
5014 if (eval_scope != NULL) { 5011 if (eval_scope != NULL) {
5015 eval_scope->set_end_position(scanner()->location().end_pos); 5012 eval_scope->set_end_position(scanner()->location().end_pos);
5016 } 5013 }
5017 5014
5018 info()->SetFunction(result); 5015 info()->SetFunction(result);
5019 5016
5020 // We cannot internalize on a background thread; a foreground task will take 5017 // We cannot internalize on a background thread; a foreground task will take
5021 // care of calling Parser::Internalize just before compilation. 5018 // care of calling Parser::Internalize just before compilation.
5022 5019
5023 if (compile_options() == ScriptCompiler::kProduceParserCache) { 5020 if (produce_cached_parse_data()) {
5024 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); 5021 if (result != NULL) *info_->cached_data() = recorder.GetScriptData();
5025 log_ = NULL; 5022 log_ = NULL;
5026 } 5023 }
5027 } 5024 }
5028 } } // namespace v8::internal 5025 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.h ('k') | src/serialize.h » ('j') | test/cctest/test-api.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698