This commit is contained in:
Lana Steuck 2015-06-04 18:49:16 -07:00
commit 13a3f9e134
72 changed files with 773 additions and 198 deletions

View File

@ -72,14 +72,11 @@ after which you can view the generated documentation at dist/javadoc/index.html.
- Running tests
Nashorn tests are TestNG based. Running tests requires downloading the
TestNG library and placing its jar file into the lib subdirectory:
TestNG library and placing its jar file into the test/lib subdirectory. This is
done automatically when executing the "ant externals" command to get external
test suites (see below).
# download and install TestNG
wget http://testng.org/testng-x.y.z.zip
unzip testng-x.y.z.zip
cp testng-x.y.z/testng-x.y.z.jar test/lib/testng.jar
After that, you can run the tests using:
Once TestNG is properly installed, you can run the tests using:
cd make
ant clean test

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2010, 2015, 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
@ -396,7 +396,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
</target>
<target name="check-testng" unless="testng.available">
<echo message="WARNING: TestNG not available, will not run tests. Please copy testng.jar under test/lib directory."/>
<echo message="WARNING: TestNG not available, will not run tests. Please copy testng.jar under ${test.lib} directory."/>
</target>
<!-- only to be invoked as dependency of "test" target -->
@ -469,7 +469,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
</testng>
</target>
<target name="test" depends="javadoc, test-pessimistic, test-optimistic"/>
<target name="test" depends="get-testng, javadoc, test-pessimistic, test-optimistic"/>
<target name="test-optimistic" depends="jar, -test-classes-all,-test-classes-single, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<echo message="Running test suite in OPTIMISTIC mode..."/>
@ -499,7 +499,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
<echo message="WARNING: Jemmy or JavaFX or TestNG not available, will not run tests. Please copy testng.jar, JemmyCore.jar, JemmyFX.jar, JemmyAWTInput.jar under test${file.separator}lib directory. And make sure you have jfxrt.jar in ${java.home}${file.separator}lib${file.separator}ext dir."/>
</target>
<target name="testjfx" depends="jar, check-jemmy.jfx.testng, compile-test" if="jemmy.jfx.testng.available">
<target name="testjfx" depends="jar, get-testng, check-jemmy.jfx.testng, compile-test" if="jemmy.jfx.testng.available">
<fileset id="test.classes" dir="${build.test.classes.dir}">
<include name="**/framework/*Test.class"/>
</fileset>
@ -527,7 +527,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
</testng>
</target>
<target name="testmarkdown" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<target name="testmarkdown" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<fileset id="test.classes" dir="${build.test.classes.dir}">
<include name="**/framework/*Test.class"/>
</fileset>
@ -546,7 +546,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
</testng>
</target>
<target name="test262" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<target name="test262" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<fileset id="test.classes" dir="${build.test.classes.dir}">
<include name="**/framework/*Test.class"/>
</fileset>
@ -570,7 +570,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
<target name="test262parallel" depends="test262-parallel"/>
<target name="test262-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<target name="test262-parallel" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<!-- use just build.test.classes.dir to avoid referring to TestNG -->
<java classname="${parallel.test.runner}" dir="${basedir}" fork="true">
<jvmarg line="${boot.class.path}"/>
@ -589,7 +589,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
<target name="testparallel" depends="test-parallel"/>
<target name="test-parallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<target name="test-parallel" depends="jar, get-testng, check-testng, check-external-tests, compile-test, generate-policy-file" if="testng.available">
<!-- use just build.test.classes.dir to avoid referring to TestNG -->
<java classname="${parallel.test.runner}" dir="${basedir}"
failonerror="true"
@ -694,7 +694,7 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
</target>
<!-- get all external test scripts -->
<target name="externals" depends="init, check-external-tests, get-test262, get-octane, get-sunspider">
<target name="externals" depends="init, check-external-tests, get-test262, get-octane, get-sunspider, get-testng">
<!-- make external test dir -->
<mkdir dir="${test.external.dir}"/>
@ -719,8 +719,8 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
<!-- showdown -->
<mkdir dir="${test.external.dir}/showdown"/>
<get src="https://raw.github.com/coreyti/showdown/master/src/showdown.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
<get src="https://raw.github.com/coreyti/showdown/master/src/extensions/table.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
<get src="https://raw.githubusercontent.com/showdownjs/showdown/0.5.4/src/showdown.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
<get src="https://raw.githubusercontent.com/showdownjs/showdown/0.5.4/src/extensions/table.js" dest="${test.external.dir}/showdown" skipexisting="true" ignoreerrors="true"/>
</target>
@ -730,12 +730,20 @@ grant codeBase "file:/${basedir}/test/script/markdown.js" {
<!-- run all perf tests -->
<target name="perf" depends="externals, update-externals, sunspider, octane"/>
<!-- run all tests -->
<target name="exit-if-no-testng" depends="init, check-testng" unless="${testng.available}">
<fail message="Exiting.."/>
<!-- download and install testng.jar -->
<target name="get-testng" depends="prepare" unless="testng.available">
<get src="http://testng.org/testng-6.8.zip" dest="${test.lib}" skipexisting="true" ignoreerrors="true"/>
<unzip src="${test.lib}${file.separator}testng-6.8.zip" dest="${test.lib}">
<patternset>
<include name="testng-6.8/testng-6.8.jar"/>
</patternset>
</unzip>
<move file="${test.lib}${file.separator}testng-6.8${file.separator}testng-6.8.jar" tofile="${test.lib}${file.separator}testng.jar"/>
<delete dir="${test.lib}${file.separator}testng-6.8"/>
</target>
<target name="alltests" depends="exit-if-no-testng, externals, update-externals, test, test262parallel, perf"/>
<!-- run all tests -->
<target name="alltests" depends="get-testng, externals, update-externals, test, test262parallel, testmarkdown, perf"/>
<import file="build-benchmark.xml"/>

View File

@ -1,5 +1,5 @@
#
# Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
# Copyright (c) 2010, 2015, 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
@ -77,8 +77,11 @@ fxshell.jar = ${dist.dir}/nashornfx.jar
# configuration for java flight recorder
run.test.jvmargs.jfr=-XX:+UnlockCommercialFeatures -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,disk=true,dumponexit=true,dumponexitpath=${build.dir},stackdepth=128
# test library location
test.lib=${basedir}${file.separator}test${file.separator}lib
# jars refererred
file.reference.testng.jar=test/lib/testng.jar
file.reference.testng.jar=${test.lib}${file.separator}testng.jar
# Set testng verbose level
# From TestNG docs: "the verbosity level (0 to 10 where 10 is most detailed)
@ -243,9 +246,9 @@ testjfx-test-sys-prop.test.js.framework=\
-fx \
${test.script.dir}${file.separator}jfx.js
file.reference.jemmyfx.jar=test${file.separator}lib${file.separator}JemmyFX.jar
file.reference.jemmycore.jar=test${file.separator}lib${file.separator}JemmyCore.jar
file.reference.jemmyawtinput.jar=test${file.separator}lib${file.separator}JemmyAWTInput.jar
file.reference.jemmyfx.jar=${test.lib}${file.separator}JemmyFX.jar
file.reference.jemmycore.jar=${test.lib}${file.separator}JemmyCore.jar
file.reference.jemmyawtinput.jar=${test.lib}${file.separator}JemmyAWTInput.jar
file.reference.jfxrt.jar=${java.home}${file.separator}lib${file.separator}ext${file.separator}jfxrt.jar
testjfx.run.test.classpath=\
${file.reference.jemmyfx.jar}${path.separator}\

View File

@ -39,6 +39,7 @@
var Class = Java.type("java.lang.Class");
var System = Java.type("java.lang.System");
var Thread = Java.type("java.lang.Thread");
var File = Java.type("java.io.File");
var JarFile = Java.type("java.util.jar.JarFile");
var Modifier = Java.type("java.lang.reflect.Modifier");
@ -58,6 +59,10 @@ function findNashorn() {
function analyzeClass(cls) {
var methods = cls.getDeclaredMethods();
for each (var method in methods) {
var methodModifiers = method.modifiers;
if (Modifier.isAbstract(methodModifiers) || Modifier.isNative(methodModifiers)) {
continue;
}
// this requires -parameters option when compiling java sources
var params = method.parameters;
for each (var p in params) {
@ -73,6 +78,8 @@ function analyzeClass(cls) {
}
var jarFile = findNashorn();
var ctxtLoader = Thread.currentThread().contextClassLoader;
// load each class and use reflection to analyze each Class
new JarFile(jarFile).stream().forEach(
function(entry) {
@ -80,8 +87,15 @@ new JarFile(jarFile).stream().forEach(
if (name.endsWith(".class")) {
var clsName = name.substring(0, name.lastIndexOf('.class'));
clsName = clsName.replace(/\//g, '.');
var cls = Class.forName(clsName);
analyzeClass(cls);
try {
// don't initialize to avoid for possible initialization errors
var cls = Class.forName(clsName, false, ctxtLoader);
analyzeClass(cls);
} catch (e) {
// print exception and continue analysis for other classes
print("Failed to analyze " + clsName);
e.printStackTrace();
}
}
}
)

View File

@ -354,8 +354,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}, CREATE_GLOBAL_ACC_CTXT);
nashornContext.initGlobal(newGlobal, this);
newGlobal.setScriptContext(ctxt);
nashornContext.initGlobal(newGlobal, this, ctxt);
return newGlobal;
}
@ -404,7 +403,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
return evalImpl(script, ctxt, getNashornGlobalFrom(ctxt));
}
private static Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
private Object evalImpl(final Context.MultiGlobalCompiledScript mgcs, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
final Global oldGlobal = Context.getGlobal();
final boolean globalChanged = (oldGlobal != ctxtGlobal);
try {
@ -413,8 +412,13 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
final ScriptFunction script = mgcs.getFunction(ctxtGlobal);
final ScriptContext oldCtxt = ctxtGlobal.getScriptContext();
ctxtGlobal.setScriptContext(ctxt);
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
try {
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} finally {
ctxtGlobal.setScriptContext(oldCtxt);
}
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);
throw new AssertionError("should not reach here");
@ -425,7 +429,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
}
private static Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt, final Global ctxtGlobal) throws ScriptException {
if (script == null) {
return null;
}
@ -436,8 +440,13 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
Context.setGlobal(ctxtGlobal);
}
final ScriptContext oldCtxt = ctxtGlobal.getScriptContext();
ctxtGlobal.setScriptContext(ctxt);
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
try {
return ScriptObjectMirror.translateUndefined(ScriptObjectMirror.wrap(ScriptRuntime.apply(script, ctxtGlobal), ctxtGlobal));
} finally {
ctxtGlobal.setScriptContext(oldCtxt);
}
} catch (final Exception e) {
throwAsScriptException(e, ctxtGlobal);
throw new AssertionError("should not reach here");

View File

@ -47,6 +47,7 @@ import jdk.nashorn.internal.objects.Global;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ECMAException;
import jdk.nashorn.internal.runtime.JSONListAdapter;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@ -72,6 +73,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
private final ScriptObject sobj;
private final Global global;
private final boolean strict;
private final boolean jsonCompatible;
@Override
public boolean equals(final Object other) {
@ -110,9 +112,9 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
if (sobj instanceof ScriptFunction) {
final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
final Object self = globalChanged? wrap(thiz, oldGlobal) : thiz;
return wrap(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)), global);
final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
final Object self = globalChanged? wrapLikeMe(thiz, oldGlobal) : thiz;
return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)sobj, unwrap(self, global), unwrapArray(modArgs, global)));
}
throw new RuntimeException("not a function: " + toString());
@ -140,8 +142,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
if (sobj instanceof ScriptFunction) {
final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
return wrap(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)), global);
final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
return wrapLikeMe(ScriptRuntime.construct((ScriptFunction)sobj, unwrapArray(modArgs, global)));
}
throw new RuntimeException("not a constructor: " + toString());
@ -170,7 +172,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
return Context.getContext();
}
}, GET_CONTEXT_ACC_CTXT);
return wrap(context.eval(global, s, sobj, null, false), global);
return wrapLikeMe(context.eval(global, s, sobj, null, false));
}
});
}
@ -193,8 +195,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
final Object val = sobj.get(functionName);
if (val instanceof ScriptFunction) {
final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args;
return wrap(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global);
final Object[] modArgs = globalChanged? wrapArrayLikeMe(args, oldGlobal) : args;
return wrapLikeMe(ScriptRuntime.apply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)));
} else if (val instanceof JSObject && ((JSObject)val).isFunction()) {
return ((JSObject)val).call(sobj, args);
}
@ -218,7 +220,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
Objects.requireNonNull(name);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return wrap(sobj.get(name), global);
return wrapLikeMe(sobj.get(name));
}
});
}
@ -227,7 +229,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public Object getSlot(final int index) {
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return wrap(sobj.get(index), global);
return wrapLikeMe(sobj.get(index));
}
});
}
@ -368,7 +370,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
while (iter.hasNext()) {
final String key = iter.next();
final Object value = translateUndefined(wrap(sobj.get(key), global));
final Object value = translateUndefined(wrapLikeMe(sobj.get(key)));
entries.add(new AbstractMap.SimpleImmutableEntry<>(key, value));
}
@ -382,7 +384,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
checkKey(key);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return translateUndefined(wrap(sobj.get(key), global));
return translateUndefined(wrapLikeMe(sobj.get(key)));
}
});
}
@ -419,8 +421,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
final boolean globalChanged = (oldGlobal != global);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
return translateUndefined(wrap(sobj.put(key, unwrap(modValue, global), strict), global));
final Object modValue = globalChanged? wrapLikeMe(value, oldGlobal) : value;
return translateUndefined(wrapLikeMe(sobj.put(key, unwrap(modValue, global), strict)));
}
});
}
@ -434,7 +436,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
@Override public Object call() {
for (final Map.Entry<? extends String, ? extends Object> entry : map.entrySet()) {
final Object value = entry.getValue();
final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
final Object modValue = globalChanged? wrapLikeMe(value, oldGlobal) : value;
final String key = entry.getKey();
checkKey(key);
sobj.set(key, unwrap(modValue, global), getCallSiteFlags());
@ -449,7 +451,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
checkKey(key);
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return translateUndefined(wrap(sobj.remove(key, strict), global));
return translateUndefined(wrapLikeMe(sobj.remove(key, strict)));
}
});
}
@ -486,7 +488,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
final Iterator<Object> iter = sobj.valueIterator();
while (iter.hasNext()) {
values.add(translateUndefined(wrap(iter.next(), global)));
values.add(translateUndefined(wrapLikeMe(iter.next())));
}
return Collections.unmodifiableList(values);
@ -503,7 +505,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public Object getProto() {
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return wrap(sobj.getProto(), global);
return wrapLikeMe(sobj.getProto());
}
});
}
@ -532,7 +534,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
public Object getOwnPropertyDescriptor(final String key) {
return inGlobal(new Callable<Object>() {
@Override public Object call() {
return wrap(sobj.getOwnPropertyDescriptor(key), global);
return wrapLikeMe(sobj.getOwnPropertyDescriptor(key));
}
});
}
@ -661,15 +663,75 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @return wrapped/converted object
*/
public static Object wrap(final Object obj, final Object homeGlobal) {
return wrap(obj, homeGlobal, false);
}
/**
* Make a script object mirror on given object if needed. Also converts ConsString instances to Strings. The
* created wrapper will implement the Java {@code List} interface if {@code obj} is a JavaScript
* {@code Array} object; this is compatible with Java JSON libraries expectations. Arrays retrieved through its
* properties (transitively) will also implement the list interface.
*
* @param obj object to be wrapped/converted
* @param homeGlobal global to which this object belongs. Not used for ConsStrings.
* @return wrapped/converted object
*/
public static Object wrapAsJSONCompatible(final Object obj, final Object homeGlobal) {
return wrap(obj, homeGlobal, true);
}
/**
* Make a script object mirror on given object if needed. Also converts ConsString instances to Strings.
*
* @param obj object to be wrapped/converted
* @param homeGlobal global to which this object belongs. Not used for ConsStrings.
* @param jsonCompatible if true, the created wrapper will implement the Java {@code List} interface if
* {@code obj} is a JavaScript {@code Array} object. Arrays retrieved through its properties (transitively)
* will also implement the list interface.
* @return wrapped/converted object
*/
private static Object wrap(final Object obj, final Object homeGlobal, final boolean jsonCompatible) {
if(obj instanceof ScriptObject) {
return homeGlobal instanceof Global ? new ScriptObjectMirror((ScriptObject)obj, (Global)homeGlobal) : obj;
}
if(obj instanceof ConsString) {
if (!(homeGlobal instanceof Global)) {
return obj;
}
final ScriptObject sobj = (ScriptObject)obj;
final Global global = (Global)homeGlobal;
final ScriptObjectMirror mirror = new ScriptObjectMirror(sobj, global, jsonCompatible);
if (jsonCompatible && sobj.isArray()) {
return new JSONListAdapter(mirror, global);
}
return mirror;
} else if(obj instanceof ConsString) {
return obj.toString();
} else if (jsonCompatible && obj instanceof ScriptObjectMirror) {
// Since choosing JSON compatible representation is an explicit decision on user's part, if we're asked to
// wrap a mirror that was not JSON compatible, explicitly create its compatible counterpart following the
// principle of least surprise.
return ((ScriptObjectMirror)obj).asJSONCompatible();
}
return obj;
}
/**
* Wraps the passed object with the same jsonCompatible flag as this mirror.
* @param obj the object
* @param homeGlobal the object's home global.
* @return a wrapper for the object.
*/
private Object wrapLikeMe(final Object obj, final Object homeGlobal) {
return wrap(obj, homeGlobal, jsonCompatible);
}
/**
* Wraps the passed object with the same home global and jsonCompatible flag as this mirror.
* @param obj the object
* @return a wrapper for the object.
*/
private Object wrapLikeMe(final Object obj) {
return wrapLikeMe(obj, global);
}
/**
* Unwrap a script object mirror if needed.
*
@ -681,6 +743,8 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
if (obj instanceof ScriptObjectMirror) {
final ScriptObjectMirror mirror = (ScriptObjectMirror)obj;
return (mirror.global == homeGlobal)? mirror.sobj : obj;
} else if (obj instanceof JSONListAdapter) {
return ((JSONListAdapter)obj).unwrap(homeGlobal);
}
return obj;
@ -694,6 +758,10 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @return wrapped array
*/
public static Object[] wrapArray(final Object[] args, final Object homeGlobal) {
return wrapArray(args, homeGlobal, false);
}
private static Object[] wrapArray(final Object[] args, final Object homeGlobal, final boolean jsonCompatible) {
if (args == null || args.length == 0) {
return args;
}
@ -701,12 +769,16 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
final Object[] newArgs = new Object[args.length];
int index = 0;
for (final Object obj : args) {
newArgs[index] = wrap(obj, homeGlobal);
newArgs[index] = wrap(obj, homeGlobal, jsonCompatible);
index++;
}
return newArgs;
}
private Object[] wrapArrayLikeMe(final Object[] args, final Object homeGlobal) {
return wrapArray(args, homeGlobal, jsonCompatible);
}
/**
* Unwrap an array of script object mirrors if needed.
*
@ -748,12 +820,17 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
// package-privates below this.
ScriptObjectMirror(final ScriptObject sobj, final Global global) {
this(sobj, global, false);
}
private ScriptObjectMirror(final ScriptObject sobj, final Global global, final boolean jsonCompatible) {
assert sobj != null : "ScriptObjectMirror on null!";
assert global != null : "home Global is null";
this.sobj = sobj;
this.global = global;
this.strict = global.isStrictContext();
this.jsonCompatible = jsonCompatible;
}
// accessors for script engine
@ -838,4 +915,11 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
});
}
private ScriptObjectMirror asJSONCompatible() {
if (this.jsonCompatible) {
return this;
}
return new ScriptObjectMirror(sobj, global, true);
}
}

View File

@ -53,7 +53,7 @@ final class ArrayAccessTreeImpl extends ExpressionTreeImpl implements ArrayAcces
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitArrayAccess(this, data);
}
}

View File

@ -47,7 +47,7 @@ final class ArrayLiteralTreeImpl extends ExpressionTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitArrayLiteral(this, data);
}
}

View File

@ -55,7 +55,7 @@ final class AssignmentTreeImpl extends ExpressionTreeImpl implements AssignmentT
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitAssignment(this, data);
}
}

View File

@ -55,7 +55,7 @@ class BinaryTreeImpl extends ExpressionTreeImpl implements BinaryTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitBinary(this, data);
}
}

View File

@ -53,7 +53,7 @@ final class BlockTreeImpl extends StatementTreeImpl implements BlockTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitBlock(this, data);
}
}

View File

@ -46,7 +46,7 @@ final class BreakTreeImpl extends StatementTreeImpl implements BreakTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitBreak(this, data);
}
}

View File

@ -56,7 +56,7 @@ final class CaseTreeImpl extends TreeImpl implements CaseTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitCase(this, data);
}
}

View File

@ -63,7 +63,7 @@ final class CatchTreeImpl extends TreeImpl implements CatchTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitCatch(this, data);
}
}

View File

@ -67,7 +67,7 @@ final class CompilationUnitTreeImpl extends TreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitCompilationUnit(this, data);
}
}

View File

@ -57,7 +57,7 @@ final class CompoundAssignmentTreeImpl extends ExpressionTreeImpl implements Com
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitCompoundAssignment(this, data);
}
}

View File

@ -61,7 +61,7 @@ final class ConditionalExpressionTreeImpl extends ExpressionTreeImpl implements
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitConditionalExpression(this, data);
}
}

View File

@ -46,7 +46,7 @@ final class ContinueTreeImpl extends StatementTreeImpl implements ContinueTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitContinue(this, data);
}
}

View File

@ -38,7 +38,7 @@ final class DebuggerTreeImpl extends StatementTreeImpl implements DebuggerTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitDebugger(this, data);
}
}

View File

@ -54,7 +54,7 @@ final class DoWhileLoopTreeImpl extends StatementTreeImpl implements DoWhileLoop
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitDoWhileLoop(this, data);
}
}

View File

@ -38,7 +38,7 @@ final class EmptyStatementTreeImpl extends StatementTreeImpl implements EmptySta
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitEmptyStatement(this, data);
}
}

View File

@ -38,7 +38,7 @@ final class ErroneousTreeImpl extends ExpressionTreeImpl implements ErroneousTre
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitErroneous(this, data);
}
}

View File

@ -46,7 +46,7 @@ final class ExpressionStatementTreeImpl extends StatementTreeImpl implements Exp
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitExpressionStatement(this, data);
}
}

View File

@ -71,7 +71,7 @@ final class ForInLoopTreeImpl extends StatementTreeImpl implements ForInLoopTree
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitForInLoop(this, data);
}
}

View File

@ -72,7 +72,7 @@ final class ForLoopTreeImpl extends StatementTreeImpl implements ForLoopTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitForLoop(this, data);
}
}

View File

@ -55,7 +55,7 @@ class FunctionCallTreeImpl extends ExpressionTreeImpl implements FunctionCallTre
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitFunctionCall(this, data);
}
}

View File

@ -74,7 +74,7 @@ final class FunctionDeclarationTreeImpl extends StatementTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitFunctionDeclaration(this, data);
}
}

View File

@ -79,7 +79,7 @@ final class FunctionExpressionTreeImpl extends ExpressionTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitFunctionExpression(this, data);
}
}

View File

@ -47,7 +47,7 @@ final class IdentifierTreeImpl extends ExpressionTreeImpl implements IdentifierT
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitIdentifier(this, data);
}
}

View File

@ -63,7 +63,7 @@ final class IfTreeImpl extends StatementTreeImpl implements IfTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitIf(this, data);
}
}

View File

@ -52,7 +52,7 @@ final class InstanceOfTreeImpl extends BinaryTreeImpl implements InstanceOfTree
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitInstanceOf(this, data);
}
}

View File

@ -54,7 +54,7 @@ final class LabeledStatementTreeImpl extends StatementTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitLabeledStatement(this, data);
}
}

View File

@ -35,12 +35,12 @@ final class LineMapImpl implements LineMap {
}
@Override
public long getLineNumber(long pos) {
public long getLineNumber(final long pos) {
return source.getLine((int)pos);
}
@Override
public long getColumnNumber(long pos) {
public long getColumnNumber(final long pos) {
return source.getColumn((int)pos);
}
}

View File

@ -61,7 +61,7 @@ final class LiteralTreeImpl extends ExpressionTreeImpl implements LiteralTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitLiteral(this, data);
}
}

View File

@ -53,7 +53,7 @@ final class MemberSelectTreeImpl extends ExpressionTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitMemberSelect(this, data);
}
}

View File

@ -47,7 +47,7 @@ final class NewTreeImpl extends ExpressionTreeImpl implements NewTree {
}
@Override
public <R, D> R accept(TreeVisitor<R, D> visitor, D data) {
public <R, D> R accept(final TreeVisitor<R, D> visitor, final D data) {
return visitor.visitNew(this, data);
}
}

View File

@ -47,7 +47,7 @@ final class ObjectLiteralTreeImpl extends ExpressionTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitObjectLiteral(this, data);
}
}

View File

@ -70,7 +70,7 @@ final class PropertyTreeImpl extends TreeImpl implements PropertyTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitProperty(this, data);
}
}

View File

@ -56,7 +56,7 @@ final class RegExpLiteralTreeImpl extends ExpressionTreeImpl
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitRegExpLiteral(this, data);
}
}

View File

@ -46,7 +46,7 @@ final class ReturnTreeImpl extends StatementTreeImpl implements ReturnTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitReturn(this, data);
}
}

View File

@ -48,28 +48,28 @@ package jdk.nashorn.api.tree;
*/
public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
@Override
public R visitAssignment(AssignmentTree node, P r) {
public R visitAssignment(final AssignmentTree node, final P r) {
node.getVariable().accept(this, r);
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitCompoundAssignment(CompoundAssignmentTree node, P r) {
public R visitCompoundAssignment(final CompoundAssignmentTree node, final P r) {
node.getVariable().accept(this, r);
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitBinary(BinaryTree node, P r) {
public R visitBinary(final BinaryTree node, final P r) {
node.getLeftOperand().accept(this, r);
node.getRightOperand().accept(this, r);
return null;
}
@Override
public R visitBlock(BlockTree node, P r) {
public R visitBlock(final BlockTree node, final P r) {
node.getStatements().forEach((tree) -> {
tree.accept(this, r);
});
@ -77,12 +77,12 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitBreak(BreakTree node, P r) {
public R visitBreak(final BreakTree node, final P r) {
return null;
}
@Override
public R visitCase(CaseTree node, P r) {
public R visitCase(final CaseTree node, final P r) {
final Tree caseVal = node.getExpression();
if (caseVal != null) {
caseVal.accept(this, r);
@ -95,7 +95,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitCatch(CatchTree node, P r) {
public R visitCatch(final CatchTree node, final P r) {
final Tree cond = node.getCondition();
if (cond != null) {
cond.accept(this, r);
@ -106,7 +106,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitConditionalExpression(ConditionalExpressionTree node, P r) {
public R visitConditionalExpression(final ConditionalExpressionTree node, final P r) {
node.getCondition().accept(this, r);
node.getTrueExpression().accept(this, r);
node.getFalseExpression().accept(this, r);
@ -114,35 +114,35 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitContinue(ContinueTree node, P r) {
public R visitContinue(final ContinueTree node, final P r) {
return null;
}
@Override
public R visitDebugger(DebuggerTree node, P r) {
public R visitDebugger(final DebuggerTree node, final P r) {
return null;
}
@Override
public R visitDoWhileLoop(DoWhileLoopTree node, P r) {
public R visitDoWhileLoop(final DoWhileLoopTree node, final P r) {
node.getStatement().accept(this, r);
node.getCondition().accept(this, r);
return null;
}
@Override
public R visitErroneous(ErroneousTree node, P r) {
public R visitErroneous(final ErroneousTree node, final P r) {
return null;
}
@Override
public R visitExpressionStatement(ExpressionStatementTree node, P r) {
public R visitExpressionStatement(final ExpressionStatementTree node, final P r) {
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitForLoop(ForLoopTree node, P r) {
public R visitForLoop(final ForLoopTree node, final P r) {
final Tree init = node.getInitializer();
if (init != null) {
init.accept(this, r);
@ -163,7 +163,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitForInLoop(ForInLoopTree node, P r) {
public R visitForInLoop(final ForInLoopTree node, final P r) {
node.getVariable().accept(this, r);
node.getExpression().accept(this, r);
final StatementTree stat = node.getStatement();
@ -174,7 +174,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitFunctionCall(FunctionCallTree node, P r) {
public R visitFunctionCall(final FunctionCallTree node, final P r) {
node.getFunctionSelect().accept(this, r);
node.getArguments().forEach((tree) -> {
tree.accept(this, r);
@ -183,7 +183,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitFunctionDeclaration(FunctionDeclarationTree node, P r) {
public R visitFunctionDeclaration(final FunctionDeclarationTree node, final P r) {
node.getParameters().forEach((tree) -> {
tree.accept(this, r);
});
@ -192,7 +192,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitFunctionExpression(FunctionExpressionTree node, P r) {
public R visitFunctionExpression(final FunctionExpressionTree node, final P r) {
node.getParameters().forEach((tree) -> {
tree.accept(this, r);
});
@ -201,12 +201,12 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitIdentifier(IdentifierTree node, P r) {
public R visitIdentifier(final IdentifierTree node, final P r) {
return null;
}
@Override
public R visitIf(IfTree node, P r) {
public R visitIf(final IfTree node, final P r) {
node.getCondition().accept(this, r);
node.getThenStatement().accept(this, r);
final Tree elseStat = node.getElseStatement();
@ -217,14 +217,14 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitArrayAccess(ArrayAccessTree node, P r) {
public R visitArrayAccess(final ArrayAccessTree node, final P r) {
node.getExpression().accept(this, r);
node.getIndex().accept(this, r);
return null;
}
@Override
public R visitArrayLiteral(ArrayLiteralTree node, P r) {
public R visitArrayLiteral(final ArrayLiteralTree node, final P r) {
node.getElements().stream().filter((tree) -> (tree != null)).forEach((tree) -> {
tree.accept(this, r);
});
@ -232,24 +232,24 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitLabeledStatement(LabeledStatementTree node, P r) {
public R visitLabeledStatement(final LabeledStatementTree node, final P r) {
node.getStatement().accept(this, r);
return null;
}
@Override
public R visitLiteral(LiteralTree node, P r) {
public R visitLiteral(final LiteralTree node, final P r) {
return null;
}
@Override
public R visitParenthesized(ParenthesizedTree node, P r) {
public R visitParenthesized(final ParenthesizedTree node, final P r) {
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitReturn(ReturnTree node, P r) {
public R visitReturn(final ReturnTree node, final P r) {
final Tree retExpr = node.getExpression();
if (retExpr != null) {
retExpr.accept(this, r);
@ -258,19 +258,19 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitMemberSelect(MemberSelectTree node, P r) {
public R visitMemberSelect(final MemberSelectTree node, final P r) {
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitNew(NewTree node, P r) {
public R visitNew(final NewTree node, final P r) {
node.getConstructorExpression().accept(this, r);
return null;
}
@Override
public R visitObjectLiteral(ObjectLiteralTree node, P r) {
public R visitObjectLiteral(final ObjectLiteralTree node, final P r) {
node.getProperties().forEach((tree) -> {
tree.accept(this, r);
});
@ -278,7 +278,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitProperty(PropertyTree node, P r) {
public R visitProperty(final PropertyTree node, final P r) {
FunctionExpressionTree getter = node.getGetter();
if (getter != null) {
getter.accept(this, r);
@ -301,17 +301,17 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitRegExpLiteral(RegExpLiteralTree node, P r) {
public R visitRegExpLiteral(final RegExpLiteralTree node, final P r) {
return null;
}
@Override
public R visitEmptyStatement(EmptyStatementTree node, P r) {
public R visitEmptyStatement(final EmptyStatementTree node, final P r) {
return null;
}
@Override
public R visitSwitch(SwitchTree node, P r) {
public R visitSwitch(final SwitchTree node, final P r) {
node.getExpression().accept(this, r);
node.getCases().forEach((tree) -> {
tree.accept(this, r);
@ -320,13 +320,13 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitThrow(ThrowTree node, P r) {
public R visitThrow(final ThrowTree node, final P r) {
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitCompilationUnit(CompilationUnitTree node, P r) {
public R visitCompilationUnit(final CompilationUnitTree node, final P r) {
node.getSourceElements().forEach((tree) -> {
tree.accept(this, r);
});
@ -334,7 +334,7 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitTry(TryTree node, P r) {
public R visitTry(final TryTree node, final P r) {
node.getBlock().accept(this, r);
node.getCatches().forEach((tree) -> {
tree.accept(this, r);
@ -348,20 +348,20 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitInstanceOf(InstanceOfTree node, P r) {
public R visitInstanceOf(final InstanceOfTree node, final P r) {
node.getType().accept(this, r);
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitUnary(UnaryTree node, P r) {
public R visitUnary(final UnaryTree node, final P r) {
node.getExpression().accept(this, r);
return null;
}
@Override
public R visitVariable(VariableTree node, P r) {
public R visitVariable(final VariableTree node, final P r) {
if (node.getInitializer() != null) {
node.getInitializer().accept(this, r);
}
@ -369,21 +369,21 @@ public class SimpleTreeVisitorES5_1<R, P> implements TreeVisitor<R, P> {
}
@Override
public R visitWhileLoop(WhileLoopTree node, P r) {
public R visitWhileLoop(final WhileLoopTree node, final P r) {
node.getCondition().accept(this, r);
node.getStatement().accept(this, r);
return null;
}
@Override
public R visitWith(WithTree node, P r) {
public R visitWith(final WithTree node, final P r) {
node.getScope().accept(this, r);
node.getStatement().accept(this, r);
return null;
}
@Override
public R visitUnknown(Tree node, P r) {
public R visitUnknown(final Tree node, final P r) {
// unknown in ECMAScript 5.1 edition
throw new UnknownTreeException(node, r);
}

View File

@ -55,7 +55,7 @@ final class SwitchTreeImpl extends StatementTreeImpl implements SwitchTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitSwitch(this, data);
}
}

View File

@ -45,7 +45,7 @@ final class ThrowTreeImpl extends StatementTreeImpl implements ThrowTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitThrow(this, data);
}
}

View File

@ -47,7 +47,7 @@ abstract class TreeImpl implements Tree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitUnknown(this, data);
}

View File

@ -63,7 +63,7 @@ final class TryTreeImpl extends StatementTreeImpl implements TryTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitTry(this, data);
}
}

View File

@ -47,7 +47,7 @@ class UnaryTreeImpl extends ExpressionTreeImpl implements UnaryTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitUnary(this, data);
}
}

View File

@ -53,7 +53,7 @@ final class VariableTreeImpl extends StatementTreeImpl implements VariableTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitVariable(this, data);
}
}

View File

@ -54,7 +54,7 @@ final class WhileLoopTreeImpl extends StatementTreeImpl implements WhileLoopTree
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitWhileLoop(this, data);
}
}

View File

@ -53,7 +53,7 @@ final class WithTreeImpl extends StatementTreeImpl implements WithTree {
}
@Override
public <R,D> R accept(TreeVisitor<R,D> visitor, D data) {
public <R,D> R accept(final TreeVisitor<R,D> visitor, final D data) {
return visitor.visitWith(this, data);
}
}

View File

@ -363,7 +363,7 @@ enum CompilationPhase {
//partial code generation
final FunctionNode newFunctionNode = transformFunction(fn, new ReplaceCompileUnits() {
@Override
CompileUnit getReplacement(CompileUnit original) {
CompileUnit getReplacement(final CompileUnit original) {
return map.get(original);
}

View File

@ -567,7 +567,7 @@ public final class OptimisticTypesPersistence {
final MessageDigest digest = MessageDigest.getInstance("SHA-1");
Files.walk(nashorn).forEach(new Consumer<Path>() {
@Override
public void accept(Path p) {
public void accept(final Path p) {
// take only the .class resources.
if (Files.isRegularFile(p) && p.toString().endsWith(".class")) {
try {

View File

@ -102,7 +102,7 @@ final class SplitIntoFunctions extends NodeVisitor<BlockLexicalContext> {
public SplitIntoFunctions(final Compiler compiler) {
super(new BlockLexicalContext() {
@Override
protected Block afterSetStatements(Block block) {
protected Block afterSetStatements(final Block block) {
for(Statement stmt: block.getStatements()) {
assert !(stmt instanceof SplitNode);
}
@ -305,7 +305,7 @@ final class SplitIntoFunctions extends NodeVisitor<BlockLexicalContext> {
}
@Override
public boolean enterVarNode(VarNode varNode) {
public boolean enterVarNode(final VarNode varNode) {
if (!inSplitNode()) {
return super.enterVarNode(varNode);
}

View File

@ -54,7 +54,7 @@ public final class SplitReturn extends Statement {
}
@Override
public void toString(StringBuilder sb, boolean printType) {
public void toString(final StringBuilder sb, final boolean printType) {
sb.append(":splitreturn;");
}

View File

@ -122,7 +122,7 @@ public final class TryNode extends LexicalContextStatement implements JoinPredec
* @param visitor IR navigating visitor.
*/
@Override
public Node accept(final LexicalContext lc, NodeVisitor<? extends LexicalContext> visitor) {
public Node accept(final LexicalContext lc, final NodeVisitor<? extends LexicalContext> visitor) {
if (visitor.enterTryNode(this)) {
// Need to do finallybody first for termination analysis. TODO still necessary?
final Block newFinallyBody = finallyBody == null ? null : (Block)finallyBody.accept(visitor);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2010, 2015, 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
@ -1109,7 +1109,7 @@ public final class NashornTextifier extends Printer {
}
final String ex = catches.get(node);
if (ex != null) {
sb.append("*** CATCH: ").append(ex).append(" ***\n");
sb.append("*** CATCH: ").append(ex).append(" ***\\l");
}
sb.append(c);
sb.append("\"]\n");

View File

@ -928,9 +928,11 @@ public final class Global extends ScriptObject implements Scope {
private final Context context;
// current ScriptContext to use - can be null.
private ScriptContext scontext;
private ThreadLocal<ScriptContext> scontext;
// current ScriptEngine associated - can be null.
private ScriptEngine engine;
// initial ScriptContext - can be null
private volatile ScriptContext initscontext;
// ES6 global lexical scope.
private final LexicalScope lexicalScope;
@ -940,10 +942,25 @@ public final class Global extends ScriptObject implements Scope {
/**
* Set the current script context
* @param scontext script context
* @param ctxt script context
*/
public void setScriptContext(final ScriptContext scontext) {
this.scontext = scontext;
public void setScriptContext(final ScriptContext ctxt) {
assert scontext != null;
scontext.set(ctxt);
}
/**
* Get the current script context
* @return current script context
*/
public ScriptContext getScriptContext() {
assert scontext != null;
return scontext.get();
}
private ScriptContext currentContext() {
final ScriptContext sc = scontext != null? scontext.get() : null;
return sc == null? initscontext : sc;
}
@Override
@ -1056,14 +1073,19 @@ public final class Global extends ScriptObject implements Scope {
* of the global scope object.
*
* @param eng ScriptEngine to initialize
* @param ctxt ScriptContext to initialize
*/
public void initBuiltinObjects(final ScriptEngine eng) {
public void initBuiltinObjects(final ScriptEngine eng, final ScriptContext ctxt) {
if (this.builtinObject != null) {
// already initialized, just return
return;
}
this.engine = eng;
this.initscontext = ctxt;
if (this.engine != null) {
this.scontext = new ThreadLocal<>();
}
init(eng);
}
@ -1392,7 +1414,7 @@ public final class Global extends ScriptObject implements Scope {
*/
public static Object __noSuchProperty__(final Object self, final Object name) {
final Global global = Global.instance();
final ScriptContext sctxt = global.scontext;
final ScriptContext sctxt = global.currentContext();
final String nameStr = name.toString();
if (sctxt != null) {
@ -2737,8 +2759,9 @@ public final class Global extends ScriptObject implements Scope {
}
private Object printImpl(final boolean newLine, final Object... objects) {
final ScriptContext sc = currentContext();
@SuppressWarnings("resource")
final PrintWriter out = scontext != null? new PrintWriter(scontext.getWriter()) : getContext().getEnv().getOut();
final PrintWriter out = sc != null? new PrintWriter(sc.getWriter()) : getContext().getEnv().getOut();
final StringBuilder sb = new StringBuilder();
for (final Object obj : objects) {

View File

@ -33,10 +33,12 @@ import java.lang.reflect.Array;
import java.util.Collection;
import java.util.Deque;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.support.TypeUtilities;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
@ -656,4 +658,20 @@ public final class NativeJava {
public static Object _super(final Object self, final Object adapter) {
return Bootstrap.createSuperAdapter(adapter);
}
/**
* Returns an object that is compatible with Java JSON libraries expectations; namely, that if it itself, or any
* object transitively reachable through it is a JavaScript array, then such objects will be exposed as
* {@link JSObject} that also implements the {@link List} interface for exposing the array elements. An explicit
* API is required as otherwise Nashorn exposes all objects externally as {@link JSObject}s that also implement the
* {@link Map} interface instead. By using this method, arrays will be exposed as {@link List}s and all other
* objects as {@link Map}s.
* @param self not used
* @param obj the object to be exposed in a Java JSON library compatible manner.
* @return a wrapper around the object that will enforce Java JSON library compatible exposure.
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object asJSONCompatible(final Object self, final Object obj) {
return ScriptObjectMirror.wrapAsJSONCompatible(obj, Context.getGlobal());
}
}

View File

@ -528,8 +528,9 @@ final class CompiledFunction {
final int fnParamCountNoCallee = fnParamCount - thisThisIndex;
final int minParams = Math.min(csParamCount - 1, fnParamCountNoCallee); // callSiteType always has callee, so subtract 1
// We must match all incoming parameters, except "this". Starting from 1 to skip "this".
for(int i = 1; i < minParams; ++i) {
// We must match all incoming parameters, including "this". "this" will usually be Object, but there
// are exceptions, e.g. when calling functions with primitive "this" in strict mode or through call/apply.
for(int i = 0; i < minParams; ++i) {
final Type fnType = Type.typeFor(type.parameterType(i + thisThisIndex));
final Type csType = csIsVarArg ? Type.OBJECT : Type.typeFor(other.parameterType(i + 1));
if(!fnType.isEquivalentTo(csType)) {

View File

@ -66,6 +66,7 @@ import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.logging.Level;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import jdk.internal.org.objectweb.asm.ClassReader;
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
@ -1095,16 +1096,17 @@ public final class Context {
*
* @param global the global
* @param engine the associated ScriptEngine instance, can be null
* @param ctxt the initial ScriptContext, can be null
* @return the initialized global scope object.
*/
public Global initGlobal(final Global global, final ScriptEngine engine) {
public Global initGlobal(final Global global, final ScriptEngine engine, final ScriptContext ctxt) {
// Need only minimal global object, if we are just compiling.
if (!env._compile_only) {
final Global oldGlobal = Context.getGlobal();
try {
Context.setGlobal(global);
// initialize global scope with builtin global objects
global.initBuiltinObjects(engine);
global.initBuiltinObjects(engine, ctxt);
} finally {
Context.setGlobal(oldGlobal);
}
@ -1120,7 +1122,7 @@ public final class Context {
* @return the initialized global scope object.
*/
public Global initGlobal(final Global global) {
return initGlobal(global, null);
return initGlobal(global, null, null);
}
/**

View File

@ -0,0 +1,161 @@
/*
* Copyright (c) 2015, 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.util.Collection;
import java.util.List;
import java.util.Set;
import jdk.nashorn.api.scripting.JSObject;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.internal.objects.Global;
/**
* A {@link ListAdapter} that also implements {@link JSObject}. Named {@code JSONListAdapter} as it is used as a
* {@code JSObject} implementing the {@link List} interface, which is the expected interface to be implemented by
* JSON-parsed arrays when they are handled in Java. We aren't implementing {@link JSObject} on {@link ListAdapter}
* directly since that'd have implications for other uses of list adapter (e.g. interferences of JSObject default
* value calculation vs. List's {@code toString()} etc.)
*/
public final class JSONListAdapter extends ListAdapter implements JSObject {
/**
* Creates a new JSON list adapter.
* @param obj the underlying object being exposed as a list.
* @param global the home global of the underlying object.
*/
public JSONListAdapter(final JSObject obj, final Global global) {
super(obj, global);
}
/**
* Unwraps this adapter into its underlying non-JSObject representative.
* @param homeGlobal the home global for unwrapping
* @return either the unwrapped object or this if it should not be unwrapped in the specified global.
*/
public Object unwrap(final Object homeGlobal) {
final Object unwrapped = ScriptObjectMirror.unwrap(obj, homeGlobal);
return unwrapped != obj ? unwrapped : this;
}
@Override
public Object call(final Object thiz, final Object... args) {
return obj.call(thiz, args);
}
@Override
public Object newObject(final Object... args) {
return obj.newObject(args);
}
@Override
public Object eval(final String s) {
return obj.eval(s);
}
@Override
public Object getMember(final String name) {
return obj.getMember(name);
}
@Override
public Object getSlot(final int index) {
return obj.getSlot(index);
}
@Override
public boolean hasMember(final String name) {
return obj.hasMember(name);
}
@Override
public boolean hasSlot(final int slot) {
return obj.hasSlot(slot);
}
@Override
public void removeMember(final String name) {
obj.removeMember(name);
}
@Override
public void setMember(final String name, final Object value) {
obj.setMember(name, value);
}
@Override
public void setSlot(final int index, final Object value) {
obj.setSlot(index, value);
}
@Override
public Set<String> keySet() {
return obj.keySet();
}
@Override
public Collection<Object> values() {
return obj.values();
}
@Override
public boolean isInstance(final Object instance) {
return obj.isInstance(instance);
}
@Override
public boolean isInstanceOf(final Object clazz) {
return obj.isInstanceOf(clazz);
}
@Override
public String getClassName() {
return obj.getClassName();
}
@Override
public boolean isFunction() {
return obj.isFunction();
}
@Override
public boolean isStrictFunction() {
return obj.isStrictFunction();
}
@Override
public boolean isArray() {
return obj.isArray();
}
@Override @Deprecated
public double toNumber() {
return obj.toNumber();
}
@Override
public Object getDefaultValue(Class<?> hint) throws UnsupportedOperationException {
return obj.getDefaultValue(hint);
}
}

View File

@ -52,7 +52,7 @@ import jdk.nashorn.internal.runtime.linker.Bootstrap;
* operations respectively, while {@link #addLast(Object)} and {@link #removeLast()} will translate to {@code push} and
* {@code pop}.
*/
public final class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
public class ListAdapter extends AbstractList<Object> implements RandomAccess, Deque<Object> {
// Invoker creator for methods that add to the start or end of the list: PUSH and UNSHIFT. Takes fn, this, and value, returns void.
private static final Callable<MethodHandle> ADD_INVOKER_CREATOR = invokerCreator(void.class, Object.class, JSObject.class, Object.class);
@ -78,21 +78,17 @@ public final class ListAdapter extends AbstractList<Object> implements RandomAcc
private static final Callable<MethodHandle> SPLICE_REMOVE_INVOKER_CREATOR = invokerCreator(void.class, Object.class, JSObject.class, int.class, int.class);
/** wrapped object */
private final JSObject obj;
final JSObject obj;
private final Global global;
// allow subclasses only in this package
ListAdapter(final JSObject obj) {
this.obj = obj;
this.global = getGlobalNonNull();
}
private static Global getGlobalNonNull() {
final Global global = Context.getGlobal();
if (global != null) {
return global;
ListAdapter(final JSObject obj, final Global global) {
if (global == null) {
throw new IllegalStateException(ECMAErrors.getMessage("list.adapter.null.global"));
}
throw new IllegalStateException(ECMAErrors.getMessage("list.adapter.null.global"));
this.obj = obj;
this.global = global;
}
/**
@ -102,12 +98,13 @@ public final class ListAdapter extends AbstractList<Object> implements RandomAcc
* @return A ListAdapter wrapper object
*/
public static ListAdapter create(final Object obj) {
return new ListAdapter(getJSObject(obj));
final Global global = Context.getGlobal();
return new ListAdapter(getJSObject(obj, global), global);
}
private static JSObject getJSObject(final Object obj) {
private static JSObject getJSObject(final Object obj, final Global global) {
if (obj instanceof ScriptObject) {
return (JSObject)ScriptObjectMirror.wrap(obj, Context.getGlobal());
return (JSObject)ScriptObjectMirror.wrap(obj, global);
} else if (obj instanceof JSObject) {
return (JSObject)obj;
}

View File

@ -137,7 +137,7 @@ public final class ScriptingFunctions {
final ScriptObject global = Context.getGlobal();
// Set up initial process.
final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeCommandLine(JSType.toString(string)));
final ProcessBuilder processBuilder = new ProcessBuilder(tokenizeString(JSType.toString(string)));
// Current ENV property state.
final Object env = global.get(ENV_NAME);
@ -237,23 +237,22 @@ public final class ScriptingFunctions {
}
/**
* Break an exec string into tokens, honoring quoted arguments and escaped
* spaces.
* Break a string into tokens, honoring quoted arguments and escaped spaces.
*
* @param execString a {@link String} with the command line to execute.
* @param str a {@link String} to tokenize.
* @return a {@link List} of {@link String}s representing the tokens that
* constitute the command line.
* constitute the string.
* @throws IOException in case {@link StreamTokenizer#nextToken()} raises it.
*/
public static List<String> tokenizeCommandLine(final String execString) throws IOException {
final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(execString));
public static List<String> tokenizeString(final String str) throws IOException {
final StreamTokenizer tokenizer = new StreamTokenizer(new StringReader(str));
tokenizer.resetSyntax();
tokenizer.wordChars(0, 255);
tokenizer.whitespaceChars(0, ' ');
tokenizer.commentChar('#');
tokenizer.quoteChar('"');
tokenizer.quoteChar('\'');
final List<String> cmdList = new ArrayList<>();
final List<String> tokenList = new ArrayList<>();
final StringBuilder toAppend = new StringBuilder();
while (tokenizer.nextToken() != StreamTokenizer.TT_EOF) {
final String s = tokenizer.sval;
@ -265,13 +264,13 @@ public final class ScriptingFunctions {
// omit trailing \, append space instead
toAppend.append(s.substring(0, s.length() - 1)).append(' ');
} else {
cmdList.add(toAppend.append(s).toString());
tokenList.add(toAppend.append(s).toString());
toAppend.setLength(0);
}
}
if (toAppend.length() != 0) {
cmdList.add(toAppend.toString());
tokenList.add(toAppend.toString());
}
return cmdList;
return tokenList;
}
}

View File

@ -934,14 +934,16 @@ public final class Source implements Loggable {
start = 2;
cs = StandardCharsets.UTF_16BE;
} else if (bytes.length > 1 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE) {
start = 2;
cs = StandardCharsets.UTF_16LE;
if (bytes.length > 3 && bytes[2] == 0 && bytes[3] == 0) {
start = 4;
cs = Charset.forName("UTF-32LE");
} else {
start = 2;
cs = StandardCharsets.UTF_16LE;
}
} else if (bytes.length > 2 && bytes[0] == (byte) 0xEF && bytes[1] == (byte) 0xBB && bytes[2] == (byte) 0xBF) {
start = 3;
cs = StandardCharsets.UTF_8;
} else if (bytes.length > 3 && bytes[0] == (byte) 0xFF && bytes[1] == (byte) 0xFE && bytes[2] == 0 && bytes[3] == 0) {
start = 4;
cs = Charset.forName("UTF-32LE");
} else if (bytes.length > 3 && bytes[0] == 0 && bytes[1] == 0 && bytes[2] == (byte) 0xFE && bytes[3] == (byte) 0xFF) {
start = 4;
cs = Charset.forName("UTF-32BE");

View File

@ -246,7 +246,7 @@ public class NashornBeansLinker implements GuardingDynamicLinker {
}
@Override
public MethodHandle filterInternalObjects(MethodHandle target) {
public MethodHandle filterInternalObjects(final MethodHandle target) {
return linkerServices.filterInternalObjects(target);
}
}

View File

@ -0,0 +1,26 @@
###########################################################################
#
# Copyright (c) 2015, 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.
#
###########################################################################
# No nashorn tests are on the problem list.

View File

@ -1,6 +1,11 @@
# This file identifies the root of the test-suite hierarchy.
# It also contains test-suite configuration information.
# DO NOT EDIT without first contacting jdk-regtest@sun.com.
# The list of keywords supported in the entire test suite
keys=2d dnd i18n
keys=intermittent randomness
# Group definitions
groups=TEST.groups
# Minimum jtreg version
requiredVersion=4.1 b11

29
nashorn/test/TEST.groups Normal file
View File

@ -0,0 +1,29 @@
# Copyright (c) 2015, 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.
#
# Tiered testing definitions
# No nashorn tests are tier 1.
tier1 =
# All nashorn tests are tier 2.
tier2 = src

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2015, 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-8066220: Fuzzing bug: MethodHandle bug (Object,Object) != (boolean)Object
*
* @test
* @run
*/
function f() {}
// Call f with primitive this first, then as constructor
f.call(1);
new f();
// Same as above in strict mode
eval('"use strict"; function e() { print(typeof this); } e.call(1); new e();');

View File

@ -0,0 +1,2 @@
number
object

View File

@ -0,0 +1,115 @@
/*
* Copyright (c) 2015, 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.api.scripting;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertTrue;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import javax.script.ScriptEngine;
import javax.script.ScriptException;
import org.testng.Assert;
import org.testng.annotations.Test;
public class JSONCompatibleTest {
/**
* Wrap a top-level array as a list.
*/
@Test
public void testWrapArray() throws ScriptException {
final ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
final Object val = engine.eval("Java.asJSONCompatible([1, 2, 3])");
assertEquals(asList(val), Arrays.asList(1, 2, 3));
}
/**
* Wrap an embedded array as a list.
*/
@Test
public void testWrapObjectWithArray() throws ScriptException {
final ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
final Object val = engine.eval("Java.asJSONCompatible({x: [1, 2, 3]})");
assertEquals(asList(asMap(val).get("x")), Arrays.asList(1, 2, 3));
}
/**
* Check it all works transitively several more levels down.
*/
@Test
public void testDeepWrapping() throws ScriptException {
final ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
final Object val = engine.eval("Java.asJSONCompatible({x: [1, {y: [2, {z: [3]}]}, [4, 5]]})");
final Map<String, Object> root = asMap(val);
final List<Object> x = asList(root.get("x"));
assertEquals(x.get(0), 1);
final Map<String, Object> x1 = asMap(x.get(1));
final List<Object> y = asList(x1.get("y"));
assertEquals(y.get(0), 2);
final Map<String, Object> y1 = asMap(y.get(1));
assertEquals(asList(y1.get("z")), Arrays.asList(3));
assertEquals(asList(x.get(2)), Arrays.asList(4, 5));
}
/**
* Ensure that the old behaviour (every object is a Map) is unchanged.
*/
@Test
public void testNonWrapping() throws ScriptException {
final ScriptEngine engine = new NashornScriptEngineFactory().getScriptEngine();
final Object val = engine.eval("({x: [1, {y: [2, {z: [3]}]}, [4, 5]]})");
final Map<String, Object> root = asMap(val);
final Map<String, Object> x = asMap(root.get("x"));
assertEquals(x.get("0"), 1);
final Map<String, Object> x1 = asMap(x.get("1"));
final Map<String, Object> y = asMap(x1.get("y"));
assertEquals(y.get("0"), 2);
final Map<String, Object> y1 = asMap(y.get("1"));
final Map<String, Object> z = asMap(y1.get("z"));
assertEquals(z.get("0"), 3);
final Map<String, Object> x2 = asMap(x.get("2"));
assertEquals(x2.get("0"), 4);
assertEquals(x2.get("1"), 5);
}
private static List<Object> asList(final Object obj) {
assertJSObject(obj);
Assert.assertTrue(obj instanceof List);
return (List)obj;
}
private static Map<String, Object> asMap(final Object obj) {
assertJSObject(obj);
Assert.assertTrue(obj instanceof Map);
return (Map)obj;
}
private static void assertJSObject(final Object obj) {
assertTrue(obj instanceof JSObject);
}
}

View File

@ -31,10 +31,12 @@ import static org.testng.Assert.fail;
import javax.script.Bindings;
import javax.script.ScriptContext;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleBindings;
import javax.script.SimpleScriptContext;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
import jdk.nashorn.api.scripting.ScriptObjectMirror;
import jdk.nashorn.api.scripting.URLReader;
import org.testng.Assert;
@ -778,4 +780,44 @@ public class ScopeTest {
throw new AssertionError("should have thrown NPE");
} catch (NullPointerException npe5) {}
}
public static class RecursiveEval {
private final ScriptEngineFactory factory = new NashornScriptEngineFactory();
private final ScriptEngine engine = factory.getScriptEngine();
private final Bindings engineBindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
public void program() throws ScriptException {
ScriptContext sc = new SimpleScriptContext();
Bindings global = new SimpleBindings();
sc.setBindings(global, ScriptContext.GLOBAL_SCOPE);
sc.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
global.put("text", "programText");
String value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "programText");
engine.put("program", this);
engine.eval("program.method()");
// eval again from here!
value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "programText");
}
public void method() throws ScriptException {
// a context with a new global bindings, same engine bindings
final ScriptContext sc = new SimpleScriptContext();
final Bindings global = new SimpleBindings();
sc.setBindings(global, ScriptContext.GLOBAL_SCOPE);
sc.setBindings(engineBindings, ScriptContext.ENGINE_SCOPE);
global.put("text", "methodText");
String value = engine.eval("text", sc).toString();
Assert.assertEquals(value, "methodText");
}
}
// @bug 8081609: engine.eval call from a java method which
// was called from a previous engine.eval results in wrong
// ScriptContext being used.
@Test
public void recursiveEvalCallScriptContextTest() throws ScriptException {
new RecursiveEval().program();
}
}

View File

@ -225,7 +225,7 @@ public final class TestFinder {
boolean explicitOptimistic = false;
String allContent = new String(Files.readAllBytes(testFile));
Iterator<String> scanner = ScriptingFunctions.tokenizeCommandLine(allContent).iterator();
Iterator<String> scanner = ScriptingFunctions.tokenizeString(allContent).iterator();
while (scanner.hasNext()) {
// TODO: Scan for /ref=file qualifiers, etc, to determine run
// behavior