| Index: src/js/json.js
|
| diff --git a/src/js/json.js b/src/js/json.js
|
| index d42b8c794a77887d4991b7a2686bd4d246f3adac..b2f5b4acec6df494165b504978d1de418af9c44b 100644
|
| --- a/src/js/json.js
|
| +++ b/src/js/json.js
|
| @@ -12,6 +12,7 @@
|
| // Imports
|
|
|
| var GlobalJSON = global.JSON;
|
| +var GlobalSet = global.Set;
|
| var InternalArray = utils.InternalArray;
|
| var MakeTypeError;
|
| var MaxSimple;
|
| @@ -30,27 +31,33 @@ utils.Import(function(from) {
|
|
|
| // -------------------------------------------------------------------
|
|
|
| +function CreateDataProperty(o, p, v) {
|
| + var desc = {value: v, enumerable: true, writable: true, configurable: true};
|
| + return %reflect_define_property(o, p, desc);
|
| +}
|
| +
|
| +
|
| function InternalizeJSONProperty(holder, name, reviver) {
|
| var val = holder[name];
|
| - if (IS_OBJECT(val) && val !== null) {
|
| - if (IS_ARRAY(val)) {
|
| - var length = val.length;
|
| + if (IS_SPEC_OBJECT(val)) {
|
| + if (%is_arraylike(val)) {
|
| + var length = TO_LENGTH(val.length);
|
| for (var i = 0; i < length; i++) {
|
| var newElement =
|
| InternalizeJSONProperty(val, %_NumberToString(i), reviver);
|
| if (IS_UNDEFINED(newElement)) {
|
| - delete val[i];
|
| + %reflect_delete_property(val, i);
|
| } else {
|
| - val[i] = newElement;
|
| + CreateDataProperty(val, i, newElement);
|
| }
|
| }
|
| } else {
|
| for (var p of ObjectKeys(val)) {
|
| var newElement = InternalizeJSONProperty(val, p, reviver);
|
| if (IS_UNDEFINED(newElement)) {
|
| - delete val[p];
|
| + %reflect_delete_property(val, p);
|
| } else {
|
| - val[p] = newElement;
|
| + CreateDataProperty(val, p, newElement);
|
| }
|
| }
|
| }
|
| @@ -74,7 +81,7 @@ function SerializeArray(value, replacer, stack, indent, gap) {
|
| var stepback = indent;
|
| indent += gap;
|
| var partial = new InternalArray();
|
| - var len = value.length;
|
| + var len = TO_LENGTH(value.length);
|
| for (var i = 0; i < len; i++) {
|
| var strP = JSONSerialize(%_NumberToString(i), value, replacer, stack,
|
| indent, gap);
|
| @@ -106,27 +113,23 @@ function SerializeObject(value, replacer, stack, indent, gap) {
|
| if (IS_ARRAY(replacer)) {
|
| var length = replacer.length;
|
| for (var i = 0; i < length; i++) {
|
| - if (HAS_OWN_PROPERTY(replacer, i)) {
|
| - var p = replacer[i];
|
| - var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
|
| - if (!IS_UNDEFINED(strP)) {
|
| - var member = %QuoteJSONString(p) + ":";
|
| - if (gap != "") member += " ";
|
| - member += strP;
|
| - partial.push(member);
|
| - }
|
| + var p = replacer[i];
|
| + var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
|
| + if (!IS_UNDEFINED(strP)) {
|
| + var member = %QuoteJSONString(p) + ":";
|
| + if (gap != "") member += " ";
|
| + member += strP;
|
| + partial.push(member);
|
| }
|
| }
|
| } else {
|
| - for (var p in value) {
|
| - if (HAS_OWN_PROPERTY(value, p)) {
|
| - var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
|
| - if (!IS_UNDEFINED(strP)) {
|
| - var member = %QuoteJSONString(p) + ":";
|
| - if (gap != "") member += " ";
|
| - member += strP;
|
| - partial.push(member);
|
| - }
|
| + for (var p of ObjectKeys(value)) {
|
| + var strP = JSONSerialize(p, value, replacer, stack, indent, gap);
|
| + if (!IS_UNDEFINED(strP)) {
|
| + var member = %QuoteJSONString(p) + ":";
|
| + if (gap != "") member += " ";
|
| + member += strP;
|
| + partial.push(member);
|
| }
|
| }
|
| }
|
| @@ -166,7 +169,7 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
|
| return "null";
|
| } else if (IS_SPEC_OBJECT(value) && !IS_CALLABLE(value)) {
|
| // Non-callable object. If it's a primitive wrapper, it must be unwrapped.
|
| - if (IS_ARRAY(value)) {
|
| + if (%is_arraylike(value)) {
|
| return SerializeArray(value, replacer, stack, indent, gap);
|
| } else if (IS_NUMBER_WRAPPER(value)) {
|
| value = TO_NUMBER(value);
|
| @@ -185,14 +188,13 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
|
|
|
|
|
| function JSONStringify(value, replacer, space) {
|
| - if (%_ArgumentsLength() == 1) {
|
| + if (%_ArgumentsLength() == 1 && !%_IsJSProxy(value)) {
|
| return %BasicJSONStringify(value);
|
| }
|
| - if (IS_ARRAY(replacer)) {
|
| - // Deduplicate replacer array items.
|
| + if (!IS_CALLABLE(replacer) && %is_arraylike(replacer)) {
|
| var property_list = new InternalArray();
|
| - var seen_properties = { __proto__: null };
|
| - var length = replacer.length;
|
| + var seen_properties = new GlobalSet();
|
| + var length = TO_LENGTH(replacer.length);
|
| for (var i = 0; i < length; i++) {
|
| var v = replacer[i];
|
| var item;
|
| @@ -205,9 +207,9 @@ function JSONStringify(value, replacer, space) {
|
| } else {
|
| continue;
|
| }
|
| - if (!seen_properties[item]) {
|
| + if (!seen_properties.has(item)) {
|
| property_list.push(item);
|
| - seen_properties[item] = true;
|
| + seen_properties.add(item);
|
| }
|
| }
|
| replacer = property_list;
|
|
|