src/jdk/nashorn/internal/runtime/JSONFunctions.java

Print this page

        

@@ -34,10 +34,12 @@
 import jdk.nashorn.internal.ir.PropertyNode;
 import jdk.nashorn.internal.ir.UnaryNode;
 import jdk.nashorn.internal.parser.JSONParser;
 import jdk.nashorn.internal.parser.TokenType;
 import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
 
 /**
  * Utilities used by "JSON" object implementation.
  */
 public final class JSONFunctions {

@@ -92,11 +94,11 @@
     // apply 'reviver' function if available
     private static Object applyReviver(final ScriptObject global, final Object unfiltered, final Object reviver) {
         if (reviver instanceof ScriptFunction) {
             assert global instanceof GlobalObject;
             final ScriptObject root = ((GlobalObject)global).newObject();
-            root.set("", unfiltered, root.isStrictContext());
+            root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
             return walk(root, "", (ScriptFunction)reviver);
         }
         return unfiltered;
     }
 

@@ -113,11 +115,11 @@
                 final Object newElement = walk(valueObj, key, reviver);
 
                 if (newElement == ScriptRuntime.UNDEFINED) {
                     valueObj.delete(key, strict);
                 } else {
-                    valueObj.set(key, newElement, strict);
+                    setPropertyValue(valueObj, key, newElement, strict);
                 }
             }
         }
 
         try {

@@ -173,11 +175,13 @@
 
             for (final Node elem : elements) {
                 final PropertyNode pNode     = (PropertyNode) elem;
                 final Node         valueNode = pNode.getValue();
 
-                object.set(pNode.getKeyName(), convertNode(global, valueNode), strict);
+                final String name = pNode.getKeyName();
+                final Object value = convertNode(global, valueNode);
+                setPropertyValue(object, name, value, strict);
             }
 
             return object;
         } else if (node instanceof UnaryNode) {
             // UnaryNode used only to represent negative number JSON value

@@ -186,10 +190,25 @@
         } else {
             return null;
         }
     }
 
+    // add a new property if does not exist already, or else set old property
+    private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
+        final int index = getArrayIndexNoThrow(name);
+        if (isValidArrayIndex(index)) {
+            // array index key
+            sobj.defineOwnProperty(index, value);
+        } else if (sobj.getMap().findProperty(name) != null) {
+            // pre-existing non-inherited property, call set
+            sobj.set(name, value, strict);
+        } else {
+            // add new property
+            sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
+        }
+    }
+
     // does the given IR node represent a numeric array?
     private static boolean isNumericArray(final Node[] values) {
         for (final Node node : values) {
             if (node instanceof LiteralNode && ((LiteralNode<?>)node).getValue() instanceof Number) {
                 continue;