Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/json-stringifier.h" | 5 #include "src/json-stringifier.h" |
| 6 | 6 |
| 7 #include "src/conversions.h" | 7 #include "src/conversions.h" |
| 8 #include "src/lookup.h" | 8 #include "src/lookup.h" |
| 9 #include "src/messages.h" | 9 #include "src/messages.h" |
| 10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 74 "\334\0 \335\0 \336\0 \337\0 " | 74 "\334\0 \335\0 \336\0 \337\0 " |
| 75 "\340\0 \341\0 \342\0 \343\0 " | 75 "\340\0 \341\0 \342\0 \343\0 " |
| 76 "\344\0 \345\0 \346\0 \347\0 " | 76 "\344\0 \345\0 \346\0 \347\0 " |
| 77 "\350\0 \351\0 \352\0 \353\0 " | 77 "\350\0 \351\0 \352\0 \353\0 " |
| 78 "\354\0 \355\0 \356\0 \357\0 " | 78 "\354\0 \355\0 \356\0 \357\0 " |
| 79 "\360\0 \361\0 \362\0 \363\0 " | 79 "\360\0 \361\0 \362\0 \363\0 " |
| 80 "\364\0 \365\0 \366\0 \367\0 " | 80 "\364\0 \365\0 \366\0 \367\0 " |
| 81 "\370\0 \371\0 \372\0 \373\0 " | 81 "\370\0 \371\0 \372\0 \373\0 " |
| 82 "\374\0 \375\0 \376\0 \377\0 "; | 82 "\374\0 \375\0 \376\0 \377\0 "; |
| 83 | 83 |
| 84 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate, Handle<String> gap) | 84 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate) |
| 85 : isolate_(isolate), builder_(isolate), gap_string_(gap), indent_(0) { | 85 : isolate_(isolate), builder_(isolate), gap_(nullptr), indent_(0) { |
| 86 tojson_string_ = factory()->toJSON_string(); | 86 tojson_string_ = factory()->toJSON_string(); |
| 87 stack_ = factory()->NewJSArray(8); | 87 stack_ = factory()->NewJSArray(8); |
| 88 int gap_length = gap->length(); | |
| 89 if (gap_length != 0) { | |
| 90 gap = String::Flatten(gap); | |
| 91 if (gap->IsTwoByteRepresentation()) builder_.ChangeEncoding(); | |
| 92 DisallowHeapAllocation no_gc; | |
| 93 String::FlatContent flat = gap->GetFlatContent(); | |
| 94 gap_ = NewArray<uc16>(gap_length + 1); | |
| 95 if (flat.IsOneByte()) { | |
| 96 CopyChars(gap_, flat.ToOneByteVector().start(), gap_length); | |
| 97 } else { | |
| 98 CopyChars(gap_, flat.ToUC16Vector().start(), gap_length); | |
| 99 } | |
| 100 gap_[gap_length] = '\0'; | |
| 101 } else { | |
| 102 gap_ = nullptr; | |
| 103 } | |
| 104 } | 88 } |
| 105 | 89 |
| 106 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object) { | 90 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object, |
| 91 Handle<Object> gap) { | |
| 92 if (!gap->IsUndefined() && !InitializeGap(gap)) return MaybeHandle<Object>(); | |
| 107 Result result = SerializeObject(object); | 93 Result result = SerializeObject(object); |
| 108 if (result == UNCHANGED) return factory()->undefined_value(); | 94 if (result == UNCHANGED) return factory()->undefined_value(); |
| 109 if (result == SUCCESS) return builder_.Finish(); | 95 if (result == SUCCESS) return builder_.Finish(); |
| 110 DCHECK(result == EXCEPTION); | 96 DCHECK(result == EXCEPTION); |
| 111 return MaybeHandle<Object>(); | 97 return MaybeHandle<Object>(); |
| 112 } | 98 } |
| 113 | 99 |
| 100 bool BasicJsonStringifier::InitializeGap(Handle<Object> gap) { | |
| 101 DCHECK_NULL(gap_); | |
| 102 HandleScope scope(isolate_); | |
| 103 if (gap->IsJSReceiver()) { | |
| 104 Handle<String> class_name(Handle<JSReceiver>::cast(gap)->class_name()); | |
| 105 if (class_name.is_identical_to(factory()->String_string())) { | |
|
Camillo Bruni
2016/05/23 14:08:25
argh :D we should have a IsNumberLike() somewhere
Yang
2016/05/23 18:19:07
Actually, the string case and the number case are
| |
| 106 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, | |
| 107 Object::ToString(isolate_, gap), false); | |
| 108 } else if (class_name.is_identical_to(factory()->number_string())) { | |
| 109 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, Object::ToNumber(gap), | |
| 110 false); | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 if (gap->IsString()) { | |
| 115 Handle<String> gap_string = Handle<String>::cast(gap); | |
| 116 if (gap_string->length() > 0) { | |
| 117 int gap_length = std::min(gap_string->length(), 10); | |
| 118 gap_ = NewArray<uc16>(gap_length + 1); | |
| 119 String::WriteToFlat(*gap_string, gap_, 0, gap_length); | |
| 120 for (int i = 0; i < gap_length; i++) { | |
| 121 if (gap_[i] > String::kMaxOneByteCharCode) { | |
| 122 builder_.ChangeEncoding(); | |
| 123 break; | |
| 124 } | |
| 125 } | |
| 126 gap_[gap_length] = '\0'; | |
| 127 } | |
| 128 } else if (gap->IsNumber()) { | |
| 129 int num_value = DoubleToInt32(gap->Number()); | |
| 130 if (num_value > 0) { | |
| 131 int gap_length = std::min(num_value, 10); | |
|
Camillo Bruni
2016/05/23 14:08:25
just read the spec, wut? :D
Yang
2016/05/23 18:19:07
Yeah. Magic numbers ftw.
| |
| 132 gap_ = NewArray<uc16>(gap_length + 1); | |
| 133 for (int i = 0; i < gap_length; i++) gap_[i] = ' '; | |
| 134 gap_[gap_length] = '\0'; | |
| 135 } | |
| 136 } | |
| 137 return true; | |
| 138 } | |
| 139 | |
| 114 MaybeHandle<Object> BasicJsonStringifier::StringifyString( | 140 MaybeHandle<Object> BasicJsonStringifier::StringifyString( |
| 115 Isolate* isolate, Handle<String> object) { | 141 Isolate* isolate, Handle<String> object) { |
| 116 static const int kJsonQuoteWorstCaseBlowup = 6; | 142 static const int kJsonQuoteWorstCaseBlowup = 6; |
| 117 static const int kSpaceForQuotes = 2; | 143 static const int kSpaceForQuotes = 2; |
| 118 int worst_case_length = | 144 int worst_case_length = |
| 119 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; | 145 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; |
| 120 | 146 |
| 121 if (worst_case_length > 32 * KB) { // Slow path if too large. | 147 if (worst_case_length > 32 * KB) { // Slow path if too large. |
| 122 BasicJsonStringifier stringifier(isolate, | 148 BasicJsonStringifier stringifier(isolate); |
| 123 isolate->factory()->empty_string()); | 149 return stringifier.Stringify(object, isolate->factory()->undefined_value()); |
| 124 return stringifier.Stringify(object); | |
| 125 } | 150 } |
| 126 | 151 |
| 127 object = String::Flatten(object); | 152 object = String::Flatten(object); |
| 128 DCHECK(object->IsFlat()); | 153 DCHECK(object->IsFlat()); |
| 129 Handle<SeqString> result; | 154 Handle<SeqString> result; |
| 130 if (object->IsOneByteRepresentationUnderneath()) { | 155 if (object->IsOneByteRepresentationUnderneath()) { |
| 131 result = isolate->factory() | 156 result = isolate->factory() |
| 132 ->NewRawOneByteString(worst_case_length) | 157 ->NewRawOneByteString(worst_case_length) |
| 133 .ToHandleChecked(); | 158 .ToHandleChecked(); |
| 134 IncrementalStringBuilder::NoExtendString<uint8_t> no_extend( | 159 IncrementalStringBuilder::NoExtendString<uint8_t> no_extend( |
| (...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 624 if (object->IsOneByteRepresentationUnderneath()) { | 649 if (object->IsOneByteRepresentationUnderneath()) { |
| 625 SerializeString_<uint8_t, uc16>(object); | 650 SerializeString_<uint8_t, uc16>(object); |
| 626 } else { | 651 } else { |
| 627 SerializeString_<uc16, uc16>(object); | 652 SerializeString_<uc16, uc16>(object); |
| 628 } | 653 } |
| 629 } | 654 } |
| 630 } | 655 } |
| 631 | 656 |
| 632 } // namespace internal | 657 } // namespace internal |
| 633 } // namespace v8 | 658 } // namespace v8 |
| OLD | NEW |