Thu, 13 Jun 2013 16:08:35 +0530
8015355: Array.prototype functions don't honour non-writable length and / or index properties
Reviewed-by: lagergren, hannesw
1.1 --- a/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java Wed Jun 12 16:41:38 2013 +0200 1.2 +++ b/src/jdk/nashorn/internal/objects/AccessorPropertyDescriptor.java Thu Jun 13 16:08:35 2013 +0530 1.3 @@ -138,18 +138,16 @@ 1.4 1.5 @Override 1.6 public PropertyDescriptor fillFrom(final ScriptObject sobj) { 1.7 - final boolean strict = isStrictContext(); 1.8 - 1.9 if (sobj.has(CONFIGURABLE)) { 1.10 this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE)); 1.11 } else { 1.12 - delete(CONFIGURABLE, strict); 1.13 + delete(CONFIGURABLE, false); 1.14 } 1.15 1.16 if (sobj.has(ENUMERABLE)) { 1.17 this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE)); 1.18 } else { 1.19 - delete(ENUMERABLE, strict); 1.20 + delete(ENUMERABLE, false); 1.21 } 1.22 1.23 if (sobj.has(GET)) { 1.24 @@ -160,7 +158,7 @@ 1.25 throw typeError("not.a.function", ScriptRuntime.safeToString(getter)); 1.26 } 1.27 } else { 1.28 - delete(GET, strict); 1.29 + delete(GET, false); 1.30 } 1.31 1.32 if (sobj.has(SET)) { 1.33 @@ -171,7 +169,7 @@ 1.34 throw typeError("not.a.function", ScriptRuntime.safeToString(setter)); 1.35 } 1.36 } else { 1.37 - delete(SET, strict); 1.38 + delete(SET, false); 1.39 } 1.40 1.41 return this;
2.1 --- a/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java Wed Jun 12 16:41:38 2013 +0200 2.2 +++ b/src/jdk/nashorn/internal/objects/DataPropertyDescriptor.java Thu Jun 13 16:08:35 2013 +0530 2.3 @@ -136,29 +136,28 @@ 2.4 2.5 @Override 2.6 public PropertyDescriptor fillFrom(final ScriptObject sobj) { 2.7 - final boolean strict = isStrictContext(); 2.8 if (sobj.has(CONFIGURABLE)) { 2.9 this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE)); 2.10 } else { 2.11 - delete(CONFIGURABLE, strict); 2.12 + delete(CONFIGURABLE, false); 2.13 } 2.14 2.15 if (sobj.has(ENUMERABLE)) { 2.16 this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE)); 2.17 } else { 2.18 - delete(ENUMERABLE, strict); 2.19 + delete(ENUMERABLE, false); 2.20 } 2.21 2.22 if (sobj.has(WRITABLE)) { 2.23 this.writable = JSType.toBoolean(sobj.get(WRITABLE)); 2.24 } else { 2.25 - delete(WRITABLE, strict); 2.26 + delete(WRITABLE, false); 2.27 } 2.28 2.29 if (sobj.has(VALUE)) { 2.30 this.value = sobj.get(VALUE); 2.31 } else { 2.32 - delete(VALUE, strict); 2.33 + delete(VALUE, false); 2.34 } 2.35 2.36 return this;
3.1 --- a/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Wed Jun 12 16:41:38 2013 +0200 3.2 +++ b/src/jdk/nashorn/internal/objects/GenericPropertyDescriptor.java Thu Jun 13 16:08:35 2013 +0530 3.3 @@ -124,17 +124,16 @@ 3.4 3.5 @Override 3.6 public PropertyDescriptor fillFrom(final ScriptObject sobj) { 3.7 - final boolean strict = isStrictContext(); 3.8 if (sobj.has(CONFIGURABLE)) { 3.9 this.configurable = JSType.toBoolean(sobj.get(CONFIGURABLE)); 3.10 } else { 3.11 - delete(CONFIGURABLE, strict); 3.12 + delete(CONFIGURABLE, false); 3.13 } 3.14 3.15 if (sobj.has(ENUMERABLE)) { 3.16 this.enumerable = JSType.toBoolean(sobj.get(ENUMERABLE)); 3.17 } else { 3.18 - delete(ENUMERABLE, strict); 3.19 + delete(ENUMERABLE, false); 3.20 } 3.21 3.22 return this;
4.1 --- a/src/jdk/nashorn/internal/objects/Global.java Wed Jun 12 16:41:38 2013 +0200 4.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Thu Jun 13 16:08:35 2013 +0530 4.3 @@ -430,15 +430,6 @@ 4.4 return instance().context; 4.5 } 4.6 4.7 - /** 4.8 - * Script access check for strict mode 4.9 - * 4.10 - * @return true if strict mode enabled in {@link Global#getThisContext()} 4.11 - */ 4.12 - static boolean isStrict() { 4.13 - return getEnv()._strict; 4.14 - } 4.15 - 4.16 // GlobalObject interface implementation 4.17 4.18 @Override 4.19 @@ -616,14 +607,12 @@ 4.20 public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) { 4.21 final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set); 4.22 4.23 - final boolean strict = context.getEnv()._strict; 4.24 - 4.25 if (get == null) { 4.26 - desc.delete(PropertyDescriptor.GET, strict); 4.27 + desc.delete(PropertyDescriptor.GET, false); 4.28 } 4.29 4.30 if (set == null) { 4.31 - desc.delete(PropertyDescriptor.SET, strict); 4.32 + desc.delete(PropertyDescriptor.SET, false); 4.33 } 4.34 4.35 return desc; 4.36 @@ -1485,7 +1474,6 @@ 4.37 // Error objects 4.38 this.builtinError = (ScriptFunction)initConstructor("Error"); 4.39 final ScriptObject errorProto = getErrorPrototype(); 4.40 - final boolean strict = Global.isStrict(); 4.41 4.42 // Nashorn specific accessors on Error.prototype - stack, lineNumber, columnNumber and fileName 4.43 final ScriptFunction getStack = ScriptFunctionImpl.makeFunction("getStack", NativeError.GET_STACK); 4.44 @@ -1503,10 +1491,10 @@ 4.45 4.46 // ECMA 15.11.4.2 Error.prototype.name 4.47 // Error.prototype.name = "Error"; 4.48 - errorProto.set(NativeError.NAME, "Error", strict); 4.49 + errorProto.set(NativeError.NAME, "Error", false); 4.50 // ECMA 15.11.4.3 Error.prototype.message 4.51 // Error.prototype.message = ""; 4.52 - errorProto.set(NativeError.MESSAGE, "", strict); 4.53 + errorProto.set(NativeError.MESSAGE, "", false); 4.54 4.55 this.builtinEvalError = initErrorSubtype("EvalError", errorProto); 4.56 this.builtinRangeError = initErrorSubtype("RangeError", errorProto); 4.57 @@ -1519,9 +1507,8 @@ 4.58 private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) { 4.59 final ScriptObject cons = initConstructor(name); 4.60 final ScriptObject prototype = ScriptFunction.getPrototype(cons); 4.61 - final boolean strict = Global.isStrict(); 4.62 - prototype.set(NativeError.NAME, name, strict); 4.63 - prototype.set(NativeError.MESSAGE, "", strict); 4.64 + prototype.set(NativeError.NAME, name, false); 4.65 + prototype.set(NativeError.MESSAGE, "", false); 4.66 prototype.setProto(errorProto); 4.67 return (ScriptFunction)cons; 4.68 } 4.69 @@ -1730,7 +1717,7 @@ 4.70 // <anon-function> 4.71 builtinFunction.setProto(anon); 4.72 builtinFunction.setPrototype(anon); 4.73 - anon.set("constructor", builtinFunction, anon.isStrict()); 4.74 + anon.set("constructor", builtinFunction, false); 4.75 anon.deleteOwnProperty(anon.getMap().findProperty("prototype")); 4.76 4.77 // now initialize Object
5.1 --- a/src/jdk/nashorn/internal/objects/NativeArray.java Wed Jun 12 16:41:38 2013 +0200 5.2 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Thu Jun 13 16:08:35 2013 +0530 5.3 @@ -118,7 +118,7 @@ 5.4 if (value == ScriptRuntime.EMPTY) { 5.5 arrayData = arrayData.delete(index); 5.6 } else { 5.7 - arrayData = arrayData.set(index, value, isStrictContext()); 5.8 + arrayData = arrayData.set(index, value, false); 5.9 } 5.10 } 5.11 5.12 @@ -158,6 +158,11 @@ 5.13 5.14 // Step 3 5.15 if ("length".equals(key)) { 5.16 + // check for length being made non-writable 5.17 + if (desc.has(WRITABLE) && !desc.isWritable()) { 5.18 + setIsLengthNotWritable(); 5.19 + } 5.20 + 5.21 // Step 3a 5.22 if (!desc.has(VALUE)) { 5.23 return super.defineOwnProperty("length", desc, reject); 5.24 @@ -603,7 +608,6 @@ 5.25 public static Object pop(final Object self) { 5.26 try { 5.27 final ScriptObject sobj = (ScriptObject)self; 5.28 - final boolean strict = sobj.isStrictContext(); 5.29 5.30 if (bulkable(sobj)) { 5.31 return sobj.getArray().pop(); 5.32 @@ -612,15 +616,15 @@ 5.33 final long len = JSType.toUint32(sobj.getLength()); 5.34 5.35 if (len == 0) { 5.36 - sobj.set("length", 0, strict); 5.37 + sobj.set("length", 0, true); 5.38 return ScriptRuntime.UNDEFINED; 5.39 } 5.40 5.41 final long index = len - 1; 5.42 final Object element = sobj.get(index); 5.43 5.44 - sobj.delete(index, strict); 5.45 - sobj.set("length", index, strict); 5.46 + sobj.delete(index, true); 5.47 + sobj.set("length", index, true); 5.48 5.49 return element; 5.50 } catch (final ClassCastException | NullPointerException e) { 5.51 @@ -639,11 +643,10 @@ 5.52 public static Object push(final Object self, final Object... args) { 5.53 try { 5.54 final ScriptObject sobj = (ScriptObject)self; 5.55 - final boolean strict = sobj.isStrictContext(); 5.56 5.57 if (bulkable(sobj)) { 5.58 if (sobj.getArray().length() + args.length <= JSType.MAX_UINT) { 5.59 - final ArrayData newData = sobj.getArray().push(sobj.isStrictContext(), args); 5.60 + final ArrayData newData = sobj.getArray().push(true, args); 5.61 sobj.setArray(newData); 5.62 return newData.length(); 5.63 } 5.64 @@ -652,9 +655,9 @@ 5.65 5.66 long len = JSType.toUint32(sobj.getLength()); 5.67 for (final Object element : args) { 5.68 - sobj.set(len++, element, strict); 5.69 + sobj.set(len++, element, true); 5.70 } 5.71 - sobj.set("length", len, strict); 5.72 + sobj.set("length", len, true); 5.73 5.74 return len; 5.75 } catch (final ClassCastException | NullPointerException e) { 5.76 @@ -672,7 +675,6 @@ 5.77 public static Object reverse(final Object self) { 5.78 try { 5.79 final ScriptObject sobj = (ScriptObject)self; 5.80 - final boolean strict = sobj.isStrictContext(); 5.81 final long len = JSType.toUint32(sobj.getLength()); 5.82 final long middle = len / 2; 5.83 5.84 @@ -684,14 +686,14 @@ 5.85 final boolean upperExists = sobj.has(upper); 5.86 5.87 if (lowerExists && upperExists) { 5.88 - sobj.set(lower, upperValue, strict); 5.89 - sobj.set(upper, lowerValue, strict); 5.90 + sobj.set(lower, upperValue, true); 5.91 + sobj.set(upper, lowerValue, true); 5.92 } else if (!lowerExists && upperExists) { 5.93 - sobj.set(lower, upperValue, strict); 5.94 - sobj.delete(upper, strict); 5.95 + sobj.set(lower, upperValue, true); 5.96 + sobj.delete(upper, true); 5.97 } else if (lowerExists && !upperExists) { 5.98 - sobj.delete(lower, strict); 5.99 - sobj.set(upper, lowerValue, strict); 5.100 + sobj.delete(lower, true); 5.101 + sobj.set(upper, lowerValue, true); 5.102 } 5.103 } 5.104 return sobj; 5.105 @@ -717,7 +719,6 @@ 5.106 } 5.107 5.108 final ScriptObject sobj = (ScriptObject) obj; 5.109 - final boolean strict = Global.isStrict(); 5.110 5.111 long len = JSType.toUint32(sobj.getLength()); 5.112 5.113 @@ -728,15 +729,15 @@ 5.114 sobj.getArray().shiftLeft(1); 5.115 } else { 5.116 for (long k = 1; k < len; k++) { 5.117 - sobj.set(k - 1, sobj.get(k), strict); 5.118 + sobj.set(k - 1, sobj.get(k), true); 5.119 } 5.120 } 5.121 - sobj.delete(--len, strict); 5.122 + sobj.delete(--len, true); 5.123 } else { 5.124 len = 0; 5.125 } 5.126 5.127 - sobj.set("length", len, strict); 5.128 + sobj.set("length", len, true); 5.129 5.130 return first; 5.131 } 5.132 @@ -833,7 +834,6 @@ 5.133 public static Object sort(final Object self, final Object comparefn) { 5.134 try { 5.135 final ScriptObject sobj = (ScriptObject) self; 5.136 - final boolean strict = sobj.isStrictContext(); 5.137 final long len = JSType.toUint32(sobj.getLength()); 5.138 ArrayData array = sobj.getArray(); 5.139 5.140 @@ -850,7 +850,7 @@ 5.141 final Object[] sorted = sort(src.toArray(), comparefn); 5.142 5.143 for (int i = 0; i < sorted.length; i++) { 5.144 - array = array.set(i, sorted[i], strict); 5.145 + array = array.set(i, sorted[i], true); 5.146 } 5.147 5.148 // delete missing elements - which are at the end of sorted array 5.149 @@ -891,7 +891,6 @@ 5.150 } 5.151 5.152 final ScriptObject sobj = (ScriptObject)obj; 5.153 - final boolean strict = Global.isStrict(); 5.154 final long len = JSType.toUint32(sobj.getLength()); 5.155 final long relativeStart = JSType.toLong(start); 5.156 5.157 @@ -914,14 +913,14 @@ 5.158 final long to = k + items.length; 5.159 5.160 if (sobj.has(from)) { 5.161 - sobj.set(to, sobj.get(from), strict); 5.162 + sobj.set(to, sobj.get(from), true); 5.163 } else { 5.164 - sobj.delete(to, strict); 5.165 + sobj.delete(to, true); 5.166 } 5.167 } 5.168 5.169 for (long k = len; k > (len - actualDeleteCount + items.length); k--) { 5.170 - sobj.delete(k - 1, strict); 5.171 + sobj.delete(k - 1, true); 5.172 } 5.173 } else if (items.length > actualDeleteCount) { 5.174 for (long k = len - actualDeleteCount; k > actualStart; k--) { 5.175 @@ -930,20 +929,20 @@ 5.176 5.177 if (sobj.has(from)) { 5.178 final Object fromValue = sobj.get(from); 5.179 - sobj.set(to, fromValue, strict); 5.180 + sobj.set(to, fromValue, true); 5.181 } else { 5.182 - sobj.delete(to, strict); 5.183 + sobj.delete(to, true); 5.184 } 5.185 } 5.186 } 5.187 5.188 long k = actualStart; 5.189 for (int i = 0; i < items.length; i++, k++) { 5.190 - sobj.set(k, items[i], strict); 5.191 + sobj.set(k, items[i], true); 5.192 } 5.193 5.194 final long newLength = len - actualDeleteCount + items.length; 5.195 - sobj.set("length", newLength, strict); 5.196 + sobj.set("length", newLength, true); 5.197 5.198 return array; 5.199 } 5.200 @@ -964,7 +963,6 @@ 5.201 } 5.202 5.203 final ScriptObject sobj = (ScriptObject)obj; 5.204 - final boolean strict = Global.isStrict(); 5.205 final long len = JSType.toUint32(sobj.getLength()); 5.206 5.207 if (items == null) { 5.208 @@ -975,7 +973,7 @@ 5.209 sobj.getArray().shiftRight(items.length); 5.210 5.211 for (int j = 0; j < items.length; j++) { 5.212 - sobj.setArray(sobj.getArray().set(j, items[j], sobj.isStrictContext())); 5.213 + sobj.setArray(sobj.getArray().set(j, items[j], true)); 5.214 } 5.215 } else { 5.216 for (long k = len; k > 0; k--) { 5.217 @@ -984,19 +982,19 @@ 5.218 5.219 if (sobj.has(from)) { 5.220 final Object fromValue = sobj.get(from); 5.221 - sobj.set(to, fromValue, strict); 5.222 + sobj.set(to, fromValue, true); 5.223 } else { 5.224 - sobj.delete(to, strict); 5.225 + sobj.delete(to, true); 5.226 } 5.227 } 5.228 5.229 for (int j = 0; j < items.length; j++) { 5.230 - sobj.set(j, items[j], strict); 5.231 + sobj.set(j, items[j], true); 5.232 } 5.233 } 5.234 5.235 final long newLength = len + items.length; 5.236 - sobj.set("length", newLength, strict); 5.237 + sobj.set("length", newLength, true); 5.238 5.239 return newLength; 5.240 } 5.241 @@ -1239,7 +1237,7 @@ 5.242 * @return true if optimizable 5.243 */ 5.244 private static boolean bulkable(final ScriptObject self) { 5.245 - return self.isArray() && !hasInheritedArrayEntries(self); 5.246 + return self.isArray() && !hasInheritedArrayEntries(self) && !self.isLengthNotWritable(); 5.247 } 5.248 5.249 private static boolean hasInheritedArrayEntries(final ScriptObject self) {
6.1 --- a/src/jdk/nashorn/internal/objects/NativeError.java Wed Jun 12 16:41:38 2013 +0200 6.2 +++ b/src/jdk/nashorn/internal/objects/NativeError.java Thu Jun 13 16:08:35 2013 +0530 6.3 @@ -90,7 +90,7 @@ 6.4 if (msg != UNDEFINED) { 6.5 this.instMessage = JSType.toString(msg); 6.6 } else { 6.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 6.8 + this.delete(NativeError.MESSAGE, false); 6.9 } 6.10 } 6.11 6.12 @@ -166,7 +166,7 @@ 6.13 public static Object setLineNumber(final Object self, final Object value) { 6.14 Global.checkObject(self); 6.15 final ScriptObject sobj = (ScriptObject)self; 6.16 - sobj.set(LINENUMBER, value, Global.isStrict()); 6.17 + sobj.set(LINENUMBER, value, false); 6.18 return value; 6.19 } 6.20 6.21 @@ -194,7 +194,7 @@ 6.22 public static Object setColumnNumber(final Object self, final Object value) { 6.23 Global.checkObject(self); 6.24 final ScriptObject sobj = (ScriptObject)self; 6.25 - sobj.set(COLUMNNUMBER, value, Global.isStrict()); 6.26 + sobj.set(COLUMNNUMBER, value, false); 6.27 return value; 6.28 } 6.29 6.30 @@ -222,7 +222,7 @@ 6.31 public static Object setFileName(final Object self, final Object value) { 6.32 Global.checkObject(self); 6.33 final ScriptObject sobj = (ScriptObject)self; 6.34 - sobj.set(FILENAME, value, Global.isStrict()); 6.35 + sobj.set(FILENAME, value, false); 6.36 return value; 6.37 } 6.38 6.39 @@ -278,7 +278,7 @@ 6.40 public static Object setStack(final Object self, final Object value) { 6.41 Global.checkObject(self); 6.42 final ScriptObject sobj = (ScriptObject)self; 6.43 - sobj.set(STACK, value, Global.isStrict()); 6.44 + sobj.set(STACK, value, false); 6.45 return value; 6.46 } 6.47
7.1 --- a/src/jdk/nashorn/internal/objects/NativeEvalError.java Wed Jun 12 16:41:38 2013 +0200 7.2 +++ b/src/jdk/nashorn/internal/objects/NativeEvalError.java Thu Jun 13 16:08:35 2013 +0530 7.3 @@ -59,7 +59,7 @@ 7.4 if (msg != UNDEFINED) { 7.5 this.instMessage = JSType.toString(msg); 7.6 } else { 7.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 7.8 + this.delete(NativeError.MESSAGE, false); 7.9 } 7.10 } 7.11
8.1 --- a/src/jdk/nashorn/internal/objects/NativeFunction.java Wed Jun 12 16:41:38 2013 +0200 8.2 +++ b/src/jdk/nashorn/internal/objects/NativeFunction.java Thu Jun 13 16:08:35 2013 +0530 8.3 @@ -216,7 +216,7 @@ 8.4 8.5 final Global global = Global.instance(); 8.6 8.7 - return Global.directEval(global, sb.toString(), global, "<function>", Global.isStrict()); 8.8 + return Global.directEval(global, sb.toString(), global, "<function>", global.isStrictContext()); 8.9 } 8.10 8.11 private static void checkFunctionParameters(final String params) {
9.1 --- a/src/jdk/nashorn/internal/objects/NativeJSON.java Wed Jun 12 16:41:38 2013 +0200 9.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSON.java Thu Jun 13 16:08:35 2013 +0530 9.3 @@ -158,7 +158,7 @@ 9.4 state.gap = gap; 9.5 9.6 final ScriptObject wrapper = Global.newEmptyInstance(); 9.7 - wrapper.set("", value, Global.isStrict()); 9.8 + wrapper.set("", value, false); 9.9 9.10 return str("", wrapper, state); 9.11 }
10.1 --- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Wed Jun 12 16:41:38 2013 +0200 10.2 +++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Thu Jun 13 16:08:35 2013 +0530 10.3 @@ -121,7 +121,7 @@ 10.4 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 10.5 final Object value = createProperty(name); 10.6 if(value != null) { 10.7 - set(name, value, isStrictContext()); 10.8 + set(name, value, false); 10.9 return true; 10.10 } 10.11 return false;
11.1 --- a/src/jdk/nashorn/internal/objects/NativeRangeError.java Wed Jun 12 16:41:38 2013 +0200 11.2 +++ b/src/jdk/nashorn/internal/objects/NativeRangeError.java Thu Jun 13 16:08:35 2013 +0530 11.3 @@ -59,7 +59,7 @@ 11.4 if (msg != UNDEFINED) { 11.5 this.instMessage = JSType.toString(msg); 11.6 } else { 11.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 11.8 + this.delete(NativeError.MESSAGE, false); 11.9 } 11.10 } 11.11
12.1 --- a/src/jdk/nashorn/internal/objects/NativeReferenceError.java Wed Jun 12 16:41:38 2013 +0200 12.2 +++ b/src/jdk/nashorn/internal/objects/NativeReferenceError.java Thu Jun 13 16:08:35 2013 +0530 12.3 @@ -59,7 +59,7 @@ 12.4 if (msg != UNDEFINED) { 12.5 this.instMessage = JSType.toString(msg); 12.6 } else { 12.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 12.8 + this.delete(NativeError.MESSAGE, false); 12.9 } 12.10 } 12.11
13.1 --- a/src/jdk/nashorn/internal/objects/NativeSyntaxError.java Wed Jun 12 16:41:38 2013 +0200 13.2 +++ b/src/jdk/nashorn/internal/objects/NativeSyntaxError.java Thu Jun 13 16:08:35 2013 +0530 13.3 @@ -59,7 +59,7 @@ 13.4 if (msg != UNDEFINED) { 13.5 this.instMessage = JSType.toString(msg); 13.6 } else { 13.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 13.8 + this.delete(NativeError.MESSAGE, false); 13.9 } 13.10 } 13.11
14.1 --- a/src/jdk/nashorn/internal/objects/NativeTypeError.java Wed Jun 12 16:41:38 2013 +0200 14.2 +++ b/src/jdk/nashorn/internal/objects/NativeTypeError.java Thu Jun 13 16:08:35 2013 +0530 14.3 @@ -59,7 +59,7 @@ 14.4 if (msg != UNDEFINED) { 14.5 this.instMessage = JSType.toString(msg); 14.6 } else { 14.7 - delete(NativeError.MESSAGE, Global.isStrict()); 14.8 + delete(NativeError.MESSAGE, false); 14.9 } 14.10 } 14.11
15.1 --- a/src/jdk/nashorn/internal/objects/NativeURIError.java Wed Jun 12 16:41:38 2013 +0200 15.2 +++ b/src/jdk/nashorn/internal/objects/NativeURIError.java Thu Jun 13 16:08:35 2013 +0530 15.3 @@ -58,7 +58,7 @@ 15.4 if (msg != UNDEFINED) { 15.5 this.instMessage = JSType.toString(msg); 15.6 } else { 15.7 - this.delete(NativeError.MESSAGE, Global.isStrict()); 15.8 + this.delete(NativeError.MESSAGE, false); 15.9 } 15.10 } 15.11
16.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Wed Jun 12 16:41:38 2013 +0200 16.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Thu Jun 13 16:08:35 2013 +0530 16.3 @@ -188,7 +188,7 @@ 16.4 private final ScriptEnvironment env; 16.5 16.6 /** is this context in strict mode? Cached from env. as this is used heavily. */ 16.7 - public final boolean _strict; 16.8 + final boolean _strict; 16.9 16.10 /** class loader to resolve classes from script. */ 16.11 private final ClassLoader appLoader;
17.1 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java Wed Jun 12 16:41:38 2013 +0200 17.2 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java Thu Jun 13 16:08:35 2013 +0530 17.3 @@ -101,7 +101,6 @@ 17.4 final Object val = holder.get(name); 17.5 if (val instanceof ScriptObject) { 17.6 final ScriptObject valueObj = (ScriptObject)val; 17.7 - final boolean strict = valueObj.isStrictContext(); 17.8 final Iterator<String> iter = valueObj.propertyIterator(); 17.9 17.10 while (iter.hasNext()) { 17.11 @@ -109,9 +108,9 @@ 17.12 final Object newElement = walk(valueObj, key, reviver); 17.13 17.14 if (newElement == ScriptRuntime.UNDEFINED) { 17.15 - valueObj.delete(key, strict); 17.16 + valueObj.delete(key, false); 17.17 } else { 17.18 - setPropertyValue(valueObj, key, newElement, strict); 17.19 + setPropertyValue(valueObj, key, newElement, false); 17.20 } 17.21 } 17.22 } 17.23 @@ -164,14 +163,13 @@ 17.24 } else if (node instanceof ObjectNode) { 17.25 final ObjectNode objNode = (ObjectNode) node; 17.26 final ScriptObject object = ((GlobalObject)global).newObject(); 17.27 - final boolean strict = global.isStrictContext(); 17.28 17.29 for (final PropertyNode pNode: objNode.getElements()) { 17.30 final Node valueNode = pNode.getValue(); 17.31 17.32 final String name = pNode.getKeyName(); 17.33 final Object value = convertNode(global, valueNode); 17.34 - setPropertyValue(object, name, value, strict); 17.35 + setPropertyValue(object, name, value, false); 17.36 } 17.37 17.38 return object;
18.1 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Wed Jun 12 16:41:38 2013 +0200 18.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Thu Jun 13 16:08:35 2013 +0530 18.3 @@ -199,7 +199,6 @@ 18.4 final String fullName = name.isEmpty() ? propertyName : name + "." + propertyName; 18.5 18.6 final Context context = getContext(); 18.7 - final boolean strict = context._strict; 18.8 18.9 Class<?> javaClass = null; 18.10 try { 18.11 @@ -209,9 +208,9 @@ 18.12 } 18.13 18.14 if (javaClass == null) { 18.15 - set(propertyName, new NativeJavaPackage(fullName, getProto()), strict); 18.16 + set(propertyName, new NativeJavaPackage(fullName, getProto()), false); 18.17 } else { 18.18 - set(propertyName, StaticClass.forClass(javaClass), strict); 18.19 + set(propertyName, StaticClass.forClass(javaClass), false); 18.20 } 18.21 18.22 return super.lookup(desc, request);
19.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Jun 12 16:41:38 2013 +0200 19.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Jun 13 16:08:35 2013 +0530 19.3 @@ -105,6 +105,9 @@ 19.4 /** Is this a prototype PropertyMap? */ 19.5 public static final int IS_PROTOTYPE = 0b0000_1000; 19.6 19.7 + /** Is length property not-writable? */ 19.8 + public static final int IS_LENGTH_NOT_WRITABLE = 0b0001_0000; 19.9 + 19.10 /** Spill growth rate - by how many elements does {@link ScriptObject#spill} when full */ 19.11 public static final int SPILL_RATE = 8; 19.12 19.13 @@ -443,7 +446,7 @@ 19.14 if (newValue && property != null) { 19.15 // Temporarily clear flags. 19.16 property = modifyOwnProperty(property, 0); 19.17 - set(key, value, getContext()._strict); 19.18 + set(key, value, false); 19.19 } 19.20 19.21 if (property == null) { 19.22 @@ -998,7 +1001,7 @@ 19.23 * @param value the value to write at the given index 19.24 */ 19.25 public void setArgument(final int key, final Object value) { 19.26 - set(key, value, getContext()._strict); 19.27 + set(key, value, false); 19.28 } 19.29 19.30 /** 19.31 @@ -1277,14 +1280,14 @@ 19.32 * 19.33 * @return {@code true} if is prototype 19.34 */ 19.35 - public boolean isPrototype() { 19.36 + public final boolean isPrototype() { 19.37 return (flags & IS_PROTOTYPE) != 0; 19.38 } 19.39 19.40 /** 19.41 * Flag this object as having a prototype. 19.42 */ 19.43 - public void setIsPrototype() { 19.44 + public final void setIsPrototype() { 19.45 if (proto != null && !isPrototype()) { 19.46 proto.addPropertyListener(this); 19.47 } 19.48 @@ -1292,6 +1295,22 @@ 19.49 } 19.50 19.51 /** 19.52 + * Check if this object has non-writable length property 19.53 + * 19.54 + * @return {@code true} if 'length' property is non-writable 19.55 + */ 19.56 + public final boolean isLengthNotWritable() { 19.57 + return (flags & IS_LENGTH_NOT_WRITABLE) != 0; 19.58 + } 19.59 + 19.60 + /** 19.61 + * Flag this object as having non-writable length property 19.62 + */ 19.63 + public void setIsLengthNotWritable() { 19.64 + flags |= IS_LENGTH_NOT_WRITABLE; 19.65 + } 19.66 + 19.67 + /** 19.68 * Get the {@link ArrayData} for this ScriptObject if it is an array 19.69 * @return array data 19.70 */ 19.71 @@ -1393,7 +1412,7 @@ 19.72 * (java.util.Map-like method to help ScriptObjectMirror implementation) 19.73 */ 19.74 public void clear() { 19.75 - final boolean strict = getContext()._strict; 19.76 + final boolean strict = isStrictContext(); 19.77 final Iterator<String> iter = propertyIterator(); 19.78 while (iter.hasNext()) { 19.79 delete(iter.next(), strict); 19.80 @@ -1481,7 +1500,7 @@ 19.81 */ 19.82 public Object put(final Object key, final Object value) { 19.83 final Object oldValue = get(key); 19.84 - set(key, value, getContext()._strict); 19.85 + set(key, value, isStrictContext()); 19.86 return oldValue; 19.87 } 19.88 19.89 @@ -1493,7 +1512,7 @@ 19.90 * @param otherMap a {@literal <key,value>} map of properties to add 19.91 */ 19.92 public void putAll(final Map<?, ?> otherMap) { 19.93 - final boolean strict = getContext()._strict; 19.94 + final boolean strict = isStrictContext(); 19.95 for (final Map.Entry<?, ?> entry : otherMap.entrySet()) { 19.96 set(entry.getKey(), entry.getValue(), strict); 19.97 } 19.98 @@ -1508,7 +1527,7 @@ 19.99 */ 19.100 public Object remove(final Object key) { 19.101 final Object oldValue = get(key); 19.102 - delete(key, getContext()._strict); 19.103 + delete(key, isStrictContext()); 19.104 return oldValue; 19.105 } 19.106 19.107 @@ -1520,7 +1539,7 @@ 19.108 * @return if the delete was successful or not 19.109 */ 19.110 public boolean delete(final Object key) { 19.111 - return delete(key, getContext()._strict); 19.112 + return delete(key, isStrictContext()); 19.113 } 19.114 19.115 /** 19.116 @@ -2222,7 +2241,7 @@ 19.117 return; 19.118 } 19.119 19.120 - final boolean isStrict = getContext()._strict; 19.121 + final boolean isStrict = isStrictContext(); 19.122 19.123 if (newLength > arrayLength) { 19.124 setArray(getArray().ensure(newLength - 1));
20.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Wed Jun 12 16:41:38 2013 +0200 20.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Thu Jun 13 16:08:35 2013 +0530 20.3 @@ -221,10 +221,9 @@ 20.4 final String err = errBuffer.toString(); 20.5 20.6 // Set globals for secondary results. 20.7 - final boolean isStrict = global.isStrictContext(); 20.8 - global.set(OUT_NAME, out, isStrict); 20.9 - global.set(ERR_NAME, err, isStrict); 20.10 - global.set(EXIT_NAME, exit, isStrict); 20.11 + global.set(OUT_NAME, out, false); 20.12 + global.set(ERR_NAME, err, false); 20.13 + global.set(EXIT_NAME, exit, false); 20.14 20.15 // Propagate exception if present. 20.16 for (int i = 0; i < exception.length; i++) {
21.1 --- a/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java Wed Jun 12 16:41:38 2013 +0200 21.2 +++ b/src/jdk/nashorn/internal/runtime/arrays/ArrayIterator.java Thu Jun 13 16:08:35 2013 +0530 21.3 @@ -83,6 +83,6 @@ 21.4 21.5 @Override 21.6 public void remove() { 21.7 - array.delete(index, array.isStrictContext()); 21.8 + array.delete(index, false); 21.9 } 21.10 }
22.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 22.2 +++ b/test/script/basic/JDK-8015355.js Thu Jun 13 16:08:35 2013 +0530 22.3 @@ -0,0 +1,122 @@ 22.4 +/* 22.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 22.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 22.7 + * 22.8 + * This code is free software; you can redistribute it and/or modify it 22.9 + * under the terms of the GNU General Public License version 2 only, as 22.10 + * published by the Free Software Foundation. 22.11 + * 22.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 22.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 22.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 22.15 + * version 2 for more details (a copy is included in the LICENSE file that 22.16 + * accompanied this code). 22.17 + * 22.18 + * You should have received a copy of the GNU General Public License version 22.19 + * 2 along with this work; if not, write to the Free Software Foundation, 22.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 22.21 + * 22.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22.23 + * or visit www.oracle.com if you need additional information or have any 22.24 + * questions. 22.25 + */ 22.26 + 22.27 +/** 22.28 + * JDK-8015355: Array.prototype functions don't honour non-writable length and / or index properties 22.29 + * 22.30 + * @test 22.31 + * @run 22.32 + */ 22.33 + 22.34 +function fail(msg) { 22.35 + print(msg); 22.36 +} 22.37 + 22.38 +function check(callback) { 22.39 + try { 22.40 + callback(); 22.41 + fail("TypeError expected for " + callback); 22.42 + } catch (e) { 22.43 + if (! (e instanceof TypeError)) { 22.44 + fail("TypeError expected, got " + e); 22.45 + } 22.46 + } 22.47 +} 22.48 + 22.49 +var array = Object.defineProperty([],"length", { writable: false }); 22.50 + 22.51 +check(function() { 22.52 + array.push(0) 22.53 +}); 22.54 + 22.55 +check(function() { 22.56 + array.pop() 22.57 +}); 22.58 + 22.59 +check(function() { 22.60 + Object.defineProperty([,,],"0",{ writable: false }).reverse(); 22.61 +}); 22.62 + 22.63 +check(function() { 22.64 + array.shift() 22.65 +}); 22.66 + 22.67 +check(function() { 22.68 + array.splice(0) 22.69 +}); 22.70 + 22.71 +check(function() { 22.72 + array.unshift() 22.73 +}); 22.74 + 22.75 +// try the above via call 22.76 + 22.77 +check(function() { 22.78 + Array.prototype.push.call(array, 0); 22.79 +}); 22.80 + 22.81 +check(function() { 22.82 + Array.prototype.pop.call(array); 22.83 +}); 22.84 + 22.85 +check(function() { 22.86 + Array.prototype.shift.call(array); 22.87 +}); 22.88 + 22.89 +check(function() { 22.90 + Array.prototype.unshift.call(array); 22.91 +}); 22.92 + 22.93 +check(function() { 22.94 + Array.prototype.splice.call(array, 0); 22.95 +}); 22.96 + 22.97 +check(function() { 22.98 + Array.prototype.reverse.call(Object.defineProperty([,,],"0",{ writable: false })); 22.99 +}); 22.100 + 22.101 +// try the above via apply 22.102 + 22.103 +check(function() { 22.104 + Array.prototype.push.apply(array, [ 0 ]); 22.105 +}); 22.106 + 22.107 +check(function() { 22.108 + Array.prototype.pop.apply(array); 22.109 +}); 22.110 + 22.111 +check(function() { 22.112 + Array.prototype.shift.apply(array); 22.113 +}); 22.114 + 22.115 +check(function() { 22.116 + Array.prototype.unshift.apply(array); 22.117 +}); 22.118 + 22.119 +check(function() { 22.120 + Array.prototype.splice.apply(array, [ 0 ]); 22.121 +}); 22.122 + 22.123 +check(function() { 22.124 + Array.prototype.reverse.apply(Object.defineProperty([,,],"0",{ writable: false })); 22.125 +});