Mon, 22 Sep 2014 13:28:28 +0200
8047764: Indexed or polymorphic set on global affects Object.prototype
Reviewed-by: lagergren, attila
1.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Sep 22 14:46:04 2014 +0200 1.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Sep 22 13:28:28 2014 +0200 1.3 @@ -50,6 +50,7 @@ 1.4 import jdk.nashorn.internal.runtime.ScriptObject; 1.5 import jdk.nashorn.internal.runtime.ScriptRuntime; 1.6 import jdk.nashorn.internal.runtime.arrays.ArrayData; 1.7 +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 1.8 1.9 /** 1.10 * Mirror object that wraps a given Nashorn Script object. 1.11 @@ -261,7 +262,7 @@ 1.12 public void setSlot(final int index, final Object value) { 1.13 inGlobal(new Callable<Void>() { 1.14 @Override public Void call() { 1.15 - sobj.set(index, unwrap(value, global), strict); 1.16 + sobj.set(index, unwrap(value, global), getCallSiteFlags()); 1.17 return null; 1.18 } 1.19 }); 1.20 @@ -425,7 +426,7 @@ 1.21 for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) { 1.22 final Object value = entry.getValue(); 1.23 final Object modValue = globalChanged? wrap(value, oldGlobal) : value; 1.24 - sobj.set(entry.getKey(), unwrap(modValue, global), strict); 1.25 + sobj.set(entry.getKey(), unwrap(modValue, global), getCallSiteFlags()); 1.26 } 1.27 return null; 1.28 } 1.29 @@ -756,6 +757,10 @@ 1.30 return (obj == ScriptRuntime.UNDEFINED)? null : obj; 1.31 } 1.32 1.33 + private int getCallSiteFlags() { 1.34 + return strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; 1.35 + } 1.36 + 1.37 // internals only below this. 1.38 private <V> V inGlobal(final Callable<V> callable) { 1.39 final Global oldGlobal = Context.getGlobal();
2.1 --- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java Mon Sep 22 14:46:04 2014 +0200 2.2 +++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java Mon Sep 22 13:28:28 2014 +0200 2.3 @@ -228,11 +228,11 @@ 2.4 private static void copyElements(final ArrayBufferView dest, final int length, final ScriptObject source, final int offset) { 2.5 if (!dest.isFloatArray()) { 2.6 for (int i = 0, j = offset; i < length; i++, j++) { 2.7 - dest.set(j, source.getInt(i, INVALID_PROGRAM_POINT), false); 2.8 + dest.set(j, source.getInt(i, INVALID_PROGRAM_POINT), 0); 2.9 } 2.10 } else { 2.11 for (int i = 0, j = offset; i < length; i++, j++) { 2.12 - dest.set(j, source.getDouble(i, INVALID_PROGRAM_POINT), false); 2.13 + dest.set(j, source.getDouble(i, INVALID_PROGRAM_POINT), 0); 2.14 } 2.15 } 2.16 }
3.1 --- a/src/jdk/nashorn/internal/objects/Global.java Mon Sep 22 14:46:04 2014 +0200 3.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Mon Sep 22 13:28:28 2014 +0200 3.3 @@ -1825,10 +1825,10 @@ 3.4 3.5 // ECMA 15.11.4.2 Error.prototype.name 3.6 // Error.prototype.name = "Error"; 3.7 - errorProto.set(NativeError.NAME, "Error", false); 3.8 + errorProto.set(NativeError.NAME, "Error", 0); 3.9 // ECMA 15.11.4.3 Error.prototype.message 3.10 // Error.prototype.message = ""; 3.11 - errorProto.set(NativeError.MESSAGE, "", false); 3.12 + errorProto.set(NativeError.MESSAGE, "", 0); 3.13 3.14 this.builtinEvalError = initErrorSubtype("EvalError", errorProto); 3.15 this.builtinRangeError = initErrorSubtype("RangeError", errorProto); 3.16 @@ -1841,8 +1841,8 @@ 3.17 private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) { 3.18 final ScriptFunction cons = initConstructor(name, ScriptFunction.class); 3.19 final ScriptObject prototype = ScriptFunction.getPrototype(cons); 3.20 - prototype.set(NativeError.NAME, name, false); 3.21 - prototype.set(NativeError.MESSAGE, "", false); 3.22 + prototype.set(NativeError.NAME, name, 0); 3.23 + prototype.set(NativeError.MESSAGE, "", 0); 3.24 prototype.setInitialProto(errorProto); 3.25 return cons; 3.26 } 3.27 @@ -1902,7 +1902,7 @@ 3.28 private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) { 3.29 for (final Field f : scriptEnv.getClass().getFields()) { 3.30 try { 3.31 - options.set(f.getName(), f.get(scriptEnv), false); 3.32 + options.set(f.getName(), f.get(scriptEnv), 0); 3.33 } catch (final IllegalArgumentException | IllegalAccessException exp) { 3.34 throw new RuntimeException(exp); 3.35 } 3.36 @@ -2046,7 +2046,7 @@ 3.37 // <anon-function> 3.38 builtinFunction.setInitialProto(anon); 3.39 builtinFunction.setPrototype(anon); 3.40 - anon.set("constructor", builtinFunction, false); 3.41 + anon.set("constructor", builtinFunction, 0); 3.42 anon.deleteOwnProperty(anon.getMap().findProperty("prototype")); 3.43 3.44 // use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
4.1 --- a/src/jdk/nashorn/internal/objects/NativeArray.java Mon Sep 22 14:46:04 2014 +0200 4.2 +++ b/src/jdk/nashorn/internal/objects/NativeArray.java Mon Sep 22 13:28:28 2014 +0200 4.3 @@ -32,6 +32,7 @@ 4.4 import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex; 4.5 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator; 4.6 import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator; 4.7 +import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT; 4.8 4.9 import java.lang.invoke.MethodHandle; 4.10 import java.util.ArrayList; 4.11 @@ -69,6 +70,7 @@ 4.12 import jdk.nashorn.internal.runtime.arrays.IteratorAction; 4.13 import jdk.nashorn.internal.runtime.linker.Bootstrap; 4.14 import jdk.nashorn.internal.runtime.linker.InvokeByName; 4.15 +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 4.16 4.17 /** 4.18 * Runtime representation of a JavaScript array. NativeArray only holds numeric 4.19 @@ -341,7 +343,7 @@ 4.20 if (!newWritable) { 4.21 // make 'length' property not writable 4.22 final ScriptObject newDesc = Global.newEmptyInstance(); 4.23 - newDesc.set(WRITABLE, false, false); 4.24 + newDesc.set(WRITABLE, false, 0); 4.25 return super.defineOwnProperty("length", newDesc, false); 4.26 } 4.27 4.28 @@ -808,7 +810,7 @@ 4.29 final long len = JSType.toUint32(sobj.getLength()); 4.30 4.31 if (len == 0) { 4.32 - sobj.set("length", 0, true); 4.33 + sobj.set("length", 0, CALLSITE_STRICT); 4.34 return ScriptRuntime.UNDEFINED; 4.35 } 4.36 4.37 @@ -816,7 +818,7 @@ 4.38 final Object element = sobj.get(index); 4.39 4.40 sobj.delete(index, true); 4.41 - sobj.set("length", index, true); 4.42 + sobj.set("length", index, CALLSITE_STRICT); 4.43 4.44 return element; 4.45 } catch (final ClassCastException | NullPointerException e) { 4.46 @@ -844,9 +846,9 @@ 4.47 4.48 long len = JSType.toUint32(sobj.getLength()); 4.49 for (final Object element : args) { 4.50 - sobj.set(len++, element, true); 4.51 + sobj.set(len++, element, CALLSITE_STRICT); 4.52 } 4.53 - sobj.set("length", len, true); 4.54 + sobj.set("length", len, CALLSITE_STRICT); 4.55 4.56 return len; 4.57 } catch (final ClassCastException | NullPointerException e) { 4.58 @@ -928,8 +930,8 @@ 4.59 } 4.60 4.61 long len = JSType.toUint32(sobj.getLength()); 4.62 - sobj.set(len++, arg, true); 4.63 - sobj.set("length", len, true); 4.64 + sobj.set(len++, arg, CALLSITE_STRICT); 4.65 + sobj.set("length", len, CALLSITE_STRICT); 4.66 return len; 4.67 } catch (final ClassCastException | NullPointerException e) { 4.68 throw typeError("not.an.object", ScriptRuntime.safeToString(self)); 4.69 @@ -957,14 +959,14 @@ 4.70 final boolean upperExists = sobj.has(upper); 4.71 4.72 if (lowerExists && upperExists) { 4.73 - sobj.set(lower, upperValue, true); 4.74 - sobj.set(upper, lowerValue, true); 4.75 + sobj.set(lower, upperValue, CALLSITE_STRICT); 4.76 + sobj.set(upper, lowerValue, CALLSITE_STRICT); 4.77 } else if (!lowerExists && upperExists) { 4.78 - sobj.set(lower, upperValue, true); 4.79 + sobj.set(lower, upperValue, CALLSITE_STRICT); 4.80 sobj.delete(upper, true); 4.81 } else if (lowerExists && !upperExists) { 4.82 sobj.delete(lower, true); 4.83 - sobj.set(upper, lowerValue, true); 4.84 + sobj.set(upper, lowerValue, CALLSITE_STRICT); 4.85 } 4.86 } 4.87 return sobj; 4.88 @@ -1003,7 +1005,7 @@ 4.89 for (long k = 1; k < len; k++) { 4.90 final boolean hasCurrent = sobj.has(k); 4.91 if (hasCurrent) { 4.92 - sobj.set(k - 1, sobj.get(k), true); 4.93 + sobj.set(k - 1, sobj.get(k), CALLSITE_STRICT); 4.94 } else if (hasPrevious) { 4.95 sobj.delete(k - 1, true); 4.96 } 4.97 @@ -1015,7 +1017,7 @@ 4.98 len = 0; 4.99 } 4.100 4.101 - sobj.set("length", len, true); 4.102 + sobj.set("length", len, CALLSITE_STRICT); 4.103 4.104 return first; 4.105 } 4.106 @@ -1226,7 +1228,7 @@ 4.107 final long to = k + items.length; 4.108 4.109 if (sobj.has(from)) { 4.110 - sobj.set(to, sobj.get(from), true); 4.111 + sobj.set(to, sobj.get(from), CALLSITE_STRICT); 4.112 } else { 4.113 sobj.delete(to, true); 4.114 } 4.115 @@ -1242,7 +1244,7 @@ 4.116 4.117 if (sobj.has(from)) { 4.118 final Object fromValue = sobj.get(from); 4.119 - sobj.set(to, fromValue, true); 4.120 + sobj.set(to, fromValue, CALLSITE_STRICT); 4.121 } else { 4.122 sobj.delete(to, true); 4.123 } 4.124 @@ -1251,11 +1253,11 @@ 4.125 4.126 long k = start; 4.127 for (int i = 0; i < items.length; i++, k++) { 4.128 - sobj.set(k, items[i], true); 4.129 + sobj.set(k, items[i], CALLSITE_STRICT); 4.130 } 4.131 4.132 final long newLength = len - deleteCount + items.length; 4.133 - sobj.set("length", newLength, true); 4.134 + sobj.set("length", newLength, CALLSITE_STRICT); 4.135 4.136 return array; 4.137 } 4.138 @@ -1295,19 +1297,19 @@ 4.139 4.140 if (sobj.has(from)) { 4.141 final Object fromValue = sobj.get(from); 4.142 - sobj.set(to, fromValue, true); 4.143 + sobj.set(to, fromValue, CALLSITE_STRICT); 4.144 } else { 4.145 sobj.delete(to, true); 4.146 } 4.147 } 4.148 4.149 for (int j = 0; j < items.length; j++) { 4.150 - sobj.set(j, items[j], true); 4.151 + sobj.set(j, items[j], CALLSITE_STRICT); 4.152 } 4.153 } 4.154 4.155 final long newLength = len + items.length; 4.156 - sobj.set("length", newLength, true); 4.157 + sobj.set("length", newLength, CALLSITE_STRICT); 4.158 4.159 return newLength; 4.160 }
5.1 --- a/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Sep 22 14:46:04 2014 +0200 5.2 +++ b/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Sep 22 13:28:28 2014 +0200 5.3 @@ -42,6 +42,7 @@ 5.4 import jdk.nashorn.internal.runtime.ScriptObject; 5.5 import jdk.nashorn.internal.runtime.events.RuntimeEvent; 5.6 import jdk.nashorn.internal.runtime.linker.LinkerCallSite; 5.7 +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 5.8 5.9 /** 5.10 * Nashorn specific debug utils. This is meant for Nashorn developers. 5.11 @@ -266,7 +267,7 @@ 5.12 */ 5.13 @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) 5.14 public static void setEventQueueCapacity(final Object self, final Object newCapacity) { 5.15 - ((ScriptObject)self).set(EVENT_QUEUE_CAPACITY, newCapacity, true); 5.16 + ((ScriptObject)self).set(EVENT_QUEUE_CAPACITY, newCapacity, NashornCallSiteDescriptor.CALLSITE_STRICT); 5.17 } 5.18 5.19 /** 5.20 @@ -355,7 +356,7 @@ 5.21 if (sobj.has(EVENT_QUEUE)) { 5.22 q = (LinkedList<RuntimeEvent<?>>)((ScriptObject)self).get(EVENT_QUEUE); 5.23 } else { 5.24 - ((ScriptObject)self).set(EVENT_QUEUE, q = new LinkedList<>(), true); 5.25 + ((ScriptObject)self).set(EVENT_QUEUE, q = new LinkedList<>(), NashornCallSiteDescriptor.CALLSITE_STRICT); 5.26 } 5.27 return q; 5.28 }
6.1 --- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Sep 22 14:46:04 2014 +0200 6.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Mon Sep 22 13:28:28 2014 +0200 6.3 @@ -250,146 +250,146 @@ 6.4 } 6.5 6.6 @Override 6.7 - public void set(final Object key, final int value, final boolean strict) { 6.8 + public void set(final Object key, final int value, final int flags) { 6.9 if (overrides && super.hasOwnProperty(key)) { 6.10 - super.set(key, value, strict); 6.11 + super.set(key, value, flags); 6.12 } else { 6.13 - callAdaptee(__put__, key, value, strict); 6.14 + callAdaptee(__put__, key, value, flags); 6.15 } 6.16 } 6.17 6.18 @Override 6.19 - public void set(final Object key, final long value, final boolean strict) { 6.20 + public void set(final Object key, final long value, final int flags) { 6.21 if (overrides && super.hasOwnProperty(key)) { 6.22 - super.set(key, value, strict); 6.23 + super.set(key, value, flags); 6.24 } else { 6.25 - callAdaptee(__put__, key, value, strict); 6.26 + callAdaptee(__put__, key, value, flags); 6.27 } 6.28 } 6.29 6.30 @Override 6.31 - public void set(final Object key, final double value, final boolean strict) { 6.32 + public void set(final Object key, final double value, final int flags) { 6.33 if (overrides && super.hasOwnProperty(key)) { 6.34 - super.set(key, value, strict); 6.35 + super.set(key, value, flags); 6.36 } else { 6.37 - callAdaptee(__put__, key, value, strict); 6.38 + callAdaptee(__put__, key, value, flags); 6.39 } 6.40 } 6.41 6.42 @Override 6.43 - public void set(final Object key, final Object value, final boolean strict) { 6.44 + public void set(final Object key, final Object value, final int flags) { 6.45 if (overrides && super.hasOwnProperty(key)) { 6.46 - super.set(key, value, strict); 6.47 + super.set(key, value, flags); 6.48 } else { 6.49 - callAdaptee(__put__, key, value, strict); 6.50 + callAdaptee(__put__, key, value, flags); 6.51 } 6.52 } 6.53 6.54 @Override 6.55 - public void set(final double key, final int value, final boolean strict) { 6.56 + public void set(final double key, final int value, final int flags) { 6.57 if (overrides && super.hasOwnProperty(key)) { 6.58 - super.set(key, value, strict); 6.59 + super.set(key, value, flags); 6.60 } else { 6.61 - callAdaptee(__put__, key, value, strict); 6.62 + callAdaptee(__put__, key, value, flags); 6.63 } 6.64 } 6.65 6.66 @Override 6.67 - public void set(final double key, final long value, final boolean strict) { 6.68 + public void set(final double key, final long value, final int flags) { 6.69 if (overrides && super.hasOwnProperty(key)) { 6.70 - super.set(key, value, strict); 6.71 + super.set(key, value, flags); 6.72 } else { 6.73 - callAdaptee(__put__, key, value, strict); 6.74 + callAdaptee(__put__, key, value, flags); 6.75 } 6.76 } 6.77 6.78 @Override 6.79 - public void set(final double key, final double value, final boolean strict) { 6.80 + public void set(final double key, final double value, final int flags) { 6.81 if (overrides && super.hasOwnProperty(key)) { 6.82 - super.set(key, value, strict); 6.83 + super.set(key, value, flags); 6.84 } else { 6.85 - callAdaptee(__put__, key, value, strict); 6.86 + callAdaptee(__put__, key, value, flags); 6.87 } 6.88 } 6.89 6.90 @Override 6.91 - public void set(final double key, final Object value, final boolean strict) { 6.92 + public void set(final double key, final Object value, final int flags) { 6.93 if (overrides && super.hasOwnProperty(key)) { 6.94 - super.set(key, value, strict); 6.95 + super.set(key, value, flags); 6.96 } else { 6.97 - callAdaptee(__put__, key, value, strict); 6.98 + callAdaptee(__put__, key, value, flags); 6.99 } 6.100 } 6.101 6.102 @Override 6.103 - public void set(final long key, final int value, final boolean strict) { 6.104 + public void set(final long key, final int value, final int flags) { 6.105 if (overrides && super.hasOwnProperty(key)) { 6.106 - super.set(key, value, strict); 6.107 + super.set(key, value, flags); 6.108 } else { 6.109 - callAdaptee(__put__, key, value, strict); 6.110 + callAdaptee(__put__, key, value, flags); 6.111 } 6.112 } 6.113 6.114 @Override 6.115 - public void set(final long key, final long value, final boolean strict) { 6.116 + public void set(final long key, final long value, final int flags) { 6.117 if (overrides && super.hasOwnProperty(key)) { 6.118 - super.set(key, value, strict); 6.119 + super.set(key, value, flags); 6.120 } else { 6.121 - callAdaptee(__put__, key, value, strict); 6.122 + callAdaptee(__put__, key, value, flags); 6.123 } 6.124 } 6.125 6.126 @Override 6.127 - public void set(final long key, final double value, final boolean strict) { 6.128 + public void set(final long key, final double value, final int flags) { 6.129 if (overrides && super.hasOwnProperty(key)) { 6.130 - super.set(key, value, strict); 6.131 + super.set(key, value, flags); 6.132 } else { 6.133 - callAdaptee(__put__, key, value, strict); 6.134 + callAdaptee(__put__, key, value, flags); 6.135 } 6.136 } 6.137 6.138 @Override 6.139 - public void set(final long key, final Object value, final boolean strict) { 6.140 + public void set(final long key, final Object value, final int flags) { 6.141 if (overrides && super.hasOwnProperty(key)) { 6.142 - super.set(key, value, strict); 6.143 + super.set(key, value, flags); 6.144 } else { 6.145 - callAdaptee(__put__, key, value, strict); 6.146 + callAdaptee(__put__, key, value, flags); 6.147 } 6.148 } 6.149 6.150 @Override 6.151 - public void set(final int key, final int value, final boolean strict) { 6.152 + public void set(final int key, final int value, final int flags) { 6.153 if (overrides && super.hasOwnProperty(key)) { 6.154 - super.set(key, value, strict); 6.155 + super.set(key, value, flags); 6.156 } else { 6.157 - callAdaptee(__put__, key, value, strict); 6.158 + callAdaptee(__put__, key, value, flags); 6.159 } 6.160 } 6.161 6.162 @Override 6.163 - public void set(final int key, final long value, final boolean strict) { 6.164 + public void set(final int key, final long value, final int flags) { 6.165 if (overrides && super.hasOwnProperty(key)) { 6.166 - super.set(key, value, strict); 6.167 + super.set(key, value, flags); 6.168 } else { 6.169 - callAdaptee(__put__, key, value, strict); 6.170 + callAdaptee(__put__, key, value, flags); 6.171 } 6.172 } 6.173 6.174 @Override 6.175 - public void set(final int key, final double value, final boolean strict) { 6.176 + public void set(final int key, final double value, final int flags) { 6.177 if (overrides && super.hasOwnProperty(key)) { 6.178 - super.set(key, value, strict); 6.179 + super.set(key, value, flags); 6.180 } else { 6.181 - callAdaptee(__put__, key, value, strict); 6.182 + callAdaptee(__put__, key, value, flags); 6.183 } 6.184 } 6.185 6.186 @Override 6.187 - public void set(final int key, final Object value, final boolean strict) { 6.188 + public void set(final int key, final Object value, final int flags) { 6.189 if (overrides && super.hasOwnProperty(key)) { 6.190 - super.set(key, value, strict); 6.191 + super.set(key, value, flags); 6.192 } else { 6.193 - callAdaptee(__put__, key, value, strict); 6.194 + callAdaptee(__put__, key, value, flags); 6.195 } 6.196 } 6.197
7.1 --- a/src/jdk/nashorn/internal/objects/NativeJSON.java Mon Sep 22 14:46:04 2014 +0200 7.2 +++ b/src/jdk/nashorn/internal/objects/NativeJSON.java Mon Sep 22 13:28:28 2014 +0200 7.3 @@ -191,7 +191,7 @@ 7.4 state.gap = gap; 7.5 7.6 final ScriptObject wrapper = Global.newEmptyInstance(); 7.7 - wrapper.set("", value, false); 7.8 + wrapper.set("", value, 0); 7.9 7.10 return str("", wrapper, state); 7.11 }
8.1 --- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Mon Sep 22 14:46:04 2014 +0200 8.2 +++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java Mon Sep 22 13:28:28 2014 +0200 8.3 @@ -146,7 +146,7 @@ 8.4 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 8.5 final Object value = createProperty(name); 8.6 if(value != null) { 8.7 - set(name, value, false); 8.8 + set(name, value, 0); 8.9 return true; 8.10 } 8.11 return false;
9.1 --- a/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java Mon Sep 22 14:46:04 2014 +0200 9.2 +++ b/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java Mon Sep 22 13:28:28 2014 +0200 9.3 @@ -112,82 +112,82 @@ 9.4 } 9.5 9.6 @Override 9.7 - public void set(final double key, final int value, final boolean strict) { 9.8 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.9 + public void set(final double key, final int value, final int flags) { 9.10 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.11 } 9.12 9.13 @Override 9.14 - public void set(final double key, final long value, final boolean strict) { 9.15 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.16 + public void set(final double key, final long value, final int flags) { 9.17 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.18 } 9.19 9.20 @Override 9.21 - public void set(final double key, final double value, final boolean strict) { 9.22 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.23 + public void set(final double key, final double value, final int flags) { 9.24 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.25 } 9.26 9.27 @Override 9.28 - public void set(final double key, final Object value, final boolean strict) { 9.29 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.30 + public void set(final double key, final Object value, final int flags) { 9.31 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.32 } 9.33 9.34 @Override 9.35 - public void set(final long key, final int value, final boolean strict) { 9.36 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.37 + public void set(final long key, final int value, final int flags) { 9.38 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.39 } 9.40 9.41 @Override 9.42 - public void set(final long key, final long value, final boolean strict) { 9.43 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.44 + public void set(final long key, final long value, final int flags) { 9.45 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.46 } 9.47 9.48 @Override 9.49 - public void set(final long key, final double value, final boolean strict) { 9.50 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.51 + public void set(final long key, final double value, final int flags) { 9.52 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.53 } 9.54 9.55 @Override 9.56 - public void set(final long key, final Object value, final boolean strict) { 9.57 - set(JSType.toObject(key), value, strict); 9.58 + public void set(final long key, final Object value, final int flags) { 9.59 + set(JSType.toObject(key), value, flags); 9.60 } 9.61 9.62 @Override 9.63 - public void set(final int key, final int value, final boolean strict) { 9.64 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.65 + public void set(final int key, final int value, final int flags) { 9.66 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.67 } 9.68 9.69 @Override 9.70 - public void set(final int key, final long value, final boolean strict) { 9.71 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.72 + public void set(final int key, final long value, final int flags) { 9.73 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.74 } 9.75 9.76 @Override 9.77 - public void set(final int key, final double value, final boolean strict) { 9.78 - set(JSType.toObject(key), JSType.toObject(value), strict); 9.79 + public void set(final int key, final double value, final int flags) { 9.80 + set(JSType.toObject(key), JSType.toObject(value), flags); 9.81 } 9.82 9.83 @Override 9.84 - public void set(final int key, final Object value, final boolean strict) { 9.85 - set(JSType.toObject(key), value, strict); 9.86 + public void set(final int key, final Object value, final int flags) { 9.87 + set(JSType.toObject(key), value, flags); 9.88 } 9.89 9.90 @Override 9.91 - public void set(final Object key, final int value, final boolean strict) { 9.92 - set(key, JSType.toObject(value), strict); 9.93 + public void set(final Object key, final int value, final int flags) { 9.94 + set(key, JSType.toObject(value), flags); 9.95 } 9.96 9.97 @Override 9.98 - public void set(final Object key, final long value, final boolean strict) { 9.99 - set(key, JSType.toObject(value), strict); 9.100 + public void set(final Object key, final long value, final int flags) { 9.101 + set(key, JSType.toObject(value), flags); 9.102 } 9.103 9.104 @Override 9.105 - public void set(final Object key, final double value, final boolean strict) { 9.106 - set(key, JSType.toObject(value), strict); 9.107 + public void set(final Object key, final double value, final int flags) { 9.108 + set(key, JSType.toObject(value), flags); 9.109 } 9.110 9.111 @Override 9.112 - public abstract void set(Object key, Object value, boolean strict); 9.113 + public abstract void set(Object key, Object value, int flags); 9.114 9.115 @Override 9.116 public abstract boolean has(Object key);
10.1 --- a/src/jdk/nashorn/internal/runtime/ECMAException.java Mon Sep 22 14:46:04 2014 +0200 10.2 +++ b/src/jdk/nashorn/internal/runtime/ECMAException.java Mon Sep 22 13:28:28 2014 +0200 10.3 @@ -285,7 +285,7 @@ 10.4 if (!sobj.has(EXCEPTION_PROPERTY)) { 10.5 sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this); 10.6 } else { 10.7 - sobj.set(EXCEPTION_PROPERTY, this, false); 10.8 + sobj.set(EXCEPTION_PROPERTY, this, 0); 10.9 } 10.10 } 10.11 }
11.1 --- a/src/jdk/nashorn/internal/runtime/FindProperty.java Mon Sep 22 14:46:04 2014 +0200 11.2 +++ b/src/jdk/nashorn/internal/runtime/FindProperty.java Mon Sep 22 13:28:28 2014 +0200 11.3 @@ -139,6 +139,17 @@ 11.4 } 11.5 11.6 /** 11.7 + * Return the {@code ScriptObject} where the search started. This is usually the ScriptObject the 11.8 + * operation was started on, except for properties found inside a 'with' statement, where it is the 11.9 + * top-level 'with' expression object. 11.10 + * 11.11 + * @return the start object. 11.12 + */ 11.13 + public ScriptObject getSelf() { 11.14 + return self; 11.15 + } 11.16 + 11.17 + /** 11.18 * Return the appropriate receiver for a getter. 11.19 * @return appropriate receiver 11.20 */
12.1 --- a/src/jdk/nashorn/internal/runtime/GlobalConstants.java Mon Sep 22 14:46:04 2014 +0200 12.2 +++ b/src/jdk/nashorn/internal/runtime/GlobalConstants.java Mon Sep 22 13:28:28 2014 +0200 12.3 @@ -309,7 +309,7 @@ 12.4 * 12.5 * @param find property lookup 12.6 * @param inv normal guarded invocation for this setter, as computed by the ScriptObject linker 12.7 - * @param desc callsite descriptr 12.8 + * @param desc callsite descriptor 12.9 * @param request link request 12.10 * 12.11 * @return null if failed to set up constant linkage 12.12 @@ -376,8 +376,12 @@ 12.13 * @return resulting getter, or null if failed to create constant 12.14 */ 12.15 synchronized GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc) { 12.16 - // Also return null if property may have side effects 12.17 - if ((GLOBAL_ONLY && !find.getOwner().isGlobal()) || find.getProperty() instanceof UserAccessorProperty) { 12.18 + // Only use constant getter for fast scope access, because the receiver may change between invocations 12.19 + // for slow-scope and non-scope callsites. 12.20 + // Also return null for user accessor properties as they may have side effects. 12.21 + if (!NashornCallSiteDescriptor.isFastScope(desc) 12.22 + || (GLOBAL_ONLY && !find.getOwner().isGlobal()) 12.23 + || find.getProperty() instanceof UserAccessorProperty) { 12.24 return null; 12.25 } 12.26
13.1 --- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java Mon Sep 22 14:46:04 2014 +0200 13.2 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java Mon Sep 22 13:28:28 2014 +0200 13.3 @@ -122,7 +122,7 @@ 13.4 if (newElement == ScriptRuntime.UNDEFINED) { 13.5 valueObj.delete(key, false); 13.6 } else { 13.7 - setPropertyValue(valueObj, key, newElement, false); 13.8 + setPropertyValue(valueObj, key, newElement); 13.9 } 13.10 } 13.11 } 13.12 @@ -179,7 +179,7 @@ 13.13 13.14 final String name = pNode.getKeyName(); 13.15 final Object value = convertNode(global, valueNode); 13.16 - setPropertyValue(object, name, value, false); 13.17 + setPropertyValue(object, name, value); 13.18 } 13.19 13.20 return object; 13.21 @@ -193,14 +193,14 @@ 13.22 } 13.23 13.24 // add a new property if does not exist already, or else set old property 13.25 - private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) { 13.26 + private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value) { 13.27 final int index = ArrayIndex.getArrayIndex(name); 13.28 if (ArrayIndex.isValidArrayIndex(index)) { 13.29 // array index key 13.30 sobj.defineOwnProperty(index, value); 13.31 } else if (sobj.getMap().findProperty(name) != null) { 13.32 // pre-existing non-inherited property, call set 13.33 - sobj.set(name, value, strict); 13.34 + sobj.set(name, value, 0); 13.35 } else { 13.36 // add new property 13.37 sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
14.1 --- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Mon Sep 22 14:46:04 2014 +0200 14.2 +++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java Mon Sep 22 13:28:28 2014 +0200 14.3 @@ -256,7 +256,7 @@ 14.4 final Object constructor = BeansLinker.getConstructorMethod( 14.5 javaClass, propertyName.substring(openBrace + 1, lastChar)); 14.6 if (constructor != null) { 14.7 - set(propertyName, constructor, false); 14.8 + set(propertyName, constructor, 0); 14.9 return constructor; 14.10 } 14.11 // we didn't find a matching constructor! 14.12 @@ -270,7 +270,7 @@ 14.13 propertyValue = StaticClass.forClass(javaClass); 14.14 } 14.15 14.16 - set(propertyName, propertyValue, false); 14.17 + set(propertyName, propertyValue, 0); 14.18 return propertyValue; 14.19 } 14.20 }
15.1 --- a/src/jdk/nashorn/internal/runtime/PropertyAccess.java Mon Sep 22 14:46:04 2014 +0200 15.2 +++ b/src/jdk/nashorn/internal/runtime/PropertyAccess.java Mon Sep 22 13:28:28 2014 +0200 15.3 @@ -163,129 +163,129 @@ 15.4 * Set the value of a given key 15.5 * @param key the key 15.6 * @param value the value 15.7 - * @param strict are we in strict mode 15.8 + * @param flags call site flags 15.9 */ 15.10 - public void set(Object key, int value, boolean strict); 15.11 + public void set(Object key, int value, int flags); 15.12 15.13 /** 15.14 * Set the value of a given key 15.15 * @param key the key 15.16 * @param value the value 15.17 - * @param strict are we in strict mode 15.18 + * @param flags call site flags 15.19 */ 15.20 - public void set(Object key, long value, boolean strict); 15.21 + public void set(Object key, long value, int flags); 15.22 15.23 /** 15.24 * Set the value of a given key 15.25 * @param key the key 15.26 * @param value the value 15.27 - * @param strict are we in strict mode 15.28 + * @param flags call site flags 15.29 */ 15.30 - public void set(Object key, double value, boolean strict); 15.31 + public void set(Object key, double value, int flags); 15.32 15.33 /** 15.34 * Set the value of a given key 15.35 * @param key the key 15.36 * @param value the value 15.37 - * @param strict are we in strict mode 15.38 + * @param flags call site flags 15.39 */ 15.40 - public void set(Object key, Object value, boolean strict); 15.41 + public void set(Object key, Object value, int flags); 15.42 15.43 /** 15.44 * Set the value of a given key 15.45 * @param key the key 15.46 * @param value the value 15.47 - * @param strict are we in strict mode 15.48 + * @param flags call site flags 15.49 */ 15.50 - public void set(double key, int value, boolean strict); 15.51 + public void set(double key, int value, int flags); 15.52 15.53 /** 15.54 * Set the value of a given key 15.55 * @param key the key 15.56 * @param value the value 15.57 - * @param strict are we in strict mode 15.58 + * @param flags call site flags 15.59 */ 15.60 - public void set(double key, long value, boolean strict); 15.61 + public void set(double key, long value, int flags); 15.62 15.63 /** 15.64 * Set the value of a given key 15.65 * @param key the key 15.66 * @param value the value 15.67 - * @param strict are we in strict mode 15.68 + * @param flags call site flags 15.69 */ 15.70 - public void set(double key, double value, boolean strict); 15.71 + public void set(double key, double value, int flags); 15.72 15.73 /** 15.74 * Set the value of a given key 15.75 * @param key the key 15.76 * @param value the value 15.77 - * @param strict are we in strict mode 15.78 + * @param flags call site flags 15.79 */ 15.80 - public void set(double key, Object value, boolean strict); 15.81 + public void set(double key, Object value, int flags); 15.82 15.83 /** 15.84 * Set the value of a given key 15.85 * @param key the key 15.86 * @param value the value 15.87 - * @param strict are we in strict mode 15.88 + * @param flags call site flags 15.89 */ 15.90 - public void set(long key, int value, boolean strict); 15.91 + public void set(long key, int value, int flags); 15.92 15.93 /** 15.94 * Set the value of a given key 15.95 * @param key the key 15.96 * @param value the value 15.97 - * @param strict are we in strict mode 15.98 + * @param flags call site flags 15.99 */ 15.100 - public void set(long key, long value, boolean strict); 15.101 + public void set(long key, long value, int flags); 15.102 15.103 /** 15.104 * Set the value of a given key 15.105 * @param key the key 15.106 * @param value the value 15.107 - * @param strict are we in strict mode 15.108 + * @param flags call site flags 15.109 */ 15.110 - public void set(long key, double value, boolean strict); 15.111 + public void set(long key, double value, int flags); 15.112 15.113 /** 15.114 * Set the value of a given key 15.115 * @param key the key 15.116 * @param value the value 15.117 - * @param strict are we in strict mode 15.118 + * @param flags call site flags 15.119 */ 15.120 - public void set(long key, Object value, boolean strict); 15.121 + public void set(long key, Object value, int flags); 15.122 15.123 /** 15.124 * Set the value of a given key 15.125 * @param key the key 15.126 * @param value the value 15.127 - * @param strict are we in strict mode 15.128 + * @param flags call site flags 15.129 */ 15.130 - public void set(int key, int value, boolean strict); 15.131 + public void set(int key, int value, int flags); 15.132 15.133 /** 15.134 * Set the value of a given key 15.135 * @param key the key 15.136 * @param value the value 15.137 - * @param strict are we in strict mode 15.138 + * @param flags call site flags 15.139 */ 15.140 - public void set(int key, long value, boolean strict); 15.141 + public void set(int key, long value, int flags); 15.142 15.143 /** 15.144 * Set the value of a given key 15.145 * @param key the key 15.146 * @param value the value 15.147 - * @param strict are we in strict mode 15.148 + * @param flags call site flags 15.149 */ 15.150 - public void set(int key, double value, boolean strict); 15.151 + public void set(int key, double value, int flags); 15.152 15.153 /** 15.154 * Set the value of a given key 15.155 * @param key the key 15.156 * @param value the value 15.157 - * @param strict are we in strict mode 15.158 + * @param flags call site flags 15.159 */ 15.160 - public void set(int key, Object value, boolean strict); 15.161 + public void set(int key, Object value, int flags); 15.162 15.163 /** 15.164 * Check if the given key exists anywhere in the proto chain
16.1 --- a/src/jdk/nashorn/internal/runtime/RewriteException.java Mon Sep 22 14:46:04 2014 +0200 16.2 +++ b/src/jdk/nashorn/internal/runtime/RewriteException.java Mon Sep 22 13:28:28 2014 +0200 16.3 @@ -45,6 +45,7 @@ 16.4 import jdk.nashorn.internal.lookup.MethodHandleFactory; 16.5 import jdk.nashorn.internal.lookup.MethodHandleFunctionality; 16.6 import jdk.nashorn.internal.objects.Global; 16.7 +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 16.8 16.9 /** 16.10 * Used to signal to the linker to relink the callee 16.11 @@ -161,7 +162,7 @@ 16.12 assert runtimeScope == null; 16.13 runtimeScope = (ScriptObject)value; 16.14 } else if(name != null) { 16.15 - locals.set(name, value, true); 16.16 + locals.set(name, value, NashornCallSiteDescriptor.CALLSITE_STRICT); 16.17 } 16.18 } 16.19 locals.setProto(runtimeScope);
17.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Sep 22 14:46:04 2014 +0200 17.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Sep 22 13:28:28 2014 +0200 17.3 @@ -198,10 +198,10 @@ 17.4 public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class); 17.5 17.6 static final MethodHandle[] SET_SLOW = new MethodHandle[] { 17.7 - findOwnMH_V("set", void.class, Object.class, int.class, boolean.class), 17.8 - findOwnMH_V("set", void.class, Object.class, long.class, boolean.class), 17.9 - findOwnMH_V("set", void.class, Object.class, double.class, boolean.class), 17.10 - findOwnMH_V("set", void.class, Object.class, Object.class, boolean.class) 17.11 + findOwnMH_V("set", void.class, Object.class, int.class, int.class), 17.12 + findOwnMH_V("set", void.class, Object.class, long.class, int.class), 17.13 + findOwnMH_V("set", void.class, Object.class, double.class, int.class), 17.14 + findOwnMH_V("set", void.class, Object.class, Object.class, int.class) 17.15 }; 17.16 17.17 /** Method handle to reset the map of this ScriptObject */ 17.18 @@ -593,7 +593,7 @@ 17.19 if (newValue && property != null) { 17.20 // Temporarily clear flags. 17.21 property = modifyOwnProperty(property, 0); 17.22 - set(key, value, false); 17.23 + set(key, value, 0); 17.24 //this might change the map if we change types of the property 17.25 //hence we need to read it again. note that we should probably 17.26 //have the setter return the new property throughout and in 17.27 @@ -758,7 +758,7 @@ 17.28 * @return FindPropertyData or null if not found. 17.29 */ 17.30 public final FindProperty findProperty(final String key, final boolean deep) { 17.31 - return findProperty(key, deep, false, this); 17.32 + return findProperty(key, deep, this); 17.33 } 17.34 17.35 /** 17.36 @@ -775,16 +775,11 @@ 17.37 * 17.38 * @param key Property key. 17.39 * @param deep Whether the search should look up proto chain. 17.40 - * @param stopOnNonScope should a deep search stop on the first non-scope object? 17.41 * @param start the object on which the lookup was originally initiated 17.42 * 17.43 * @return FindPropertyData or null if not found. 17.44 */ 17.45 - FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) { 17.46 - // if doing deep search, stop search on the first non-scope object if asked to do so 17.47 - if (stopOnNonScope && start != this && !isScope()) { 17.48 - return null; 17.49 - } 17.50 + FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) { 17.51 17.52 final PropertyMap selfMap = getMap(); 17.53 final Property property = selfMap.findProperty(key); 17.54 @@ -796,7 +791,7 @@ 17.55 if (deep) { 17.56 final ScriptObject myProto = getProto(); 17.57 if (myProto != null) { 17.58 - return myProto.findProperty(key, deep, stopOnNonScope, start); 17.59 + return myProto.findProperty(key, deep, start); 17.60 } 17.61 } 17.62 17.63 @@ -1164,7 +1159,7 @@ 17.64 * @param value the value to write at the given index 17.65 */ 17.66 public void setArgument(final int key, final Object value) { 17.67 - set(key, value, false); 17.68 + set(key, value, 0); 17.69 } 17.70 17.71 /** 17.72 @@ -1725,7 +1720,8 @@ 17.73 */ 17.74 public Object put(final Object key, final Object value, final boolean strict) { 17.75 final Object oldValue = get(key); 17.76 - set(key, value, strict); 17.77 + final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; 17.78 + set(key, value, flags); 17.79 return oldValue; 17.80 } 17.81 17.82 @@ -1738,8 +1734,9 @@ 17.83 * @param strict strict mode or not 17.84 */ 17.85 public void putAll(final Map<?, ?> otherMap, final boolean strict) { 17.86 + final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0; 17.87 for (final Map.Entry<?, ?> entry : otherMap.entrySet()) { 17.88 - set(entry.getKey(), entry.getValue(), strict); 17.89 + set(entry.getKey(), entry.getValue(), flags); 17.90 } 17.91 } 17.92 17.93 @@ -2042,7 +2039,7 @@ 17.94 17.95 final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION)); 17.96 setMap(newMap); 17.97 - set(key, value, true); 17.98 + set(key, value, 0); 17.99 } 17.100 17.101 /** 17.102 @@ -2135,7 +2132,6 @@ 17.103 return findMegaMorphicSetMethod(desc, name); 17.104 } 17.105 17.106 - final boolean scope = isScope(); 17.107 final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request); 17.108 17.109 /* 17.110 @@ -2145,16 +2141,18 @@ 17.111 * 17.112 * toString = function() { print("global toString"); } // don't affect Object.prototype.toString 17.113 */ 17.114 - FindProperty find = findProperty(name, true, scope, this); 17.115 + FindProperty find = findProperty(name, true, this); 17.116 17.117 // If it's not a scope search, then we don't want any inherited properties except those with user defined accessors. 17.118 - if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { 17.119 + if (find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) { 17.120 // We should still check if inherited data property is not writable 17.121 if (isExtensible() && !find.getProperty().isWritable()) { 17.122 - return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", false); 17.123 + return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true); 17.124 } 17.125 - // Otherwise, forget the found property 17.126 - find = null; 17.127 + // Otherwise, forget the found property unless this is a scope callsite and the owner is a scope object as well. 17.128 + if (!NashornCallSiteDescriptor.isScope(desc) || !find.getOwner().isScope()) { 17.129 + find = null; 17.130 + } 17.131 } 17.132 17.133 if (find != null) { 17.134 @@ -2180,8 +2178,8 @@ 17.135 17.136 private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String strictErrorMessage, final boolean canBeFastScope) { 17.137 final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND); 17.138 - if (NashornCallSiteDescriptor.isStrict(desc)) { 17.139 - throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this)); 17.140 + if (NashornCallSiteDescriptor.isStrict(desc)) { 17.141 + throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this)); 17.142 } 17.143 assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc); 17.144 return new GuardedInvocation( 17.145 @@ -2207,7 +2205,7 @@ 17.146 private GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) { 17.147 final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class); 17.148 //never bother with ClassCastExceptionGuard for megamorphic callsites 17.149 - final GuardedInvocation inv = findSetIndexMethod(getClass(), false, type, NashornCallSiteDescriptor.isStrict(desc)); 17.150 + final GuardedInvocation inv = findSetIndexMethod(getClass(), desc, false, type); 17.151 return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard()); 17.152 } 17.153 17.154 @@ -2230,24 +2228,26 @@ 17.155 * @return GuardedInvocation to be invoked at call site. 17.156 */ 17.157 protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value 17.158 - return findSetIndexMethod(getClass(), explicitInstanceOfCheck(desc, request), desc.getMethodType(), NashornCallSiteDescriptor.isStrict(desc)); 17.159 + return findSetIndexMethod(getClass(), desc, explicitInstanceOfCheck(desc, request), desc.getMethodType()); 17.160 } 17.161 17.162 /** 17.163 * Find the appropriate SETINDEX method for an invoke dynamic call. 17.164 * 17.165 + * @param clazz the receiver class 17.166 + * @param desc the call site descriptor 17.167 + * @param explicitInstanceOfCheck add an explicit instanceof check? 17.168 * @param callType the method type at the call site 17.169 - * @param isStrict are we in strict mode? 17.170 * 17.171 * @return GuardedInvocation to be invoked at call site. 17.172 */ 17.173 - private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final boolean explicitInstanceOfCheck, final MethodType callType, final boolean isStrict) { 17.174 + private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final MethodType callType) { 17.175 assert callType.parameterCount() == 3; 17.176 final Class<?> keyClass = callType.parameterType(1); 17.177 final Class<?> valueClass = callType.parameterType(2); 17.178 17.179 - MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, boolean.class); 17.180 - methodHandle = MH.insertArguments(methodHandle, 3, isStrict); 17.181 + MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, int.class); 17.182 + methodHandle = MH.insertArguments(methodHandle, 3, NashornCallSiteDescriptor.getFlags(desc)); 17.183 17.184 return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class); 17.185 } 17.186 @@ -2672,7 +2672,7 @@ 17.187 if (isValidArrayIndex(index)) { 17.188 for (ScriptObject object = this; ; ) { 17.189 if (object.getMap().containsArrayKeys()) { 17.190 - final FindProperty find = object.findProperty(key, false, false, this); 17.191 + final FindProperty find = object.findProperty(key, false, this); 17.192 17.193 if (find != null) { 17.194 return getIntValue(find, programPoint); 17.195 @@ -2755,7 +2755,7 @@ 17.196 if (isValidArrayIndex(index)) { 17.197 for (ScriptObject object = this; ; ) { 17.198 if (object.getMap().containsArrayKeys()) { 17.199 - final FindProperty find = object.findProperty(key, false, false, this); 17.200 + final FindProperty find = object.findProperty(key, false, this); 17.201 if (find != null) { 17.202 return getLongValue(find, programPoint); 17.203 } 17.204 @@ -2837,7 +2837,7 @@ 17.205 if (isValidArrayIndex(index)) { 17.206 for (ScriptObject object = this; ; ) { 17.207 if (object.getMap().containsArrayKeys()) { 17.208 - final FindProperty find = object.findProperty(key, false, false, this); 17.209 + final FindProperty find = object.findProperty(key, false, this); 17.210 if (find != null) { 17.211 return getDoubleValue(find, programPoint); 17.212 } 17.213 @@ -2919,7 +2919,7 @@ 17.214 if (isValidArrayIndex(index)) { 17.215 for (ScriptObject object = this; ; ) { 17.216 if (object.getMap().containsArrayKeys()) { 17.217 - final FindProperty find = object.findProperty(key, false, false, this); 17.218 + final FindProperty find = object.findProperty(key, false, this); 17.219 17.220 if (find != null) { 17.221 return find.getObjectValue(); 17.222 @@ -2996,48 +2996,48 @@ 17.223 return get(index, JSType.toString(key)); 17.224 } 17.225 17.226 - private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final boolean strict) { 17.227 + private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final int callSiteFlags) { 17.228 if (getMap().containsArrayKeys()) { 17.229 final String key = JSType.toString(longIndex); 17.230 final FindProperty find = findProperty(key, true); 17.231 if (find != null) { 17.232 - setObject(find, strict, key, value); 17.233 + setObject(find, callSiteFlags, key, value); 17.234 return true; 17.235 } 17.236 } 17.237 return false; 17.238 } 17.239 17.240 - private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final boolean strict) { 17.241 + private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final int callSiteFlags) { 17.242 if (getMap().containsArrayKeys()) { 17.243 final String key = JSType.toString(longIndex); 17.244 final FindProperty find = findProperty(key, true); 17.245 if (find != null) { 17.246 - setObject(find, strict, key, value); 17.247 + setObject(find, callSiteFlags, key, value); 17.248 return true; 17.249 } 17.250 } 17.251 return false; 17.252 } 17.253 17.254 - private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final boolean strict) { 17.255 + private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final int callSiteFlags) { 17.256 if (getMap().containsArrayKeys()) { 17.257 final String key = JSType.toString(longIndex); 17.258 final FindProperty find = findProperty(key, true); 17.259 if (find != null) { 17.260 - setObject(find, strict, key, value); 17.261 + setObject(find, callSiteFlags, key, value); 17.262 return true; 17.263 } 17.264 } 17.265 return false; 17.266 } 17.267 17.268 - private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final boolean strict) { 17.269 + private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final int callSiteFlags) { 17.270 if (getMap().containsArrayKeys()) { 17.271 final String key = JSType.toString(longIndex); 17.272 final FindProperty find = findProperty(key, true); 17.273 if (find != null) { 17.274 - setObject(find, strict, key, value); 17.275 + setObject(find, callSiteFlags, key, value); 17.276 return true; 17.277 } 17.278 } 17.279 @@ -3045,10 +3045,10 @@ 17.280 } 17.281 17.282 //value agnostic 17.283 - private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final boolean strict) { 17.284 + private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) { 17.285 if (longIndex >= oldLength) { 17.286 if (!isExtensible()) { 17.287 - if (strict) { 17.288 + if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { 17.289 throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this)); 17.290 } 17.291 return true; 17.292 @@ -3068,37 +3068,41 @@ 17.293 } 17.294 } 17.295 17.296 - private void doesNotHave(final int index, final int value, final boolean strict) { 17.297 + private void doesNotHave(final int index, final int value, final int callSiteFlags) { 17.298 final long oldLength = getArray().length(); 17.299 final long longIndex = ArrayIndex.toLongIndex(index); 17.300 - if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) { 17.301 + if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { 17.302 + final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); 17.303 setArray(getArray().set(index, value, strict)); 17.304 doesNotHaveEnsureDelete(longIndex, oldLength, strict); 17.305 } 17.306 } 17.307 17.308 - private void doesNotHave(final int index, final long value, final boolean strict) { 17.309 + private void doesNotHave(final int index, final long value, final int callSiteFlags) { 17.310 final long oldLength = getArray().length(); 17.311 final long longIndex = ArrayIndex.toLongIndex(index); 17.312 - if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) { 17.313 + if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { 17.314 + final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); 17.315 setArray(getArray().set(index, value, strict)); 17.316 doesNotHaveEnsureDelete(longIndex, oldLength, strict); 17.317 } 17.318 } 17.319 17.320 - private void doesNotHave(final int index, final double value, final boolean strict) { 17.321 + private void doesNotHave(final int index, final double value, final int callSiteFlags) { 17.322 final long oldLength = getArray().length(); 17.323 final long longIndex = ArrayIndex.toLongIndex(index); 17.324 - if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) { 17.325 + if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { 17.326 + final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); 17.327 setArray(getArray().set(index, value, strict)); 17.328 doesNotHaveEnsureDelete(longIndex, oldLength, strict); 17.329 } 17.330 } 17.331 17.332 - private void doesNotHave(final int index, final Object value, final boolean strict) { 17.333 + private void doesNotHave(final int index, final Object value, final int callSiteFlags) { 17.334 final long oldLength = getArray().length(); 17.335 final long longIndex = ArrayIndex.toLongIndex(index); 17.336 - if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) { 17.337 + if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) { 17.338 + final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags); 17.339 setArray(getArray().set(index, value, strict)); 17.340 doesNotHaveEnsureDelete(longIndex, oldLength, strict); 17.341 } 17.342 @@ -3108,32 +3112,47 @@ 17.343 * This is the most generic of all Object setters. Most of the others use this in some form. 17.344 * TODO: should be further specialized 17.345 * 17.346 - * @param find found property 17.347 - * @param strict are we in strict mode 17.348 - * @param key property key 17.349 - * @param value property value 17.350 + * @param find found property 17.351 + * @param callSiteFlags callsite flags 17.352 + * @param key property key 17.353 + * @param value property value 17.354 */ 17.355 - public final void setObject(final FindProperty find, final boolean strict, final String key, final Object value) { 17.356 + public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) { 17.357 FindProperty f = find; 17.358 17.359 - if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty) && !isScope()) { 17.360 - // Setting a property should not modify the property in prototype unless this is a scope object. 17.361 - f = null; 17.362 + if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) { 17.363 + final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags); 17.364 + // If the start object of the find is not this object it means the property was found inside a 17.365 + // 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set' 17.366 + // to the 'with' object. 17.367 + // Note that although a 'set' operation involving a with statement follows scope rules outside 17.368 + // the 'with' expression (the 'set' operation is performed on the owning prototype if it exists), 17.369 + // it follows non-scope rules inside the 'with' expression (set is performed on the top level object). 17.370 + // This is why we clear the callsite flags and FindProperty in the forward call to the 'with' object. 17.371 + if (isScope && f.getSelf() != this) { 17.372 + f.getSelf().setObject(null, 0, key, value); 17.373 + return; 17.374 + } 17.375 + // Setting a property should not modify the property in prototype unless this is a scope callsite 17.376 + // and the owner is a scope object as well (with the exception of 'with' statement handled above). 17.377 + if (!isScope || !f.getOwner().isScope()) { 17.378 + f = null; 17.379 + } 17.380 } 17.381 17.382 if (f != null) { 17.383 if (!f.getProperty().isWritable()) { 17.384 - if (strict) { 17.385 + if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { 17.386 throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this)); 17.387 } 17.388 17.389 return; 17.390 } 17.391 17.392 - f.setValue(value, strict); 17.393 + f.setValue(value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)); 17.394 17.395 } else if (!isExtensible()) { 17.396 - if (strict) { 17.397 + if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) { 17.398 throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this)); 17.399 } 17.400 } else { 17.401 @@ -3153,293 +3172,293 @@ 17.402 } 17.403 17.404 @Override 17.405 - public void set(final Object key, final int value, final boolean strict) { 17.406 + public void set(final Object key, final int value, final int callSiteFlags) { 17.407 final Object primitiveKey = JSType.toPrimitive(key, String.class); 17.408 final int index = getArrayIndex(primitiveKey); 17.409 17.410 if (isValidArrayIndex(index)) { 17.411 if (getArray().has(index)) { 17.412 - setArray(getArray().set(index, value, strict)); 17.413 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.414 } else { 17.415 - doesNotHave(index, value, strict); 17.416 + doesNotHave(index, value, callSiteFlags); 17.417 } 17.418 17.419 return; 17.420 } 17.421 17.422 final String propName = JSType.toString(primitiveKey); 17.423 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.424 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.425 } 17.426 17.427 @Override 17.428 - public void set(final Object key, final long value, final boolean strict) { 17.429 + public void set(final Object key, final long value, final int callSiteFlags) { 17.430 final Object primitiveKey = JSType.toPrimitive(key, String.class); 17.431 final int index = getArrayIndex(primitiveKey); 17.432 17.433 if (isValidArrayIndex(index)) { 17.434 if (getArray().has(index)) { 17.435 - setArray(getArray().set(index, value, strict)); 17.436 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.437 } else { 17.438 - doesNotHave(index, value, strict); 17.439 + doesNotHave(index, value, callSiteFlags); 17.440 } 17.441 17.442 return; 17.443 } 17.444 17.445 final String propName = JSType.toString(primitiveKey); 17.446 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.447 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.448 } 17.449 17.450 @Override 17.451 - public void set(final Object key, final double value, final boolean strict) { 17.452 + public void set(final Object key, final double value, final int callSiteFlags) { 17.453 final Object primitiveKey = JSType.toPrimitive(key, String.class); 17.454 final int index = getArrayIndex(primitiveKey); 17.455 17.456 if (isValidArrayIndex(index)) { 17.457 if (getArray().has(index)) { 17.458 - setArray(getArray().set(index, value, strict)); 17.459 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.460 } else { 17.461 - doesNotHave(index, value, strict); 17.462 + doesNotHave(index, value, callSiteFlags); 17.463 } 17.464 17.465 return; 17.466 } 17.467 17.468 final String propName = JSType.toString(primitiveKey); 17.469 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.470 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.471 } 17.472 17.473 @Override 17.474 - public void set(final Object key, final Object value, final boolean strict) { 17.475 + public void set(final Object key, final Object value, final int callSiteFlags) { 17.476 final Object primitiveKey = JSType.toPrimitive(key, String.class); 17.477 final int index = getArrayIndex(primitiveKey); 17.478 17.479 if (isValidArrayIndex(index)) { 17.480 if (getArray().has(index)) { 17.481 - setArray(getArray().set(index, value, strict)); 17.482 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.483 } else { 17.484 - doesNotHave(index, value, strict); 17.485 + doesNotHave(index, value, callSiteFlags); 17.486 } 17.487 17.488 return; 17.489 } 17.490 17.491 final String propName = JSType.toString(primitiveKey); 17.492 - setObject(findProperty(propName, true), strict, propName, value); 17.493 + setObject(findProperty(propName, true), callSiteFlags, propName, value); 17.494 } 17.495 17.496 @Override 17.497 - public void set(final double key, final int value, final boolean strict) { 17.498 + public void set(final double key, final int value, final int callSiteFlags) { 17.499 final int index = getArrayIndex(key); 17.500 17.501 if (isValidArrayIndex(index)) { 17.502 if (getArray().has(index)) { 17.503 - setArray(getArray().set(index, value, strict)); 17.504 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.505 } else { 17.506 - doesNotHave(index, value, strict); 17.507 + doesNotHave(index, value, callSiteFlags); 17.508 } 17.509 17.510 return; 17.511 } 17.512 17.513 final String propName = JSType.toString(key); 17.514 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.515 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.516 } 17.517 17.518 @Override 17.519 - public void set(final double key, final long value, final boolean strict) { 17.520 + public void set(final double key, final long value, final int callSiteFlags) { 17.521 final int index = getArrayIndex(key); 17.522 17.523 if (isValidArrayIndex(index)) { 17.524 if (getArray().has(index)) { 17.525 - setArray(getArray().set(index, value, strict)); 17.526 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.527 } else { 17.528 - doesNotHave(index, value, strict); 17.529 + doesNotHave(index, value, callSiteFlags); 17.530 } 17.531 17.532 return; 17.533 } 17.534 17.535 final String propName = JSType.toString(key); 17.536 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.537 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.538 } 17.539 17.540 @Override 17.541 - public void set(final double key, final double value, final boolean strict) { 17.542 + public void set(final double key, final double value, final int callSiteFlags) { 17.543 final int index = getArrayIndex(key); 17.544 17.545 if (isValidArrayIndex(index)) { 17.546 if (getArray().has(index)) { 17.547 - setArray(getArray().set(index, value, strict)); 17.548 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.549 } else { 17.550 - doesNotHave(index, value, strict); 17.551 + doesNotHave(index, value, callSiteFlags); 17.552 } 17.553 17.554 return; 17.555 } 17.556 17.557 final String propName = JSType.toString(key); 17.558 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.559 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.560 } 17.561 17.562 @Override 17.563 - public void set(final double key, final Object value, final boolean strict) { 17.564 + public void set(final double key, final Object value, final int callSiteFlags) { 17.565 final int index = getArrayIndex(key); 17.566 17.567 if (isValidArrayIndex(index)) { 17.568 if (getArray().has(index)) { 17.569 - setArray(getArray().set(index, value, strict)); 17.570 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.571 } else { 17.572 - doesNotHave(index, value, strict); 17.573 + doesNotHave(index, value, callSiteFlags); 17.574 } 17.575 17.576 return; 17.577 } 17.578 17.579 final String propName = JSType.toString(key); 17.580 - setObject(findProperty(propName, true), strict, propName, value); 17.581 + setObject(findProperty(propName, true), callSiteFlags, propName, value); 17.582 } 17.583 17.584 @Override 17.585 - public void set(final long key, final int value, final boolean strict) { 17.586 + public void set(final long key, final int value, final int callSiteFlags) { 17.587 final int index = getArrayIndex(key); 17.588 17.589 if (isValidArrayIndex(index)) { 17.590 if (getArray().has(index)) { 17.591 - setArray(getArray().set(index, value, strict)); 17.592 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.593 } else { 17.594 - doesNotHave(index, value, strict); 17.595 + doesNotHave(index, value, callSiteFlags); 17.596 } 17.597 17.598 return; 17.599 } 17.600 17.601 final String propName = JSType.toString(key); 17.602 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.603 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.604 } 17.605 17.606 @Override 17.607 - public void set(final long key, final long value, final boolean strict) { 17.608 + public void set(final long key, final long value, final int callSiteFlags) { 17.609 final int index = getArrayIndex(key); 17.610 17.611 if (isValidArrayIndex(index)) { 17.612 if (getArray().has(index)) { 17.613 - setArray(getArray().set(index, value, strict)); 17.614 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.615 } else { 17.616 - doesNotHave(index, value, strict); 17.617 + doesNotHave(index, value, callSiteFlags); 17.618 } 17.619 17.620 return; 17.621 } 17.622 17.623 final String propName = JSType.toString(key); 17.624 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.625 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.626 } 17.627 17.628 @Override 17.629 - public void set(final long key, final double value, final boolean strict) { 17.630 + public void set(final long key, final double value, final int callSiteFlags) { 17.631 final int index = getArrayIndex(key); 17.632 17.633 if (isValidArrayIndex(index)) { 17.634 if (getArray().has(index)) { 17.635 - setArray(getArray().set(index, value, strict)); 17.636 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.637 } else { 17.638 - doesNotHave(index, value, strict); 17.639 + doesNotHave(index, value, callSiteFlags); 17.640 } 17.641 17.642 return; 17.643 } 17.644 17.645 final String propName = JSType.toString(key); 17.646 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.647 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.648 } 17.649 17.650 @Override 17.651 - public void set(final long key, final Object value, final boolean strict) { 17.652 + public void set(final long key, final Object value, final int callSiteFlags) { 17.653 final int index = getArrayIndex(key); 17.654 17.655 if (isValidArrayIndex(index)) { 17.656 if (getArray().has(index)) { 17.657 - setArray(getArray().set(index, value, strict)); 17.658 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.659 } else { 17.660 - doesNotHave(index, value, strict); 17.661 + doesNotHave(index, value, callSiteFlags); 17.662 } 17.663 17.664 return; 17.665 } 17.666 17.667 final String propName = JSType.toString(key); 17.668 - setObject(findProperty(propName, true), strict, propName, value); 17.669 + setObject(findProperty(propName, true), callSiteFlags, propName, value); 17.670 } 17.671 17.672 @Override 17.673 - public void set(final int key, final int value, final boolean strict) { 17.674 + public void set(final int key, final int value, final int callSiteFlags) { 17.675 final int index = getArrayIndex(key); 17.676 if (isValidArrayIndex(index)) { 17.677 if (getArray().has(index)) { 17.678 - setArray(getArray().set(index, value, strict)); 17.679 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.680 } else { 17.681 - doesNotHave(index, value, strict); 17.682 + doesNotHave(index, value, callSiteFlags); 17.683 } 17.684 return; 17.685 } 17.686 17.687 final String propName = JSType.toString(key); 17.688 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.689 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.690 } 17.691 17.692 @Override 17.693 - public void set(final int key, final long value, final boolean strict) { 17.694 + public void set(final int key, final long value, final int callSiteFlags) { 17.695 final int index = getArrayIndex(key); 17.696 17.697 if (isValidArrayIndex(index)) { 17.698 if (getArray().has(index)) { 17.699 - setArray(getArray().set(index, value, strict)); 17.700 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.701 } else { 17.702 - doesNotHave(index, value, strict); 17.703 + doesNotHave(index, value, callSiteFlags); 17.704 } 17.705 17.706 return; 17.707 } 17.708 17.709 final String propName = JSType.toString(key); 17.710 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.711 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.712 } 17.713 17.714 @Override 17.715 - public void set(final int key, final double value, final boolean strict) { 17.716 + public void set(final int key, final double value, final int callSiteFlags) { 17.717 final int index = getArrayIndex(key); 17.718 17.719 if (isValidArrayIndex(index)) { 17.720 if (getArray().has(index)) { 17.721 - setArray(getArray().set(index, value, strict)); 17.722 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.723 } else { 17.724 - doesNotHave(index, value, strict); 17.725 + doesNotHave(index, value, callSiteFlags); 17.726 } 17.727 17.728 return; 17.729 } 17.730 17.731 final String propName = JSType.toString(key); 17.732 - setObject(findProperty(propName, true), strict, propName, JSType.toObject(value)); 17.733 + setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value)); 17.734 } 17.735 17.736 @Override 17.737 - public void set(final int key, final Object value, final boolean strict) { 17.738 + public void set(final int key, final Object value, final int callSiteFlags) { 17.739 final int index = getArrayIndex(key); 17.740 17.741 if (isValidArrayIndex(index)) { 17.742 if (getArray().has(index)) { 17.743 - setArray(getArray().set(index, value, strict)); 17.744 + setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags))); 17.745 } else { 17.746 - doesNotHave(index, value, strict); 17.747 + doesNotHave(index, value, callSiteFlags); 17.748 } 17.749 17.750 return; 17.751 } 17.752 17.753 final String propName = JSType.toString(key); 17.754 - setObject(findProperty(propName, true), strict, propName, value); 17.755 + setObject(findProperty(propName, true), callSiteFlags, propName, value); 17.756 } 17.757 17.758 @Override
18.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Mon Sep 22 14:46:04 2014 +0200 18.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Mon Sep 22 13:28:28 2014 +0200 18.3 @@ -221,9 +221,9 @@ 18.4 final String err = errBuffer.toString(); 18.5 18.6 // Set globals for secondary results. 18.7 - global.set(OUT_NAME, out, false); 18.8 - global.set(ERR_NAME, err, false); 18.9 - global.set(EXIT_NAME, exit, false); 18.10 + global.set(OUT_NAME, out, 0); 18.11 + global.set(ERR_NAME, err, 0); 18.12 + global.set(EXIT_NAME, exit, 0); 18.13 18.14 // Propagate exception if present. 18.15 for (final IOException element : exception) {
19.1 --- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Mon Sep 22 14:46:04 2014 +0200 19.2 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Mon Sep 22 13:28:28 2014 +0200 19.3 @@ -205,7 +205,7 @@ 19.4 19.5 //slow setter, that calls ScriptObject.set with appropraite type and key name 19.6 MethodHandle slowSetter = ScriptObject.SET_SLOW[getAccessorTypeIndex(type)]; 19.7 - slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.isStrict(desc)); 19.8 + slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.getFlags(desc)); 19.9 slowSetter = MH.insertArguments(slowSetter, 1, name); 19.10 slowSetter = MH.asType(slowSetter, slowSetter.type().changeParameterType(0, Object.class)); 19.11
20.1 --- a/src/jdk/nashorn/internal/runtime/Undefined.java Mon Sep 22 14:46:04 2014 +0200 20.2 +++ b/src/jdk/nashorn/internal/runtime/Undefined.java Mon Sep 22 13:28:28 2014 +0200 20.3 @@ -34,6 +34,7 @@ 20.4 import jdk.internal.dynalink.linker.GuardedInvocation; 20.5 import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 20.6 import jdk.internal.dynalink.support.Guards; 20.7 +import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; 20.8 20.9 /** 20.10 * Unique instance of this class is used to represent JavaScript undefined. 20.11 @@ -128,7 +129,7 @@ 20.12 } 20.13 20.14 private static final MethodHandle GET_METHOD = findOwnMH("get", Object.class, Object.class); 20.15 - private static final MethodHandle SET_METHOD = MH.insertArguments(findOwnMH("set", void.class, Object.class, Object.class, boolean.class), 3, Boolean.TRUE); 20.16 + private static final MethodHandle SET_METHOD = MH.insertArguments(findOwnMH("set", void.class, Object.class, Object.class, int.class), 3, NashornCallSiteDescriptor.CALLSITE_STRICT); 20.17 20.18 private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) { 20.19 return new GuardedInvocation(MH.insertArguments(GET_METHOD, 1, desc.getNameToken(2)), UNDEFINED_GUARD).asType(desc); 20.20 @@ -152,7 +153,7 @@ 20.21 } 20.22 20.23 @Override 20.24 - public void set(final Object key, final Object value, final boolean strict) { 20.25 + public void set(final Object key, final Object value, final int flags) { 20.26 throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key)); 20.27 } 20.28
21.1 --- a/src/jdk/nashorn/internal/runtime/WithObject.java Mon Sep 22 14:46:04 2014 +0200 21.2 +++ b/src/jdk/nashorn/internal/runtime/WithObject.java Mon Sep 22 13:28:28 2014 +0200 21.3 @@ -193,18 +193,20 @@ 21.4 * 21.5 * @param key Property key. 21.6 * @param deep Whether the search should look up proto chain. 21.7 - * @param stopOnNonScope should a deep search stop on the first non-scope object? 21.8 * @param start the object on which the lookup was originally initiated 21.9 * 21.10 * @return FindPropertyData or null if not found. 21.11 */ 21.12 @Override 21.13 - FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) { 21.14 - final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start); 21.15 + FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) { 21.16 + // We call findProperty on 'expression' with 'expression' itself as start parameter. 21.17 + // This way in ScriptObject.setObject we can tell the property is from a 'with' expression 21.18 + // (as opposed from another non-scope object in the proto chain such as Object.prototype). 21.19 + final FindProperty exprProperty = expression.findProperty(key, true, expression); 21.20 if (exprProperty != null) { 21.21 return exprProperty; 21.22 } 21.23 - return super.findProperty(key, deep, stopOnNonScope, start); 21.24 + return super.findProperty(key, deep, start); 21.25 } 21.26 21.27 @Override
22.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Mon Sep 22 14:46:04 2014 +0200 22.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java Mon Sep 22 13:28:28 2014 +0200 22.3 @@ -255,7 +255,7 @@ 22.4 * @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site 22.5 * descriptor. 22.6 */ 22.7 - private static int getFlags(final CallSiteDescriptor desc) { 22.8 + public static int getFlags(final CallSiteDescriptor desc) { 22.9 return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0; 22.10 } 22.11 22.12 @@ -343,6 +343,24 @@ 22.13 } 22.14 22.15 /** 22.16 + * Returns true if {@code flags} has the {@link #CALLSITE_STRICT} bit set. 22.17 + * @param flags the flags 22.18 + * @return true if the flag is set, false otherwise. 22.19 + */ 22.20 + public static boolean isStrictFlag(final int flags) { 22.21 + return (flags & CALLSITE_STRICT) != 0; 22.22 + } 22.23 + 22.24 + /** 22.25 + * Returns true if {@code flags} has the {@link #CALLSITE_SCOPE} bit set. 22.26 + * @param flags the flags 22.27 + * @return true if the flag is set, false otherwise. 22.28 + */ 22.29 + public static boolean isScopeFlag(final int flags) { 22.30 + return (flags & CALLSITE_SCOPE) != 0; 22.31 + } 22.32 + 22.33 + /** 22.34 * Get a program point from a descriptor (must be optimistic) 22.35 * @param desc descriptor 22.36 * @return program point
23.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 23.2 +++ b/test/script/basic/JDK-8047764-strict.js Mon Sep 22 13:28:28 2014 +0200 23.3 @@ -0,0 +1,69 @@ 23.4 +/* 23.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 23.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 23.7 + * 23.8 + * This code is free software; you can redistribute it and/or modify it 23.9 + * under the terms of the GNU General Public License version 2 only, as 23.10 + * published by the Free Software Foundation. 23.11 + * 23.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 23.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 23.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 23.15 + * version 2 for more details (a copy is included in the LICENSE file that 23.16 + * accompanied this code). 23.17 + * 23.18 + * You should have received a copy of the GNU General Public License version 23.19 + * 2 along with this work; if not, write to the Free Software Foundation, 23.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 23.21 + * 23.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 23.23 + * or visit www.oracle.com if you need additional information or have any 23.24 + * questions. 23.25 + */ 23.26 + 23.27 +/** 23.28 + * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype 23.29 + * 23.30 + * @test 23.31 + * @run 23.32 + */ 23.33 + 23.34 +// Same as JDK-8047764.js but running in strict mode 23.35 +"use strict"; 23.36 + 23.37 +// Test global set operation on properties defined in Object.prototype 23.38 + 23.39 +Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }}); 23.40 +Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false }); 23.41 + 23.42 +try { 23.43 + prop1 = 1; 23.44 + print("prop 1: " + prop2); 23.45 +} catch (e) { 23.46 + print(e.name); 23.47 +} 23.48 + 23.49 +try { 23.50 + prop2 = 2; 23.51 + print("prop 2: " + prop2); 23.52 +} catch (e) { 23.53 + print(e.name); 23.54 +} 23.55 + 23.56 +// Make sure various ways of setting global toString don't affect Object.prototype.toString 23.57 + 23.58 +function checkToString() { 23.59 + print(global); 23.60 + print(Object.prototype); 23.61 + print(global.toString === Object.prototype.toString); 23.62 + print(objProtoToString === Object.prototype.toString); 23.63 +} 23.64 + 23.65 +var global = this; 23.66 +var objProtoToString = Object.prototype.toString; 23.67 +global["toString"] = function() { return "global toString 1"; }; 23.68 +checkToString(); 23.69 +global.toString = function() { return "global toString 2"; }; 23.70 +checkToString(); 23.71 +toString = function() { return "global toString 3"; }; 23.72 +checkToString();
24.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 24.2 +++ b/test/script/basic/JDK-8047764-strict.js.EXPECTED Mon Sep 22 13:28:28 2014 +0200 24.3 @@ -0,0 +1,15 @@ 24.4 +setting prop1: 1 24.5 +prop 1: 1 24.6 +TypeError 24.7 +global toString 1 24.8 +[object Object] 24.9 +false 24.10 +true 24.11 +global toString 2 24.12 +[object Object] 24.13 +false 24.14 +true 24.15 +global toString 3 24.16 +[object Object] 24.17 +false 24.18 +true
25.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 25.2 +++ b/test/script/basic/JDK-8047764.js Mon Sep 22 13:28:28 2014 +0200 25.3 @@ -0,0 +1,94 @@ 25.4 +/* 25.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 25.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 25.7 + * 25.8 + * This code is free software; you can redistribute it and/or modify it 25.9 + * under the terms of the GNU General Public License version 2 only, as 25.10 + * published by the Free Software Foundation. 25.11 + * 25.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 25.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 25.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 25.15 + * version 2 for more details (a copy is included in the LICENSE file that 25.16 + * accompanied this code). 25.17 + * 25.18 + * You should have received a copy of the GNU General Public License version 25.19 + * 2 along with this work; if not, write to the Free Software Foundation, 25.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 25.21 + * 25.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 25.23 + * or visit www.oracle.com if you need additional information or have any 25.24 + * questions. 25.25 + */ 25.26 + 25.27 +/** 25.28 + * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype 25.29 + * 25.30 + * @test 25.31 + * @run 25.32 + */ 25.33 + 25.34 +// Test global set operation on properties defined in Object.prototype 25.35 + 25.36 +Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }}); 25.37 +Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false }); 25.38 + 25.39 +try { 25.40 + prop1 = 1; 25.41 + print("prop 1: " + prop2); 25.42 +} catch (e) { 25.43 + print(e.name); 25.44 +} 25.45 + 25.46 +try { 25.47 + prop2 = 2; 25.48 + print("prop 2: " + prop2); 25.49 +} catch (e) { 25.50 + print(e.name); 25.51 +} 25.52 + 25.53 +// Make sure various ways of setting global toString don't affect Object.prototype.toString 25.54 + 25.55 +function checkToString() { 25.56 + print(global); 25.57 + print(Object.prototype); 25.58 + print(global.toString === Object.prototype.toString); 25.59 + print(objProtoToString === Object.prototype.toString); 25.60 +} 25.61 + 25.62 +var global = this; 25.63 +var objProtoToString = Object.prototype.toString; 25.64 +global["toString"] = function() { return "global toString 1"; }; 25.65 +checkToString(); 25.66 +global.toString = function() { return "global toString 2"; }; 25.67 +checkToString(); 25.68 +toString = function() { return "global toString 3"; }; 25.69 +checkToString(); 25.70 + 25.71 +// Test setters on 'with' object 25.72 + 25.73 +var p = { prop3: 3, toString: function() { return "[object p]"; }}; 25.74 +Object.defineProperty(p, "prop4", { get: function() { print("get", this); return 4; }, set: function(v) { print("set", this, v); }}); 25.75 +var o = Object.create(p); 25.76 +o.toString = function() { return "[object o]"; }; 25.77 + 25.78 +with(o) { 25.79 + (function() { 25.80 + var m = 5; 25.81 + (function() { 25.82 + print(prop3); 25.83 + prop3 = m; 25.84 + print(prop3); 25.85 + print(prop4); 25.86 + prop4 = m; 25.87 + print(prop4); 25.88 + })(); 25.89 + })(); 25.90 +} 25.91 + 25.92 +print(o.hasOwnProperty("prop3")); 25.93 +print(o.prop3); 25.94 +print(p.prop3); 25.95 +print(o.hasOwnProperty("prop4")); 25.96 +print(o.prop4); 25.97 +print(p.prop4);
26.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 26.2 +++ b/test/script/basic/JDK-8047764.js.EXPECTED Mon Sep 22 13:28:28 2014 +0200 26.3 @@ -0,0 +1,30 @@ 26.4 +setting prop1: 1 26.5 +prop 1: 1 26.6 +prop 2: 1 26.7 +global toString 1 26.8 +[object Object] 26.9 +false 26.10 +true 26.11 +global toString 2 26.12 +[object Object] 26.13 +false 26.14 +true 26.15 +global toString 3 26.16 +[object Object] 26.17 +false 26.18 +true 26.19 +3 26.20 +5 26.21 +get [object o] 26.22 +4 26.23 +set [object o] 5 26.24 +get [object o] 26.25 +4 26.26 +true 26.27 +5 26.28 +3 26.29 +false 26.30 +get [object o] 26.31 +4 26.32 +get [object p] 26.33 +4