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/base/platform/platform.h" | 9 #include "src/base/platform/platform.h" |
10 #include "src/bootstrapper.h" | 10 #include "src/bootstrapper.h" |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 // Only call immediately after adding an atom or character! | 175 // Only call immediately after adding an atom or character! |
176 UNREACHABLE(); | 176 UNREACHABLE(); |
177 return; | 177 return; |
178 } | 178 } |
179 terms_.Add( | 179 terms_.Add( |
180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); | 180 new(zone()) RegExpQuantifier(min, max, quantifier_type, atom), zone()); |
181 LAST(ADD_TERM); | 181 LAST(ADD_TERM); |
182 } | 182 } |
183 | 183 |
184 | 184 |
185 ScriptData* ScriptData::New(const char* data, int length, bool owns_store) { | 185 FunctionEntry ParseData::GetFunctionEntry(int start) { |
186 // The length is obviously invalid. | |
187 if (length % sizeof(unsigned) != 0) { | |
188 return NULL; | |
189 } | |
190 | |
191 int deserialized_data_length = length / sizeof(unsigned); | |
192 unsigned* deserialized_data; | |
193 owns_store = | |
194 owns_store || reinterpret_cast<intptr_t>(data) % sizeof(unsigned) != 0; | |
195 if (owns_store) { | |
196 // Copy the data to align it. | |
197 deserialized_data = i::NewArray<unsigned>(deserialized_data_length); | |
198 i::CopyBytes(reinterpret_cast<char*>(deserialized_data), | |
199 data, static_cast<size_t>(length)); | |
200 } else { | |
201 // If aligned, don't create a copy of the data. | |
202 deserialized_data = reinterpret_cast<unsigned*>(const_cast<char*>(data)); | |
203 } | |
204 return new ScriptData( | |
205 Vector<unsigned>(deserialized_data, deserialized_data_length), | |
206 owns_store); | |
207 } | |
208 | |
209 | |
210 FunctionEntry ScriptData::GetFunctionEntry(int start) { | |
211 // The current pre-data entry must be a FunctionEntry with the given | 186 // The current pre-data entry must be a FunctionEntry with the given |
212 // start position. | 187 // start position. |
213 if ((function_index_ + FunctionEntry::kSize <= store_.length()) | 188 if ((function_index_ + FunctionEntry::kSize <= Length()) && |
214 && (static_cast<int>(store_[function_index_]) == start)) { | 189 (static_cast<int>(Data()[function_index_]) == start)) { |
215 int index = function_index_; | 190 int index = function_index_; |
216 function_index_ += FunctionEntry::kSize; | 191 function_index_ += FunctionEntry::kSize; |
217 return FunctionEntry(store_.SubVector(index, | 192 Vector<unsigned> subvector(&(Data()[index]), FunctionEntry::kSize); |
218 index + FunctionEntry::kSize)); | 193 return FunctionEntry(subvector); |
219 } | 194 } |
220 return FunctionEntry(); | 195 return FunctionEntry(); |
221 } | 196 } |
222 | 197 |
223 | 198 |
224 int ScriptData::GetSymbolIdentifier() { | 199 int ParseData::FunctionCount() { |
225 return ReadNumber(&symbol_data_); | 200 int functions_size = FunctionsSize(); |
| 201 if (functions_size < 0) return 0; |
| 202 if (functions_size % FunctionEntry::kSize != 0) return 0; |
| 203 return functions_size / FunctionEntry::kSize; |
226 } | 204 } |
227 | 205 |
228 | 206 |
229 bool ScriptData::SanityCheck() { | 207 bool ParseData::IsSane() { |
230 // Check that the header data is valid and doesn't specify | 208 // Check that the header data is valid and doesn't specify |
231 // point to positions outside the store. | 209 // point to positions outside the store. |
232 if (store_.length() < PreparseDataConstants::kHeaderSize) return false; | 210 int data_length = Length(); |
233 if (magic() != PreparseDataConstants::kMagicNumber) return false; | 211 if (data_length < PreparseDataConstants::kHeaderSize) return false; |
234 if (version() != PreparseDataConstants::kCurrentVersion) return false; | 212 if (Magic() != PreparseDataConstants::kMagicNumber) return false; |
235 if (has_error()) { | 213 if (Version() != PreparseDataConstants::kCurrentVersion) return false; |
236 // Extra sane sanity check for error message encoding. | 214 if (HasError()) return false; |
237 if (store_.length() <= PreparseDataConstants::kHeaderSize | |
238 + PreparseDataConstants::kMessageTextPos) { | |
239 return false; | |
240 } | |
241 if (Read(PreparseDataConstants::kMessageStartPos) > | |
242 Read(PreparseDataConstants::kMessageEndPos)) { | |
243 return false; | |
244 } | |
245 unsigned arg_count = Read(PreparseDataConstants::kMessageArgCountPos); | |
246 int pos = PreparseDataConstants::kMessageTextPos; | |
247 for (unsigned int i = 0; i <= arg_count; i++) { | |
248 if (store_.length() <= PreparseDataConstants::kHeaderSize + pos) { | |
249 return false; | |
250 } | |
251 int length = static_cast<int>(Read(pos)); | |
252 if (length < 0) return false; | |
253 pos += 1 + length; | |
254 } | |
255 if (store_.length() < PreparseDataConstants::kHeaderSize + pos) { | |
256 return false; | |
257 } | |
258 return true; | |
259 } | |
260 // Check that the space allocated for function entries is sane. | 215 // Check that the space allocated for function entries is sane. |
261 int functions_size = | 216 int functions_size = FunctionsSize(); |
262 static_cast<int>(store_[PreparseDataConstants::kFunctionsSizeOffset]); | |
263 if (functions_size < 0) return false; | 217 if (functions_size < 0) return false; |
264 if (functions_size % FunctionEntry::kSize != 0) return false; | 218 if (functions_size % FunctionEntry::kSize != 0) return false; |
265 // Check that the total size has room for header and function entries. | 219 // Check that the total size has room for header and function entries. |
266 int minimum_size = | 220 int minimum_size = |
267 PreparseDataConstants::kHeaderSize + functions_size; | 221 PreparseDataConstants::kHeaderSize + functions_size; |
268 if (store_.length() < minimum_size) return false; | 222 if (data_length < minimum_size) return false; |
269 return true; | 223 return true; |
270 } | 224 } |
271 | 225 |
272 | 226 |
273 | 227 void ParseData::Initialize() { |
274 const char* ScriptData::ReadString(unsigned* start, int* chars) { | 228 // Prepares state for use. |
275 int length = start[0]; | 229 int data_length = Length(); |
276 char* result = NewArray<char>(length + 1); | 230 if (data_length >= PreparseDataConstants::kHeaderSize) { |
277 for (int i = 0; i < length; i++) { | 231 function_index_ = PreparseDataConstants::kHeaderSize; |
278 result[i] = start[i + 1]; | |
279 } | 232 } |
280 result[length] = '\0'; | |
281 if (chars != NULL) *chars = length; | |
282 return result; | |
283 } | 233 } |
284 | 234 |
285 | 235 |
286 Scanner::Location ScriptData::MessageLocation() const { | 236 bool ParseData::HasError() { |
287 int beg_pos = Read(PreparseDataConstants::kMessageStartPos); | 237 return Data()[PreparseDataConstants::kHasErrorOffset]; |
288 int end_pos = Read(PreparseDataConstants::kMessageEndPos); | |
289 return Scanner::Location(beg_pos, end_pos); | |
290 } | 238 } |
291 | 239 |
292 | 240 |
293 bool ScriptData::IsReferenceError() const { | 241 unsigned ParseData::Magic() { |
294 return Read(PreparseDataConstants::kIsReferenceErrorPos); | 242 return Data()[PreparseDataConstants::kMagicOffset]; |
295 } | 243 } |
296 | 244 |
297 | 245 |
298 const char* ScriptData::BuildMessage() const { | 246 unsigned ParseData::Version() { |
299 unsigned* start = ReadAddress(PreparseDataConstants::kMessageTextPos); | 247 return Data()[PreparseDataConstants::kVersionOffset]; |
300 return ReadString(start, NULL); | |
301 } | 248 } |
302 | 249 |
303 | 250 |
304 const char* ScriptData::BuildArg() const { | 251 int ParseData::FunctionsSize() { |
305 int arg_count = Read(PreparseDataConstants::kMessageArgCountPos); | 252 return static_cast<int>(Data()[PreparseDataConstants::kFunctionsSizeOffset]); |
306 ASSERT(arg_count == 0 || arg_count == 1); | |
307 if (arg_count == 0) { | |
308 return NULL; | |
309 } | |
310 // Position after text found by skipping past length field and | |
311 // length field content words. | |
312 int pos = PreparseDataConstants::kMessageTextPos + 1 | |
313 + Read(PreparseDataConstants::kMessageTextPos); | |
314 int count = 0; | |
315 return ReadString(ReadAddress(pos), &count); | |
316 } | 253 } |
317 | 254 |
318 | 255 |
319 unsigned ScriptData::Read(int position) const { | 256 void Parser::SetCachedData() { |
320 return store_[PreparseDataConstants::kHeaderSize + position]; | 257 if (cached_data_mode() == NO_CACHED_DATA) { |
| 258 cached_parse_data_ = NULL; |
| 259 } else { |
| 260 ASSERT(info_->cached_data() != NULL); |
| 261 if (cached_data_mode() == CONSUME_CACHED_DATA) { |
| 262 cached_parse_data_ = new ParseData(*info_->cached_data()); |
| 263 } |
| 264 } |
321 } | 265 } |
322 | 266 |
323 | 267 |
324 unsigned* ScriptData::ReadAddress(int position) const { | |
325 return &store_[PreparseDataConstants::kHeaderSize + position]; | |
326 } | |
327 | |
328 | |
329 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { | 268 Scope* Parser::NewScope(Scope* parent, ScopeType scope_type) { |
330 ASSERT(ast_value_factory_); | 269 ASSERT(ast_value_factory_); |
331 Scope* result = | 270 Scope* result = |
332 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); | 271 new (zone()) Scope(parent, scope_type, ast_value_factory_, zone()); |
333 result->Initialize(); | 272 result->Initialize(); |
334 return result; | 273 return result; |
335 } | 274 } |
336 | 275 |
337 | 276 |
338 // ---------------------------------------------------------------------------- | 277 // ---------------------------------------------------------------------------- |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
750 return parser_->ParseFunctionLiteral(name, function_name_location, | 689 return parser_->ParseFunctionLiteral(name, function_name_location, |
751 name_is_strict_reserved, is_generator, | 690 name_is_strict_reserved, is_generator, |
752 function_token_position, type, | 691 function_token_position, type, |
753 arity_restriction, ok); | 692 arity_restriction, ok); |
754 } | 693 } |
755 | 694 |
756 | 695 |
757 Parser::Parser(CompilationInfo* info) | 696 Parser::Parser(CompilationInfo* info) |
758 : ParserBase<ParserTraits>(&scanner_, | 697 : ParserBase<ParserTraits>(&scanner_, |
759 info->isolate()->stack_guard()->real_climit(), | 698 info->isolate()->stack_guard()->real_climit(), |
760 info->extension(), | 699 info->extension(), NULL, info->zone(), this), |
761 NULL, | |
762 info->zone(), | |
763 this), | |
764 isolate_(info->isolate()), | 700 isolate_(info->isolate()), |
765 script_(info->script()), | 701 script_(info->script()), |
766 scanner_(isolate_->unicode_cache()), | 702 scanner_(isolate_->unicode_cache()), |
767 reusable_preparser_(NULL), | 703 reusable_preparser_(NULL), |
768 original_scope_(NULL), | 704 original_scope_(NULL), |
769 target_stack_(NULL), | 705 target_stack_(NULL), |
770 cached_data_(NULL), | 706 cached_parse_data_(NULL), |
771 cached_data_mode_(NO_CACHED_DATA), | |
772 ast_value_factory_(NULL), | 707 ast_value_factory_(NULL), |
773 info_(info), | 708 info_(info), |
774 has_pending_error_(false), | 709 has_pending_error_(false), |
775 pending_error_message_(NULL), | 710 pending_error_message_(NULL), |
776 pending_error_arg_(NULL), | 711 pending_error_arg_(NULL), |
777 pending_error_char_arg_(NULL) { | 712 pending_error_char_arg_(NULL) { |
778 ASSERT(!script_.is_null()); | 713 ASSERT(!script_.is_null()); |
779 isolate_->set_ast_node_id(0); | 714 isolate_->set_ast_node_id(0); |
780 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); | 715 set_allow_harmony_scoping(!info->is_native() && FLAG_harmony_scoping); |
781 set_allow_modules(!info->is_native() && FLAG_harmony_modules); | 716 set_allow_modules(!info->is_native() && FLAG_harmony_modules); |
(...skipping 16 matching lines...) Expand all Loading... |
798 Handle<String> source(String::cast(script_->source())); | 733 Handle<String> source(String::cast(script_->source())); |
799 isolate()->counters()->total_parse_size()->Increment(source->length()); | 734 isolate()->counters()->total_parse_size()->Increment(source->length()); |
800 base::ElapsedTimer timer; | 735 base::ElapsedTimer timer; |
801 if (FLAG_trace_parse) { | 736 if (FLAG_trace_parse) { |
802 timer.Start(); | 737 timer.Start(); |
803 } | 738 } |
804 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); | 739 fni_ = new(zone()) FuncNameInferrer(ast_value_factory_, zone()); |
805 | 740 |
806 // Initialize parser state. | 741 // Initialize parser state. |
807 CompleteParserRecorder recorder; | 742 CompleteParserRecorder recorder; |
808 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 743 if (cached_data_mode() == PRODUCE_CACHED_DATA) { |
809 log_ = &recorder; | 744 log_ = &recorder; |
810 } else if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 745 } else if (cached_data_mode() == CONSUME_CACHED_DATA) { |
811 (*cached_data_)->Initialize(); | 746 cached_parse_data_->Initialize(); |
812 } | 747 } |
813 | 748 |
814 source = String::Flatten(source); | 749 source = String::Flatten(source); |
815 FunctionLiteral* result; | 750 FunctionLiteral* result; |
816 if (source->IsExternalTwoByteString()) { | 751 if (source->IsExternalTwoByteString()) { |
817 // Notice that the stream is destroyed at the end of the branch block. | 752 // Notice that the stream is destroyed at the end of the branch block. |
818 // The last line of the blocks can't be moved outside, even though they're | 753 // The last line of the blocks can't be moved outside, even though they're |
819 // identical calls. | 754 // identical calls. |
820 ExternalTwoByteStringUtf16CharacterStream stream( | 755 ExternalTwoByteStringUtf16CharacterStream stream( |
821 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); | 756 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); |
(...skipping 11 matching lines...) Expand all Loading... |
833 PrintF("[parsing eval"); | 768 PrintF("[parsing eval"); |
834 } else if (info()->script()->name()->IsString()) { | 769 } else if (info()->script()->name()->IsString()) { |
835 String* name = String::cast(info()->script()->name()); | 770 String* name = String::cast(info()->script()->name()); |
836 SmartArrayPointer<char> name_chars = name->ToCString(); | 771 SmartArrayPointer<char> name_chars = name->ToCString(); |
837 PrintF("[parsing script: %s", name_chars.get()); | 772 PrintF("[parsing script: %s", name_chars.get()); |
838 } else { | 773 } else { |
839 PrintF("[parsing script"); | 774 PrintF("[parsing script"); |
840 } | 775 } |
841 PrintF(" - took %0.3f ms]\n", ms); | 776 PrintF(" - took %0.3f ms]\n", ms); |
842 } | 777 } |
843 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 778 if (cached_data_mode() == PRODUCE_CACHED_DATA) { |
844 if (result != NULL) { | 779 if (result != NULL) *info_->cached_data() = recorder.GetScriptData(); |
845 Vector<unsigned> store = recorder.ExtractData(); | |
846 *cached_data_ = new ScriptData(store); | |
847 } | |
848 log_ = NULL; | 780 log_ = NULL; |
849 } | 781 } |
850 return result; | 782 return result; |
851 } | 783 } |
852 | 784 |
853 | 785 |
854 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, | 786 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, |
855 Handle<String> source) { | 787 Handle<String> source) { |
856 ASSERT(scope_ == NULL); | 788 ASSERT(scope_ == NULL); |
857 ASSERT(target_stack_ == NULL); | 789 ASSERT(target_stack_ == NULL); |
(...skipping 2428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3286 // DebuggerStatement :: | 3218 // DebuggerStatement :: |
3287 // 'debugger' ';' | 3219 // 'debugger' ';' |
3288 | 3220 |
3289 int pos = peek_position(); | 3221 int pos = peek_position(); |
3290 Expect(Token::DEBUGGER, CHECK_OK); | 3222 Expect(Token::DEBUGGER, CHECK_OK); |
3291 ExpectSemicolon(CHECK_OK); | 3223 ExpectSemicolon(CHECK_OK); |
3292 return factory()->NewDebuggerStatement(pos); | 3224 return factory()->NewDebuggerStatement(pos); |
3293 } | 3225 } |
3294 | 3226 |
3295 | 3227 |
3296 void Parser::ReportInvalidCachedData(const AstRawString* name, bool* ok) { | |
3297 ParserTraits::ReportMessage("invalid_cached_data_function", name); | |
3298 *ok = false; | |
3299 } | |
3300 | |
3301 | |
3302 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { | 3228 bool CompileTimeValue::IsCompileTimeValue(Expression* expression) { |
3303 if (expression->IsLiteral()) return true; | 3229 if (expression->IsLiteral()) return true; |
3304 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); | 3230 MaterializedLiteral* lit = expression->AsMaterializedLiteral(); |
3305 return lit != NULL && lit->is_simple(); | 3231 return lit != NULL && lit->is_simple(); |
3306 } | 3232 } |
3307 | 3233 |
3308 | 3234 |
3309 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, | 3235 Handle<FixedArray> CompileTimeValue::GetValue(Isolate* isolate, |
3310 Expression* expression) { | 3236 Expression* expression) { |
3311 Factory* factory = isolate->factory(); | 3237 Factory* factory = isolate->factory(); |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3608 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); | 3534 if (fni_ != NULL && should_infer_name) fni_->AddFunction(function_literal); |
3609 return function_literal; | 3535 return function_literal; |
3610 } | 3536 } |
3611 | 3537 |
3612 | 3538 |
3613 void Parser::SkipLazyFunctionBody(const AstRawString* function_name, | 3539 void Parser::SkipLazyFunctionBody(const AstRawString* function_name, |
3614 int* materialized_literal_count, | 3540 int* materialized_literal_count, |
3615 int* expected_property_count, | 3541 int* expected_property_count, |
3616 bool* ok) { | 3542 bool* ok) { |
3617 int function_block_pos = position(); | 3543 int function_block_pos = position(); |
3618 if (cached_data_mode_ == CONSUME_CACHED_DATA) { | 3544 if (cached_data_mode() == CONSUME_CACHED_DATA) { |
3619 // If we have cached data, we use it to skip parsing the function body. The | 3545 // If we have cached data, we use it to skip parsing the function body. The |
3620 // data contains the information we need to construct the lazy function. | 3546 // data contains the information we need to construct the lazy function. |
3621 FunctionEntry entry = | 3547 FunctionEntry entry = |
3622 (*cached_data())->GetFunctionEntry(function_block_pos); | 3548 cached_parse_data_->GetFunctionEntry(function_block_pos); |
3623 if (entry.is_valid()) { | 3549 // Check that cached data is valid. |
3624 if (entry.end_pos() <= function_block_pos) { | 3550 CHECK(entry.is_valid()); |
3625 // End position greater than end of stream is safe, and hard to check. | 3551 // End position greater than end of stream is safe, and hard to check. |
3626 ReportInvalidCachedData(function_name, ok); | 3552 CHECK(entry.end_pos() > function_block_pos); |
3627 if (!*ok) { | 3553 scanner()->SeekForward(entry.end_pos() - 1); |
3628 return; | |
3629 } | |
3630 } | |
3631 scanner()->SeekForward(entry.end_pos() - 1); | |
3632 | 3554 |
3633 scope_->set_end_position(entry.end_pos()); | 3555 scope_->set_end_position(entry.end_pos()); |
3634 Expect(Token::RBRACE, ok); | 3556 Expect(Token::RBRACE, ok); |
3635 if (!*ok) { | 3557 if (!*ok) { |
3636 return; | |
3637 } | |
3638 isolate()->counters()->total_preparse_skipped()->Increment( | |
3639 scope_->end_position() - function_block_pos); | |
3640 *materialized_literal_count = entry.literal_count(); | |
3641 *expected_property_count = entry.property_count(); | |
3642 scope_->SetStrictMode(entry.strict_mode()); | |
3643 } else { | |
3644 // This case happens when we have preparse data but it doesn't contain an | |
3645 // entry for the function. Fail the compilation. | |
3646 ReportInvalidCachedData(function_name, ok); | |
3647 return; | 3558 return; |
3648 } | 3559 } |
| 3560 isolate()->counters()->total_preparse_skipped()->Increment( |
| 3561 scope_->end_position() - function_block_pos); |
| 3562 *materialized_literal_count = entry.literal_count(); |
| 3563 *expected_property_count = entry.property_count(); |
| 3564 scope_->SetStrictMode(entry.strict_mode()); |
3649 } else { | 3565 } else { |
3650 // With no cached data, we partially parse the function, without building an | 3566 // With no cached data, we partially parse the function, without building an |
3651 // AST. This gathers the data needed to build a lazy function. | 3567 // AST. This gathers the data needed to build a lazy function. |
3652 SingletonLogger logger; | 3568 SingletonLogger logger; |
3653 PreParser::PreParseResult result = | 3569 PreParser::PreParseResult result = |
3654 ParseLazyFunctionBodyWithPreParser(&logger); | 3570 ParseLazyFunctionBodyWithPreParser(&logger); |
3655 if (result == PreParser::kPreParseStackOverflow) { | 3571 if (result == PreParser::kPreParseStackOverflow) { |
3656 // Propagate stack overflow. | 3572 // Propagate stack overflow. |
3657 set_stack_overflow(); | 3573 set_stack_overflow(); |
3658 *ok = false; | 3574 *ok = false; |
3659 return; | 3575 return; |
3660 } | 3576 } |
3661 if (logger.has_error()) { | 3577 if (logger.has_error()) { |
3662 ParserTraits::ReportMessageAt( | 3578 ParserTraits::ReportMessageAt( |
3663 Scanner::Location(logger.start(), logger.end()), | 3579 Scanner::Location(logger.start(), logger.end()), |
3664 logger.message(), logger.argument_opt(), logger.is_reference_error()); | 3580 logger.message(), logger.argument_opt(), logger.is_reference_error()); |
3665 *ok = false; | 3581 *ok = false; |
3666 return; | 3582 return; |
3667 } | 3583 } |
3668 scope_->set_end_position(logger.end()); | 3584 scope_->set_end_position(logger.end()); |
3669 Expect(Token::RBRACE, ok); | 3585 Expect(Token::RBRACE, ok); |
3670 if (!*ok) { | 3586 if (!*ok) { |
3671 return; | 3587 return; |
3672 } | 3588 } |
3673 isolate()->counters()->total_preparse_skipped()->Increment( | 3589 isolate()->counters()->total_preparse_skipped()->Increment( |
3674 scope_->end_position() - function_block_pos); | 3590 scope_->end_position() - function_block_pos); |
3675 *materialized_literal_count = logger.literals(); | 3591 *materialized_literal_count = logger.literals(); |
3676 *expected_property_count = logger.properties(); | 3592 *expected_property_count = logger.properties(); |
3677 scope_->SetStrictMode(logger.strict_mode()); | 3593 scope_->SetStrictMode(logger.strict_mode()); |
3678 if (cached_data_mode_ == PRODUCE_CACHED_DATA) { | 3594 if (cached_data_mode() == PRODUCE_CACHED_DATA) { |
3679 ASSERT(log_); | 3595 ASSERT(log_); |
3680 // Position right after terminal '}'. | 3596 // Position right after terminal '}'. |
3681 int body_end = scanner()->location().end_pos; | 3597 int body_end = scanner()->location().end_pos; |
3682 log_->LogFunction(function_block_pos, body_end, | 3598 log_->LogFunction(function_block_pos, body_end, |
3683 *materialized_literal_count, | 3599 *materialized_literal_count, |
3684 *expected_property_count, | 3600 *expected_property_count, |
3685 scope_->strict_mode()); | 3601 scope_->strict_mode()); |
3686 } | 3602 } |
3687 } | 3603 } |
3688 } | 3604 } |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4760 ranges->Add(CharacterRange::Everything(), zone()); | 4676 ranges->Add(CharacterRange::Everything(), zone()); |
4761 is_negated = !is_negated; | 4677 is_negated = !is_negated; |
4762 } | 4678 } |
4763 return new(zone()) RegExpCharacterClass(ranges, is_negated); | 4679 return new(zone()) RegExpCharacterClass(ranges, is_negated); |
4764 } | 4680 } |
4765 | 4681 |
4766 | 4682 |
4767 // ---------------------------------------------------------------------------- | 4683 // ---------------------------------------------------------------------------- |
4768 // The Parser interface. | 4684 // The Parser interface. |
4769 | 4685 |
4770 ScriptData::~ScriptData() { | |
4771 if (owns_store_) store_.Dispose(); | |
4772 } | |
4773 | |
4774 | |
4775 int ScriptData::Length() { | |
4776 return store_.length() * sizeof(unsigned); | |
4777 } | |
4778 | |
4779 | |
4780 const char* ScriptData::Data() { | |
4781 return reinterpret_cast<const char*>(store_.start()); | |
4782 } | |
4783 | |
4784 | |
4785 bool ScriptData::HasError() { | |
4786 return has_error(); | |
4787 } | |
4788 | |
4789 | |
4790 void ScriptData::Initialize() { | |
4791 // Prepares state for use. | |
4792 if (store_.length() >= PreparseDataConstants::kHeaderSize) { | |
4793 function_index_ = PreparseDataConstants::kHeaderSize; | |
4794 int symbol_data_offset = PreparseDataConstants::kHeaderSize | |
4795 + store_[PreparseDataConstants::kFunctionsSizeOffset]; | |
4796 if (store_.length() > symbol_data_offset) { | |
4797 symbol_data_ = reinterpret_cast<byte*>(&store_[symbol_data_offset]); | |
4798 } else { | |
4799 // Partial preparse causes no symbol information. | |
4800 symbol_data_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); | |
4801 } | |
4802 symbol_data_end_ = reinterpret_cast<byte*>(&store_[0] + store_.length()); | |
4803 } | |
4804 } | |
4805 | |
4806 | |
4807 int ScriptData::ReadNumber(byte** source) { | |
4808 // Reads a number from symbol_data_ in base 128. The most significant | |
4809 // bit marks that there are more digits. | |
4810 // If the first byte is 0x80 (kNumberTerminator), it would normally | |
4811 // represent a leading zero. Since that is useless, and therefore won't | |
4812 // appear as the first digit of any actual value, it is used to | |
4813 // mark the end of the input stream. | |
4814 byte* data = *source; | |
4815 if (data >= symbol_data_end_) return -1; | |
4816 byte input = *data; | |
4817 if (input == PreparseDataConstants::kNumberTerminator) { | |
4818 // End of stream marker. | |
4819 return -1; | |
4820 } | |
4821 int result = input & 0x7f; | |
4822 data++; | |
4823 while ((input & 0x80u) != 0) { | |
4824 if (data >= symbol_data_end_) return -1; | |
4825 input = *data; | |
4826 result = (result << 7) | (input & 0x7f); | |
4827 data++; | |
4828 } | |
4829 *source = data; | |
4830 return result; | |
4831 } | |
4832 | |
4833 | |
4834 bool RegExpParser::ParseRegExp(FlatStringReader* input, | 4686 bool RegExpParser::ParseRegExp(FlatStringReader* input, |
4835 bool multiline, | 4687 bool multiline, |
4836 RegExpCompileData* result, | 4688 RegExpCompileData* result, |
4837 Zone* zone) { | 4689 Zone* zone) { |
4838 ASSERT(result != NULL); | 4690 ASSERT(result != NULL); |
4839 RegExpParser parser(input, &result->error, multiline, zone); | 4691 RegExpParser parser(input, &result->error, multiline, zone); |
4840 RegExpTree* tree = parser.ParsePattern(); | 4692 RegExpTree* tree = parser.ParsePattern(); |
4841 if (parser.failed()) { | 4693 if (parser.failed()) { |
4842 ASSERT(tree == NULL); | 4694 ASSERT(tree == NULL); |
4843 ASSERT(!result->error.is_null()); | 4695 ASSERT(!result->error.is_null()); |
(...skipping 26 matching lines...) Expand all Loading... |
4870 } | 4722 } |
4871 | 4723 |
4872 if (info()->is_lazy()) { | 4724 if (info()->is_lazy()) { |
4873 ASSERT(!info()->is_eval()); | 4725 ASSERT(!info()->is_eval()); |
4874 if (info()->shared_info()->is_function()) { | 4726 if (info()->shared_info()->is_function()) { |
4875 result = ParseLazy(); | 4727 result = ParseLazy(); |
4876 } else { | 4728 } else { |
4877 result = ParseProgram(); | 4729 result = ParseProgram(); |
4878 } | 4730 } |
4879 } else { | 4731 } else { |
4880 SetCachedData(info()->cached_data(), info()->cached_data_mode()); | 4732 SetCachedData(); |
4881 result = ParseProgram(); | 4733 result = ParseProgram(); |
4882 } | 4734 } |
4883 info()->SetFunction(result); | 4735 info()->SetFunction(result); |
4884 ASSERT(ast_value_factory_->IsInternalized()); | 4736 ASSERT(ast_value_factory_->IsInternalized()); |
4885 // info takes ownership of ast_value_factory_. | 4737 // info takes ownership of ast_value_factory_. |
4886 if (info()->ast_value_factory() == NULL) { | 4738 if (info()->ast_value_factory() == NULL) { |
4887 info()->SetAstValueFactory(ast_value_factory_); | 4739 info()->SetAstValueFactory(ast_value_factory_); |
4888 } | 4740 } |
4889 ast_value_factory_ = NULL; | 4741 ast_value_factory_ = NULL; |
4890 | 4742 |
4891 InternalizeUseCounts(); | 4743 InternalizeUseCounts(); |
4892 | 4744 |
4893 return (result != NULL); | 4745 return (result != NULL); |
4894 } | 4746 } |
4895 | 4747 |
4896 } } // namespace v8::internal | 4748 } } // namespace v8::internal |
OLD | NEW |