Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(931)

Side by Side Diff: src/json-stringifier.cc

Issue 2006663002: [json] implement JSON.stringify gap pre-processing in C++. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@jsonrefactor
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime-json.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime-json.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698