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; |