Chromium Code Reviews| 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 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 52 template <bool is_ascii> void Extend(); | 52 template <bool is_ascii> void Extend(); |
| 53 | 53 |
| 54 void ChangeEncoding(); | 54 void ChangeEncoding(); |
| 55 | 55 |
| 56 void ShrinkCurrentPart(); | 56 void ShrinkCurrentPart(); |
| 57 | 57 |
| 58 template <bool is_ascii, typename Char> | 58 template <bool is_ascii, typename Char> |
| 59 INLINE(void Append_(Char c)); | 59 INLINE(void Append_(Char c)); |
| 60 | 60 |
| 61 template <bool is_ascii, typename Char> | 61 template <bool is_ascii, typename Char> |
| 62 INLINE(void AppendUnchecked_(Char c)); | |
| 63 | |
| 64 template <bool is_ascii, typename Char> | |
| 65 INLINE(void Append_(const Char* chars)); | 62 INLINE(void Append_(const Char* chars)); |
| 66 | 63 |
| 67 template <bool is_ascii, typename Char> | |
| 68 INLINE(void AppendUnchecked_(const Char* chars)); | |
| 69 | |
| 70 INLINE(void Append(char c)) { | 64 INLINE(void Append(char c)) { |
| 71 if (is_ascii_) { | 65 if (is_ascii_) { |
| 72 Append_<true>(c); | 66 Append_<true>(c); |
| 73 } else { | 67 } else { |
| 74 Append_<false>(c); | 68 Append_<false>(c); |
| 75 } | 69 } |
| 76 } | 70 } |
| 77 | 71 |
| 78 INLINE(void Append(const char* chars)) { | 72 INLINE(void Append(const char* chars)) { |
| 79 if (is_ascii_) { | 73 if (is_ascii_) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 116 INLINE(Result SerializeDouble(double number)); | 110 INLINE(Result SerializeDouble(double number)); |
| 117 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { | 111 INLINE(Result SerializeHeapNumber(Handle<HeapNumber> object)) { |
| 118 return SerializeDouble(object->value()); | 112 return SerializeDouble(object->value()); |
| 119 } | 113 } |
| 120 | 114 |
| 121 Result SerializeArray(Handle<JSArray> object); | 115 Result SerializeArray(Handle<JSArray> object); |
| 122 Result SerializeObject(Handle<JSObject> object); | 116 Result SerializeObject(Handle<JSObject> object); |
| 123 | 117 |
| 124 void SerializeString(Handle<String> object); | 118 void SerializeString(Handle<String> object); |
| 125 | 119 |
| 120 template <typename SrcChar, typename DestChar> | |
| 121 INLINE(void SerializeStringUnchecked_(const SrcChar* src, | |
| 122 DestChar* dest, | |
| 123 int length)); | |
| 124 | |
| 126 template <bool is_ascii, typename Char> | 125 template <bool is_ascii, typename Char> |
| 127 INLINE(void SerializeString_(Vector<const Char> vector, | 126 INLINE(void SerializeString_(Vector<const Char> vector, |
| 128 Handle<String> string)); | 127 Handle<String> string)); |
| 129 | 128 |
| 130 template <typename Char> | 129 template <typename Char> |
| 130 INLINE(bool NeedsEscaping(Char c)); | |
| 131 | |
| 132 template <typename Char> | |
| 131 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); | 133 INLINE(Vector<const Char> GetCharVector(Handle<String> string)); |
| 132 | 134 |
| 133 INLINE(Result StackPush(Handle<Object> object)); | 135 INLINE(Result StackPush(Handle<Object> object)); |
| 134 INLINE(void StackPop()); | 136 INLINE(void StackPop()); |
| 135 | 137 |
| 136 INLINE(Handle<String> accumulator()) { | 138 INLINE(Handle<String> accumulator()) { |
| 137 return Handle<String>(String::cast(accumulator_store_->value())); | 139 return Handle<String>(String::cast(accumulator_store_->value())); |
| 138 } | 140 } |
| 139 | 141 |
| 140 INLINE(void set_accumulator(Handle<String> string)) { | 142 INLINE(void set_accumulator(Handle<String> string)) { |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 229 current_index_++, c); | 231 current_index_++, c); |
| 230 } else { | 232 } else { |
| 231 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( | 233 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( |
| 232 current_index_++, c); | 234 current_index_++, c); |
| 233 } | 235 } |
| 234 if (current_index_ == part_length_) Extend<is_ascii>(); | 236 if (current_index_ == part_length_) Extend<is_ascii>(); |
| 235 } | 237 } |
| 236 | 238 |
| 237 | 239 |
| 238 template <bool is_ascii, typename Char> | 240 template <bool is_ascii, typename Char> |
| 239 void BasicJsonStringifier::AppendUnchecked_(Char c) { | |
| 240 if (is_ascii) { | |
| 241 SeqAsciiString::cast(*current_part_)->SeqAsciiStringSet( | |
| 242 current_index_++, c); | |
| 243 } else { | |
| 244 SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet( | |
| 245 current_index_++, c); | |
| 246 } | |
| 247 ASSERT(current_index_ < part_length_); | |
| 248 } | |
| 249 | |
| 250 | |
| 251 template <bool is_ascii, typename Char> | |
| 252 void BasicJsonStringifier::Append_(const Char* chars) { | 241 void BasicJsonStringifier::Append_(const Char* chars) { |
| 253 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars); | 242 for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars); |
| 254 } | 243 } |
| 255 | 244 |
| 256 | 245 |
| 257 template <bool is_ascii, typename Char> | |
| 258 void BasicJsonStringifier::AppendUnchecked_(const Char* chars) { | |
| 259 for ( ; *chars != '\0'; chars++) AppendUnchecked_<is_ascii, Char>(*chars); | |
| 260 } | |
| 261 | |
| 262 | |
| 263 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object, | 246 Handle<Object> BasicJsonStringifier::GetProperty(Handle<JSObject> object, |
| 264 Handle<String> key) { | 247 Handle<String> key) { |
| 265 LookupResult lookup(isolate_); | 248 LookupResult lookup(isolate_); |
| 266 object->LocalLookupRealNamedProperty(*key, &lookup); | 249 object->LocalLookupRealNamedProperty(*key, &lookup); |
| 267 if (!lookup.IsProperty()) return isolate_->factory()->undefined_value(); | 250 if (!lookup.IsProperty()) return isolate_->factory()->undefined_value(); |
| 268 switch (lookup.type()) { | 251 switch (lookup.type()) { |
| 269 case NORMAL: { | 252 case NORMAL: { |
| 270 Object* value = lookup.holder()->GetNormalizedProperty(&lookup); | 253 Object* value = lookup.holder()->GetNormalizedProperty(&lookup); |
| 271 ASSERT(!value->IsTheHole()); | 254 ASSERT(!value->IsTheHole()); |
| 272 return Handle<Object>(value); | 255 return Handle<Object>(value); |
| (...skipping 299 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 ShrinkCurrentPart(); | 555 ShrinkCurrentPart(); |
| 573 set_accumulator( | 556 set_accumulator( |
| 574 isolate_->factory()->NewConsString(accumulator(), current_part_)); | 557 isolate_->factory()->NewConsString(accumulator(), current_part_)); |
| 575 current_part_ = | 558 current_part_ = |
| 576 isolate_->factory()->NewRawTwoByteString(part_length_); | 559 isolate_->factory()->NewRawTwoByteString(part_length_); |
| 577 current_index_ = 0; | 560 current_index_ = 0; |
| 578 is_ascii_ = false; | 561 is_ascii_ = false; |
| 579 } | 562 } |
| 580 | 563 |
| 581 | 564 |
| 565 template <typename SrcChar, typename DestChar> | |
| 566 void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src, | |
| 567 DestChar* dest, | |
| 568 int length) { | |
| 569 dest += current_index_; | |
| 570 DestChar* dest_start = dest; | |
| 571 | |
| 572 *(dest++) = '"'; | |
| 573 for (int i = 0; i < length; i++) { | |
| 574 SrcChar c = src[i]; | |
| 575 if (NeedsEscaping(c)) { | |
|
Toon Verwaest
2012/10/23 08:24:35
This seems backwards; shouldn't it use 'JsonQuotes
Yang
2012/10/23 08:57:37
Done.
| |
| 576 *(dest++) = c; | |
| 577 } else { | |
| 578 const char* chars = &JsonQuotes[c * kJsonQuotesCharactersPerEntry]; | |
| 579 while (*chars != '\0') *(dest++) = *(chars++); | |
| 580 } | |
| 581 } | |
| 582 | |
| 583 *(dest++) = '"'; | |
| 584 current_index_ += dest - dest_start; | |
| 585 } | |
| 586 | |
| 587 | |
| 582 template <bool is_ascii, typename Char> | 588 template <bool is_ascii, typename Char> |
| 583 void BasicJsonStringifier::SerializeString_(Vector<const Char> vector, | 589 void BasicJsonStringifier::SerializeString_(Vector<const Char> vector, |
| 584 Handle<String> string) { | 590 Handle<String> string) { |
| 585 int length = vector.length(); | 591 int length = vector.length(); |
| 586 if (current_index_ + (length << 3) < (part_length_ - 2)) { | 592 if (current_index_ + (length << 3) < (part_length_ - 2)) { |
|
Toon Verwaest
2012/10/23 08:24:35
Please document these magic numbers somehow (eithe
Yang
2012/10/23 08:57:37
Done.
| |
| 587 AssertNoAllocation no_allocation_scope; | 593 if (is_ascii) { |
| 588 AppendUnchecked_<is_ascii, char>('"'); | 594 SerializeStringUnchecked_( |
| 589 for (int i = 0; i < length; i++) { | 595 vector.start(), |
| 590 Char c = vector[i]; | 596 SeqAsciiString::cast(*current_part_)->GetChars(), |
| 591 if ((c >= '#' && c <= '~' && c != '\\') || | 597 length); |
| 592 (!is_ascii && ((c & 0xFF80) != 0))) { | 598 } else { |
| 593 AppendUnchecked_<is_ascii, Char>(c); | 599 SerializeStringUnchecked_( |
| 594 } else { | 600 vector.start(), |
| 595 AppendUnchecked_<is_ascii, char>( | 601 SeqTwoByteString::cast(*current_part_)->GetChars(), |
| 596 &JsonQuotes[c * kJsonQuotesCharactersPerEntry]); | 602 length); |
| 597 } | |
| 598 } | 603 } |
| 599 AppendUnchecked_<is_ascii, char>('"'); | |
| 600 } else { | 604 } else { |
| 601 Append_<is_ascii, char>('"'); | 605 Append_<is_ascii, char>('"'); |
| 602 String* string_location = *string; | 606 String* string_location = *string; |
| 603 for (int i = 0; i < length; i++) { | 607 for (int i = 0; i < length; i++) { |
| 604 Char c = vector[i]; | 608 Char c = vector[i]; |
| 605 if ((c >= '#' && c <= '~' && c != '\\') || | 609 if (NeedsEscaping(c)) { |
| 606 (!is_ascii && ((c & 0xFF80) != 0))) { | |
| 607 Append_<is_ascii, Char>(c); | 610 Append_<is_ascii, Char>(c); |
| 608 } else { | 611 } else { |
| 609 Append_<is_ascii, char>(&JsonQuotes[c * kJsonQuotesCharactersPerEntry]); | 612 Append_<is_ascii, char>(&JsonQuotes[c * kJsonQuotesCharactersPerEntry]); |
| 610 } | 613 } |
| 611 // If GC moved the string, we need to refresh the vector. | 614 // If GC moved the string, we need to refresh the vector. |
| 612 if (*string != string_location) { | 615 if (*string != string_location) { |
| 613 vector = GetCharVector<Char>(string); | 616 vector = GetCharVector<Char>(string); |
| 614 string_location = *string; | 617 string_location = *string; |
| 615 } | 618 } |
| 616 } | 619 } |
| 617 Append_<is_ascii, char>('"'); | 620 Append_<is_ascii, char>('"'); |
| 618 } | 621 } |
| 619 } | 622 } |
| 620 | 623 |
| 621 | 624 |
| 622 template <> | 625 template <> |
| 626 bool BasicJsonStringifier::NeedsEscaping(char c) { | |
| 627 return c >= '#' && c <= '~' && c != '\\'; | |
| 628 } | |
| 629 | |
| 630 | |
| 631 template <> | |
| 632 bool BasicJsonStringifier::NeedsEscaping(uc16 c) { | |
| 633 return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\'); | |
| 634 } | |
| 635 | |
| 636 | |
| 637 template <> | |
| 623 Vector<const char> BasicJsonStringifier::GetCharVector(Handle<String> string) { | 638 Vector<const char> BasicJsonStringifier::GetCharVector(Handle<String> string) { |
| 624 String::FlatContent flat = string->GetFlatContent(); | 639 String::FlatContent flat = string->GetFlatContent(); |
| 625 ASSERT(flat.IsAscii()); | 640 ASSERT(flat.IsAscii()); |
| 626 return flat.ToAsciiVector(); | 641 return flat.ToAsciiVector(); |
| 627 } | 642 } |
| 628 | 643 |
| 629 | 644 |
| 630 template <> | 645 template <> |
| 631 Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) { | 646 Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) { |
| 632 String::FlatContent flat = string->GetFlatContent(); | 647 String::FlatContent flat = string->GetFlatContent(); |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 650 SerializeString_<false, char>(flat.ToAsciiVector(), object); | 665 SerializeString_<false, char>(flat.ToAsciiVector(), object); |
| 651 } else { | 666 } else { |
| 652 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); | 667 SerializeString_<false, uc16>(flat.ToUC16Vector(), object); |
| 653 } | 668 } |
| 654 } | 669 } |
| 655 } | 670 } |
| 656 | 671 |
| 657 } } // namespace v8::internal | 672 } } // namespace v8::internal |
| 658 | 673 |
| 659 #endif // V8_JSON_STRINGIFIER_H_ | 674 #endif // V8_JSON_STRINGIFIER_H_ |
| OLD | NEW |