Revision: 5916
Author: [email protected]
Date: Fri Dec 3 03:12:02 2010
Log: Simplify JSON stringify and add special case for default replacer and
space.
Review URL: http://codereview.chromium.org/5551002
http://code.google.com/p/v8/source/detail?r=5916
Modified:
/branches/bleeding_edge/src/json.js
/branches/bleeding_edge/src/runtime.cc
=======================================
--- /branches/bleeding_edge/src/json.js Wed Dec 1 02:04:34 2010
+++ /branches/bleeding_edge/src/json.js Fri Dec 3 03:12:02 2010
@@ -65,12 +65,6 @@
return unfiltered;
}
}
-
-function QuoteJSONString(str) {
- var quoted_str = %QuoteJSONString(str);
- if (IS_STRING(quoted_str)) return quoted_str;
- return '"' + str + '"';
-}
function StackContains(stack, val) {
var length = stack.length;
@@ -128,7 +122,7 @@
var p = replacer[i];
var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
if (!IS_UNDEFINED(strP)) {
- var member = QuoteJSONString(p) + ":";
+ var member = %QuoteJSONString(p) + ":";
if (gap != "") member += " ";
member += strP;
partial.push(member);
@@ -140,7 +134,7 @@
if (ObjectHasOwnProperty.call(value, p)) {
var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
if (!IS_UNDEFINED(strP)) {
- var member = QuoteJSONString(p) + ":";
+ var member = %QuoteJSONString(p) + ":";
if (gap != "") member += " ";
member += strP;
partial.push(member);
@@ -185,7 +179,7 @@
}
switch (typeof value) {
case "string":
- return QuoteJSONString(value);
+ return %QuoteJSONString(value);
case "object":
if (!value) {
return "null";
@@ -200,10 +194,77 @@
return value ? "true" : "false";
}
}
+
+function BasicSerializeArray(value, stack) {
+ if (StackContains(stack, value)) {
+ throw MakeTypeError('circular_structure', []);
+ }
+ stack.push(value);
+ var partial = [];
+ var len = value.length;
+ for (var i = 0; i < len; i++) {
+ var strP = BasicJSONSerialize($String(i), value, stack);
+ if (IS_UNDEFINED(strP)) strP = "null";
+ partial.push(strP);
+ }
+ stack.pop();
+ return "[" + partial.join() + "]";
+}
+
+function BasicSerializeObject(value, stack) {
+ if (StackContains(stack, value)) {
+ throw MakeTypeError('circular_structure', []);
+ }
+ stack.push(value);
+ var partial = [];
+ for (var p in value) {
+ if (ObjectHasOwnProperty.call(value, p)) {
+ var strP = BasicJSONSerialize(p, value, stack);
+ if (!IS_UNDEFINED(strP)) partial.push(%QuoteJSONString(p) + ":" +
strP);
+ }
+ }
+ stack.pop();
+ return "{" + partial.join() + "}";
+}
+
+function BasicJSONSerialize(key, holder, stack) {
+ var value = holder[key];
+ if (IS_OBJECT(value) && value) {
+ var toJSON = value.toJSON;
+ if (IS_FUNCTION(toJSON)) value = toJSON.call(value, key);
+ }
+ // Unwrap value if necessary
+ if (IS_OBJECT(value)) {
+ if (IS_NUMBER_WRAPPER(value)) {
+ value = $Number(value);
+ } else if (IS_STRING_WRAPPER(value)) {
+ value = $String(value);
+ } else if (IS_BOOLEAN_WRAPPER(value)) {
+ value = %_ValueOf(value);
+ }
+ }
+ switch (typeof value) {
+ case "string":
+ return %QuoteJSONString(value);
+ case "object":
+ if (!value) {
+ return "null";
+ } else if (IS_ARRAY(value)) {
+ return BasicSerializeArray(value, stack);
+ } else {
+ return BasicSerializeObject(value, stack);
+ }
+ case "number":
+ return $isFinite(value) ? $String(value) : "null";
+ case "boolean":
+ return value ? "true" : "false";
+ }
+}
function JSONStringify(value, replacer, space) {
- var stack = [];
- var indent = "";
+ if (IS_UNDEFINED(replacer) && IS_UNDEFINED(space)) {
+ return BasicJSONSerialize('', {'': value}, []);
+ }
if (IS_OBJECT(space)) {
// Unwrap 'space' if it is wrapped
if (IS_NUMBER_WRAPPER(space)) {
@@ -228,7 +289,7 @@
} else {
gap = "";
}
- return JSONSerialize('', {'': value}, replacer, stack, indent, gap);
+ return JSONSerialize('', {'': value}, replacer, [], "", gap);
}
function SetupJSON() {
=======================================
--- /branches/bleeding_edge/src/runtime.cc Wed Dec 1 05:11:28 2010
+++ /branches/bleeding_edge/src/runtime.cc Fri Dec 3 03:12:02 2010
@@ -4619,9 +4619,6 @@
quoted_length += JsonQuoteLengths[c];
}
}
- if (quoted_length == length) {
- return Heap::undefined_value();
- }
Counters::quote_json_char_count.Increment(length);
// Add space for quotes.
@@ -4641,17 +4638,22 @@
new_string->address() + SeqAsciiString::kHeaderSize);
*(write_cursor++) = '"';
const Char* read_cursor = characters.start();
- const Char* end = read_cursor + length;
- while (read_cursor < end) {
- Char c = *(read_cursor++);
- if (sizeof(Char) > 1u && static_cast<unsigned>(c) >=
kQuoteTableLength) {
- *(write_cursor++) = c;
- } else {
- const char* replacement = JsonQuotes[static_cast<unsigned>(c)];
- if (!replacement) {
+ if (quoted_length == length + 2) {
+ CopyChars(write_cursor, read_cursor, length);
+ write_cursor += length;
+ } else {
+ const Char* end = read_cursor + length;
+ while (read_cursor < end) {
+ Char c = *(read_cursor++);
+ if (sizeof(Char) > 1u && static_cast<unsigned>(c) >=
kQuoteTableLength) {
*(write_cursor++) = c;
} else {
- write_cursor = WriteString(write_cursor, replacement);
+ const char* replacement = JsonQuotes[static_cast<unsigned>(c)];
+ if (!replacement) {
+ *(write_cursor++) = c;
+ } else {
+ write_cursor = WriteString(write_cursor, replacement);
+ }
}
}
}
@@ -4680,6 +4682,7 @@
return QuoteJsonString<char, SeqAsciiString>(str->ToAsciiVector());
}
}
+
static MaybeObject* Runtime_StringParseInt(Arguments args) {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev