diff --git a/nashorn/make/BuildNashorn.gmk b/nashorn/make/BuildNashorn.gmk
index fc87044245b..a987874c7ea 100644
--- a/nashorn/make/BuildNashorn.gmk
+++ b/nashorn/make/BuildNashorn.gmk
@@ -77,7 +77,7 @@ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN)
$(RM) -rf $(@D)/jdk $(@D)/netscape
$(CP) -R -p $(NASHORN_OUTPUTDIR)/nashorn_classes/* $(@D)/
$(FIXPATH) $(JAVA) \
- -cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
+ -Xbootclasspath/p:"$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \
jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D)
$(TOUCH) $@
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index 78a713bfc46..74eae86a588 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -125,6 +125,7 @@
+
@@ -243,6 +244,7 @@
+
@@ -253,6 +255,10 @@
+
+
+
+
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index d51e72e4180..5af728794e2 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -206,7 +206,7 @@ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests
# test262 test frameworks
test262-test-sys-prop.test.js.framework=\
- --class-cache-size=0 \
+ --class-cache-size=10 \
--no-java \
--no-typed-arrays \
-timezone=PST \
diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
index 3c4d29fc025..9c14359ec4e 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java
@@ -57,9 +57,9 @@ import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
-import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -99,7 +99,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
private final boolean _global_per_engine;
// This is the initial default Nashorn global object.
// This is used as "shared" global if above option is true.
- private final ScriptObject global;
+ private final Global global;
// initialized bit late to be made 'final'.
// Property object for "context" property of global object.
private volatile Property contextProperty;
@@ -264,7 +264,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
public Object __noSuchProperty__(final Object self, final ScriptContext ctxt, final String name) {
if (ctxt != null) {
final int scope = ctxt.getAttributesScope(name);
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(ctxt);
+ final Global ctxtGlobal = getNashornGlobalFrom(ctxt);
if (scope != -1) {
return ScriptObjectMirror.unwrap(ctxt.getAttribute(name, scope), ctxtGlobal);
}
@@ -317,7 +317,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
ScriptObject realSelf = null;
- ScriptObject realGlobal = null;
+ Global realGlobal = null;
if(thiz == null) {
// making interface out of global functions
realSelf = realGlobal = getNashornGlobalFrom(context);
@@ -346,7 +346,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
try {
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != realGlobal);
try {
if (globalChanged) {
@@ -371,7 +371,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
// Retrieve nashorn Global object for a given ScriptContext object
- private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) {
+ private Global getNashornGlobalFrom(final ScriptContext ctxt) {
if (_global_per_engine) {
// shared single global object for all ENGINE_SCOPE Bindings
return global;
@@ -380,18 +380,18 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE);
// is this Nashorn's own Bindings implementation?
if (bindings instanceof ScriptObjectMirror) {
- final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)bindings);
- if (sobj != null) {
- return sobj;
+ final Global glob = globalFromMirror((ScriptObjectMirror)bindings);
+ if (glob != null) {
+ return glob;
}
}
// Arbitrary user Bindings implementation. Look for NASHORN_GLOBAL in it!
Object scope = bindings.get(NASHORN_GLOBAL);
if (scope instanceof ScriptObjectMirror) {
- final ScriptObject sobj = globalFromMirror((ScriptObjectMirror)scope);
- if (sobj != null) {
- return sobj;
+ final Global glob = globalFromMirror((ScriptObjectMirror)scope);
+ if (glob != null) {
+ return glob;
}
}
@@ -399,14 +399,14 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// Create new global instance mirror and associate with the Bindings.
final ScriptObjectMirror mirror = createGlobalMirror(ctxt);
bindings.put(NASHORN_GLOBAL, mirror);
- return mirror.getScriptObject();
+ return mirror.getHomeGlobal();
}
// Retrieve nashorn Global object from a given ScriptObjectMirror
- private ScriptObject globalFromMirror(final ScriptObjectMirror mirror) {
+ private Global globalFromMirror(final ScriptObjectMirror mirror) {
ScriptObject sobj = mirror.getScriptObject();
- if (sobj instanceof GlobalObject && isOfContext(sobj, nashornContext)) {
- return sobj;
+ if (sobj instanceof Global && isOfContext((Global)sobj, nashornContext)) {
+ return (Global)sobj;
}
return null;
@@ -414,15 +414,15 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
// Create a new ScriptObjectMirror wrapping a newly created Nashorn Global object
private ScriptObjectMirror createGlobalMirror(final ScriptContext ctxt) {
- final ScriptObject newGlobal = createNashornGlobal(ctxt);
+ final Global newGlobal = createNashornGlobal(ctxt);
return new ScriptObjectMirror(newGlobal, newGlobal);
}
// Create a new Nashorn Global object
- private ScriptObject createNashornGlobal(final ScriptContext ctxt) {
- final ScriptObject newGlobal = AccessController.doPrivileged(new PrivilegedAction() {
+ private Global createNashornGlobal(final ScriptContext ctxt) {
+ final Global newGlobal = AccessController.doPrivileged(new PrivilegedAction() {
@Override
- public ScriptObject run() {
+ public Global run() {
try {
return nashornContext.newGlobal();
} catch (final RuntimeException e) {
@@ -460,7 +460,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
// scripts should see "context" and "engine" as variables in the given global object
- private void setContextVariables(final ScriptObject ctxtGlobal, final ScriptContext ctxt) {
+ private void setContextVariables(final Global ctxtGlobal, final ScriptContext ctxt) {
// set "context" global variable via contextProperty - because this
// property is non-writable
contextProperty.setObjectValue(ctxtGlobal, ctxtGlobal, ctxt, false);
@@ -470,7 +470,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
// if no arguments passed, expose it
if (! (args instanceof ScriptObject)) {
- args = ((GlobalObject)ctxtGlobal).wrapAsObject(args);
+ args = ctxtGlobal.wrapAsObject(args);
ctxtGlobal.set("arguments", args, false);
}
}
@@ -478,7 +478,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
name.getClass(); // null check
- ScriptObject invokeGlobal = null;
+ Global invokeGlobal = null;
ScriptObjectMirror selfMirror = null;
if (selfObject instanceof ScriptObjectMirror) {
selfMirror = (ScriptObjectMirror)selfObject;
@@ -489,7 +489,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
} else if (selfObject instanceof ScriptObject) {
// invokeMethod called from script code - in which case we may get 'naked' ScriptObject
// Wrap it with oldGlobal to make a ScriptObjectMirror for the same.
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
invokeGlobal = oldGlobal;
if (oldGlobal == null) {
throw new IllegalArgumentException(getMessage("no.current.nashorn.global"));
@@ -502,7 +502,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(selfObject, oldGlobal);
} else if (selfObject == null) {
// selfObject is null => global function call
- final ScriptObject ctxtGlobal = getNashornGlobalFrom(context);
+ final Global ctxtGlobal = getNashornGlobalFrom(context);
invokeGlobal = ctxtGlobal;
selfMirror = (ScriptObjectMirror)ScriptObjectMirror.wrap(ctxtGlobal, ctxtGlobal);
}
@@ -532,11 +532,11 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
- private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final ScriptObject ctxtGlobal) throws ScriptException {
+ private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
if (globalChanged) {
@@ -558,7 +558,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}
- private static void throwAsScriptException(final Exception e, final ScriptObject global) throws ScriptException {
+ private static void throwAsScriptException(final Exception e, final Global global) throws ScriptException {
if (e instanceof ScriptException) {
throw (ScriptException)e;
} else if (e instanceof NashornException) {
@@ -582,7 +582,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return new CompiledScript() {
@Override
public Object eval(final ScriptContext ctxt) throws ScriptException {
- final ScriptObject globalObject = getNashornGlobalFrom(ctxt);
+ final Global globalObject = getNashornGlobalFrom(ctxt);
// Are we running the script in the correct global?
if (func.getScope() == globalObject) {
return evalImpl(func, ctxt, globalObject);
@@ -602,8 +602,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return compileImpl(source, getNashornGlobalFrom(ctxt));
}
- private ScriptFunction compileImpl(final Source source, final ScriptObject newGlobal) throws ScriptException {
- final ScriptObject oldGlobal = Context.getGlobal();
+ private ScriptFunction compileImpl(final Source source, final Global newGlobal) throws ScriptException {
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != newGlobal);
try {
if (globalChanged) {
@@ -641,8 +641,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return true;
}
- private static boolean isOfContext(final ScriptObject global, final Context context) {
- assert global instanceof GlobalObject: "Not a Global object";
- return ((GlobalObject)global).isOfContext(context);
+ private static boolean isOfContext(final Global global, final Context context) {
+ return global.isOfContext(context);
}
}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index 7a9792df19c..b12553369d4 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -42,10 +42,10 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import javax.script.Bindings;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -64,7 +64,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
private final ScriptObject sobj;
- private final ScriptObject global;
+ private final Global global;
private final boolean strict;
@Override
@@ -95,7 +95,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override
public Object call(final Object thiz, final Object... args) {
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
@@ -125,7 +125,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override
public Object newObject(final Object... args) {
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
@@ -171,7 +171,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public Object callMember(final String functionName, final Object... args) {
functionName.getClass(); // null check
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
@@ -642,7 +642,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
*/
public static Object wrap(final Object obj, final Object homeGlobal) {
if(obj instanceof ScriptObject) {
- return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
+ return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
}
if(obj instanceof ConsString) {
return obj.toString();
@@ -710,13 +710,13 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
// package-privates below this.
- ScriptObjectMirror(final ScriptObject sobj, final ScriptObject global) {
+ ScriptObjectMirror(final ScriptObject sobj, final Global global) {
assert sobj != null : "ScriptObjectMirror on null!";
- assert global instanceof GlobalObject : "global is not a GlobalObject";
+ assert global != null : "home Global is null";
this.sobj = sobj;
this.global = global;
- this.strict = ((GlobalObject)global).isStrictContext();
+ this.strict = global.isStrictContext();
}
// accessors for script engine
@@ -724,7 +724,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return sobj;
}
- ScriptObject getHomeGlobal() {
+ Global getHomeGlobal() {
return global;
}
@@ -734,7 +734,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
// internals only below this.
private V inGlobal(final Callable callable) {
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
if (globalChanged) {
Context.setGlobal(global);
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
index 177cfef4e4b..61ccb712772 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
@@ -375,10 +375,11 @@ final class Attr extends NodeOperatorVisitor {
* @return Symbol for given name or null for redefinition.
*/
private Symbol defineSymbol(final Block block, final String name, final int symbolFlags) {
- int flags = symbolFlags;
- Symbol symbol = findSymbol(block, name); // Locate symbol.
+ int flags = symbolFlags;
+ Symbol symbol = findSymbol(block, name); // Locate symbol.
+ boolean isGlobal = (flags & KINDMASK) == IS_GLOBAL;
- if ((flags & KINDMASK) == IS_GLOBAL) {
+ if (isGlobal) {
flags |= IS_SCOPE;
}
@@ -414,6 +415,8 @@ final class Attr extends NodeOperatorVisitor {
// Determine where to create it.
if ((flags & Symbol.KINDMASK) == IS_VAR && ((flags & IS_INTERNAL) == IS_INTERNAL || (flags & IS_LET) == IS_LET)) {
symbolBlock = block; //internal vars are always defined in the block closest to them
+ } else if (isGlobal) {
+ symbolBlock = lc.getOutermostFunction().getBody();
} else {
symbolBlock = lc.getFunctionBody(function);
}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 6ad92829bfe..e0ca67a4a92 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -685,7 +685,7 @@ final class CodeGenerator extends NodeOperatorVisitor 0) {
- classCache = new ClassCache(cacheSize);
- }
}
/**
@@ -439,11 +432,9 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
* @return the global singleton
*/
public static Global instance() {
- ScriptObject global = Context.getGlobal();
- if (! (global instanceof Global)) {
- throw new IllegalStateException("no current global instance");
- }
- return (Global)global;
+ Global global = Context.getGlobal();
+ global.getClass(); // null check
+ return global;
}
/**
@@ -464,19 +455,30 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
return instance().getContext();
}
- // GlobalObject interface implementation
+ // Runtime interface to Global
- @Override
+ /**
+ * Is this global of the given Context?
+ * @param ctxt the context
+ * @return true if this global belongs to the given Context
+ */
public boolean isOfContext(final Context ctxt) {
return this.context == ctxt;
}
- @Override
+ /**
+ * Does this global belong to a strict Context?
+ * @return true if this global belongs to a strict Context
+ */
public boolean isStrictContext() {
return context.getEnv()._strict;
}
- @Override
+ /**
+ * Initialize standard builtin objects like "Object", "Array", "Function" etc.
+ * as well as our extension builtin objects like "Java", "JSAdapter" as properties
+ * of the global scope object.
+ */
public void initBuiltinObjects() {
if (this.builtinObject != null) {
// already initialized, just return
@@ -486,12 +488,26 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
init();
}
- @Override
+ /**
+ * Create a new ScriptFunction object
+ *
+ * @param name function name
+ * @param handle invocation handle for function
+ * @param scope the scope
+ * @param strict are we in strict mode
+ *
+ * @return new script function
+ */
public ScriptFunction newScriptFunction(final String name, final MethodHandle handle, final ScriptObject scope, final boolean strict) {
- return new ScriptFunctionImpl(name, handle, scope, null, strict, false, true);
+ return new ScriptFunctionImpl(name, handle, scope, null, strict ? ScriptFunctionData.IS_STRICT_CONSTRUCTOR : ScriptFunctionData.IS_CONSTRUCTOR);
}
- @Override
+ /**
+ * Wrap a Java object as corresponding script object
+ *
+ * @param obj object to wrap
+ * @return wrapped object
+ */
public Object wrapAsObject(final Object obj) {
if (obj instanceof Boolean) {
return new NativeBoolean((Boolean)obj, this);
@@ -513,7 +529,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
}
}
- @Override
+ /**
+ * Lookup helper for JS primitive types
+ *
+ * @param request the link request for the dynamic call site.
+ * @param self self reference
+ *
+ * @return guarded invocation
+ */
public GuardedInvocation primitiveLookup(final LinkRequest request, final Object self) {
if (self instanceof String || self instanceof ConsString) {
return NativeString.lookupPrimitive(request, self);
@@ -525,12 +548,23 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
throw new IllegalArgumentException("Unsupported primitive: " + self);
}
- @Override
+ /**
+ * Create a new empty script object
+ *
+ * @return the new ScriptObject
+ */
public ScriptObject newObject() {
return new JO(getObjectPrototype(), JO.getInitialMap());
}
- @Override
+ /**
+ * Default value of given type
+ *
+ * @param sobj script object
+ * @param typeHint type hint
+ *
+ * @return default value
+ */
public Object getDefaultValue(final ScriptObject sobj, final Class> typeHint) {
// When the [[DefaultValue]] internal method of O is called with no hint,
// then it behaves as if the hint were Number, unless O is a Date object
@@ -590,7 +624,12 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
return UNDEFINED;
}
- @Override
+ /**
+ * Is the given ScriptObject an ECMAScript Error object?
+ *
+ * @param sobj the object being checked
+ * @return true if sobj is an Error object
+ */
public boolean isError(final ScriptObject sobj) {
final ScriptObject errorProto = getErrorPrototype();
ScriptObject proto = sobj.getProto();
@@ -603,52 +642,108 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
return false;
}
- @Override
+ /**
+ * Create a new ECMAScript Error object.
+ *
+ * @param msg error message
+ * @return newly created Error object
+ */
public ScriptObject newError(final String msg) {
return new NativeError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript EvalError object.
+ *
+ * @param msg error message
+ * @return newly created EvalError object
+ */
public ScriptObject newEvalError(final String msg) {
return new NativeEvalError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript RangeError object.
+ *
+ * @param msg error message
+ * @return newly created RangeError object
+ */
public ScriptObject newRangeError(final String msg) {
return new NativeRangeError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript ReferenceError object.
+ *
+ * @param msg error message
+ * @return newly created ReferenceError object
+ */
public ScriptObject newReferenceError(final String msg) {
return new NativeReferenceError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript SyntaxError object.
+ *
+ * @param msg error message
+ * @return newly created SyntaxError object
+ */
public ScriptObject newSyntaxError(final String msg) {
return new NativeSyntaxError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript TypeError object.
+ *
+ * @param msg error message
+ * @return newly created TypeError object
+ */
public ScriptObject newTypeError(final String msg) {
return new NativeTypeError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript URIError object.
+ *
+ * @param msg error message
+ * @return newly created URIError object
+ */
public ScriptObject newURIError(final String msg) {
return new NativeURIError(msg, this);
}
- @Override
+ /**
+ * Create a new ECMAScript GenericDescriptor object.
+ *
+ * @param configurable is the property configurable?
+ * @param enumerable is the property enumerable?
+ * @return newly created GenericDescriptor object
+ */
public PropertyDescriptor newGenericDescriptor(final boolean configurable, final boolean enumerable) {
return new GenericPropertyDescriptor(configurable, enumerable, this);
}
- @Override
+ /**
+ * Create a new ECMAScript DatePropertyDescriptor object.
+ *
+ * @param value of the data property
+ * @param configurable is the property configurable?
+ * @param enumerable is the property enumerable?
+ * @return newly created DataPropertyDescriptor object
+ */
public PropertyDescriptor newDataDescriptor(final Object value, final boolean configurable, final boolean enumerable, final boolean writable) {
return new DataPropertyDescriptor(configurable, enumerable, writable, value, this);
}
- @Override
+ /**
+ * Create a new ECMAScript AccessorPropertyDescriptor object.
+ *
+ * @param get getter function of the user accessor property
+ * @param set setter function of the user accessor property
+ * @param configurable is the property configurable?
+ * @param enumerable is the property enumerable?
+ * @return newly created AccessorPropertyDescriptor object
+ */
public PropertyDescriptor newAccessorDescriptor(final Object get, final Object set, final boolean configurable, final boolean enumerable) {
final AccessorPropertyDescriptor desc = new AccessorPropertyDescriptor(configurable, enumerable, get == null ? UNDEFINED : get, set == null ? UNDEFINED : set, this);
@@ -664,62 +759,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
}
- /**
- * Cache for compiled script classes.
- */
- @SuppressWarnings("serial")
- private static class ClassCache extends LinkedHashMap
* You normally don't use this class directly, but rather either create adapters from script using
- * {@link NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
- * {@link NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
+ * {@link jdk.nashorn.internal.objects.NativeJava#extend(Object, Object...)}, using the {@code new} operator on abstract classes and interfaces (see
+ * {@link jdk.nashorn.internal.objects.NativeJava#type(Object, Object)}), or implicitly when passing script functions to Java methods expecting SAM
* types.
*
*/
@@ -337,6 +336,7 @@ public final class JavaAdapterFactory {
private static ProtectionDomain createMinimalPermissionDomain() {
// Generated classes need to have at least the permission to access Nashorn runtime and runtime.linker packages.
final Permissions permissions = new Permissions();
+ permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.objects"));
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime"));
permissions.add(new RuntimePermission("accessClassInPackage.jdk.nashorn.internal.runtime.linker"));
return new ProtectionDomain(new CodeSource(null, (CodeSigner[])null), permissions);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
index 0b720be2740..ca3e10c48d4 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java
@@ -29,6 +29,11 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
+import java.lang.ref.WeakReference;
+import jdk.internal.dynalink.CallSiteDescriptor;
+import jdk.nashorn.internal.codegen.ObjectClassGenerator;
+import jdk.nashorn.internal.objects.Global;
+import jdk.nashorn.internal.runtime.Property;
import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -40,6 +45,7 @@ public final class NashornGuards {
private static final MethodHandle IS_SCRIPTOBJECT = findOwnMH("isScriptObject", boolean.class, Object.class);
private static final MethodHandle IS_SCRIPTFUNCTION = findOwnMH("isScriptFunction", boolean.class, Object.class);
private static final MethodHandle IS_MAP = findOwnMH("isMap", boolean.class, Object.class, PropertyMap.class);
+ private static final MethodHandle SAME_OBJECT = findOwnMH("sameObject", boolean.class, Object.class, WeakReference.class);
private static final MethodHandle IS_INSTANCEOF_2 = findOwnMH("isInstanceOf2", boolean.class, Object.class, Class.class, Class.class);
// don't create me!
@@ -74,6 +80,55 @@ public final class NashornGuards {
return MH.insertArguments(IS_MAP, 1, map);
}
+ /**
+ * Determine whether the given callsite needs a guard.
+ * @param property the property, or null
+ * @param desc the callsite descriptor
+ * @return true if a guard should be used for this callsite
+ */
+ static boolean needsGuard(final Property property, final CallSiteDescriptor desc) {
+ return property == null || property.isConfigurable()
+ || property.isBound() || !ObjectClassGenerator.OBJECT_FIELDS_ONLY
+ || !NashornCallSiteDescriptor.isFastScope(desc) || property.canChangeType();
+ }
+
+ /**
+ * Get the guard for a property access. This returns an identity guard for non-configurable global properties
+ * and a map guard for everything else.
+ *
+ * @param sobj the first object in the prototype chain
+ * @param property the property
+ * @param desc the callsite descriptor
+ * @return method handle for guard
+ */
+ public static MethodHandle getGuard(final ScriptObject sobj, final Property property, final CallSiteDescriptor desc) {
+ if (!needsGuard(property, desc)) {
+ return null;
+ }
+ if (NashornCallSiteDescriptor.isScope(desc)) {
+ if (property != null && property.isBound()) {
+ // This is a declared top level variables in main script or eval, use identity guard.
+ return getIdentityGuard(sobj);
+ }
+ if (!(sobj instanceof Global) && (property == null || property.isConfigurable())) {
+ // Undeclared variables in nested evals need stronger guards
+ return combineGuards(getIdentityGuard(sobj), getMapGuard(sobj.getMap()));
+ }
+ }
+ return getMapGuard(sobj.getMap());
+ }
+
+
+ /**
+ * Get a guard that checks referential identity of the current object.
+ *
+ * @param sobj the self object
+ * @return true if same self object instance
+ */
+ public static MethodHandle getIdentityGuard(final ScriptObject sobj) {
+ return MH.insertArguments(SAME_OBJECT, 1, new WeakReference<>(sobj));
+ }
+
/**
* Get a guard that checks if in item is an instance of either of two classes.
*
@@ -111,6 +166,11 @@ public final class NashornGuards {
return self instanceof ScriptObject && ((ScriptObject)self).getMap() == map;
}
+ @SuppressWarnings("unused")
+ private static boolean sameObject(final Object self, final WeakReference ref) {
+ return self == ref.get();
+ }
+
@SuppressWarnings("unused")
private static boolean isInstanceOf2(final Object self, final Class> class1, final Class> class2) {
return class1.isInstance(self) || class2.isInstance(self);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java
index 5cc1cd2c632..22135bc15bc 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornPrimitiveLinker.java
@@ -37,9 +37,9 @@ import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.TypeUtilities;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
-import jdk.nashorn.internal.runtime.GlobalObject;
/**
* Internal linker for String, Boolean, and Number objects, only ever used by Nashorn engine and not exposed to other
@@ -62,7 +62,7 @@ final class NashornPrimitiveLinker implements TypeBasedGuardingDynamicLinker, Gu
final LinkRequest request = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
final Object self = request.getReceiver();
- final GlobalObject global = (GlobalObject) Context.getGlobal();
+ final Global global = Context.getGlobal();
final NashornCallSiteDescriptor desc = (NashornCallSiteDescriptor) request.getCallSiteDescriptor();
return Bootstrap.asType(global.primitiveLookup(request, self), linkerServices, desc);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
index c9b5eaa3fa9..7665be7fcb3 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/PrimitiveLookup.java
@@ -35,6 +35,7 @@ import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.internal.dynalink.support.Guards;
import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.FindProperty;
import jdk.nashorn.internal.runtime.ScriptObject;
/**
@@ -61,8 +62,9 @@ public final class PrimitiveLookup {
* type {@code receiverClass}.
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final Class> receiverClass,
- final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
- return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter);
+ final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+ final MethodHandle protoFilter) {
+ return lookupPrimitive(request, Guards.getInstanceOfGuard(receiverClass), wrappedReceiver, wrapFilter, protoFilter);
}
/**
@@ -79,7 +81,8 @@ public final class PrimitiveLookup {
* type (that is implied by both {@code guard} and {@code wrappedReceiver}).
*/
public static GuardedInvocation lookupPrimitive(final LinkRequest request, final MethodHandle guard,
- final ScriptObject wrappedReceiver, final MethodHandle wrapFilter) {
+ final ScriptObject wrappedReceiver, final MethodHandle wrapFilter,
+ final MethodHandle protoFilter) {
final CallSiteDescriptor desc = request.getCallSiteDescriptor();
final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0);
if ("setProp".equals(operator) || "setElem".equals(operator)) {
@@ -93,9 +96,23 @@ public final class PrimitiveLookup {
if(desc.getNameTokenCount() > 2) {
final String name = desc.getNameToken(CallSiteDescriptor.NAME_OPERAND);
- if(wrappedReceiver.findProperty(name, true) == null) {
+ final FindProperty find = wrappedReceiver.findProperty(name, true);
+ if(find == null) {
// Give up early, give chance to BeanLinker and NashornBottomLinker to deal with it.
return null;
+ } else if (find.isInherited() && !find.getProperty().hasGetterFunction(find.getOwner())) {
+ // If property is found in the prototype object bind the method handle directly to
+ // the proto filter instead of going through wrapper instantiation below.
+ final ScriptObject proto = wrappedReceiver.getProto();
+ final GuardedInvocation link = proto.lookup(desc, request);
+
+ if (link != null) {
+ final MethodHandle invocation = link.getInvocation();
+ final MethodHandle adaptedInvocation = MH.asType(invocation, invocation.type().changeParameterType(0, Object.class));
+ final MethodHandle method = MH.filterArguments(adaptedInvocation, 0, protoFilter);
+ final MethodHandle protoGuard = MH.filterArguments(link.getGuard(), 0, protoFilter);
+ return new GuardedInvocation(method, NashornGuards.combineGuards(guard, protoGuard));
+ }
}
}
final GuardedInvocation link = wrappedReceiver.lookup(desc, request);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index e1c4d1f1f8a..47248fce715 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -79,6 +79,7 @@ type.error.not.a.function={0} is not a function
type.error.not.a.constructor={0} is not a constructor function
type.error.not.a.file={0} is not a File
type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
+type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
# operations not permitted on undefined
type.error.cant.call.undefined=Cannot call undefined
@@ -137,6 +138,9 @@ type.error.no.method.matches.args=Can not invoke method {0} with the passed argu
type.error.method.not.constructor=Java method {0} can't 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}.
+
+range.error.dataview.constructor.offset=Wrong offset or length in DataView constructor
+range.error.dataview.offset=Offset is outside the bounds of the DataView
range.error.inappropriate.array.length=inappropriate array length: {0}
range.error.inappropriate.array.buffer.length=inappropriate array buffer length: {0}
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java
index ad19484ceb8..ad833d8171b 100644
--- a/nashorn/src/jdk/nashorn/tools/Shell.java
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java
@@ -42,6 +42,7 @@ import jdk.nashorn.internal.codegen.Compiler;
import jdk.nashorn.internal.ir.FunctionNode;
import jdk.nashorn.internal.ir.debug.ASTWriter;
import jdk.nashorn.internal.ir.debug.PrintVisitor;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.parser.Parser;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
@@ -148,7 +149,7 @@ public class Shell {
return COMMANDLINE_ERROR;
}
- final ScriptObject global = context.createGlobal();
+ final Global global = context.createGlobal();
final ScriptEnvironment env = context.getEnv();
final List files = env.getFiles();
if (files.isEmpty()) {
@@ -231,8 +232,8 @@ public class Shell {
* @return error code
* @throws IOException when any script file read results in I/O error
*/
- private static int compileScripts(final Context context, final ScriptObject global, final List files) throws IOException {
- final ScriptObject oldGlobal = Context.getGlobal();
+ private static int compileScripts(final Context context, final Global global, final List files) throws IOException {
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
final ScriptEnvironment env = context.getEnv();
try {
@@ -281,8 +282,8 @@ public class Shell {
* @return error code
* @throws IOException when any script file read results in I/O error
*/
- private int runScripts(final Context context, final ScriptObject global, final List files) throws IOException {
- final ScriptObject oldGlobal = Context.getGlobal();
+ private int runScripts(final Context context, final Global global, final List files) throws IOException {
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
if (globalChanged) {
@@ -339,8 +340,8 @@ public class Shell {
* @return error code
* @throws IOException when any script file read results in I/O error
*/
- private static int runFXScripts(final Context context, final ScriptObject global, final List files) throws IOException {
- final ScriptObject oldGlobal = Context.getGlobal();
+ private static int runFXScripts(final Context context, final Global global, final List files) throws IOException {
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
if (globalChanged) {
@@ -389,11 +390,11 @@ public class Shell {
* @return return code
*/
@SuppressWarnings("resource")
- private static int readEvalPrint(final Context context, final ScriptObject global) {
+ private static int readEvalPrint(final Context context, final Global global) {
final String prompt = bundle.getString("shell.prompt");
final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
final PrintWriter err = context.getErr();
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
final ScriptEnvironment env = context.getEnv();
diff --git a/nashorn/test/script/basic/JDK-8034055.js b/nashorn/test/script/basic/JDK-8034055.js
new file mode 100644
index 00000000000..0a21d9f915a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8034055.js
@@ -0,0 +1,55 @@
+/*
+ * 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-8034055: delete on global object not properly guarded
+ *
+ * @test
+ * @run
+ */
+
+
+var global = this;
+var x;
+
+function test(defineGlobals) {
+ if (defineGlobals) {
+ global.x = 1;
+ global.y = 2;
+ }
+ try {
+ print(x);
+ print(y);
+ } catch (e) {
+ print(e);
+ } finally {
+ print(delete global.x);
+ print(delete global.y);
+ }
+}
+
+// Repeatedly set and delete global variables
+test(true);
+test(false);
+test(true);
+test(false);
diff --git a/nashorn/test/script/basic/JDK-8034055.js.EXPECTED b/nashorn/test/script/basic/JDK-8034055.js.EXPECTED
new file mode 100644
index 00000000000..c947f4aeb23
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8034055.js.EXPECTED
@@ -0,0 +1,16 @@
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
+1
+2
+false
+true
+1
+ReferenceError: "y" is not defined
+false
+true
diff --git a/nashorn/test/script/basic/dataview_endian.js b/nashorn/test/script/basic/dataview_endian.js
new file mode 100644
index 00000000000..f7607c0ee05
--- /dev/null
+++ b/nashorn/test/script/basic/dataview_endian.js
@@ -0,0 +1,70 @@
+/*
+ * 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-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// set/get endianess checks
+
+var buffer = new ArrayBuffer(4);
+var dv = new DataView(buffer);
+
+// write (default) big endian, read big/little endian
+dv.setUint16(0, 0xABCD);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write little endian, read big/little endian
+dv.setUint16(0, 0xABCD, true);
+Assert.assertEquals(dv.getUint16(0), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, false), 0xCDAB);
+Assert.assertEquals(dv.getUint16(0, true), 0xABCD);
+
+// write explicit big endian, read big/little endian
+dv.setUint16(0, 0xABCD, false);
+Assert.assertEquals(dv.getUint16(0), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, false), 0xABCD);
+Assert.assertEquals(dv.getUint16(0, true), 0xCDAB);
+
+// write (default) big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
+
+// write little endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, true);
+Assert.assertEquals(dv.getUint32(0), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, false), 0x89EFCDAB);
+Assert.assertEquals(dv.getUint32(0, true), 0xABCDEF89);
+
+// write explicit big endian, read big/little endian
+dv.setUint32(0, 0xABCDEF89, false);
+Assert.assertEquals(dv.getUint32(0), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, false), 0xABCDEF89);
+Assert.assertEquals(dv.getUint32(0, true), 0x89EFCDAB);
diff --git a/nashorn/test/script/basic/dataview_getset.js b/nashorn/test/script/basic/dataview_getset.js
new file mode 100644
index 00000000000..8c7a994c1d0
--- /dev/null
+++ b/nashorn/test/script/basic/dataview_getset.js
@@ -0,0 +1,93 @@
+/*
+ * 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-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// checking get/set of values of various types
+// Also basic endianess check.
+
+var Float = Java.type("java.lang.Float");
+var Double = Java.type("java.lang.Double");
+
+var DOUBLE_MIN = Double.MIN_VALUE;
+var DOUBLE_MIN_NORMAL = Double.MIN_NORMAL;
+var FLOAT_MIN = Float.MIN_VALUE;
+var FLOAT_MIN_NORMAL = Float.MIN_NORMAL;
+
+var buffer = new ArrayBuffer(12);
+var dv = new DataView(buffer);
+
+dv.setInt8(1, 123);
+Assert.assertEquals(dv.getInt8(1), 123);
+dv.setInt8(1, 123, true);
+Assert.assertEquals(dv.getInt8(1, true), 123);
+
+dv.setUint8(1, 255);
+Assert.assertEquals(dv.getUint8(1), 255);
+dv.setUint8(1, 255, true);
+Assert.assertEquals(dv.getUint8(1, true), 255);
+
+dv.setInt16(1, 1234);
+Assert.assertEquals(dv.getInt16(1), 1234);
+dv.setInt16(1, 1234, true);
+Assert.assertEquals(dv.getInt16(1, true), 1234);
+
+dv.setUint16(1, 65535);
+Assert.assertEquals(dv.getUint16(1), 65535);
+dv.setUint16(1, 65535, true);
+Assert.assertEquals(dv.getUint16(1, true), 65535);
+
+dv.setInt32(1, 1234);
+Assert.assertEquals(dv.getInt32(1), 1234);
+dv.setInt32(1, 1234, true);
+Assert.assertEquals(dv.getInt32(1, true), 1234);
+
+dv.setUint32(1, 4294967295);
+Assert.assertEquals(dv.getUint32(1), 4294967295);
+dv.setUint32(1, 4294967295, true);
+Assert.assertEquals(dv.getUint32(1, true), 4294967295);
+
+dv.setFloat64(1, Math.PI);
+Assert.assertEquals(dv.getFloat64(1), Math.PI, DOUBLE_MIN);
+dv.setFloat64(1, Math.PI, true);
+Assert.assertEquals(dv.getFloat64(1, true), Math.PI, DOUBLE_MIN);
+
+dv.setFloat64(1, DOUBLE_MIN_NORMAL);
+Assert.assertEquals(dv.getFloat64(1), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+dv.setFloat64(1, DOUBLE_MIN_NORMAL, true);
+Assert.assertEquals(dv.getFloat64(1, true), DOUBLE_MIN_NORMAL, DOUBLE_MIN);
+
+dv.setFloat32(1, 1.414);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), 1.414, FLOAT_MIN);
+dv.setFloat32(1, 1.414, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), 1.414, FLOAT_MIN);
+
+dv.setFloat32(1, FLOAT_MIN_NORMAL);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1), FLOAT_MIN_NORMAL, FLOAT_MIN);
+dv.setFloat32(1, FLOAT_MIN_NORMAL, true);
+Assert["assertEquals(float, float, float)"](dv.getFloat32(1, true), FLOAT_MIN_NORMAL, FLOAT_MIN);
diff --git a/nashorn/test/script/basic/dataview_new.js b/nashorn/test/script/basic/dataview_new.js
new file mode 100644
index 00000000000..78f8183d52a
--- /dev/null
+++ b/nashorn/test/script/basic/dataview_new.js
@@ -0,0 +1,71 @@
+/*
+ * 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-8015958: DataView constructor is not defined
+ *
+ * @test
+ * @run
+ */
+
+// basic DataView constructor checks.
+
+// check ArrayBufferView property values of DataView instance
+function check(dv, buf, offset, length) {
+ if (dv.buffer !== buf) {
+ fail("DataView.buffer is wrong");
+ }
+
+ if (dv.byteOffset != offset) {
+ fail("DataView.byteOffset = " + dv.byteOffset + ", expected " + offset);
+ }
+
+ if (dv.byteLength != length) {
+ fail("DataView.byteLength = " + dv.byteLength + ", expected " + length);
+ }
+}
+
+var buffer = new ArrayBuffer(12);
+check(new DataView(buffer), buffer, 0, 12);
+check(new DataView(buffer, 2), buffer, 2, 10);
+check(new DataView(buffer, 4, 8), buffer, 4, 8);
+
+// make sure expected error is thrown
+function checkError(callback, ErrorType) {
+ try {
+ callback();
+ fail("Should have thrown " + ErrorType.name);
+ } catch (e) {
+ if (! (e instanceof ErrorType)) {
+ fail("Expected " + ErrorType.name + " got " + e);
+ }
+ }
+}
+
+// non ArrayBuffer as first arg
+checkError(function() { new DataView(344) }, TypeError);
+
+// illegal offset/length values
+checkError(function() { new DataView(buffer, -1) }, RangeError);
+checkError(function() { new DataView(buffer, 15) }, RangeError);
+checkError(function() { new DataView(buffer, 1, 32) }, RangeError);
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java
index a18055bb602..dc27d826402 100644
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScopeTest.java
@@ -245,4 +245,320 @@ public class ScopeTest {
sb.put("x", "newX");
assertTrue(e.eval("x", ctx).equals("newX"));
}
+
+ /**
+ * Test multi-threaded access to defined global variables for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedVarTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "foo";
+
+ assertEquals(e.eval("var foo = 'original context';", origContext), null);
+ assertEquals(e.eval("var foo = 'new context';", newCtxt), null);
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval("var foo = 'newer context';", newCtxt), null);
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ assertEquals(e.eval(sharedScript), "original context");
+ assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded access to undefined global variables for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ assertEquals(e.eval("foo = 'original context';", origContext), "original context");
+ assertEquals(e.eval("foo = 'new context';", newCtxt), "new context");
+ final String sharedScript = "foo";
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ Assert.assertEquals(e.eval(sharedScript), "original context");
+ Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedIncTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ assertEquals(e.eval("var x = 0;", origContext), null);
+ assertEquals(e.eval("var x = 2;", newCtxt), null);
+ final String sharedScript = "x++;";
+
+ final Thread t1 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, origContext), (double)i);
+ }
+ } catch (ScriptException se) {
+ fail(se.toString());
+ }
+ }
+ });
+ final Thread t2 = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ for (int i = 2; i < 1000; i++) {
+ assertEquals(e.eval(sharedScript, newCtxt), (double)i);
+ }
+ } catch (ScriptException se) {
+ fail(se.toString());
+ }
+ }
+ });
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+ }
+
+ /**
+ * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext);
+ Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt);
+ assertEquals(obj1, "original context");
+ assertEquals(obj2, "new context");
+ final String sharedScript = "''.foo";
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000));
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt);
+ assertEquals(obj3, "newer context");
+ final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000));
+ final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000));
+
+ t3.start();
+ t4.start();
+ t3.join();
+ t4.join();
+
+ Assert.assertEquals(e.eval(sharedScript), "original context");
+ Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context");
+ }
+
+ /**
+ * Test multi-threaded scope function invocation for shared script classes with multiple globals.
+ */
+ @Test
+ public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext);
+ assertEquals(origContext.getAttribute("scopeVar"), 1);
+ assertEquals(e.eval("scopeTest()"), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt);
+ assertEquals(newCtxt.getAttribute("scopeVar"), 1);
+ assertEquals(e.eval("scopeTest();", newCtxt), 1);
+
+ assertEquals(e.eval("scopeVar = 3;", newCtxt), 3);
+ assertEquals(newCtxt.getAttribute("scopeVar"), 3);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ }
+
+ /**
+ * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+ */
+ @Test
+ public static void getterSetterTest() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "accessor1";
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+ assertEquals(e.eval("accessor1 = 1;"), 1);
+ assertEquals(e.eval(sharedScript), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+ assertEquals(e.eval("accessor1 = 2;", newCtxt), 2);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval(sharedScript), 1);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+ assertEquals(e.eval("v"), 1);
+ assertEquals(e.eval("v", newCtxt), 2);
+ }
+
+ /**
+ * Test multi-threaded access to global getters and setters for shared script classes with multiple globals.
+ */
+ @Test
+ public static void getterSetter2Test() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ final Bindings b = e.createBindings();
+ final ScriptContext origContext = e.getContext();
+ final ScriptContext newCtxt = new SimpleScriptContext();
+ newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+ final String sharedScript = "accessor2";
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext);
+ assertEquals(e.eval("accessor2 = 1;"), 1);
+ assertEquals(e.eval(sharedScript), 1);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt);
+ assertEquals(e.eval("accessor2 = 2;", newCtxt), 2);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+
+
+ final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000));
+ final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000));
+
+ t1.start();
+ t2.start();
+ t1.join();
+ t2.join();
+
+ assertEquals(e.eval(sharedScript), 1);
+ assertEquals(e.eval(sharedScript, newCtxt), 2);
+ assertEquals(e.eval("x"), 1);
+ assertEquals(e.eval("x", newCtxt), 2);
+ }
+
+ /**
+ * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals.
+ */
+ @Test
+ public static void testSlowScope() throws ScriptException, InterruptedException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+
+ for (int i = 0; i < 100; i++) {
+ final Bindings b = e.createBindings();
+ final ScriptContext ctxt = new SimpleScriptContext();
+ ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE);
+
+ e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt);
+ assertEquals(e.eval("a", ctxt), 1);
+ assertEquals(b.get("a"), 1);
+ assertEquals(e.eval("b", ctxt), 3);
+ assertEquals(b.get("b"), 3);
+ assertEquals(e.eval("c", ctxt), 10);
+ assertEquals(b.get("c"), 10);
+ }
+ }
+
+ private static class ScriptRunner implements Runnable {
+
+ final ScriptEngine engine;
+ final ScriptContext context;
+ final String source;
+ final Object expected;
+ final int iterations;
+
+ ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) {
+ this.engine = engine;
+ this.context = context;
+ this.source = source;
+ this.expected = expected;
+ this.iterations = iterations;
+ }
+
+ @Override
+ public void run() {
+ try {
+ for (int i = 0; i < iterations; i++) {
+ assertEquals(engine.eval(source, context), expected);
+ }
+ } catch (ScriptException se) {
+ throw new RuntimeException(se);
+ }
+ }
+ }
+
}
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js b/nashorn/test/src/jdk/nashorn/api/scripting/resources/func.js
new file mode 100644
index 00000000000..477bd1a64be
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/func.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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var scopeVar = 1;
+var global = this;
+undefGlobal = this;
+
+function scopeTest() {
+ if (this !== global) {
+ throw new Error("this !== global");
+ }
+ if (this !== undefGlobal) {
+ throw new Error("this !== undefinedGlobal")
+ }
+ return scopeVar;
+}
+
+scopeTest();
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js b/nashorn/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js
new file mode 100644
index 00000000000..51e24727466
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js
@@ -0,0 +1,38 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var v;
+
+Object.defineProperty(this, "accessor1", {
+ get: function() { return v; },
+ set: function(n) { v = n; }
+});
+
+Object.defineProperty(this, "accessor2", {
+ get: function() { return x; },
+ set: function(n) { x = n; }
+});
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/resources/witheval.js b/nashorn/test/src/jdk/nashorn/api/scripting/resources/witheval.js
new file mode 100644
index 00000000000..6041d5b4928
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/resources/witheval.js
@@ -0,0 +1,60 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse.
+
+var a;
+
+function outer(p, e) {
+ eval(e);
+ with(p) {
+ function inner() {
+ a = 1;
+ c = 10;
+ if (a !== 1) {
+ throw new Error("a !== 1");
+ }
+ if (b !== 3) {
+ throw new Error("b !== 3");
+ }
+ if (c !== 10) {
+ throw new Error("c !== 10");
+ }
+ }
+ inner();
+ }
+}
+
+outer({}, "b = 3;");
+
+if (a !== 1) {
+ throw new Error("a !== 1");
+}
+if (b !== 3) {
+ throw new Error("b !== 3");
+}
+if (c !== 10) {
+ throw new Error("c !== 10");
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java
index 00d79acbda9..ac438101e67 100644
--- a/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java
+++ b/nashorn/test/src/jdk/nashorn/internal/codegen/CompilerTest.java
@@ -28,6 +28,7 @@ package jdk.nashorn.internal.codegen;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.ScriptFunction;
@@ -58,7 +59,7 @@ public class CompilerTest {
}
private Context context;
- private ScriptObject global;
+ private Global global;
@BeforeClass
public void setupTest() {
@@ -146,7 +147,7 @@ public class CompilerTest {
log("Begin compiling " + file.getAbsolutePath());
}
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != global);
try {
diff --git a/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java b/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java
index 999f6fa4529..ce969210053 100644
--- a/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java
+++ b/nashorn/test/src/jdk/nashorn/internal/performance/PerformanceWrapper.java
@@ -31,9 +31,9 @@ import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
@@ -89,7 +89,7 @@ public class PerformanceWrapper extends jdk.nashorn.tools.Shell {
@Override
protected Object apply(final ScriptFunction target, final Object self) {
if (_runsPerIteration == 0 && _numberOfIterations == 0) {
- final ScriptObject global = jdk.nashorn.internal.runtime.Context.getGlobal();
+ final Global global = jdk.nashorn.internal.runtime.Context.getGlobal();
final ScriptFunction _target = target;
final Object _self = self;
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
index 1b21c23f404..1ec416951a3 100644
--- a/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/ContextTest.java
@@ -29,6 +29,7 @@ import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Map;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.options.Options;
import org.testng.annotations.Test;
@@ -45,7 +46,7 @@ public class ContextTest {
final Options options = new Options("");
final ErrorManager errors = new ErrorManager();
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
Context.setGlobal(cx.createGlobal());
try {
String code = "22 + 10";
@@ -65,7 +66,7 @@ public class ContextTest {
final ErrorManager errors = new ErrorManager();
final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader());
final boolean strict = cx.getEnv()._strict;
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
Context.setGlobal(cx.createGlobal());
try {
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java
new file mode 100644
index 00000000000..aefa828b470
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java
@@ -0,0 +1,133 @@
+/*
+ * 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+package jdk.nashorn.internal.runtime;
+
+import java.io.ByteArrayOutputStream;
+import java.io.PrintStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import static org.testng.Assert.fail;
+import org.testng.annotations.Test;
+
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineFactory;
+import javax.script.ScriptEngineManager;
+import javax.script.SimpleScriptContext;
+import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
+
+/**
+ * @test
+ * @bug 8037378
+ * @summary Sanity tests for no persistence caching
+ * @run testng/othervm jdk.nashorn.internal.runtime.NoPersistenceCachingTest
+ */
+public class NoPersistenceCachingTest {
+
+ private ScriptEngine engine;
+ private ScriptContext context1, context2, context3;
+ private ByteArrayOutputStream stderr;
+ private PrintStream prevStderr;
+ private final String script = "print('Hello')";
+
+ public void setupTest() {
+ stderr = new ByteArrayOutputStream();
+ prevStderr = System.err;
+ System.setErr(new PrintStream(stderr));
+ NashornScriptEngineFactory nashornFactory = null;
+ ScriptEngineManager sm = new ScriptEngineManager();
+ for (ScriptEngineFactory fac : sm.getEngineFactories()) {
+ if (fac instanceof NashornScriptEngineFactory) {
+ nashornFactory = (NashornScriptEngineFactory) fac;
+ break;
+ }
+ }
+ if (nashornFactory == null) {
+ fail("Cannot find nashorn factory!");
+ }
+ String[] options = new String[]{"--log=compiler:finest"};
+ engine = nashornFactory.getScriptEngine(options);
+ }
+
+ public void setErrTest() {
+ System.setErr(prevStderr);
+ }
+
+ public void runTest(int numberOfContext, String expectedOutputPattern,
+ int expectedPatternOccurrence) {
+ setupTest();
+ try {
+ switch (numberOfContext) {
+ case 2:
+ context1 = engine.getContext();
+ context2 = new SimpleScriptContext();
+ context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+ engine.eval(script, context1);
+ engine.eval(script, context2);
+ break;
+ case 3:
+ context1 = engine.getContext();
+ context2 = new SimpleScriptContext();
+ context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+ context3 = new SimpleScriptContext();
+ context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE);
+ engine.eval(script, context1);
+ engine.eval(script, context2);
+ engine.eval(script, context3);
+ break;
+ }
+ } catch (final Exception se) {
+ se.printStackTrace();
+ fail(se.getMessage());
+ }
+ Pattern deoptimizing = Pattern.compile(expectedOutputPattern);
+ Matcher matcher = deoptimizing.matcher(stderr.toString());
+ int matches = 0;
+ while (matcher.find()) {
+ matches++;
+ }
+ if (matches != expectedPatternOccurrence) {
+ fail("Number of cache hit is not correct, expected: "
+ + expectedPatternOccurrence + " and found: " + matches + "\n"
+ + stderr);
+ }
+ setErrTest();
+ }
+
+ private static String getCodeCachePattern() {
+ return ("\\[compiler\\]\\sCode\\scache\\shit\\sfor\\s\\savoiding\\srecompile.");
+ }
+
+ @Test
+ public void twoContextTest() {
+ runTest(2, getCodeCachePattern(), 1);
+
+ }
+
+ @Test
+ public void threeContextTest() {
+ runTest(3, getCodeCachePattern(), 2);
+ }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
index ac2dc17293c..83d057f327f 100644
--- a/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
+++ b/nashorn/test/src/jdk/nashorn/internal/test/framework/SharedContextEvaluator.java
@@ -34,10 +34,10 @@ import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import jdk.nashorn.api.scripting.NashornException;
+import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ErrorManager;
import jdk.nashorn.internal.runtime.ScriptFunction;
-import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.Source;
import jdk.nashorn.internal.runtime.options.Options;
@@ -110,12 +110,12 @@ public final class SharedContextEvaluator implements ScriptEvaluator {
@Override
public int run(final OutputStream out, final OutputStream err, final String[] args) throws IOException {
- final ScriptObject oldGlobal = Context.getGlobal();
+ final Global oldGlobal = Context.getGlobal();
try {
ctxOut.setDelegatee(out);
ctxErr.setDelegatee(err);
final ErrorManager errors = context.getErrorManager();
- final ScriptObject global = context.createGlobal();
+ final Global global = context.createGlobal();
Context.setGlobal(global);
// For each file on the command line.