OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 return result; | 220 return result; |
221 } | 221 } |
222 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); | 222 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); |
223 return result; | 223 return result; |
224 } | 224 } |
225 | 225 |
226 | 226 |
227 ScriptData* ScriptData::New(const char* data, int length) { | 227 ScriptData* ScriptData::New(const char* data, int length) { |
228 // The length is obviously invalid. | 228 // The length is obviously invalid. |
229 if (length % sizeof(unsigned) != 0) { | 229 if (length % sizeof(unsigned) != 0) { |
230 return new ScriptData(); | 230 return NULL; |
231 } | 231 } |
232 | 232 |
233 int deserialized_data_length = length / sizeof(unsigned); | 233 int deserialized_data_length = length / sizeof(unsigned); |
234 unsigned* deserialized_data; | 234 unsigned* deserialized_data; |
235 ScriptData* script_data = new ScriptData(); | 235 bool owns_store = reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0; |
236 script_data->owns_store_ = | 236 if (owns_store) { |
237 reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0; | |
238 if (script_data->owns_store_) { | |
239 // Copy the data to align it. | 237 // Copy the data to align it. |
240 deserialized_data = i::NewArray<unsigned>(deserialized_data_length); | 238 deserialized_data = i::NewArray<unsigned>(deserialized_data_length); |
241 i::CopyBytes(reinterpret_cast<char*>(deserialized_data), | 239 i::CopyBytes(reinterpret_cast<char*>(deserialized_data), |
242 data, static_cast<size_t>(length)); | 240 data, static_cast<size_t>(length)); |
243 } else { | 241 } else { |
244 // If aligned, don't create a copy of the data. | 242 // If aligned, don't create a copy of the data. |
245 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data)); | 243 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data)); |
246 } | 244 } |
247 script_data->store_ = | 245 return new ScriptData( |
248 Vector<unsigned>(deserialized_data, deserialized_data_length); | 246 Vector<unsigned>(deserialized_data, deserialized_data_length), |
249 return script_data; | 247 owns_store); |
250 } | 248 } |
251 | 249 |
252 | 250 |
253 FunctionEntry ScriptData::GetFunctionEntry(int start) { | 251 FunctionEntry ScriptData::GetFunctionEntry(int start) { |
254 // The current pre-data entry must be a FunctionEntry with the given | 252 // The current pre-data entry must be a FunctionEntry with the given |
255 // start position. | 253 // start position. |
256 if ((function_index_ + FunctionEntry::kSize <= store_.length()) | 254 if ((function_index_ + FunctionEntry::kSize <= store_.length()) |
257 && (static_cast<int>(store_[function_index_]) == start)) { | 255 && (static_cast<int>(store_[function_index_]) == start)) { |
258 int index = function_index_; | 256 int index = function_index_; |
259 function_index_ += FunctionEntry::kSize; | 257 function_index_ += FunctionEntry::kSize; |
(...skipping 2871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3131 // DebuggerStatement :: | 3129 // DebuggerStatement :: |
3132 // 'debugger' ';' | 3130 // 'debugger' ';' |
3133 | 3131 |
3134 int pos = peek_position(); | 3132 int pos = peek_position(); |
3135 Expect(Token::DEBUGGER, CHECK_OK); | 3133 Expect(Token::DEBUGGER, CHECK_OK); |
3136 ExpectSemicolon(CHECK_OK); | 3134 ExpectSemicolon(CHECK_OK); |
3137 return factory()->NewDebuggerStatement(pos); | 3135 return factory()->NewDebuggerStatement(pos); |
3138 } | 3136 } |
3139 | 3137 |
3140 | 3138 |
3141 void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) { | 3139 void Parser::ReportInvalidCachedData(Handle<String> name, bool* ok) { |
3142 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); | 3140 SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS); |
3143 const char* element[1] = { name_string.get() }; | 3141 const char* element[1] = { name_string.get() }; |
3144 ReportMessage("invalid_preparser_data", | 3142 ReportMessage("invalid_cached_data_function", |
3145 Vector<const char*>(element, 1)); | 3143 Vector<const char*>(element, 1)); |
3146 *ok = false; | 3144 *ok = false; |
3147 } | 3145 } |
3148 | 3146 |
3149 | 3147 |
3150 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3148 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
3151 if (expression->AsLiteral() != NULL) return true; | 3149 if (expression->AsLiteral() != NULL) return true; |
3152 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3150 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
3153 return lit != NULL && lit->is_simple(); | 3151 return lit != NULL && lit->is_simple(); |
3154 } | 3152 } |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3395 FunctionEntry entry; | 3393 FunctionEntry entry; |
3396 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3394 if (cached_data_mode_ == CONSUME_CACHED_DATA) { |
3397 // If we have cached data, we use it to skip parsing the function body. | 3395 // If we have cached data, we use it to skip parsing the function body. |
3398 // The data contains the information we need to construct the lazy | 3396 // The data contains the information we need to construct the lazy |
3399 // function. | 3397 // function. |
3400 entry = (*cached_data())->GetFunctionEntry(function_block_pos); | 3398 entry = (*cached_data())->GetFunctionEntry(function_block_pos); |
3401 if (entry.is_valid()) { | 3399 if (entry.is_valid()) { |
3402 if (entry.end_pos() <= function_block_pos) { | 3400 if (entry.end_pos() <= function_block_pos) { |
3403 // End position greater than end of stream is safe, and hard | 3401 // End position greater than end of stream is safe, and hard |
3404 // to check. | 3402 // to check. |
3405 ReportInvalidPreparseData(function_name, CHECK_OK); | 3403 ReportInvalidCachedData(function_name, CHECK_OK); |
3406 } | 3404 } |
3407 scanner()->SeekForward(entry.end_pos() - 1); | 3405 scanner()->SeekForward(entry.end_pos() - 1); |
3408 | 3406 |
3409 scope->set_end_position(entry.end_pos()); | 3407 scope->set_end_position(entry.end_pos()); |
3410 Expect(Token::RBRACE, CHECK_OK); | 3408 Expect(Token::RBRACE, CHECK_OK); |
3411 isolate()->counters()->total_preparse_skipped()->Increment( | 3409 isolate()->counters()->total_preparse_skipped()->Increment( |
3412 scope->end_position() - function_block_pos); | 3410 scope->end_position() - function_block_pos); |
3413 materialized_literal_count = entry.literal_count(); | 3411 materialized_literal_count = entry.literal_count(); |
3414 expected_property_count = entry.property_count(); | 3412 expected_property_count = entry.property_count(); |
3415 scope_->SetStrictMode(entry.strict_mode()); | 3413 scope_->SetStrictMode(entry.strict_mode()); |
3416 } else { | 3414 } else { |
3417 // This case happens when we have preparse data but it doesn't contain | 3415 // This case happens when we have preparse data but it doesn't contain |
3418 // an entry for the function. As a safety net, fall back to eager | 3416 // an entry for the function. Fail the compilation. |
3419 // parsing. It is unclear whether PreParser's laziness analysis can | 3417 ReportInvalidCachedData(function_name, CHECK_OK); |
3420 // produce different results than the Parser's laziness analysis (see | |
3421 // https://codereview.chromium.org/7565003 ). In this case, we must | |
3422 // discard all the preparse data, since the symbol data will be wrong. | |
3423 is_lazily_parsed = false; | |
3424 cached_data_mode_ = NO_CACHED_DATA; | |
3425 } | 3418 } |
3426 } else { | 3419 } else { |
3427 // With no cached data, we partially parse the function, without | 3420 // With no cached data, we partially parse the function, without |
3428 // building an AST. This gathers the data needed to build a lazy | 3421 // building an AST. This gathers the data needed to build a lazy |
3429 // function. | 3422 // function. |
3430 // FIXME(marja): Now the PreParser doesn't need to log functions / | 3423 // FIXME(marja): Now the PreParser doesn't need to log functions / |
3431 // symbols; only errors -> clean that up. | 3424 // symbols; only errors -> clean that up. |
3432 SingletonLogger logger; | 3425 SingletonLogger logger; |
3433 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); | 3426 PreParser::PreParseResult result = LazyParseFunctionLiteral(&logger); |
3434 if (result == PreParser::kPreParseStackOverflow) { | 3427 if (result == PreParser::kPreParseStackOverflow) { |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4678 ASSERT(info()->isolate()->has_pending_exception()); | 4671 ASSERT(info()->isolate()->has_pending_exception()); |
4679 } else { | 4672 } else { |
4680 result = ParseProgram(); | 4673 result = ParseProgram(); |
4681 } | 4674 } |
4682 } | 4675 } |
4683 info()->SetFunction(result); | 4676 info()->SetFunction(result); |
4684 return (result != NULL); | 4677 return (result != NULL); |
4685 } | 4678 } |
4686 | 4679 |
4687 } } // namespace v8::internal | 4680 } } // namespace v8::internal |
OLD | NEW |