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 |