aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlana <none@none>2014-09-25 11:01:35 -0700
committerlana <none@none>2014-09-25 11:01:35 -0700
commit4a399d3eb805cc3fede2eeff7d0351261f74859c (patch)
tree72c34b6f2e9e649bfa7f546946b18312407aa96e
parent1c5554083466dac28b6076be9e29e03cc709d9f6 (diff)
parent9b5a7641b4e2ae67b26c1d9f7ea05affdbd8dc9b (diff)
-rw-r--r--src/jdk/nashorn/api/scripting/ScriptObjectMirror.java9
-rw-r--r--src/jdk/nashorn/internal/codegen/FieldObjectCreator.java2
-rw-r--r--src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java12
-rw-r--r--src/jdk/nashorn/internal/objects/ArrayBufferView.java4
-rw-r--r--src/jdk/nashorn/internal/objects/Global.java28
-rw-r--r--src/jdk/nashorn/internal/objects/NativeArray.java42
-rw-r--r--src/jdk/nashorn/internal/objects/NativeDebug.java5
-rw-r--r--src/jdk/nashorn/internal/objects/NativeJSAdapter.java96
-rw-r--r--src/jdk/nashorn/internal/objects/NativeJSON.java2
-rw-r--r--src/jdk/nashorn/internal/objects/NativeJavaImporter.java2
-rw-r--r--src/jdk/nashorn/internal/parser/Parser.java5
-rw-r--r--src/jdk/nashorn/internal/runtime/AccessorProperty.java2
-rw-r--r--src/jdk/nashorn/internal/runtime/CodeStore.java314
-rw-r--r--src/jdk/nashorn/internal/runtime/Context.java15
-rw-r--r--src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java62
-rw-r--r--src/jdk/nashorn/internal/runtime/ECMAException.java2
-rw-r--r--src/jdk/nashorn/internal/runtime/FindProperty.java11
-rw-r--r--src/jdk/nashorn/internal/runtime/FunctionInitializer.java11
-rw-r--r--src/jdk/nashorn/internal/runtime/GlobalConstants.java10
-rw-r--r--src/jdk/nashorn/internal/runtime/JSONFunctions.java8
-rw-r--r--src/jdk/nashorn/internal/runtime/NativeJavaPackage.java4
-rw-r--r--src/jdk/nashorn/internal/runtime/Property.java2
-rw-r--r--src/jdk/nashorn/internal/runtime/PropertyAccess.java64
-rw-r--r--src/jdk/nashorn/internal/runtime/PropertyMap.java4
-rw-r--r--src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java5
-rw-r--r--src/jdk/nashorn/internal/runtime/RewriteException.java3
-rw-r--r--src/jdk/nashorn/internal/runtime/ScriptObject.java275
-rw-r--r--src/jdk/nashorn/internal/runtime/ScriptingFunctions.java6
-rw-r--r--src/jdk/nashorn/internal/runtime/SetMethodCreator.java2
-rw-r--r--src/jdk/nashorn/internal/runtime/StoredScript.java21
-rw-r--r--src/jdk/nashorn/internal/runtime/Undefined.java5
-rw-r--r--src/jdk/nashorn/internal/runtime/WithObject.java10
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java9
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java7
-rw-r--r--src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java20
-rw-r--r--src/jdk/nashorn/internal/runtime/resources/Messages.properties10
-rw-r--r--test/script/basic/JDK-8043232.js.EXPECTED6
-rw-r--r--test/script/basic/JDK-8047764-strict.js69
-rw-r--r--test/script/basic/JDK-8047764-strict.js.EXPECTED15
-rw-r--r--test/script/basic/JDK-8047764.js94
-rw-r--r--test/script/basic/JDK-8047764.js.EXPECTED30
-rw-r--r--test/script/basic/JDK-8049242.js.EXPECTED2
-rw-r--r--test/script/basic/JDK-8056978.js46
-rw-r--r--test/script/basic/JDK-8056978.js.EXPECTED2
-rw-r--r--test/script/basic/JDK-8058422.js55
-rw-r--r--test/script/basic/JDK-8058545.js41
-rw-r--r--test/script/basic/JDK-8058561.js42
-rw-r--r--test/script/basic/JDK-8058615.js36
-rw-r--r--test/script/basic/JDK-8058615.js.EXPECTED1
-rw-r--r--test/src/jdk/nashorn/api/scripting/ScopeTest.java54
50 files changed, 1151 insertions, 431 deletions
diff --git a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index 7f4ca755..e28da041 100644
--- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -50,6 +50,7 @@ import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
/**
* Mirror object that wraps a given Nashorn Script object.
@@ -261,7 +262,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public void setSlot(final int index, final Object value) {
inGlobal(new Callable<Void>() {
@Override public Void call() {
- sobj.set(index, unwrap(value, global), strict);
+ sobj.set(index, unwrap(value, global), getCallSiteFlags());
return null;
}
});
@@ -425,7 +426,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
final Object value = entry.getValue();
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
- sobj.set(entry.getKey(), unwrap(modValue, global), strict);
+ sobj.set(entry.getKey(), unwrap(modValue, global), getCallSiteFlags());
}
return null;
}
@@ -756,6 +757,10 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return (obj == ScriptRuntime.UNDEFINED)? null : obj;
}
+ private int getCallSiteFlags() {
+ return strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
+ }
+
// internals only below this.
private <V> V inGlobal(final Callable<V> callable) {
final Global oldGlobal = Context.getGlobal();
diff --git a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
index 774a0be6..491af86f 100644
--- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
+++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java
@@ -231,7 +231,7 @@ public abstract class FieldObjectCreator<T> extends ObjectCreator<T> {
if (symbol != null) {
if (hasArguments() && symbol.isParam()) {
symbol.setFieldIndex(paramCount++);
- } else {
+ } else if (!isValidArrayIndex(getArrayIndex(tuple.key))) {
symbol.setFieldIndex(fieldCount++);
}
}
diff --git a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
index 995b29a6..c9580d41 100644
--- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
+++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java
@@ -558,7 +558,7 @@ final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
// of the compilation that the object being iterated over must use strings for property
// names (e.g., it is a native JS object or array), then we'll not bother trying to treat
// the property names optimistically.
- !forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression()));
+ !compiler.useOptimisticTypes() || (!forNode.isForEach() && compiler.hasStringPropertyIterator(iterable.getExpression())));
} else {
if(init != null) {
init.accept(this);
@@ -686,6 +686,10 @@ final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
@Override
public boolean enterReturnNode(final ReturnNode returnNode) {
+ if(!reachable) {
+ return false;
+ }
+
final Expression returnExpr = returnNode.getExpression();
final Type returnExprType;
if(returnExpr != null) {
@@ -701,6 +705,9 @@ final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
@Override
public boolean enterSplitNode(final SplitNode splitNode) {
+ if(!reachable) {
+ return false;
+ }
// Need to visit inside of split nodes. While it's true that they don't have local variables, we need to visit
// breaks, continues, and returns in them.
if(topSplit == null) {
@@ -950,6 +957,9 @@ final class LocalVariableTypesCalculator extends NodeVisitor<LexicalContext>{
@Override
public boolean enterVarNode(final VarNode varNode) {
+ if (!reachable) {
+ return false;
+ }
final Expression init = varNode.getInit();
if(init != null) {
init.accept(this);
diff --git a/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/src/jdk/nashorn/internal/objects/ArrayBufferView.java
index 445dc19c..93506c37 100644
--- a/src/jdk/nashorn/internal/objects/ArrayBufferView.java
+++ b/src/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -228,11 +228,11 @@ abstract class ArrayBufferView extends ScriptObject {
private static void copyElements(final ArrayBufferView dest, final int length, final ScriptObject source, final int offset) {
if (!dest.isFloatArray()) {
for (int i = 0, j = offset; i < length; i++, j++) {
- dest.set(j, source.getInt(i, INVALID_PROGRAM_POINT), false);
+ dest.set(j, source.getInt(i, INVALID_PROGRAM_POINT), 0);
}
} else {
for (int i = 0, j = offset; i < length; i++, j++) {
- dest.set(j, source.getDouble(i, INVALID_PROGRAM_POINT), false);
+ dest.set(j, source.getDouble(i, INVALID_PROGRAM_POINT), 0);
}
}
}
diff --git a/src/jdk/nashorn/internal/objects/Global.java b/src/jdk/nashorn/internal/objects/Global.java
index 03a2c9ae..b8ec90fd 100644
--- a/src/jdk/nashorn/internal/objects/Global.java
+++ b/src/jdk/nashorn/internal/objects/Global.java
@@ -439,8 +439,8 @@ public final class Global extends ScriptObject implements Scope {
// current ScriptContext to use - can be null.
private ScriptContext scontext;
- // associated Property object for "context" property.
- private jdk.nashorn.internal.runtime.Property scontextProperty;
+ // current ScriptEngine associated - can be null.
+ private ScriptEngine engine;
/**
* Set the current script context
@@ -448,7 +448,6 @@ public final class Global extends ScriptObject implements Scope {
*/
public void setScriptContext(final ScriptContext scontext) {
this.scontext = scontext;
- scontextProperty.setValue(this, this, scontext, false);
}
// global constants for this global - they can be replaced with MethodHandle.constant until invalidated
@@ -581,6 +580,7 @@ public final class Global extends ScriptObject implements Scope {
return;
}
+ this.engine = engine;
init(engine);
}
@@ -917,6 +917,13 @@ public final class Global extends ScriptObject implements Scope {
}
}
+ switch (nameStr) {
+ case "context":
+ return sctxt;
+ case "engine":
+ return global.engine;
+ }
+
if (self == UNDEFINED) {
// scope access and so throw ReferenceError
throw referenceError(global, "not.defined", nameStr);
@@ -1789,9 +1796,6 @@ public final class Global extends ScriptObject implements Scope {
}
if (engine != null) {
- final int NOT_ENUMERABLE_NOT_CONFIG = Attribute.NOT_ENUMERABLE | Attribute.NOT_CONFIGURABLE;
- scontextProperty = addOwnProperty("context", NOT_ENUMERABLE_NOT_CONFIG, null);
- addOwnProperty("engine", NOT_ENUMERABLE_NOT_CONFIG, engine);
// default file name
addOwnProperty(ScriptEngine.FILENAME, Attribute.NOT_ENUMERABLE, null);
// __noSuchProperty__ hook for ScriptContext search of missing variables
@@ -1821,10 +1825,10 @@ public final class Global extends ScriptObject implements Scope {
// ECMA 15.11.4.2 Error.prototype.name
// Error.prototype.name = "Error";
- errorProto.set(NativeError.NAME, "Error", false);
+ errorProto.set(NativeError.NAME, "Error", 0);
// ECMA 15.11.4.3 Error.prototype.message
// Error.prototype.message = "";
- errorProto.set(NativeError.MESSAGE, "", false);
+ errorProto.set(NativeError.MESSAGE, "", 0);
this.builtinEvalError = initErrorSubtype("EvalError", errorProto);
this.builtinRangeError = initErrorSubtype("RangeError", errorProto);
@@ -1837,8 +1841,8 @@ public final class Global extends ScriptObject implements Scope {
private ScriptFunction initErrorSubtype(final String name, final ScriptObject errorProto) {
final ScriptFunction cons = initConstructor(name, ScriptFunction.class);
final ScriptObject prototype = ScriptFunction.getPrototype(cons);
- prototype.set(NativeError.NAME, name, false);
- prototype.set(NativeError.MESSAGE, "", false);
+ prototype.set(NativeError.NAME, name, 0);
+ prototype.set(NativeError.MESSAGE, "", 0);
prototype.setInitialProto(errorProto);
return cons;
}
@@ -1898,7 +1902,7 @@ public final class Global extends ScriptObject implements Scope {
private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
for (final Field f : scriptEnv.getClass().getFields()) {
try {
- options.set(f.getName(), f.get(scriptEnv), false);
+ options.set(f.getName(), f.get(scriptEnv), 0);
} catch (final IllegalArgumentException | IllegalAccessException exp) {
throw new RuntimeException(exp);
}
@@ -2042,7 +2046,7 @@ public final class Global extends ScriptObject implements Scope {
// <anon-function>
builtinFunction.setInitialProto(anon);
builtinFunction.setPrototype(anon);
- anon.set("constructor", builtinFunction, false);
+ anon.set("constructor", builtinFunction, 0);
anon.deleteOwnProperty(anon.getMap().findProperty("prototype"));
// use "getter" so that [[ThrowTypeError]] function's arity is 0 - as specified in step 10 of section 13.2.3
diff --git a/src/jdk/nashorn/internal/objects/NativeArray.java b/src/jdk/nashorn/internal/objects/NativeArray.java
index 776803b3..163e86a4 100644
--- a/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -32,6 +32,7 @@ import static jdk.nashorn.internal.runtime.PropertyDescriptor.WRITABLE;
import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.arrayLikeIterator;
import static jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator.reverseArrayLikeIterator;
+import static jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor.CALLSITE_STRICT;
import java.lang.invoke.MethodHandle;
import java.util.ArrayList;
@@ -69,6 +70,7 @@ import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
import jdk.nashorn.internal.runtime.arrays.IteratorAction;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
/**
* Runtime representation of a JavaScript array. NativeArray only holds numeric
@@ -341,7 +343,7 @@ public final class NativeArray extends ScriptObject {
if (!newWritable) {
// make 'length' property not writable
final ScriptObject newDesc = Global.newEmptyInstance();
- newDesc.set(WRITABLE, false, false);
+ newDesc.set(WRITABLE, false, 0);
return super.defineOwnProperty("length", newDesc, false);
}
@@ -808,7 +810,7 @@ public final class NativeArray extends ScriptObject {
final long len = JSType.toUint32(sobj.getLength());
if (len == 0) {
- sobj.set("length", 0, true);
+ sobj.set("length", 0, CALLSITE_STRICT);
return ScriptRuntime.UNDEFINED;
}
@@ -816,7 +818,7 @@ public final class NativeArray extends ScriptObject {
final Object element = sobj.get(index);
sobj.delete(index, true);
- sobj.set("length", index, true);
+ sobj.set("length", index, CALLSITE_STRICT);
return element;
} catch (final ClassCastException | NullPointerException e) {
@@ -844,9 +846,9 @@ public final class NativeArray extends ScriptObject {
long len = JSType.toUint32(sobj.getLength());
for (final Object element : args) {
- sobj.set(len++, element, true);
+ sobj.set(len++, element, CALLSITE_STRICT);
}
- sobj.set("length", len, true);
+ sobj.set("length", len, CALLSITE_STRICT);
return len;
} catch (final ClassCastException | NullPointerException e) {
@@ -928,8 +930,8 @@ public final class NativeArray extends ScriptObject {
}
long len = JSType.toUint32(sobj.getLength());
- sobj.set(len++, arg, true);
- sobj.set("length", len, true);
+ sobj.set(len++, arg, CALLSITE_STRICT);
+ sobj.set("length", len, CALLSITE_STRICT);
return len;
} catch (final ClassCastException | NullPointerException e) {
throw typeError("not.an.object", ScriptRuntime.safeToString(self));
@@ -957,14 +959,14 @@ public final class NativeArray extends ScriptObject {
final boolean upperExists = sobj.has(upper);
if (lowerExists && upperExists) {
- sobj.set(lower, upperValue, true);
- sobj.set(upper, lowerValue, true);
+ sobj.set(lower, upperValue, CALLSITE_STRICT);
+ sobj.set(upper, lowerValue, CALLSITE_STRICT);
} else if (!lowerExists && upperExists) {
- sobj.set(lower, upperValue, true);
+ sobj.set(lower, upperValue, CALLSITE_STRICT);
sobj.delete(upper, true);
} else if (lowerExists && !upperExists) {
sobj.delete(lower, true);
- sobj.set(upper, lowerValue, true);
+ sobj.set(upper, lowerValue, CALLSITE_STRICT);
}
}
return sobj;
@@ -1003,7 +1005,7 @@ public final class NativeArray extends ScriptObject {
for (long k = 1; k < len; k++) {
final boolean hasCurrent = sobj.has(k);
if (hasCurrent) {
- sobj.set(k - 1, sobj.get(k), true);
+ sobj.set(k - 1, sobj.get(k), CALLSITE_STRICT);
} else if (hasPrevious) {
sobj.delete(k - 1, true);
}
@@ -1015,7 +1017,7 @@ public final class NativeArray extends ScriptObject {
len = 0;
}
- sobj.set("length", len, true);
+ sobj.set("length", len, CALLSITE_STRICT);
return first;
}
@@ -1226,7 +1228,7 @@ public final class NativeArray extends ScriptObject {
final long to = k + items.length;
if (sobj.has(from)) {
- sobj.set(to, sobj.get(from), true);
+ sobj.set(to, sobj.get(from), CALLSITE_STRICT);
} else {
sobj.delete(to, true);
}
@@ -1242,7 +1244,7 @@ public final class NativeArray extends ScriptObject {
if (sobj.has(from)) {
final Object fromValue = sobj.get(from);
- sobj.set(to, fromValue, true);
+ sobj.set(to, fromValue, CALLSITE_STRICT);
} else {
sobj.delete(to, true);
}
@@ -1251,11 +1253,11 @@ public final class NativeArray extends ScriptObject {
long k = start;
for (int i = 0; i < items.length; i++, k++) {
- sobj.set(k, items[i], true);
+ sobj.set(k, items[i], CALLSITE_STRICT);
}
final long newLength = len - deleteCount + items.length;
- sobj.set("length", newLength, true);
+ sobj.set("length", newLength, CALLSITE_STRICT);
return array;
}
@@ -1295,19 +1297,19 @@ public final class NativeArray extends ScriptObject {
if (sobj.has(from)) {
final Object fromValue = sobj.get(from);
- sobj.set(to, fromValue, true);
+ sobj.set(to, fromValue, CALLSITE_STRICT);
} else {
sobj.delete(to, true);
}
}
for (int j = 0; j < items.length; j++) {
- sobj.set(j, items[j], true);
+ sobj.set(j, items[j], CALLSITE_STRICT);
}
}
final long newLength = len + items.length;
- sobj.set("length", newLength, true);
+ sobj.set("length", newLength, CALLSITE_STRICT);
return newLength;
}
diff --git a/src/jdk/nashorn/internal/objects/NativeDebug.java b/src/jdk/nashorn/internal/objects/NativeDebug.java
index dc6ba044..20dd85e5 100644
--- a/src/jdk/nashorn/internal/objects/NativeDebug.java
+++ b/src/jdk/nashorn/internal/objects/NativeDebug.java
@@ -42,6 +42,7 @@ import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.events.RuntimeEvent;
import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
/**
* Nashorn specific debug utils. This is meant for Nashorn developers.
@@ -266,7 +267,7 @@ public final class NativeDebug extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static void setEventQueueCapacity(final Object self, final Object newCapacity) {
- ((ScriptObject)self).set(EVENT_QUEUE_CAPACITY, newCapacity, true);
+ ((ScriptObject)self).set(EVENT_QUEUE_CAPACITY, newCapacity, NashornCallSiteDescriptor.CALLSITE_STRICT);
}
/**
@@ -355,7 +356,7 @@ public final class NativeDebug extends ScriptObject {
if (sobj.has(EVENT_QUEUE)) {
q = (LinkedList<RuntimeEvent<?>>)((ScriptObject)self).get(EVENT_QUEUE);
} else {
- ((ScriptObject)self).set(EVENT_QUEUE, q = new LinkedList<>(), true);
+ ((ScriptObject)self).set(EVENT_QUEUE, q = new LinkedList<>(), NashornCallSiteDescriptor.CALLSITE_STRICT);
}
return q;
}
diff --git a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
index ab544697..f2b1bef4 100644
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
+++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
@@ -250,146 +250,146 @@ public final class NativeJSAdapter extends ScriptObject {
}
@Override
- public void set(final Object key, final int value, final boolean strict) {
+ public void set(final Object key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final Object key, final long value, final boolean strict) {
+ public void set(final Object key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final Object key, final double value, final boolean strict) {
+ public void set(final Object key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final Object key, final Object value, final boolean strict) {
+ public void set(final Object key, final Object value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final double key, final int value, final boolean strict) {
+ public void set(final double key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final double key, final long value, final boolean strict) {
+ public void set(final double key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final double key, final double value, final boolean strict) {
+ public void set(final double key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final double key, final Object value, final boolean strict) {
+ public void set(final double key, final Object value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final long key, final int value, final boolean strict) {
+ public void set(final long key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final long key, final long value, final boolean strict) {
+ public void set(final long key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final long key, final double value, final boolean strict) {
+ public void set(final long key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final long key, final Object value, final boolean strict) {
+ public void set(final long key, final Object value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final int key, final int value, final boolean strict) {
+ public void set(final int key, final int value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final int key, final long value, final boolean strict) {
+ public void set(final int key, final long value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final int key, final double value, final boolean strict) {
+ public void set(final int key, final double value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
@Override
- public void set(final int key, final Object value, final boolean strict) {
+ public void set(final int key, final Object value, final int flags) {
if (overrides && super.hasOwnProperty(key)) {
- super.set(key, value, strict);
+ super.set(key, value, flags);
} else {
- callAdaptee(__put__, key, value, strict);
+ callAdaptee(__put__, key, value, flags);
}
}
diff --git a/src/jdk/nashorn/internal/objects/NativeJSON.java b/src/jdk/nashorn/internal/objects/NativeJSON.java
index 2578d39a..7bd8a4a3 100644
--- a/src/jdk/nashorn/internal/objects/NativeJSON.java
+++ b/src/jdk/nashorn/internal/objects/NativeJSON.java
@@ -191,7 +191,7 @@ public final class NativeJSON extends ScriptObject {
state.gap = gap;
final ScriptObject wrapper = Global.newEmptyInstance();
- wrapper.set("", value, false);
+ wrapper.set("", value, 0);
return str("", wrapper, state);
}
diff --git a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
index 1443c943..d1aa8cb1 100644
--- a/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
+++ b/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
@@ -146,7 +146,7 @@ public final class NativeJavaImporter extends ScriptObject {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
final Object value = createProperty(name);
if(value != null) {
- set(name, value, false);
+ set(name, value, 0);
return true;
}
return false;
diff --git a/src/jdk/nashorn/internal/parser/Parser.java b/src/jdk/nashorn/internal/parser/Parser.java
index 6f47c3fc..3162e184 100644
--- a/src/jdk/nashorn/internal/parser/Parser.java
+++ b/src/jdk/nashorn/internal/parser/Parser.java
@@ -54,6 +54,7 @@ import static jdk.nashorn.internal.parser.TokenType.SEMICOLON;
import static jdk.nashorn.internal.parser.TokenType.TERNARY;
import static jdk.nashorn.internal.parser.TokenType.WHILE;
+import java.io.Serializable;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collections;
@@ -2977,11 +2978,13 @@ loop:
* Encapsulates part of the state of the parser, enough to reconstruct the state of both parser and lexer
* for resuming parsing after skipping a function body.
*/
- private static class ParserState {
+ private static class ParserState implements Serializable {
private final int position;
private final int line;
private final int linePosition;
+ private static final long serialVersionUID = -2382565130754093694L;
+
ParserState(final int position, final int line, final int linePosition) {
this.position = position;
this.line = line;
diff --git a/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/src/jdk/nashorn/internal/runtime/AccessorProperty.java
index e030354a..44b3c3b0 100644
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -119,7 +119,7 @@ public class AccessorProperty extends Property {
* produce different boun method handles wrapping the same access mechanism
* depending on callsite
*/
- private MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES];
+ private transient MethodHandle[] GETTER_CACHE = new MethodHandle[NOOF_TYPES];
/**
* Create a new accessor property. Factory method used by nasgen generated code.
diff --git a/src/jdk/nashorn/internal/runtime/CodeStore.java b/src/jdk/nashorn/internal/runtime/CodeStore.java
index 8d793203..a736cc36 100644
--- a/src/jdk/nashorn/internal/runtime/CodeStore.java
+++ b/src/jdk/nashorn/internal/runtime/CodeStore.java
@@ -34,51 +34,42 @@ import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
+import java.security.AccessControlException;
import java.security.AccessController;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.util.Iterator;
import java.util.Map;
+import java.util.ServiceLoader;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.logging.DebugLogger;
import jdk.nashorn.internal.runtime.logging.Loggable;
import jdk.nashorn.internal.runtime.logging.Logger;
+import jdk.nashorn.internal.runtime.options.Options;
/**
* A code cache for persistent caching of compiled scripts.
*/
@Logger(name="codestore")
-final class CodeStore implements Loggable {
-
- private final File dir;
- private final int minSize;
- private final DebugLogger log;
-
- // Default minimum size for storing a compiled script class
- private final static int DEFAULT_MIN_SIZE = 1000;
+public abstract class CodeStore implements Loggable {
/**
- * Constructor
- * @throws IOException
+ * Permission needed to provide a CodeStore instance via ServiceLoader.
*/
- public CodeStore(final Context context, final String path) throws IOException {
- this(context, path, DEFAULT_MIN_SIZE);
- }
+ public final static String NASHORN_PROVIDE_CODE_STORE = "nashorn.provideCodeStore";
+
+ private DebugLogger log;
/**
* Constructor
- * @param path directory to store code in
- * @param minSize minimum file size for caching scripts
- * @throws IOException
*/
- public CodeStore(final Context context, final String path, final int minSize) throws IOException {
- this.dir = checkDirectory(path);
- this.minSize = minSize;
- this.log = initLogger(context);
+ protected CodeStore() {
}
@Override
public DebugLogger initLogger(final Context context) {
- return context.getLogger(getClass());
+ log = context.getLogger(getClass());
+ return log;
}
@Override
@@ -86,29 +77,101 @@ final class CodeStore implements Loggable {
return log;
}
- private static File checkDirectory(final String path) throws IOException {
+ /**
+ * Returns a new code store instance.
+ *
+ * @param context the current context
+ * @return The instance
+ * @throws IOException If an error occurs
+ */
+ public static CodeStore newCodeStore(final Context context) throws IOException {
+ final Class<CodeStore> baseClass = CodeStore.class;
try {
- return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
- @Override
- public File run() throws IOException {
- final File dir = new File(path).getAbsoluteFile();
- if (!dir.exists() && !dir.mkdirs()) {
- throw new IOException("Could not create directory: " + dir.getPath());
- } else if (!dir.isDirectory()) {
- throw new IOException("Not a directory: " + dir.getPath());
- } else if (!dir.canRead() || !dir.canWrite()) {
- throw new IOException("Directory not readable or writable: " + dir.getPath());
- }
- return dir;
- }
- });
- } catch (final PrivilegedActionException e) {
- throw (IOException) e.getException();
+ // security check first
+ final SecurityManager sm = System.getSecurityManager();
+ if (sm != null) {
+ sm.checkPermission(new RuntimePermission(NASHORN_PROVIDE_CODE_STORE));
+ }
+ final ServiceLoader<CodeStore> services = ServiceLoader.load(baseClass);
+ final Iterator<CodeStore> iterator = services.iterator();
+ if (iterator.hasNext()) {
+ final CodeStore store = iterator.next();
+ store.initLogger(context).info("using code store provider ", store.getClass().getCanonicalName());
+ return store;
+ }
+ } catch (final AccessControlException e) {
+ context.getLogger(CodeStore.class).warning("failed to load code store provider ", e);
}
+ final CodeStore store = new DirectoryCodeStore();
+ store.initLogger(context);
+ return store;
+ }
+
+
+ /**
+ * Store a compiled script in the cache.
+ *
+ * @param functionKey the function key
+ * @param source the source
+ * @param mainClassName the main class name
+ * @param classBytes a map of class bytes
+ * @param initializers the function initializers
+ * @param constants the constants array
+ * @param compilationId the compilation id
+ */
+ public StoredScript store(final String functionKey,
+ final Source source,
+ final String mainClassName,
+ final Map<String, byte[]> classBytes,
+ final Map<Integer, FunctionInitializer> initializers,
+ final Object[] constants,
+ final int compilationId) {
+ return store(functionKey, source, storedScriptFor(source, mainClassName, classBytes, initializers, constants, compilationId));
}
- private File getCacheFile(final Source source, final String functionKey) {
- return new File(dir, source.getDigest() + '-' + functionKey);
+ /**
+ * Stores a compiled script.
+ *
+ * @param functionKey the function key
+ * @param source the source
+ * @param script The compiled script
+ * @return The compiled script or {@code null} if not stored
+ */
+ public abstract StoredScript store(final String functionKey,
+ final Source source,
+ final StoredScript script);
+
+ /**
+ * Return a compiled script from the cache, or null if it isn't found.
+ *
+ * @param source the source
+ * @param functionKey the function key
+ * @return the stored script or null
+ */
+ public abstract StoredScript load(final Source source, final String functionKey);
+
+ /**
+ * Returns a new StoredScript instance.
+ *
+ * @param mainClassName the main class name
+ * @param classBytes a map of class bytes
+ * @param initializers function initializers
+ * @param constants the constants array
+ * @param compilationId the compilation id
+ * @return The compiled script
+ */
+ public StoredScript storedScriptFor(final Source source, final String mainClassName,
+ final Map<String, byte[]> classBytes,
+ final Map<Integer, FunctionInitializer> initializers,
+ final Object[] constants, final int compilationId) {
+ for (final Object constant : constants) {
+ // Make sure all constant data is serializable
+ if (!(constant instanceof Serializable)) {
+ getLogger().warning("cannot store ", source, " non serializable constant ", constant);
+ return null;
+ }
+ }
+ return new StoredScript(compilationId, mainClassName, classBytes, initializers, constants);
}
/**
@@ -129,77 +192,130 @@ final class CodeStore implements Loggable {
}
/**
- * Return a compiled script from the cache, or null if it isn't found.
- *
- * @param source the source
- * @param functionKey the function key
- * @return the stored script or null
+ * A store using a file system directory.
*/
- public StoredScript loadScript(final Source source, final String functionKey) {
- if (source.getLength() < minSize) {
- return null;
+ public static class DirectoryCodeStore extends CodeStore {
+
+ // Default minimum size for storing a compiled script class
+ private final static int DEFAULT_MIN_SIZE = 1000;
+
+ private final File dir;
+ private final boolean readOnly;
+ private final int minSize;
+
+ /**
+ * Constructor
+ *
+ * @throws IOException
+ */
+ public DirectoryCodeStore() throws IOException {
+ this(Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache"), false, DEFAULT_MIN_SIZE);
}
- final File file = getCacheFile(source, functionKey);
+ /**
+ * Constructor
+ *
+ * @param path directory to store code in
+ * @param minSize minimum file size for caching scripts
+ * @throws IOException
+ */
+ public DirectoryCodeStore(final String path, final boolean readOnly, final int minSize) throws IOException {
+ this.dir = checkDirectory(path, readOnly);
+ this.readOnly = readOnly;
+ this.minSize = minSize;
+ }
- try {
- return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
- @Override
- public StoredScript run() throws IOException, ClassNotFoundException {
- if (!file.exists()) {
- return null;
- }
- try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
- final StoredScript storedScript = (StoredScript) in.readObject();
- getLogger().info("loaded ", source, "-", functionKey);
- return storedScript;
+ private static File checkDirectory(final String path, final boolean readOnly) throws IOException {
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<File>() {
+ @Override
+ public File run() throws IOException {
+ final File dir = new File(path).getAbsoluteFile();
+ if (readOnly) {
+ if (!dir.exists() || !dir.isDirectory()) {
+ throw new IOException("Not a directory: " + dir.getPath());
+ } else if (!dir.canRead()) {
+ throw new IOException("Directory not readable: " + dir.getPath());
+ }
+ } else if (!dir.exists() && !dir.mkdirs()) {
+ throw new IOException("Could not create directory: " + dir.getPath());
+ } else if (!dir.isDirectory()) {
+ throw new IOException("Not a directory: " + dir.getPath());
+ } else if (!dir.canRead() || !dir.canWrite()) {
+ throw new IOException("Directory not readable or writable: " + dir.getPath());
+ }
+ return dir;
}
- }
- });
- } catch (final PrivilegedActionException e) {
- getLogger().warning("failed to load ", source, "-", functionKey, ": ", e.getException());
- return null;
+ });
+ } catch (final PrivilegedActionException e) {
+ throw (IOException) e.getException();
+ }
}
- }
- /**
- * Store a compiled script in the cache.
- *
- * @param functionKey the function key
- * @param source the source
- * @param mainClassName the main class name
- * @param classBytes a map of class bytes
- * @param constants the constants array
- */
- public void storeScript(final String functionKey, final Source source, final String mainClassName, final Map<String, byte[]> classBytes,
- final Map<Integer, FunctionInitializer> initializers, final Object[] constants, final int compilationId) {
- if (source.getLength() < minSize) {
- return;
- }
- for (final Object constant : constants) {
- // Make sure all constant data is serializable
- if (! (constant instanceof Serializable)) {
- getLogger().warning("cannot store ", source, " non serializable constant ", constant);
- return;
+ @Override
+ public StoredScript load(final Source source, final String functionKey) {
+ if (source.getLength() < minSize) {
+ return null;
+ }
+
+ final File file = getCacheFile(source, functionKey);
+
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
+ @Override
+ public StoredScript run() throws IOException, ClassNotFoundException {
+ if (!file.exists()) {
+ return null;
+ }
+ try (ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(new FileInputStream(file)))) {
+ final StoredScript storedScript = (StoredScript) in.readObject();
+ getLogger().info("loaded ", source, "-", functionKey);
+ return storedScript;
+ }
+ }
+ });
+ } catch (final PrivilegedActionException e) {
+ getLogger().warning("failed to load ", source, "-", functionKey, ": ", e.getException());
+ return null;
}
}
- final File file = getCacheFile(source, functionKey);
- final StoredScript script = new StoredScript(compilationId, mainClassName, classBytes, initializers, constants);
+ @Override
+ public StoredScript store(final String functionKey, final Source source, final StoredScript script) {
+ if (readOnly || script == null || belowThreshold(source)) {
+ return null;
+ }
- try {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {
- @Override
- public Void run() throws IOException {
- try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
- out.writeObject(script);
+ final File file = getCacheFile(source, functionKey);
+
+ try {
+ return AccessController.doPrivileged(new PrivilegedExceptionAction<StoredScript>() {
+ @Override
+ public StoredScript run() throws IOException {
+ try (ObjectOutputStream out = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(file)))) {
+ out.writeObject(script);
+ }
+ getLogger().info("stored ", source, "-", functionKey);
+ return script;
}
- getLogger().info("stored ", source, "-", functionKey);
- return null;
- }
- });
- } catch (final PrivilegedActionException e) {
- getLogger().warning("failed to store ", script, "-", functionKey, ": ", e.getException());
+ });
+ } catch (final PrivilegedActionException e) {
+ getLogger().warning("failed to store ", script, "-", functionKey, ": ", e.getException());
+ return null;
+ }
+ }
+
+
+ private File getCacheFile(final Source source, final String functionKey) {
+ return new File(dir, source.getDigest() + '-' + functionKey);
+ }
+
+ private boolean belowThreshold(final Source source) {
+ if (source.getLength() < minSize) {
+ getLogger().info("below size threshold ", source);
+ return true;
+ }
+ return false;
}
}
}
diff --git a/src/jdk/nashorn/internal/runtime/Context.java b/src/jdk/nashorn/internal/runtime/Context.java
index c144d363..aa3306a4 100644
--- a/src/jdk/nashorn/internal/runtime/Context.java
+++ b/src/jdk/nashorn/internal/runtime/Context.java
@@ -29,6 +29,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.CONSTANTS;
import static jdk.nashorn.internal.codegen.CompilerConstants.CREATE_PROGRAM_FUNCTION;
import static jdk.nashorn.internal.codegen.CompilerConstants.SOURCE;
import static jdk.nashorn.internal.codegen.CompilerConstants.STRICT_MODE;
+import static jdk.nashorn.internal.runtime.CodeStore.newCodeStore;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
import static jdk.nashorn.internal.runtime.Source.sourceFor;
@@ -200,14 +201,14 @@ public final class Context {
final Map<String,byte[]> classBytes, final Map<Integer, FunctionInitializer> initializers,
final Object[] constants, final int compilationId) {
if (context.codeStore != null) {
- context.codeStore.storeScript(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId);
+ context.codeStore.store(cacheKey, source, mainClassName, classBytes, initializers, constants, compilationId);
}
}
@Override
public StoredScript loadScript(final Source source, final String functionKey) {
if (context.codeStore != null) {
- return context.codeStore.loadScript(source, functionKey);
+ return context.codeStore.load(source, functionKey);
}
return null;
}
@@ -463,8 +464,7 @@ public final class Context {
if (env._persistent_cache) {
try {
- final String cacheDir = Options.getStringProperty("nashorn.persistent.code.cache", "nashorn_code_cache");
- codeStore = new CodeStore(this, cacheDir);
+ codeStore = newCodeStore(this);
} catch (final IOException e) {
throw new RuntimeException("Error initializing code cache", e);
}
@@ -1117,7 +1117,7 @@ public final class Context {
final String cacheKey = useCodeStore ? CodeStore.getCacheKey(0, null) : null;
if (useCodeStore) {
- storedScript = codeStore.loadScript(source, cacheKey);
+ storedScript = codeStore.load(source, cacheKey);
}
if (storedScript == null) {
@@ -1194,15 +1194,16 @@ public final class Context {
private static Class<?> install(final StoredScript storedScript, final Source source, final CodeInstaller<ScriptEnvironment> installer) {
final Map<String, Class<?>> installedClasses = new HashMap<>();
+ final Map<String, byte[]> classBytes = storedScript.getClassBytes();
final Object[] constants = storedScript.getConstants();
final String mainClassName = storedScript.getMainClassName();
- final byte[] mainClassBytes = storedScript.getClassBytes().get(mainClassName);
+ final byte[] mainClassBytes = classBytes.get(mainClassName);
final Class<?> mainClass = installer.install(mainClassName, mainClassBytes);
final Map<Integer, FunctionInitializer> initialzers = storedScript.getInitializers();
installedClasses.put(mainClassName, mainClass);
- for (final Map.Entry<String, byte[]> entry : storedScript.getClassBytes().entrySet()) {
+ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
final String className = entry.getKey();
if (className.equals(mainClassName)) {
continue;
diff --git a/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java b/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java
index c1ae1f59..e69eda92 100644
--- a/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java
+++ b/src/jdk/nashorn/internal/runtime/DefaultPropertyAccess.java
@@ -112,82 +112,82 @@ public abstract class DefaultPropertyAccess implements PropertyAccess {
}
@Override
- public void set(final double key, final int value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final double key, final int value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final double key, final long value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final double key, final long value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final double key, final double value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final double key, final double value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final double key, final Object value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final double key, final Object value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final long key, final int value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final long key, final int value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final long key, final long value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final long key, final long value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final long key, final double value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final long key, final double value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final long key, final Object value, final boolean strict) {
- set(JSType.toObject(key), value, strict);
+ public void set(final long key, final Object value, final int flags) {
+ set(JSType.toObject(key), value, flags);
}
@Override
- public void set(final int key, final int value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final int key, final int value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final int key, final long value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final int key, final long value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final int key, final double value, final boolean strict) {
- set(JSType.toObject(key), JSType.toObject(value), strict);
+ public void set(final int key, final double value, final int flags) {
+ set(JSType.toObject(key), JSType.toObject(value), flags);
}
@Override
- public void set(final int key, final Object value, final boolean strict) {
- set(JSType.toObject(key), value, strict);
+ public void set(final int key, final Object value, final int flags) {
+ set(JSType.toObject(key), value, flags);
}
@Override
- public void set(final Object key, final int value, final boolean strict) {
- set(key, JSType.toObject(value), strict);
+ public void set(final Object key, final int value, final int flags) {
+ set(key, JSType.toObject(value), flags);
}
@Override
- public void set(final Object key, final long value, final boolean strict) {
- set(key, JSType.toObject(value), strict);
+ public void set(final Object key, final long value, final int flags) {
+ set(key, JSType.toObject(value), flags);
}
@Override
- public void set(final Object key, final double value, final boolean strict) {
- set(key, JSType.toObject(value), strict);
+ public void set(final Object key, final double value, final int flags) {
+ set(key, JSType.toObject(value), flags);
}
@Override
- public abstract void set(Object key, Object value, boolean strict);
+ public abstract void set(Object key, Object value, int flags);
@Override
public abstract boolean has(Object key);
diff --git a/src/jdk/nashorn/internal/runtime/ECMAException.java b/src/jdk/nashorn/internal/runtime/ECMAException.java
index ce691afa..954a1707 100644
--- a/src/jdk/nashorn/internal/runtime/ECMAException.java
+++ b/src/jdk/nashorn/internal/runtime/ECMAException.java
@@ -285,7 +285,7 @@ public final class ECMAException extends NashornException {
if (!sobj.has(EXCEPTION_PROPERTY)) {
sobj.addOwnProperty(EXCEPTION_PROPERTY, Property.NOT_ENUMERABLE, this);
} else {
- sobj.set(EXCEPTION_PROPERTY, this, false);
+ sobj.set(EXCEPTION_PROPERTY, this, 0);
}
}
}
diff --git a/src/jdk/nashorn/internal/runtime/FindProperty.java b/src/jdk/nashorn/internal/runtime/FindProperty.java
index 72a2d835..06f682bf 100644
--- a/src/jdk/nashorn/internal/runtime/FindProperty.java
+++ b/src/jdk/nashorn/internal/runtime/FindProperty.java
@@ -139,6 +139,17 @@ public final class FindProperty {
}
/**
+ * Return the {@code ScriptObject} where the search started. This is usually the ScriptObject the
+ * operation was started on, except for properties found inside a 'with' statement, where it is the
+ * top-level 'with' expression object.
+ *
+ * @return the start object.
+ */
+ public ScriptObject getSelf() {
+ return self;
+ }
+
+ /**
* Return the appropriate receiver for a getter.
* @return appropriate receiver
*/
diff --git a/src/jdk/nashorn/internal/runtime/FunctionInitializer.java b/src/jdk/nashorn/internal/runtime/FunctionInitializer.java
index e2912a25..906024d7 100644
--- a/src/jdk/nashorn/internal/runtime/FunctionInitializer.java
+++ b/src/jdk/nashorn/internal/runtime/FunctionInitializer.java
@@ -60,6 +60,17 @@ public final class FunctionInitializer implements Serializable {
}
/**
+ * Copy constructor.
+ *
+ * @param init original initializer
+ */
+ FunctionInitializer(final FunctionInitializer init) {
+ this.className = init.getClassName();
+ this.methodType = init.getMethodType();
+ this.flags = init.getFlags();
+ }
+
+ /**
* Constructor.
*
* @param functionNode the function node
diff --git a/src/jdk/nashorn/internal/runtime/GlobalConstants.java b/src/jdk/nashorn/internal/runtime/GlobalConstants.java
index df947cdb..3a104812 100644
--- a/src/jdk/nashorn/internal/runtime/GlobalConstants.java
+++ b/src/jdk/nashorn/internal/runtime/GlobalConstants.java
@@ -309,7 +309,7 @@ public final class GlobalConstants implements Loggable {
*
* @param find property lookup
* @param inv normal guarded invocation for this setter, as computed by the ScriptObject linker
- * @param desc callsite descriptr
+ * @param desc callsite descriptor
* @param request link request
*
* @return null if failed to set up constant linkage
@@ -376,8 +376,12 @@ public final class GlobalConstants implements Loggable {
* @return resulting getter, or null if failed to create constant
*/
synchronized GuardedInvocation findGetMethod(final FindProperty find, final ScriptObject receiver, final CallSiteDescriptor desc) {
- // Also return null if property may have side effects
- if ((GLOBAL_ONLY && !find.getOwner().isGlobal()) || find.getProperty() instanceof UserAccessorProperty) {
+ // Only use constant getter for fast scope access, because the receiver may change between invocations
+ // for slow-scope and non-scope callsites.
+ // Also return null for user accessor properties as they may have side effects.
+ if (!NashornCallSiteDescriptor.isFastScope(desc)
+ || (GLOBAL_ONLY && !find.getOwner().isGlobal())
+ || find.getProperty() instanceof UserAccessorProperty) {
return null;
}
diff --git a/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/src/jdk/nashorn/internal/runtime/JSONFunctions.java
index 5fe57725..a400bbd9 100644
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -122,7 +122,7 @@ public final class JSONFunctions {
if (newElement == ScriptRuntime.UNDEFINED) {
valueObj.delete(key, false);
} else {
- setPropertyValue(valueObj, key, newElement, false);
+ setPropertyValue(valueObj, key, newElement);
}
}
}
@@ -179,7 +179,7 @@ public final class JSONFunctions {
final String name = pNode.getKeyName();
final Object value = convertNode(global, valueNode);
- setPropertyValue(object, name, value, false);
+ setPropertyValue(object, name, value);
}
return object;
@@ -193,14 +193,14 @@ public final class JSONFunctions {
}
// add a new property if does not exist already, or else set old property
- private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
+ private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value) {
final int index = ArrayIndex.getArrayIndex(name);
if (ArrayIndex.isValidArrayIndex(index)) {
// array index key
sobj.defineOwnProperty(index, value);
} else if (sobj.getMap().findProperty(name) != null) {
// pre-existing non-inherited property, call set
- sobj.set(name, value, strict);
+ sobj.set(name, value, 0);
} else {
// add new property
sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
diff --git a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
index 27c9bca7..2d110e08 100644
--- a/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
+++ b/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
@@ -256,7 +256,7 @@ public final class NativeJavaPackage extends ScriptObject {
final Object constructor = BeansLinker.getConstructorMethod(
javaClass, propertyName.substring(openBrace + 1, lastChar));
if (constructor != null) {
- set(propertyName, constructor, false);
+ set(propertyName, constructor, 0);
return constructor;
}
// we didn't find a matching constructor!
@@ -270,7 +270,7 @@ public final class NativeJavaPackage extends ScriptObject {
propertyValue = StaticClass.forClass(javaClass);
}
- set(propertyName, propertyValue, false);
+ set(propertyName, propertyValue, 0);
return propertyValue;
}
}
diff --git a/src/jdk/nashorn/internal/runtime/Property.java b/src/jdk/nashorn/internal/runtime/Property.java
index c83c4531..1f9f1459 100644
--- a/src/jdk/nashorn/internal/runtime/Property.java
+++ b/src/jdk/nashorn/internal/runtime/Property.java
@@ -101,7 +101,7 @@ public abstract class Property implements Serializable {
private final int slot;
/** SwitchPoint that is invalidated when property is changed, optional */
- protected SwitchPoint changeCallback;
+ protected transient SwitchPoint changeCallback;
private static final long serialVersionUID = 2099814273074501176L;
diff --git a/src/jdk/nashorn/internal/runtime/PropertyAccess.java b/src/jdk/nashorn/internal/runtime/PropertyAccess.java
index 6f09e997..420ef44f 100644
--- a/src/jdk/nashorn/internal/runtime/PropertyAccess.java
+++ b/src/jdk/nashorn/internal/runtime/PropertyAccess.java
@@ -163,129 +163,129 @@ public interface PropertyAccess {
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(Object key, int value, boolean strict);
+ public void set(Object key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(Object key, long value, boolean strict);
+ public void set(Object key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(Object key, double value, boolean strict);
+ public void set(Object key, double value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(Object key, Object value, boolean strict);
+ public void set(Object key, Object value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(double key, int value, boolean strict);
+ public void set(double key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(double key, long value, boolean strict);
+ public void set(double key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(double key, double value, boolean strict);
+ public void set(double key, double value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(double key, Object value, boolean strict);
+ public void set(double key, Object value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(long key, int value, boolean strict);
+ public void set(long key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(long key, long value, boolean strict);
+ public void set(long key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(long key, double value, boolean strict);
+ public void set(long key, double value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(long key, Object value, boolean strict);
+ public void set(long key, Object value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(int key, int value, boolean strict);
+ public void set(int key, int value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(int key, long value, boolean strict);
+ public void set(int key, long value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(int key, double value, boolean strict);
+ public void set(int key, double value, int flags);
/**
* Set the value of a given key
* @param key the key
* @param value the value
- * @param strict are we in strict mode
+ * @param flags call site flags
*/
- public void set(int key, Object value, boolean strict);
+ public void set(int key, Object value, int flags);
/**
* Check if the given key exists anywhere in the proto chain
diff --git a/src/jdk/nashorn/internal/runtime/PropertyMap.java b/src/jdk/nashorn/internal/runtime/PropertyMap.java
index 0246b531..d8e76082 100644
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java
+++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java
@@ -568,9 +568,7 @@ public final class PropertyMap implements Iterable<Object>, Serializable {
for (final Property property : otherProperties) {
// This method is only safe to use with non-slotted, native getter/setter properties
assert property.getSlot() == -1;
- if (isValidArrayIndex(getArrayIndex(property.getKey()))) {
- newMap.setContainsArrayKeys();
- }
+ assert !(isValidArrayIndex(getArrayIndex(property.getKey())));
}
return newMap;
diff --git a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
index 5f5229ba..2d5ccc05 100644
--- a/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
+++ b/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
@@ -491,14 +491,15 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData imp
private FunctionInitializer install(final StoredScript script) {
final Map<String, Class<?>> installedClasses = new HashMap<>();
+ final Map<String, byte[]> classBytes = script.getClassBytes();
final String mainClassName = script.getMainClassName();
- final byte[] mainClassBytes = script.getClassBytes().get(mainClassName);
+ final byte[] mainClassBytes = classBytes.get(mainClassName);
final Class<?> mainClass = installer.install(mainClassName, mainClassBytes);
installedClasses.put(mainClassName, mainClass);
- for (final Map.Entry<String, byte[]> entry : script.getClassBytes().entrySet()) {
+ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
final String className = entry.getKey();
final byte[] code = entry.getValue();
diff --git a/src/jdk/nashorn/internal/runtime/RewriteException.java b/src/jdk/nashorn/internal/runtime/RewriteException.java
index 37d65f2f..4c0e0a3a 100644
--- a/src/jdk/nashorn/internal/runtime/RewriteException.java
+++ b/src/jdk/nashorn/internal/runtime/RewriteException.java
@@ -45,6 +45,7 @@ import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.lookup.MethodHandleFactory;
import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
/**
* Used to signal to the linker to relink the callee
@@ -161,7 +162,7 @@ public final class RewriteException extends Exception {
assert runtimeScope == null;
runtimeScope = (ScriptObject)value;
} else if(name != null) {
- locals.set(name, value, true);
+ locals.set(name, value, NashornCallSiteDescriptor.CALLSITE_STRICT);
}
}
locals.setProto(runtimeScope);
diff --git a/src/jdk/nashorn/internal/runtime/ScriptObject.java b/src/jdk/nashorn/internal/runtime/ScriptObject.java
index cabd1357..8d616b58 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -198,10 +198,10 @@ public abstract class ScriptObject implements PropertyAccess {
public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
static final MethodHandle[] SET_SLOW = new MethodHandle[] {
- findOwnMH_V("set", void.class, Object.class, int.class, boolean.class),
- findOwnMH_V("set", void.class, Object.class, long.class, boolean.class),
- findOwnMH_V("set", void.class, Object.class, double.class, boolean.class),
- findOwnMH_V("set", void.class, Object.class, Object.class, boolean.class)
+ findOwnMH_V("set", void.class, Object.class, int.class, int.class),
+ findOwnMH_V("set", void.class, Object.class, long.class, int.class),
+ findOwnMH_V("set", void.class, Object.class, double.class, int.class),
+ findOwnMH_V("set", void.class, Object.class, Object.class, int.class)
};
/** Method handle to reset the map of this ScriptObject */
@@ -593,7 +593,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (newValue && property != null) {
// Temporarily clear flags.
property = modifyOwnProperty(property, 0);
- set(key, value, false);
+ set(key, value, 0);
//this might change the map if we change types of the property
//hence we need to read it again. note that we should probably
//have the setter return the new property throughout and in
@@ -758,7 +758,7 @@ public abstract class ScriptObject implements PropertyAccess {
* @return FindPropertyData or null if not found.
*/
public final FindProperty findProperty(final String key, final boolean deep) {
- return findProperty(key, deep, false, this);
+ return findProperty(key, deep, this);
}
/**
@@ -775,16 +775,11 @@ public abstract class ScriptObject implements PropertyAccess {
*
* @param key Property key.
* @param deep Whether the search should look up proto chain.
- * @param stopOnNonScope should a deep search stop on the first non-scope object?
* @param start the object on which the lookup was originally initiated
*
* @return FindPropertyData or null if not found.
*/
- FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
- // if doing deep search, stop search on the first non-scope object if asked to do so
- if (stopOnNonScope && start != this && !isScope()) {
- return null;
- }
+ FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) {
final PropertyMap selfMap = getMap();
final Property property = selfMap.findProperty(key);
@@ -796,7 +791,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (deep) {
final ScriptObject myProto = getProto();
if (myProto != null) {
- return myProto.findProperty(key, deep, stopOnNonScope, start);
+ return myProto.findProperty(key, deep, start);
}
}
@@ -1164,7 +1159,7 @@ public abstract class ScriptObject implements PropertyAccess {
* @param value the value to write at the given index
*/
public void setArgument(final int key, final Object value) {
- set(key, value, false);
+ set(key, value, 0);
}
/**
@@ -1725,7 +1720,8 @@ public abstract class ScriptObject implements PropertyAccess {
*/
public Object put(final Object key, final Object value, final boolean strict) {
final Object oldValue = get(key);
- set(key, value, strict);
+ final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
+ set(key, value, flags);
return oldValue;
}
@@ -1738,8 +1734,9 @@ public abstract class ScriptObject implements PropertyAccess {
* @param strict strict mode or not
*/
public void putAll(final Map<?, ?> otherMap, final boolean strict) {
+ final int flags = strict ? NashornCallSiteDescriptor.CALLSITE_STRICT : 0;
for (final Map.Entry<?, ?> entry : otherMap.entrySet()) {
- set(entry.getKey(), entry.getValue(), strict);
+ set(entry.getKey(), entry.getValue(), flags);
}
}
@@ -2042,7 +2039,7 @@ public abstract class ScriptObject implements PropertyAccess {
final PropertyMap newMap = map.replaceProperty(property, property.removeFlags(Property.NEEDS_DECLARATION));
setMap(newMap);
- set(key, value, true);
+ set(key, value, 0);
}
/**
@@ -2135,7 +2132,6 @@ public abstract class ScriptObject implements PropertyAccess {
return findMegaMorphicSetMethod(desc, name);
}
- final boolean scope = isScope();
final boolean explicitInstanceOfCheck = explicitInstanceOfCheck(desc, request);
/*
@@ -2145,16 +2141,18 @@ public abstract class ScriptObject implements PropertyAccess {
*
* toString = function() { print("global toString"); } // don't affect Object.prototype.toString
*/
- FindProperty find = findProperty(name, true, scope, this);
+ FindProperty find = findProperty(name, true, this);
// If it's not a scope search, then we don't want any inherited properties except those with user defined accessors.
- if (!scope && find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
+ if (find != null && find.isInherited() && !(find.getProperty() instanceof UserAccessorProperty)) {
// We should still check if inherited data property is not writable
if (isExtensible() && !find.getProperty().isWritable()) {
- return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", false);
+ return createEmptySetMethod(desc, explicitInstanceOfCheck, "property.not.writable", true);
+ }
+ // Otherwise, forget the found property unless this is a scope callsite and the owner is a scope object as well.
+ if (!NashornCallSiteDescriptor.isScope(desc) || !find.getOwner().isScope()) {
+ find = null;
}
- // Otherwise, forget the found property
- find = null;
}
if (find != null) {
@@ -2180,8 +2178,8 @@ public abstract class ScriptObject implements PropertyAccess {
private GuardedInvocation createEmptySetMethod(final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final String strictErrorMessage, final boolean canBeFastScope) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
- if (NashornCallSiteDescriptor.isStrict(desc)) {
- throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this));
+ if (NashornCallSiteDescriptor.isStrict(desc)) {
+ throw typeError(strictErrorMessage, name, ScriptRuntime.safeToString(this));
}
assert canBeFastScope || !NashornCallSiteDescriptor.isFastScope(desc);
return new GuardedInvocation(
@@ -2207,7 +2205,7 @@ public abstract class ScriptObject implements PropertyAccess {
private GuardedInvocation findMegaMorphicSetMethod(final CallSiteDescriptor desc, final String name) {
final MethodType type = desc.getMethodType().insertParameterTypes(1, Object.class);
//never bother with ClassCastExceptionGuard for megamorphic callsites
- final GuardedInvocation inv = findSetIndexMethod(getClass(), false, type, NashornCallSiteDescriptor.isStrict(desc));
+ final GuardedInvocation inv = findSetIndexMethod(getClass(), desc, false, type);
return inv.replaceMethods(MH.insertArguments(inv.getInvocation(), 1, name), inv.getGuard());
}
@@ -2230,24 +2228,26 @@ public abstract class ScriptObject implements PropertyAccess {
* @return GuardedInvocation to be invoked at call site.
*/
protected GuardedInvocation findSetIndexMethod(final CallSiteDescriptor desc, final LinkRequest request) { // array, index, value
- return findSetIndexMethod(getClass(), explicitInstanceOfCheck(desc, request), desc.getMethodType(), NashornCallSiteDescriptor.isStrict(desc));
+ return findSetIndexMethod(getClass(), desc, explicitInstanceOfCheck(desc, request), desc.getMethodType());
}
/**
* Find the appropriate SETINDEX method for an invoke dynamic call.
*
+ * @param clazz the receiver class
+ * @param desc the call site descriptor
+ * @param explicitInstanceOfCheck add an explicit instanceof check?
* @param callType the method type at the call site
- * @param isStrict are we in strict mode?
*
* @return GuardedInvocation to be invoked at call site.
*/
- private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final boolean explicitInstanceOfCheck, final MethodType callType, final boolean isStrict) {
+ private static GuardedInvocation findSetIndexMethod(final Class<? extends ScriptObject> clazz, final CallSiteDescriptor desc, final boolean explicitInstanceOfCheck, final MethodType callType) {
assert callType.parameterCount() == 3;
final Class<?> keyClass = callType.parameterType(1);
final Class<?> valueClass = callType.parameterType(2);
- MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, boolean.class);
- methodHandle = MH.insertArguments(methodHandle, 3, isStrict);
+ MethodHandle methodHandle = findOwnMH_V(clazz, "set", void.class, keyClass, valueClass, int.class);
+ methodHandle = MH.insertArguments(methodHandle, 3, NashornCallSiteDescriptor.getFlags(desc));
return new GuardedInvocation(methodHandle, getScriptObjectGuard(callType, explicitInstanceOfCheck), (SwitchPoint)null, explicitInstanceOfCheck ? null : ClassCastException.class);
}
@@ -2672,7 +2672,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
if (object.getMap().containsArrayKeys()) {
- final FindProperty find = object.findProperty(key, false, false, this);
+ final FindProperty find = object.findProperty(key, false, this);
if (find != null) {
return getIntValue(find, programPoint);
@@ -2755,7 +2755,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
if (object.getMap().containsArrayKeys()) {
- final FindProperty find = object.findProperty(key, false, false, this);
+ final FindProperty find = object.findProperty(key, false, this);
if (find != null) {
return getLongValue(find, programPoint);
}
@@ -2837,7 +2837,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
if (object.getMap().containsArrayKeys()) {
- final FindProperty find = object.findProperty(key, false, false, this);
+ final FindProperty find = object.findProperty(key, false, this);
if (find != null) {
return getDoubleValue(find, programPoint);
}
@@ -2919,7 +2919,7 @@ public abstract class ScriptObject implements PropertyAccess {
if (isValidArrayIndex(index)) {
for (ScriptObject object = this; ; ) {
if (object.getMap().containsArrayKeys()) {
- final FindProperty find = object.findProperty(key, false, false, this);
+ final FindProperty find = object.findProperty(key, false, this);
if (find != null) {
return find.getObjectValue();
@@ -2996,48 +2996,48 @@ public abstract class ScriptObject implements PropertyAccess {
return get(index, JSType.toString(key));
}
- private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final boolean strict) {
+ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final int value, final int callSiteFlags) {
if (getMap().containsArrayKeys()) {
final String key = JSType.toString(longIndex);
final FindProperty find = findProperty(key, true);
if (find != null) {
- setObject(find, strict, key, value);
+ setObject(find, callSiteFlags, key, value);
return true;
}
}
return false;
}
- private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final boolean strict) {
+ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final long value, final int callSiteFlags) {
if (getMap().containsArrayKeys()) {
final String key = JSType.toString(longIndex);
final FindProperty find = findProperty(key, true);
if (find != null) {
- setObject(find, strict, key, value);
+ setObject(find, callSiteFlags, key, value);
return true;
}
}
return false;
}
- private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final boolean strict) {
+ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final double value, final int callSiteFlags) {
if (getMap().containsArrayKeys()) {
final String key = JSType.toString(longIndex);
final FindProperty find = findProperty(key, true);
if (find != null) {
- setObject(find, strict, key, value);
+ setObject(find, callSiteFlags, key, value);
return true;
}
}
return false;
}
- private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final boolean strict) {
+ private boolean doesNotHaveCheckArrayKeys(final long longIndex, final Object value, final int callSiteFlags) {
if (getMap().containsArrayKeys()) {
final String key = JSType.toString(longIndex);
final FindProperty find = findProperty(key, true);
if (find != null) {
- setObject(find, strict, key, value);
+ setObject(find, callSiteFlags, key, value);
return true;
}
}
@@ -3045,10 +3045,10 @@ public abstract class ScriptObject implements PropertyAccess {
}
//value agnostic
- private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final boolean strict) {
+ private boolean doesNotHaveEnsureLength(final long longIndex, final long oldLength, final int callSiteFlags) {
if (longIndex >= oldLength) {
if (!isExtensible()) {
- if (strict) {
+ if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) {
throw typeError("object.non.extensible", JSType.toString(longIndex), ScriptRuntime.safeToString(this));
}
return true;
@@ -3068,37 +3068,41 @@ public abstract class ScriptObject implements PropertyAccess {
}
}
- private void doesNotHave(final int index, final int value, final boolean strict) {
+ private void doesNotHave(final int index, final int value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
- if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) {
+ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
+ final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags);
setArray(getArray().set(index, value, strict));
doesNotHaveEnsureDelete(longIndex, oldLength, strict);
}
}
- private void doesNotHave(final int index, final long value, final boolean strict) {
+ private void doesNotHave(final int index, final long value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
- if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) {
+ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
+ final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags);
setArray(getArray().set(index, value, strict));
doesNotHaveEnsureDelete(longIndex, oldLength, strict);
}
}
- private void doesNotHave(final int index, final double value, final boolean strict) {
+ private void doesNotHave(final int index, final double value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
- if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) {
+ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
+ final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags);
setArray(getArray().set(index, value, strict));
doesNotHaveEnsureDelete(longIndex, oldLength, strict);
}
}
- private void doesNotHave(final int index, final Object value, final boolean strict) {
+ private void doesNotHave(final int index, final Object value, final int callSiteFlags) {
final long oldLength = getArray().length();
final long longIndex = ArrayIndex.toLongIndex(index);
- if (!doesNotHaveCheckArrayKeys(longIndex, value, strict) && !doesNotHaveEnsureLength(longIndex, oldLength, strict)) {
+ if (!doesNotHaveCheckArrayKeys(longIndex, value, callSiteFlags) && !doesNotHaveEnsureLength(longIndex, oldLength, callSiteFlags)) {
+ final boolean strict = NashornCallSiteDescriptor.isStrictFlag(callSiteFlags);
setArray(getArray().set(index, value, strict));
doesNotHaveEnsureDelete(longIndex, oldLength, strict);
}
@@ -3108,32 +3112,47 @@ public abstract class ScriptObject implements PropertyAccess {
* This is the most generic of all Object setters. Most of the others use this in some form.
* TODO: should be further specialized
*
- * @param find found property
- * @param strict are we in strict mode
- * @param key property key
- * @param value property value
+ * @param find found property
+ * @param callSiteFlags callsite flags
+ * @param key property key
+ * @param value property value
*/
- public final void setObject(final FindProperty find, final boolean strict, final String key, final Object value) {
+ public final void setObject(final FindProperty find, final int callSiteFlags, final String key, final Object value) {
FindProperty f = find;
- if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty) && !isScope()) {
- // Setting a property should not modify the property in prototype unless this is a scope object.
- f = null;
+ if (f != null && f.isInherited() && !(f.getProperty() instanceof UserAccessorProperty)) {
+ final boolean isScope = NashornCallSiteDescriptor.isScopeFlag(callSiteFlags);
+ // If the start object of the find is not this object it means the property was found inside a
+ // 'with' statement expression (see WithObject.findProperty()). In this case we forward the 'set'
+ // to the 'with' object.
+ // Note that although a 'set' operation involving a with statement follows scope rules outside
+ // the 'with' expression (the 'set' operation is performed on the owning prototype if it exists),
+ // it follows non-scope rules inside the 'with' expression (set is performed on the top level object).
+ // This is why we clear the callsite flags and FindProperty in the forward call to the 'with' object.
+ if (isScope && f.getSelf() != this) {
+ f.getSelf().setObject(null, 0, key, value);
+ return;
+ }
+ // Setting a property should not modify the property in prototype unless this is a scope callsite
+ // and the owner is a scope object as well (with the exception of 'with' statement handled above).
+ if (!isScope || !f.getOwner().isScope()) {
+ f = null;
+ }
}
if (f != null) {
if (!f.getProperty().isWritable()) {
- if (strict) {
+ if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) {
throw typeError("property.not.writable", key, ScriptRuntime.safeToString(this));
}
return;
}
- f.setValue(value, strict);
+ f.setValue(value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags));
} else if (!isExtensible()) {
- if (strict) {
+ if (NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)) {
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
}
} else {
@@ -3153,293 +3172,293 @@ public abstract class ScriptObject implements PropertyAccess {
}
@Override
- public void set(final Object key, final int value, final boolean strict) {
+ public void set(final Object key, final int value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(primitiveKey);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final Object key, final long value, final boolean strict) {
+ public void set(final Object key, final long value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(primitiveKey);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final Object key, final double value, final boolean strict) {
+ public void set(final Object key, final double value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(primitiveKey);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final Object key, final Object value, final boolean strict) {
+ public void set(final Object key, final Object value, final int callSiteFlags) {
final Object primitiveKey = JSType.toPrimitive(key, String.class);
final int index = getArrayIndex(primitiveKey);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(primitiveKey);
- setObject(findProperty(propName, true), strict, propName, value);
+ setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
- public void set(final double key, final int value, final boolean strict) {
+ public void set(final double key, final int value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final double key, final long value, final boolean strict) {
+ public void set(final double key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final double key, final double value, final boolean strict) {
+ public void set(final double key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final double key, final Object value, final boolean strict) {
+ public void set(final double key, final Object value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, value);
+ setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
- public void set(final long key, final int value, final boolean strict) {
+ public void set(final long key, final int value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final long key, final long value, final boolean strict) {
+ public void set(final long key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final long key, final double value, final boolean strict) {
+ public void set(final long key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final long key, final Object value, final boolean strict) {
+ public void set(final long key, final Object value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, value);
+ setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
- public void set(final int key, final int value, final boolean strict) {
+ public void set(final int key, final int value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final int key, final long value, final boolean strict) {
+ public void set(final int key, final long value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final int key, final double value, final boolean strict) {
+ public void set(final int key, final double value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, JSType.toObject(value));
+ setObject(findProperty(propName, true), callSiteFlags, propName, JSType.toObject(value));
}
@Override
- public void set(final int key, final Object value, final boolean strict) {
+ public void set(final int key, final Object value, final int callSiteFlags) {
final int index = getArrayIndex(key);
if (isValidArrayIndex(index)) {
if (getArray().has(index)) {
- setArray(getArray().set(index, value, strict));
+ setArray(getArray().set(index, value, NashornCallSiteDescriptor.isStrictFlag(callSiteFlags)));
} else {
- doesNotHave(index, value, strict);
+ doesNotHave(index, value, callSiteFlags);
}
return;
}
final String propName = JSType.toString(key);
- setObject(findProperty(propName, true), strict, propName, value);
+ setObject(findProperty(propName, true), callSiteFlags, propName, value);
}
@Override
diff --git a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
index 2113b79c..83583232 100644
--- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
+++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
@@ -221,9 +221,9 @@ public final class ScriptingFunctions {
final String err = errBuffer.toString();
// Set globals for secondary results.
- global.set(OUT_NAME, out, false);
- global.set(ERR_NAME, err, false);
- global.set(EXIT_NAME, exit, false);
+ global.set(OUT_NAME, out, 0);
+ global.set(ERR_NAME, err, 0);
+ global.set(EXIT_NAME, exit, 0);
// Propagate exception if present.
for (final IOException element : exception) {
diff --git a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
index 757cb305..99ec3135 100644
--- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
+++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
@@ -205,7 +205,7 @@ final class SetMethodCreator {
//slow setter, that calls ScriptObject.set with appropraite type and key name
MethodHandle slowSetter = ScriptObject.SET_SLOW[getAccessorTypeIndex(type)];
- slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.isStrict(desc));
+ slowSetter = MH.insertArguments(slowSetter, 3, NashornCallSiteDescriptor.getFlags(desc));
slowSetter = MH.insertArguments(slowSetter, 1, name);
slowSetter = MH.asType(slowSetter, slowSetter.type().changeParameterType(0, Object.class));
diff --git a/src/jdk/nashorn/internal/runtime/StoredScript.java b/src/jdk/nashorn/internal/runtime/StoredScript.java
index 7a76b983..5b6a77b2 100644
--- a/src/jdk/nashorn/internal/runtime/StoredScript.java
+++ b/src/jdk/nashorn/internal/runtime/StoredScript.java
@@ -27,6 +27,7 @@ package jdk.nashorn.internal.runtime;
import java.io.Serializable;
import java.util.Arrays;
+import java.util.LinkedHashMap;
import java.util.Map;
/**
@@ -83,7 +84,11 @@ public final class StoredScript implements Serializable {
* @return map of class bytes
*/
public Map<String, byte[]> getClassBytes() {
- return classBytes;
+ final Map<String, byte[]> clonedMap = new LinkedHashMap<>();
+ for (final Map.Entry<String, byte[]> entry : classBytes.entrySet()) {
+ clonedMap.put(entry.getKey(), entry.getValue().clone());
+ }
+ return clonedMap;
}
/**
@@ -91,11 +96,19 @@ public final class StoredScript implements Serializable {
* @return constants array
*/
public Object[] getConstants() {
- return constants;
+ return constants.clone();
}
- Map<Integer, FunctionInitializer> getInitializers() {
- return initializers;
+ /**
+ * Returns the function initializers map.
+ * @return The initializers map.
+ */
+ public Map<Integer, FunctionInitializer> getInitializers() {
+ final Map<Integer, FunctionInitializer> clonedMap = new LinkedHashMap<>();
+ for (final Map.Entry<Integer, FunctionInitializer> entry : initializers.entrySet()) {
+ clonedMap.put(entry.getKey(), new FunctionInitializer(entry.getValue()));
+ }
+ return clonedMap;
}
@Override
diff --git a/src/jdk/nashorn/internal/runtime/Undefined.java b/src/jdk/nashorn/internal/runtime/Undefined.java
index fc1a028a..57c7e5f1 100644
--- a/src/jdk/nashorn/internal/runtime/Undefined.java
+++ b/src/jdk/nashorn/internal/runtime/Undefined.java
@@ -34,6 +34,7 @@ import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor;
/**
* Unique instance of this class is used to represent JavaScript undefined.
@@ -128,7 +129,7 @@ public final class Undefined extends DefaultPropertyAccess {
}
private static final MethodHandle GET_METHOD = findOwnMH("get", Object.class, Object.class);
- private static final MethodHandle SET_METHOD = MH.insertArguments(findOwnMH("set", void.class, Object.class, Object.class, boolean.class), 3, Boolean.TRUE);
+ private static final MethodHandle SET_METHOD = MH.insertArguments(findOwnMH("set", void.class, Object.class, Object.class, int.class), 3, NashornCallSiteDescriptor.CALLSITE_STRICT);
private static GuardedInvocation findGetMethod(final CallSiteDescriptor desc) {
return new GuardedInvocation(MH.insertArguments(GET_METHOD, 1, desc.getNameToken(2)), UNDEFINED_GUARD).asType(desc);
@@ -152,7 +153,7 @@ public final class Undefined extends DefaultPropertyAccess {
}
@Override
- public void set(final Object key, final Object value, final boolean strict) {
+ public void set(final Object key, final Object value, final int flags) {
throw typeError("cant.set.property.of.undefined", ScriptRuntime.safeToString(key));
}
diff --git a/src/jdk/nashorn/internal/runtime/WithObject.java b/src/jdk/nashorn/internal/runtime/WithObject.java
index 723b510f..54ec06f5 100644
--- a/src/jdk/nashorn/internal/runtime/WithObject.java
+++ b/src/jdk/nashorn/internal/runtime/WithObject.java
@@ -193,18 +193,20 @@ public final class WithObject extends ScriptObject implements Scope {
*
* @param key Property key.
* @param deep Whether the search should look up proto chain.
- * @param stopOnNonScope should a deep search stop on the first non-scope object?
* @param start the object on which the lookup was originally initiated
*
* @return FindPropertyData or null if not found.
*/
@Override
- FindProperty findProperty(final String key, final boolean deep, final boolean stopOnNonScope, final ScriptObject start) {
- final FindProperty exprProperty = expression.findProperty(key, deep, stopOnNonScope, start);
+ FindProperty findProperty(final String key, final boolean deep, final ScriptObject start) {
+ // We call findProperty on 'expression' with 'expression' itself as start parameter.
+ // This way in ScriptObject.setObject we can tell the property is from a 'with' expression
+ // (as opposed from another non-scope object in the proto chain such as Object.prototype).
+ final FindProperty exprProperty = expression.findProperty(key, true, expression);
if (exprProperty != null) {
return exprProperty;
}
- return super.findProperty(key, deep, stopOnNonScope, start);
+ return super.findProperty(key, deep, start);
}
@Override
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
index e6b8b90b..f802e039 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
@@ -125,6 +125,15 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
@Override
public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
+ if (sourceType == ConsString.class) {
+ if (String.class == targetType1 || CharSequence.class == targetType1) {
+ return Comparison.TYPE_1_BETTER;
+ }
+
+ if (String.class == targetType2 || CharSequence.class == targetType2) {
+ return Comparison.TYPE_2_BETTER;
+ }
+ }
return linkerServices.compareConversion(sourceType, targetType1, targetType2);
}
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
index f859f7bb..4ed6e3a2 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java
@@ -131,11 +131,16 @@ final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeCo
}
return getInvocation(EMPTY_ELEM_GETTER, self, linkerServices, desc);
case "setProp":
- case "setElem":
+ case "setElem": {
+ final boolean strict = NashornCallSiteDescriptor.isStrict(desc);
+ if (strict) {
+ throw typeError("cant.set.property", getArgument(linkRequest), ScriptRuntime.safeToString(self));
+ }
if (desc.getOperand() != null) {
return getInvocation(EMPTY_PROP_SETTER, self, linkerServices, desc);
}
return getInvocation(EMPTY_ELEM_SETTER, self, linkerServices, desc);
+ }
default:
break;
}
diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
index 1871a2cb..27fc3a2e 100644
--- a/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
+++ b/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
@@ -255,7 +255,7 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor
* @return the Nashorn-specific flags for the call site, or 0 if the passed descriptor is not a Nashorn call site
* descriptor.
*/
- private static int getFlags(final CallSiteDescriptor desc) {
+ public static int getFlags(final CallSiteDescriptor desc) {
return desc instanceof NashornCallSiteDescriptor ? ((NashornCallSiteDescriptor)desc).flags : 0;
}
@@ -343,6 +343,24 @@ public final class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor
}
/**
+ * Returns true if {@code flags} has the {@link #CALLSITE_STRICT} bit set.
+ * @param flags the flags
+ * @return true if the flag is set, false otherwise.
+ */
+ public static boolean isStrictFlag(final int flags) {
+ return (flags & CALLSITE_STRICT) != 0;
+ }
+
+ /**
+ * Returns true if {@code flags} has the {@link #CALLSITE_SCOPE} bit set.
+ * @param flags the flags
+ * @return true if the flag is set, false otherwise.
+ */
+ public static boolean isScopeFlag(final int flags) {
+ return (flags & CALLSITE_SCOPE) != 0;
+ }
+
+ /**
* Get a program point from a descriptor (must be optimistic)
* @param desc descriptor
* @return program point
diff --git a/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index 16b4e05d..056dc87d 100644
--- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -92,7 +92,7 @@ type.error.cant.delete.property.of.undefined=Cannot delete property "{0}" of und
# other wrong usages of property
type.error.property.has.no.setter=Cannot set property "{0}" of {1} that has only a getter
-type.error.cant.set.proto.to.non.object=Cannot set Object {0}'s __proto__ to be a non-object like {1}
+type.error.cant.set.proto.to.non.object=Cannot set Object {0}''s __proto__ to be a non-object like {1}
type.error.no.such.function={1} has no such function "{0}"
type.error.no.such.java.class=No such Java class: {0}
type.error.no.such.java.constructor=No such Java constructor: {0}
@@ -125,10 +125,10 @@ type.error.prototype.not.an.object="prototype" of {0} is not an Object, it is {1
type.error.cant.load.script=Cannot load script from {0}
type.error.JSON.stringify.cyclic=JSON.stringify got a cyclic data structure
type.error.cant.convert.string.to.char=Cannot convert string to character; its length must be exactly 1
-type.error.cant.convert.number.to.char=Cannot convert number to character; it's out of 0-65535 range
+type.error.cant.convert.number.to.char=Cannot convert number to character; it is out of 0-65535 range
type.error.cant.convert.to.java.string=Cannot convert object of type {0} to a Java argument of string type
type.error.cant.convert.to.java.number=Cannot convert object of type {0} to a Java argument of number type
-type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Can't convert object of type {0}.
+type.error.cant.convert.to.javascript.array=Can only convert Java arrays and lists to JavaScript arrays. Cannot convert object of type {0}.
type.error.extend.expects.at.least.one.argument=Java.extend needs at least one argument.
type.error.extend.expects.at.least.one.type.argument=Java.extend needs at least one type argument.
type.error.extend.expects.java.types=Java.extend needs Java types as its arguments.
@@ -141,10 +141,10 @@ type.error.extend.ERROR_NO_COMMON_LOADER=Can not find a common class loader for
type.error.extend.ERROR_FINAL_FINALIZER=Can not extend class because {0} has a final finalize method.
type.error.no.constructor.matches.args=Can not construct {0} with the passed arguments; they do not match any of its constructor signatures.
type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
-type.error.method.not.constructor=Java method {0} can't be used as a constructor.
+type.error.method.not.constructor=Java method {0} cannot be used as a constructor.
type.error.env.not.object=$ENV must be an Object.
type.error.unsupported.java.to.type=Unsupported Java.to target type {0}.
-type.error.constructor.requires.new=Constructor {0} requires 'new'.
+type.error.constructor.requires.new=Constructor {0} requires "new".
type.error.new.on.nonpublic.javatype=new cannot be used with non-public java type {0}.
range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
diff --git a/test/script/basic/JDK-8043232.js.EXPECTED b/test/script/basic/JDK-8043232.js.EXPECTED
index 5fcfab8e..03382ea5 100644
--- a/test/script/basic/JDK-8043232.js.EXPECTED
+++ b/test/script/basic/JDK-8043232.js.EXPECTED
@@ -6,9 +6,9 @@ TypeError: No such Java constructor: Object(String)
TypeError: Java constructor signature invalid: Object()xxxxx
TypeError: Java constructor signature invalid: Object(
TypeError: Java constructor signature invalid: Object)
-TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cant be used as a constructor.
-TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cant be used as a constructor.
-TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new.
+TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.lang.System.getProperty] cannot be used as a constructor.
+TypeError: Java method [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] cannot be used as a constructor.
+TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
TypeError: No such Java constructor: Runnable()
TypeError: No such Java constructor: Runnable(int)
java.lang.InstantiationException: java.io.InputStream
diff --git a/test/script/basic/JDK-8047764-strict.js b/test/script/basic/JDK-8047764-strict.js
new file mode 100644
index 00000000..d10b5b37
--- /dev/null
+++ b/test/script/basic/JDK-8047764-strict.js
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype
+ *
+ * @test
+ * @run
+ */
+
+// Same as JDK-8047764.js but running in strict mode
+"use strict";
+
+// Test global set operation on properties defined in Object.prototype
+
+Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }});
+Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false });
+
+try {
+ prop1 = 1;
+ print("prop 1: " + prop2);
+} catch (e) {
+ print(e.name);
+}
+
+try {
+ prop2 = 2;
+ print("prop 2: " + prop2);
+} catch (e) {
+ print(e.name);
+}
+
+// Make sure various ways of setting global toString don't affect Object.prototype.toString
+
+function checkToString() {
+ print(global);
+ print(Object.prototype);
+ print(global.toString === Object.prototype.toString);
+ print(objProtoToString === Object.prototype.toString);
+}
+
+var global = this;
+var objProtoToString = Object.prototype.toString;
+global["toString"] = function() { return "global toString 1"; };
+checkToString();
+global.toString = function() { return "global toString 2"; };
+checkToString();
+toString = function() { return "global toString 3"; };
+checkToString();
diff --git a/test/script/basic/JDK-8047764-strict.js.EXPECTED b/test/script/basic/JDK-8047764-strict.js.EXPECTED
new file mode 100644
index 00000000..c452cfac
--- /dev/null
+++ b/test/script/basic/JDK-8047764-strict.js.EXPECTED
@@ -0,0 +1,15 @@
+setting prop1: 1
+prop 1: 1
+TypeError
+global toString 1
+[object Object]
+false
+true
+global toString 2
+[object Object]
+false
+true
+global toString 3
+[object Object]
+false
+true
diff --git a/test/script/basic/JDK-8047764.js b/test/script/basic/JDK-8047764.js
new file mode 100644
index 00000000..3920323f
--- /dev/null
+++ b/test/script/basic/JDK-8047764.js
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8047764: Indexed or polymorphic set on global affects Object.prototype
+ *
+ * @test
+ * @run
+ */
+
+// Test global set operation on properties defined in Object.prototype
+
+Object.defineProperty(Object.prototype, "prop1", { get: function() { return 1; }, set: function(v) { print("setting prop1: " + v); }});
+Object.defineProperty(Object.prototype, "prop2", { value: 1, writable: false, configurable: false });
+
+try {
+ prop1 = 1;
+ print("prop 1: " + prop2);
+} catch (e) {
+ print(e.name);
+}
+
+try {
+ prop2 = 2;
+ print("prop 2: " + prop2);
+} catch (e) {
+ print(e.name);
+}
+
+// Make sure various ways of setting global toString don't affect Object.prototype.toString
+
+function checkToString() {
+ print(global);
+ print(Object.prototype);
+ print(global.toString === Object.prototype.toString);
+ print(objProtoToString === Object.prototype.toString);
+}
+
+var global = this;
+var objProtoToString = Object.prototype.toString;
+global["toString"] = function() { return "global toString 1"; };
+checkToString();
+global.toString = function() { return "global toString 2"; };
+checkToString();
+toString = function() { return "global toString 3"; };
+checkToString();
+
+// Test setters on 'with' object
+
+var p = { prop3: 3, toString: function() { return "[object p]"; }};
+Object.defineProperty(p, "prop4", { get: function() { print("get", this); return 4; }, set: function(v) { print("set", this, v); }});
+var o = Object.create(p);
+o.toString = function() { return "[object o]"; };
+
+with(o) {
+ (function() {
+ var m = 5;
+ (function() {
+ print(prop3);
+ prop3 = m;
+ print(prop3);
+ print(prop4);
+ prop4 = m;
+ print(prop4);
+ })();
+ })();
+}
+
+print(o.hasOwnProperty("prop3"));
+print(o.prop3);
+print(p.prop3);
+print(o.hasOwnProperty("prop4"));
+print(o.prop4);
+print(p.prop4);
diff --git a/test/script/basic/JDK-8047764.js.EXPECTED b/test/script/basic/JDK-8047764.js.EXPECTED
new file mode 100644
index 00000000..5c9b0eb5
--- /dev/null
+++ b/test/script/basic/JDK-8047764.js.EXPECTED
@@ -0,0 +1,30 @@
+setting prop1: 1
+prop 1: 1
+prop 2: 1
+global toString 1
+[object Object]
+false
+true
+global toString 2
+[object Object]
+false
+true
+global toString 3
+[object Object]
+false
+true
+3
+5
+get [object o]
+4
+set [object o] 5
+get [object o]
+4
+true
+5
+3
+false
+get [object o]
+4
+get [object p]
+4
diff --git a/test/script/basic/JDK-8049242.js.EXPECTED b/test/script/basic/JDK-8049242.js.EXPECTED
index 4aa46276..4a2f4169 100644
--- a/test/script/basic/JDK-8049242.js.EXPECTED
+++ b/test/script/basic/JDK-8049242.js.EXPECTED
@@ -4,7 +4,7 @@ java.awt.Color[r=33,g=233,b=2]
TypeError: null is not a function
TypeError: null is not a function
TypeError: null is not a function
-TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires new.
+TypeError: Constructor [jdk.internal.dynalink.beans.SimpleDynamicMethod Color java.awt.Color.java.awt.Color(int,int,int)] requires "new".
TypeError: null is not a function
TypeError: null is not a function
java.lang.InstantiationException: java.io.InputStream
diff --git a/test/script/basic/JDK-8056978.js b/test/script/basic/JDK-8056978.js
new file mode 100644
index 00000000..1b3577d4
--- /dev/null
+++ b/test/script/basic/JDK-8056978.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8056978: ClassCastException: cannot cast jdk.nashorn.internal.scripts.JO*
+ *
+ * @test
+ * @run
+ */
+
+var obj1 = {
+ 'name': 'test name',
+ '1': '1',
+ '2': '2',
+ '3': '3',
+ '4': '4',
+ '5': '5'
+};
+
+var obj2 = {
+ 'name': 'hello'
+};
+
+print(obj2['name']);
+print(obj2.name);
+
diff --git a/test/script/basic/JDK-8056978.js.EXPECTED b/test/script/basic/JDK-8056978.js.EXPECTED
new file mode 100644
index 00000000..317e9677
--- /dev/null
+++ b/test/script/basic/JDK-8056978.js.EXPECTED
@@ -0,0 +1,2 @@
+hello
+hello
diff --git a/test/script/basic/JDK-8058422.js b/test/script/basic/JDK-8058422.js
new file mode 100644
index 00000000..b15c7cfb
--- /dev/null
+++ b/test/script/basic/JDK-8058422.js
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058422: Users should be able to overwrite "context" and "engine" variables
+ *
+ * @test
+ * @run
+ */
+
+var m = new javax.script.ScriptEngineManager();
+var e = m.getEngineByName("nashorn");
+e.put("foo", "hello");
+var obj = e.eval("context.getAttribute('foo')");
+if (obj != "hello") {
+ fail("Expected 'obj' to be 'hello'");
+}
+
+e.put("context", "bar");
+if (e.eval("context") != "bar") {
+ fail("Expected 'context' to be 'bar'");
+}
+
+if (e.eval("foo") != "hello") {
+ fail("Expected 'foo' to be 'hello'");
+}
+
+if (e.eval("engine") != e) {
+ fail("'engine' is not evaluaed to current engine");
+}
+
+e.put("engine", "foobar");
+if (e.eval("engine") != "foobar") {
+ fail("'engine' is not evalued to 'foobar'");
+}
diff --git a/test/script/basic/JDK-8058545.js b/test/script/basic/JDK-8058545.js
new file mode 100644
index 00000000..3b3a7c60
--- /dev/null
+++ b/test/script/basic/JDK-8058545.js
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058545: With strict mode, bean property assignment of a non-existent property should result in TypeError
+ *
+ * @test
+ * @run
+ */
+
+'use strict';
+var File = Java.type("java.io.File");
+var f = new File(".");
+try {
+ f.foo = 33;
+ fail("Should have thrown TypeError");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("Expected TypeError, got " + e);
+ }
+}
diff --git a/test/script/basic/JDK-8058561.js b/test/script/basic/JDK-8058561.js
new file mode 100644
index 00000000..f27d1d1b
--- /dev/null
+++ b/test/script/basic/JDK-8058561.js
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058561: NPE in LocalVariableTypesCalculator
+ *
+ * @test
+ * @run
+ * @option --lazy-compilation=false
+ */
+
+// Just attempting to compile this caused the NPE
+function func(x, y) {
+ while(true) {
+ switch (y[0]) {
+ case "bar":
+ x = 'xxx';
+ break;
+ }
+ }
+ return x;
+}
diff --git a/test/script/basic/JDK-8058615.js b/test/script/basic/JDK-8058615.js
new file mode 100644
index 00000000..354b5e4b
--- /dev/null
+++ b/test/script/basic/JDK-8058615.js
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8058615: Overload resolution ambiguity involving ConsString
+ *
+ * @test
+ * @run
+ */
+
+var strw = new java.io.StringWriter();
+var bufw = new java.io.BufferedWriter(strw);
+var s = "hello ";
+bufw.write(s + "world");
+bufw.close();
+print(strw.toString());
diff --git a/test/script/basic/JDK-8058615.js.EXPECTED b/test/script/basic/JDK-8058615.js.EXPECTED
new file mode 100644
index 00000000..3b18e512
--- /dev/null
+++ b/test/script/basic/JDK-8058615.js.EXPECTED
@@ -0,0 +1 @@
+hello world
diff --git a/test/src/jdk/nashorn/api/scripting/ScopeTest.java b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
index 865c97d6..3e2a6b6e 100644
--- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java
+++ b/test/src/jdk/nashorn/api/scripting/ScopeTest.java
@@ -582,6 +582,60 @@ public class ScopeTest {
assertEquals(e.eval("x", newCtxt), 2);
}
+ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+ @Test
+ public static void contextOverwriteTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = new SimpleBindings();
+ b.put("context", "hello");
+ b.put("foo", 32);
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ e.setContext(newCtxt);
+ assertEquals(e.eval("context"), "hello");
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ }
+
+ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+ @Test
+ public static void contextOverwriteInScriptTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ e.put("foo", 32);
+
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ assertEquals(e.eval("context = 'bar'"), "bar");
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ }
+
+ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+ @Test
+ public static void engineOverwriteTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = new SimpleBindings();
+ b.put("engine", "hello");
+ b.put("foo", 32);
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ e.setContext(newCtxt);
+ assertEquals(e.eval("engine"), "hello");
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ }
+
+ // @bug 8058422: Users should be able to overwrite "context" and "engine" variables
+ @Test
+ public static void engineOverwriteInScriptTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ e.put("foo", 32);
+
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ assertEquals(e.eval("engine = 'bar'"), "bar");
+ assertEquals(((Number)e.eval("foo")).intValue(), 32);
+ }
+
// @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook
@Test
public static void testMegamorphicGetInGlobal() throws Exception {