From 209eb1c2190bdbb8fd527eafaae8c2d20d230a21 Mon Sep 17 00:00:00 2001 From: "sandholm@chromium.org" Date: Mon, 6 Dec 2010 15:41:07 +0000 Subject: [PATCH] Improved JSON stringify. Review URL: http://codereview.chromium.org/5578004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@5919 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/array.js | 5 ++++- src/json.js | 9 +++++---- test/mjsunit/json.js | 6 ++++++ 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/src/array.js b/src/array.js index 5ecf5e3..c5ff505 100644 --- a/src/array.js +++ b/src/array.js @@ -148,6 +148,9 @@ function Join(array, length, separator, convert) { } } } + elements.length = elements_length; + var result = %_FastAsciiArrayJoin(elements, ""); + if (!IS_UNDEFINED(result)) return result; return %StringBuilderConcat(elements, elements_length, ''); } finally { // Make sure to pop the visited array no matter what happens. @@ -366,7 +369,7 @@ function ArrayJoin(separator) { } var result = %_FastAsciiArrayJoin(this, separator); - if (typeof result != "undefined") return result; + if (!IS_UNDEFINED(result)) return result; var length = TO_UINT32(this.length); return Join(this, length, separator, ConvertToString); diff --git a/src/json.js b/src/json.js index 31ec2b6..e8b732a 100644 --- a/src/json.js +++ b/src/json.js @@ -205,7 +205,7 @@ function BasicSerializeArray(value, stack, builder) { var len = value.length; for (var i = 0; i < len; i++) { var before = builder.length; - BasicJSONSerialize($String(i), value, stack, builder); + BasicJSONSerialize(i, value, stack, builder); if (before == builder.length) builder.push("null"); builder.push(","); } @@ -226,8 +226,9 @@ function BasicSerializeObject(value, stack, builder) { stack.push(value); builder.push("{"); for (var p in value) { - if (ObjectHasOwnProperty.call(value, p)) { - builder.push(%QuoteJSONString(p), ":"); + if (%HasLocalProperty(value, p)) { + builder.push(%QuoteJSONString(p)); + builder.push(":"); var before = builder.length; BasicJSONSerialize(p, value, stack, builder); if (before == builder.length) { @@ -251,7 +252,7 @@ function BasicJSONSerialize(key, holder, stack, builder) { var value = holder[key]; if (IS_OBJECT(value) && value) { var toJSON = value.toJSON; - if (IS_FUNCTION(toJSON)) value = toJSON.call(value, key); + if (IS_FUNCTION(toJSON)) value = toJSON.call(value, $String(key)); } if (IS_STRING(value)) { builder.push(%QuoteJSONString(value)); diff --git a/test/mjsunit/json.js b/test/mjsunit/json.js index 5353d6c..1c55959 100644 --- a/test/mjsunit/json.js +++ b/test/mjsunit/json.js @@ -278,6 +278,12 @@ assertEquals('{\n "a": "b",\n "c": "d"\n}', JSON.stringify({a:"b",c:"d"}, null, 1)); assertEquals('{"y":6,"x":5}', JSON.stringify({x:5,y:6}, ['y', 'x'])); +// toJSON get string keys. +var checker = {}; +var array = [checker]; +checker.toJSON = function(key) { return 1 + key; }; +assertEquals('["10"]', JSON.stringify(array)); + // The gap is capped at ten characters if specified as string. assertEquals('{\n "a": "b",\n "c": "d"\n}', JSON.stringify({a:"b",c:"d"}, null, -- 2.7.4