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 |