| 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 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 if (!gap->IsUndefined(isolate_) && !InitializeGap(gap)) { | 94 if (!gap->IsUndefined(isolate_) && !InitializeGap(gap)) { |
| 95 return MaybeHandle<Object>(); | 95 return MaybeHandle<Object>(); |
| 96 } | 96 } |
| 97 Result result = SerializeObject(object); | 97 Result result = SerializeObject(object); |
| 98 if (result == UNCHANGED) return factory()->undefined_value(); | 98 if (result == UNCHANGED) return factory()->undefined_value(); |
| 99 if (result == SUCCESS) return builder_.Finish(); | 99 if (result == SUCCESS) return builder_.Finish(); |
| 100 DCHECK(result == EXCEPTION); | 100 DCHECK(result == EXCEPTION); |
| 101 return MaybeHandle<Object>(); | 101 return MaybeHandle<Object>(); |
| 102 } | 102 } |
| 103 | 103 |
| 104 bool IsInList(Handle<String> key, List<Handle<String> >* list) { | |
| 105 // TODO(yangguo): This is O(n^2) for n properties in the list. Deal with this | |
| 106 // if this becomes an issue. | |
| 107 for (const Handle<String>& existing : *list) { | |
| 108 if (String::Equals(existing, key)) return true; | |
| 109 } | |
| 110 return false; | |
| 111 } | |
| 112 | |
| 113 bool JsonStringifier::InitializeReplacer(Handle<Object> replacer) { | 104 bool JsonStringifier::InitializeReplacer(Handle<Object> replacer) { |
| 114 DCHECK(property_list_.is_null()); | 105 DCHECK(property_list_.is_null()); |
| 115 DCHECK(replacer_function_.is_null()); | 106 DCHECK(replacer_function_.is_null()); |
| 116 Maybe<bool> is_array = Object::IsArray(replacer); | 107 Maybe<bool> is_array = Object::IsArray(replacer); |
| 117 if (is_array.IsNothing()) return false; | 108 if (is_array.IsNothing()) return false; |
| 118 if (is_array.FromJust()) { | 109 if (is_array.FromJust()) { |
| 119 HandleScope handle_scope(isolate_); | 110 HandleScope handle_scope(isolate_); |
| 120 List<Handle<String> > list; | 111 Handle<OrderedHashSet> set = factory()->NewOrderedHashSet(); |
| 121 Handle<Object> length_obj; | 112 Handle<Object> length_obj; |
| 122 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 113 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 123 isolate_, length_obj, | 114 isolate_, length_obj, |
| 124 Object::GetLengthFromArrayLike(isolate_, replacer), false); | 115 Object::GetLengthFromArrayLike(isolate_, replacer), false); |
| 125 uint32_t length; | 116 uint32_t length; |
| 126 if (!length_obj->ToUint32(&length)) length = kMaxUInt32; | 117 if (!length_obj->ToUint32(&length)) length = kMaxUInt32; |
| 127 for (uint32_t i = 0; i < length; i++) { | 118 for (uint32_t i = 0; i < length; i++) { |
| 128 Handle<Object> element; | 119 Handle<Object> element; |
| 129 Handle<String> key; | 120 Handle<String> key; |
| 130 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 121 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 131 isolate_, element, Object::GetElement(isolate_, replacer, i), false); | 122 isolate_, element, Object::GetElement(isolate_, replacer, i), false); |
| 132 if (element->IsNumber() || element->IsString()) { | 123 if (element->IsNumber() || element->IsString()) { |
| 133 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 124 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 134 isolate_, key, Object::ToString(isolate_, element), false); | 125 isolate_, key, Object::ToString(isolate_, element), false); |
| 135 } else if (element->IsJSValue()) { | 126 } else if (element->IsJSValue()) { |
| 136 Handle<Object> value(Handle<JSValue>::cast(element)->value(), isolate_); | 127 Handle<Object> value(Handle<JSValue>::cast(element)->value(), isolate_); |
| 137 if (value->IsNumber() || value->IsString()) { | 128 if (value->IsNumber() || value->IsString()) { |
| 138 ASSIGN_RETURN_ON_EXCEPTION_VALUE( | 129 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 139 isolate_, key, Object::ToString(isolate_, element), false); | 130 isolate_, key, Object::ToString(isolate_, element), false); |
| 140 } | 131 } |
| 141 } | 132 } |
| 142 if (key.is_null()) continue; | 133 if (key.is_null()) continue; |
| 143 if (!IsInList(key, &list)) list.Add(key); | 134 // Object keys are internalized, so do it here. |
| 135 key = factory()->InternalizeString(key); |
| 136 set = OrderedHashSet::Add(set, key); |
| 144 } | 137 } |
| 145 property_list_ = factory()->NewUninitializedFixedArray(list.length()); | 138 property_list_ = OrderedHashSet::ConvertToKeysArray( |
| 146 for (int i = 0; i < list.length(); i++) { | 139 set, GetKeysConversion::kKeepNumbers); |
| 147 property_list_->set(i, *list[i]); | |
| 148 } | |
| 149 property_list_ = handle_scope.CloseAndEscape(property_list_); | 140 property_list_ = handle_scope.CloseAndEscape(property_list_); |
| 150 } else if (replacer->IsCallable()) { | 141 } else if (replacer->IsCallable()) { |
| 151 replacer_function_ = Handle<JSReceiver>::cast(replacer); | 142 replacer_function_ = Handle<JSReceiver>::cast(replacer); |
| 152 } | 143 } |
| 153 return true; | 144 return true; |
| 154 } | 145 } |
| 155 | 146 |
| 156 bool JsonStringifier::InitializeGap(Handle<Object> gap) { | 147 bool JsonStringifier::InitializeGap(Handle<Object> gap) { |
| 157 DCHECK_NULL(gap_); | 148 DCHECK_NULL(gap_); |
| 158 HandleScope scope(isolate_); | 149 HandleScope scope(isolate_); |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 713 if (object->IsOneByteRepresentationUnderneath()) { | 704 if (object->IsOneByteRepresentationUnderneath()) { |
| 714 SerializeString_<uint8_t, uc16>(object); | 705 SerializeString_<uint8_t, uc16>(object); |
| 715 } else { | 706 } else { |
| 716 SerializeString_<uc16, uc16>(object); | 707 SerializeString_<uc16, uc16>(object); |
| 717 } | 708 } |
| 718 } | 709 } |
| 719 } | 710 } |
| 720 | 711 |
| 721 } // namespace internal | 712 } // namespace internal |
| 722 } // namespace v8 | 713 } // namespace v8 |
| OLD | NEW |