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

Unified Diff: src/json-stringifier.h

Issue 11369004: Correctly handle proxies in JSON.stringify. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 2 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.js ('k') | src/runtime.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/json-stringifier.h
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 1b4ab9a0faa9f8a9e803c85575f994359dadc4da..20793fd46cae922bc8e7969c95efa37b71eb85d0 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -48,7 +48,7 @@ class BasicJsonStringifier BASE_EMBEDDED {
enum Result { UNCHANGED, SUCCESS, EXCEPTION, CIRCULAR, STACK_OVERFLOW };
- template <bool is_ascii> void Extend();
+ void Extend();
void ChangeEncoding();
@@ -82,6 +82,11 @@ class BasicJsonStringifier BASE_EMBEDDED {
Handle<Object> ApplyToJsonFunction(Handle<Object> object,
Handle<Object> key);
+ Result SerializeGeneric(Handle<Object> object,
+ Handle<Object> key,
+ bool deferred_comma,
+ bool deferred_key);
+
// Entry point to serialize the object.
INLINE(Result SerializeObject(Handle<Object> obj)) {
return Serialize_<false>(obj, false, isolate_->factory()->empty_string());
@@ -246,7 +251,7 @@ void BasicJsonStringifier::Append_(Char c) {
SeqTwoByteString::cast(*current_part_)->SeqTwoByteStringSet(
current_index_++, c);
}
- if (current_index_ == part_length_) Extend<is_ascii>();
+ if (current_index_ == part_length_) Extend();
}
@@ -338,47 +343,84 @@ BasicJsonStringifier::Result BasicJsonStringifier::Serialize_(
if (object.is_null()) return EXCEPTION;
}
- if (object->IsJSObject()) {
- if (object->IsJSFunction()) return UNCHANGED;
+ if (object->IsSmi()) {
if (deferred_string_key) SerializeDeferredKey(comma, key);
- if (object->IsJSArray()) {
- return SerializeJSArray(Handle<JSArray>::cast(object));
- } else if (object->IsJSValue()) {
- return SerializeJSValue(Handle<JSValue>::cast(object));
- } else {
- return SerializeJSObject(Handle<JSObject>::cast(object));
- }
+ return SerializeSmi(Smi::cast(*object));
}
- // Handle non-JSObject.
- if (object->IsString()) {
- if (deferred_string_key) SerializeDeferredKey(comma, key);
- SerializeString(Handle<String>::cast(object));
- return SUCCESS;
- } else if (object->IsSmi()) {
- if (deferred_string_key) SerializeDeferredKey(comma, key);
- return SerializeSmi(Smi::cast(*object));
- } else if (object->IsHeapNumber()) {
- if (deferred_string_key) SerializeDeferredKey(comma, key);
- return SerializeHeapNumber(Handle<HeapNumber>::cast(object));
- } else if (object->IsOddball()) {
- switch (Oddball::cast(*object)->kind()) {
- case Oddball::kFalse:
- if (deferred_string_key) SerializeDeferredKey(comma, key);
- Append("false");
- return SUCCESS;
- case Oddball::kTrue:
+ switch (HeapObject::cast(*object)->map()->instance_type()) {
+ case HEAP_NUMBER_TYPE:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ return SerializeHeapNumber(Handle<HeapNumber>::cast(object));
+ case ODDBALL_TYPE:
+ switch (Oddball::cast(*object)->kind()) {
+ case Oddball::kFalse:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ Append("false");
+ return SUCCESS;
+ case Oddball::kTrue:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ Append("true");
+ return SUCCESS;
+ case Oddball::kNull:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ Append("null");
+ return SUCCESS;
+ default:
+ return UNCHANGED;
+ }
+ case JS_ARRAY_TYPE:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ return SerializeJSArray(Handle<JSArray>::cast(object));
+ case JS_VALUE_TYPE:
+ if (deferred_string_key) SerializeDeferredKey(comma, key);
+ return SerializeJSValue(Handle<JSValue>::cast(object));
+ case JS_FUNCTION_TYPE:
+ return UNCHANGED;
+ default:
+ if (object->IsString()) {
if (deferred_string_key) SerializeDeferredKey(comma, key);
- Append("true");
+ SerializeString(Handle<String>::cast(object));
return SUCCESS;
- case Oddball::kNull:
+ } else if (object->IsJSObject()) {
if (deferred_string_key) SerializeDeferredKey(comma, key);
- Append("null");
- return SUCCESS;
- }
+ return SerializeJSObject(Handle<JSObject>::cast(object));
+ } else {
+ return SerializeGeneric(object, key, comma, deferred_string_key);
+ }
}
+}
+
- return UNCHANGED;
+BasicJsonStringifier::Result BasicJsonStringifier::SerializeGeneric(
+ Handle<Object> object,
+ Handle<Object> key,
+ bool deferred_comma,
+ bool deferred_key) {
+ Handle<JSObject> builtins(isolate_->native_context()->builtins());
+ Handle<JSFunction> builtin = Handle<JSFunction>::cast(
+ v8::internal::GetProperty(builtins, "JSONSerializeAdapter"));
+
+ Handle<Object> argv[] = { key, object };
+ bool has_exception = false;
+ Handle<Object> result =
+ Execution::Call(builtin, object, 2, argv, &has_exception);
+ if (has_exception) return EXCEPTION;
+ if (result->IsUndefined()) return UNCHANGED;
+ if (deferred_key) {
+ if (key->IsSmi()) key = isolate_->factory()->NumberToString(key);
+ SerializeDeferredKey(deferred_comma, key);
+ }
+
+ Handle<String> result_string = Handle<String>::cast(result);
+ // Shrink current part, attach it to the accumulator, also attach the result
+ // string to the accumulator, and allocate a new part.
+ ShrinkCurrentPart(); // Shrink.
+ part_length_ = kInitialPartLength; // Allocate conservatively.
+ Extend(); // Attach current part and allocate new part.
+ set_accumulator( // Attach result string to the accumulator.
+ isolate_->factory()->NewConsString(accumulator(), result_string));
+ return SUCCESS;
}
@@ -580,14 +622,13 @@ void BasicJsonStringifier::ShrinkCurrentPart() {
}
-template <bool is_ascii>
void BasicJsonStringifier::Extend() {
set_accumulator(
isolate_->factory()->NewConsString(accumulator(), current_part_));
if (part_length_ <= kMaxPartLength / kPartLengthGrowthFactor) {
part_length_ *= kPartLengthGrowthFactor;
}
- if (is_ascii) {
+ if (is_ascii_) {
current_part_ =
isolate_->factory()->NewRawAsciiString(part_length_);
} else {
« no previous file with comments | « src/json.js ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698