1.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Oct 18 12:50:21 2013 +0200 1.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Fri Oct 18 22:42:41 2013 +0200 1.3 @@ -508,7 +508,7 @@ 1.4 if (property == null) { 1.5 // promoting an arrayData value to actual property 1.6 addOwnProperty(key, propFlags, value); 1.7 - removeArraySlot(key); 1.8 + checkIntegerKey(key); 1.9 } else { 1.10 // Now set the new flags 1.11 modifyOwnProperty(property, propFlags); 1.12 @@ -616,15 +616,6 @@ 1.13 } 1.14 } 1.15 1.16 - private void removeArraySlot(final String key) { 1.17 - final int index = getArrayIndex(key); 1.18 - final ArrayData array = getArray(); 1.19 - 1.20 - if (array.has(index)) { 1.21 - setArray(array.delete(index)); 1.22 - } 1.23 - } 1.24 - 1.25 /** 1.26 * Add a new property to the object. 1.27 * 1.28 @@ -1203,21 +1194,10 @@ 1.29 * Check if this ScriptObject has array entries. This means that someone has 1.30 * set values with numeric keys in the object. 1.31 * 1.32 - * Note: this can be O(n) up to the array length 1.33 - * 1.34 * @return true if array entries exists. 1.35 */ 1.36 public boolean hasArrayEntries() { 1.37 - final ArrayData array = getArray(); 1.38 - final long length = array.length(); 1.39 - 1.40 - for (long i = 0; i < length; i++) { 1.41 - if (array.has((int)i)) { 1.42 - return true; 1.43 - } 1.44 - } 1.45 - 1.46 - return false; 1.47 + return getArray().length() > 0 || getMap().containsArrayKeys(); 1.48 } 1.49 1.50 /** 1.51 @@ -2356,8 +2336,29 @@ 1.52 } 1.53 1.54 if (newLength < arrayLength) { 1.55 - setArray(getArray().shrink(newLength)); 1.56 - getArray().setLength(newLength); 1.57 + long actualLength = newLength; 1.58 + 1.59 + // Check for numeric keys in property map and delete them or adjust length, depending on whether 1.60 + // they're defined as configurable. See ES5 #15.4.5.2 1.61 + if (getMap().containsArrayKeys()) { 1.62 + 1.63 + for (long l = arrayLength - 1; l >= newLength; l--) { 1.64 + final FindProperty find = findProperty(JSType.toString(l), false); 1.65 + 1.66 + if (find != null) { 1.67 + 1.68 + if (find.getProperty().isConfigurable()) { 1.69 + deleteOwnProperty(find.getProperty()); 1.70 + } else { 1.71 + actualLength = l + 1; 1.72 + break; 1.73 + } 1.74 + } 1.75 + } 1.76 + } 1.77 + 1.78 + setArray(getArray().shrink(actualLength)); 1.79 + getArray().setLength(actualLength); 1.80 } 1.81 } 1.82 1.83 @@ -2680,7 +2681,7 @@ 1.84 final long oldLength = getArray().length(); 1.85 final long longIndex = index & JSType.MAX_UINT; 1.86 1.87 - if (!getArray().has(index)) { 1.88 + if (getMap().containsArrayKeys()) { 1.89 final String key = JSType.toString(longIndex); 1.90 final FindProperty find = findProperty(key, true); 1.91