OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
51 | 51 |
52 private: | 52 private: |
53 // Parse a string containing a single JSON value. | 53 // Parse a string containing a single JSON value. |
54 Handle<Object> ParseJson(Handle<String> source, Zone* zone); | 54 Handle<Object> ParseJson(Handle<String> source, Zone* zone); |
55 | 55 |
56 inline void Advance() { | 56 inline void Advance() { |
57 position_++; | 57 position_++; |
58 if (position_ >= source_length_) { | 58 if (position_ >= source_length_) { |
59 c0_ = kEndOfString; | 59 c0_ = kEndOfString; |
60 } else if (seq_ascii) { | 60 } else if (seq_ascii) { |
61 c0_ = seq_source_->SeqAsciiStringGet(position_); | 61 c0_ = seq_source_->SeqOneByteStringGet(position_); |
62 } else { | 62 } else { |
63 c0_ = source_->Get(position_); | 63 c0_ = source_->Get(position_); |
64 } | 64 } |
65 } | 65 } |
66 | 66 |
67 // The JSON lexical grammar is specified in the ECMAScript 5 standard, | 67 // The JSON lexical grammar is specified in the ECMAScript 5 standard, |
68 // section 15.12.1.1. The only allowed whitespace characters between tokens | 68 // section 15.12.1.1. The only allowed whitespace characters between tokens |
69 // are tab, carriage-return, newline and space. | 69 // are tab, carriage-return, newline and space. |
70 | 70 |
71 inline void AdvanceSkipWhitespace() { | 71 inline void AdvanceSkipWhitespace() { |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 inline Handle<JSFunction> object_constructor() { return object_constructor_; } | 153 inline Handle<JSFunction> object_constructor() { return object_constructor_; } |
154 inline Zone* zone() const { return zone_; } | 154 inline Zone* zone() const { return zone_; } |
155 | 155 |
156 static const int kInitialSpecialStringLength = 1024; | 156 static const int kInitialSpecialStringLength = 1024; |
157 static const int kPretenureTreshold = 100 * 1024; | 157 static const int kPretenureTreshold = 100 * 1024; |
158 | 158 |
159 | 159 |
160 private: | 160 private: |
161 Handle<String> source_; | 161 Handle<String> source_; |
162 int source_length_; | 162 int source_length_; |
163 Handle<SeqAsciiString> seq_source_; | 163 Handle<SeqOneByteString> seq_source_; |
164 | 164 |
165 PretenureFlag pretenure_; | 165 PretenureFlag pretenure_; |
166 Isolate* isolate_; | 166 Isolate* isolate_; |
167 Factory* factory_; | 167 Factory* factory_; |
168 Handle<JSFunction> object_constructor_; | 168 Handle<JSFunction> object_constructor_; |
169 uc32 c0_; | 169 uc32 c0_; |
170 int position_; | 170 int position_; |
171 Zone* zone_; | 171 Zone* zone_; |
172 }; | 172 }; |
173 | 173 |
174 template <bool seq_ascii> | 174 template <bool seq_ascii> |
175 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, | 175 Handle<Object> JsonParser<seq_ascii>::ParseJson(Handle<String> source, |
176 Zone* zone) { | 176 Zone* zone) { |
177 isolate_ = source->map()->GetHeap()->isolate(); | 177 isolate_ = source->map()->GetHeap()->isolate(); |
178 factory_ = isolate_->factory(); | 178 factory_ = isolate_->factory(); |
179 object_constructor_ = Handle<JSFunction>( | 179 object_constructor_ = Handle<JSFunction>( |
180 isolate()->native_context()->object_function(), isolate()); | 180 isolate()->native_context()->object_function(), isolate()); |
181 zone_ = zone; | 181 zone_ = zone; |
182 FlattenString(source); | 182 FlattenString(source); |
183 source_ = source; | 183 source_ = source; |
184 source_length_ = source_->length(); | 184 source_length_ = source_->length(); |
185 pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED; | 185 pretenure_ = (source_length_ >= kPretenureTreshold) ? TENURED : NOT_TENURED; |
186 | 186 |
187 // Optimized fast case where we only have ASCII characters. | 187 // Optimized fast case where we only have ASCII characters. |
188 if (seq_ascii) { | 188 if (seq_ascii) { |
189 seq_source_ = Handle<SeqAsciiString>::cast(source_); | 189 seq_source_ = Handle<SeqOneByteString>::cast(source_); |
190 } | 190 } |
191 | 191 |
192 // Set initial position right before the string. | 192 // Set initial position right before the string. |
193 position_ = -1; | 193 position_ = -1; |
194 // Advance to the first character (possibly EOS) | 194 // Advance to the first character (possibly EOS) |
195 AdvanceSkipWhitespace(); | 195 AdvanceSkipWhitespace(); |
196 Handle<Object> result = ParseJsonValue(); | 196 Handle<Object> result = ParseJsonValue(); |
197 if (result.is_null() || c0_ != kEndOfString) { | 197 if (result.is_null() || c0_ != kEndOfString) { |
198 // Some exception (for example stack overflow) is already pending. | 198 // Some exception (for example stack overflow) is already pending. |
199 if (isolate_->has_pending_exception()) return Handle<Object>::null(); | 199 if (isolate_->has_pending_exception()) return Handle<Object>::null(); |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
465 | 465 |
466 template <typename StringType> | 466 template <typename StringType> |
467 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); | 467 inline void SeqStringSet(Handle<StringType> seq_str, int i, uc32 c); |
468 | 468 |
469 template <> | 469 template <> |
470 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { | 470 inline void SeqStringSet(Handle<SeqTwoByteString> seq_str, int i, uc32 c) { |
471 seq_str->SeqTwoByteStringSet(i, c); | 471 seq_str->SeqTwoByteStringSet(i, c); |
472 } | 472 } |
473 | 473 |
474 template <> | 474 template <> |
475 inline void SeqStringSet(Handle<SeqAsciiString> seq_str, int i, uc32 c) { | 475 inline void SeqStringSet(Handle<SeqOneByteString> seq_str, int i, uc32 c) { |
476 seq_str->SeqAsciiStringSet(i, c); | 476 seq_str->SeqOneByteStringSet(i, c); |
477 } | 477 } |
478 | 478 |
479 template <typename StringType> | 479 template <typename StringType> |
480 inline Handle<StringType> NewRawString(Factory* factory, | 480 inline Handle<StringType> NewRawString(Factory* factory, |
481 int length, | 481 int length, |
482 PretenureFlag pretenure); | 482 PretenureFlag pretenure); |
483 | 483 |
484 template <> | 484 template <> |
485 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, | 485 inline Handle<SeqTwoByteString> NewRawString(Factory* factory, |
486 int length, | 486 int length, |
487 PretenureFlag pretenure) { | 487 PretenureFlag pretenure) { |
488 return factory->NewRawTwoByteString(length, pretenure); | 488 return factory->NewRawTwoByteString(length, pretenure); |
489 } | 489 } |
490 | 490 |
491 template <> | 491 template <> |
492 inline Handle<SeqAsciiString> NewRawString(Factory* factory, | 492 inline Handle<SeqOneByteString> NewRawString(Factory* factory, |
493 int length, | 493 int length, |
494 PretenureFlag pretenure) { | 494 PretenureFlag pretenure) { |
495 return factory->NewRawAsciiString(length, pretenure); | 495 return factory->NewRawOneByteString(length, pretenure); |
496 } | 496 } |
497 | 497 |
498 | 498 |
499 // Scans the rest of a JSON string starting from position_ and writes | 499 // Scans the rest of a JSON string starting from position_ and writes |
500 // prefix[start..end] along with the scanned characters into a | 500 // prefix[start..end] along with the scanned characters into a |
501 // sequential string of type StringType. | 501 // sequential string of type StringType. |
502 template <bool seq_ascii> | 502 template <bool seq_ascii> |
503 template <typename StringType, typename SinkChar> | 503 template <typename StringType, typename SinkChar> |
504 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( | 504 Handle<String> JsonParser<seq_ascii>::SlowScanJsonString( |
505 Handle<String> prefix, int start, int end) { | 505 Handle<String> prefix, int start, int end) { |
(...skipping 17 matching lines...) Expand all Loading... |
523 // If the sink can contain UC16 characters, or source_ contains only | 523 // If the sink can contain UC16 characters, or source_ contains only |
524 // ASCII characters, there's no need to test whether we can store the | 524 // ASCII characters, there's no need to test whether we can store the |
525 // character. Otherwise check whether the UC16 source character can fit | 525 // character. Otherwise check whether the UC16 source character can fit |
526 // in the ASCII sink. | 526 // in the ASCII sink. |
527 if (sizeof(SinkChar) == kUC16Size || | 527 if (sizeof(SinkChar) == kUC16Size || |
528 seq_ascii || | 528 seq_ascii || |
529 c0_ <= kMaxAsciiCharCode) { | 529 c0_ <= kMaxAsciiCharCode) { |
530 SeqStringSet(seq_str, count++, c0_); | 530 SeqStringSet(seq_str, count++, c0_); |
531 Advance(); | 531 Advance(); |
532 } else { | 532 } else { |
533 // StringType is SeqAsciiString and we just read a non-ASCII char. | 533 // StringType is SeqOneByteString and we just read a non-ASCII char. |
534 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count); | 534 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, 0, count); |
535 } | 535 } |
536 } else { | 536 } else { |
537 Advance(); // Advance past the \. | 537 Advance(); // Advance past the \. |
538 switch (c0_) { | 538 switch (c0_) { |
539 case '"': | 539 case '"': |
540 case '\\': | 540 case '\\': |
541 case '/': | 541 case '/': |
542 SeqStringSet(seq_str, count++, c0_); | 542 SeqStringSet(seq_str, count++, c0_); |
543 break; | 543 break; |
(...skipping 19 matching lines...) Expand all Loading... |
563 int digit = HexValue(c0_); | 563 int digit = HexValue(c0_); |
564 if (digit < 0) { | 564 if (digit < 0) { |
565 return Handle<String>::null(); | 565 return Handle<String>::null(); |
566 } | 566 } |
567 value = value * 16 + digit; | 567 value = value * 16 + digit; |
568 } | 568 } |
569 if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) { | 569 if (sizeof(SinkChar) == kUC16Size || value <= kMaxAsciiCharCode) { |
570 SeqStringSet(seq_str, count++, value); | 570 SeqStringSet(seq_str, count++, value); |
571 break; | 571 break; |
572 } else { | 572 } else { |
573 // StringType is SeqAsciiString and we just read a non-ASCII char. | 573 // StringType is SeqOneByteString and we just read a non-ASCII char. |
574 position_ -= 6; // Rewind position_ to \ in \uxxxx. | 574 position_ -= 6; // Rewind position_ to \ in \uxxxx. |
575 Advance(); | 575 Advance(); |
576 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, | 576 return SlowScanJsonString<SeqTwoByteString, uc16>(seq_str, |
577 0, | 577 0, |
578 count); | 578 count); |
579 } | 579 } |
580 } | 580 } |
581 default: | 581 default: |
582 return Handle<String>::null(); | 582 return Handle<String>::null(); |
583 } | 583 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
619 // a known symbol, contains backslashes or unexpectedly reaches the end of | 619 // a known symbol, contains backslashes or unexpectedly reaches the end of |
620 // string, return with an empty handle. | 620 // string, return with an empty handle. |
621 uint32_t running_hash = isolate()->heap()->HashSeed(); | 621 uint32_t running_hash = isolate()->heap()->HashSeed(); |
622 int position = position_; | 622 int position = position_; |
623 uc32 c0 = c0_; | 623 uc32 c0 = c0_; |
624 do { | 624 do { |
625 if (c0 == '\\') { | 625 if (c0 == '\\') { |
626 c0_ = c0; | 626 c0_ = c0; |
627 int beg_pos = position_; | 627 int beg_pos = position_; |
628 position_ = position; | 628 position_ = position; |
629 return SlowScanJsonString<SeqAsciiString, char>(source_, | 629 return SlowScanJsonString<SeqOneByteString, char>(source_, |
630 beg_pos, | 630 beg_pos, |
631 position_); | 631 position_); |
632 } | 632 } |
633 if (c0 < 0x20) return Handle<String>::null(); | 633 if (c0 < 0x20) return Handle<String>::null(); |
634 running_hash = StringHasher::AddCharacterCore(running_hash, c0); | 634 running_hash = StringHasher::AddCharacterCore(running_hash, c0); |
635 position++; | 635 position++; |
636 if (position >= source_length_) return Handle<String>::null(); | 636 if (position >= source_length_) return Handle<String>::null(); |
637 c0 = seq_source_->SeqAsciiStringGet(position); | 637 c0 = seq_source_->SeqOneByteStringGet(position); |
638 } while (c0 != '"'); | 638 } while (c0 != '"'); |
639 int length = position - position_; | 639 int length = position - position_; |
640 uint32_t hash = (length <= String::kMaxHashCalcLength) | 640 uint32_t hash = (length <= String::kMaxHashCalcLength) |
641 ? StringHasher::GetHashCore(running_hash) : length; | 641 ? StringHasher::GetHashCore(running_hash) : length; |
642 Vector<const char> string_vector( | 642 Vector<const char> string_vector( |
643 seq_source_->GetChars() + position_, length); | 643 seq_source_->GetChars() + position_, length); |
644 SymbolTable* symbol_table = isolate()->heap()->symbol_table(); | 644 SymbolTable* symbol_table = isolate()->heap()->symbol_table(); |
645 uint32_t capacity = symbol_table->Capacity(); | 645 uint32_t capacity = symbol_table->Capacity(); |
646 uint32_t entry = SymbolTable::FirstProbe(hash, capacity); | 646 uint32_t entry = SymbolTable::FirstProbe(hash, capacity); |
647 uint32_t count = 1; | 647 uint32_t count = 1; |
(...skipping 22 matching lines...) Expand all Loading... |
670 if (c0_ < 0x20) return Handle<String>::null(); | 670 if (c0_ < 0x20) return Handle<String>::null(); |
671 if (c0_ != '\\') { | 671 if (c0_ != '\\') { |
672 if (seq_ascii || c0_ <= kMaxAsciiCharCode) { | 672 if (seq_ascii || c0_ <= kMaxAsciiCharCode) { |
673 Advance(); | 673 Advance(); |
674 } else { | 674 } else { |
675 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, | 675 return SlowScanJsonString<SeqTwoByteString, uc16>(source_, |
676 beg_pos, | 676 beg_pos, |
677 position_); | 677 position_); |
678 } | 678 } |
679 } else { | 679 } else { |
680 return SlowScanJsonString<SeqAsciiString, char>(source_, | 680 return SlowScanJsonString<SeqOneByteString, char>(source_, |
681 beg_pos, | 681 beg_pos, |
682 position_); | 682 position_); |
683 } | 683 } |
684 } while (c0_ != '"'); | 684 } while (c0_ != '"'); |
685 int length = position_ - beg_pos; | 685 int length = position_ - beg_pos; |
686 Handle<String> result; | 686 Handle<String> result; |
687 if (seq_ascii && is_symbol) { | 687 if (seq_ascii && is_symbol) { |
688 result = factory()->LookupAsciiSymbol(seq_source_, | 688 result = factory()->LookupAsciiSymbol(seq_source_, |
689 beg_pos, | 689 beg_pos, |
690 length); | 690 length); |
691 } else { | 691 } else { |
692 result = factory()->NewRawAsciiString(length, pretenure_); | 692 result = factory()->NewRawOneByteString(length, pretenure_); |
693 char* dest = SeqAsciiString::cast(*result)->GetChars(); | 693 char* dest = SeqOneByteString::cast(*result)->GetChars(); |
694 String::WriteToFlat(*source_, dest, beg_pos, position_); | 694 String::WriteToFlat(*source_, dest, beg_pos, position_); |
695 } | 695 } |
696 ASSERT_EQ('"', c0_); | 696 ASSERT_EQ('"', c0_); |
697 // Advance past the last '"'. | 697 // Advance past the last '"'. |
698 AdvanceSkipWhitespace(); | 698 AdvanceSkipWhitespace(); |
699 return result; | 699 return result; |
700 } | 700 } |
701 | 701 |
702 } } // namespace v8::internal | 702 } } // namespace v8::internal |
703 | 703 |
704 #endif // V8_JSON_PARSER_H_ | 704 #endif // V8_JSON_PARSER_H_ |
OLD | NEW |