| Index: src/json-stringifier.h
|
| diff --git a/src/json-stringifier.h b/src/json-stringifier.h
|
| index cec98443a5c628cb103c56e27aec2db4e35a4fb6..2433792965771b3948c3406f865c9469c6d2ae41 100644
|
| --- a/src/json-stringifier.h
|
| +++ b/src/json-stringifier.h
|
| @@ -54,14 +54,14 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
|
|
| void ShrinkCurrentPart();
|
|
|
| - template <bool is_ascii, typename Char>
|
| + template <bool ascii_mode, typename Char>
|
| INLINE(void Append_(Char c));
|
|
|
| - template <bool is_ascii, typename Char>
|
| + template <bool ascii_mode, typename Char>
|
| INLINE(void Append_(const Char* chars));
|
|
|
| INLINE(void Append(uint8_t c)) {
|
| - if (is_ascii_) {
|
| + if (ascii_mode_) {
|
| Append_<true>(c);
|
| } else {
|
| Append_<false>(c);
|
| @@ -69,7 +69,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
| }
|
|
|
| INLINE(void AppendAscii(const char* chars)) {
|
| - if (is_ascii_) {
|
| + if (ascii_mode_) {
|
| Append_<true>(reinterpret_cast<const uint8_t*>(chars));
|
| } else {
|
| Append_<false>(reinterpret_cast<const uint8_t*>(chars));
|
| @@ -130,15 +130,15 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
|
|
| void SerializeString(Handle<String> object);
|
|
|
| - template <typename SrcChar, typename DestChar>
|
| + template <bool printable_ascii_only, typename SrcChar, typename DestChar>
|
| INLINE(void SerializeStringUnchecked_(const SrcChar* src,
|
| DestChar* dest,
|
| int length));
|
|
|
| - template <bool is_ascii, typename Char>
|
| + template <bool printable_ascii_only, bool ascii_mode, typename Char>
|
| INLINE(void SerializeString_(Handle<String> string));
|
|
|
| - template <typename Char>
|
| + template <bool printable_ascii_only, typename Char>
|
| INLINE(bool DoNotEscape(Char c));
|
|
|
| template <typename Char>
|
| @@ -165,7 +165,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
|
| Handle<JSArray> stack_;
|
| int current_index_;
|
| int part_length_;
|
| - bool is_ascii_;
|
| + bool ascii_mode_;
|
|
|
| static const int kJsonEscapeTableEntrySize = 8;
|
| static const char* const JsonEscapeTable;
|
| @@ -210,7 +210,7 @@ const char* const BasicJsonStringifier::JsonEscapeTable =
|
|
|
|
|
| BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
|
| - : isolate_(isolate), current_index_(0), is_ascii_(true) {
|
| + : isolate_(isolate), current_index_(0), ascii_mode_(true) {
|
| factory_ = isolate_->factory();
|
| accumulator_store_ = Handle<JSValue>::cast(
|
| factory_->ToObject(factory_->empty_string()));
|
| @@ -240,9 +240,9 @@ MaybeObject* BasicJsonStringifier::Stringify(Handle<Object> object) {
|
| }
|
|
|
|
|
| -template <bool is_ascii, typename Char>
|
| +template <bool ascii_mode, typename Char>
|
| void BasicJsonStringifier::Append_(Char c) {
|
| - if (is_ascii) {
|
| + if (ascii_mode) {
|
| SeqOneByteString::cast(*current_part_)->SeqOneByteStringSet(
|
| current_index_++, c);
|
| } else {
|
| @@ -253,9 +253,9 @@ void BasicJsonStringifier::Append_(Char c) {
|
| }
|
|
|
|
|
| -template <bool is_ascii, typename Char>
|
| +template <bool ascii_mode, typename Char>
|
| void BasicJsonStringifier::Append_(const Char* chars) {
|
| - for ( ; *chars != '\0'; chars++) Append_<is_ascii, Char>(*chars);
|
| + for ( ; *chars != '\0'; chars++) Append_<ascii_mode, Char>(*chars);
|
| }
|
|
|
|
|
| @@ -608,7 +608,7 @@ void BasicJsonStringifier::Extend() {
|
| if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
|
| part_length_ *= kPartLengthGrowthFactor;
|
| }
|
| - if (is_ascii_) {
|
| + if (ascii_mode_) {
|
| current_part_ = factory_->NewRawOneByteString(part_length_);
|
| } else {
|
| current_part_ = factory_->NewRawTwoByteString(part_length_);
|
| @@ -622,11 +622,11 @@ void BasicJsonStringifier::ChangeEncoding() {
|
| set_accumulator(factory_->NewConsString(accumulator(), current_part_));
|
| current_part_ = factory_->NewRawTwoByteString(part_length_);
|
| current_index_ = 0;
|
| - is_ascii_ = false;
|
| + ascii_mode_ = false;
|
| }
|
|
|
|
|
| -template <typename SrcChar, typename DestChar>
|
| +template < bool printable_ascii_only, typename SrcChar, typename DestChar>
|
| void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
|
| DestChar* dest,
|
| int length) {
|
| @@ -639,7 +639,7 @@ void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
|
|
|
| for (int i = 0; i < length; i++) {
|
| SrcChar c = src[i];
|
| - if (DoNotEscape(c)) {
|
| + if (DoNotEscape<printable_ascii_only>(c)) {
|
| *(dest++) = static_cast<DestChar>(c);
|
| } else {
|
| const char* chars = &JsonEscapeTable[c * kJsonEscapeTableEntrySize];
|
| @@ -651,10 +651,10 @@ void BasicJsonStringifier::SerializeStringUnchecked_(const SrcChar* src,
|
| }
|
|
|
|
|
| -template <bool is_ascii, typename Char>
|
| +template <bool printable_ascii_only, bool ascii_mode, typename Char>
|
| void BasicJsonStringifier::SerializeString_(Handle<String> string) {
|
| int length = string->length();
|
| - Append_<is_ascii, char>('"');
|
| + Append_<ascii_mode, char>('"');
|
| // We make a rough estimate to find out if the current string can be
|
| // serialized without allocating a new string part. The worst case length of
|
| // an escaped character is 6. Shifting the remainin string length right by 3
|
| @@ -663,13 +663,13 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
|
| if (((part_length_ - current_index_) >> 3) > length) {
|
| AssertNoAllocation no_allocation;
|
| Vector<const Char> vector = GetCharVector<Char>(string);
|
| - if (is_ascii) {
|
| - SerializeStringUnchecked_(
|
| + if (ascii_mode) {
|
| + SerializeStringUnchecked_<printable_ascii_only>(
|
| vector.start(),
|
| SeqOneByteString::cast(*current_part_)->GetChars(),
|
| length);
|
| } else {
|
| - SerializeStringUnchecked_(
|
| + SerializeStringUnchecked_<printable_ascii_only>(
|
| vector.start(),
|
| SeqTwoByteString::cast(*current_part_)->GetChars(),
|
| length);
|
| @@ -679,10 +679,10 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
|
| Vector<const Char> vector = GetCharVector<Char>(string);
|
| for (int i = 0; i < length; i++) {
|
| Char c = vector[i];
|
| - if (DoNotEscape(c)) {
|
| - Append_<is_ascii, Char>(c);
|
| + if (DoNotEscape<printable_ascii_only>(c)) {
|
| + Append_<ascii_mode, Char>(c);
|
| } else {
|
| - Append_<is_ascii, uint8_t>(
|
| + Append_<ascii_mode, uint8_t>(
|
| reinterpret_cast<const uint8_t*>(
|
| &JsonEscapeTable[c * kJsonEscapeTableEntrySize]));
|
| }
|
| @@ -694,13 +694,15 @@ void BasicJsonStringifier::SerializeString_(Handle<String> string) {
|
| }
|
| }
|
|
|
| - Append_<is_ascii, uint8_t>('"');
|
| + Append_<ascii_mode, uint8_t>('"');
|
| }
|
|
|
|
|
| -template <typename Char>
|
| +template <bool printable_ascii_only, typename Char>
|
| bool BasicJsonStringifier::DoNotEscape(Char c) {
|
| - return (c >= 0x80) || (c >= '#' && c <= '~' && c != '\\');
|
| + // "Printable" ASCII is in the range 0x20 .. 0x7e.
|
| + return (c != '"' && c != '\\') &&
|
| + (printable_ascii_only || (c != 0x7f && c >= 0x20));
|
| }
|
|
|
|
|
| @@ -724,18 +726,26 @@ Vector<const uc16> BasicJsonStringifier::GetCharVector(Handle<String> string) {
|
| void BasicJsonStringifier::SerializeString(Handle<String> object) {
|
| FlattenString(object);
|
| String::FlatContent flat = object->GetFlatContent();
|
| - if (is_ascii_) {
|
| + if (ascii_mode_) {
|
| if (flat.IsAscii()) {
|
| - SerializeString_<true, uint8_t>(object);
|
| + if (object->map() == isolate_->heap()->printable_ascii_symbol_map()) {
|
| + SerializeString_<true, true, uint8_t>(object);
|
| + } else {
|
| + SerializeString_<false, true, uint8_t>(object);
|
| + }
|
| } else {
|
| ChangeEncoding();
|
| SerializeString(object);
|
| }
|
| } else {
|
| if (flat.IsAscii()) {
|
| - SerializeString_<false, uint8_t>(object);
|
| + if (object->map() == isolate_->heap()->printable_ascii_symbol_map()) {
|
| + SerializeString_<true, false, uint8_t>(object);
|
| + } else {
|
| + SerializeString_<false, false, uint8_t>(object);
|
| + }
|
| } else {
|
| - SerializeString_<false, uc16>(object);
|
| + SerializeString_<false, false, uc16>(object);
|
| }
|
| }
|
| }
|
|
|