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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/json-stringifier.h ('k') | src/runtime/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/json-stringifier.cc
diff --git a/src/json-stringifier.cc b/src/json-stringifier.cc
index ac206822e9abc5b704c3aad1d8f09e18603c984a..79463f1d983b68016dfbb89e051720fc2b328b70 100644
--- a/src/json-stringifier.cc
+++ b/src/json-stringifier.cc
@@ -88,7 +88,9 @@ BasicJsonStringifier::BasicJsonStringifier(Isolate* isolate)
}
MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object,
+ Handle<Object> replacer,
Handle<Object> gap) {
+ if (!InitializeReplacer(replacer)) return MaybeHandle<Object>();
if (!gap->IsUndefined() && !InitializeGap(gap)) return MaybeHandle<Object>();
Result result = SerializeObject(object);
if (result == UNCHANGED) return factory()->undefined_value();
@@ -97,15 +99,64 @@ MaybeHandle<Object> BasicJsonStringifier::Stringify(Handle<Object> object,
return MaybeHandle<Object>();
}
+bool IsInList(Handle<String> key, List<Handle<String> >* list) {
+ // TODO(yangguo): This is O(n^2) for n properties in the list. Deal with this
+ // if this becomes an issue.
+ for (const Handle<String>& existing : *list) {
+ if (String::Equals(existing, key)) return true;
+ }
+ return false;
+}
+
+bool BasicJsonStringifier::InitializeReplacer(Handle<Object> replacer) {
+ DCHECK(property_list_.is_null());
+ Maybe<bool> is_array = Object::IsArray(replacer);
+ if (is_array.IsNothing()) return false;
+ if (is_array.FromJust()) {
+ HandleScope handle_scope(isolate_);
+ List<Handle<String> > list;
+ Handle<Object> length_obj;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, length_obj,
+ Object::GetLengthFromArrayLike(isolate_, replacer), false);
+ uint32_t length;
+ if (!length_obj->ToUint32(&length)) length = kMaxUInt32;
+ for (uint32_t i = 0; i < length; i++) {
+ Handle<Object> element;
+ Handle<String> key;
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, element, Object::GetElement(isolate_, replacer, i), false);
+ if (element->IsNumber() || element->IsString()) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, key, Object::ToString(isolate_, element), false);
+ } else if (element->IsJSValue()) {
+ Handle<Object> value(Handle<JSValue>::cast(element)->value(), isolate_);
+ if (value->IsNumber() || value->IsString()) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, key, Object::ToString(isolate_, element), false);
+ }
+ }
+ if (key.is_null()) continue;
+ if (!IsInList(key, &list)) list.Add(key);
+ }
+ property_list_ = factory()->NewUninitializedFixedArray(list.length());
+ for (int i = 0; i < list.length(); i++) {
+ property_list_->set(i, *list[i]);
+ }
+ property_list_ = handle_scope.CloseAndEscape(property_list_);
+ }
+ return true;
+}
+
bool BasicJsonStringifier::InitializeGap(Handle<Object> gap) {
DCHECK_NULL(gap_);
HandleScope scope(isolate_);
- if (gap->IsJSReceiver()) {
- Handle<String> class_name(Handle<JSReceiver>::cast(gap)->class_name());
- if (class_name.is_identical_to(factory()->String_string())) {
+ if (gap->IsJSValue()) {
+ Handle<Object> value(Handle<JSValue>::cast(gap)->value(), isolate_);
+ if (value->IsString()) {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap,
Object::ToString(isolate_, gap), false);
- } else if (class_name.is_identical_to(factory()->number_string())) {
+ } else if (value->IsNumber()) {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate_, gap, Object::ToNumber(gap),
false);
}
@@ -146,7 +197,8 @@ MaybeHandle<Object> BasicJsonStringifier::StringifyString(
if (worst_case_length > 32 * KB) { // Slow path if too large.
BasicJsonStringifier stringifier(isolate);
- return stringifier.Stringify(object, isolate->factory()->undefined_value());
+ Handle<Object> undefined = isolate->factory()->undefined_value();
+ return stringifier.Stringify(object, undefined, undefined);
}
object = String::Flatten(object);
@@ -437,7 +489,8 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
Result stack_push = StackPush(object);
if (stack_push != SUCCESS) return stack_push;
- if (object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
+ if (property_list_.is_null() &&
+ object->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
object->HasFastProperties() &&
Handle<JSObject>::cast(object)->elements()->length() == 0) {
DCHECK(object->IsJSObject());
@@ -487,10 +540,12 @@ BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSObject(
BasicJsonStringifier::Result BasicJsonStringifier::SerializeJSReceiverSlow(
Handle<JSReceiver> object) {
- Handle<FixedArray> contents;
- ASSIGN_RETURN_ON_EXCEPTION_VALUE(
- isolate_, contents,
- JSReceiver::GetKeys(object, OWN_ONLY, ENUMERABLE_STRINGS), EXCEPTION);
+ Handle<FixedArray> contents = property_list_;
+ if (contents.is_null()) {
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(
+ isolate_, contents,
+ JSReceiver::GetKeys(object, OWN_ONLY, ENUMERABLE_STRINGS), EXCEPTION);
+ }
builder_.AppendCharacter('{');
Indent();
« 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