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

Side by Side Diff: src/parser.cc

Issue 9600009: Fix input and output to handle UTF16 surrogate pairs. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years, 9 months 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 | Annotate | Revision Log
OLDNEW
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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 // If we are larger than that, or negative, it's not a cached symbol. 251 // If we are larger than that, or negative, it's not a cached symbol.
252 // This might also happen if there is no preparser symbol data, even 252 // This might also happen if there is no preparser symbol data, even
253 // if there is some preparser data. 253 // if there is some preparser data.
254 if (static_cast<unsigned>(symbol_id) 254 if (static_cast<unsigned>(symbol_id)
255 >= static_cast<unsigned>(symbol_cache_.length())) { 255 >= static_cast<unsigned>(symbol_cache_.length())) {
256 if (scanner().is_literal_ascii()) { 256 if (scanner().is_literal_ascii()) {
257 return isolate()->factory()->LookupAsciiSymbol( 257 return isolate()->factory()->LookupAsciiSymbol(
258 scanner().literal_ascii_string()); 258 scanner().literal_ascii_string());
259 } else { 259 } else {
260 return isolate()->factory()->LookupTwoByteSymbol( 260 return isolate()->factory()->LookupTwoByteSymbol(
261 scanner().literal_uc16_string()); 261 scanner().literal_utf16_string());
262 } 262 }
263 } 263 }
264 return LookupCachedSymbol(symbol_id); 264 return LookupCachedSymbol(symbol_id);
265 } 265 }
266 266
267 267
268 Handle<String> Parser::LookupCachedSymbol(int symbol_id) { 268 Handle<String> Parser::LookupCachedSymbol(int symbol_id) {
269 // Make sure the cache is large enough to hold the symbol identifier. 269 // Make sure the cache is large enough to hold the symbol identifier.
270 if (symbol_cache_.length() <= symbol_id) { 270 if (symbol_cache_.length() <= symbol_id) {
271 // Increase length to index + 1. 271 // Increase length to index + 1.
272 symbol_cache_.AddBlock(Handle<String>::null(), 272 symbol_cache_.AddBlock(Handle<String>::null(),
273 symbol_id + 1 - symbol_cache_.length()); 273 symbol_id + 1 - symbol_cache_.length());
274 } 274 }
275 Handle<String> result = symbol_cache_.at(symbol_id); 275 Handle<String> result = symbol_cache_.at(symbol_id);
276 if (result.is_null()) { 276 if (result.is_null()) {
277 if (scanner().is_literal_ascii()) { 277 if (scanner().is_literal_ascii()) {
278 result = isolate()->factory()->LookupAsciiSymbol( 278 result = isolate()->factory()->LookupAsciiSymbol(
279 scanner().literal_ascii_string()); 279 scanner().literal_ascii_string());
280 } else { 280 } else {
281 result = isolate()->factory()->LookupTwoByteSymbol( 281 result = isolate()->factory()->LookupTwoByteSymbol(
282 scanner().literal_uc16_string()); 282 scanner().literal_utf16_string());
283 } 283 }
284 symbol_cache_.at(symbol_id) = result; 284 symbol_cache_.at(symbol_id) = result;
285 return result; 285 return result;
286 } 286 }
287 isolate()->counters()->total_preparse_symbols_skipped()->Increment(); 287 isolate()->counters()->total_preparse_symbols_skipped()->Increment();
288 return result; 288 return result;
289 } 289 }
290 290
291 291
292 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) { 292 FunctionEntry ScriptDataImpl::GetFunctionEntry(int start) {
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 Handle<String> source(String::cast(script_->source())); 569 Handle<String> source(String::cast(script_->source()));
570 isolate()->counters()->total_parse_size()->Increment(source->length()); 570 isolate()->counters()->total_parse_size()->Increment(source->length());
571 fni_ = new(zone()) FuncNameInferrer(isolate()); 571 fni_ = new(zone()) FuncNameInferrer(isolate());
572 572
573 // Initialize parser state. 573 // Initialize parser state.
574 source->TryFlatten(); 574 source->TryFlatten();
575 if (source->IsExternalTwoByteString()) { 575 if (source->IsExternalTwoByteString()) {
576 // Notice that the stream is destroyed at the end of the branch block. 576 // Notice that the stream is destroyed at the end of the branch block.
577 // The last line of the blocks can't be moved outside, even though they're 577 // The last line of the blocks can't be moved outside, even though they're
578 // identical calls. 578 // identical calls.
579 ExternalTwoByteStringUC16CharacterStream stream( 579 ExternalTwoByteStringUtf16CharacterStream stream(
580 Handle<ExternalTwoByteString>::cast(source), 0, source->length()); 580 Handle<ExternalTwoByteString>::cast(source), 0, source->length());
581 scanner_.Initialize(&stream); 581 scanner_.Initialize(&stream);
582 return DoParseProgram(info, source, &zone_scope); 582 return DoParseProgram(info, source, &zone_scope);
583 } else { 583 } else {
584 GenericStringUC16CharacterStream stream(source, 0, source->length()); 584 GenericStringUtf16CharacterStream stream(source, 0, source->length());
585 scanner_.Initialize(&stream); 585 scanner_.Initialize(&stream);
586 return DoParseProgram(info, source, &zone_scope); 586 return DoParseProgram(info, source, &zone_scope);
587 } 587 }
588 } 588 }
589 589
590 590
591 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info, 591 FunctionLiteral* Parser::DoParseProgram(CompilationInfo* info,
592 Handle<String> source, 592 Handle<String> source,
593 ZoneScope* zone_scope) { 593 ZoneScope* zone_scope) {
594 ASSERT(top_scope_ == NULL); 594 ASSERT(top_scope_ == NULL);
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) { 658 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info) {
659 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT); 659 ZoneScope zone_scope(isolate(), DONT_DELETE_ON_EXIT);
660 HistogramTimerScope timer(isolate()->counters()->parse_lazy()); 660 HistogramTimerScope timer(isolate()->counters()->parse_lazy());
661 Handle<String> source(String::cast(script_->source())); 661 Handle<String> source(String::cast(script_->source()));
662 isolate()->counters()->total_parse_size()->Increment(source->length()); 662 isolate()->counters()->total_parse_size()->Increment(source->length());
663 663
664 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 664 Handle<SharedFunctionInfo> shared_info = info->shared_info();
665 // Initialize parser state. 665 // Initialize parser state.
666 source->TryFlatten(); 666 source->TryFlatten();
667 if (source->IsExternalTwoByteString()) { 667 if (source->IsExternalTwoByteString()) {
668 ExternalTwoByteStringUC16CharacterStream stream( 668 ExternalTwoByteStringUtf16CharacterStream stream(
669 Handle<ExternalTwoByteString>::cast(source), 669 Handle<ExternalTwoByteString>::cast(source),
670 shared_info->start_position(), 670 shared_info->start_position(),
671 shared_info->end_position()); 671 shared_info->end_position());
672 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 672 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
673 return result; 673 return result;
674 } else { 674 } else {
675 GenericStringUC16CharacterStream stream(source, 675 GenericStringUtf16CharacterStream stream(source,
676 shared_info->start_position(), 676 shared_info->start_position(),
677 shared_info->end_position()); 677 shared_info->end_position());
678 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope); 678 FunctionLiteral* result = ParseLazy(info, &stream, &zone_scope);
679 return result; 679 return result;
680 } 680 }
681 } 681 }
682 682
683 683
684 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info, 684 FunctionLiteral* Parser::ParseLazy(CompilationInfo* info,
685 UC16CharacterStream* source, 685 Utf16CharacterStream* source,
686 ZoneScope* zone_scope) { 686 ZoneScope* zone_scope) {
687 Handle<SharedFunctionInfo> shared_info = info->shared_info(); 687 Handle<SharedFunctionInfo> shared_info = info->shared_info();
688 scanner_.Initialize(source); 688 scanner_.Initialize(source);
689 ASSERT(top_scope_ == NULL); 689 ASSERT(top_scope_ == NULL);
690 ASSERT(target_stack_ == NULL); 690 ASSERT(target_stack_ == NULL);
691 691
692 Handle<String> name(String::cast(shared_info->name())); 692 Handle<String> name(String::cast(shared_info->name()));
693 fni_ = new(zone()) FuncNameInferrer(isolate()); 693 fni_ = new(zone()) FuncNameInferrer(isolate());
694 fni_->PushEnclosingName(name); 694 fni_->PushEnclosingName(name);
695 695
(...skipping 3508 matching lines...) Expand 10 before | Expand all | Expand 10 after
4204 ASSERT(!has_error_); 4204 ASSERT(!has_error_);
4205 start_ = start; 4205 start_ = start;
4206 end_ = end; 4206 end_ = end;
4207 literals_ = literals; 4207 literals_ = literals;
4208 properties_ = properties; 4208 properties_ = properties;
4209 mode_ = mode; 4209 mode_ = mode;
4210 }; 4210 };
4211 4211
4212 // Logs a symbol creation of a literal or identifier. 4212 // Logs a symbol creation of a literal or identifier.
4213 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { } 4213 virtual void LogAsciiSymbol(int start, Vector<const char> literal) { }
4214 virtual void LogUC16Symbol(int start, Vector<const uc16> literal) { } 4214 virtual void LogUtf16Symbol(int start, Vector<const uc16> literal) { }
4215 4215
4216 // Logs an error message and marks the log as containing an error. 4216 // Logs an error message and marks the log as containing an error.
4217 // Further logging will be ignored, and ExtractData will return a vector 4217 // Further logging will be ignored, and ExtractData will return a vector
4218 // representing the error only. 4218 // representing the error only.
4219 virtual void LogMessage(int start, 4219 virtual void LogMessage(int start,
4220 int end, 4220 int end,
4221 const char* message, 4221 const char* message,
4222 const char* argument_opt) { 4222 const char* argument_opt) {
4223 has_error_ = true; 4223 has_error_ = true;
4224 start_ = start; 4224 start_ = start;
(...skipping 1568 matching lines...) Expand 10 before | Expand all | Expand 10 after
5793 input = *data; 5793 input = *data;
5794 result = (result << 7) | (input & 0x7f); 5794 result = (result << 7) | (input & 0x7f);
5795 data++; 5795 data++;
5796 } 5796 }
5797 *source = data; 5797 *source = data;
5798 return result; 5798 return result;
5799 } 5799 }
5800 5800
5801 5801
5802 // Create a Scanner for the preparser to use as input, and preparse the source. 5802 // Create a Scanner for the preparser to use as input, and preparse the source.
5803 static ScriptDataImpl* DoPreParse(UC16CharacterStream* source, 5803 static ScriptDataImpl* DoPreParse(Utf16CharacterStream* source,
5804 int flags, 5804 int flags,
5805 ParserRecorder* recorder) { 5805 ParserRecorder* recorder) {
5806 Isolate* isolate = Isolate::Current(); 5806 Isolate* isolate = Isolate::Current();
5807 HistogramTimerScope timer(isolate->counters()->pre_parse()); 5807 HistogramTimerScope timer(isolate->counters()->pre_parse());
5808 Scanner scanner(isolate->unicode_cache()); 5808 Scanner scanner(isolate->unicode_cache());
5809 scanner.SetHarmonyScoping(FLAG_harmony_scoping); 5809 scanner.SetHarmonyScoping(FLAG_harmony_scoping);
5810 scanner.Initialize(source); 5810 scanner.Initialize(source);
5811 intptr_t stack_limit = isolate->stack_guard()->real_climit(); 5811 intptr_t stack_limit = isolate->stack_guard()->real_climit();
5812 preparser::PreParser::PreParseResult result = 5812 preparser::PreParser::PreParseResult result =
5813 preparser::PreParser::PreParseProgram(&scanner, 5813 preparser::PreParser::PreParseProgram(&scanner,
(...skipping 20 matching lines...) Expand all
5834 bool allow_lazy = FLAG_lazy && (extension == NULL); 5834 bool allow_lazy = FLAG_lazy && (extension == NULL);
5835 if (!allow_lazy) { 5835 if (!allow_lazy) {
5836 // Partial preparsing is only about lazily compiled functions. 5836 // Partial preparsing is only about lazily compiled functions.
5837 // If we don't allow lazy compilation, the log data will be empty. 5837 // If we don't allow lazy compilation, the log data will be empty.
5838 return NULL; 5838 return NULL;
5839 } 5839 }
5840 flags |= kAllowLazy; 5840 flags |= kAllowLazy;
5841 PartialParserRecorder recorder; 5841 PartialParserRecorder recorder;
5842 int source_length = source->length(); 5842 int source_length = source->length();
5843 if (source->IsExternalTwoByteString()) { 5843 if (source->IsExternalTwoByteString()) {
5844 ExternalTwoByteStringUC16CharacterStream stream( 5844 ExternalTwoByteStringUtf16CharacterStream stream(
5845 Handle<ExternalTwoByteString>::cast(source), 0, source_length); 5845 Handle<ExternalTwoByteString>::cast(source), 0, source_length);
5846 return DoPreParse(&stream, flags, &recorder); 5846 return DoPreParse(&stream, flags, &recorder);
5847 } else { 5847 } else {
5848 GenericStringUC16CharacterStream stream(source, 0, source_length); 5848 GenericStringUtf16CharacterStream stream(source, 0, source_length);
5849 return DoPreParse(&stream, flags, &recorder); 5849 return DoPreParse(&stream, flags, &recorder);
5850 } 5850 }
5851 } 5851 }
5852 5852
5853 5853
5854 ScriptDataImpl* ParserApi::PreParse(UC16CharacterStream* source, 5854 ScriptDataImpl* ParserApi::PreParse(Utf16CharacterStream* source,
5855 v8::Extension* extension, 5855 v8::Extension* extension,
5856 int flags) { 5856 int flags) {
5857 Handle<Script> no_script; 5857 Handle<Script> no_script;
5858 if (FLAG_lazy && (extension == NULL)) { 5858 if (FLAG_lazy && (extension == NULL)) {
5859 flags |= kAllowLazy; 5859 flags |= kAllowLazy;
5860 } 5860 }
5861 CompleteParserRecorder recorder; 5861 CompleteParserRecorder recorder;
5862 return DoPreParse(source, flags, &recorder); 5862 return DoPreParse(source, flags, &recorder);
5863 } 5863 }
5864 5864
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
5925 ASSERT(info->isolate()->has_pending_exception()); 5925 ASSERT(info->isolate()->has_pending_exception());
5926 } else { 5926 } else {
5927 result = parser.ParseProgram(info); 5927 result = parser.ParseProgram(info);
5928 } 5928 }
5929 } 5929 }
5930 info->SetFunction(result); 5930 info->SetFunction(result);
5931 return (result != NULL); 5931 return (result != NULL);
5932 } 5932 }
5933 5933
5934 } } // namespace v8::internal 5934 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698