Merge
@ -372,6 +372,12 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
|
||||
|
||||
<copy file="${file.reference.jfxrt.jar}" todir="dist"/>
|
||||
|
||||
<condition property="jfx.prism.order" value="-Dprism.order=j2d" else=" ">
|
||||
<not>
|
||||
<os family="mac"/>
|
||||
</not>
|
||||
</condition>
|
||||
|
||||
<testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
|
||||
verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
|
||||
<jvmarg line="${ext.class.path}"/>
|
||||
@ -380,6 +386,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
|
||||
<propertyref prefix="testjfx-test-sys-prop."/>
|
||||
<mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/>
|
||||
</propertyset>
|
||||
<sysproperty key="test.fork.jvm.options" value="${testjfx-test-sys-prop.test.fork.jvm.options} ${jfx.prism.order}"/>
|
||||
<classpath>
|
||||
<pathelement path="${testjfx.run.test.classpath}"/>
|
||||
</classpath>
|
||||
|
@ -230,7 +230,7 @@ testjfx.run.test.classpath=\
|
||||
${file.reference.jemmyawtinput.jar}${path.separator}\
|
||||
${file.reference.testng.jar}${path.separator}\
|
||||
${nashorn.internal.tests.jar}${path.separator}\
|
||||
${nashorn.api.tests.jar}
|
||||
${nashorn.api.tests.jar}
|
||||
|
||||
# testjfx VM options for script tests with @fork option
|
||||
testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath}
|
||||
|
@ -41,6 +41,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.Callable;
|
||||
import javax.script.Bindings;
|
||||
import jdk.nashorn.internal.runtime.ConsString;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
@ -594,14 +595,35 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a script object mirror on given object if needed.
|
||||
* Utilitity to convert this script object to the given type.
|
||||
*
|
||||
* @param obj object to be wrapped
|
||||
* @param homeGlobal global to which this object belongs
|
||||
* @return wrapped object
|
||||
* @param type destination type to convert to
|
||||
* @return converted object
|
||||
*/
|
||||
public static Object wrap(final Object obj, final ScriptObject homeGlobal) {
|
||||
return (obj instanceof ScriptObject && homeGlobal != null) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
|
||||
public <T> T to(final Class<T> type) {
|
||||
return inGlobal(new Callable<T>() {
|
||||
@Override
|
||||
public T call() {
|
||||
return type.cast(ScriptUtils.convert(sobj, type));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return wrapped/converted object
|
||||
*/
|
||||
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;
|
||||
}
|
||||
if(obj instanceof ConsString) {
|
||||
return obj.toString();
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -611,7 +633,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
||||
* @param homeGlobal global to which this object belongs
|
||||
* @return unwrapped object
|
||||
*/
|
||||
public static Object unwrap(final Object obj, final ScriptObject homeGlobal) {
|
||||
public static Object unwrap(final Object obj, final Object homeGlobal) {
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
final ScriptObjectMirror mirror = (ScriptObjectMirror)obj;
|
||||
return (mirror.global == homeGlobal)? mirror.sobj : obj;
|
||||
@ -627,7 +649,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
||||
* @param homeGlobal global to which this object belongs
|
||||
* @return wrapped array
|
||||
*/
|
||||
public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) {
|
||||
public static Object[] wrapArray(final Object[] args, final Object homeGlobal) {
|
||||
if (args == null || args.length == 0) {
|
||||
return args;
|
||||
}
|
||||
@ -648,7 +670,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
|
||||
* @param homeGlobal global to which this object belongs
|
||||
* @return unwrapped array
|
||||
*/
|
||||
public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) {
|
||||
public static Object[] unwrapArray(final Object[] args, final Object homeGlobal) {
|
||||
if (args == null || args.length == 0) {
|
||||
return args;
|
||||
}
|
||||
|
@ -25,11 +25,17 @@
|
||||
|
||||
package jdk.nashorn.api.scripting;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import jdk.internal.dynalink.beans.StaticClass;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
|
||||
/**
|
||||
* Utilities that are to be called from script code
|
||||
* Utilities that are to be called from script code.
|
||||
*/
|
||||
public final class ScriptUtils {
|
||||
private ScriptUtils() {}
|
||||
@ -71,4 +77,96 @@ public final class ScriptUtils {
|
||||
return func.makeSynchronizedFunction(sync);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a script object mirror on given object if needed.
|
||||
*
|
||||
* @param obj object to be wrapped
|
||||
* @return wrapped object
|
||||
*/
|
||||
public static Object wrap(final Object obj) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return ScriptObjectMirror.wrap(obj, Context.getGlobal());
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap a script object mirror if needed.
|
||||
*
|
||||
* @param obj object to be unwrapped
|
||||
* @return unwrapped object
|
||||
*/
|
||||
public static Object unwrap(final Object obj) {
|
||||
if (obj instanceof ScriptObjectMirror) {
|
||||
return ScriptObjectMirror.unwrap(obj, Context.getGlobal());
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Wrap an array of object to script object mirrors if needed.
|
||||
*
|
||||
* @param args array to be unwrapped
|
||||
* @return wrapped array
|
||||
*/
|
||||
public static Object[] wrapArray(final Object[] args) {
|
||||
if (args == null || args.length == 0) {
|
||||
return args;
|
||||
}
|
||||
|
||||
return ScriptObjectMirror.wrapArray(args, Context.getGlobal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Unwrap an array of script object mirrors if needed.
|
||||
*
|
||||
* @param args array to be unwrapped
|
||||
* @return unwrapped array
|
||||
*/
|
||||
public static Object[] unwrapArray(final Object[] args) {
|
||||
if (args == null || args.length == 0) {
|
||||
return args;
|
||||
}
|
||||
|
||||
return ScriptObjectMirror.unwrapArray(args, Context.getGlobal());
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the given object to the given type.
|
||||
*
|
||||
* @param obj object to be converted
|
||||
* @param type destination type to convert to
|
||||
* @return converted object
|
||||
*/
|
||||
public static Object convert(final Object obj, final Object type) {
|
||||
if (obj == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final Class<?> clazz;
|
||||
if (type instanceof Class) {
|
||||
clazz = (Class<?>)type;
|
||||
} else if (type instanceof StaticClass) {
|
||||
clazz = ((StaticClass)type).getRepresentedClass();
|
||||
} else {
|
||||
throw new IllegalArgumentException("type expected");
|
||||
}
|
||||
|
||||
final LinkerServices linker = Bootstrap.getLinkerServices();
|
||||
final MethodHandle converter = linker.getTypeConverter(obj.getClass(), clazz);
|
||||
if (converter == null) {
|
||||
// no supported conversion!
|
||||
throw new UnsupportedOperationException("conversion not supported");
|
||||
}
|
||||
|
||||
try {
|
||||
return converter.invoke(obj);
|
||||
} catch (final RuntimeException | Error e) {
|
||||
throw e;
|
||||
} catch (final Throwable t) {
|
||||
throw new RuntimeException(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -271,6 +271,7 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
functionNode.addDeclaredSymbol(symbol);
|
||||
if (varNode.isFunctionDeclaration()) {
|
||||
newType(symbol, FunctionNode.FUNCTION_TYPE);
|
||||
symbol.setIsFunctionDeclaration();
|
||||
}
|
||||
return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
|
||||
}
|
||||
@ -1264,12 +1265,17 @@ final class Attr extends NodeOperatorVisitor<LexicalContext> {
|
||||
|
||||
@Override
|
||||
public Node leaveCOMMARIGHT(final BinaryNode binaryNode) {
|
||||
return end(ensureSymbol(binaryNode.rhs().getType(), binaryNode));
|
||||
return leaveComma(binaryNode, binaryNode.rhs());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Node leaveCOMMALEFT(final BinaryNode binaryNode) {
|
||||
return end(ensureSymbol(binaryNode.lhs().getType(), binaryNode));
|
||||
return leaveComma(binaryNode, binaryNode.lhs());
|
||||
}
|
||||
|
||||
private Node leaveComma(final BinaryNode commaNode, final Expression effectiveExpr) {
|
||||
ensureTypeNotUnknown(effectiveExpr);
|
||||
return end(ensureSymbol(effectiveExpr.getType(), commaNode));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -412,6 +412,8 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex
|
||||
return method;
|
||||
}
|
||||
|
||||
assert !type.isUnknown();
|
||||
|
||||
/*
|
||||
* The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y"
|
||||
* or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are
|
||||
|
@ -134,6 +134,10 @@ public class MapCreator {
|
||||
flags |= Property.CAN_BE_UNDEFINED;
|
||||
}
|
||||
|
||||
if (symbol.isFunctionDeclaration()) {
|
||||
flags |= Property.IS_FUNCTION_DECLARATION;
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
|
@ -75,6 +75,8 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
public static final int IS_SPECIALIZED_PARAM = 1 << 13;
|
||||
/** Is this symbol a shared temporary? */
|
||||
public static final int IS_SHARED = 1 << 14;
|
||||
/** Is this a function declaration? */
|
||||
public static final int IS_FUNCTION_DECLARATION = 1 << 15;
|
||||
|
||||
/** Null or name identifying symbol. */
|
||||
private final String name;
|
||||
@ -359,6 +361,14 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
return (flags & IS_SHARED) == IS_SHARED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this symbol is a function declaration
|
||||
* @return true if a function declaration
|
||||
*/
|
||||
public boolean isFunctionDeclaration() {
|
||||
return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an unshared copy of a symbol. The symbol must be currently shared.
|
||||
* @param newName the name for the new symbol.
|
||||
@ -395,6 +405,16 @@ public final class Symbol implements Comparable<Symbol> {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mark this symbol as a function declaration.
|
||||
*/
|
||||
public void setIsFunctionDeclaration() {
|
||||
if (!isFunctionDeclaration()) {
|
||||
trace("SET IS FUNCTION DECLARATION");
|
||||
flags |= IS_FUNCTION_DECLARATION;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if this symbol is a variable
|
||||
* @return true if variable
|
||||
|
@ -53,19 +53,19 @@ import jdk.nashorn.internal.runtime.GlobalFunctions;
|
||||
import jdk.nashorn.internal.runtime.GlobalObject;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.NativeJavaPackage;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.PropertyDescriptor;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
import jdk.nashorn.internal.runtime.regexp.RegExpResult;
|
||||
import jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import jdk.nashorn.internal.runtime.Scope;
|
||||
import jdk.nashorn.internal.runtime.ScriptEnvironment;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.ScriptingFunctions;
|
||||
import jdk.nashorn.internal.runtime.Source;
|
||||
import jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
||||
import jdk.nashorn.internal.runtime.regexp.RegExpResult;
|
||||
import jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
/**
|
||||
|
@ -60,6 +60,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import jdk.nashorn.internal.runtime.linker.Bootstrap;
|
||||
import jdk.nashorn.internal.runtime.linker.InvokeByName;
|
||||
import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
|
||||
|
||||
/**
|
||||
* ECMA 15.2 Object objects
|
||||
@ -729,8 +730,7 @@ public final class NativeObject {
|
||||
final MethodType methodType, final Object source) {
|
||||
final GuardedInvocation inv;
|
||||
try {
|
||||
inv = linker.getGuardedInvocation(createLinkRequest(operation, methodType, source),
|
||||
Bootstrap.getLinkerServices());
|
||||
inv = NashornBeansLinker.getGuardedInvocation(linker, createLinkRequest(operation, methodType, source), Bootstrap.getLinkerServices());
|
||||
assert passesGuard(source, inv.getGuard());
|
||||
} catch(RuntimeException|Error e) {
|
||||
throw e;
|
||||
|
@ -57,10 +57,7 @@ public final class ConsString implements CharSequence {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (!flat) {
|
||||
flatten();
|
||||
}
|
||||
return (String) left;
|
||||
return (String) flattened();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -70,18 +67,19 @@ public final class ConsString implements CharSequence {
|
||||
|
||||
@Override
|
||||
public char charAt(final int index) {
|
||||
if (!flat) {
|
||||
flatten();
|
||||
}
|
||||
return left.charAt(index);
|
||||
return flattened().charAt(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence subSequence(final int start, final int end) {
|
||||
return flattened().subSequence(start, end);
|
||||
}
|
||||
|
||||
private CharSequence flattened() {
|
||||
if (!flat) {
|
||||
flatten();
|
||||
}
|
||||
return left.subSequence(start, end);
|
||||
return left;
|
||||
}
|
||||
|
||||
private void flatten() {
|
||||
|
@ -88,6 +88,9 @@ public enum JSType {
|
||||
/** JavaScript compliant conversion function from Object to number */
|
||||
public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class);
|
||||
|
||||
/** JavaScript compliant conversion function from Object to String */
|
||||
public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class);
|
||||
|
||||
/** JavaScript compliant conversion function from Object to int32 */
|
||||
public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class);
|
||||
|
||||
@ -883,7 +886,7 @@ public enum JSType {
|
||||
*/
|
||||
public static Object toJavaArray(final Object obj, final Class<?> componentType) {
|
||||
if (obj instanceof ScriptObject) {
|
||||
return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType);
|
||||
return ((ScriptObject)obj).getArray().asArrayOfType(componentType);
|
||||
} else if (obj instanceof JSObject) {
|
||||
final ArrayLikeIterator<?> itr = ArrayLikeIterator.arrayLikeIterator(obj);
|
||||
final int len = (int) itr.getLength();
|
||||
@ -908,6 +911,15 @@ public enum JSType {
|
||||
* @return converted Java array
|
||||
*/
|
||||
public static Object convertArray(final Object[] src, final Class<?> componentType) {
|
||||
if(componentType == Object.class) {
|
||||
for(int i = 0; i < src.length; ++i) {
|
||||
final Object e = src[i];
|
||||
if(e instanceof ConsString) {
|
||||
src[i] = e.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final int l = src.length;
|
||||
final Object dst = Array.newInstance(componentType, l);
|
||||
final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
|
||||
|
@ -56,33 +56,36 @@ public abstract class Property {
|
||||
public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
|
||||
|
||||
/** ECMA 8.6.1 - Is this property not writable? */
|
||||
public static final int NOT_WRITABLE = 0b0000_0000_0001;
|
||||
public static final int NOT_WRITABLE = 1 << 0;
|
||||
|
||||
/** ECMA 8.6.1 - Is this property not enumerable? */
|
||||
public static final int NOT_ENUMERABLE = 0b0000_0000_0010;
|
||||
public static final int NOT_ENUMERABLE = 1 << 1;
|
||||
|
||||
/** ECMA 8.6.1 - Is this property not configurable? */
|
||||
public static final int NOT_CONFIGURABLE = 0b0000_0000_0100;
|
||||
public static final int NOT_CONFIGURABLE = 1 << 2;
|
||||
|
||||
private static final int MODIFY_MASK = 0b0000_0000_1111;
|
||||
private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE);
|
||||
|
||||
/** Is this a spill property? See {@link AccessorProperty} */
|
||||
public static final int IS_SPILL = 0b0000_0001_0000;
|
||||
public static final int IS_SPILL = 1 << 3;
|
||||
|
||||
/** Is this a function parameter? */
|
||||
public static final int IS_PARAMETER = 0b0000_0010_0000;
|
||||
public static final int IS_PARAMETER = 1 << 4;
|
||||
|
||||
/** Is parameter accessed thru arguments? */
|
||||
public static final int HAS_ARGUMENTS = 0b0000_0100_0000;
|
||||
public static final int HAS_ARGUMENTS = 1 << 5;
|
||||
|
||||
/** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */
|
||||
public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000;
|
||||
public static final int IS_ALWAYS_OBJECT = 1 << 6;
|
||||
|
||||
/** Can this property be primitive? */
|
||||
public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000;
|
||||
public static final int CAN_BE_PRIMITIVE = 1 << 7;
|
||||
|
||||
/** Can this property be undefined? */
|
||||
public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000;
|
||||
public static final int CAN_BE_UNDEFINED = 1 << 8;
|
||||
|
||||
/* Is this a function declaration property ? */
|
||||
public static final int IS_FUNCTION_DECLARATION = 1 << 9;
|
||||
|
||||
/** Property key. */
|
||||
private final String key;
|
||||
@ -522,4 +525,12 @@ public abstract class Property {
|
||||
public boolean canBeUndefined() {
|
||||
return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether this property represents a function declaration.
|
||||
* @return whether this property is a function declaration or not.
|
||||
*/
|
||||
public boolean isFunctionDeclaration() {
|
||||
return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
|
||||
}
|
||||
}
|
||||
|
@ -226,14 +226,23 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
|
||||
|
||||
for (final Property property : properties) {
|
||||
final String key = property.getKey();
|
||||
|
||||
if (newMap.findProperty(key) == null) {
|
||||
final Property oldProp = newMap.findProperty(key);
|
||||
if (oldProp == null) {
|
||||
if (property instanceof UserAccessorProperty) {
|
||||
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
|
||||
newMap = newMap.addProperty(prop);
|
||||
} else {
|
||||
newMap = newMap.addPropertyBind((AccessorProperty)property, source);
|
||||
}
|
||||
} else {
|
||||
// See ECMA section 10.5 Declaration Binding Instantiation
|
||||
// step 5 processing each function declaration.
|
||||
if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
|
||||
if (oldProp instanceof UserAccessorProperty ||
|
||||
!(oldProp.isWritable() && oldProp.isEnumerable())) {
|
||||
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ public final class Bootstrap {
|
||||
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
|
||||
factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
|
||||
new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
|
||||
factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
|
||||
factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker());
|
||||
factory.setSyncOnRelink(true);
|
||||
final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
|
||||
if (relinkThreshold > -1) {
|
||||
|
@ -72,7 +72,7 @@ final class BoundDynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
|
||||
type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass()));
|
||||
|
||||
// Delegate to BeansLinker
|
||||
final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation(
|
||||
final GuardedInvocation inv = NashornBeansLinker.getGuardedInvocation(BeansLinker.getLinkerForClass(dynamicMethodClass),
|
||||
linkRequest.replaceArguments(newDescriptor, args), linkerServices);
|
||||
if(inv == null) {
|
||||
return null;
|
||||
|
@ -100,8 +100,9 @@ final class JavaSuperAdapterLinker implements TypeBasedGuardingDynamicLinker {
|
||||
type.changeParameterType(0, adapterClass), 0);
|
||||
|
||||
// Delegate to BeansLinker
|
||||
final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation(
|
||||
linkRequest.replaceArguments(newDescriptor, args), linkerServices);
|
||||
final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
|
||||
BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
|
||||
linkerServices);
|
||||
|
||||
final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
|
||||
if(guardedInv == null) {
|
||||
|
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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.linker;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import jdk.internal.dynalink.beans.BeansLinker;
|
||||
import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.support.Lookup;
|
||||
import jdk.nashorn.internal.runtime.ConsString;
|
||||
|
||||
/**
|
||||
* This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
|
||||
* {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
|
||||
* observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add
|
||||
* this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
|
||||
* the target method handle parameter signature is {@code Object}.
|
||||
*/
|
||||
public class NashornBeansLinker implements GuardingDynamicLinker {
|
||||
private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
|
||||
|
||||
private final BeansLinker beansLinker = new BeansLinker();
|
||||
|
||||
@Override
|
||||
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
|
||||
return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delegates to the specified linker but injects its linker services wrapper so that it will apply all special
|
||||
* conversions that this class does.
|
||||
* @param delegateLinker the linker to which the actual work is delegated to.
|
||||
* @param linkRequest the delegated link request
|
||||
* @param linkerServices the original link services that will be augmented with special conversions
|
||||
* @return the guarded invocation from the delegate, possibly augmented with special conversions
|
||||
* @throws Exception if the delegate throws an exception
|
||||
*/
|
||||
public static GuardedInvocation getGuardedInvocation(final GuardingDynamicLinker delegateLinker, final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
|
||||
return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Object exportArgument(final Object arg) {
|
||||
return arg instanceof ConsString ? arg.toString() : arg;
|
||||
}
|
||||
|
||||
private static class NashornBeansLinkerServices implements LinkerServices {
|
||||
private final LinkerServices linkerServices;
|
||||
|
||||
NashornBeansLinkerServices(final LinkerServices linkerServices) {
|
||||
this.linkerServices = linkerServices;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
|
||||
final MethodHandle typed = linkerServices.asType(handle, fromType);
|
||||
|
||||
final MethodType handleType = handle.type();
|
||||
final int paramCount = handleType.parameterCount();
|
||||
assert fromType.parameterCount() == handleType.parameterCount();
|
||||
|
||||
MethodHandle[] filters = null;
|
||||
for(int i = 0; i < paramCount; ++i) {
|
||||
if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) {
|
||||
if(filters == null) {
|
||||
filters = new MethodHandle[paramCount];
|
||||
}
|
||||
filters[i] = EXPORT_ARGUMENT;
|
||||
}
|
||||
}
|
||||
|
||||
return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
|
||||
}
|
||||
|
||||
private static boolean shouldConvert(final Class<?> handleType, final Class<?> fromType) {
|
||||
return handleType == Object.class && fromType == Object.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) {
|
||||
return linkerServices.getTypeConverter(sourceType, targetType);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canConvert(final Class<?> from, final Class<?> to) {
|
||||
return linkerServices.canConvert(from, to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
|
||||
return linkerServices.getGuardedInvocation(linkRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) {
|
||||
return linkerServices.compareConversion(sourceType, targetType1, targetType2);
|
||||
}
|
||||
}
|
||||
}
|
@ -33,14 +33,18 @@ import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.beans.BeansLinker;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.GuardingDynamicLinker;
|
||||
import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.support.Guards;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
|
||||
/**
|
||||
@ -50,7 +54,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
* setters for Java objects that couldn't be linked by any other linker, and throw appropriate ECMAScript errors for
|
||||
* attempts to invoke arbitrary Java objects as functions or constructors.
|
||||
*/
|
||||
final class NashornBottomLinker implements GuardingDynamicLinker {
|
||||
final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeConverterFactory {
|
||||
|
||||
@Override
|
||||
public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices)
|
||||
@ -129,6 +133,29 @@ final class NashornBottomLinker implements GuardingDynamicLinker {
|
||||
throw new AssertionError("unknown call type " + desc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception {
|
||||
final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType);
|
||||
return gi == null ? null : gi.asType(MH.type(targetType, sourceType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't
|
||||
* care about adapting the method signature; that's done by the invoking method. Returns conversion from Object to String/number/boolean (JS primitive types).
|
||||
* @param sourceType the source type
|
||||
* @param targetType the target type
|
||||
* @return a guarded invocation that converts from the source type to the target type.
|
||||
* @throws Exception if something goes wrong
|
||||
*/
|
||||
private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception {
|
||||
final MethodHandle mh = CONVERTERS.get(targetType);
|
||||
if (mh != null) {
|
||||
return new GuardedInvocation(mh, null);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) {
|
||||
return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc);
|
||||
}
|
||||
@ -161,6 +188,15 @@ final class NashornBottomLinker implements GuardingDynamicLinker {
|
||||
throw new AssertionError("unknown call type " + desc);
|
||||
}
|
||||
|
||||
private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>();
|
||||
static {
|
||||
CONVERTERS.put(boolean.class, JSType.TO_BOOLEAN.methodHandle());
|
||||
CONVERTERS.put(double.class, JSType.TO_NUMBER.methodHandle());
|
||||
CONVERTERS.put(int.class, JSType.TO_INTEGER.methodHandle());
|
||||
CONVERTERS.put(long.class, JSType.TO_LONG.methodHandle());
|
||||
CONVERTERS.put(String.class, JSType.TO_STRING.methodHandle());
|
||||
}
|
||||
|
||||
private static String getArgument(final LinkRequest linkRequest) {
|
||||
final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor();
|
||||
if (desc.getNameTokenCount() > 2) {
|
||||
|
@ -32,6 +32,8 @@ import java.lang.invoke.MethodHandles;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Deque;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.script.Bindings;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import jdk.internal.dynalink.linker.ConversionComparator;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
@ -40,7 +42,11 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||
import jdk.internal.dynalink.support.Guards;
|
||||
import jdk.nashorn.api.scripting.JSObject;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.api.scripting.ScriptUtils;
|
||||
import jdk.nashorn.internal.objects.NativeArray;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.runtime.JSType;
|
||||
import jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import jdk.nashorn.internal.runtime.ScriptObject;
|
||||
@ -115,9 +121,14 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
|
||||
return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
|
||||
}
|
||||
|
||||
GuardedInvocation inv = getArrayConverter(sourceType, targetType);
|
||||
if(inv != null) {
|
||||
return inv;
|
||||
final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType);
|
||||
if(arrayConverter != null) {
|
||||
return arrayConverter;
|
||||
}
|
||||
|
||||
final GuardedInvocation mirrorConverter = getMirrorConverter(sourceType, targetType);
|
||||
if(mirrorConverter != null) {
|
||||
return mirrorConverter;
|
||||
}
|
||||
|
||||
return getSamTypeConverter(sourceType, targetType);
|
||||
@ -181,6 +192,18 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
|
||||
return MH.asType(converter, converter.type().changeReturnType(type));
|
||||
}
|
||||
|
||||
private static GuardedInvocation getMirrorConverter(Class<?> sourceType, Class<?> targetType) {
|
||||
// Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but
|
||||
// it's probably better to explicitly spell out the supported target types
|
||||
if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) {
|
||||
if(ScriptObject.class.isAssignableFrom(sourceType)) {
|
||||
return new GuardedInvocation(CREATE_MIRROR, null);
|
||||
}
|
||||
return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) {
|
||||
return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) &&
|
||||
JavaAdapterFactory.isAutoConvertibleFromFunction(clazz);
|
||||
@ -235,17 +258,23 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
|
||||
return clazz == List.class || clazz == Deque.class;
|
||||
}
|
||||
|
||||
private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class));
|
||||
private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class));
|
||||
private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class));
|
||||
|
||||
private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined",
|
||||
Boolean.TYPE, Object.class);
|
||||
private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class);
|
||||
private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class);
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static boolean isNashornTypeOrUndefined(final Object obj) {
|
||||
return obj instanceof ScriptObject || obj instanceof Undefined;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static Object createMirror(final Object obj) {
|
||||
return ScriptUtils.wrap(obj);
|
||||
}
|
||||
|
||||
private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) {
|
||||
return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types));
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
|
||||
}
|
||||
|
||||
private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception {
|
||||
return staticClassLinker.getGuardedInvocation(request, linkerServices);
|
||||
return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices);
|
||||
}
|
||||
|
||||
private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class<?> receiverClass) {
|
||||
|
@ -28,10 +28,6 @@
|
||||
* @run
|
||||
*/
|
||||
|
||||
function fail(msg) {
|
||||
print(msg);
|
||||
}
|
||||
|
||||
function check(callback) {
|
||||
try {
|
||||
callback();
|
||||
|
37
nashorn/test/script/basic/JDK-8027236.js
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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-8027236: Ensure ScriptObject and ConsString aren't visible to Java
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
// Check that ConsString is flattened
|
||||
var m = new java.util.HashMap()
|
||||
var x = "f"
|
||||
x += "oo"
|
||||
m.put(x, "bar")
|
||||
print(m.get("foo"))
|
||||
// Note: many more tests are run by the JavaExportImportTest TestNG class.
|
1
nashorn/test/script/basic/JDK-8027236.js.EXPECTED
Normal file
@ -0,0 +1 @@
|
||||
bar
|
54
nashorn/test/script/basic/JDK-8027700.js
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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-8027700: function redeclaration checks missing for declaration binding instantiation
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
Object.defineProperty(this,"x", {
|
||||
value:0,
|
||||
writable:true,
|
||||
enumerable:false
|
||||
})
|
||||
|
||||
try {
|
||||
eval("function x() {}");
|
||||
fail("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
fail("TypeError expected but got " + e);
|
||||
}
|
||||
}
|
||||
|
||||
Object.defineProperty(this, "foo", { value:0 })
|
||||
try {
|
||||
eval("function foo() {}");
|
||||
fail("should have thrown TypeError");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
fail("TypeError expected but got " + e);
|
||||
}
|
||||
}
|
50
nashorn/test/script/basic/JDK-8027753.js
Normal file
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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-8027753: Support ScriptObject to JSObject, ScriptObjectMirror, Map, Bindings auto-conversion as well as explicit wrap, unwrap
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils");
|
||||
var ScriptObjectMirror = Java.type("jdk.nashorn.api.scripting.ScriptObjectMirror");
|
||||
|
||||
var obj = { foo: 34, bar: 'hello' };
|
||||
|
||||
var wrapped = ScriptUtils.wrap(obj);
|
||||
if (! (wrapped instanceof ScriptObjectMirror)) {
|
||||
fail("ScriptUtils.wrap does not return a ScriptObjectMirror");
|
||||
}
|
||||
|
||||
print("wrapped.foo = " + wrapped.foo);
|
||||
print("wrapped.bar = " + wrapped.bar);
|
||||
|
||||
var unwrapped = ScriptUtils.unwrap(wrapped);
|
||||
if (! (unwrapped instanceof Object)) {
|
||||
fail("ScriptUtils.unwrap does not return a ScriptObject");
|
||||
}
|
||||
|
||||
// same object unwrapped?
|
||||
print(unwrapped === obj);
|
3
nashorn/test/script/basic/JDK-8027753.js.EXPECTED
Normal file
@ -0,0 +1,3 @@
|
||||
wrapped.foo = 34
|
||||
wrapped.bar = hello
|
||||
true
|
35
nashorn/test/script/basic/JDK-8027828.js
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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-8027828: ClassCastException when converting return value of a Java method to boolean
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var x = new java.util.HashMap()
|
||||
x.put('test', new java.io.File('test'))
|
||||
if (x.get("test")) {
|
||||
print('Found!')
|
||||
}
|
1
nashorn/test/script/basic/JDK-8027828.js.EXPECTED
Normal file
@ -0,0 +1 @@
|
||||
Found!
|
40
nashorn/test/script/basic/JDK-8028020.js
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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-8028020: Function parameter as last expression in comma in return value causes bad type calculation
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
function f(x) {
|
||||
return 1, x
|
||||
}
|
||||
|
||||
function g(x, y) {
|
||||
return x, y
|
||||
}
|
||||
|
||||
print(f("'1, x' works."))
|
||||
print(g(42, "'x, y' works too."))
|
2
nashorn/test/script/basic/JDK-8028020.js.EXPECTED
Normal file
@ -0,0 +1,2 @@
|
||||
'1, x' works.
|
||||
'x, y' works too.
|
61
nashorn/test/script/basic/convert.js
Normal file
@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Tests for convert method of ScriptUtils.
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils");
|
||||
obj = { valueOf: function() { print("hello"); return 43.3; } };
|
||||
|
||||
// object to double
|
||||
print(ScriptUtils.convert(obj, java.lang.Number.class));
|
||||
|
||||
// array to List
|
||||
var arr = [3, 44, 23, 33];
|
||||
var list = ScriptUtils.convert(arr, java.util.List.class);
|
||||
print(list instanceof java.util.List)
|
||||
print(list);
|
||||
|
||||
// object to Map
|
||||
obj = { foo: 333, bar: 'hello'};
|
||||
var map = ScriptUtils.convert(obj, java.util.Map.class);
|
||||
print(map instanceof java.util.Map);
|
||||
for (m in map) {
|
||||
print(m + " " + map[m]);
|
||||
}
|
||||
|
||||
// object to String
|
||||
obj = { toString: function() { print("in toString"); return "foo" } };
|
||||
print(ScriptUtils.convert(obj, java.lang.String.class));
|
||||
|
||||
// array to Java array
|
||||
var jarr = ScriptUtils.convert(arr, Java.type("int[]"));
|
||||
print(jarr instanceof Java.type("int[]"));
|
||||
for (i in jarr) {
|
||||
print(jarr[i]);
|
||||
}
|
||||
|
14
nashorn/test/script/basic/convert.js.EXPECTED
Normal file
@ -0,0 +1,14 @@
|
||||
hello
|
||||
43.3
|
||||
true
|
||||
[3, 44, 23, 33]
|
||||
true
|
||||
foo 333
|
||||
bar hello
|
||||
in toString
|
||||
foo
|
||||
true
|
||||
3
|
||||
44
|
||||
23
|
||||
33
|
@ -37,13 +37,24 @@ var ByWindowType = Java.type("org.jemmy.fx.ByWindowType");
|
||||
var Scene = Java.type("javafx.scene.Scene");
|
||||
var Stage = Java.type("javafx.stage.Stage");
|
||||
var File = Java.type("java.io.File");
|
||||
var Timer = Java.type("java.util.Timer");
|
||||
var TimerTask = Java.type("java.util.TimerTask");
|
||||
var OSInfo = Java.type("sun.awt.OSInfo");
|
||||
var OSType = Java.type("sun.awt.OSInfo.OSType");
|
||||
var StringBuffer = Java.type("java.lang.StringBuffer");
|
||||
var Paint = Java.type("javafx.scene.paint.Paint");
|
||||
var Color = Java.type("javafx.scene.paint.Color");
|
||||
var Image = Java.type("javafx.scene.image.Image");
|
||||
var Canvas = Java.type("javafx.scene.canvas.Canvas");
|
||||
var BorderPane = Java.type("javafx.scene.layout.BorderPane");
|
||||
var StackPane = Java.type("javafx.scene.layout.StackPane");
|
||||
var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap");
|
||||
var Platform = Java.type("javafx.application.Platform");
|
||||
var Runnable = Java.type("java.lang.Runnable");
|
||||
var RunnableExtend = Java.extend(Runnable);
|
||||
var AnimationTimer = Java.type("javafx.animation.AnimationTimer");
|
||||
var AnimationTimerExtend = Java.extend(AnimationTimer);
|
||||
var Timer = Java.type("java.util.Timer");
|
||||
var TimerTask = Java.type("java.util.TimerTask");
|
||||
|
||||
var WAIT = 2000;
|
||||
var TESTNAME = "test";
|
||||
var fsep = System.getProperty("file.separator");
|
||||
|
||||
@ -53,14 +64,16 @@ function checkImageAndExit() {
|
||||
run: function run() {
|
||||
var tmpdir = System.getProperty("java.io.tmpdir");
|
||||
var timenow = (new Date()).getTime();
|
||||
makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png");
|
||||
var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden");
|
||||
(new File(mpdir + fsep + "screenshot" + timenow +".png")).delete();
|
||||
if (!dupImg) System.err.println("ERROR: screenshot does not match golden image");
|
||||
var scrShotTmp = tmpdir + fsep + "screenshot" + timenow +".png";
|
||||
var goldenImageDir = __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden";
|
||||
makeScreenShot(scrShotTmp);
|
||||
var dupImg = isDuplicateImages(scrShotTmp, goldenImageDir);
|
||||
(new File(scrShotTmp)).delete();
|
||||
if (!dupImg) System.err.println("ERROR: screenshot does not match the golden image");
|
||||
exit(0);
|
||||
}
|
||||
};
|
||||
raceTimer.schedule(timerTask, WAIT);
|
||||
raceTimer.schedule(timerTask, 100);
|
||||
}
|
||||
|
||||
function makeScreenShot(shootToImg) {
|
||||
@ -70,10 +83,10 @@ function makeScreenShot(shootToImg) {
|
||||
imageJemmy.save(shootToImg);
|
||||
}
|
||||
|
||||
function isDuplicateImages(file1, file2) {
|
||||
var f1 = new File(file1);
|
||||
function isDuplicateImages(screenShot, goldenDir) {
|
||||
var f1 = new File(screenShot);
|
||||
var f2;
|
||||
var sb = new StringBuffer(file2);
|
||||
var sb = new StringBuffer(goldenDir);
|
||||
if (OSInfo.getOSType() == OSType.WINDOWS) {
|
||||
f2 = new File(sb.append(fsep + "windows.png").toString());
|
||||
} else if (OSInfo.getOSType() == OSType.LINUX) {
|
||||
@ -81,8 +94,6 @@ function isDuplicateImages(file1, file2) {
|
||||
} else if (OSInfo.getOSType() == OSType.MACOSX) {
|
||||
f2 = new File(sb.append(fsep + "macosx.png").toString());
|
||||
}
|
||||
print(f1.getAbsolutePath());
|
||||
print(f2.getAbsolutePath());
|
||||
if (f1.exists() && f2.exists()) {
|
||||
var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath()));
|
||||
var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath()));
|
||||
|
@ -31,15 +31,6 @@
|
||||
|
||||
TESTNAME = "flyingimage";
|
||||
|
||||
var Image = Java.type("javafx.scene.image.Image");
|
||||
var Color = Java.type("javafx.scene.paint.Color");
|
||||
var Canvas = Java.type("javafx.scene.canvas.Canvas");
|
||||
var BorderPane = Java.type("javafx.scene.layout.BorderPane");
|
||||
var StackPane = Java.type("javafx.scene.layout.StackPane");
|
||||
var Font = Java.type("javafx.scene.text.Font");
|
||||
var FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType");
|
||||
var Text = Java.type("javafx.scene.text.Text");
|
||||
|
||||
var WIDTH = 800;
|
||||
var HEIGHT = 600;
|
||||
var canvas = new Canvas(WIDTH, HEIGHT);
|
||||
@ -48,10 +39,9 @@ function fileToURL(file) {
|
||||
}
|
||||
var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png");
|
||||
var img = new Image(imageUrl);
|
||||
var font = new Font("Arial", 16);
|
||||
var t = 0;
|
||||
var isFrameRendered = false;
|
||||
function renderFrame() {
|
||||
var t = frame;
|
||||
var gc = canvas.graphicsContext2D;
|
||||
gc.setFill(Color.web("#cccccc"));
|
||||
gc.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
@ -61,7 +51,7 @@ function renderFrame() {
|
||||
var c = 200;
|
||||
var msc= 0.5 * HEIGHT / img.height;
|
||||
var sp0 = 0.003;
|
||||
for (var h = 0; h < c; h++, t++) {
|
||||
for (var h = 0; h < c; h++) {
|
||||
gc.setTransform(1, 0, 0, 1, 0, 0);
|
||||
var yh = h / (c - 1);
|
||||
gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh));
|
||||
@ -69,15 +59,26 @@ function renderFrame() {
|
||||
gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI));
|
||||
gc.scale(sc, sc);
|
||||
gc.drawImage(img, -img.width / 2, -img.height / 2);
|
||||
}
|
||||
}
|
||||
gc.setTransform(1, 0, 0, 1, 0, 0);
|
||||
isFrameRendered = true;
|
||||
}
|
||||
var stack = new StackPane();
|
||||
var pane = new BorderPane();
|
||||
|
||||
pane.setCenter(canvas);
|
||||
stack.getChildren().add(pane);
|
||||
$STAGE.scene = new Scene(stack);
|
||||
renderFrame();
|
||||
checkImageAndExit();
|
||||
var frame = 0;
|
||||
var timer = new AnimationTimerExtend() {
|
||||
handle: function handle(now) {
|
||||
if (frame < 200) {
|
||||
renderFrame();
|
||||
frame++;
|
||||
} else {
|
||||
checkImageAndExit();
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
timer.start();
|
||||
|
||||
|
Before Width: | Height: | Size: 439 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 67 KiB |
Before Width: | Height: | Size: 9.6 KiB After Width: | Height: | Size: 67 KiB |
@ -30,13 +30,6 @@
|
||||
*/
|
||||
|
||||
TESTNAME = "kaleidoscope";
|
||||
WAIT = 4000;
|
||||
|
||||
var Paint = Java.type("javafx.scene.paint.Paint");
|
||||
var Canvas = Java.type("javafx.scene.canvas.Canvas");
|
||||
var BorderPane = Java.type("javafx.scene.layout.BorderPane");
|
||||
var StackPane = Java.type("javafx.scene.layout.StackPane");
|
||||
var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap");
|
||||
|
||||
var WIDTH = 800;
|
||||
var HEIGHT = 600;
|
||||
@ -56,26 +49,28 @@ var d=new Array(6);
|
||||
var r,e;
|
||||
var fade;
|
||||
var prv_x,prv_y,prv_x2,prv_y2;
|
||||
var isFrameRendered = false;
|
||||
|
||||
function renderFrame() {
|
||||
a=0.2*angle;
|
||||
b=0.7*angle;
|
||||
r=0;
|
||||
fade=32;
|
||||
for(var i=0;i<6;i++)
|
||||
{
|
||||
c[i]=1.0/(i+1)/2;
|
||||
d[i]=1.0/(i+1)/2;
|
||||
}
|
||||
radius=Math.round((WIDTH+HEIGHT)/8);
|
||||
e=radius*0.2;
|
||||
p_x=Math.round(WIDTH/2);
|
||||
p_y=Math.round(HEIGHT/2);
|
||||
x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
|
||||
y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
|
||||
for (i = 0; i < 800; i++) {
|
||||
anim();
|
||||
if (!isFrameRendered) {
|
||||
a=0.2*angle;
|
||||
b=0.7*angle;
|
||||
r=0;
|
||||
fade=32;
|
||||
for(var i=0;i<6;i++)
|
||||
{
|
||||
c[i]=1.0/(i+1)/2;
|
||||
d[i]=1.0/(i+1)/2;
|
||||
}
|
||||
radius=Math.round((WIDTH+HEIGHT)/8);
|
||||
e=radius*0.2;
|
||||
p_x=Math.round(WIDTH/2);
|
||||
p_y=Math.round(HEIGHT/2);
|
||||
x=(radius*c[0])*Math.cos(a*d[1])+(radius*c[2])*Math.sin(a*d[3])+(radius*c[4])*Math.sin(a*d[5]);
|
||||
y=(radius*c[5])*Math.sin(a*d[4])+(radius*c[3])*Math.cos(a*d[2])+(radius*c[1])*Math.cos(a*d[0]);
|
||||
isFrameRendered = true;
|
||||
}
|
||||
anim();
|
||||
}
|
||||
|
||||
function anim() {
|
||||
@ -154,9 +149,19 @@ function draw_line(x,y,x1,y1,x2,y2) {
|
||||
|
||||
var stack = new StackPane();
|
||||
var pane = new BorderPane();
|
||||
|
||||
pane.setCenter(canvas);
|
||||
stack.getChildren().add(pane);
|
||||
$STAGE.scene = new Scene(stack);
|
||||
renderFrame();
|
||||
checkImageAndExit();
|
||||
var frame = 0;
|
||||
var timer = new AnimationTimerExtend() {
|
||||
handle: function handle(now) {
|
||||
if (frame < 800) {
|
||||
renderFrame();
|
||||
frame++;
|
||||
} else {
|
||||
checkImageAndExit();
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
timer.start();
|
||||
|
Before Width: | Height: | Size: 181 KiB After Width: | Height: | Size: 188 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 198 KiB |
Before Width: | Height: | Size: 198 KiB After Width: | Height: | Size: 188 KiB |
222
nashorn/test/script/jfx/spread.js
Normal file
@ -0,0 +1,222 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Testing JavaFX canvas run by Nashorn.
|
||||
*
|
||||
* @test/nocompare
|
||||
* @run
|
||||
* @fork
|
||||
*/
|
||||
|
||||
TESTNAME = "spread";
|
||||
|
||||
var WIDTH = 800;
|
||||
var HEIGHT = 600;
|
||||
var canvas = new Canvas(WIDTH, HEIGHT);
|
||||
var context = canvas.graphicsContext2D;
|
||||
|
||||
/* "Spread" tech demo of canvas by Tom Theisen
|
||||
*
|
||||
* This will animate a sequence of branch structures in a canvas element.
|
||||
* Each frame, a new direction is calculated, similar to the last frame.
|
||||
*/
|
||||
|
||||
var start_width = 20; // starting width of each branch
|
||||
var frame_time = 30; // milliseconds per frame
|
||||
var straighten_factor = 0.95; // value from 0 to 1, factor applied to direction_offset every frame
|
||||
var curviness = 0.2; // amount of random direction change each frame
|
||||
|
||||
var color_speed = 0.03; // speed at which colors change when cycling is enabled
|
||||
var branch_shrink = 0.95; // factor by which branches shrink every frame
|
||||
var min_width = 1; // minimum WIDTH for branch, after which they are discontinued
|
||||
var branch_opacity = 0.4; // opacity of lines drawn
|
||||
var branch_count = 3; // branch count per tree
|
||||
var branch_bud_size = 0.5; // ratio of original branch size at which branch will split
|
||||
var branch_bud_angle = 1; // angle offset for split branch;
|
||||
|
||||
var paper; // reference to graphics context
|
||||
var branches = Object(); // linked list of active branches
|
||||
var color_styles = []; // pre-computed list of colors as styles. format: (r,g,b,a)
|
||||
var direction_offset = 0; // current direction offset in radians. this is applied to all branches.
|
||||
var frame = 0; // frame counter
|
||||
var timespent = 0; // total time spent so far, used to calculate average frame render duration
|
||||
var frameratespan; // html span element for updating performance number
|
||||
|
||||
// preferences object, contains an attribute for each user setting
|
||||
var prefs = {
|
||||
wrap: true, // causes branches reaching edge of viewable area to appear on opposite side
|
||||
fade: false, // fade existing graphics on each frame
|
||||
cycle: true, // gradually change colors each frame
|
||||
new_branch_frames: 20 // number of frames elapsed between each auto-generated tree
|
||||
};
|
||||
|
||||
// create tree at the specified position with number of branches
|
||||
function create_tree(branches, start_width, position, branch_count) {
|
||||
var angle_offset = Math.PI * 2 / branch_count;
|
||||
for (var i = 0; i < branch_count; ++i) {
|
||||
branch_add(branches, new Branch(position, angle_offset * i, start_width));
|
||||
}
|
||||
}
|
||||
|
||||
// add branch to collection
|
||||
function branch_add(branches, branch) {
|
||||
branch.next = branches.next;
|
||||
branches.next = branch;
|
||||
}
|
||||
|
||||
// get the coordinates for the position of a new tree
|
||||
// use the center of the canvas
|
||||
function get_new_tree_center(width, height) {
|
||||
return {
|
||||
x: 0.5 * width,
|
||||
y: 0.5 * height
|
||||
};
|
||||
}
|
||||
|
||||
// Branch constructor
|
||||
// position has x and y properties
|
||||
// direction is in radians
|
||||
function Branch(position, direction, width) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.width = width;
|
||||
this.original_width = width;
|
||||
this.direction = direction;
|
||||
}
|
||||
|
||||
// update position, direction and width of a particular branch
|
||||
function branch_update(branches, branch, paper) {
|
||||
paper.beginPath();
|
||||
paper.lineWidth = branch.width;
|
||||
paper.moveTo(branch.x, branch.y);
|
||||
|
||||
branch.width *= branch_shrink;
|
||||
branch.direction += direction_offset;
|
||||
branch.x += Math.cos(branch.direction) * branch.width;
|
||||
branch.y += Math.sin(branch.direction) * branch.width;
|
||||
|
||||
paper.lineTo(branch.x, branch.y);
|
||||
paper.stroke();
|
||||
|
||||
if (prefs.wrap) wrap_branch(branch, WIDTH, HEIGHT);
|
||||
|
||||
if (branch.width < branch.original_width * branch_bud_size) {
|
||||
branch.original_width *= branch_bud_size;
|
||||
branch_add(branches, new Branch(branch, branch.direction + 1, branch.original_width));
|
||||
}
|
||||
}
|
||||
|
||||
function draw_frame() {
|
||||
if (prefs.fade) {
|
||||
paper.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
}
|
||||
|
||||
if (prefs.cycle) {
|
||||
paper.setStroke(Paint.valueOf(color_styles[frame % color_styles.length]));
|
||||
}
|
||||
|
||||
if (frame++ % prefs.new_branch_frames == 0) {
|
||||
create_tree(branches, start_width, get_new_tree_center(WIDTH, HEIGHT), branch_count);
|
||||
}
|
||||
|
||||
direction_offset += (0.35 + (frame % 200) * 0.0015) * curviness - curviness / 2;
|
||||
direction_offset *= straighten_factor;
|
||||
|
||||
var branch = branches;
|
||||
var prev_branch = branches;
|
||||
while (branch = branch.next) {
|
||||
branch_update(branches, branch, paper);
|
||||
|
||||
if (branch.width < min_width) {
|
||||
// remove branch from list
|
||||
prev_branch.next = branch.next;
|
||||
}
|
||||
|
||||
prev_branch = branch;
|
||||
}
|
||||
}
|
||||
|
||||
// constrain branch position to visible area by "wrapping" from edge to edge
|
||||
function wrap_branch(branch, WIDTH, HEIGHT) {
|
||||
branch.x = positive_mod(branch.x, WIDTH);
|
||||
branch.y = positive_mod(branch.y, HEIGHT);
|
||||
}
|
||||
|
||||
// for a < 0, b > 0, javascript returns a negative number for a % b
|
||||
// this is a variant of the % operator that adds b to the result in this case
|
||||
function positive_mod(a, b) {
|
||||
// ECMA 262 11.5.3: Applying the % Operator
|
||||
// remainder operator does not convert operands to integers,
|
||||
// although negative results are possible
|
||||
|
||||
return ((a % b) + b) % b;
|
||||
}
|
||||
|
||||
// pre-compute color styles that will be used for color cycling
|
||||
function populate_colors(color_speed, color_styles, branch_opacity) {
|
||||
// used in calculation of RGB values
|
||||
var two_thirds_pi = Math.PI * 2 / 3;
|
||||
var four_thirds_pi = Math.PI * 4 / 3;
|
||||
var two_pi = Math.PI * 2;
|
||||
|
||||
// hue does represent hue, but not in the conventional HSL scheme
|
||||
for(var hue = 0; hue < two_pi; hue += color_speed) {
|
||||
var r = Math.floor(Math.sin(hue) * 128 + 128);
|
||||
var g = Math.floor(Math.sin(hue + two_thirds_pi) * 128 + 128);
|
||||
var b = Math.floor(Math.sin(hue + four_thirds_pi) * 128 + 128);
|
||||
color = "rgba(" + [r, g, b, branch_opacity].join() + ")";
|
||||
|
||||
color_styles.push(color);
|
||||
}
|
||||
}
|
||||
|
||||
// apply initial settings to canvas object
|
||||
function setup_canvas() {
|
||||
paper = canvas.graphicsContext2D;
|
||||
paper.setFill(Paint.valueOf('rgb(0, 0, 0)'));
|
||||
paper.fillRect(0, 0, WIDTH, HEIGHT);
|
||||
paper.setFill(Paint.valueOf("rgba(0, 0, 0, 0.005)"));
|
||||
paper.setStroke(Paint.valueOf("rgba(128, 128, 64, " + String(branch_opacity) + ")"));
|
||||
}
|
||||
|
||||
populate_colors(color_speed, color_styles, branch_opacity);
|
||||
setup_canvas();
|
||||
|
||||
var stack = new StackPane();
|
||||
var pane = new BorderPane();
|
||||
pane.setCenter(canvas);
|
||||
stack.getChildren().add(pane);
|
||||
$STAGE.scene = new Scene(stack);
|
||||
var timer = new AnimationTimerExtend() {
|
||||
handle: function handle(now) {
|
||||
if (frame < 200) {
|
||||
draw_frame();
|
||||
} else {
|
||||
checkImageAndExit();
|
||||
timer.stop();
|
||||
}
|
||||
}
|
||||
};
|
||||
timer.start();
|
||||
|
BIN
nashorn/test/script/jfx/spread/golden/linux.png
Normal file
After Width: | Height: | Size: 196 KiB |
BIN
nashorn/test/script/jfx/spread/golden/macosx.png
Normal file
After Width: | Height: | Size: 195 KiB |
BIN
nashorn/test/script/jfx/spread/golden/windows.png
Normal file
After Width: | Height: | Size: 196 KiB |
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (c) 2010, 2013, 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.javaaccess;
|
||||
|
||||
import static org.testng.AssertJUnit.assertEquals;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import jdk.nashorn.api.scripting.JSObject;
|
||||
import org.testng.TestNG;
|
||||
import org.testng.annotations.AfterClass;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
public class ConsStringTest {
|
||||
private static ScriptEngine e = null;
|
||||
|
||||
public static void main(final String[] args) {
|
||||
TestNG.main(args);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpClass() throws ScriptException {
|
||||
e = new ScriptEngineManager().getEngineByName("nashorn");
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void tearDownClass() {
|
||||
e = null;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsStringFlattening() throws ScriptException {
|
||||
final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
final Map<Object, Object> m = new HashMap<>();
|
||||
b.put("m", m);
|
||||
e.eval("var x = 'f'; x += 'oo'; var y = 'b'; y += 'ar'; m.put(x, y)");
|
||||
assertEquals("bar", m.get("foo"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testConsStringFromMirror() throws ScriptException {
|
||||
final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
final Map<Object, Object> m = new HashMap<>();
|
||||
e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};");
|
||||
assertEquals("foo", ((JSObject)b.get("obj")).getMember("x"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testArrayConsString() throws ScriptException {
|
||||
final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
final ArrayHolder h = new ArrayHolder();
|
||||
b.put("h", h);
|
||||
e.eval("var x = 'f'; x += 'oo'; h.array = [x];");
|
||||
assertEquals(1, h.array.length);
|
||||
assertEquals("foo", h.array[0]);
|
||||
}
|
||||
|
||||
|
||||
public static class ArrayHolder {
|
||||
private Object[] array;
|
||||
|
||||
public void setArray(Object[] array) {
|
||||
this.array = array;
|
||||
}
|
||||
|
||||
public Object[] getArray() {
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
@ -523,6 +523,18 @@ public class ScriptEngineTest {
|
||||
assertEquals(sw.toString(), println("34 true hello"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scriptObjectAutoConversionTest() throws ScriptException {
|
||||
final ScriptEngineManager m = new ScriptEngineManager();
|
||||
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||
e.eval("obj = { foo: 'hello' }");
|
||||
e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window"));
|
||||
assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
|
||||
assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello");
|
||||
assertEquals(e.eval("Window.funcMap(obj)"), "hello");
|
||||
assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
|
||||
}
|
||||
|
||||
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
|
||||
|
||||
// Returns String that would be the result of calling PrintWriter.println
|
||||
|
@ -26,6 +26,7 @@
|
||||
package jdk.nashorn.api.scripting;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.script.ScriptEngine;
|
||||
import javax.script.ScriptEngineManager;
|
||||
@ -227,4 +228,28 @@ public class ScriptObjectMirrorTest {
|
||||
final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject();
|
||||
assertTrue(newObj instanceof ScriptObjectMirror);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionTest() throws ScriptException {
|
||||
final ScriptEngineManager m = new ScriptEngineManager();
|
||||
final ScriptEngine e = m.getEngineByName("nashorn");
|
||||
final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]");
|
||||
final int[] intArr = arr.to(int[].class);
|
||||
assertEquals(intArr[0], 33);
|
||||
assertEquals(intArr[1], 45);
|
||||
assertEquals(intArr[2], 23);
|
||||
|
||||
final List<?> list = arr.to(List.class);
|
||||
assertEquals(list.get(0), 33);
|
||||
assertEquals(list.get(1), 45);
|
||||
assertEquals(list.get(2), 23);
|
||||
|
||||
ScriptObjectMirror obj = (ScriptObjectMirror)e.eval(
|
||||
"({ valueOf: function() { return 42 } })");
|
||||
assertEquals(Double.valueOf(42.0), obj.to(Double.class));
|
||||
|
||||
obj = (ScriptObjectMirror)e.eval(
|
||||
"({ toString: function() { return 'foo' } })");
|
||||
assertEquals("foo", obj.to(String.class));
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,9 @@
|
||||
|
||||
package jdk.nashorn.api.scripting;
|
||||
|
||||
import java.util.Map;
|
||||
import javax.script.Bindings;
|
||||
|
||||
public class Window {
|
||||
|
||||
private String location = "http://localhost:8080/window";
|
||||
@ -63,4 +66,20 @@ public class Window {
|
||||
System.out.println("window.setTimeout: " + delay + ", code: " + code);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static Object funcJSObject(final JSObject jsobj) {
|
||||
return jsobj.getMember("foo");
|
||||
}
|
||||
|
||||
public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) {
|
||||
return sobj.get("foo");
|
||||
}
|
||||
|
||||
public static Object funcMap(final Map<?,?> map) {
|
||||
return map.get("foo");
|
||||
}
|
||||
|
||||
public static Object funcBindings(final Bindings bindings) {
|
||||
return bindings.get("foo");
|
||||
}
|
||||
}
|
||||
|