Tue, 03 Dec 2013 14:13:15 +0400
Merge
1.1 --- a/.hgtags Sun Nov 03 07:33:34 2013 +0000 1.2 +++ b/.hgtags Tue Dec 03 14:13:15 2013 +0400 1.3 @@ -224,3 +224,7 @@ 1.4 6a4fdb3bb4e34af4c5bb8db467bb01e13b1a7e31 jdk8-b112 1.5 676cd7bf5e092356f7ee2116c8cf88cdc12377c7 jdk8-b113 1.6 79f7b79bf97b71c9b5c9b103dbdef5f269eeb86d jdk8-b114 1.7 +f0d3ac2474ee755b1180ec71bcdfa190845b17eb jdk8-b115 1.8 +0fb1a427fbf6e04c77cebbbf99b6631c664ed793 jdk8-b116 1.9 +1db3d4e4d18913e853d7bebf86816e87fda00a71 jdk8-b117 1.10 +8d014b039b44c23fa520ce20c2c27f7aa91441e9 jdk8-b118
2.1 --- a/make/build.xml Sun Nov 03 07:33:34 2013 +0000 2.2 +++ b/make/build.xml Tue Dec 03 14:13:15 2013 +0400 2.3 @@ -372,6 +372,12 @@ 2.4 2.5 <copy file="${file.reference.jfxrt.jar}" todir="dist"/> 2.6 2.7 + <condition property="jfx.prism.order" value="-Dprism.order=j2d" else=" "> 2.8 + <not> 2.9 + <os family="mac"/> 2.10 + </not> 2.11 + </condition> 2.12 + 2.13 <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes" 2.14 verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}"> 2.15 <jvmarg line="${ext.class.path}"/> 2.16 @@ -380,6 +386,7 @@ 2.17 <propertyref prefix="testjfx-test-sys-prop."/> 2.18 <mapper from="testjfx-test-sys-prop.*" to="*" type="glob"/> 2.19 </propertyset> 2.20 + <sysproperty key="test.fork.jvm.options" value="${testjfx-test-sys-prop.test.fork.jvm.options} ${jfx.prism.order}"/> 2.21 <classpath> 2.22 <pathelement path="${testjfx.run.test.classpath}"/> 2.23 </classpath>
3.1 --- a/make/project.properties Sun Nov 03 07:33:34 2013 +0000 3.2 +++ b/make/project.properties Tue Dec 03 14:13:15 2013 +0400 3.3 @@ -230,7 +230,7 @@ 3.4 ${file.reference.jemmyawtinput.jar}${path.separator}\ 3.5 ${file.reference.testng.jar}${path.separator}\ 3.6 ${nashorn.internal.tests.jar}${path.separator}\ 3.7 - ${nashorn.api.tests.jar} 3.8 + ${nashorn.api.tests.jar} 3.9 3.10 # testjfx VM options for script tests with @fork option 3.11 testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath}
4.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Sun Nov 03 07:33:34 2013 +0000 4.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Tue Dec 03 14:13:15 2013 +0400 4.3 @@ -41,6 +41,7 @@ 4.4 import java.util.Set; 4.5 import java.util.concurrent.Callable; 4.6 import javax.script.Bindings; 4.7 +import jdk.nashorn.internal.runtime.ConsString; 4.8 import jdk.nashorn.internal.runtime.Context; 4.9 import jdk.nashorn.internal.runtime.GlobalObject; 4.10 import jdk.nashorn.internal.runtime.JSType; 4.11 @@ -594,14 +595,35 @@ 4.12 } 4.13 4.14 /** 4.15 - * Make a script object mirror on given object if needed. 4.16 + * Utilitity to convert this script object to the given type. 4.17 * 4.18 - * @param obj object to be wrapped 4.19 - * @param homeGlobal global to which this object belongs 4.20 - * @return wrapped object 4.21 + * @param type destination type to convert to 4.22 + * @return converted object 4.23 */ 4.24 - public static Object wrap(final Object obj, final ScriptObject homeGlobal) { 4.25 - return (obj instanceof ScriptObject && homeGlobal != null) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj; 4.26 + public <T> T to(final Class<T> type) { 4.27 + return inGlobal(new Callable<T>() { 4.28 + @Override 4.29 + public T call() { 4.30 + return type.cast(ScriptUtils.convert(sobj, type)); 4.31 + } 4.32 + }); 4.33 + } 4.34 + 4.35 + /** 4.36 + * Make a script object mirror on given object if needed. Also converts ConsString instances to Strings. 4.37 + * 4.38 + * @param obj object to be wrapped/converted 4.39 + * @param homeGlobal global to which this object belongs. Not used for ConsStrings. 4.40 + * @return wrapped/converted object 4.41 + */ 4.42 + public static Object wrap(final Object obj, final Object homeGlobal) { 4.43 + if(obj instanceof ScriptObject) { 4.44 + return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj; 4.45 + } 4.46 + if(obj instanceof ConsString) { 4.47 + return obj.toString(); 4.48 + } 4.49 + return obj; 4.50 } 4.51 4.52 /** 4.53 @@ -611,7 +633,7 @@ 4.54 * @param homeGlobal global to which this object belongs 4.55 * @return unwrapped object 4.56 */ 4.57 - public static Object unwrap(final Object obj, final ScriptObject homeGlobal) { 4.58 + public static Object unwrap(final Object obj, final Object homeGlobal) { 4.59 if (obj instanceof ScriptObjectMirror) { 4.60 final ScriptObjectMirror mirror = (ScriptObjectMirror)obj; 4.61 return (mirror.global == homeGlobal)? mirror.sobj : obj; 4.62 @@ -627,7 +649,7 @@ 4.63 * @param homeGlobal global to which this object belongs 4.64 * @return wrapped array 4.65 */ 4.66 - public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) { 4.67 + public static Object[] wrapArray(final Object[] args, final Object homeGlobal) { 4.68 if (args == null || args.length == 0) { 4.69 return args; 4.70 } 4.71 @@ -648,7 +670,7 @@ 4.72 * @param homeGlobal global to which this object belongs 4.73 * @return unwrapped array 4.74 */ 4.75 - public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) { 4.76 + public static Object[] unwrapArray(final Object[] args, final Object homeGlobal) { 4.77 if (args == null || args.length == 0) { 4.78 return args; 4.79 }
5.1 --- a/src/jdk/nashorn/api/scripting/ScriptUtils.java Sun Nov 03 07:33:34 2013 +0000 5.2 +++ b/src/jdk/nashorn/api/scripting/ScriptUtils.java Tue Dec 03 14:13:15 2013 +0400 5.3 @@ -25,11 +25,17 @@ 5.4 5.5 package jdk.nashorn.api.scripting; 5.6 5.7 +import java.lang.invoke.MethodHandle; 5.8 +import jdk.internal.dynalink.beans.StaticClass; 5.9 +import jdk.internal.dynalink.linker.LinkerServices; 5.10 +import jdk.nashorn.internal.runtime.linker.Bootstrap; 5.11 +import jdk.nashorn.internal.runtime.Context; 5.12 import jdk.nashorn.internal.runtime.ScriptFunction; 5.13 +import jdk.nashorn.internal.runtime.ScriptObject; 5.14 import jdk.nashorn.internal.runtime.ScriptRuntime; 5.15 5.16 /** 5.17 - * Utilities that are to be called from script code 5.18 + * Utilities that are to be called from script code. 5.19 */ 5.20 public final class ScriptUtils { 5.21 private ScriptUtils() {} 5.22 @@ -71,4 +77,96 @@ 5.23 return func.makeSynchronizedFunction(sync); 5.24 } 5.25 5.26 + /** 5.27 + * Make a script object mirror on given object if needed. 5.28 + * 5.29 + * @param obj object to be wrapped 5.30 + * @return wrapped object 5.31 + */ 5.32 + public static Object wrap(final Object obj) { 5.33 + if (obj instanceof ScriptObject) { 5.34 + return ScriptObjectMirror.wrap(obj, Context.getGlobal()); 5.35 + } 5.36 + 5.37 + return obj; 5.38 + } 5.39 + 5.40 + /** 5.41 + * Unwrap a script object mirror if needed. 5.42 + * 5.43 + * @param obj object to be unwrapped 5.44 + * @return unwrapped object 5.45 + */ 5.46 + public static Object unwrap(final Object obj) { 5.47 + if (obj instanceof ScriptObjectMirror) { 5.48 + return ScriptObjectMirror.unwrap(obj, Context.getGlobal()); 5.49 + } 5.50 + 5.51 + return obj; 5.52 + } 5.53 + 5.54 + /** 5.55 + * Wrap an array of object to script object mirrors if needed. 5.56 + * 5.57 + * @param args array to be unwrapped 5.58 + * @return wrapped array 5.59 + */ 5.60 + public static Object[] wrapArray(final Object[] args) { 5.61 + if (args == null || args.length == 0) { 5.62 + return args; 5.63 + } 5.64 + 5.65 + return ScriptObjectMirror.wrapArray(args, Context.getGlobal()); 5.66 + } 5.67 + 5.68 + /** 5.69 + * Unwrap an array of script object mirrors if needed. 5.70 + * 5.71 + * @param args array to be unwrapped 5.72 + * @return unwrapped array 5.73 + */ 5.74 + public static Object[] unwrapArray(final Object[] args) { 5.75 + if (args == null || args.length == 0) { 5.76 + return args; 5.77 + } 5.78 + 5.79 + return ScriptObjectMirror.unwrapArray(args, Context.getGlobal()); 5.80 + } 5.81 + 5.82 + /** 5.83 + * Convert the given object to the given type. 5.84 + * 5.85 + * @param obj object to be converted 5.86 + * @param type destination type to convert to 5.87 + * @return converted object 5.88 + */ 5.89 + public static Object convert(final Object obj, final Object type) { 5.90 + if (obj == null) { 5.91 + return null; 5.92 + } 5.93 + 5.94 + final Class<?> clazz; 5.95 + if (type instanceof Class) { 5.96 + clazz = (Class<?>)type; 5.97 + } else if (type instanceof StaticClass) { 5.98 + clazz = ((StaticClass)type).getRepresentedClass(); 5.99 + } else { 5.100 + throw new IllegalArgumentException("type expected"); 5.101 + } 5.102 + 5.103 + final LinkerServices linker = Bootstrap.getLinkerServices(); 5.104 + final MethodHandle converter = linker.getTypeConverter(obj.getClass(), clazz); 5.105 + if (converter == null) { 5.106 + // no supported conversion! 5.107 + throw new UnsupportedOperationException("conversion not supported"); 5.108 + } 5.109 + 5.110 + try { 5.111 + return converter.invoke(obj); 5.112 + } catch (final RuntimeException | Error e) { 5.113 + throw e; 5.114 + } catch (final Throwable t) { 5.115 + throw new RuntimeException(t); 5.116 + } 5.117 + } 5.118 }
6.1 --- a/src/jdk/nashorn/internal/codegen/Attr.java Sun Nov 03 07:33:34 2013 +0000 6.2 +++ b/src/jdk/nashorn/internal/codegen/Attr.java Tue Dec 03 14:13:15 2013 +0400 6.3 @@ -271,6 +271,7 @@ 6.4 functionNode.addDeclaredSymbol(symbol); 6.5 if (varNode.isFunctionDeclaration()) { 6.6 newType(symbol, FunctionNode.FUNCTION_TYPE); 6.7 + symbol.setIsFunctionDeclaration(); 6.8 } 6.9 return varNode.setName((IdentNode)ident.setSymbol(lc, symbol)); 6.10 } 6.11 @@ -1264,12 +1265,17 @@ 6.12 6.13 @Override 6.14 public Node leaveCOMMARIGHT(final BinaryNode binaryNode) { 6.15 - return end(ensureSymbol(binaryNode.rhs().getType(), binaryNode)); 6.16 + return leaveComma(binaryNode, binaryNode.rhs()); 6.17 } 6.18 6.19 @Override 6.20 public Node leaveCOMMALEFT(final BinaryNode binaryNode) { 6.21 - return end(ensureSymbol(binaryNode.lhs().getType(), binaryNode)); 6.22 + return leaveComma(binaryNode, binaryNode.lhs()); 6.23 + } 6.24 + 6.25 + private Node leaveComma(final BinaryNode commaNode, final Expression effectiveExpr) { 6.26 + ensureTypeNotUnknown(effectiveExpr); 6.27 + return end(ensureSymbol(effectiveExpr.getType(), commaNode)); 6.28 } 6.29 6.30 @Override
7.1 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Sun Nov 03 07:33:34 2013 +0000 7.2 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Tue Dec 03 14:13:15 2013 +0400 7.3 @@ -359,8 +359,11 @@ 7.4 return load(node, node.hasType() ? node.getType() : null, false); 7.5 } 7.6 7.7 - private static boolean safeLiteral(final Expression rhs) { 7.8 - return rhs instanceof LiteralNode && !(rhs instanceof ArrayLiteralNode); 7.9 + // Test whether conversion from source to target involves a call of ES 9.1 ToPrimitive 7.10 + // with possible side effects from calling an object's toString or valueOf methods. 7.11 + private boolean noToPrimitiveConversion(final Type source, final Type target) { 7.12 + // Object to boolean conversion does not cause ToPrimitive call 7.13 + return source.isJSPrimitive() || !target.isJSPrimitive() || target.isBoolean(); 7.14 } 7.15 7.16 MethodEmitter loadBinaryOperands(final Expression lhs, final Expression rhs, final Type type) { 7.17 @@ -374,25 +377,19 @@ 7.18 // can combine a LOAD with a CONVERT operation (e.g. use a dynamic getter with the conversion target type as its 7.19 // return value). What we do here is reorder LOAD RIGHT and CONVERT LEFT when possible; it is possible only when 7.20 // we can prove that executing CONVERT LEFT can't have a side effect that changes the value of LOAD RIGHT. 7.21 - // Basically, if we know that either LEFT is not an object, or RIGHT is a constant literal, then we can do the 7.22 + // Basically, if we know that either LEFT already is a primitive value, or does not have to be converted to 7.23 + // a primitive value, or RIGHT is an expression that loads without side effects, then we can do the 7.24 // reordering and collapse LOAD/CONVERT into a single operation; otherwise we need to do the more costly 7.25 // separate operations to preserve specification semantics. 7.26 - final Type lhsType = lhs.getType(); 7.27 - if (lhsType.isObject() && !safeLiteral(rhs)) { 7.28 - // Can't reorder. Load and convert separately. 7.29 - load(lhs, lhsType, baseAlreadyOnStack); 7.30 - load(rhs, rhs.getType(), false); 7.31 - // Avoid empty SWAP, SWAP bytecode sequence if CONVERT LEFT is a no-op 7.32 - if (!lhsType.isEquivalentTo(type)) { 7.33 - method.swap(); 7.34 - method.convert(type); 7.35 - method.swap(); 7.36 - } 7.37 - method.convert(type); 7.38 - } else { 7.39 + if (noToPrimitiveConversion(lhs.getType(), type) || rhs.isLocal()) { 7.40 // Can reorder. Combine load and convert into single operations. 7.41 load(lhs, type, baseAlreadyOnStack); 7.42 load(rhs, type, false); 7.43 + } else { 7.44 + // Can't reorder. Load and convert separately. 7.45 + load(lhs, lhs.getType(), baseAlreadyOnStack); 7.46 + load(rhs, rhs.getType(), false); 7.47 + method.swap().convert(type).swap().convert(type); 7.48 } 7.49 7.50 return method; 7.51 @@ -415,6 +412,8 @@ 7.52 return method; 7.53 } 7.54 7.55 + assert !type.isUnknown(); 7.56 + 7.57 /* 7.58 * The load may be of type IdentNode, e.g. "x", AccessNode, e.g. "x.y" 7.59 * or IndexNode e.g. "x[y]". Both AccessNodes and IndexNodes are 7.60 @@ -709,6 +708,12 @@ 7.61 final CallNode.EvalArgs evalArgs = callNode.getEvalArgs(); 7.62 // load evaluated code 7.63 load(evalArgs.getCode(), Type.OBJECT); 7.64 + // load second and subsequent args for side-effect 7.65 + final List<Expression> args = callNode.getArgs(); 7.66 + final int numArgs = args.size(); 7.67 + for (int i = 1; i < numArgs; i++) { 7.68 + load(args.get(i)).pop(); 7.69 + } 7.70 // special/extra 'eval' arguments 7.71 load(evalArgs.getThis()); 7.72 method.load(evalArgs.getLocation());
8.1 --- a/src/jdk/nashorn/internal/codegen/MapCreator.java Sun Nov 03 07:33:34 2013 +0000 8.2 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java Tue Dec 03 14:13:15 2013 +0400 8.3 @@ -134,6 +134,10 @@ 8.4 flags |= Property.CAN_BE_UNDEFINED; 8.5 } 8.6 8.7 + if (symbol.isFunctionDeclaration()) { 8.8 + flags |= Property.IS_FUNCTION_DECLARATION; 8.9 + } 8.10 + 8.11 return flags; 8.12 } 8.13
9.1 --- a/src/jdk/nashorn/internal/codegen/types/Type.java Sun Nov 03 07:33:34 2013 +0000 9.2 +++ b/src/jdk/nashorn/internal/codegen/types/Type.java Tue Dec 03 14:13:15 2013 +0400 9.3 @@ -292,6 +292,16 @@ 9.4 } 9.5 9.6 /** 9.7 + * Determines whether this type represents an primitive type according to the ECMAScript specification, 9.8 + * which includes Boolean, Number, and String. 9.9 + * 9.10 + * @return true if a JavaScript primitive type, false otherwise. 9.11 + */ 9.12 + public boolean isJSPrimitive() { 9.13 + return !isObject() || isString(); 9.14 + } 9.15 + 9.16 + /** 9.17 * Determines whether a type is the BOOLEAN type 9.18 * @return true if BOOLEAN, false otherwise 9.19 */ 9.20 @@ -443,7 +453,7 @@ 9.21 } else if (type0.isArray() != type1.isArray()) { 9.22 //array and non array is always object, widest(Object[], int) NEVER returns Object[], which has most weight. that does not make sense 9.23 return Type.OBJECT; 9.24 - } else if (type0.isObject() && type1.isObject() && ((ObjectType)type0).getTypeClass() != ((ObjectType)type1).getTypeClass()) { 9.25 + } else if (type0.isObject() && type1.isObject() && type0.getTypeClass() != type1.getTypeClass()) { 9.26 // Object<type=String> and Object<type=ScriptFunction> will produce Object 9.27 // TODO: maybe find most specific common superclass? 9.28 return Type.OBJECT;
10.1 --- a/src/jdk/nashorn/internal/ir/BinaryNode.java Sun Nov 03 07:33:34 2013 +0000 10.2 +++ b/src/jdk/nashorn/internal/ir/BinaryNode.java Tue Dec 03 14:13:15 2013 +0400 10.3 @@ -90,6 +90,9 @@ 10.4 return Type.LONG; 10.5 case ASSIGN_SAR: 10.6 case ASSIGN_SHL: 10.7 + case BIT_AND: 10.8 + case BIT_OR: 10.9 + case BIT_XOR: 10.10 case ASSIGN_BIT_AND: 10.11 case ASSIGN_BIT_OR: 10.12 case ASSIGN_BIT_XOR: 10.13 @@ -170,6 +173,42 @@ 10.14 } 10.15 10.16 @Override 10.17 + public boolean isLocal() { 10.18 + switch (tokenType()) { 10.19 + case SAR: 10.20 + case SHL: 10.21 + case SHR: 10.22 + case BIT_AND: 10.23 + case BIT_OR: 10.24 + case BIT_XOR: 10.25 + case ADD: 10.26 + case DIV: 10.27 + case MOD: 10.28 + case MUL: 10.29 + case SUB: 10.30 + return lhs.isLocal() && lhs.getType().isJSPrimitive() 10.31 + && rhs.isLocal() && rhs.getType().isJSPrimitive(); 10.32 + case ASSIGN_ADD: 10.33 + case ASSIGN_BIT_AND: 10.34 + case ASSIGN_BIT_OR: 10.35 + case ASSIGN_BIT_XOR: 10.36 + case ASSIGN_DIV: 10.37 + case ASSIGN_MOD: 10.38 + case ASSIGN_MUL: 10.39 + case ASSIGN_SAR: 10.40 + case ASSIGN_SHL: 10.41 + case ASSIGN_SHR: 10.42 + case ASSIGN_SUB: 10.43 + return lhs instanceof IdentNode && lhs.isLocal() && lhs.getType().isJSPrimitive() 10.44 + && rhs.isLocal() && rhs.getType().isJSPrimitive(); 10.45 + case ASSIGN: 10.46 + return lhs instanceof IdentNode && lhs.isLocal() && rhs.isLocal(); 10.47 + default: 10.48 + return false; 10.49 + } 10.50 + } 10.51 + 10.52 + @Override 10.53 public void toString(final StringBuilder sb) { 10.54 final TokenType type = tokenType(); 10.55
11.1 --- a/src/jdk/nashorn/internal/ir/Expression.java Sun Nov 03 07:33:34 2013 +0000 11.2 +++ b/src/jdk/nashorn/internal/ir/Expression.java Tue Dec 03 14:13:15 2013 +0400 11.3 @@ -96,4 +96,16 @@ 11.4 assert hasType() : this + " has no type"; 11.5 return symbol.getSymbolType(); 11.6 } 11.7 + 11.8 + /** 11.9 + * Returns {@code true} if this expression depends exclusively on state that is constant 11.10 + * or local to the currently running function and thus inaccessible to other functions. 11.11 + * This implies that a local expression must not call any other functions (neither directly 11.12 + * nor implicitly through a getter, setter, or object-to-primitive type conversion). 11.13 + * 11.14 + * @return true if this expression does not depend on state shared with other functions. 11.15 + */ 11.16 + public boolean isLocal() { 11.17 + return false; 11.18 + } 11.19 }
12.1 --- a/src/jdk/nashorn/internal/ir/IdentNode.java Sun Nov 03 07:33:34 2013 +0000 12.2 +++ b/src/jdk/nashorn/internal/ir/IdentNode.java Tue Dec 03 14:13:15 2013 +0400 12.3 @@ -138,6 +138,11 @@ 12.4 return getName(); 12.5 } 12.6 12.7 + @Override 12.8 + public boolean isLocal() { 12.9 + return !getSymbol().isScope(); 12.10 + } 12.11 + 12.12 /** 12.13 * Check if this IdentNode is a property name 12.14 * @return true if this is a property name
13.1 --- a/src/jdk/nashorn/internal/ir/LiteralNode.java Sun Nov 03 07:33:34 2013 +0000 13.2 +++ b/src/jdk/nashorn/internal/ir/LiteralNode.java Tue Dec 03 14:13:15 2013 +0400 13.3 @@ -275,6 +275,11 @@ 13.4 public boolean isTrue() { 13.5 return JSType.toBoolean(value); 13.6 } 13.7 + 13.8 + @Override 13.9 + public boolean isLocal() { 13.10 + return true; 13.11 + } 13.12 } 13.13 13.14 @Immutable
14.1 --- a/src/jdk/nashorn/internal/ir/Symbol.java Sun Nov 03 07:33:34 2013 +0000 14.2 +++ b/src/jdk/nashorn/internal/ir/Symbol.java Tue Dec 03 14:13:15 2013 +0400 14.3 @@ -75,6 +75,8 @@ 14.4 public static final int IS_SPECIALIZED_PARAM = 1 << 13; 14.5 /** Is this symbol a shared temporary? */ 14.6 public static final int IS_SHARED = 1 << 14; 14.7 + /** Is this a function declaration? */ 14.8 + public static final int IS_FUNCTION_DECLARATION = 1 << 15; 14.9 14.10 /** Null or name identifying symbol. */ 14.11 private final String name; 14.12 @@ -360,6 +362,14 @@ 14.13 } 14.14 14.15 /** 14.16 + * Check if this symbol is a function declaration 14.17 + * @return true if a function declaration 14.18 + */ 14.19 + public boolean isFunctionDeclaration() { 14.20 + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; 14.21 + } 14.22 + 14.23 + /** 14.24 * Creates an unshared copy of a symbol. The symbol must be currently shared. 14.25 * @param newName the name for the new symbol. 14.26 * @return a new, unshared symbol. 14.27 @@ -396,6 +406,16 @@ 14.28 14.29 14.30 /** 14.31 + * Mark this symbol as a function declaration. 14.32 + */ 14.33 + public void setIsFunctionDeclaration() { 14.34 + if (!isFunctionDeclaration()) { 14.35 + trace("SET IS FUNCTION DECLARATION"); 14.36 + flags |= IS_FUNCTION_DECLARATION; 14.37 + } 14.38 + } 14.39 + 14.40 + /** 14.41 * Check if this symbol is a variable 14.42 * @return true if variable 14.43 */
15.1 --- a/src/jdk/nashorn/internal/ir/TernaryNode.java Sun Nov 03 07:33:34 2013 +0000 15.2 +++ b/src/jdk/nashorn/internal/ir/TernaryNode.java Tue Dec 03 14:13:15 2013 +0400 15.3 @@ -109,6 +109,13 @@ 15.4 } 15.5 } 15.6 15.7 + @Override 15.8 + public boolean isLocal() { 15.9 + return getTest().isLocal() 15.10 + && getTrueExpression().isLocal() 15.11 + && getFalseExpression().isLocal(); 15.12 + } 15.13 + 15.14 /** 15.15 * Get the test expression for this ternary expression, i.e. "x" in x ? y : z 15.16 * @return the test expression
16.1 --- a/src/jdk/nashorn/internal/ir/UnaryNode.java Sun Nov 03 07:33:34 2013 +0000 16.2 +++ b/src/jdk/nashorn/internal/ir/UnaryNode.java Tue Dec 03 14:13:15 2013 +0400 16.3 @@ -129,6 +129,26 @@ 16.4 } 16.5 16.6 @Override 16.7 + public boolean isLocal() { 16.8 + switch (tokenType()) { 16.9 + case NEW: 16.10 + return false; 16.11 + case ADD: 16.12 + case SUB: 16.13 + case NOT: 16.14 + case BIT_NOT: 16.15 + return rhs.isLocal() && rhs.getType().isJSPrimitive(); 16.16 + case DECPOSTFIX: 16.17 + case DECPREFIX: 16.18 + case INCPOSTFIX: 16.19 + case INCPREFIX: 16.20 + return rhs instanceof IdentNode && rhs.isLocal() && rhs.getType().isJSPrimitive(); 16.21 + default: 16.22 + return rhs.isLocal(); 16.23 + } 16.24 + } 16.25 + 16.26 + @Override 16.27 public void toString(final StringBuilder sb) { 16.28 toString(sb, new Runnable() { 16.29 @Override
17.1 --- a/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Sun Nov 03 07:33:34 2013 +0000 17.2 +++ b/src/jdk/nashorn/internal/ir/debug/ObjectSizeCalculator.java Tue Dec 03 14:13:15 2013 +0400 17.3 @@ -25,10 +25,10 @@ 17.4 17.5 package jdk.nashorn.internal.ir.debug; 17.6 17.7 -import java.lang.management.ManagementFactory; 17.8 -import java.lang.management.MemoryPoolMXBean; 17.9 import java.lang.reflect.Array; 17.10 import java.lang.reflect.Field; 17.11 +import java.lang.reflect.InvocationTargetException; 17.12 +import java.lang.reflect.Method; 17.13 import java.lang.reflect.Modifier; 17.14 import java.util.ArrayDeque; 17.15 import java.util.ArrayList; 17.16 @@ -51,9 +51,9 @@ 17.17 * switch, it can not detect 17.18 * this fact and will report incorrect sizes, as it will presume the default JVM 17.19 * behavior. 17.20 - * 17.21 - * @author Attila Szegedi 17.22 */ 17.23 + 17.24 +@SuppressWarnings("StaticNonFinalUsedInInitialization") 17.25 public class ObjectSizeCalculator { 17.26 17.27 /** 17.28 @@ -368,6 +368,29 @@ 17.29 type.getName()); 17.30 } 17.31 17.32 + // ALERT: java.lang.management is not available in compact 1. We need 17.33 + // to use reflection to soft link test memory statistics. 17.34 + 17.35 + static Class<?> managementFactory = null; 17.36 + static Class<?> memoryPoolMXBean = null; 17.37 + static Class<?> memoryUsage = null; 17.38 + static Method getMemoryPoolMXBeans = null; 17.39 + static Method getUsage = null; 17.40 + static Method getMax = null; 17.41 + static { 17.42 + try { 17.43 + managementFactory = Class.forName("java.lang.management.ManagementFactory"); 17.44 + memoryPoolMXBean = Class.forName("java.lang.management.MemoryPoolMXBean"); 17.45 + memoryUsage = Class.forName("java.lang.management.MemoryUsage"); 17.46 + 17.47 + getMemoryPoolMXBeans = managementFactory.getMethod("getMemoryPoolMXBeans"); 17.48 + getUsage = memoryPoolMXBean.getMethod("getUsage"); 17.49 + getMax = memoryUsage.getMethod("getMax"); 17.50 + } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) { 17.51 + // Pass thru, asserts when attempting to use. 17.52 + } 17.53 + } 17.54 + 17.55 /** 17.56 * Return the current memory usage 17.57 * @return current memory usage derived from system configuration 17.58 @@ -409,9 +432,33 @@ 17.59 strVmVersion.indexOf('.'))); 17.60 if (vmVersion >= 17) { 17.61 long maxMemory = 0; 17.62 - for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { 17.63 - maxMemory += mp.getUsage().getMax(); 17.64 + 17.65 + /* 17.66 + See ALERT above. The reflection code below duplicates the following 17.67 + sequence, and avoids hard coding of java.lang.management. 17.68 + 17.69 + for (MemoryPoolMXBean mp : ManagementFactory.getMemoryPoolMXBeans()) { 17.70 + maxMemory += mp.getUsage().getMax(); 17.71 + } 17.72 + */ 17.73 + 17.74 + if (getMemoryPoolMXBeans == null) { 17.75 + throw new AssertionError("java.lang.management not available in compact 1"); 17.76 } 17.77 + 17.78 + try { 17.79 + final List<?> memoryPoolMXBeans = (List<?>)getMemoryPoolMXBeans.invoke(managementFactory); 17.80 + for (final Object mp : memoryPoolMXBeans) { 17.81 + final Object usage = getUsage.invoke(mp); 17.82 + final Object max = getMax.invoke(usage); 17.83 + maxMemory += ((Long)max).longValue(); 17.84 + } 17.85 + } catch (IllegalAccessException | 17.86 + IllegalArgumentException | 17.87 + InvocationTargetException ex) { 17.88 + throw new AssertionError("java.lang.management not available in compact 1"); 17.89 + } 17.90 + 17.91 if (maxMemory < 30L * 1024 * 1024 * 1024) { 17.92 // HotSpot 17.0 and above use compressed OOPs below 30GB of RAM total 17.93 // for all memory pools (yes, including code cache).
18.1 --- a/src/jdk/nashorn/internal/objects/Global.java Sun Nov 03 07:33:34 2013 +0000 18.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Tue Dec 03 14:13:15 2013 +0400 18.3 @@ -53,19 +53,19 @@ 18.4 import jdk.nashorn.internal.runtime.GlobalObject; 18.5 import jdk.nashorn.internal.runtime.JSType; 18.6 import jdk.nashorn.internal.runtime.NativeJavaPackage; 18.7 +import jdk.nashorn.internal.runtime.PropertyDescriptor; 18.8 import jdk.nashorn.internal.runtime.PropertyMap; 18.9 +import jdk.nashorn.internal.runtime.Scope; 18.10 import jdk.nashorn.internal.runtime.ScriptEnvironment; 18.11 -import jdk.nashorn.internal.runtime.PropertyDescriptor; 18.12 -import jdk.nashorn.internal.runtime.arrays.ArrayData; 18.13 -import jdk.nashorn.internal.runtime.regexp.RegExpResult; 18.14 -import jdk.nashorn.internal.runtime.Scope; 18.15 import jdk.nashorn.internal.runtime.ScriptFunction; 18.16 import jdk.nashorn.internal.runtime.ScriptObject; 18.17 import jdk.nashorn.internal.runtime.ScriptRuntime; 18.18 import jdk.nashorn.internal.runtime.ScriptingFunctions; 18.19 import jdk.nashorn.internal.runtime.Source; 18.20 +import jdk.nashorn.internal.runtime.arrays.ArrayData; 18.21 import jdk.nashorn.internal.runtime.linker.Bootstrap; 18.22 import jdk.nashorn.internal.runtime.linker.InvokeByName; 18.23 +import jdk.nashorn.internal.runtime.regexp.RegExpResult; 18.24 import jdk.nashorn.internal.scripts.JO; 18.25 18.26 /**
19.1 --- a/src/jdk/nashorn/internal/objects/NativeObject.java Sun Nov 03 07:33:34 2013 +0000 19.2 +++ b/src/jdk/nashorn/internal/objects/NativeObject.java Tue Dec 03 14:13:15 2013 +0400 19.3 @@ -60,6 +60,7 @@ 19.4 import jdk.nashorn.internal.runtime.ScriptRuntime; 19.5 import jdk.nashorn.internal.runtime.linker.Bootstrap; 19.6 import jdk.nashorn.internal.runtime.linker.InvokeByName; 19.7 +import jdk.nashorn.internal.runtime.linker.NashornBeansLinker; 19.8 19.9 /** 19.10 * ECMA 15.2 Object objects 19.11 @@ -729,8 +730,7 @@ 19.12 final MethodType methodType, final Object source) { 19.13 final GuardedInvocation inv; 19.14 try { 19.15 - inv = linker.getGuardedInvocation(createLinkRequest(operation, methodType, source), 19.16 - Bootstrap.getLinkerServices()); 19.17 + inv = NashornBeansLinker.getGuardedInvocation(linker, createLinkRequest(operation, methodType, source), Bootstrap.getLinkerServices()); 19.18 assert passesGuard(source, inv.getGuard()); 19.19 } catch(RuntimeException|Error e) { 19.20 throw e;
20.1 --- a/src/jdk/nashorn/internal/runtime/CompiledFunctions.java Sun Nov 03 07:33:34 2013 +0000 20.2 +++ b/src/jdk/nashorn/internal/runtime/CompiledFunctions.java Tue Dec 03 14:13:15 2013 +0400 20.3 @@ -24,6 +24,7 @@ 20.4 */ 20.5 package jdk.nashorn.internal.runtime; 20.6 20.7 +import java.lang.invoke.MethodHandle; 20.8 import java.lang.invoke.MethodType; 20.9 import java.util.Iterator; 20.10 import java.util.TreeSet; 20.11 @@ -35,6 +36,8 @@ 20.12 @SuppressWarnings("serial") 20.13 final class CompiledFunctions extends TreeSet<CompiledFunction> { 20.14 20.15 + private CompiledFunction generic; 20.16 + 20.17 CompiledFunction best(final MethodType type) { 20.18 final Iterator<CompiledFunction> iter = iterator(); 20.19 while (iter.hasNext()) { 20.20 @@ -43,13 +46,10 @@ 20.21 return next; 20.22 } 20.23 } 20.24 - return mostGeneric(); 20.25 + return generic(); 20.26 } 20.27 20.28 boolean needsCallee() { 20.29 - for (final CompiledFunction inv : this) { 20.30 - assert ScriptFunctionData.needsCallee(inv.getInvoker()) == ScriptFunctionData.needsCallee(mostGeneric().getInvoker()); 20.31 - } 20.32 return ScriptFunctionData.needsCallee(mostGeneric().getInvoker()); 20.33 } 20.34 20.35 @@ -57,6 +57,48 @@ 20.36 return last(); 20.37 } 20.38 20.39 + CompiledFunction generic() { 20.40 + CompiledFunction gen = this.generic; 20.41 + if (gen == null) { 20.42 + gen = this.generic = makeGeneric(mostGeneric()); 20.43 + } 20.44 + return gen; 20.45 + } 20.46 + 20.47 + private static CompiledFunction makeGeneric(final CompiledFunction func) { 20.48 + final MethodHandle invoker = composeGenericMethod(func.getInvoker()); 20.49 + final MethodHandle constructor = func.hasConstructor() ? composeGenericMethod(func.getConstructor()) : null; 20.50 + return new CompiledFunction(invoker.type(), invoker, constructor); 20.51 + } 20.52 + 20.53 + /** 20.54 + * Takes a method handle, and returns a potentially different method handle that can be used in 20.55 + * {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}. 20.56 + * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into 20.57 + * {@code Object} as well, except for the following ones: 20.58 + * <ul> 20.59 + * <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li> 20.60 + * <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself 20.61 + * (callee) as an argument.</li> 20.62 + * </ul> 20.63 + * 20.64 + * @param mh the original method handle 20.65 + * 20.66 + * @return the new handle, conforming to the rules above. 20.67 + */ 20.68 + private static MethodHandle composeGenericMethod(final MethodHandle mh) { 20.69 + final MethodType type = mh.type(); 20.70 + final boolean isVarArg = ScriptFunctionData.isVarArg(mh); 20.71 + final int paramCount = isVarArg ? type.parameterCount() - 1 : type.parameterCount(); 20.72 + 20.73 + MethodType newType = MethodType.genericMethodType(paramCount, isVarArg); 20.74 + 20.75 + if (ScriptFunctionData.needsCallee(mh)) { 20.76 + newType = newType.changeParameterType(0, ScriptFunction.class); 20.77 + } 20.78 + return type.equals(newType) ? mh : mh.asType(newType); 20.79 + } 20.80 + 20.81 /** 20.82 * Is the given type even more specific than this entire list? That means 20.83 * we have an opportunity for more specific versions of the method
21.1 --- a/src/jdk/nashorn/internal/runtime/ConsString.java Sun Nov 03 07:33:34 2013 +0000 21.2 +++ b/src/jdk/nashorn/internal/runtime/ConsString.java Tue Dec 03 14:13:15 2013 +0400 21.3 @@ -57,10 +57,7 @@ 21.4 21.5 @Override 21.6 public String toString() { 21.7 - if (!flat) { 21.8 - flatten(); 21.9 - } 21.10 - return (String) left; 21.11 + return (String) flattened(); 21.12 } 21.13 21.14 @Override 21.15 @@ -70,18 +67,19 @@ 21.16 21.17 @Override 21.18 public char charAt(final int index) { 21.19 - if (!flat) { 21.20 - flatten(); 21.21 - } 21.22 - return left.charAt(index); 21.23 + return flattened().charAt(index); 21.24 } 21.25 21.26 @Override 21.27 public CharSequence subSequence(final int start, final int end) { 21.28 + return flattened().subSequence(start, end); 21.29 + } 21.30 + 21.31 + private CharSequence flattened() { 21.32 if (!flat) { 21.33 flatten(); 21.34 } 21.35 - return left.subSequence(start, end); 21.36 + return left; 21.37 } 21.38 21.39 private void flatten() {
22.1 --- a/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Sun Nov 03 07:33:34 2013 +0000 22.2 +++ b/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java Tue Dec 03 14:13:15 2013 +0400 22.3 @@ -40,7 +40,7 @@ 22.4 * 22.5 * @param name name 22.6 * @param arity arity 22.7 - * @param list precompiled code 22.8 + * @param functions precompiled code 22.9 * @param isStrict strict 22.10 * @param isBuiltin builtin 22.11 * @param isConstructor constructor 22.12 @@ -73,12 +73,13 @@ 22.13 } 22.14 22.15 private void addInvoker(final MethodHandle mh) { 22.16 - boolean needsCallee = needsCallee(mh); 22.17 if (isConstructor(mh)) { 22.18 - //only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor 22.19 - //is too conservative a check. However, isConstructor(mh) always implies isConstructor param 22.20 + // only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor 22.21 + // is too conservative a check. However, isConstructor(mh) always implies isConstructor param 22.22 assert isConstructor(); 22.23 - code.add(new CompiledFunction(mh.type(), MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor 22.24 + final MethodHandle invoker = MH.insertArguments(mh, 0, false); 22.25 + final MethodHandle constructor = composeConstructor(MH.insertArguments(mh, 0, true)); 22.26 + code.add(new CompiledFunction(mh.type(), invoker, constructor)); 22.27 } else { 22.28 code.add(new CompiledFunction(mh.type(), mh)); 22.29 }
23.1 --- a/src/jdk/nashorn/internal/runtime/JSType.java Sun Nov 03 07:33:34 2013 +0000 23.2 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Tue Dec 03 14:13:15 2013 +0400 23.3 @@ -88,6 +88,9 @@ 23.4 /** JavaScript compliant conversion function from Object to number */ 23.5 public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class); 23.6 23.7 + /** JavaScript compliant conversion function from Object to String */ 23.8 + public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class); 23.9 + 23.10 /** JavaScript compliant conversion function from Object to int32 */ 23.11 public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class); 23.12 23.13 @@ -883,7 +886,7 @@ 23.14 */ 23.15 public static Object toJavaArray(final Object obj, final Class<?> componentType) { 23.16 if (obj instanceof ScriptObject) { 23.17 - return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType); 23.18 + return ((ScriptObject)obj).getArray().asArrayOfType(componentType); 23.19 } else if (obj instanceof JSObject) { 23.20 final ArrayLikeIterator<?> itr = ArrayLikeIterator.arrayLikeIterator(obj); 23.21 final int len = (int) itr.getLength(); 23.22 @@ -908,6 +911,15 @@ 23.23 * @return converted Java array 23.24 */ 23.25 public static Object convertArray(final Object[] src, final Class<?> componentType) { 23.26 + if(componentType == Object.class) { 23.27 + for(int i = 0; i < src.length; ++i) { 23.28 + final Object e = src[i]; 23.29 + if(e instanceof ConsString) { 23.30 + src[i] = e.toString(); 23.31 + } 23.32 + } 23.33 + } 23.34 + 23.35 final int l = src.length; 23.36 final Object dst = Array.newInstance(componentType, l); 23.37 final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
24.1 --- a/src/jdk/nashorn/internal/runtime/Property.java Sun Nov 03 07:33:34 2013 +0000 24.2 +++ b/src/jdk/nashorn/internal/runtime/Property.java Tue Dec 03 14:13:15 2013 +0400 24.3 @@ -56,33 +56,36 @@ 24.4 public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000; 24.5 24.6 /** ECMA 8.6.1 - Is this property not writable? */ 24.7 - public static final int NOT_WRITABLE = 0b0000_0000_0001; 24.8 + public static final int NOT_WRITABLE = 1 << 0; 24.9 24.10 /** ECMA 8.6.1 - Is this property not enumerable? */ 24.11 - public static final int NOT_ENUMERABLE = 0b0000_0000_0010; 24.12 + public static final int NOT_ENUMERABLE = 1 << 1; 24.13 24.14 /** ECMA 8.6.1 - Is this property not configurable? */ 24.15 - public static final int NOT_CONFIGURABLE = 0b0000_0000_0100; 24.16 + public static final int NOT_CONFIGURABLE = 1 << 2; 24.17 24.18 - private static final int MODIFY_MASK = 0b0000_0000_1111; 24.19 + private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE); 24.20 24.21 /** Is this a spill property? See {@link AccessorProperty} */ 24.22 - public static final int IS_SPILL = 0b0000_0001_0000; 24.23 + public static final int IS_SPILL = 1 << 3; 24.24 24.25 /** Is this a function parameter? */ 24.26 - public static final int IS_PARAMETER = 0b0000_0010_0000; 24.27 + public static final int IS_PARAMETER = 1 << 4; 24.28 24.29 /** Is parameter accessed thru arguments? */ 24.30 - public static final int HAS_ARGUMENTS = 0b0000_0100_0000; 24.31 + public static final int HAS_ARGUMENTS = 1 << 5; 24.32 24.33 /** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */ 24.34 - public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000; 24.35 + public static final int IS_ALWAYS_OBJECT = 1 << 6; 24.36 24.37 /** Can this property be primitive? */ 24.38 - public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000; 24.39 + public static final int CAN_BE_PRIMITIVE = 1 << 7; 24.40 24.41 /** Can this property be undefined? */ 24.42 - public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000; 24.43 + public static final int CAN_BE_UNDEFINED = 1 << 8; 24.44 + 24.45 + /* Is this a function declaration property ? */ 24.46 + public static final int IS_FUNCTION_DECLARATION = 1 << 9; 24.47 24.48 /** Property key. */ 24.49 private final String key; 24.50 @@ -522,4 +525,12 @@ 24.51 public boolean canBeUndefined() { 24.52 return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED; 24.53 } 24.54 + 24.55 + /** 24.56 + * Check whether this property represents a function declaration. 24.57 + * @return whether this property is a function declaration or not. 24.58 + */ 24.59 + public boolean isFunctionDeclaration() { 24.60 + return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; 24.61 + } 24.62 }
25.1 --- a/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Sun Nov 03 07:33:34 2013 +0000 25.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java Tue Dec 03 14:13:15 2013 +0400 25.3 @@ -213,13 +213,13 @@ 25.4 */ 25.5 public final MethodHandle getGenericInvoker() { 25.6 ensureCodeGenerated(); 25.7 - return composeGenericMethod(code.mostGeneric().getInvoker()); 25.8 + return code.generic().getInvoker(); 25.9 } 25.10 25.11 final MethodHandle getGenericConstructor() { 25.12 ensureCodeGenerated(); 25.13 - ensureConstructor(code.mostGeneric()); 25.14 - return composeGenericMethod(code.mostGeneric().getConstructor()); 25.15 + ensureConstructor(code.generic()); 25.16 + return code.generic().getConstructor(); 25.17 } 25.18 25.19 private CompiledFunction getBest(final MethodType callSiteType) { 25.20 @@ -267,18 +267,17 @@ 25.21 } 25.22 25.23 /** 25.24 - * Compose a constructor given a primordial constructor handle 25.25 + * Compose a constructor given a primordial constructor handle. 25.26 * 25.27 - * @param ctor primordial constructor handle 25.28 - * @param needsCallee do we need to pass a callee 25.29 - * 25.30 + * @param ctor primordial constructor handle 25.31 * @return the composed constructor 25.32 */ 25.33 - protected MethodHandle composeConstructor(final MethodHandle ctor, final boolean needsCallee) { 25.34 + protected MethodHandle composeConstructor(final MethodHandle ctor) { 25.35 // If it was (callee, this, args...), permute it to (this, callee, args...). We're doing this because having 25.36 // "this" in the first argument position is what allows the elegant folded composition of 25.37 // (newFilter x constructor x allocator) further down below in the code. Also, ensure the composite constructor 25.38 // always returns Object. 25.39 + final boolean needsCallee = needsCallee(ctor); 25.40 MethodHandle composedCtor = needsCallee ? swapCalleeAndThis(ctor) : ctor; 25.41 25.42 composedCtor = changeReturnTypeToObject(composedCtor); 25.43 @@ -472,33 +471,6 @@ 25.44 } 25.45 25.46 /** 25.47 - * Takes a method handle, and returns a potentially different method handle that can be used in 25.48 - * {@code ScriptFunction#invoke(Object, Object...)} or {code ScriptFunction#construct(Object, Object...)}. 25.49 - * The returned method handle will be sure to return {@code Object}, and will have all its parameters turned into 25.50 - * {@code Object} as well, except for the following ones: 25.51 - * <ul> 25.52 - * <li>a last parameter of type {@code Object[]} which is used for vararg functions,</li> 25.53 - * <li>the first argument, which is forced to be {@link ScriptFunction}, in case the function receives itself 25.54 - * (callee) as an argument.</li> 25.55 - * </ul> 25.56 - * 25.57 - * @param mh the original method handle 25.58 - * 25.59 - * @return the new handle, conforming to the rules above. 25.60 - */ 25.61 - protected MethodHandle composeGenericMethod(final MethodHandle mh) { 25.62 - final MethodType type = mh.type(); 25.63 - MethodType newType = type.generic(); 25.64 - if (isVarArg(mh)) { 25.65 - newType = newType.changeParameterType(type.parameterCount() - 1, Object[].class); 25.66 - } 25.67 - if (needsCallee(mh)) { 25.68 - newType = newType.changeParameterType(0, ScriptFunction.class); 25.69 - } 25.70 - return type.equals(newType) ? mh : mh.asType(newType); 25.71 - } 25.72 - 25.73 - /** 25.74 * Execute this script function. 25.75 * 25.76 * @param self Target object. 25.77 @@ -508,10 +480,9 @@ 25.78 * @throws Throwable if there is an exception/error with the invocation or thrown from it 25.79 */ 25.80 Object invoke(final ScriptFunction fn, final Object self, final Object... arguments) throws Throwable { 25.81 - final MethodHandle mh = getGenericInvoker(); 25.82 - 25.83 - final Object selfObj = convertThisObject(self); 25.84 - final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; 25.85 + final MethodHandle mh = getGenericInvoker(); 25.86 + final Object selfObj = convertThisObject(self); 25.87 + final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; 25.88 25.89 if (isVarArg(mh)) { 25.90 if (needsCallee(mh)) { 25.91 @@ -531,6 +502,12 @@ 25.92 return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1)); 25.93 case 5: 25.94 return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 25.95 + case 6: 25.96 + return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3)); 25.97 + case 7: 25.98 + return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4)); 25.99 + case 8: 25.100 + return mh.invokeExact(fn, selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4), getArg(args, 5)); 25.101 default: 25.102 return mh.invokeWithArguments(withArguments(fn, selfObj, paramCount, args)); 25.103 } 25.104 @@ -545,15 +522,20 @@ 25.105 return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1)); 25.106 case 4: 25.107 return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 25.108 + case 5: 25.109 + return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3)); 25.110 + case 6: 25.111 + return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4)); 25.112 + case 7: 25.113 + return mh.invokeExact(selfObj, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4), getArg(args, 5)); 25.114 default: 25.115 return mh.invokeWithArguments(withArguments(null, selfObj, paramCount, args)); 25.116 } 25.117 } 25.118 25.119 Object construct(final ScriptFunction fn, final Object... arguments) throws Throwable { 25.120 - final MethodHandle mh = getGenericConstructor(); 25.121 - 25.122 - final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; 25.123 + final MethodHandle mh = getGenericConstructor(); 25.124 + final Object[] args = arguments == null ? ScriptRuntime.EMPTY_ARRAY : arguments; 25.125 25.126 if (isVarArg(mh)) { 25.127 if (needsCallee(mh)) { 25.128 @@ -573,6 +555,12 @@ 25.129 return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1)); 25.130 case 4: 25.131 return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1), getArg(args, 2)); 25.132 + case 5: 25.133 + return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3)); 25.134 + case 6: 25.135 + return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4)); 25.136 + case 7: 25.137 + return mh.invokeExact(fn, getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4), getArg(args, 5)); 25.138 default: 25.139 return mh.invokeWithArguments(withArguments(fn, paramCount, args)); 25.140 } 25.141 @@ -587,6 +575,12 @@ 25.142 return mh.invokeExact(getArg(args, 0), getArg(args, 1)); 25.143 case 3: 25.144 return mh.invokeExact(getArg(args, 0), getArg(args, 1), getArg(args, 2)); 25.145 + case 4: 25.146 + return mh.invokeExact(getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3)); 25.147 + case 5: 25.148 + return mh.invokeExact(getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4)); 25.149 + case 6: 25.150 + return mh.invokeExact(getArg(args, 0), getArg(args, 1), getArg(args, 2), getArg(args, 3), getArg(args, 4), getArg(args, 5)); 25.151 default: 25.152 return mh.invokeWithArguments(withArguments(null, paramCount, args)); 25.153 } 25.154 @@ -664,20 +658,21 @@ 25.155 * @return the adapted handle 25.156 */ 25.157 private static MethodHandle changeReturnTypeToObject(final MethodHandle mh) { 25.158 - return MH.asType(mh, mh.type().changeReturnType(Object.class)); 25.159 + final MethodType type = mh.type(); 25.160 + return (type.returnType() == Object.class) ? mh : MH.asType(mh, type.changeReturnType(Object.class)); 25.161 } 25.162 25.163 private void ensureConstructor(final CompiledFunction inv) { 25.164 if (!inv.hasConstructor()) { 25.165 - inv.setConstructor(composeConstructor(inv.getInvoker(), needsCallee(inv.getInvoker()))); 25.166 + inv.setConstructor(composeConstructor(inv.getInvoker())); 25.167 } 25.168 } 25.169 25.170 /** 25.171 - * Heuristic to figure out if the method handle has a callee argument. If it's type is either 25.172 - * {@code (boolean, ScriptFunction, ...)} or {@code (ScriptFunction, ...)}, then we'll assume it has 25.173 - * a callee argument. We need this as the constructor above is not passed this information, and can't just blindly 25.174 - * assume it's false (notably, it's being invoked for creation of new scripts, and scripts have scopes, therefore 25.175 + * Heuristic to figure out if the method handle has a callee argument. If it's type is 25.176 + * {@code (ScriptFunction, ...)}, then we'll assume it has a callee argument. We need this as 25.177 + * the constructor above is not passed this information, and can't just blindly assume it's false 25.178 + * (notably, it's being invoked for creation of new scripts, and scripts have scopes, therefore 25.179 * they also always receive a callee). 25.180 * 25.181 * @param mh the examined method handle 25.182 @@ -685,18 +680,8 @@ 25.183 * @return true if the method handle expects a callee, false otherwise 25.184 */ 25.185 protected static boolean needsCallee(final MethodHandle mh) { 25.186 - final MethodType type = mh.type(); 25.187 - final int length = type.parameterCount(); 25.188 - 25.189 - if (length == 0) { 25.190 - return false; 25.191 - } 25.192 - 25.193 - if (type.parameterType(0) == ScriptFunction.class) { 25.194 - return true; 25.195 - } 25.196 - 25.197 - return length > 1 && type.parameterType(0) == boolean.class && type.parameterType(1) == ScriptFunction.class; 25.198 + final MethodType type = mh.type(); 25.199 + return (type.parameterCount() > 0 && type.parameterType(0) == ScriptFunction.class); 25.200 } 25.201 25.202 /**
26.1 --- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Sun Nov 03 07:33:34 2013 +0000 26.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Tue Dec 03 14:13:15 2013 +0400 26.3 @@ -226,14 +226,23 @@ 26.4 26.5 for (final Property property : properties) { 26.6 final String key = property.getKey(); 26.7 - 26.8 - if (newMap.findProperty(key) == null) { 26.9 + final Property oldProp = newMap.findProperty(key); 26.10 + if (oldProp == null) { 26.11 if (property instanceof UserAccessorProperty) { 26.12 final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source)); 26.13 newMap = newMap.addProperty(prop); 26.14 } else { 26.15 newMap = newMap.addPropertyBind((AccessorProperty)property, source); 26.16 } 26.17 + } else { 26.18 + // See ECMA section 10.5 Declaration Binding Instantiation 26.19 + // step 5 processing each function declaration. 26.20 + if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) { 26.21 + if (oldProp instanceof UserAccessorProperty || 26.22 + !(oldProp.isWritable() && oldProp.isEnumerable())) { 26.23 + throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this)); 26.24 + } 26.25 + } 26.26 } 26.27 } 26.28
27.1 --- a/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Sun Nov 03 07:33:34 2013 +0000 27.2 +++ b/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java Tue Dec 03 14:13:15 2013 +0400 27.3 @@ -190,7 +190,7 @@ 27.4 char buffer[] = new char[1024]; 27.5 try (final InputStreamReader inputStream = new InputStreamReader(process.getErrorStream())) { 27.6 for (int length; (length = inputStream.read(buffer, 0, buffer.length)) != -1; ) { 27.7 - outBuffer.append(buffer, 0, length); 27.8 + errBuffer.append(buffer, 0, length); 27.9 } 27.10 } catch (IOException ex) { 27.11 exception[1] = ex;
28.1 --- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Sun Nov 03 07:33:34 2013 +0000 28.2 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Tue Dec 03 14:13:15 2013 +0400 28.3 @@ -63,7 +63,7 @@ 28.4 final DynamicLinkerFactory factory = new DynamicLinkerFactory(); 28.5 factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(), 28.6 new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker()); 28.7 - factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker()); 28.8 + factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker()); 28.9 factory.setSyncOnRelink(true); 28.10 final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1); 28.11 if (relinkThreshold > -1) {
29.1 --- a/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Sun Nov 03 07:33:34 2013 +0000 29.2 +++ b/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java Tue Dec 03 14:13:15 2013 +0400 29.3 @@ -72,7 +72,7 @@ 29.4 type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass())); 29.5 29.6 // Delegate to BeansLinker 29.7 - final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation( 29.8 + final GuardedInvocation inv = NashornBeansLinker.getGuardedInvocation(BeansLinker.getLinkerForClass(dynamicMethodClass), 29.9 linkRequest.replaceArguments(newDescriptor, args), linkerServices); 29.10 if(inv == null) { 29.11 return null;
30.1 --- a/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Sun Nov 03 07:33:34 2013 +0000 30.2 +++ b/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java Tue Dec 03 14:13:15 2013 +0400 30.3 @@ -100,8 +100,9 @@ 30.4 type.changeParameterType(0, adapterClass), 0); 30.5 30.6 // Delegate to BeansLinker 30.7 - final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation( 30.8 - linkRequest.replaceArguments(newDescriptor, args), linkerServices); 30.9 + final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation( 30.10 + BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args), 30.11 + linkerServices); 30.12 30.13 final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass); 30.14 if(guardedInv == null) {
31.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 31.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java Tue Dec 03 14:13:15 2013 +0400 31.3 @@ -0,0 +1,127 @@ 31.4 +/* 31.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 31.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 31.7 + * 31.8 + * This code is free software; you can redistribute it and/or modify it 31.9 + * under the terms of the GNU General Public License version 2 only, as 31.10 + * published by the Free Software Foundation. Oracle designates this 31.11 + * particular file as subject to the "Classpath" exception as provided 31.12 + * by Oracle in the LICENSE file that accompanied this code. 31.13 + * 31.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 31.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 31.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 31.17 + * version 2 for more details (a copy is included in the LICENSE file that 31.18 + * accompanied this code). 31.19 + * 31.20 + * You should have received a copy of the GNU General Public License version 31.21 + * 2 along with this work; if not, write to the Free Software Foundation, 31.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 31.23 + * 31.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 31.25 + * or visit www.oracle.com if you need additional information or have any 31.26 + * questions. 31.27 + */ 31.28 + 31.29 +package jdk.nashorn.internal.runtime.linker; 31.30 + 31.31 +import java.lang.invoke.MethodHandle; 31.32 +import java.lang.invoke.MethodHandles; 31.33 +import java.lang.invoke.MethodType; 31.34 +import jdk.internal.dynalink.beans.BeansLinker; 31.35 +import jdk.internal.dynalink.linker.ConversionComparator.Comparison; 31.36 +import jdk.internal.dynalink.linker.GuardedInvocation; 31.37 +import jdk.internal.dynalink.linker.GuardingDynamicLinker; 31.38 +import jdk.internal.dynalink.linker.LinkRequest; 31.39 +import jdk.internal.dynalink.linker.LinkerServices; 31.40 +import jdk.internal.dynalink.support.Lookup; 31.41 +import jdk.nashorn.internal.runtime.ConsString; 31.42 + 31.43 +/** 31.44 + * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified 31.45 + * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally 31.46 + * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add 31.47 + * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when 31.48 + * the target method handle parameter signature is {@code Object}. 31.49 + */ 31.50 +public class NashornBeansLinker implements GuardingDynamicLinker { 31.51 + private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class); 31.52 + 31.53 + private final BeansLinker beansLinker = new BeansLinker(); 31.54 + 31.55 + @Override 31.56 + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { 31.57 + return getGuardedInvocation(beansLinker, linkRequest, linkerServices); 31.58 + } 31.59 + 31.60 + /** 31.61 + * Delegates to the specified linker but injects its linker services wrapper so that it will apply all special 31.62 + * conversions that this class does. 31.63 + * @param delegateLinker the linker to which the actual work is delegated to. 31.64 + * @param linkRequest the delegated link request 31.65 + * @param linkerServices the original link services that will be augmented with special conversions 31.66 + * @return the guarded invocation from the delegate, possibly augmented with special conversions 31.67 + * @throws Exception if the delegate throws an exception 31.68 + */ 31.69 + public static GuardedInvocation getGuardedInvocation(final GuardingDynamicLinker delegateLinker, final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception { 31.70 + return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices)); 31.71 + } 31.72 + 31.73 + @SuppressWarnings("unused") 31.74 + private static Object exportArgument(final Object arg) { 31.75 + return arg instanceof ConsString ? arg.toString() : arg; 31.76 + } 31.77 + 31.78 + private static class NashornBeansLinkerServices implements LinkerServices { 31.79 + private final LinkerServices linkerServices; 31.80 + 31.81 + NashornBeansLinkerServices(final LinkerServices linkerServices) { 31.82 + this.linkerServices = linkerServices; 31.83 + } 31.84 + 31.85 + @Override 31.86 + public MethodHandle asType(final MethodHandle handle, final MethodType fromType) { 31.87 + final MethodHandle typed = linkerServices.asType(handle, fromType); 31.88 + 31.89 + final MethodType handleType = handle.type(); 31.90 + final int paramCount = handleType.parameterCount(); 31.91 + assert fromType.parameterCount() == handleType.parameterCount(); 31.92 + 31.93 + MethodHandle[] filters = null; 31.94 + for(int i = 0; i < paramCount; ++i) { 31.95 + if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) { 31.96 + if(filters == null) { 31.97 + filters = new MethodHandle[paramCount]; 31.98 + } 31.99 + filters[i] = EXPORT_ARGUMENT; 31.100 + } 31.101 + } 31.102 + 31.103 + return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed; 31.104 + } 31.105 + 31.106 + private static boolean shouldConvert(final Class<?> handleType, final Class<?> fromType) { 31.107 + return handleType == Object.class && fromType == Object.class; 31.108 + } 31.109 + 31.110 + @Override 31.111 + public MethodHandle getTypeConverter(final Class<?> sourceType, final Class<?> targetType) { 31.112 + return linkerServices.getTypeConverter(sourceType, targetType); 31.113 + } 31.114 + 31.115 + @Override 31.116 + public boolean canConvert(final Class<?> from, final Class<?> to) { 31.117 + return linkerServices.canConvert(from, to); 31.118 + } 31.119 + 31.120 + @Override 31.121 + public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception { 31.122 + return linkerServices.getGuardedInvocation(linkRequest); 31.123 + } 31.124 + 31.125 + @Override 31.126 + public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) { 31.127 + return linkerServices.compareConversion(sourceType, targetType1, targetType2); 31.128 + } 31.129 + } 31.130 +}
32.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Sun Nov 03 07:33:34 2013 +0000 32.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornBottomLinker.java Tue Dec 03 14:13:15 2013 +0400 32.3 @@ -33,14 +33,18 @@ 32.4 import java.lang.invoke.MethodType; 32.5 import java.lang.reflect.Method; 32.6 import java.lang.reflect.Modifier; 32.7 +import java.util.Map; 32.8 +import java.util.HashMap; 32.9 import jdk.internal.dynalink.CallSiteDescriptor; 32.10 import jdk.internal.dynalink.beans.BeansLinker; 32.11 import jdk.internal.dynalink.linker.GuardedInvocation; 32.12 import jdk.internal.dynalink.linker.GuardingDynamicLinker; 32.13 +import jdk.internal.dynalink.linker.GuardingTypeConverterFactory; 32.14 import jdk.internal.dynalink.linker.LinkRequest; 32.15 import jdk.internal.dynalink.linker.LinkerServices; 32.16 import jdk.internal.dynalink.support.Guards; 32.17 import jdk.nashorn.internal.runtime.Context; 32.18 +import jdk.nashorn.internal.runtime.JSType; 32.19 import jdk.nashorn.internal.runtime.ScriptRuntime; 32.20 32.21 /** 32.22 @@ -50,7 +54,7 @@ 32.23 * setters for Java objects that couldn't be linked by any other linker, and throw appropriate ECMAScript errors for 32.24 * attempts to invoke arbitrary Java objects as functions or constructors. 32.25 */ 32.26 -final class NashornBottomLinker implements GuardingDynamicLinker { 32.27 +final class NashornBottomLinker implements GuardingDynamicLinker, GuardingTypeConverterFactory { 32.28 32.29 @Override 32.30 public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) 32.31 @@ -129,6 +133,29 @@ 32.32 throw new AssertionError("unknown call type " + desc); 32.33 } 32.34 32.35 + @Override 32.36 + public GuardedInvocation convertToType(final Class<?> sourceType, final Class<?> targetType) throws Exception { 32.37 + final GuardedInvocation gi = convertToTypeNoCast(sourceType, targetType); 32.38 + return gi == null ? null : gi.asType(MH.type(targetType, sourceType)); 32.39 + } 32.40 + 32.41 + /** 32.42 + * Main part of the implementation of {@link GuardingTypeConverterFactory#convertToType(Class, Class)} that doesn't 32.43 + * care about adapting the method signature; that's done by the invoking method. Returns conversion from Object to String/number/boolean (JS primitive types). 32.44 + * @param sourceType the source type 32.45 + * @param targetType the target type 32.46 + * @return a guarded invocation that converts from the source type to the target type. 32.47 + * @throws Exception if something goes wrong 32.48 + */ 32.49 + private static GuardedInvocation convertToTypeNoCast(final Class<?> sourceType, final Class<?> targetType) throws Exception { 32.50 + final MethodHandle mh = CONVERTERS.get(targetType); 32.51 + if (mh != null) { 32.52 + return new GuardedInvocation(mh, null); 32.53 + } 32.54 + 32.55 + return null; 32.56 + } 32.57 + 32.58 private static GuardedInvocation getInvocation(final MethodHandle handle, final Object self, final LinkerServices linkerServices, final CallSiteDescriptor desc) { 32.59 return Bootstrap.asType(new GuardedInvocation(handle, Guards.getClassGuard(self.getClass())), linkerServices, desc); 32.60 } 32.61 @@ -161,6 +188,15 @@ 32.62 throw new AssertionError("unknown call type " + desc); 32.63 } 32.64 32.65 + private static final Map<Class<?>, MethodHandle> CONVERTERS = new HashMap<>(); 32.66 + static { 32.67 + CONVERTERS.put(boolean.class, JSType.TO_BOOLEAN.methodHandle()); 32.68 + CONVERTERS.put(double.class, JSType.TO_NUMBER.methodHandle()); 32.69 + CONVERTERS.put(int.class, JSType.TO_INTEGER.methodHandle()); 32.70 + CONVERTERS.put(long.class, JSType.TO_LONG.methodHandle()); 32.71 + CONVERTERS.put(String.class, JSType.TO_STRING.methodHandle()); 32.72 + } 32.73 + 32.74 private static String getArgument(final LinkRequest linkRequest) { 32.75 final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor(); 32.76 if (desc.getNameTokenCount() > 2) {
33.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Sun Nov 03 07:33:34 2013 +0000 33.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java Tue Dec 03 14:13:15 2013 +0400 33.3 @@ -32,6 +32,8 @@ 33.4 import java.lang.reflect.Modifier; 33.5 import java.util.Deque; 33.6 import java.util.List; 33.7 +import java.util.Map; 33.8 +import javax.script.Bindings; 33.9 import jdk.internal.dynalink.CallSiteDescriptor; 33.10 import jdk.internal.dynalink.linker.ConversionComparator; 33.11 import jdk.internal.dynalink.linker.GuardedInvocation; 33.12 @@ -40,7 +42,11 @@ 33.13 import jdk.internal.dynalink.linker.LinkerServices; 33.14 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 33.15 import jdk.internal.dynalink.support.Guards; 33.16 +import jdk.nashorn.api.scripting.JSObject; 33.17 +import jdk.nashorn.api.scripting.ScriptObjectMirror; 33.18 +import jdk.nashorn.api.scripting.ScriptUtils; 33.19 import jdk.nashorn.internal.objects.NativeArray; 33.20 +import jdk.nashorn.internal.runtime.Context; 33.21 import jdk.nashorn.internal.runtime.JSType; 33.22 import jdk.nashorn.internal.runtime.ScriptFunction; 33.23 import jdk.nashorn.internal.runtime.ScriptObject; 33.24 @@ -115,9 +121,14 @@ 33.25 return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE); 33.26 } 33.27 33.28 - GuardedInvocation inv = getArrayConverter(sourceType, targetType); 33.29 - if(inv != null) { 33.30 - return inv; 33.31 + final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType); 33.32 + if(arrayConverter != null) { 33.33 + return arrayConverter; 33.34 + } 33.35 + 33.36 + final GuardedInvocation mirrorConverter = getMirrorConverter(sourceType, targetType); 33.37 + if(mirrorConverter != null) { 33.38 + return mirrorConverter; 33.39 } 33.40 33.41 return getSamTypeConverter(sourceType, targetType); 33.42 @@ -181,6 +192,18 @@ 33.43 return MH.asType(converter, converter.type().changeReturnType(type)); 33.44 } 33.45 33.46 + private static GuardedInvocation getMirrorConverter(Class<?> sourceType, Class<?> targetType) { 33.47 + // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but 33.48 + // it's probably better to explicitly spell out the supported target types 33.49 + if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) { 33.50 + if(ScriptObject.class.isAssignableFrom(sourceType)) { 33.51 + return new GuardedInvocation(CREATE_MIRROR, null); 33.52 + } 33.53 + return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT); 33.54 + } 33.55 + return null; 33.56 + } 33.57 + 33.58 private static boolean isAutoConvertibleFromFunction(final Class<?> clazz) { 33.59 return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) && 33.60 JavaAdapterFactory.isAutoConvertibleFromFunction(clazz); 33.61 @@ -235,17 +258,23 @@ 33.62 return clazz == List.class || clazz == Deque.class; 33.63 } 33.64 33.65 + private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class)); 33.66 private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class)); 33.67 private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class)); 33.68 33.69 - private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", 33.70 - Boolean.TYPE, Object.class); 33.71 + private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class); 33.72 + private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class); 33.73 33.74 @SuppressWarnings("unused") 33.75 private static boolean isNashornTypeOrUndefined(final Object obj) { 33.76 return obj instanceof ScriptObject || obj instanceof Undefined; 33.77 } 33.78 33.79 + @SuppressWarnings("unused") 33.80 + private static Object createMirror(final Object obj) { 33.81 + return ScriptUtils.wrap(obj); 33.82 + } 33.83 + 33.84 private static MethodHandle findOwnMH(final String name, final Class<?> rtype, final Class<?>... types) { 33.85 return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types)); 33.86 }
34.1 --- a/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Sun Nov 03 07:33:34 2013 +0000 34.2 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java Tue Dec 03 14:13:15 2013 +0400 34.3 @@ -93,7 +93,7 @@ 34.4 } 34.5 34.6 private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception { 34.7 - return staticClassLinker.getGuardedInvocation(request, linkerServices); 34.8 + return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices); 34.9 } 34.10 34.11 private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class<?> receiverClass) {
35.1 --- a/test/script/basic/JDK-8015355.js Sun Nov 03 07:33:34 2013 +0000 35.2 +++ b/test/script/basic/JDK-8015355.js Tue Dec 03 14:13:15 2013 +0400 35.3 @@ -28,10 +28,6 @@ 35.4 * @run 35.5 */ 35.6 35.7 -function fail(msg) { 35.8 - print(msg); 35.9 -} 35.10 - 35.11 function check(callback) { 35.12 try { 35.13 callback();
36.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 36.2 +++ b/test/script/basic/JDK-8027042.js Tue Dec 03 14:13:15 2013 +0400 36.3 @@ -0,0 +1,58 @@ 36.4 +/* 36.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 36.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 36.7 + * 36.8 + * This code is free software; you can redistribute it and/or modify it 36.9 + * under the terms of the GNU General Public License version 2 only, as 36.10 + * published by the Free Software Foundation. 36.11 + * 36.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 36.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 36.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 36.15 + * version 2 for more details (a copy is included in the LICENSE file that 36.16 + * accompanied this code). 36.17 + * 36.18 + * You should have received a copy of the GNU General Public License version 36.19 + * 2 along with this work; if not, write to the Free Software Foundation, 36.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 36.21 + * 36.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 36.23 + * or visit www.oracle.com if you need additional information or have any 36.24 + * questions. 36.25 + */ 36.26 + 36.27 +/** 36.28 + * JDK-8027042: Evaluation order for binary operators can be improved 36.29 + * 36.30 + * @test 36.31 + * @run 36.32 + */ 36.33 + 36.34 +// var with getter side effect 36.35 +Object.defineProperty(this, "a", { get: function() {print("get a"); return 1; }}); 36.36 + 36.37 +// var with both getter and conversion side effect 36.38 +Object.defineProperty(this, "b", { get: function() {print("get b"); return {valueOf: function() { print("conv b"); return 10; }}; }}); 36.39 + 36.40 +(function() { 36.41 + // var with toPrimitive conversion side effect 36.42 + var c = {valueOf: function() { print("conv c"); return 100; }}; 36.43 + 36.44 + print(b + (c + a)); 36.45 + print(b + (c + b)); 36.46 + print(b + (a + b)); 36.47 + print(b + (b + c)); 36.48 + print(b + (b + c)); 36.49 + print(b + (c + (a - b))); 36.50 + print(b + (c + (c - b))); 36.51 + print(b + (c + (b - c))); 36.52 + print(b + (b + (a ? 2 : 3))); 36.53 + print(b + (b + (b ? 2 : 3))); 36.54 + print(b + (b + (c ? 2 : 3))); 36.55 + print(b + ((-c) + (-a))); 36.56 + print(b + ((-c) + (-b))); 36.57 + print(b + ((-c) + (-c))); 36.58 + try { print(b + new a); } catch (e) {} 36.59 + try { print(b + new b); } catch (e) {} 36.60 + try { print(b + new c); } catch (e) {} 36.61 +})();
37.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 37.2 +++ b/test/script/basic/JDK-8027042.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 37.3 @@ -0,0 +1,88 @@ 37.4 +get b 37.5 +get a 37.6 +conv c 37.7 +conv b 37.8 +111 37.9 +get b 37.10 +get b 37.11 +conv c 37.12 +conv b 37.13 +conv b 37.14 +120 37.15 +get b 37.16 +get a 37.17 +get b 37.18 +conv b 37.19 +conv b 37.20 +21 37.21 +get b 37.22 +get b 37.23 +conv b 37.24 +conv c 37.25 +conv b 37.26 +120 37.27 +get b 37.28 +get b 37.29 +conv b 37.30 +conv c 37.31 +conv b 37.32 +120 37.33 +get b 37.34 +get a 37.35 +get b 37.36 +conv b 37.37 +conv c 37.38 +conv b 37.39 +101 37.40 +get b 37.41 +get b 37.42 +conv c 37.43 +conv b 37.44 +conv c 37.45 +conv b 37.46 +200 37.47 +get b 37.48 +get b 37.49 +conv b 37.50 +conv c 37.51 +conv c 37.52 +conv b 37.53 +20 37.54 +get b 37.55 +get b 37.56 +get a 37.57 +conv b 37.58 +conv b 37.59 +22 37.60 +get b 37.61 +get b 37.62 +get b 37.63 +conv b 37.64 +conv b 37.65 +22 37.66 +get b 37.67 +get b 37.68 +conv b 37.69 +conv b 37.70 +22 37.71 +get b 37.72 +conv c 37.73 +get a 37.74 +conv b 37.75 +-91 37.76 +get b 37.77 +conv c 37.78 +get b 37.79 +conv b 37.80 +conv b 37.81 +-100 37.82 +get b 37.83 +conv c 37.84 +conv c 37.85 +conv b 37.86 +-190 37.87 +get b 37.88 +get a 37.89 +get b 37.90 +get b 37.91 +get b
38.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 38.2 +++ b/test/script/basic/JDK-8027236.js Tue Dec 03 14:13:15 2013 +0400 38.3 @@ -0,0 +1,37 @@ 38.4 +/* 38.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 38.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 38.7 + * 38.8 + * This code is free software; you can redistribute it and/or modify it 38.9 + * under the terms of the GNU General Public License version 2 only, as 38.10 + * published by the Free Software Foundation. 38.11 + * 38.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 38.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 38.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 38.15 + * version 2 for more details (a copy is included in the LICENSE file that 38.16 + * accompanied this code). 38.17 + * 38.18 + * You should have received a copy of the GNU General Public License version 38.19 + * 2 along with this work; if not, write to the Free Software Foundation, 38.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 38.21 + * 38.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 38.23 + * or visit www.oracle.com if you need additional information or have any 38.24 + * questions. 38.25 + */ 38.26 + 38.27 +/** 38.28 + * JDK-8027236: Ensure ScriptObject and ConsString aren't visible to Java 38.29 + * 38.30 + * @test 38.31 + * @run 38.32 + */ 38.33 + 38.34 +// Check that ConsString is flattened 38.35 +var m = new java.util.HashMap() 38.36 +var x = "f" 38.37 +x += "oo" 38.38 +m.put(x, "bar") 38.39 +print(m.get("foo")) 38.40 +// Note: many more tests are run by the JavaExportImportTest TestNG class.
39.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 39.2 +++ b/test/script/basic/JDK-8027236.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 39.3 @@ -0,0 +1,1 @@ 39.4 +bar
40.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 40.2 +++ b/test/script/basic/JDK-8027562.js Tue Dec 03 14:13:15 2013 +0400 40.3 @@ -0,0 +1,39 @@ 40.4 +/* 40.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 40.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 40.7 + * 40.8 + * This code is free software; you can redistribute it and/or modify it 40.9 + * under the terms of the GNU General Public License version 2 only, as 40.10 + * published by the Free Software Foundation. 40.11 + * 40.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 40.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 40.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 40.15 + * version 2 for more details (a copy is included in the LICENSE file that 40.16 + * accompanied this code). 40.17 + * 40.18 + * You should have received a copy of the GNU General Public License version 40.19 + * 2 along with this work; if not, write to the Free Software Foundation, 40.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 40.21 + * 40.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 40.23 + * or visit www.oracle.com if you need additional information or have any 40.24 + * questions. 40.25 + */ 40.26 + 40.27 +/** 40.28 + * JDK-8027562: eval should load second and subsequent arguments for side effect 40.29 + * 40.30 + * @test 40.31 + * @run 40.32 + */ 40.33 + 40.34 +try { 40.35 + eval("", x); 40.36 + fail("should have thrown ReferenceError for 'x'"); 40.37 +} catch (e) { 40.38 + if (! (e instanceof ReferenceError)) { 40.39 + fail("Expected ReferenceError, got " + e); 40.40 + } 40.41 + print(e); 40.42 +}
41.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 41.2 +++ b/test/script/basic/JDK-8027562.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 41.3 @@ -0,0 +1,1 @@ 41.4 +ReferenceError: "x" is not defined
42.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 42.2 +++ b/test/script/basic/JDK-8027700.js Tue Dec 03 14:13:15 2013 +0400 42.3 @@ -0,0 +1,54 @@ 42.4 +/* 42.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 42.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 42.7 + * 42.8 + * This code is free software; you can redistribute it and/or modify it 42.9 + * under the terms of the GNU General Public License version 2 only, as 42.10 + * published by the Free Software Foundation. 42.11 + * 42.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 42.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 42.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 42.15 + * version 2 for more details (a copy is included in the LICENSE file that 42.16 + * accompanied this code). 42.17 + * 42.18 + * You should have received a copy of the GNU General Public License version 42.19 + * 2 along with this work; if not, write to the Free Software Foundation, 42.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 42.21 + * 42.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 42.23 + * or visit www.oracle.com if you need additional information or have any 42.24 + * questions. 42.25 + */ 42.26 + 42.27 +/** 42.28 + * JDK-8027700: function redeclaration checks missing for declaration binding instantiation 42.29 + * 42.30 + * @test 42.31 + * @run 42.32 + */ 42.33 + 42.34 +Object.defineProperty(this,"x", { 42.35 + value:0, 42.36 + writable:true, 42.37 + enumerable:false 42.38 +}) 42.39 + 42.40 +try { 42.41 + eval("function x() {}"); 42.42 + fail("should have thrown TypeError"); 42.43 +} catch (e) { 42.44 + if (! (e instanceof TypeError)) { 42.45 + fail("TypeError expected but got " + e); 42.46 + } 42.47 +} 42.48 + 42.49 +Object.defineProperty(this, "foo", { value:0 }) 42.50 +try { 42.51 + eval("function foo() {}"); 42.52 + fail("should have thrown TypeError"); 42.53 +} catch (e) { 42.54 + if (! (e instanceof TypeError)) { 42.55 + fail("TypeError expected but got " + e); 42.56 + } 42.57 +}
43.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 43.2 +++ b/test/script/basic/JDK-8027753.js Tue Dec 03 14:13:15 2013 +0400 43.3 @@ -0,0 +1,50 @@ 43.4 +/* 43.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 43.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 43.7 + * 43.8 + * This code is free software; you can redistribute it and/or modify it 43.9 + * under the terms of the GNU General Public License version 2 only, as 43.10 + * published by the Free Software Foundation. 43.11 + * 43.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 43.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 43.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 43.15 + * version 2 for more details (a copy is included in the LICENSE file that 43.16 + * accompanied this code). 43.17 + * 43.18 + * You should have received a copy of the GNU General Public License version 43.19 + * 2 along with this work; if not, write to the Free Software Foundation, 43.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 43.21 + * 43.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 43.23 + * or visit www.oracle.com if you need additional information or have any 43.24 + * questions. 43.25 + */ 43.26 + 43.27 +/** 43.28 + * JDK-8027753: Support ScriptObject to JSObject, ScriptObjectMirror, Map, Bindings auto-conversion as well as explicit wrap, unwrap 43.29 + * 43.30 + * @test 43.31 + * @run 43.32 + */ 43.33 + 43.34 +var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils"); 43.35 +var ScriptObjectMirror = Java.type("jdk.nashorn.api.scripting.ScriptObjectMirror"); 43.36 + 43.37 +var obj = { foo: 34, bar: 'hello' }; 43.38 + 43.39 +var wrapped = ScriptUtils.wrap(obj); 43.40 +if (! (wrapped instanceof ScriptObjectMirror)) { 43.41 + fail("ScriptUtils.wrap does not return a ScriptObjectMirror"); 43.42 +} 43.43 + 43.44 +print("wrapped.foo = " + wrapped.foo); 43.45 +print("wrapped.bar = " + wrapped.bar); 43.46 + 43.47 +var unwrapped = ScriptUtils.unwrap(wrapped); 43.48 +if (! (unwrapped instanceof Object)) { 43.49 + fail("ScriptUtils.unwrap does not return a ScriptObject"); 43.50 +} 43.51 + 43.52 +// same object unwrapped? 43.53 +print(unwrapped === obj);
44.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 44.2 +++ b/test/script/basic/JDK-8027753.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 44.3 @@ -0,0 +1,3 @@ 44.4 +wrapped.foo = 34 44.5 +wrapped.bar = hello 44.6 +true
45.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 45.2 +++ b/test/script/basic/JDK-8027828.js Tue Dec 03 14:13:15 2013 +0400 45.3 @@ -0,0 +1,35 @@ 45.4 +/* 45.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 45.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 45.7 + * 45.8 + * This code is free software; you can redistribute it and/or modify it 45.9 + * under the terms of the GNU General Public License version 2 only, as 45.10 + * published by the Free Software Foundation. 45.11 + * 45.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 45.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 45.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 45.15 + * version 2 for more details (a copy is included in the LICENSE file that 45.16 + * accompanied this code). 45.17 + * 45.18 + * You should have received a copy of the GNU General Public License version 45.19 + * 2 along with this work; if not, write to the Free Software Foundation, 45.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 45.21 + * 45.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 45.23 + * or visit www.oracle.com if you need additional information or have any 45.24 + * questions. 45.25 + */ 45.26 + 45.27 +/** 45.28 + * JDK-8027828: ClassCastException when converting return value of a Java method to boolean 45.29 + * 45.30 + * @test 45.31 + * @run 45.32 + */ 45.33 + 45.34 +var x = new java.util.HashMap() 45.35 +x.put('test', new java.io.File('test')) 45.36 +if (x.get("test")) { 45.37 + print('Found!') 45.38 +}
46.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 46.2 +++ b/test/script/basic/JDK-8027828.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 46.3 @@ -0,0 +1,1 @@ 46.4 +Found!
47.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 47.2 +++ b/test/script/basic/JDK-8028020.js Tue Dec 03 14:13:15 2013 +0400 47.3 @@ -0,0 +1,40 @@ 47.4 +/* 47.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 47.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 47.7 + * 47.8 + * This code is free software; you can redistribute it and/or modify it 47.9 + * under the terms of the GNU General Public License version 2 only, as 47.10 + * published by the Free Software Foundation. 47.11 + * 47.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 47.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 47.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 47.15 + * version 2 for more details (a copy is included in the LICENSE file that 47.16 + * accompanied this code). 47.17 + * 47.18 + * You should have received a copy of the GNU General Public License version 47.19 + * 2 along with this work; if not, write to the Free Software Foundation, 47.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 47.21 + * 47.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 47.23 + * or visit www.oracle.com if you need additional information or have any 47.24 + * questions. 47.25 + */ 47.26 + 47.27 +/** 47.28 + * JDK-8028020: Function parameter as last expression in comma in return value causes bad type calculation 47.29 + * 47.30 + * @test 47.31 + * @run 47.32 + */ 47.33 + 47.34 +function f(x) { 47.35 + return 1, x 47.36 +} 47.37 + 47.38 +function g(x, y) { 47.39 + return x, y 47.40 +} 47.41 + 47.42 +print(f("'1, x' works.")) 47.43 +print(g(42, "'x, y' works too."))
48.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 48.2 +++ b/test/script/basic/JDK-8028020.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 48.3 @@ -0,0 +1,2 @@ 48.4 +'1, x' works. 48.5 +'x, y' works too.
49.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 49.2 +++ b/test/script/basic/convert.js Tue Dec 03 14:13:15 2013 +0400 49.3 @@ -0,0 +1,61 @@ 49.4 +/* 49.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 49.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 49.7 + * 49.8 + * This code is free software; you can redistribute it and/or modify it 49.9 + * under the terms of the GNU General Public License version 2 only, as 49.10 + * published by the Free Software Foundation. 49.11 + * 49.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 49.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 49.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 49.15 + * version 2 for more details (a copy is included in the LICENSE file that 49.16 + * accompanied this code). 49.17 + * 49.18 + * You should have received a copy of the GNU General Public License version 49.19 + * 2 along with this work; if not, write to the Free Software Foundation, 49.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 49.21 + * 49.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 49.23 + * or visit www.oracle.com if you need additional information or have any 49.24 + * questions. 49.25 + */ 49.26 + 49.27 +/** 49.28 + * Tests for convert method of ScriptUtils. 49.29 + * 49.30 + * @test 49.31 + * @run 49.32 + */ 49.33 + 49.34 +var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils"); 49.35 +obj = { valueOf: function() { print("hello"); return 43.3; } }; 49.36 + 49.37 +// object to double 49.38 +print(ScriptUtils.convert(obj, java.lang.Number.class)); 49.39 + 49.40 +// array to List 49.41 +var arr = [3, 44, 23, 33]; 49.42 +var list = ScriptUtils.convert(arr, java.util.List.class); 49.43 +print(list instanceof java.util.List) 49.44 +print(list); 49.45 + 49.46 +// object to Map 49.47 +obj = { foo: 333, bar: 'hello'}; 49.48 +var map = ScriptUtils.convert(obj, java.util.Map.class); 49.49 +print(map instanceof java.util.Map); 49.50 +for (m in map) { 49.51 + print(m + " " + map[m]); 49.52 +} 49.53 + 49.54 +// object to String 49.55 +obj = { toString: function() { print("in toString"); return "foo" } }; 49.56 +print(ScriptUtils.convert(obj, java.lang.String.class)); 49.57 + 49.58 +// array to Java array 49.59 +var jarr = ScriptUtils.convert(arr, Java.type("int[]")); 49.60 +print(jarr instanceof Java.type("int[]")); 49.61 +for (i in jarr) { 49.62 + print(jarr[i]); 49.63 +} 49.64 +
50.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 50.2 +++ b/test/script/basic/convert.js.EXPECTED Tue Dec 03 14:13:15 2013 +0400 50.3 @@ -0,0 +1,14 @@ 50.4 +hello 50.5 +43.3 50.6 +true 50.7 +[3, 44, 23, 33] 50.8 +true 50.9 +foo 333 50.10 +bar hello 50.11 +in toString 50.12 +foo 50.13 +true 50.14 +3 50.15 +44 50.16 +23 50.17 +33
51.1 --- a/test/script/jfx.js Sun Nov 03 07:33:34 2013 +0000 51.2 +++ b/test/script/jfx.js Tue Dec 03 14:13:15 2013 +0400 51.3 @@ -37,13 +37,24 @@ 51.4 var Scene = Java.type("javafx.scene.Scene"); 51.5 var Stage = Java.type("javafx.stage.Stage"); 51.6 var File = Java.type("java.io.File"); 51.7 -var Timer = Java.type("java.util.Timer"); 51.8 -var TimerTask = Java.type("java.util.TimerTask"); 51.9 var OSInfo = Java.type("sun.awt.OSInfo"); 51.10 var OSType = Java.type("sun.awt.OSInfo.OSType"); 51.11 var StringBuffer = Java.type("java.lang.StringBuffer"); 51.12 +var Paint = Java.type("javafx.scene.paint.Paint"); 51.13 +var Color = Java.type("javafx.scene.paint.Color"); 51.14 +var Image = Java.type("javafx.scene.image.Image"); 51.15 +var Canvas = Java.type("javafx.scene.canvas.Canvas"); 51.16 +var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 51.17 +var StackPane = Java.type("javafx.scene.layout.StackPane"); 51.18 +var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); 51.19 +var Platform = Java.type("javafx.application.Platform"); 51.20 +var Runnable = Java.type("java.lang.Runnable"); 51.21 +var RunnableExtend = Java.extend(Runnable); 51.22 +var AnimationTimer = Java.type("javafx.animation.AnimationTimer"); 51.23 +var AnimationTimerExtend = Java.extend(AnimationTimer); 51.24 +var Timer = Java.type("java.util.Timer"); 51.25 +var TimerTask = Java.type("java.util.TimerTask"); 51.26 51.27 -var WAIT = 2000; 51.28 var TESTNAME = "test"; 51.29 var fsep = System.getProperty("file.separator"); 51.30 51.31 @@ -53,14 +64,16 @@ 51.32 run: function run() { 51.33 var tmpdir = System.getProperty("java.io.tmpdir"); 51.34 var timenow = (new Date()).getTime(); 51.35 - makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png"); 51.36 - var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden"); 51.37 - (new File(mpdir + fsep + "screenshot" + timenow +".png")).delete(); 51.38 - if (!dupImg) System.err.println("ERROR: screenshot does not match golden image"); 51.39 + var scrShotTmp = tmpdir + fsep + "screenshot" + timenow +".png"; 51.40 + var goldenImageDir = __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden"; 51.41 + makeScreenShot(scrShotTmp); 51.42 + var dupImg = isDuplicateImages(scrShotTmp, goldenImageDir); 51.43 + (new File(scrShotTmp)).delete(); 51.44 + if (!dupImg) System.err.println("ERROR: screenshot does not match the golden image"); 51.45 exit(0); 51.46 } 51.47 }; 51.48 - raceTimer.schedule(timerTask, WAIT); 51.49 + raceTimer.schedule(timerTask, 100); 51.50 } 51.51 51.52 function makeScreenShot(shootToImg) { 51.53 @@ -70,10 +83,10 @@ 51.54 imageJemmy.save(shootToImg); 51.55 } 51.56 51.57 -function isDuplicateImages(file1, file2) { 51.58 - var f1 = new File(file1); 51.59 +function isDuplicateImages(screenShot, goldenDir) { 51.60 + var f1 = new File(screenShot); 51.61 var f2; 51.62 - var sb = new StringBuffer(file2); 51.63 + var sb = new StringBuffer(goldenDir); 51.64 if (OSInfo.getOSType() == OSType.WINDOWS) { 51.65 f2 = new File(sb.append(fsep + "windows.png").toString()); 51.66 } else if (OSInfo.getOSType() == OSType.LINUX) { 51.67 @@ -81,8 +94,6 @@ 51.68 } else if (OSInfo.getOSType() == OSType.MACOSX) { 51.69 f2 = new File(sb.append(fsep + "macosx.png").toString()); 51.70 } 51.71 - print(f1.getAbsolutePath()); 51.72 - print(f2.getAbsolutePath()); 51.73 if (f1.exists() && f2.exists()) { 51.74 var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath())); 51.75 var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath()));
52.1 --- a/test/script/jfx/flyingimage.js Sun Nov 03 07:33:34 2013 +0000 52.2 +++ b/test/script/jfx/flyingimage.js Tue Dec 03 14:13:15 2013 +0400 52.3 @@ -31,15 +31,6 @@ 52.4 52.5 TESTNAME = "flyingimage"; 52.6 52.7 -var Image = Java.type("javafx.scene.image.Image"); 52.8 -var Color = Java.type("javafx.scene.paint.Color"); 52.9 -var Canvas = Java.type("javafx.scene.canvas.Canvas"); 52.10 -var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 52.11 -var StackPane = Java.type("javafx.scene.layout.StackPane"); 52.12 -var Font = Java.type("javafx.scene.text.Font"); 52.13 -var FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType"); 52.14 -var Text = Java.type("javafx.scene.text.Text"); 52.15 - 52.16 var WIDTH = 800; 52.17 var HEIGHT = 600; 52.18 var canvas = new Canvas(WIDTH, HEIGHT); 52.19 @@ -48,10 +39,9 @@ 52.20 } 52.21 var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png"); 52.22 var img = new Image(imageUrl); 52.23 -var font = new Font("Arial", 16); 52.24 -var t = 0; 52.25 var isFrameRendered = false; 52.26 function renderFrame() { 52.27 + var t = frame; 52.28 var gc = canvas.graphicsContext2D; 52.29 gc.setFill(Color.web("#cccccc")); 52.30 gc.fillRect(0, 0, WIDTH, HEIGHT); 52.31 @@ -61,7 +51,7 @@ 52.32 var c = 200; 52.33 var msc= 0.5 * HEIGHT / img.height; 52.34 var sp0 = 0.003; 52.35 - for (var h = 0; h < c; h++, t++) { 52.36 + for (var h = 0; h < c; h++) { 52.37 gc.setTransform(1, 0, 0, 1, 0, 0); 52.38 var yh = h / (c - 1); 52.39 gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh)); 52.40 @@ -69,15 +59,26 @@ 52.41 gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI)); 52.42 gc.scale(sc, sc); 52.43 gc.drawImage(img, -img.width / 2, -img.height / 2); 52.44 - } 52.45 + } 52.46 gc.setTransform(1, 0, 0, 1, 0, 0); 52.47 isFrameRendered = true; 52.48 } 52.49 var stack = new StackPane(); 52.50 var pane = new BorderPane(); 52.51 - 52.52 pane.setCenter(canvas); 52.53 stack.getChildren().add(pane); 52.54 $STAGE.scene = new Scene(stack); 52.55 -renderFrame(); 52.56 -checkImageAndExit(); 52.57 +var frame = 0; 52.58 +var timer = new AnimationTimerExtend() { 52.59 + handle: function handle(now) { 52.60 + if (frame < 200) { 52.61 + renderFrame(); 52.62 + frame++; 52.63 + } else { 52.64 + checkImageAndExit(); 52.65 + timer.stop(); 52.66 + } 52.67 + } 52.68 +}; 52.69 +timer.start(); 52.70 +
53.1 Binary file test/script/jfx/flyingimage/flyingimage.png has changed
54.1 Binary file test/script/jfx/flyingimage/golden/linux.png has changed
55.1 Binary file test/script/jfx/flyingimage/golden/macosx.png has changed
56.1 Binary file test/script/jfx/flyingimage/golden/windows.png has changed
57.1 --- a/test/script/jfx/kaleidoscope.js Sun Nov 03 07:33:34 2013 +0000 57.2 +++ b/test/script/jfx/kaleidoscope.js Tue Dec 03 14:13:15 2013 +0400 57.3 @@ -30,13 +30,6 @@ 57.4 */ 57.5 57.6 TESTNAME = "kaleidoscope"; 57.7 -WAIT = 4000; 57.8 - 57.9 -var Paint = Java.type("javafx.scene.paint.Paint"); 57.10 -var Canvas = Java.type("javafx.scene.canvas.Canvas"); 57.11 -var BorderPane = Java.type("javafx.scene.layout.BorderPane"); 57.12 -var StackPane = Java.type("javafx.scene.layout.StackPane"); 57.13 -var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap"); 57.14 57.15 var WIDTH = 800; 57.16 var HEIGHT = 600; 57.17 @@ -56,26 +49,28 @@ 57.18 var r,e; 57.19 var fade; 57.20 var prv_x,prv_y,prv_x2,prv_y2; 57.21 +var isFrameRendered = false; 57.22 57.23 function renderFrame() { 57.24 - a=0.2*angle; 57.25 - b=0.7*angle; 57.26 - r=0; 57.27 - fade=32; 57.28 - for(var i=0;i<6;i++) 57.29 - { 57.30 - c[i]=1.0/(i+1)/2; 57.31 - d[i]=1.0/(i+1)/2; 57.32 - } 57.33 - radius=Math.round((WIDTH+HEIGHT)/8); 57.34 - e=radius*0.2; 57.35 - p_x=Math.round(WIDTH/2); 57.36 - p_y=Math.round(HEIGHT/2); 57.37 - 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]); 57.38 - 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]); 57.39 - for (i = 0; i < 800; i++) { 57.40 - anim(); 57.41 + if (!isFrameRendered) { 57.42 + a=0.2*angle; 57.43 + b=0.7*angle; 57.44 + r=0; 57.45 + fade=32; 57.46 + for(var i=0;i<6;i++) 57.47 + { 57.48 + c[i]=1.0/(i+1)/2; 57.49 + d[i]=1.0/(i+1)/2; 57.50 + } 57.51 + radius=Math.round((WIDTH+HEIGHT)/8); 57.52 + e=radius*0.2; 57.53 + p_x=Math.round(WIDTH/2); 57.54 + p_y=Math.round(HEIGHT/2); 57.55 + 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]); 57.56 + 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]); 57.57 + isFrameRendered = true; 57.58 } 57.59 + anim(); 57.60 } 57.61 57.62 function anim() { 57.63 @@ -154,9 +149,19 @@ 57.64 57.65 var stack = new StackPane(); 57.66 var pane = new BorderPane(); 57.67 - 57.68 pane.setCenter(canvas); 57.69 stack.getChildren().add(pane); 57.70 $STAGE.scene = new Scene(stack); 57.71 -renderFrame(); 57.72 -checkImageAndExit(); 57.73 \ No newline at end of file 57.74 +var frame = 0; 57.75 +var timer = new AnimationTimerExtend() { 57.76 + handle: function handle(now) { 57.77 + if (frame < 800) { 57.78 + renderFrame(); 57.79 + frame++; 57.80 + } else { 57.81 + checkImageAndExit(); 57.82 + timer.stop(); 57.83 + } 57.84 + } 57.85 +}; 57.86 +timer.start();
58.1 Binary file test/script/jfx/kaleidoscope/golden/linux.png has changed
59.1 Binary file test/script/jfx/kaleidoscope/golden/macosx.png has changed
60.1 Binary file test/script/jfx/kaleidoscope/golden/windows.png has changed
61.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 61.2 +++ b/test/script/jfx/spread.js Tue Dec 03 14:13:15 2013 +0400 61.3 @@ -0,0 +1,222 @@ 61.4 +/* 61.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 61.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 61.7 + * 61.8 + * This code is free software; you can redistribute it and/or modify it 61.9 + * under the terms of the GNU General Public License version 2 only, as 61.10 + * published by the Free Software Foundation. 61.11 + * 61.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 61.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 61.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 61.15 + * version 2 for more details (a copy is included in the LICENSE file that 61.16 + * accompanied this code). 61.17 + * 61.18 + * You should have received a copy of the GNU General Public License version 61.19 + * 2 along with this work; if not, write to the Free Software Foundation, 61.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 61.21 + * 61.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 61.23 + * or visit www.oracle.com if you need additional information or have any 61.24 + * questions. 61.25 + */ 61.26 + 61.27 +/** 61.28 + * Testing JavaFX canvas run by Nashorn. 61.29 + * 61.30 + * @test/nocompare 61.31 + * @run 61.32 + * @fork 61.33 + */ 61.34 + 61.35 +TESTNAME = "spread"; 61.36 + 61.37 +var WIDTH = 800; 61.38 +var HEIGHT = 600; 61.39 +var canvas = new Canvas(WIDTH, HEIGHT); 61.40 +var context = canvas.graphicsContext2D; 61.41 + 61.42 +/* "Spread" tech demo of canvas by Tom Theisen 61.43 + * 61.44 + * This will animate a sequence of branch structures in a canvas element. 61.45 + * Each frame, a new direction is calculated, similar to the last frame. 61.46 + */ 61.47 + 61.48 +var start_width = 20; // starting width of each branch 61.49 +var frame_time = 30; // milliseconds per frame 61.50 +var straighten_factor = 0.95; // value from 0 to 1, factor applied to direction_offset every frame 61.51 +var curviness = 0.2; // amount of random direction change each frame 61.52 + 61.53 +var color_speed = 0.03; // speed at which colors change when cycling is enabled 61.54 +var branch_shrink = 0.95; // factor by which branches shrink every frame 61.55 +var min_width = 1; // minimum WIDTH for branch, after which they are discontinued 61.56 +var branch_opacity = 0.4; // opacity of lines drawn 61.57 +var branch_count = 3; // branch count per tree 61.58 +var branch_bud_size = 0.5; // ratio of original branch size at which branch will split 61.59 +var branch_bud_angle = 1; // angle offset for split branch; 61.60 + 61.61 +var paper; // reference to graphics context 61.62 +var branches = Object(); // linked list of active branches 61.63 +var color_styles = []; // pre-computed list of colors as styles. format: (r,g,b,a) 61.64 +var direction_offset = 0; // current direction offset in radians. this is applied to all branches. 61.65 +var frame = 0; // frame counter 61.66 +var timespent = 0; // total time spent so far, used to calculate average frame render duration 61.67 +var frameratespan; // html span element for updating performance number 61.68 + 61.69 +// preferences object, contains an attribute for each user setting 61.70 +var prefs = { 61.71 + wrap: true, // causes branches reaching edge of viewable area to appear on opposite side 61.72 + fade: false, // fade existing graphics on each frame 61.73 + cycle: true, // gradually change colors each frame 61.74 + new_branch_frames: 20 // number of frames elapsed between each auto-generated tree 61.75 +}; 61.76 + 61.77 +// create tree at the specified position with number of branches 61.78 +function create_tree(branches, start_width, position, branch_count) { 61.79 + var angle_offset = Math.PI * 2 / branch_count; 61.80 + for (var i = 0; i < branch_count; ++i) { 61.81 + branch_add(branches, new Branch(position, angle_offset * i, start_width)); 61.82 + } 61.83 +} 61.84 + 61.85 +// add branch to collection 61.86 +function branch_add(branches, branch) { 61.87 + branch.next = branches.next; 61.88 + branches.next = branch; 61.89 +} 61.90 + 61.91 +// get the coordinates for the position of a new tree 61.92 +// use the center of the canvas 61.93 +function get_new_tree_center(width, height) { 61.94 + return { 61.95 + x: 0.5 * width, 61.96 + y: 0.5 * height 61.97 + }; 61.98 +} 61.99 + 61.100 +// Branch constructor 61.101 +// position has x and y properties 61.102 +// direction is in radians 61.103 +function Branch(position, direction, width) { 61.104 + this.x = position.x; 61.105 + this.y = position.y; 61.106 + this.width = width; 61.107 + this.original_width = width; 61.108 + this.direction = direction; 61.109 +} 61.110 + 61.111 +// update position, direction and width of a particular branch 61.112 +function branch_update(branches, branch, paper) { 61.113 + paper.beginPath(); 61.114 + paper.lineWidth = branch.width; 61.115 + paper.moveTo(branch.x, branch.y); 61.116 + 61.117 + branch.width *= branch_shrink; 61.118 + branch.direction += direction_offset; 61.119 + branch.x += Math.cos(branch.direction) * branch.width; 61.120 + branch.y += Math.sin(branch.direction) * branch.width; 61.121 + 61.122 + paper.lineTo(branch.x, branch.y); 61.123 + paper.stroke(); 61.124 + 61.125 + if (prefs.wrap) wrap_branch(branch, WIDTH, HEIGHT); 61.126 + 61.127 + if (branch.width < branch.original_width * branch_bud_size) { 61.128 + branch.original_width *= branch_bud_size; 61.129 + branch_add(branches, new Branch(branch, branch.direction + 1, branch.original_width)); 61.130 + } 61.131 +} 61.132 + 61.133 +function draw_frame() { 61.134 + if (prefs.fade) { 61.135 + paper.fillRect(0, 0, WIDTH, HEIGHT); 61.136 + } 61.137 + 61.138 + if (prefs.cycle) { 61.139 + paper.setStroke(Paint.valueOf(color_styles[frame % color_styles.length])); 61.140 + } 61.141 + 61.142 + if (frame++ % prefs.new_branch_frames == 0) { 61.143 + create_tree(branches, start_width, get_new_tree_center(WIDTH, HEIGHT), branch_count); 61.144 + } 61.145 + 61.146 + direction_offset += (0.35 + (frame % 200) * 0.0015) * curviness - curviness / 2; 61.147 + direction_offset *= straighten_factor; 61.148 + 61.149 + var branch = branches; 61.150 + var prev_branch = branches; 61.151 + while (branch = branch.next) { 61.152 + branch_update(branches, branch, paper); 61.153 + 61.154 + if (branch.width < min_width) { 61.155 + // remove branch from list 61.156 + prev_branch.next = branch.next; 61.157 + } 61.158 + 61.159 + prev_branch = branch; 61.160 + } 61.161 +} 61.162 + 61.163 +// constrain branch position to visible area by "wrapping" from edge to edge 61.164 +function wrap_branch(branch, WIDTH, HEIGHT) { 61.165 + branch.x = positive_mod(branch.x, WIDTH); 61.166 + branch.y = positive_mod(branch.y, HEIGHT); 61.167 +} 61.168 + 61.169 +// for a < 0, b > 0, javascript returns a negative number for a % b 61.170 +// this is a variant of the % operator that adds b to the result in this case 61.171 +function positive_mod(a, b) { 61.172 + // ECMA 262 11.5.3: Applying the % Operator 61.173 + // remainder operator does not convert operands to integers, 61.174 + // although negative results are possible 61.175 + 61.176 + return ((a % b) + b) % b; 61.177 +} 61.178 + 61.179 +// pre-compute color styles that will be used for color cycling 61.180 +function populate_colors(color_speed, color_styles, branch_opacity) { 61.181 + // used in calculation of RGB values 61.182 + var two_thirds_pi = Math.PI * 2 / 3; 61.183 + var four_thirds_pi = Math.PI * 4 / 3; 61.184 + var two_pi = Math.PI * 2; 61.185 + 61.186 + // hue does represent hue, but not in the conventional HSL scheme 61.187 + for(var hue = 0; hue < two_pi; hue += color_speed) { 61.188 + var r = Math.floor(Math.sin(hue) * 128 + 128); 61.189 + var g = Math.floor(Math.sin(hue + two_thirds_pi) * 128 + 128); 61.190 + var b = Math.floor(Math.sin(hue + four_thirds_pi) * 128 + 128); 61.191 + color = "rgba(" + [r, g, b, branch_opacity].join() + ")"; 61.192 + 61.193 + color_styles.push(color); 61.194 + } 61.195 +} 61.196 + 61.197 +// apply initial settings to canvas object 61.198 +function setup_canvas() { 61.199 + paper = canvas.graphicsContext2D; 61.200 + paper.setFill(Paint.valueOf('rgb(0, 0, 0)')); 61.201 + paper.fillRect(0, 0, WIDTH, HEIGHT); 61.202 + paper.setFill(Paint.valueOf("rgba(0, 0, 0, 0.005)")); 61.203 + paper.setStroke(Paint.valueOf("rgba(128, 128, 64, " + String(branch_opacity) + ")")); 61.204 +} 61.205 + 61.206 +populate_colors(color_speed, color_styles, branch_opacity); 61.207 +setup_canvas(); 61.208 + 61.209 +var stack = new StackPane(); 61.210 +var pane = new BorderPane(); 61.211 +pane.setCenter(canvas); 61.212 +stack.getChildren().add(pane); 61.213 +$STAGE.scene = new Scene(stack); 61.214 +var timer = new AnimationTimerExtend() { 61.215 + handle: function handle(now) { 61.216 + if (frame < 200) { 61.217 + draw_frame(); 61.218 + } else { 61.219 + checkImageAndExit(); 61.220 + timer.stop(); 61.221 + } 61.222 + } 61.223 +}; 61.224 +timer.start(); 61.225 +
62.1 Binary file test/script/jfx/spread/golden/linux.png has changed
63.1 Binary file test/script/jfx/spread/golden/macosx.png has changed
64.1 Binary file test/script/jfx/spread/golden/windows.png has changed
65.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 65.2 +++ b/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java Tue Dec 03 14:13:15 2013 +0400 65.3 @@ -0,0 +1,99 @@ 65.4 +/* 65.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 65.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 65.7 + * 65.8 + * This code is free software; you can redistribute it and/or modify it 65.9 + * under the terms of the GNU General Public License version 2 only, as 65.10 + * published by the Free Software Foundation. Oracle designates this 65.11 + * particular file as subject to the "Classpath" exception as provided 65.12 + * by Oracle in the LICENSE file that accompanied this code. 65.13 + * 65.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 65.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 65.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 65.17 + * version 2 for more details (a copy is included in the LICENSE file that 65.18 + * accompanied this code). 65.19 + * 65.20 + * You should have received a copy of the GNU General Public License version 65.21 + * 2 along with this work; if not, write to the Free Software Foundation, 65.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 65.23 + * 65.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 65.25 + * or visit www.oracle.com if you need additional information or have any 65.26 + * questions. 65.27 + */ 65.28 + 65.29 +package jdk.nashorn.api.javaaccess; 65.30 + 65.31 +import static org.testng.AssertJUnit.assertEquals; 65.32 + 65.33 +import java.util.HashMap; 65.34 +import java.util.Map; 65.35 +import javax.script.Bindings; 65.36 +import javax.script.ScriptContext; 65.37 +import javax.script.ScriptEngine; 65.38 +import javax.script.ScriptEngineManager; 65.39 +import javax.script.ScriptException; 65.40 +import jdk.nashorn.api.scripting.JSObject; 65.41 +import org.testng.TestNG; 65.42 +import org.testng.annotations.AfterClass; 65.43 +import org.testng.annotations.BeforeClass; 65.44 +import org.testng.annotations.Test; 65.45 + 65.46 +public class ConsStringTest { 65.47 + private static ScriptEngine e = null; 65.48 + 65.49 + public static void main(final String[] args) { 65.50 + TestNG.main(args); 65.51 + } 65.52 + 65.53 + @BeforeClass 65.54 + public static void setUpClass() throws ScriptException { 65.55 + e = new ScriptEngineManager().getEngineByName("nashorn"); 65.56 + } 65.57 + 65.58 + @AfterClass 65.59 + public static void tearDownClass() { 65.60 + e = null; 65.61 + } 65.62 + 65.63 + @Test 65.64 + public void testConsStringFlattening() throws ScriptException { 65.65 + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); 65.66 + final Map<Object, Object> m = new HashMap<>(); 65.67 + b.put("m", m); 65.68 + e.eval("var x = 'f'; x += 'oo'; var y = 'b'; y += 'ar'; m.put(x, y)"); 65.69 + assertEquals("bar", m.get("foo")); 65.70 + } 65.71 + 65.72 + @Test 65.73 + public void testConsStringFromMirror() throws ScriptException { 65.74 + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); 65.75 + final Map<Object, Object> m = new HashMap<>(); 65.76 + e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};"); 65.77 + assertEquals("foo", ((JSObject)b.get("obj")).getMember("x")); 65.78 + } 65.79 + 65.80 + @Test 65.81 + public void testArrayConsString() throws ScriptException { 65.82 + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); 65.83 + final ArrayHolder h = new ArrayHolder(); 65.84 + b.put("h", h); 65.85 + e.eval("var x = 'f'; x += 'oo'; h.array = [x];"); 65.86 + assertEquals(1, h.array.length); 65.87 + assertEquals("foo", h.array[0]); 65.88 + } 65.89 + 65.90 + 65.91 + public static class ArrayHolder { 65.92 + private Object[] array; 65.93 + 65.94 + public void setArray(Object[] array) { 65.95 + this.array = array; 65.96 + } 65.97 + 65.98 + public Object[] getArray() { 65.99 + return array; 65.100 + } 65.101 + } 65.102 +}
66.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Sun Nov 03 07:33:34 2013 +0000 66.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Tue Dec 03 14:13:15 2013 +0400 66.3 @@ -523,6 +523,18 @@ 66.4 assertEquals(sw.toString(), println("34 true hello")); 66.5 } 66.6 66.7 + @Test 66.8 + public void scriptObjectAutoConversionTest() throws ScriptException { 66.9 + final ScriptEngineManager m = new ScriptEngineManager(); 66.10 + final ScriptEngine e = m.getEngineByName("nashorn"); 66.11 + e.eval("obj = { foo: 'hello' }"); 66.12 + e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window")); 66.13 + assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); 66.14 + assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello"); 66.15 + assertEquals(e.eval("Window.funcMap(obj)"), "hello"); 66.16 + assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); 66.17 + } 66.18 + 66.19 private static final String LINE_SEPARATOR = System.getProperty("line.separator"); 66.20 66.21 // Returns String that would be the result of calling PrintWriter.println
67.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Sun Nov 03 07:33:34 2013 +0000 67.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Tue Dec 03 14:13:15 2013 +0400 67.3 @@ -26,6 +26,7 @@ 67.4 package jdk.nashorn.api.scripting; 67.5 67.6 import java.util.HashMap; 67.7 +import java.util.List; 67.8 import java.util.Map; 67.9 import javax.script.ScriptEngine; 67.10 import javax.script.ScriptEngineManager; 67.11 @@ -227,4 +228,28 @@ 67.12 final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); 67.13 assertTrue(newObj instanceof ScriptObjectMirror); 67.14 } 67.15 + 67.16 + @Test 67.17 + public void conversionTest() throws ScriptException { 67.18 + final ScriptEngineManager m = new ScriptEngineManager(); 67.19 + final ScriptEngine e = m.getEngineByName("nashorn"); 67.20 + final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]"); 67.21 + final int[] intArr = arr.to(int[].class); 67.22 + assertEquals(intArr[0], 33); 67.23 + assertEquals(intArr[1], 45); 67.24 + assertEquals(intArr[2], 23); 67.25 + 67.26 + final List<?> list = arr.to(List.class); 67.27 + assertEquals(list.get(0), 33); 67.28 + assertEquals(list.get(1), 45); 67.29 + assertEquals(list.get(2), 23); 67.30 + 67.31 + ScriptObjectMirror obj = (ScriptObjectMirror)e.eval( 67.32 + "({ valueOf: function() { return 42 } })"); 67.33 + assertEquals(Double.valueOf(42.0), obj.to(Double.class)); 67.34 + 67.35 + obj = (ScriptObjectMirror)e.eval( 67.36 + "({ toString: function() { return 'foo' } })"); 67.37 + assertEquals("foo", obj.to(String.class)); 67.38 + } 67.39 }
68.1 --- a/test/src/jdk/nashorn/api/scripting/Window.java Sun Nov 03 07:33:34 2013 +0000 68.2 +++ b/test/src/jdk/nashorn/api/scripting/Window.java Tue Dec 03 14:13:15 2013 +0400 68.3 @@ -25,6 +25,9 @@ 68.4 68.5 package jdk.nashorn.api.scripting; 68.6 68.7 +import java.util.Map; 68.8 +import javax.script.Bindings; 68.9 + 68.10 public class Window { 68.11 68.12 private String location = "http://localhost:8080/window"; 68.13 @@ -63,4 +66,20 @@ 68.14 System.out.println("window.setTimeout: " + delay + ", code: " + code); 68.15 return 0; 68.16 } 68.17 + 68.18 + public static Object funcJSObject(final JSObject jsobj) { 68.19 + return jsobj.getMember("foo"); 68.20 + } 68.21 + 68.22 + public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) { 68.23 + return sobj.get("foo"); 68.24 + } 68.25 + 68.26 + public static Object funcMap(final Map<?,?> map) { 68.27 + return map.get("foo"); 68.28 + } 68.29 + 68.30 + public static Object funcBindings(final Bindings bindings) { 68.31 + return bindings.get("foo"); 68.32 + } 68.33 }