| Index: src/json.js
|
| ===================================================================
|
| --- src/json.js (revision 6941)
|
| +++ src/json.js (working copy)
|
| @@ -27,11 +27,6 @@
|
|
|
| var $JSON = global.JSON;
|
|
|
| -function ParseJSONUnfiltered(text) {
|
| - var s = $String(text);
|
| - return %ParseJson(s);
|
| -}
|
| -
|
| function Revive(holder, name, reviver) {
|
| var val = holder[name];
|
| if (IS_OBJECT(val)) {
|
| @@ -58,7 +53,7 @@
|
| }
|
|
|
| function JSONParse(text, reviver) {
|
| - var unfiltered = ParseJSONUnfiltered(text);
|
| + var unfiltered = %ParseJson(TO_STRING_INLINE(text));
|
| if (IS_FUNCTION(reviver)) {
|
| return Revive({'': unfiltered}, '', reviver);
|
| } else {
|
| @@ -158,7 +153,7 @@
|
| if (IS_STRING(value)) {
|
| return %QuoteJSONString(value);
|
| } else if (IS_NUMBER(value)) {
|
| - return $isFinite(value) ? $String(value) : "null";
|
| + return NUMBER_IS_FINITE(value) ? $String(value) : "null";
|
| } else if (IS_BOOLEAN(value)) {
|
| return value ? "true" : "false";
|
| } else if (IS_NULL(value)) {
|
| @@ -169,7 +164,7 @@
|
| return SerializeArray(value, replacer, stack, indent, gap);
|
| } else if (IS_NUMBER_WRAPPER(value)) {
|
| value = ToNumber(value);
|
| - return $isFinite(value) ? ToString(value) : "null";
|
| + return NUMBER_IS_FINITE(value) ? ToString(value) : "null";
|
| } else if (IS_STRING_WRAPPER(value)) {
|
| return %QuoteJSONString(ToString(value));
|
| } else if (IS_BOOLEAN_WRAPPER(value)) {
|
| @@ -184,24 +179,60 @@
|
|
|
|
|
| function BasicSerializeArray(value, stack, builder) {
|
| + var len = value.length;
|
| + if (len == 0) {
|
| + builder.push("[]");
|
| + return;
|
| + }
|
| if (!%PushIfAbsent(stack, value)) {
|
| throw MakeTypeError('circular_structure', []);
|
| }
|
| builder.push("[");
|
| - var len = value.length;
|
| - for (var i = 0; i < len; i++) {
|
| + var val = value[0];
|
| + if (IS_STRING(val)) {
|
| + // First entry is a string. Remaining entries are likely to be strings too.
|
| + builder.push(%QuoteJSONString(val));
|
| + for (var i = 1; i < len; i++) {
|
| + builder.push(",");
|
| + val = value[i];
|
| + if (IS_STRING(val)) {
|
| + builder.push(%QuoteJSONString(val));
|
| + } else {
|
| + var before = builder.length;
|
| + BasicJSONSerialize(i, value[i], stack, builder);
|
| + if (before == builder.length) builder.push("null");
|
| + }
|
| + }
|
| + } else if (IS_NUMBER(val)) {
|
| + // First entry is a number. Remaining entries are likely to be numbers too.
|
| + builder.push(NUMBER_IS_FINITE(val) ? %_NumberToString(val) : "null");
|
| + for (var i = 1; i < len; i++) {
|
| + builder.push(",");
|
| + val = value[i];
|
| + if (IS_NUMBER(val)) {
|
| + builder.push(NUMBER_IS_FINITE(val)
|
| + ? %_NumberToString(val)
|
| + : "null");
|
| + } else {
|
| + var before = builder.length;
|
| + BasicJSONSerialize(i, value[i], stack, builder);
|
| + if (before == builder.length) builder.push("null");
|
| + }
|
| + }
|
| + } else {
|
| var before = builder.length;
|
| - BasicJSONSerialize(i, value, stack, builder);
|
| + BasicJSONSerialize(0, val, stack, builder);
|
| if (before == builder.length) builder.push("null");
|
| - builder.push(",");
|
| + for (var i = 1; i < len; i++) {
|
| + builder.push(",");
|
| + before = builder.length;
|
| + val = value[i];
|
| + BasicJSONSerialize(i, val, stack, builder);
|
| + if (before == builder.length) builder.push("null");
|
| + }
|
| }
|
| stack.pop();
|
| - if (builder.pop() != ",") {
|
| - builder.push("[]"); // Zero length array. Push "[" back on.
|
| - } else {
|
| - builder.push("]");
|
| - }
|
| -
|
| + builder.push("]");
|
| }
|
|
|
|
|
| @@ -215,7 +246,7 @@
|
| builder.push(%QuoteJSONString(p));
|
| builder.push(":");
|
| var before = builder.length;
|
| - BasicJSONSerialize(p, value, stack, builder);
|
| + BasicJSONSerialize(p, value[p], stack, builder);
|
| if (before == builder.length) {
|
| builder.pop();
|
| builder.pop();
|
| @@ -233,8 +264,7 @@
|
| }
|
|
|
|
|
| -function BasicJSONSerialize(key, holder, stack, builder) {
|
| - var value = holder[key];
|
| +function BasicJSONSerialize(key, value, stack, builder) {
|
| if (IS_SPEC_OBJECT(value)) {
|
| var toJSON = value.toJSON;
|
| if (IS_FUNCTION(toJSON)) {
|
| @@ -244,7 +274,7 @@
|
| if (IS_STRING(value)) {
|
| builder.push(%QuoteJSONString(value));
|
| } else if (IS_NUMBER(value)) {
|
| - builder.push(($isFinite(value) ? %_NumberToString(value) : "null"));
|
| + builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
|
| } else if (IS_BOOLEAN(value)) {
|
| builder.push(value ? "true" : "false");
|
| } else if (IS_NULL(value)) {
|
| @@ -254,7 +284,7 @@
|
| // Unwrap value if necessary
|
| if (IS_NUMBER_WRAPPER(value)) {
|
| value = ToNumber(value);
|
| - builder.push(($isFinite(value) ? %_NumberToString(value) : "null"));
|
| + builder.push(NUMBER_IS_FINITE(value) ? %_NumberToString(value) : "null");
|
| } else if (IS_STRING_WRAPPER(value)) {
|
| builder.push(%QuoteJSONString(ToString(value)));
|
| } else if (IS_BOOLEAN_WRAPPER(value)) {
|
| @@ -271,7 +301,7 @@
|
| function JSONStringify(value, replacer, space) {
|
| if (%_ArgumentsLength() == 1) {
|
| var builder = [];
|
| - BasicJSONSerialize('', {'': value}, [], builder);
|
| + BasicJSONSerialize('', value, [], builder);
|
| if (builder.length == 0) return;
|
| var result = %_FastAsciiArrayJoin(builder, "");
|
| if (!IS_UNDEFINED(result)) return result;
|
|
|