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

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

Issue 2004413002: [json] support property list argument in BasicJsonStringifier. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 7 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.h » ('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 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) 84 BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
85 : isolate_(isolate), builder_(isolate), gap_(nullptr), 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 } 88 }
89 89
90 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object, 90 MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object,
91 Handle<Object> replacer,
91 Handle<Object> gap) { 92 Handle<Object> gap) {
93 if (!InitializeReplacer(replacer)) return MaybeHandle<Object>();
92 if (!gap->IsUndefined() && !InitializeGap(gap)) return MaybeHandle<Object>(); 94 if (!gap->IsUndefined() && !InitializeGap(gap)) return MaybeHandle<Object>();
93 Result result = SerializeObject(object); 95 Result result = SerializeObject(object);
94 if (result == UNCHANGED) return factory()->undefined_value(); 96 if (result == UNCHANGED) return factory()->undefined_value();
95 if (result == SUCCESS) return builder_.Finish(); 97 if (result == SUCCESS) return builder_.Finish();
96 DCHECK(result == EXCEPTION); 98 DCHECK(result == EXCEPTION);
97 return MaybeHandle<Object>(); 99 return MaybeHandle<Object>();
98 } 100 }
99 101
102 bool IsInList(Handle<String> key, List<Handle<String> >* list) {
103 // TODO(yangguo): This is O(n^2) for n properties in the list. Deal with this
104 // if this becomes an issue.
105 for (const Handle<String>& existing : *list) {
106 if (String::Equals(existing, key)) return true;
107 }
108 return false;
109 }
110
111 bool BasicJsonStringifier::InitializeReplacer(Handle<Object> replacer) {
112 DCHECK(property_list_.is_null());
113 Maybe<bool> is_array = Object::IsArray(replacer);
114 if (is_array.IsNothing()) return false;
115 if (is_array.FromJust()) {
116 HandleScope handle_scope(isolate_);
117 List<Handle<String> > list;
118 Handle<Object> length_obj;
119 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
120 isolate_, length_obj,
121 Object::GetLengthFromArrayLike(isolate_, replacer), false);
122 uint32_t length;
123 if (!length_obj->ToUint32(&length)) length = kMaxUInt32;
124 for (uint32_t i = 0; i < length; i++) {
125 Handle<Object> element;
126 Handle<String> key;
127 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
128 isolate_, element, Object::GetElement(isolate_, replacer, i), false);
129 if (element->IsNumber() || element->IsString()) {
130 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
131 isolate_, key, Object::ToString(isolate_, element), false);
132 } else if (element->IsJSValue()) {
133 Handle<Object> value(Handle<JSValue>::cast(element)->value(), isolate_);
134 if (value->IsNumber() || value->IsString()) {
135 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
136 isolate_, key, Object::ToString(isolate_, element), false);
137 }
138 }
139 if (key.is_null()) continue;
140 if (!IsInList(key, &list)) list.Add(key);
141 }
142 property_list_ = factory()->NewUninitializedFixedArray(list.length());
143 for (int i = 0; i < list.length(); i++) {
144 property_list_->set(i, *list[i]);
145 }
146 property_list_ = handle_scope.CloseAndEscape(property_list_);
147 }
148 return true;
149 }
150
100 bool BasicJsonStringifier::InitializeGap(Handle<Object> gap) { 151 bool BasicJsonStringifier::InitializeGap(Handle<Object> gap) {
101 DCHECK_NULL(gap_); 152 DCHECK_NULL(gap_);
102 HandleScope scope(isolate_); 153 HandleScope scope(isolate_);
103 if (gap->IsJSReceiver()) { 154 if (gap->IsJSValue()) {
104 Handle<String> class_name(Handle<JSReceiver>::cast(gap)->class_name()); 155 Handle<Object> value(Handle<JSValue>::cast(gap)->value(), isolate_);
105 if (class_name.is_identical_to(factory()->String_string())) { 156 if (value->IsString()) {
106 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, 157 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap,
107 Object::ToString(isolate_, gap), false); 158 Object::ToString(isolate_, gap), false);
108 } else if (class_name.is_identical_to(factory()->number_string())) { 159 } else if (value->IsNumber()) {
109 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, Object::ToNumber(gap), 160 ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, Object::ToNumber(gap),
110 false); 161 false);
111 } 162 }
112 } 163 }
113 164
114 if (gap->IsString()) { 165 if (gap->IsString()) {
115 Handle<String> gap_string = Handle<String>::cast(gap); 166 Handle<String> gap_string = Handle<String>::cast(gap);
116 if (gap_string->length() > 0) { 167 if (gap_string->length() > 0) {
117 int gap_length = std::min(gap_string->length(), 10); 168 int gap_length = std::min(gap_string->length(), 10);
118 gap_ = NewArray<uc16>(gap_length + 1); 169 gap_ = NewArray<uc16>(gap_length + 1);
(...skipping 20 matching lines...) Expand all
139 190
140 MaybeHandle<Object> BasicJsonStringifier::StringifyString( 191 MaybeHandle<Object> BasicJsonStringifier::StringifyString(
141 Isolate* isolate, Handle<String> object) { 192 Isolate* isolate, Handle<String> object) {
142 static const int kJsonQuoteWorstCaseBlowup = 6; 193 static const int kJsonQuoteWorstCaseBlowup = 6;
143 static const int kSpaceForQuotes = 2; 194 static const int kSpaceForQuotes = 2;
144 int worst_case_length = 195 int worst_case_length =
145 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes; 196 object->length() * kJsonQuoteWorstCaseBlowup + kSpaceForQuotes;
146 197
147 if (worst_case_length > 32 * KB) { // Slow path if too large. 198 if (worst_case_length > 32 * KB) { // Slow path if too large.
148 BasicJsonStringifier stringifier(isolate); 199 BasicJsonStringifier stringifier(isolate);
149 return stringifier.Stringify(object, isolate->factory()->undefined_value()); 200 Handle<Object> undefined = isolate->factory()->undefined_value();
201 return stringifier.Stringify(object, undefined, undefined);
150 } 202 }
151 203
152 object = String::Flatten(object); 204 object = String::Flatten(object);
153 DCHECK(object->IsFlat()); 205 DCHECK(object->IsFlat());
154 Handle<SeqString> result; 206 Handle<SeqString> result;
155 if (object->IsOneByteRepresentationUnderneath()) { 207 if (object->IsOneByteRepresentationUnderneath()) {
156 result = isolate->factory() 208 result = isolate->factory()
157 ->NewRawOneByteString(worst_case_length) 209 ->NewRawOneByteString(worst_case_length)
158 .ToHandleChecked(); 210 .ToHandleChecked();
159 IncrementalStringBuilder::NoExtendString<uint8_t> no_extend( 211 IncrementalStringBuilder::NoExtendString<uint8_t> no_extend(
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
430 } 482 }
431 return SUCCESS; 483 return SUCCESS;
432 } 484 }
433 485
434 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject( 486 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
435 Handle<JSObject> object) { 487 Handle<JSObject> object) {
436 HandleScope handle_scope(isolate_); 488 HandleScope handle_scope(isolate_);
437 Result stack_push = StackPush(object); 489 Result stack_push = StackPush(object);
438 if (stack_push != SUCCESS) return stack_push; 490 if (stack_push != SUCCESS) return stack_push;
439 491
440 if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER && 492 if (property_list_.is_null() &&
493 object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
441 object->HasFastProperties() && 494 object->HasFastProperties() &&
442 Handle<JSObject>::cast(object)->elements()->length() == 0) { 495 Handle<JSObject>::cast(object)->elements()->length() == 0) {
443 DCHECK(object->IsJSObject()); 496 DCHECK(object->IsJSObject());
444 DCHECK(!object->IsJSGlobalProxy()); 497 DCHECK(!object->IsJSGlobalProxy());
445 Handle<JSObject> js_obj = Handle<JSObject>::cast(object); 498 Handle<JSObject> js_obj = Handle<JSObject>::cast(object);
446 DCHECK(!js_obj->HasIndexedInterceptor()); 499 DCHECK(!js_obj->HasIndexedInterceptor());
447 DCHECK(!js_obj->HasNamedInterceptor()); 500 DCHECK(!js_obj->HasNamedInterceptor());
448 Handle<Map> map(js_obj->map()); 501 Handle<Map> map(js_obj->map());
449 builder_.AppendCharacter('{'); 502 builder_.AppendCharacter('{');
450 Indent(); 503 Indent();
(...skipping 29 matching lines...) Expand all
480 } else { 533 } else {
481 Result result = SerializeJSReceiverSlow(object); 534 Result result = SerializeJSReceiverSlow(object);
482 if (result != SUCCESS) return result; 535 if (result != SUCCESS) return result;
483 } 536 }
484 StackPop(); 537 StackPop();
485 return SUCCESS; 538 return SUCCESS;
486 } 539 }
487 540
488 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSReceiverSlow( 541 BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSReceiverSlow(
489 Handle<JSReceiver> object) { 542 Handle<JSReceiver> object) {
490 Handle<FixedArray> contents; 543 Handle<FixedArray> contents = property_list_;
491 ASSIGN_RETURN_ON_EXCEPTION_VALUE( 544 if (contents.is_null()) {
492 isolate_, contents, 545 ASSIGN_RETURN_ON_EXCEPTION_VALUE(
493 JSReceiver::GetKeys(object, OWN_ONLY, ENUMERABLE_STRINGS), EXCEPTION); 546 isolate_, contents,
547 JSReceiver::GetKeys(object, OWN_ONLY, ENUMERABLE_STRINGS), EXCEPTION);
548 }
494 549
495 builder_.AppendCharacter('{'); 550 builder_.AppendCharacter('{');
496 Indent(); 551 Indent();
497 bool comma = false; 552 bool comma = false;
498 for (int i = 0; i < contents->length(); i++) { 553 for (int i = 0; i < contents->length(); i++) {
499 Object* key = contents->get(i); 554 Object* key = contents->get(i);
500 Handle<String> key_handle; 555 Handle<String> key_handle;
501 MaybeHandle<Object> maybe_property; 556 MaybeHandle<Object> maybe_property;
502 if (key->IsString()) { 557 if (key->IsString()) {
503 key_handle = Handle<String>(String::cast(key), isolate_); 558 key_handle = Handle<String>(String::cast(key), isolate_);
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
649 if (object->IsOneByteRepresentationUnderneath()) { 704 if (object->IsOneByteRepresentationUnderneath()) {
650 SerializeString_<uint8_t, uc16>(object); 705 SerializeString_<uint8_t, uc16>(object);
651 } else { 706 } else {
652 SerializeString_<uc16, uc16>(object); 707 SerializeString_<uc16, uc16>(object);
653 } 708 }
654 } 709 }
655 } 710 }
656 711
657 } // namespace internal 712 } // namespace internal
658 } // namespace v8 713 } // namespace v8
OLDNEW
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698