Mercurial > hg > release > icedtea8-forest-3.0 > nashorn
changeset 1328:d03eb34e4b84 jdk8u60-b12
Merge
author | lana |
---|---|
date | Thu, 16 Apr 2015 16:01:11 -0700 |
parents | 6673e739a995 (current diff) d82b07c9c6e3 (diff) |
children | 3628ab9fdbc0 37de779feba1 |
files | test/src/jdk/internal/dynalink/beans/CallerSensitiveTest.java test/src/jdk/nashorn/api/NashornSQLDriver.java test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java test/src/jdk/nashorn/api/javaaccess/Person.java test/src/jdk/nashorn/api/javaaccess/SharedObject.java test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java test/src/jdk/nashorn/api/scripting/InvocableTest.java test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java test/src/jdk/nashorn/api/scripting/ScopeTest.java test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java test/src/jdk/nashorn/api/scripting/VariableArityTestInterface.java test/src/jdk/nashorn/api/scripting/Window.java test/src/jdk/nashorn/api/scripting/WindowEventHandler.java test/src/jdk/nashorn/api/scripting/resources/func.js test/src/jdk/nashorn/api/scripting/resources/gettersetter.js test/src/jdk/nashorn/api/scripting/resources/witheval.js test/src/jdk/nashorn/api/scripting/test/ScriptEngineTest.java test/src/jdk/nashorn/internal/codegen/CompilerTest.java test/src/jdk/nashorn/internal/parser/ParserTest.java test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java test/src/jdk/nashorn/internal/runtime/ConsStringTest.java test/src/jdk/nashorn/internal/runtime/ContextTest.java test/src/jdk/nashorn/internal/runtime/ExceptionsNotSerializable.java test/src/jdk/nashorn/internal/runtime/JSTypeTest.java test/src/jdk/nashorn/internal/runtime/LexicalBindingTest.java test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java test/src/jdk/nashorn/internal/runtime/SourceTest.java test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java test/src/jdk/nashorn/internal/runtime/resources/load_test.js |
diffstat | 115 files changed, 9651 insertions(+), 9286 deletions(-) [+] |
line wrap: on
line diff
--- a/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java Thu Apr 16 16:01:11 2015 -0700 @@ -124,8 +124,6 @@ if (memberCount > 0) { // call "super(map$)" mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); - // make sure we use duplicated PropertyMap so that original map - // stays intact and so can be used for many global. mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); // initialize Function type fields initFunctionFields(mi);
--- a/docs/DEVELOPER_README Wed Apr 15 14:45:25 2015 -0700 +++ b/docs/DEVELOPER_README Thu Apr 16 16:01:11 2015 -0700 @@ -63,16 +63,19 @@ See the description of the codegen logger below. -SYSTEM PROPERTY: -Dnashorn.fields.objects +SYSTEM PROPERTY: -Dnashorn.fields.objects, -Dnashorn.fields.dual -When this property is true, Nashorn will only use object fields for -AccessorProperties. This means that primitive values must be boxed -when stored in a field, which is significantly slower than using -primitive fields. +When the nashorn.fields.objects property is true, Nashorn will always +use object fields for AccessorProperties, requiring boxing for all +primitive property values. When nashorn.fields.dual is set, Nashorn +will always use dual long/object fields, which allows primitives to be +stored without boxing. When neither system property is set, Nashorn +chooses a setting depending on the optimistic types setting (dual +fields when optimistic types are enabled, object-only fields otherwise). -By default, Nashorn uses dual object and long fields. Ints are -represented as the 32 low bits of the long fields. Doubles are -represented as the doubleToLongBits of their value. This way a +With dual fields, Nashorn uses long fields to store primitive values. +Ints are represented as the 32 low bits of the long fields. Doubles +are represented as the doubleToLongBits of their value. This way a single field can be used for all primitive types. Packing and unpacking doubles to their bit representation is intrinsified by the JVM and extremely fast.
--- a/make/build.xml Wed Apr 15 14:45:25 2015 -0700 +++ b/make/build.xml Thu Apr 16 16:01:11 2015 -0700 @@ -282,12 +282,12 @@ <fileset dir="${test.src.dir}/META-INF/services/"/> </copy> - <copy todir="${build.test.classes.dir}/jdk/nashorn/internal/runtime/resources"> - <fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/resources"/> + <copy todir="${build.test.classes.dir}/jdk/nashorn/internal/runtime/test/resources"> + <fileset dir="${test.src.dir}/jdk/nashorn/internal/runtime/test/resources"/> </copy> - <copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/resources"> - <fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/resources"/> + <copy todir="${build.test.classes.dir}/jdk/nashorn/api/scripting/test/resources"> + <fileset dir="${test.src.dir}/jdk/nashorn/api/scripting/test/resources"/> </copy> <!-- tests that check nashorn internals and internal API --> @@ -394,13 +394,13 @@ <!-- only to be invoked as dependency of "test" target --> <target name="-test-classes-all" depends="jar" unless="test.class"> <fileset id="test.classes" dir="${build.test.classes.dir}"> - <include name="**/api/javaaccess/*Test.class"/> - <include name="**/api/scripting/*Test.class"/> - <include name="**/codegen/*Test.class"/> - <include name="**/parser/*Test.class"/> - <include name="**/runtime/*Test.class"/> - <include name="**/runtime/regexp/*Test.class"/> - <include name="**/runtime/regexp/joni/*Test.class"/> + <include name="**/api/javaaccess/test/*Test.class"/> + <include name="**/api/scripting/test/*Test.class"/> + <include name="**/codegen/test/*Test.class"/> + <include name="**/parser/test/*Test.class"/> + <include name="**/runtime/test/*Test.class"/> + <include name="**/runtime/regexp/test/*Test.class"/> + <include name="**/runtime/regexp/joni/test/*Test.class"/> <include name="**/framework/*Test.class"/> </fileset> </target>
--- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java Thu Apr 16 16:01:11 2015 -0700 @@ -43,7 +43,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import static jdk.nashorn.internal.ir.Symbol.HAS_SLOT; import static jdk.nashorn.internal.ir.Symbol.IS_INTERNAL; import static jdk.nashorn.internal.runtime.UnwarrantedOptimismException.INVALID_PROGRAM_POINT; @@ -298,6 +297,20 @@ } /** + * Gets the flags for a scope call site. + * @param symbol a scope symbol + * @return the correct flags for the scope call site + */ + private int getScopeCallSiteFlags(final Symbol symbol) { + assert symbol.isScope(); + final int flags = getCallSiteFlags() | CALLSITE_SCOPE; + if (isEvalCode() && symbol.isGlobal()) { + return flags; // Don't set fast-scope flag on non-declared globals in eval code - see JDK-8077955. + } + return isFastScope(symbol) ? flags | CALLSITE_FAST_SCOPE : flags; + } + + /** * Are we generating code for 'eval' code? * @return true if currently compiled code is 'eval' code. */ @@ -306,6 +319,14 @@ } /** + * Are we using dual primitive/object field representation? + * @return true if using dual field representation, false for object-only fields + */ + boolean useDualFields() { + return compiler.getContext().useDualFields(); + } + + /** * Load an identity node * * @param identNode an identity node to load @@ -326,7 +347,7 @@ } assert identNode.getSymbol().isScope() : identNode + " is not in scope!"; - final int flags = CALLSITE_SCOPE | getCallSiteFlags(); + final int flags = getScopeCallSiteFlags(symbol); if (isFastScope(symbol)) { // Only generate shared scope getter for fast-scope symbols so we know we can dial in correct scope. if (symbol.getUseCount() > SharedScopeCall.FAST_SCOPE_GET_THRESHOLD && !isOptimisticOrRestOf()) { @@ -450,7 +471,7 @@ } else { method.load(-1); } - return lc.getScopeGet(unit, symbol, valueType, flags | CALLSITE_FAST_SCOPE).generateInvoke(method); + return lc.getScopeGet(unit, symbol, valueType, flags).generateInvoke(method); } private class LoadScopeVar extends OptimisticOperation { @@ -488,7 +509,7 @@ private class LoadFastScopeVar extends LoadScopeVar { LoadFastScopeVar(final IdentNode identNode, final TypeBounds resultBounds, final int flags) { - super(identNode, resultBounds, flags | CALLSITE_FAST_SCOPE); + super(identNode, resultBounds, flags); } @Override @@ -499,7 +520,7 @@ private MethodEmitter storeFastScopeVar(final Symbol symbol, final int flags) { loadFastScopeProto(symbol, true); - method.dynamicSet(symbol.getName(), flags | CALLSITE_FAST_SCOPE, false); + method.dynamicSet(symbol.getName(), flags, false); return method; } @@ -1419,7 +1440,6 @@ private MethodEmitter sharedScopeCall(final IdentNode identNode, final int flags) { final Symbol symbol = identNode.getSymbol(); final boolean isFastScope = isFastScope(symbol); - final int scopeCallFlags = flags | (isFastScope ? CALLSITE_FAST_SCOPE : 0); new OptimisticOperation(callNode, resultBounds) { @Override void loadStack() { @@ -1442,7 +1462,7 @@ // As shared scope calls are only used in non-optimistic compilation, we switch from using // TypeBounds to just a single definitive type, resultBounds.widest. final SharedScopeCall scopeCall = codegenLexicalContext.getScopeCall(unit, symbol, - identNode.getType(), resultBounds.widest, paramTypes, scopeCallFlags); + identNode.getType(), resultBounds.widest, paramTypes, flags); scopeCall.generateInvoke(method); } }.emit(); @@ -1543,7 +1563,7 @@ final Symbol symbol = node.getSymbol(); if (symbol.isScope()) { - final int flags = getCallSiteFlags() | CALLSITE_SCOPE; + final int flags = getScopeCallSiteFlags(symbol); final int useCount = symbol.getUseCount(); // Threshold for generating shared scope callsite is lower for fast scope symbols because we know @@ -1896,10 +1916,10 @@ //this symbol will be put fielded, we can't initialize it as undefined with a known type @Override public Class<?> getValueType() { - if (OBJECT_FIELDS_ONLY || value == null || paramType == null) { + if (!useDualFields() || value == null || paramType == null || paramType.isBoolean()) { return Object.class; } - return paramType.isBoolean() ? Object.class : paramType.getTypeClass(); + return paramType.getTypeClass(); } }); } @@ -2555,7 +2575,7 @@ //for literals, a value of null means object type, i.e. the value null or getter setter function //(I think) - final Class<?> valueType = (OBJECT_FIELDS_ONLY || value == null || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass(); + final Class<?> valueType = (!useDualFields() || value == null || value.getType().isBoolean()) ? Object.class : value.getType().getTypeClass(); tuples.add(new MapTuple<Expression>(key, symbol, Type.typeFor(valueType), value) { @Override public Class<?> getValueType() { @@ -3285,7 +3305,7 @@ // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ) method.loadCompilerConstant(SCOPE); method.loadUndefined(Type.OBJECT); - final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); + final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); assert isFastScope(identSymbol); storeFastScopeVar(identSymbol, flags); } @@ -3302,7 +3322,7 @@ if (needsScope) { loadExpressionUnbounded(init); // block scoped variables need a DECLARE flag to signal end of temporal dead zone (TDZ) - final int flags = CALLSITE_SCOPE | getCallSiteFlags() | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); + final int flags = getScopeCallSiteFlags(identSymbol) | (varNode.isBlockScoped() ? CALLSITE_DECLARE : 0); if (isFastScope(identSymbol)) { storeFastScopeVar(identSymbol, flags); } else { @@ -4436,7 +4456,7 @@ final Symbol symbol = node.getSymbol(); assert symbol != null; if (symbol.isScope()) { - final int flags = CALLSITE_SCOPE | getCallSiteFlags(); + final int flags = getScopeCallSiteFlags(symbol); if (isFastScope(symbol)) { storeFastScopeVar(symbol, flags); } else {
--- a/src/jdk/nashorn/internal/codegen/CompilerConstants.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/CompilerConstants.java Thu Apr 16 16:01:11 2015 -0700 @@ -149,8 +149,11 @@ /** Arguments parameter in scope object constructors; in slot 3 when present */ INIT_ARGUMENTS(null, 3), - /** prefix for all ScriptObject subclasses with fields, @see ObjectGenerator */ - JS_OBJECT_PREFIX("JO"), + /** prefix for all ScriptObject subclasses with dual object/primitive fields, see {@link ObjectClassGenerator} */ + JS_OBJECT_DUAL_FIELD_PREFIX("JD"), + + /** prefix for all ScriptObject subclasses with object fields only, see {@link ObjectClassGenerator} */ + JS_OBJECT_SINGLE_FIELD_PREFIX("JO"), /** name for allocate method in JO objects */ ALLOCATE("allocate"),
--- a/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java Thu Apr 16 16:01:11 2015 -0700 @@ -151,7 +151,7 @@ @Override protected PropertyMap makeMap() { assert propertyMap == null : "property map already initialized"; - propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), fieldCount, paddedFieldCount, evalCode); + propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), codegen.useDualFields(), fieldCount, paddedFieldCount, evalCode); return propertyMap; } @@ -166,7 +166,7 @@ private void putField(final MethodEmitter method, final String key, final int fieldIndex, final MapTuple<T> tuple) { method.dup(); - final Type fieldType = tuple.isPrimitive() ? PRIMITIVE_FIELD_TYPE : Type.OBJECT; + final Type fieldType = codegen.useDualFields() && tuple.isPrimitive() ? PRIMITIVE_FIELD_TYPE : Type.OBJECT; final String fieldClass = getClassName(); final String fieldName = getFieldName(fieldIndex, fieldType); final String fieldDesc = typeDescriptor(fieldType.getTypeClass()); @@ -202,8 +202,8 @@ */ private void findClass() { fieldObjectClassName = isScope() ? - ObjectClassGenerator.getClassName(fieldCount, paramCount) : - ObjectClassGenerator.getClassName(paddedFieldCount); + ObjectClassGenerator.getClassName(fieldCount, paramCount, codegen.useDualFields()) : + ObjectClassGenerator.getClassName(paddedFieldCount, codegen.useDualFields()); try { this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName));
--- a/src/jdk/nashorn/internal/codegen/FindScopeDepths.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/FindScopeDepths.java Thu Apr 16 16:01:11 2015 -0700 @@ -207,7 +207,7 @@ final RecompilableScriptFunctionData data = new RecompilableScriptFunctionData( newFunctionNode, compiler.getCodeInstaller(), - ObjectClassGenerator.createAllocationStrategy(newFunctionNode.getThisProperties()), + ObjectClassGenerator.createAllocationStrategy(newFunctionNode.getThisProperties(), compiler.getContext().useDualFields()), nestedFunctions, externalSymbolDepths.get(fnId), internalSymbols.get(fnId),
--- a/src/jdk/nashorn/internal/codegen/MapCreator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/MapCreator.java Thu Apr 16 16:01:11 2015 -0700 @@ -68,17 +68,17 @@ * @param evalCode is this property map created for 'eval' code? * @return New map populated with accessor properties. */ - PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum, final boolean evalCode) { + PropertyMap makeFieldMap(final boolean hasArguments, final boolean dualFields, final int fieldCount, final int fieldMaximum, final boolean evalCode) { final List<Property> properties = new ArrayList<>(); assert tuples != null; for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; - final Class<?> initialType = tuple.getValueType(); + final Class<?> initialType = dualFields ? tuple.getValueType() : Object.class; if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { - final int flags = getPropertyFlags(symbol, hasArguments, evalCode); + final int flags = getPropertyFlags(symbol, hasArguments, evalCode, dualFields); final Property property = new AccessorProperty( key, flags, @@ -92,7 +92,7 @@ return PropertyMap.newMap(properties, structure.getName(), fieldCount, fieldMaximum, 0); } - PropertyMap makeSpillMap(final boolean hasArguments) { + PropertyMap makeSpillMap(final boolean hasArguments, final boolean dualFields) { final List<Property> properties = new ArrayList<>(); int spillIndex = 0; assert tuples != null; @@ -100,10 +100,10 @@ for (final MapTuple<T> tuple : tuples) { final String key = tuple.key; final Symbol symbol = tuple.symbol; - final Class<?> initialType = tuple.getValueType(); + final Class<?> initialType = dualFields ? tuple.getValueType() : Object.class; if (symbol != null && !isValidArrayIndex(getArrayIndex(key))) { - final int flags = getPropertyFlags(symbol, hasArguments, false); + final int flags = getPropertyFlags(symbol, hasArguments, false, dualFields); properties.add( new SpillProperty( key, @@ -124,7 +124,7 @@ * * @return flags to use for fields */ - static int getPropertyFlags(final Symbol symbol, final boolean hasArguments, final boolean evalCode) { + static int getPropertyFlags(final Symbol symbol, final boolean hasArguments, final boolean evalCode, final boolean dualFields) { int flags = 0; if (symbol.isParam()) { @@ -162,6 +162,10 @@ flags |= Property.NEEDS_DECLARATION; } + if (dualFields) { + flags |= Property.DUAL_FIELDS; + } + return flags; } }
--- a/src/jdk/nashorn/internal/codegen/MapTuple.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/MapTuple.java Thu Apr 16 16:01:11 2015 -0700 @@ -25,8 +25,6 @@ package jdk.nashorn.internal.codegen; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.Symbol; @@ -52,11 +50,11 @@ } public Class<?> getValueType() { - return OBJECT_FIELDS_ONLY ? Object.class : null; //until proven otherwise we are undefined, see NASHORN-592 int.class; + return null; //until proven otherwise we are undefined, see NASHORN-592 int.class; } boolean isPrimitive() { - return !OBJECT_FIELDS_ONLY && getValueType().isPrimitive() && getValueType() != boolean.class; + return getValueType() != null && getValueType().isPrimitive() && getValueType() != boolean.class; } @Override
--- a/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java Thu Apr 16 16:01:11 2015 -0700 @@ -31,7 +31,8 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_MAP; import static jdk.nashorn.internal.codegen.CompilerConstants.INIT_SCOPE; import static jdk.nashorn.internal.codegen.CompilerConstants.JAVA_THIS; -import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_DUAL_FIELD_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_SINGLE_FIELD_PREFIX; import static jdk.nashorn.internal.codegen.CompilerConstants.className; import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; import static jdk.nashorn.internal.lookup.Lookup.MH; @@ -99,18 +100,10 @@ */ private final DebugLogger log; - /** - * Should the runtime only use java.lang.Object slots for fields? If this is false, the representation - * will be a primitive 64-bit long value used for all primitives and a java.lang.Object for references. - * This introduces a larger number of method handles in the system, as we need to have different getters - * and setters for the different fields. - * - * This is engineered to plug into the TaggedArray implementation, when it's done. - */ - public static final boolean OBJECT_FIELDS_ONLY = Options.getBooleanProperty("nashorn.fields.objects"); - - /** The field types in the system */ - private static final List<Type> FIELD_TYPES = new LinkedList<>(); + /** Field types for object-only fields */ + private static final Type[] FIELD_TYPES_OBJECT = new Type[] { Type.OBJECT }; + /** Field types for dual primitive/object fields */ + private static final Type[] FIELD_TYPES_DUAL = new Type[] { Type.LONG, Type.OBJECT }; /** What type is the primitive type in dual representation */ public static final Type PRIMITIVE_FIELD_TYPE = Type.LONG; @@ -118,33 +111,27 @@ private static final MethodHandle GET_DIFFERENT = findOwnMH("getDifferent", Object.class, Object.class, Class.class, MethodHandle.class, MethodHandle.class, int.class); private static final MethodHandle GET_DIFFERENT_UNDEFINED = findOwnMH("getDifferentUndefined", Object.class, int.class); - /** - * The list of field types that we support - one type creates one field. This is currently either - * LONG + OBJECT or just OBJECT for classic mode. - */ - static { - if (!OBJECT_FIELDS_ONLY) { - FIELD_TYPES.add(PRIMITIVE_FIELD_TYPE); - } - FIELD_TYPES.add(Type.OBJECT); - } private static boolean initialized = false; /** The context */ private final Context context; + private final boolean dualFields; + /** * Constructor * * @param context a context + * @param dualFields whether to use dual fields representation */ - public ObjectClassGenerator(final Context context) { + public ObjectClassGenerator(final Context context, final boolean dualFields) { this.context = context; + this.dualFields = dualFields; assert context != null; this.log = initLogger(context); if (!initialized) { initialized = true; - if (OBJECT_FIELDS_ONLY) { + if (!dualFields) { log.warning("Running with object fields only - this is a deprecated configuration."); } } @@ -176,16 +163,30 @@ throw new AssertionError("cannot pack" + n); } + private static String getPrefixName(final boolean dualFields) { + return dualFields ? JS_OBJECT_DUAL_FIELD_PREFIX.symbolName() : JS_OBJECT_SINGLE_FIELD_PREFIX.symbolName(); + } + + private static String getPrefixName(final String className) { + if (className.startsWith(JS_OBJECT_DUAL_FIELD_PREFIX.symbolName())) { + return getPrefixName(true); + } else if (className.startsWith(JS_OBJECT_SINGLE_FIELD_PREFIX.symbolName())) { + return getPrefixName(false); + } + throw new AssertionError("Not a structure class: " + className); + } + /** * Returns the class name for JavaScript objects with fieldCount fields. * * @param fieldCount Number of fields to allocate. - * + * @param dualFields whether to use dual fields representation * @return The class name. */ - public static String getClassName(final int fieldCount) { - return fieldCount != 0 ? SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.symbolName() + fieldCount : - SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.symbolName(); + public static String getClassName(final int fieldCount, final boolean dualFields) { + final String prefix = getPrefixName(dualFields); + return fieldCount != 0 ? SCRIPTS_PACKAGE + '/' + prefix + fieldCount : + SCRIPTS_PACKAGE + '/' + prefix; } /** @@ -194,22 +195,23 @@ * * @param fieldCount Number of fields to allocate. * @param paramCount Number of parameters to allocate - * + * @param dualFields whether to use dual fields representation * @return The class name. */ - public static String getClassName(final int fieldCount, final int paramCount) { - return SCRIPTS_PACKAGE + '/' + JS_OBJECT_PREFIX.symbolName() + fieldCount + SCOPE_MARKER + paramCount; + public static String getClassName(final int fieldCount, final int paramCount, final boolean dualFields) { + return SCRIPTS_PACKAGE + '/' + getPrefixName(dualFields) + fieldCount + SCOPE_MARKER + paramCount; } /** * Returns the number of fields in the JavaScript scope class. Its name had to be generated using either - * {@link #getClassName(int)} or {@link #getClassName(int, int)}. + * {@link #getClassName(int, boolean)} or {@link #getClassName(int, int, boolean)}. * @param clazz the JavaScript scope class. * @return the number of fields in the scope class. */ public static int getFieldCount(final Class<?> clazz) { final String name = clazz.getSimpleName(); - final String prefix = JS_OBJECT_PREFIX.symbolName(); + final String prefix = getPrefixName(name); + if (prefix.equals(name)) { return 0; } @@ -238,8 +240,8 @@ * @param className name of class * @param fieldNames fields to initialize to undefined, where applicable */ - private static void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) { - if (!OBJECT_FIELDS_ONLY) { + private void initializeToUndefined(final MethodEmitter init, final String className, final List<String> fieldNames) { + if (dualFields) { // no need to initialize anything to undefined in the dual field world // - then we have a constant getter for undefined for any unknown type return; @@ -292,7 +294,7 @@ * @return Byte codes for generated class. */ public byte[] generate(final int fieldCount) { - final String className = getClassName(fieldCount); + final String className = getClassName(fieldCount, dualFields); final String superName = className(ScriptObject.class); final ClassEmitter classEmitter = newClassEmitter(className, superName); @@ -322,7 +324,7 @@ * @return Byte codes for generated class. */ public byte[] generate(final int fieldCount, final int paramCount) { - final String className = getClassName(fieldCount, paramCount); + final String className = getClassName(fieldCount, paramCount, dualFields); final String superName = className(FunctionScope.class); final ClassEmitter classEmitter = newClassEmitter(className, superName); final List<String> initFields = addFields(classEmitter, fieldCount); @@ -353,11 +355,11 @@ * * @return List fields that need to be initialized. */ - private static List<String> addFields(final ClassEmitter classEmitter, final int fieldCount) { + private List<String> addFields(final ClassEmitter classEmitter, final int fieldCount) { final List<String> initFields = new LinkedList<>(); - + final Type[] fieldTypes = dualFields ? FIELD_TYPES_DUAL : FIELD_TYPES_OBJECT; for (int i = 0; i < fieldCount; i++) { - for (final Type type : FIELD_TYPES) { + for (final Type type : fieldTypes) { final String fieldName = getFieldName(i, type); classEmitter.field(fieldName, type.getTypeClass()); @@ -533,13 +535,10 @@ private static MethodHandle getterForType(final Class<?> forType, final MethodHandle primitiveGetter, final MethodHandle objectGetter) { switch (getAccessorTypeIndex(forType)) { case TYPE_INT_INDEX: - assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields"; return MH.explicitCastArguments(primitiveGetter, primitiveGetter.type().changeReturnType(int.class)); case TYPE_LONG_INDEX: - assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields"; return primitiveGetter; case TYPE_DOUBLE_INDEX: - assert !OBJECT_FIELDS_ONLY : "this can only happen with dual fields"; return MH.filterReturnValue(primitiveGetter, UNPACK_DOUBLE); case TYPE_OBJECT_INDEX: return objectGetter; @@ -557,7 +556,7 @@ final boolean isPrimitiveStorage = forType != null && forType.isPrimitive(); //which is the primordial getter - final MethodHandle getter = OBJECT_FIELDS_ONLY ? objectGetter : isPrimitiveStorage ? primitiveGetter : objectGetter; + final MethodHandle getter = primitiveGetter == null ? objectGetter : isPrimitiveStorage ? primitiveGetter : objectGetter; if (forType == null) { if (isOptimistic) { @@ -580,8 +579,7 @@ return MH.dropArguments(GET_UNDEFINED.get(ti), 0, Object.class); } - assert forType != null; - assert !OBJECT_FIELDS_ONLY || forType == Object.class : forType; + assert primitiveGetter != null || forType == Object.class : forType; if (isOptimistic) { if (fti < ti) { @@ -635,8 +633,6 @@ return tgetter; } - assert !OBJECT_FIELDS_ONLY; - //final MethodType pmt = primitiveGetter.type(); assert primitiveGetter != null; final MethodType tgetterType = tgetter.type(); switch (fti) { @@ -727,7 +723,7 @@ final int fti = getAccessorTypeIndex(forType); final int ti = getAccessorTypeIndex(type); - if (fti == TYPE_OBJECT_INDEX || OBJECT_FIELDS_ONLY) { + if (fti == TYPE_OBJECT_INDEX || primitiveSetter == null) { if (ti == TYPE_OBJECT_INDEX) { return objectSetter; } @@ -735,8 +731,6 @@ return MH.asType(objectSetter, objectSetter.type().changeParameterType(1, type)); } - assert !OBJECT_FIELDS_ONLY; - final MethodType pmt = primitiveSetter.type(); switch (fti) { @@ -832,8 +826,8 @@ * @param thisProperties number of properties assigned to "this" * @return the allocation strategy */ - static AllocationStrategy createAllocationStrategy(final int thisProperties) { + static AllocationStrategy createAllocationStrategy(final int thisProperties, final boolean dualFields) { final int paddedFieldCount = getPaddedFieldCount(thisProperties); - return new AllocationStrategy(paddedFieldCount); + return new AllocationStrategy(paddedFieldCount, dualFields); } }
--- a/src/jdk/nashorn/internal/codegen/ObjectCreator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/ObjectCreator.java Thu Apr 16 16:01:11 2015 -0700 @@ -134,7 +134,7 @@ MethodEmitter loadTuple(final MethodEmitter method, final MapTuple<T> tuple, final boolean pack) { loadValue(tuple.value, tuple.type); - if (pack && tuple.isPrimitive()) { + if (pack && codegen.useDualFields() && tuple.isPrimitive()) { method.pack(); } else { method.convert(Type.OBJECT);
--- a/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java Thu Apr 16 16:01:11 2015 -0700 @@ -27,7 +27,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import java.util.LinkedHashSet; import java.util.List; @@ -42,6 +41,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.arrays.ArrayIndex; +import jdk.nashorn.internal.scripts.JD; import jdk.nashorn.internal.scripts.JO; /** @@ -65,10 +65,13 @@ assert !isScope() : "spill scope objects are not currently supported"; final int length = tuples.size(); - final long[] jpresetValues = new long[ScriptObject.spillAllocationLength(length)]; - final Object[] opresetValues = new Object[ScriptObject.spillAllocationLength(length)]; + final boolean dualFields = codegen.useDualFields(); + final int spillLength = ScriptObject.spillAllocationLength(length); + final long[] jpresetValues = dualFields ? new long[spillLength] : null; + final Object[] opresetValues = new Object[spillLength]; final Set<Integer> postsetValues = new LinkedHashSet<>(); final int callSiteFlags = codegen.getCallSiteFlags(); + final Class<?> objectClass = dualFields ? JD.class : JO.class; ArrayData arrayData = ArrayData.allocate(ScriptRuntime.EMPTY_ARRAY); // Compute constant property values @@ -88,9 +91,9 @@ final Property property = propertyMap.findProperty(key); if (property != null) { // normal property key - property.setType(JSType.unboxedFieldType(constantValue)); + property.setType(dualFields ? JSType.unboxedFieldType(constantValue) : Object.class); final int slot = property.getSlot(); - if (!OBJECT_FIELDS_ONLY && constantValue instanceof Number) { + if (dualFields && constantValue instanceof Number) { jpresetValues[slot] = ObjectClassGenerator.pack((Number)constantValue); } else { opresetValues[slot] = constantValue; @@ -130,28 +133,32 @@ //assert postsetValues.isEmpty() : "test me " + postsetValues; // create object and invoke constructor - method._new(JO.class).dup(); + method._new(objectClass).dup(); codegen.loadConstant(propertyMap); //load primitive values to j spill array - codegen.loadConstant(jpresetValues); - for (final int i : postsetValues) { - final MapTuple<Expression> tuple = tuples.get(i); - final Property property = propertyMap.findProperty(tuple.key); - if (property != null && tuple.isPrimitive()) { - method.dup(); - method.load(property.getSlot()); - loadTuple(method, tuple); - method.arraystore(); + if (dualFields) { + codegen.loadConstant(jpresetValues); + for (final int i : postsetValues) { + final MapTuple<Expression> tuple = tuples.get(i); + final Property property = propertyMap.findProperty(tuple.key); + if (property != null && tuple.isPrimitive()) { + method.dup(); + method.load(property.getSlot()); + loadTuple(method, tuple); + method.arraystore(); + } } + } else { + method.loadNull(); } //load object values to o spill array codegen.loadConstant(opresetValues); for (final int i : postsetValues) { - final MapTuple<Expression> tuple = tuples.get(i); - final Property property = propertyMap.findProperty(tuple.key); - if (property != null && !tuple.isPrimitive()) { + final MapTuple<Expression> tuple = tuples.get(i); + final Property property = propertyMap.findProperty(tuple.key); + if (property != null && (!dualFields || !tuple.isPrimitive())) { method.dup(); method.load(property.getSlot()); loadTuple(method, tuple); @@ -160,7 +167,7 @@ } //instantiate the script object with spill objects - method.invoke(constructorNoLookup(JO.class, PropertyMap.class, long[].class, Object[].class)); + method.invoke(constructorNoLookup(objectClass, PropertyMap.class, long[].class, Object[].class)); // Set prefix array data if any if (arrayData.length() > 0) { @@ -171,8 +178,8 @@ // set postfix for (final int i : postsetValues) { - final MapTuple<Expression> tuple = tuples.get(i); - final Property property = propertyMap.findProperty(tuple.key); + final MapTuple<Expression> tuple = tuples.get(i); + final Property property = propertyMap.findProperty(tuple.key); if (property == null) { final int index = ArrayIndex.getArrayIndex(tuple.key); assert ArrayIndex.isValidArrayIndex(index); @@ -188,7 +195,9 @@ @Override protected PropertyMap makeMap() { assert propertyMap == null : "property map already initialized"; - propertyMap = new MapCreator<>(JO.class, tuples).makeSpillMap(false); + final boolean dualFields = codegen.useDualFields(); + final Class<? extends ScriptObject> clazz = dualFields ? JD.class : JO.class; + propertyMap = new MapCreator<>(clazz, tuples).makeSpillMap(false, codegen.useDualFields()); return propertyMap; }
--- a/src/jdk/nashorn/internal/objects/Global.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/objects/Global.java Thu Apr 16 16:01:11 2015 -0700 @@ -79,6 +79,7 @@ import jdk.nashorn.internal.runtime.linker.InvokeByName; import jdk.nashorn.internal.runtime.linker.NashornCallSiteDescriptor; import jdk.nashorn.internal.runtime.regexp.RegExpResult; +import jdk.nashorn.internal.scripts.JD; import jdk.nashorn.internal.scripts.JO; import jdk.nashorn.tools.ShellFunctions; @@ -718,7 +719,7 @@ private static final MethodHandle LOAD = findOwnMH_S("load", Object.class, Object.class, Object.class); private static final MethodHandle LOAD_WITH_NEW_GLOBAL = findOwnMH_S("loadWithNewGlobal", Object.class, Object.class, Object[].class); private static final MethodHandle EXIT = findOwnMH_S("exit", Object.class, Object.class, Object.class); - private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter", Object.class, Object.class); + private static final MethodHandle LEXICAL_SCOPE_FILTER = findOwnMH_S("lexicalScopeFilter", Object.class, Object.class); // initialized by nasgen private static PropertyMap $nasgenmap$; @@ -750,6 +751,11 @@ return context; } + @Override + protected boolean useDualFields() { + return context.useDualFields(); + } + // performs initialization checks for Global constructor and returns the // PropertyMap, if everything is fine. private static PropertyMap checkAndGetMap(final Context context) { @@ -934,7 +940,7 @@ * @return the new ScriptObject */ public ScriptObject newObject() { - return new JO(getObjectPrototype(), JO.getInitialMap()); + return useDualFields() ? new JD(getObjectPrototype()) : new JO(getObjectPrototype()); } /** @@ -2746,8 +2752,8 @@ */ private static class LexicalScope extends ScriptObject { - LexicalScope(final ScriptObject proto) { - super(proto, PropertyMap.newMap()); + LexicalScope(final Global global) { + super(global, PropertyMap.newMap()); } @Override
--- a/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/objects/NativeJSAdapter.java Thu Apr 16 16:01:11 2015 -0700 @@ -160,7 +160,7 @@ } private static ScriptObject wrapAdaptee(final ScriptObject adaptee) { - return new JO(adaptee, JO.getInitialMap()); + return new JO(adaptee); } @Override
--- a/src/jdk/nashorn/internal/parser/JSONParser.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/parser/JSONParser.java Thu Apr 16 16:01:11 2015 -0700 @@ -41,6 +41,7 @@ import jdk.nashorn.internal.runtime.SpillProperty; import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.arrays.ArrayIndex; +import jdk.nashorn.internal.scripts.JD; import jdk.nashorn.internal.scripts.JO; import static jdk.nashorn.internal.parser.TokenType.STRING; @@ -54,11 +55,10 @@ final private String source; final private Global global; + final private boolean dualFields; final int length; int pos = 0; - private static PropertyMap EMPTY_MAP = PropertyMap.newMap(); - private static final int EOF = -1; private static final String TRUE = "true"; @@ -74,10 +74,11 @@ * @param source the source * @param global the global object */ - public JSONParser(final String source, final Global global ) { + public JSONParser(final String source, final Global global, final boolean dualFields) { this.source = source; this.global = global; this.length = source.length(); + this.dualFields = dualFields; } /** @@ -180,7 +181,7 @@ } private Object parseObject() { - PropertyMap propertyMap = EMPTY_MAP; + PropertyMap propertyMap = dualFields ? JD.getInitialMap() : JO.getInitialMap(); ArrayData arrayData = ArrayData.EMPTY_ARRAY; final ArrayList<Object> values = new ArrayList<>(); int state = STATE_EMPTY; @@ -241,36 +242,45 @@ return newArrayData.set(index, value, false); } - private static PropertyMap addObjectProperty(final PropertyMap propertyMap, final List<Object> values, + private PropertyMap addObjectProperty(final PropertyMap propertyMap, final List<Object> values, final String id, final Object value) { final Property oldProperty = propertyMap.findProperty(id); final PropertyMap newMap; - final Class<?> type = ObjectClassGenerator.OBJECT_FIELDS_ONLY ? Object.class : getType(value); + final Class<?> type; + final int flags; + if (dualFields) { + type = getType(value); + flags = Property.DUAL_FIELDS; + } else { + type = Object.class; + flags = 0; + } if (oldProperty != null) { values.set(oldProperty.getSlot(), value); - newMap = propertyMap.replaceProperty(oldProperty, new SpillProperty(id, 0, oldProperty.getSlot(), type));; + newMap = propertyMap.replaceProperty(oldProperty, new SpillProperty(id, flags, oldProperty.getSlot(), type));; } else { values.add(value); - newMap = propertyMap.addProperty(new SpillProperty(id, 0, propertyMap.size(), type)); + newMap = propertyMap.addProperty(new SpillProperty(id, flags, propertyMap.size(), type)); } return newMap; } private Object createObject(final PropertyMap propertyMap, final List<Object> values, final ArrayData arrayData) { - final long[] primitiveSpill = new long[values.size()]; + final long[] primitiveSpill = dualFields ? new long[values.size()] : null; final Object[] objectSpill = new Object[values.size()]; for (final Property property : propertyMap.getProperties()) { - if (property.getType() == Object.class) { + if (!dualFields || property.getType() == Object.class) { objectSpill[property.getSlot()] = values.get(property.getSlot()); } else { primitiveSpill[property.getSlot()] = ObjectClassGenerator.pack((Number) values.get(property.getSlot())); } } - final ScriptObject object = new JO(propertyMap, primitiveSpill, objectSpill); + final ScriptObject object = dualFields ? + new JD(propertyMap, primitiveSpill, objectSpill) : new JO(propertyMap, null, objectSpill); object.setInitialProto(global.getObjectPrototype()); object.setArray(arrayData); return object;
--- a/src/jdk/nashorn/internal/runtime/AccessorProperty.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/AccessorProperty.java Thu Apr 16 16:01:11 2015 -0700 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.runtime; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import static jdk.nashorn.internal.codegen.ObjectClassGenerator.PRIMITIVE_FIELD_TYPE; import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createGetter; import static jdk.nashorn.internal.codegen.ObjectClassGenerator.createSetter; @@ -98,7 +97,7 @@ objectSetters[i] = MH.asType(MH.setter(LOOKUP, structure, fieldName, typeClass), Lookup.SET_OBJECT_TYPE); } - if (!OBJECT_FIELDS_ONLY) { + if (!StructureLoader.isSingleFieldStructure(structure.getName())) { for (int i = 0; i < fieldCount; i++) { final String fieldNamePrimitive = getFieldName(i, PRIMITIVE_FIELD_TYPE); final Class<?> typeClass = PRIMITIVE_FIELD_TYPE.getTypeClass(); @@ -211,7 +210,7 @@ * @param setter the property setter or null if non writable, non configurable */ private AccessorProperty(final String key, final int flags, final int slot, final MethodHandle getter, final MethodHandle setter) { - super(key, flags | IS_BUILTIN | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot); + super(key, flags | IS_BUILTIN | DUAL_FIELDS | (getter.type().returnType().isPrimitive() ? IS_NASGEN_PRIMITIVE : 0), slot); assert !isSpill(); // we don't need to prep the setters these will never be invalidated as this is a nasgen @@ -221,18 +220,15 @@ final Class<?> setterType = setter == null ? null : setter.type().parameterType(1); assert setterType == null || setterType == getterType; - if (OBJECT_FIELDS_ONLY) { - primitiveGetter = primitiveSetter = null; + + if (getterType == int.class || getterType == long.class) { + primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE); + primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE); + } else if (getterType == double.class) { + primitiveGetter = MH.asType(MH.filterReturnValue(getter, ObjectClassGenerator.PACK_DOUBLE), Lookup.GET_PRIMITIVE_TYPE); + primitiveSetter = setter == null ? null : MH.asType(MH.filterArguments(setter, 1, ObjectClassGenerator.UNPACK_DOUBLE), Lookup.SET_PRIMITIVE_TYPE); } else { - if (getterType == int.class || getterType == long.class) { - primitiveGetter = MH.asType(getter, Lookup.GET_PRIMITIVE_TYPE); - primitiveSetter = setter == null ? null : MH.asType(setter, Lookup.SET_PRIMITIVE_TYPE); - } else if (getterType == double.class) { - primitiveGetter = MH.asType(MH.filterReturnValue(getter, ObjectClassGenerator.PACK_DOUBLE), Lookup.GET_PRIMITIVE_TYPE); - primitiveSetter = setter == null ? null : MH.asType(MH.filterArguments(setter, 1, ObjectClassGenerator.UNPACK_DOUBLE), Lookup.SET_PRIMITIVE_TYPE); - } else { - primitiveGetter = primitiveSetter = null; - } + primitiveGetter = primitiveSetter = null; } assert primitiveGetter == null || primitiveGetter.type() == Lookup.GET_PRIMITIVE_TYPE : primitiveGetter + "!=" + Lookup.GET_PRIMITIVE_TYPE; @@ -241,7 +237,7 @@ objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter; objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter; - setType(OBJECT_FIELDS_ONLY ? Object.class : getterType); + setType(getterType); } /** @@ -282,6 +278,9 @@ objectSetter = gs.objectSetters[slot]; primitiveSetter = gs.primitiveSetters[slot]; } + + // Always use dual fields except for single field structures + assert hasDualFields() != StructureLoader.isSingleFieldStructure(structure.getName()); } /** @@ -310,7 +309,7 @@ */ public AccessorProperty(final String key, final int flags, final Class<?> structure, final int slot, final Class<?> initialType) { this(key, flags, structure, slot); - setType(OBJECT_FIELDS_ONLY ? Object.class : initialType); + setType(hasDualFields() ? initialType : Object.class); } /** @@ -347,7 +346,7 @@ * @param initialValue initial value */ protected final void setInitialValue(final ScriptObject owner, final Object initialValue) { - setType(JSType.unboxedFieldType(initialValue)); + setType(hasDualFields() ? JSType.unboxedFieldType(initialValue) : Object.class); if (initialValue instanceof Integer) { invokeSetter(owner, ((Integer)initialValue).intValue()); } else if (initialValue instanceof Long) { @@ -363,7 +362,7 @@ * Initialize the type of a property */ protected final void initializeType() { - setType(OBJECT_FIELDS_ONLY ? Object.class : null); + setType(!hasDualFields() ? Object.class : null); } private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { @@ -670,7 +669,7 @@ @Override public final boolean canChangeType() { - if (OBJECT_FIELDS_ONLY) { + if (!hasDualFields()) { return false; } // Return true for currently undefined even if non-writable/configurable to allow initialization of ES6 CONST.
--- a/src/jdk/nashorn/internal/runtime/AllocationStrategy.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/AllocationStrategy.java Thu Apr 16 16:01:11 2015 -0700 @@ -44,6 +44,9 @@ /** Number of fields in the allocated object */ private final int fieldCount; + /** Whether to use dual field representation */ + private final boolean dualFields; + /** Name of class where allocator function resides */ private transient String allocatorClassName; @@ -53,15 +56,17 @@ /** * Construct an allocation strategy with the given map and class name. * @param fieldCount number of fields in the allocated object + * @param dualFields whether to use dual field representation */ - public AllocationStrategy(final int fieldCount) { + public AllocationStrategy(final int fieldCount, final boolean dualFields) { this.fieldCount = fieldCount; + this.dualFields = dualFields; } private String getAllocatorClassName() { if (allocatorClassName == null) { // These classes get loaded, so an interned variant of their name is most likely around anyway. - allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount)).intern(); + allocatorClassName = Compiler.binaryName(ObjectClassGenerator.getClassName(fieldCount, dualFields)).intern(); } return allocatorClassName; }
--- a/src/jdk/nashorn/internal/runtime/Context.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/Context.java Thu Apr 16 16:01:11 2015 -0700 @@ -131,6 +131,23 @@ private static MethodType CREATE_PROGRAM_FUNCTION_TYPE = MethodType.methodType(ScriptFunction.class, ScriptObject.class); /** + * Should scripts use only object slots for fields, or dual long/object slots? The default + * behaviour is to couple this to optimistic types, using dual representation if optimistic types are enabled + * and single field representation otherwise. This can be overridden by setting either the "nashorn.fields.objects" + * or "nashorn.fields.dual" system property. + */ + private final FieldMode fieldMode; + + private static enum FieldMode { + /** Value for automatic field representation depending on optimistic types setting */ + AUTO, + /** Value for object field representation regardless of optimistic types setting */ + OBJECTS, + /** Value for dual primitive/object field representation regardless of optimistic types setting */ + DUAL + } + + /** * Keeps track of which builtin prototypes and properties have been relinked * Currently we are conservative and associate the name of a builtin class with all * its properties, so it's enough to invalidate a property to break all assumptions @@ -434,7 +451,7 @@ * @param appLoader application class loader */ public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) { - this(options, errors, appLoader, (ClassFilter)null); + this(options, errors, appLoader, null); } /** @@ -522,6 +539,14 @@ getErr().println("nashorn full version " + Version.fullVersion()); } + if (Options.getBooleanProperty("nashorn.fields.dual")) { + fieldMode = FieldMode.DUAL; + } else if (Options.getBooleanProperty("nashorn.fields.objects")) { + fieldMode = FieldMode.OBJECTS; + } else { + fieldMode = FieldMode.AUTO; + } + initLoggers(); } @@ -576,6 +601,14 @@ } /** + * Should scripts compiled by this context use dual field representation? + * @return true if using dual fields, false for object-only fields + */ + public boolean useDualFields() { + return fieldMode == FieldMode.DUAL || (fieldMode == FieldMode.AUTO && env._optimistic_types); + } + + /** * Get the PropertyMap of the current global scope * @return the property map of the current global scope */
--- a/src/jdk/nashorn/internal/runtime/JSONFunctions.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/JSONFunctions.java Thu Apr 16 16:01:11 2015 -0700 @@ -72,7 +72,8 @@ public static Object parse(final Object text, final Object reviver) { final String str = JSType.toString(text); final Global global = Context.getGlobal(); - final JSONParser parser = new JSONParser(str, global); + final boolean dualFields = ((ScriptObject) global).useDualFields(); + final JSONParser parser = new JSONParser(str, global, dualFields); final Object value; try {
--- a/src/jdk/nashorn/internal/runtime/JSType.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/JSType.java Thu Apr 16 16:01:11 2015 -0700 @@ -26,7 +26,6 @@ package jdk.nashorn.internal.runtime; import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; @@ -1973,10 +1972,6 @@ * @return primive type or Object.class if not primitive */ public static Class<?> unboxedFieldType(final Object o) { - if (OBJECT_FIELDS_ONLY) { - return Object.class; - } - if (o == null) { return Object.class; } else if (o.getClass() == Integer.class) {
--- a/src/jdk/nashorn/internal/runtime/Property.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/Property.java Thu Apr 16 16:01:11 2015 -0700 @@ -96,6 +96,9 @@ /** Is this property an ES6 lexical binding? */ public static final int IS_LEXICAL_BINDING = 1 << 10; + /** Does this property support dual field representation? */ + public static final int DUAL_FIELDS = 1 << 11; + /** Property key. */ private final String key; @@ -286,7 +289,7 @@ * @return true if parameter */ public boolean isParameter() { - return (flags & IS_PARAMETER) == IS_PARAMETER; + return (flags & IS_PARAMETER) != 0; } /** @@ -294,7 +297,7 @@ * @return true if has arguments */ public boolean hasArguments() { - return (flags & HAS_ARGUMENTS) == HAS_ARGUMENTS; + return (flags & HAS_ARGUMENTS) != 0; } /** @@ -316,7 +319,7 @@ * @return true if this is a bound property */ public boolean isBound() { - return (flags & IS_BOUND) == IS_BOUND; + return (flags & IS_BOUND) != 0; } /** @@ -325,7 +328,7 @@ * @return true if this is a block-scoped variable */ public boolean needsDeclaration() { - return (flags & NEEDS_DECLARATION) == NEEDS_DECLARATION; + return (flags & NEEDS_DECLARATION) != 0; } /** @@ -346,16 +349,6 @@ } /** - * Check if a flag is set for a property - * @param property property - * @param flag flag to check - * @return true if flag is set - */ - public static boolean checkFlag(final Property property, final int flag) { - return (property.getFlags() & flag) == flag; - } - - /** * Get the flags for this property * @return property flags */ @@ -364,16 +357,6 @@ } /** - * Get the modify flags for this property. The modify flags are the ECMA 8.6.1 - * flags that decide if the Property is writable, configurable and/or enumerable. - * - * @return modify flags for property - */ - public int getModifyFlags() { - return flags & MODIFY_MASK; - } - - /** * Remove property flags from the property. Properties are immutable here, * so any property change that results in a smaller flag set results in the * property being cloned. Use only the return value @@ -715,7 +698,7 @@ * @return whether this property is a function declaration or not. */ public boolean isFunctionDeclaration() { - return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION; + return (flags & IS_FUNCTION_DECLARATION) != 0; } /** @@ -723,6 +706,14 @@ * @return true if this property represents a lexical binding. */ public boolean isLexicalBinding() { - return (flags & IS_LEXICAL_BINDING) == IS_LEXICAL_BINDING; + return (flags & IS_LEXICAL_BINDING) != 0; + } + + /** + * Does this property support dual fields for both primitive and object values? + * @return true if supports dual fields + */ + public boolean hasDualFields() { + return (flags & DUAL_FIELDS) != 0; } }
--- a/src/jdk/nashorn/internal/runtime/PropertyMap.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/PropertyMap.java Thu Apr 16 16:01:11 2015 -0700 @@ -199,12 +199,21 @@ } /** + * Return a sharable empty map for the given object class. + * @param clazz the base object class + * @return New empty {@link PropertyMap}. + */ + public static PropertyMap newMap(final Class<? extends ScriptObject> clazz) { + return new PropertyMap(EMPTY_HASHMAP, clazz.getName(), 0, 0, 0, false); + } + + /** * Return a sharable empty map. * * @return New empty {@link PropertyMap}. */ public static PropertyMap newMap() { - return new PropertyMap(EMPTY_HASHMAP, JO.class.getName(), 0, 0, 0, false); + return newMap(JO.class); } /**
--- a/src/jdk/nashorn/internal/runtime/ScriptObject.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Apr 16 16:01:11 2015 -0700 @@ -28,7 +28,6 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCallNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall; import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import static jdk.nashorn.internal.lookup.Lookup.MH; import static jdk.nashorn.internal.runtime.ECMAErrors.referenceError; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; @@ -146,12 +145,6 @@ /** Area for reference properties added to object after instantiation, see {@link AccessorProperty} */ protected Object[] objectSpill; - /** - * Number of elements in the spill. This may be less than the spill array lengths, if not all of - * the allocated memory is in use - */ - private int spillLength; - /** Indexed array data. */ private ArrayData arrayData; @@ -171,12 +164,6 @@ /** Method handle for getting the array data */ public static final Call GET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArray", ArrayData.class); - /** Method handle for getting the property map - debugging purposes */ - public static final Call GET_MAP = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getMap", PropertyMap.class); - - /** Method handle for setting the array data */ - public static final Call SET_ARRAY = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArray", void.class, ArrayData.class); - /** Method handle for getting a function argument at a given index. Used from MapCreator */ public static final Call GET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class); @@ -259,8 +246,7 @@ this(map); this.primitiveSpill = primitiveSpill; this.objectSpill = objectSpill; - assert primitiveSpill.length == objectSpill.length : " primitive spill pool size is not the same length as object spill pool size"; - this.spillLength = spillAllocationLength(primitiveSpill.length); + assert primitiveSpill == null || primitiveSpill.length == objectSpill.length : " primitive spill pool size is not the same length as object spill pool size"; } /** @@ -727,7 +713,7 @@ setArray(getArray().ensure(longIndex)); doesNotHaveEnsureDelete(longIndex, oldLength, false); } - setArray(getArray().set(index,value, false)); + setArray(getArray().set(index, value, false)); } private void checkIntegerKey(final String key) { @@ -976,10 +962,10 @@ * @param setter setter for {@link UserAccessorProperty}, null if not present or N/A */ protected final void initUserAccessors(final String key, final int propertyFlags, final ScriptFunction getter, final ScriptFunction setter) { - final int slot = spillLength; - ensureSpillSize(spillLength); //arguments=slot0, caller=slot0 + final PropertyMap oldMap = getMap(); + final int slot = oldMap.getFreeSpillSlot(); + ensureSpillSize(slot); objectSpill[slot] = new UserAccessorProperty.Accessors(getter, setter); - final PropertyMap oldMap = getMap(); Property newProperty; PropertyMap newMap; do { @@ -1006,19 +992,12 @@ final int slot = uc.getSlot(); assert uc.getLocalType() == Object.class; - if (slot >= spillLength) { - uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); - } else { - final UserAccessorProperty.Accessors gs = uc.getAccessors(this); //this crashes - if (gs == null) { - uc.setAccessors(this, getMap(), new UserAccessorProperty.Accessors(getter, setter)); - } else { - //reuse existing getter setter for speed - gs.set(getter, setter); - if (uc.getFlags() == propertyFlags) { - return oldProperty; - } - } + final UserAccessorProperty.Accessors gs = uc.getAccessors(this); //this crashes + assert gs != null; + //reuse existing getter setter for speed + gs.set(getter, setter); + if (uc.getFlags() == propertyFlags) { + return oldProperty; } newProperty = new UserAccessorProperty(uc.getKey(), propertyFlags, slot); } else { @@ -2053,8 +2032,6 @@ protoSwitchPoint = null; } - assert OBJECT_FIELDS_ONLY || guard != null : "we always need a map guard here"; - final GuardedInvocation inv = new GuardedInvocation(mh, guard, protoSwitchPoint, exception); return inv.addSwitchPoint(findBuiltinSwitchPoint(name)); } @@ -2531,13 +2508,14 @@ /** * Add a spill property for the given key. - * @param key Property key. - * @param propertyFlags Property flags. + * @param key Property key. + * @param flags Property flags. * @return Added property. */ - private Property addSpillProperty(final String key, final int propertyFlags, final Object value, final boolean hasInitialValue) { + private Property addSpillProperty(final String key, final int flags, final Object value, final boolean hasInitialValue) { final PropertyMap propertyMap = getMap(); final int fieldSlot = propertyMap.getFreeFieldSlot(); + final int propertyFlags = flags | (useDualFields() ? Property.DUAL_FIELDS : 0); Property property; if (fieldSlot > -1) { @@ -2562,7 +2540,7 @@ * @return Setter method handle. */ MethodHandle addSpill(final Class<?> type, final String key) { - return addSpillProperty(key, 0, null, false).getSetter(OBJECT_FIELDS_ONLY ? Object.class : type, getMap()); + return addSpillProperty(key, 0, null, false).getSetter(type, getMap()); } /** @@ -2649,9 +2627,9 @@ final int spreadArgs = mh.type().parameterCount() - callSiteParamCount + 1; return MH.filterArguments( MH.asSpreader( - mh, - Object[].class, - spreadArgs), + mh, + Object[].class, + spreadArgs), callSiteParamCount - 1, MH.insertArguments( TRUNCATINGFILTER, @@ -3739,24 +3717,32 @@ return uc; } + /** + * Returns {@code true} if properties for this object should use dual field mode, {@code false} otherwise. + * @return {@code true} if dual fields should be used. + */ + protected boolean useDualFields() { + return !StructureLoader.isSingleFieldStructure(getClass().getName()); + } + Object ensureSpillSize(final int slot) { - if (slot < spillLength) { + final int oldLength = objectSpill == null ? 0 : objectSpill.length; + if (slot < oldLength) { return this; } final int newLength = alignUp(slot + 1, SPILL_RATE); final Object[] newObjectSpill = new Object[newLength]; - final long[] newPrimitiveSpill = OBJECT_FIELDS_ONLY ? null : new long[newLength]; + final long[] newPrimitiveSpill = useDualFields() ? new long[newLength] : null; if (objectSpill != null) { - System.arraycopy(objectSpill, 0, newObjectSpill, 0, spillLength); - if (!OBJECT_FIELDS_ONLY) { - System.arraycopy(primitiveSpill, 0, newPrimitiveSpill, 0, spillLength); + System.arraycopy(objectSpill, 0, newObjectSpill, 0, oldLength); + if (primitiveSpill != null && newPrimitiveSpill != null) { + System.arraycopy(primitiveSpill, 0, newPrimitiveSpill, 0, oldLength); } } this.primitiveSpill = newPrimitiveSpill; this.objectSpill = newObjectSpill; - this.spillLength = newLength; return this; }
--- a/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/SetMethodCreator.java Thu Apr 16 16:01:11 2015 -0700 @@ -232,14 +232,18 @@ } private SetMethod createNewFieldSetter(final SwitchPoint builtinSwitchPoint) { - return createNewSetter(new AccessorProperty(getName(), 0, sobj.getClass(), getMap().getFreeFieldSlot(), type), builtinSwitchPoint); + return createNewSetter(new AccessorProperty(getName(), getFlags(sobj), sobj.getClass(), getMap().getFreeFieldSlot(), type), builtinSwitchPoint); } private SetMethod createNewSpillPropertySetter(final SwitchPoint builtinSwitchPoint) { - return createNewSetter(new SpillProperty(getName(), 0, getMap().getFreeSpillSlot(), type), builtinSwitchPoint); + return createNewSetter(new SpillProperty(getName(), getFlags(sobj), getMap().getFreeSpillSlot(), type), builtinSwitchPoint); } private PropertyMap getNewMap(final Property property) { return getMap().addProperty(property); } + + private static int getFlags(final ScriptObject scriptObject) { + return scriptObject.useDualFields() ? Property.DUAL_FIELDS : 0; + } }
--- a/src/jdk/nashorn/internal/runtime/SpillProperty.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/SpillProperty.java Thu Apr 16 16:01:11 2015 -0700 @@ -25,7 +25,6 @@ package jdk.nashorn.internal.runtime; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.OBJECT_FIELDS_ONLY; import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; @@ -139,11 +138,11 @@ } } - private static MethodHandle primitiveGetter(final int slot) { - return OBJECT_FIELDS_ONLY ? null : Accessors.getCached(slot, true, true); + private static MethodHandle primitiveGetter(final int slot, final int flags) { + return (flags & DUAL_FIELDS) == DUAL_FIELDS ? Accessors.getCached(slot, true, true) : null; } - private static MethodHandle primitiveSetter(final int slot) { - return OBJECT_FIELDS_ONLY ? null : Accessors.getCached(slot, true, false); + private static MethodHandle primitiveSetter(final int slot, final int flags) { + return (flags & DUAL_FIELDS) == DUAL_FIELDS ? Accessors.getCached(slot, true, false) : null; } private static MethodHandle objectGetter(final int slot) { return Accessors.getCached(slot, false, true); @@ -160,8 +159,7 @@ * @param slot spill slot */ public SpillProperty(final String key, final int flags, final int slot) { - super(key, flags, slot, primitiveGetter(slot), primitiveSetter(slot), objectGetter(slot), objectSetter(slot)); - assert !OBJECT_FIELDS_ONLY || getLocalType() == Object.class; + super(key, flags, slot, primitiveGetter(slot, flags), primitiveSetter(slot, flags), objectGetter(slot), objectSetter(slot)); } /** @@ -173,7 +171,7 @@ */ public SpillProperty(final String key, final int flags, final int slot, final Class<?> initialType) { this(key, flags, slot); - setType(OBJECT_FIELDS_ONLY ? Object.class : initialType); + setType(hasDualFields() ? initialType : Object.class); } SpillProperty(final String key, final int flags, final int slot, final ScriptObject owner, final Object initialValue) { @@ -216,8 +214,8 @@ @Override void initMethodHandles(final Class<?> structure) { final int slot = getSlot(); - primitiveGetter = primitiveGetter(slot); - primitiveSetter = primitiveSetter(slot); + primitiveGetter = primitiveGetter(slot, getFlags()); + primitiveSetter = primitiveSetter(slot, getFlags()); objectGetter = objectGetter(slot); objectSetter = objectSetter(slot); }
--- a/src/jdk/nashorn/internal/runtime/StructureLoader.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/StructureLoader.java Thu Apr 16 16:01:11 2015 -0700 @@ -27,7 +27,8 @@ import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE; import static jdk.nashorn.internal.codegen.Compiler.binaryName; -import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_DUAL_FIELD_PREFIX; +import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_SINGLE_FIELD_PREFIX; import java.security.ProtectionDomain; import jdk.nashorn.internal.codegen.ObjectClassGenerator; @@ -36,7 +37,8 @@ * Responsible for on the fly construction of structure classes. */ final class StructureLoader extends NashornLoader { - private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); + private static final String SINGLE_FIELD_PREFIX = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_SINGLE_FIELD_PREFIX.symbolName(); + private static final String DUAL_FIELD_PREFIX = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_DUAL_FIELD_PREFIX.symbolName(); /** * Constructor. @@ -45,14 +47,39 @@ super(parent); } + /** + * Returns true if the class name represents a structure object with dual primitive/object fields. + * @param name a class name + * @return true if a dual field structure class + */ + private static boolean isDualFieldStructure(final String name) { + return name.startsWith(DUAL_FIELD_PREFIX); + } + + /** + * Returns true if the class name represents a structure object with single object-only fields. + * @param name a class name + * @return true if a single field structure class + */ + static boolean isSingleFieldStructure(final String name) { + return name.startsWith(SINGLE_FIELD_PREFIX); + } + + /** + * Returns true if the class name represents a Nashorn structure object. + * @param name a class name + * @return true if a structure class + */ static boolean isStructureClass(final String name) { - return name.startsWith(JS_OBJECT_PREFIX_EXTERNAL); + return isDualFieldStructure(name) || isSingleFieldStructure(name); } @Override protected Class<?> findClass(final String name) throws ClassNotFoundException { - if (isStructureClass(name)) { - return generateClass(name, name.substring(JS_OBJECT_PREFIX_EXTERNAL.length())); + if (isDualFieldStructure(name)) { + return generateClass(name, name.substring(DUAL_FIELD_PREFIX.length()), true); + } else if (isSingleFieldStructure(name)) { + return generateClass(name, name.substring(SINGLE_FIELD_PREFIX.length()), false); } return super.findClass(name); } @@ -63,10 +90,10 @@ * @param descriptor Layout descriptor. * @return Generated class. */ - private Class<?> generateClass(final String name, final String descriptor) { + private Class<?> generateClass(final String name, final String descriptor, final boolean dualFields) { final Context context = Context.getContextTrusted(); - final byte[] code = new ObjectClassGenerator(context).generate(descriptor); + final byte[] code = new ObjectClassGenerator(context, dualFields).generate(descriptor); return defineClass(name, code, 0, code.length, new ProtectionDomain(null, getPermissions(null))); } }
--- a/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java Thu Apr 16 16:01:11 2015 -0700 @@ -74,17 +74,16 @@ * of object fields only, it is fine. However, with dual fields, in order to get * performance on benchmarks with a lot of object instantiation and then field * reassignment, it can take slightly more relinks to become stable with type - * changes swapping out an entire proprety map and making a map guard fail. - * Therefore the relink threshold is set to 16 for dual fields (now the default). - * This doesn't seem to have any other negative performance implication. + * changes swapping out an entire property map and making a map guard fail. + * Since we need to set this value statically it must work with possibly changing + * optimistic types and dual fields settings. A higher value does not seem to have + * any other negative performance implication when running with object-only fields, + * so we choose a higher value here. * * See for example octane.gbemu, run with --log=fields:warning to study * megamorphic behavior */ - private static final int NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD = - ObjectClassGenerator.OBJECT_FIELDS_ONLY ? - 8 : - 16; + private static final int NASHORN_DEFAULT_UNSTABLE_RELINK_THRESHOLD = 16; // do not create me!! private Bootstrap() {
--- a/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/runtime/linker/NashornGuards.java Thu Apr 16 16:01:11 2015 -0700 @@ -33,7 +33,6 @@ import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.LinkRequest; import jdk.nashorn.api.scripting.JSObject; -import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.objects.Global; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; @@ -123,7 +122,7 @@ */ static boolean needsGuard(final Property property, final CallSiteDescriptor desc) { return property == null || property.isConfigurable() - || property.isBound() || !ObjectClassGenerator.OBJECT_FIELDS_ONLY + || property.isBound() || property.hasDualFields() || !NashornCallSiteDescriptor.isFastScope(desc) || property.canChangeType(); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/jdk/nashorn/internal/scripts/JD.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.scripts; + +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.ScriptObject; + +/** + * Empty object class for dual primitive-object fields. + */ +public class JD extends ScriptObject { + + private static final PropertyMap map$ = PropertyMap.newMap(JD.class); + + /** + * Returns the initial property map to be used. + * @return the initial property map. + */ + public static PropertyMap getInitialMap() { + return map$; + } + + /** + * Constructor given an initial property map + * + * @param map the property map + */ + public JD(final PropertyMap map) { + super(map); + } + + /** + * Constructor given an initial prototype and the default initial property map. + * + * @param proto the prototype object + */ + public JD(final ScriptObject proto) { + super(proto, getInitialMap()); + } + + /** + * Constructor that takes a pre-initialized spill pool. Used by + * {@link jdk.nashorn.internal.codegen.SpillObjectCreator} and + * {@link jdk.nashorn.internal.parser.JSONParser} for initializing object literals + * + * @param map property map + * @param primitiveSpill primitive spill pool + * @param objectSpill reference spill pool + */ + public JD(final PropertyMap map, final long[] primitiveSpill, final Object[] objectSpill) { + super(map, primitiveSpill, objectSpill); + } + + /** + * A method handle of this method is passed to the ScriptFunction constructor. + * + * @param map the property map to use for allocatorMap + * + * @return newly allocated ScriptObject + */ + public static ScriptObject allocate(final PropertyMap map) { + return new JD(map); + } +} +
--- a/src/jdk/nashorn/internal/scripts/JO.java Wed Apr 15 14:45:25 2015 -0700 +++ b/src/jdk/nashorn/internal/scripts/JO.java Thu Apr 16 16:01:11 2015 -0700 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,11 +29,11 @@ import jdk.nashorn.internal.runtime.ScriptObject; /** - * Empty object class. + * Empty object class for object-only fields. */ public class JO extends ScriptObject { - private static final PropertyMap map$ = PropertyMap.newMap(); + private static final PropertyMap map$ = PropertyMap.newMap(JO.class); /** * Returns the initial property map to be used. @@ -53,13 +53,12 @@ } /** - * Constructor given an initial prototype and an initial property map. + * Constructor given an initial prototype and the default initial property map. * * @param proto the prototype object - * @param map the property map */ - public JO(final ScriptObject proto, final PropertyMap map) { - super(proto, map); + public JO(final ScriptObject proto) { + super(proto, getInitialMap()); } /** @@ -86,3 +85,4 @@ return new JO(map); } } +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/basic/JDK-8077955.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8077955: Undeclared globals in eval code should not be handled as fast scope + * + * @test + * @run + * @fork + * @option -Dnashorn.fields.objects + */ + +var m = new javax.script.ScriptEngineManager(); +var e = m.getEngineByName('js'); + +// leave the whitespace - need both eval("e") at same column for this test! + +e.eval('function f(e) { eval("e") } f()'); +e.eval('function f() { var e = 33; eval("e") } f()'); + +function f() { + Function.call.call(function x() { eval("x") }); eval("x") +} + +try { + f(); + fail("Should have thrown ReferenceError"); +} catch (e) { + if (! (e instanceof ReferenceError)) { + fail("ReferenceError expected but got " + e); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/script/nosecurity/JDK-8067215.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8067215: Disable dual fields when not using optimistic types + * + * @test + * @run + * @option -Dnashorn.debug=true + * @fork + */ + +var intType = Java.type("int"); +var doubleType = Java.type("double"); +var longType = Java.type("long"); +var objectType = Java.type("java.lang.Object"); + +var Context = Java.type("jdk.nashorn.internal.runtime.Context"); +var JSType = Java.type("jdk.nashorn.internal.runtime.JSType"); + +var context = Context.getContext(); +var dualFields = context.useDualFields(); +var optimisticTypes = context.getEnv()._optimistic_types; + +if (dualFields != optimisticTypes) { + throw new Error("Wrong dual fields setting"); +} + +function testMap(obj) { + obj.x = "foo"; + obj["y"] = 0; + Object.defineProperty(obj, "z", {value: 0.5}); + var map = Debug.map(obj); + for (var key in obj) { + var prop = map.findProperty(key); + if (prop.hasDualFields() !== dualFields) { + throw new Error("Wrong property flags: " + prop); + } + if (prop.getType() != getExpectedType(obj[key])) { + throw new Error("Wrong property type: " + prop.getType() + " // " + getExpectedType(obj[key])); + + } + } +} + +function getExpectedType(value) { + if (!dualFields) { + return objectType.class; + } + if (JSType.isRepresentableAsInt(value)) { + return intType.class; + } + if (JSType.isRepresentableAsLong(value)) { + return longType.class; + } + if (JSType.isNumber(value)) { + return doubleType.class; + } + return objectType.class; +} + +var o = { + a: 1, + b: 2.5, + c: 0x10000000000, + d: true +}; + +function C() { + this.a = 1; + this.b = 2.5; + this.c = 0x10000000000; + this.d = true; +} + +var a = 1; +var b = 2.5; +var c = 0x10000000000; +var d = true; + +testMap(o); +testMap(new C()); +testMap(JSON.parse('{ "a": 1, "b": 2.5, "c": 1099511627776, "d": true }')); +testMap(this);
--- a/test/script/sandbox/interfaceimpl.js Wed Apr 15 14:45:25 2015 -0700 +++ b/test/script/sandbox/interfaceimpl.js Thu Apr 16 16:01:11 2015 -0700 @@ -29,8 +29,8 @@ * @security */ -var Window = Java.type("jdk.nashorn.api.scripting.Window"); -var WindowEventHandler = Java.type("jdk.nashorn.api.scripting.WindowEventHandler"); +var Window = Java.type("jdk.nashorn.api.scripting.test.Window"); +var WindowEventHandler = Java.type("jdk.nashorn.api.scripting.test.WindowEventHandler"); var w = new Window();
--- a/test/script/trusted/JDK-8025629.js Wed Apr 15 14:45:25 2015 -0700 +++ b/test/script/trusted/JDK-8025629.js Thu Apr 16 16:01:11 2015 -0700 @@ -28,6 +28,6 @@ * @run */ -load("classpath:jdk/nashorn/internal/runtime/resources/load_test.js") +load("classpath:jdk/nashorn/internal/runtime/test/resources/load_test.js") Assert.assertEquals(loadedFunc("hello"), "HELLO");
--- a/test/src/META-INF/services/java.sql.Driver Wed Apr 15 14:45:25 2015 -0700 +++ b/test/src/META-INF/services/java.sql.Driver Thu Apr 16 16:01:11 2015 -0700 @@ -1,1 +1,1 @@ -jdk.nashorn.api.NashornSQLDriver +jdk.nashorn.api.test.NashornSQLDriver
--- a/test/src/jdk/internal/dynalink/beans/CallerSensitiveTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.dynalink.beans; - -import jdk.nashorn.test.models.ClassLoaderAware; -import org.testng.annotations.Test; - -@SuppressWarnings("javadoc") -public class CallerSensitiveTest { - @Test - public void testCallerSensitive() { - BeansLinker.getLinkerForClass(ClassLoaderAware.class); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/internal/dynalink/beans/test/CallerSensitiveTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.dynalink.beans.test; + +import jdk.internal.dynalink.beans.BeansLinker; +import jdk.nashorn.test.models.ClassLoaderAware; +import org.testng.annotations.Test; + +@SuppressWarnings("javadoc") +public class CallerSensitiveTest { + @Test + public void testCallerSensitive() { + BeansLinker.getLinkerForClass(ClassLoaderAware.class); + } +}
--- a/test/src/jdk/nashorn/api/NashornSQLDriver.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api; - -import java.sql.Connection; -import java.sql.Driver; -import java.sql.DriverManager; -import java.sql.DriverPropertyInfo; -import java.sql.SQLException; -import java.sql.SQLFeatureNotSupportedException; -import java.util.Properties; -import java.util.logging.Logger; - -/** - * A dummy SQL driver for testing purpose. - */ -public final class NashornSQLDriver implements Driver { - static { - try { - DriverManager.registerDriver(new NashornSQLDriver(), null); - } catch (final SQLException se) { - throw new RuntimeException(se); - } - } - - @Override - public boolean acceptsURL(final String url) { - return url.startsWith("jdbc:nashorn:"); - } - - @Override - public Connection connect(final String url, final Properties info) { - throw new UnsupportedOperationException("I am a dummy!!"); - } - - @Override - public int getMajorVersion() { - return -1; - } - - @Override - public int getMinorVersion() { - return -1; - } - - @Override - public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) { - return new DriverPropertyInfo[0]; - } - - @Override - public boolean jdbcCompliant() { - // no way! - return false; - } - - @Override - public Logger getParentLogger() throws SQLFeatureNotSupportedException { - throw new SQLFeatureNotSupportedException(); - } -}
--- a/test/src/jdk/nashorn/api/javaaccess/ArrayConversionTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertFalse; -import static org.testng.AssertJUnit.assertNull; -import static org.testng.AssertJUnit.assertTrue; -import java.util.Arrays; -import java.util.List; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -@SuppressWarnings("javadoc") -public class ArrayConversionTest { - private static ScriptEngine e = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() { - e = new ScriptEngineManager().getEngineByName("nashorn"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - } - - @Test - public void testIntArrays() throws ScriptException { - runTest("assertNullIntArray", "null"); - runTest("assertEmptyIntArray", "[]"); - runTest("assertSingle42IntArray", "[42]"); - runTest("assertSingle42IntArray", "['42']"); - runTest("assertIntArrayConversions", "[false, true, NaN, Infinity, -Infinity, 0.4, 0.6, null, undefined, [], {}, [1], [1, 2]]"); - } - - @Test - public void testIntIntArrays() throws ScriptException { - runTest("assertNullIntIntArray", "null"); - runTest("assertEmptyIntIntArray", "[]"); - runTest("assertSingleEmptyIntIntArray", "[[]]"); - runTest("assertSingleNullIntIntArray", "[null]"); - runTest("assertLargeIntIntArray", "[[false], [1], [2, 3], [4, 5, 6], ['7', {valueOf: function() { return 8 }}]]"); - } - - @Test - public void testObjectObjectArrays() throws ScriptException { - runTest("assertLargeObjectObjectArray", "[[false], [1], ['foo', 42.3], [{x: 17}]]"); - } - - @Test - public void testBooleanArrays() throws ScriptException { - runTest("assertBooleanArrayConversions", "[false, true, '', 'false', 0, 1, 0.4, 0.6, {}, [], [false], [true], NaN, Infinity, null, undefined]"); - } - - @Test - public void testArrayAmbiguity() throws ScriptException { - runTest("x", "'abc'"); - runTest("x", "['foo', 'bar']"); - } - - @Test - public void testListArrays() throws ScriptException { - runTest("assertListArray", "[['foo', 'bar'], ['apple', 'orange']]"); - } - - @Test - public void testVarArgs() throws ScriptException { - // Sole NativeArray in vararg position becomes vararg array itself - runTest("assertVarArg_42_17", "[42, 17]"); - // NativeArray in vararg position becomes an argument if there are more arguments - runTest("assertVarArg_array_17", "[42], 18"); - // Only NativeArray is converted to vararg array, other objects (e.g. a function) aren't - runTest("assertVarArg_function", "function() { return 'Hello' }"); - } - - private static void runTest(final String testMethodName, final String argument) throws ScriptException { - e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")"); - } - - public static void assertNullIntArray(final int[] array) { - assertNull(array); - } - - public static void assertNullIntIntArray(final int[][] array) { - assertNull(array); - } - - public static void assertEmptyIntArray(final int[] array) { - assertEquals(0, array.length); - } - - public static void assertSingle42IntArray(final int[] array) { - assertEquals(1, array.length); - assertEquals(42, array[0]); - } - - - public static void assertIntArrayConversions(final int[] array) { - assertEquals(13, array.length); - assertEquals(0, array[0]); // false - assertEquals(1, array[1]); // true - assertEquals(0, array[2]); // NaN - assertEquals(0, array[3]); // Infinity - assertEquals(0, array[4]); // -Infinity - assertEquals(0, array[5]); // 0.4 - assertEquals(0, array[6]); // 0.6 - floor, not round - assertEquals(0, array[7]); // null - assertEquals(0, array[8]); // undefined - assertEquals(0, array[9]); // [] - assertEquals(0, array[10]); // {} - assertEquals(1, array[11]); // [1] - assertEquals(0, array[12]); // [1, 2] - } - - public static void assertEmptyIntIntArray(final int[][] array) { - assertEquals(0, array.length); - } - - public static void assertSingleEmptyIntIntArray(final int[][] array) { - assertEquals(1, array.length); - assertTrue(Arrays.equals(new int[0], array[0])); - } - - public static void assertSingleNullIntIntArray(final int[][] array) { - assertEquals(1, array.length); - assertNull(null, array[0]); - } - - public static void assertLargeIntIntArray(final int[][] array) { - assertEquals(5, array.length); - assertTrue(Arrays.equals(new int[] { 0 }, array[0])); - assertTrue(Arrays.equals(new int[] { 1 }, array[1])); - assertTrue(Arrays.equals(new int[] { 2, 3 }, array[2])); - assertTrue(Arrays.equals(new int[] { 4, 5, 6 }, array[3])); - assertTrue(Arrays.equals(new int[] { 7, 8 }, array[4])); - } - - public static void assertLargeObjectObjectArray(final Object[][] array) throws ScriptException { - assertEquals(4, array.length); - assertTrue(Arrays.equals(new Object[] { Boolean.FALSE }, array[0])); - assertTrue(Arrays.equals(new Object[] { 1 }, array[1])); - assertTrue(Arrays.equals(new Object[] { "foo", 42.3d }, array[2])); - assertEquals(1, array[3].length); - e.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", array[3][0]); - assertEquals(17, e.eval("obj.x")); - } - - public static void assertBooleanArrayConversions(final boolean[] array) { - assertEquals(16, array.length); - assertFalse(array[0]); // false - assertTrue(array[1]); // true - assertFalse(array[2]); // '' - assertTrue(array[3]); // 'false' (yep, every non-empty string converts to true) - assertFalse(array[4]); // 0 - assertTrue(array[5]); // 1 - assertTrue(array[6]); // 0.4 - assertTrue(array[7]); // 0.6 - assertTrue(array[8]); // {} - assertTrue(array[9]); // [] - assertTrue(array[10]); // [false] - assertTrue(array[11]); // [true] - assertFalse(array[12]); // NaN - assertTrue(array[13]); // Infinity - assertFalse(array[14]); // null - assertFalse(array[15]); // undefined - } - - public static void assertListArray(final List<?>[] array) { - assertEquals(2, array.length); - assertEquals(Arrays.asList("foo", "bar"), array[0]); - assertEquals(Arrays.asList("apple", "orange"), array[1]); - } - - public static void assertVarArg_42_17(final Object... args) { - assertEquals(2, args.length); - assertEquals(42, ((Number)args[0]).intValue()); - assertEquals(17, ((Number)args[1]).intValue()); - } - - public static void assertVarArg_array_17(final Object... args) throws ScriptException { - assertEquals(2, args.length); - e.getBindings(ScriptContext.ENGINE_SCOPE).put("arr", args[0]); - assertTrue((Boolean)e.eval("arr instanceof Array && arr.length == 1 && arr[0] == 42")); - assertEquals(18, ((Number)args[1]).intValue()); - } - - public static void assertVarArg_function(final Object... args) throws ScriptException { - assertEquals(1, args.length); - e.getBindings(ScriptContext.ENGINE_SCOPE).put("fn", args[0]); - assertEquals("Hello", e.eval("fn()")); - } - - - - public static void x(final String y) { - assertEquals("abc", y); - } - public static void x(final String[] y) { - assertTrue(Arrays.equals(new String[] { "foo", "bar"}, y)); - } -}
--- a/test/src/jdk/nashorn/api/javaaccess/BooleanAccessTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,219 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertTrue; -import java.util.Arrays; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.BooleanAccessTest - * @run testng/othervm jdk.nashorn.api.javaaccess.BooleanAccessTest - */ -@SuppressWarnings("javadoc") -public class BooleanAccessTest { - - private static ScriptEngine e = null; - private static SharedObject o = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - @Test - public void accessFieldBoolean() throws ScriptException { - e.eval("var p_boolean = o.publicBoolean;"); - assertEquals(o.publicBoolean, e.get("p_boolean")); - assertEquals("boolean", e.eval("typeof p_boolean;")); - e.eval("o.publicBoolean = false;"); - assertEquals(false, o.publicBoolean); - } - - @Test - public void accessFieldBooleanArray() throws ScriptException { - e.eval("var p_boolean_array = o.publicBooleanArray;"); - assertEquals(o.publicBooleanArray[0], e.eval("o.publicBooleanArray[0]")); - assertTrue(Arrays.equals(o.publicBooleanArray, (boolean[])e.get("p_boolean_array"))); - e.eval("var t_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + - "t_boolean_arr[0] = true;" + - "t_boolean_arr[1] = false;" + - "t_boolean_arr[2] = false;" + - "o.publicBooleanArray = t_boolean_arr;"); - assertTrue(Arrays.equals(new boolean[] { true, false, false }, o.publicBooleanArray)); - e.eval("o.publicBooleanArray[0] = false;"); - assertEquals(false, o.publicBooleanArray[0]); - } - - @Test - public void accessStaticFieldBoolean() throws ScriptException { - e.eval("var ps_boolean = SharedObject.publicStaticBoolean;"); - assertEquals(SharedObject.publicStaticBoolean, e.get("ps_boolean")); - assertEquals("boolean", e.eval("typeof ps_boolean;")); - e.eval("SharedObject.publicStaticBoolean = false;"); - assertEquals(false, SharedObject.publicStaticBoolean); - } - - @Test - public void accessStaticFieldBooleanArray() throws ScriptException { - e.eval("var ps_boolean_array = SharedObject.publicStaticBooleanArray;"); - assertEquals(SharedObject.publicStaticBooleanArray[0], e.eval("SharedObject.publicStaticBooleanArray[0]")); - assertTrue(Arrays.equals(SharedObject.publicStaticBooleanArray, (boolean[])e.get("ps_boolean_array"))); - e.eval("var ts_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + - "ts_boolean_arr[0] = true;" + - "ts_boolean_arr[1] = false;" + - "ts_boolean_arr[2] = true;" + - "SharedObject.publicStaticBooleanArray = ts_boolean_arr;"); - assertTrue(Arrays.equals(new boolean[] { true, false, true }, SharedObject.publicStaticBooleanArray)); - e.eval("SharedObject.publicStaticBooleanArray[0] = false;"); - assertEquals(false, SharedObject.publicStaticBooleanArray[0]); - } - - @Test - public void accessFinalFieldBoolean() throws ScriptException { - e.eval("var pf_boolean = o.publicFinalBoolean;"); - assertEquals(o.publicFinalBoolean, e.get("pf_boolean")); - assertEquals("boolean", e.eval("typeof pf_boolean;")); - e.eval("o.publicFinalBoolean = false;"); - assertEquals(true, o.publicFinalBoolean); - } - - @Test - public void accessFinalFieldBooleanArray() throws ScriptException { - e.eval("var pf_boolean_array = o.publicFinalBooleanArray;"); - assertEquals(o.publicFinalBooleanArray[0], e.eval("o.publicFinalBooleanArray[0]")); - assertTrue(Arrays.equals(o.publicFinalBooleanArray, (boolean[])e.get("pf_boolean_array"))); - e.eval("var tf_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + - "tf_boolean_arr[0] = false;" + - "tf_boolean_arr[1] = false;" + - "tf_boolean_arr[2] = true;" + - "o.publicOFinalbjectArray = tf_boolean_arr;"); - assertTrue(Arrays.equals(new boolean[] { false, false, true, false }, o.publicFinalBooleanArray)); - e.eval("o.publicFinalBooleanArray[0] = true;"); - assertEquals(true, o.publicFinalBooleanArray[0]); - } - - @Test - public void accessStaticFinalFieldBoolean() throws ScriptException { - e.eval("var psf_boolean = SharedObject.publicStaticFinalBoolean;"); - assertEquals(SharedObject.publicStaticFinalBoolean, e.get("psf_boolean")); - assertEquals("boolean", e.eval("typeof psf_boolean;")); - e.eval("SharedObject.publicStaticFinalBoolean = false;"); - assertEquals(true, SharedObject.publicStaticFinalBoolean); - } - - @Test - public void accessStaticFinalFieldBooleanArray() throws ScriptException { - e.eval("var psf_boolean_array = SharedObject.publicStaticFinalBooleanArray;"); - assertEquals(SharedObject.publicStaticFinalBooleanArray[0], e.eval("SharedObject.publicStaticFinalBooleanArray[0]")); - assertTrue(Arrays.equals(SharedObject.publicStaticFinalBooleanArray, (boolean[])e.get("psf_boolean_array"))); - e.eval("var tsf_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + - "tsf_boolean_arr[0] = false;" + - "tsf_boolean_arr[1] = true;" + - "tsf_boolean_arr[2] = false;" + - "SharedObject.publicStaticFinalBooleanArray = tsf_boolean_arr;"); - assertTrue(Arrays.equals(new boolean[] { false, true, false, false }, SharedObject.publicStaticFinalBooleanArray)); - e.eval("SharedObject.publicStaticFinalBooleanArray[0] = true;"); - assertEquals(true, SharedObject.publicStaticFinalBooleanArray[0]); - } - - @Test - public void accessFieldBooleanBoxing() throws ScriptException { - e.eval("var p_boolean_box = o.publicBooleanBox;"); - assertEquals(o.publicBooleanBox, e.get("p_boolean_box")); - assertEquals("boolean", e.eval("typeof p_boolean_box;")); - e.eval("o.publicBooleanBox = false;"); - assertEquals(false, (boolean)o.publicBooleanBox); - } - - @Test - public void accessStaticFieldBooleanBoxing() throws ScriptException { - e.eval("var ps_boolean_box = SharedObject.publicStaticBooleanBox;"); - assertEquals(SharedObject.publicStaticBooleanBox, e.get("ps_boolean_box")); - assertEquals("boolean", e.eval("typeof ps_boolean_box;")); - e.eval("SharedObject.publicStaticBooleanBox = false;"); - assertEquals(false, (boolean)SharedObject.publicStaticBooleanBox); - } - - @Test - public void accessFinalFieldBooleanBoxing() throws ScriptException { - e.eval("var pf_boolean_box = o.publicFinalBooleanBox;"); - assertEquals(o.publicFinalBooleanBox, e.get("pf_boolean_box")); - assertEquals("boolean", e.eval("typeof pf_boolean_box;")); - e.eval("o.publicFinalBooleanBox = false;"); - assertEquals(true, (boolean)o.publicFinalBooleanBox); - } - - @Test - public void accessStaticFinalFieldBooleanBoxing() throws ScriptException { - e.eval("var psf_boolean_box = SharedObject.publicStaticFinalBooleanBox;"); - assertEquals(SharedObject.publicStaticFinalBooleanBox, e.get("psf_boolean_box")); - assertEquals("boolean", e.eval("typeof psf_boolean_box;")); - e.eval("SharedObject.publicStaticFinalBooleanBox = false;"); - assertEquals(true, (boolean)SharedObject.publicStaticFinalBooleanBox); - } - - @Test - public void accessVolatileField() throws ScriptException { - e.eval("var pv_boolean = o.volatileBoolean;"); - assertEquals(o.volatileBoolean, e.get("pv_boolean")); - assertEquals("boolean", e.eval("typeof pv_boolean;")); - e.eval("o.volatileBoolean = false;"); - assertEquals(false, o.volatileBoolean); - } - - @Test - public void accessTransientField() throws ScriptException { - e.eval("var pt_boolean = o.transientBoolean;"); - assertEquals(o.transientBoolean, e.get("pt_boolean")); - assertEquals("boolean", e.eval("typeof pt_boolean;")); - e.eval("o.transientBoolean = false;"); - assertEquals(false, o.transientBoolean); - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import java.util.HashMap; -import java.util.Map; -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import jdk.nashorn.api.scripting.JSObject; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -@SuppressWarnings("javadoc") -public class ConsStringTest { - private static ScriptEngine e = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() { - e = new ScriptEngineManager().getEngineByName("nashorn"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - } - - @Test - public void testConsStringFlattening() throws ScriptException { - final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); - final Map<Object, Object> m = new HashMap<>(); - b.put("m", m); - e.eval("var x = 'f'; x += 'oo'; var y = 'b'; y += 'ar'; m.put(x, y)"); - assertEquals("bar", m.get("foo")); - } - - @Test - public void testConsStringFromMirror() throws ScriptException { - final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); - //final Map<Object, Object> m = new HashMap<>(); - e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};"); - assertEquals("foo", ((JSObject)b.get("obj")).getMember("x")); - } - - @Test - public void testArrayConsString() throws ScriptException { - final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); - final ArrayHolder h = new ArrayHolder(); - b.put("h", h); - e.eval("var x = 'f'; x += 'oo'; h.array = [x];"); - assertEquals(1, h.array.length); - assertEquals("foo", h.array[0]); - } - - - public static class ArrayHolder { - private Object[] array; - - public void setArray(final Object[] array) { - this.array = array; - } - - public Object[] getArray() { - return array; - } - } -}
--- a/test/src/jdk/nashorn/api/javaaccess/MethodAccessTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,466 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Locale; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.MethodAccessTest - * @run testng/othervm jdk.nashorn.api.javaaccess.MethodAccessTest - */ -@SuppressWarnings("javadoc") -public class MethodAccessTest { - - private static ScriptEngine e = null; - private static SharedObject o = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - o.setEngine(e); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - @Test - public void accessMethodthrowsCheckedException() throws ScriptException { - e.eval("try {" + - " var a = java.lang.Long.parseLong('foo');" + - "} catch(e) {" + - " var isThrown = true;" + - " var isNumberException = e instanceof java.lang.NumberFormatException;" + - "} finally {" + - " var isFinalized = true;" + - "}"); - assertEquals("Exception thrown", true, e.get("isThrown")); - assertEquals("Finally called", true, e.get("isFinalized")); - assertEquals("Type is NumberFormatException", true, e.get("isNumberException")); - } - - @Test - public void accessMethodthrowsUnCheckedException() throws ScriptException { - e.eval("try {" + - " var a = java.lang.String.valueOf(null);" + - "} catch(e) {" + - " var isThrown = true;" + - " var isNumberException = e instanceof java.lang.NullPointerException;" + - "} finally {" + - " var isFinalized = true;" + - "}"); - assertEquals(true, e.get("isThrown")); - assertEquals(true, e.get("isFinalized")); - assertEquals(true, e.get("isNumberException")); - } - - @Test - public void accessMethodStartsThread() throws ScriptException { - e.eval("o.methodStartsThread();"); - assertEquals(false, o.isFinished); - } - - @Test - public void accessStaticMethod() throws ScriptException { - assertEquals(10, e.eval("java.lang.Math.abs(-10);")); - } - - @Test - public void accessSynchronousMethod() throws ScriptException { - e.eval("var v = new java.util.Vector();" + "v.add(10);" + "v.add(20);" + "v.add(30);"); - assertEquals(10, e.eval("v[0]")); - assertEquals(20, e.eval("v[1]")); - assertEquals(30, e.eval("v[2]")); - assertEquals(3, e.eval("v.size()")); - } - - @Test - public void accessStaticSynchronousMethod() throws ScriptException { - e.eval("var locales = java.util.Calendar.getAvailableLocales();"); - final Locale[] locales = (Locale[])e.get("locales"); - assertEquals(locales.length, Calendar.getAvailableLocales().length); - } - - @Test - public void accessNativeMethod() throws ScriptException { - assertEquals(4.0, e.eval("java.lang.StrictMath.log10(10000);")); - } - - @Test - public void accessConstructorOfAbstractClass() throws ScriptException { - e.eval("try {" + - " var a = new java.util.AbstractList();" + - " print('fail');" + - "} catch(e) {" + - " var isThrown = true;" + - "}"); - assertEquals(true, e.get("isThrown")); - } - - @Test - public void accessMethodVoid() throws ScriptException { - o.isAccessed = false; - e.eval("o.voidMethod();"); - assertTrue(o.isAccessed); - } - - @Test - public void accessMethodBoolean() throws ScriptException { - assertEquals(true, e.eval("o.booleanMethod(false);")); - assertEquals(false, e.eval("o.booleanMethod(true);")); - assertEquals(false, e.eval("o.booleanMethod('false');")); - assertEquals(true, e.eval("o.booleanMethod('');")); - assertEquals(true, e.eval("o.booleanMethod(0);")); - } - - @Test - public void accessMethodInt() throws ScriptException { - assertEquals(0, e.eval("o.intMethod(0);")); - assertEquals(-200, e.eval("o.intMethod(-100);")); - assertEquals(0, e.eval("o.intMethod('0');")); - assertEquals(-200, e.eval("o.intMethod('-100');")); - } - - @Test - public void accessMethodLong() throws ScriptException { - assertEquals((long)0, e.eval("o.longMethod(0);")); - assertEquals((long)400, e.eval("o.longMethod(200);")); - assertEquals((long) 0, e.eval("o.longMethod('0');")); - assertEquals((long) 400, e.eval("o.longMethod('200');")); - } - - @Test - public void accessMethodByte() throws ScriptException { - assertEquals((byte) 0, e.eval("o.byteMethod(0);")); - assertEquals((byte) 10, e.eval("o.byteMethod(5);")); - assertEquals((byte) 0, e.eval("o.byteMethod('0');")); - assertEquals((byte) 10, e.eval("o.byteMethod('5');")); - } - - @Test - public void accessMethodShort() throws ScriptException { - assertEquals((short)0, e.eval("o.shortMethod(0);")); - assertEquals((short)8000, e.eval("o.shortMethod(4000);")); - assertEquals((short) 0, e.eval("o.shortMethod('0');")); - assertEquals((short) 8000, e.eval("o.shortMethod('4000');")); - } - - @Test - public void accessMethodChar() throws ScriptException { - assertEquals('A', e.eval("o.charMethod('a');")); - assertEquals('Z', e.eval("o.charMethod('z');")); - assertEquals(o.charMethod((char)0), e.eval("o.charMethod(0);")); - assertEquals(o.charMethod((char)3150), e.eval("o.charMethod(3150);")); - } - - @Test - public void accessMethodFloat() throws ScriptException { - assertEquals(0.0f, e.eval("o.floatMethod(0.0);")); - assertEquals(4.2f, e.eval("o.floatMethod(2.1);")); - assertEquals(0.0f, e.eval("o.floatMethod('0.0');")); - assertEquals(4.2f, e.eval("o.floatMethod('2.1');")); - } - - @Test - public void accessMethodDouble() throws ScriptException { - assertEquals(0.0, e.eval("o.doubleMethod(0.0);")); - assertEquals(14.0, e.eval("o.doubleMethod(7.0);")); - assertEquals(0.0, e.eval("o.doubleMethod('0.0');")); - assertEquals(14.0, e.eval("o.doubleMethod('7.0');")); - } - - @Test - public void accessMethodBooleanBoxing() throws ScriptException { - assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.FALSE);")); - assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.TRUE);")); - assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod('');")); - assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod('false');")); - } - - @Test - public void accessMethodIntBoxing() throws ScriptException { - assertEquals(0, e.eval("o.intBoxingMethod(0);")); - assertEquals(-200, e.eval("o.intBoxingMethod(-100);")); - assertTrue((int)e.eval("(new java.lang.Integer(2)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodLongBoxing() throws ScriptException { - assertEquals((long) 0, e.eval("o.longBoxingMethod(0);")); - assertEquals((long) 400, e.eval("o.longBoxingMethod(200);")); - assertTrue((int)e.eval("(new java.lang.Long(2)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodByteBoxing() throws ScriptException { - assertEquals((byte) 0, e.eval("o.byteBoxingMethod(0);")); - assertEquals((byte) 10, e.eval("o.byteBoxingMethod(5);")); - assertTrue((int)e.eval("(new java.lang.Byte(2)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodShortBoxing() throws ScriptException { - assertEquals((short) 0, e.eval("o.shortBoxingMethod(0);")); - assertEquals((short) 8000, e.eval("o.shortBoxingMethod(4000);")); - assertTrue((int)e.eval("(new java.lang.Short(2)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodCharBoxing() throws ScriptException { - assertEquals('A', e.eval("o.charBoxingMethod('a');")); - assertEquals('Z', e.eval("o.charBoxingMethod('z');")); - assertTrue((int)e.eval("(new java.lang.Character(2)).compareTo(10)") < 0); - } - - @Test - public void accessMethodFloatBoxing() throws ScriptException { - assertEquals(0.0f, e.eval("o.floatBoxingMethod(0.0);")); - assertEquals(4.2f, e.eval("o.floatBoxingMethod(2.1);")); - assertTrue((int)e.eval("(new java.lang.Float(2.0)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodDoubleBoxing() throws ScriptException { - assertEquals(0.0, e.eval("o.doubleBoxingMethod(0.0);")); - assertEquals(14.0, e.eval("o.doubleBoxingMethod(7.0);")); - assertTrue((int)e.eval("(new java.lang.Double(2)).compareTo(10.0)") < 0); - } - - @Test - public void accessMethodString() throws ScriptException { - assertEquals("", e.eval("o.stringMethod('');")); - assertEquals("abcabc", e.eval("o.stringMethod('abc');")); - } - - @Test - public void accessMethodObject() throws ScriptException { - e.put("so", new Person(5)); - e.eval("var rso = o.objectMethod(so);"); - assertEquals(new Person(10), e.get("rso")); - } - - @Test - public void accessMethodBooleanArray() throws ScriptException { - assertTrue(Arrays.equals(o.booleanArrayMethod(o.publicBooleanArray), (boolean[])e.eval("o.booleanArrayMethod(o.publicBooleanArray);"))); - } - - @Test - public void accessMethodIntArray() throws ScriptException { - assertArrayEquals(o.intArrayMethod(o.publicIntArray), (int[])e.eval("o.intArrayMethod(o.publicIntArray);")); - } - - @Test - public void accessMethodLongArray() throws ScriptException { - assertArrayEquals(o.longArrayMethod(o.publicLongArray), (long[])e.eval("o.longArrayMethod(o.publicLongArray);")); - } - - @Test - public void accessMethodByteArray() throws ScriptException { - assertArrayEquals(o.byteArrayMethod(o.publicByteArray), (byte[])e.eval("o.byteArrayMethod(o.publicByteArray);")); - } - - @Test - public void accessMethodShortArray() throws ScriptException { - assertArrayEquals(o.shortArrayMethod(o.publicShortArray), (short[])e.eval("o.shortArrayMethod(o.publicShortArray);")); - } - - @Test - public void accessMethodCharArray() throws ScriptException { - assertArrayEquals(o.charArrayMethod(o.publicCharArray), (char[])e.eval("o.charArrayMethod(o.publicCharArray);")); - } - - @Test - public void accessMethodFloatArray() throws ScriptException { - assertArrayEquals(o.floatArrayMethod(o.publicFloatArray), (float[])e.eval("o.floatArrayMethod(o.publicFloatArray);"), 1e-10f); - } - - @Test - public void accessMethodDoubleArray() throws ScriptException { - assertArrayEquals(o.doubleArrayMethod(o.publicDoubleArray), (double[])e.eval("o.doubleArrayMethod(o.publicDoubleArray);"), 1e-10); - } - - @Test - public void accessMethodStringArray() throws ScriptException { - assertArrayEquals(o.stringArrayMethod(o.publicStringArray), (String[])e.eval("o.stringArrayMethod(o.publicStringArray);")); - } - - @Test - public void accessMethodObjectArray() throws ScriptException { - assertArrayEquals(o.objectArrayMethod(o.publicObjectArray), (Person[])e.eval("o.objectArrayMethod(o.publicObjectArray);")); - } - - @Test - public void accessDefaultConstructor() throws ScriptException { - e.eval("var dc = new Packages.jdk.nashorn.api.javaaccess.Person()"); - assertEquals(new Person(), e.get("dc")); - } - - @Test - public void accessCustomConstructor() throws ScriptException { - e.eval("var cc = new Packages.jdk.nashorn.api.javaaccess.Person(17)"); - assertEquals(new Person(17), e.get("cc")); - } - - @Test - public void accessMethod2PrimitiveParams() throws ScriptException { - assertEquals(o.twoParamMethod(50, 40.0), e.eval("o.twoParamMethod(50,40);")); - } - - @Test - public void accessMethod3PrimitiveParams() throws ScriptException { - assertEquals(o.threeParamMethod((short)10, 20L, 'b'), e.eval("o.threeParamMethod(10,20,'b');")); - } - - @Test - public void accessMethod2ObjectParams() throws ScriptException { - assertArrayEquals(new Person[] { new Person(200), new Person(300) }, (Person[])e.eval("o.twoObjectParamMethod(new Person(300),new Person(200));")); - } - - @Test - public void accessMethod3ObjectParams() throws ScriptException { - assertArrayEquals(new Person[] { new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.threeObjectParamMethod(new Person(1),new Person(2),new Person(3));")); - } - - @Test - public void accessMethod8ObjectParams() throws ScriptException { - assertArrayEquals(new Person[] { new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.eightObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6),new Person(7),new Person(8));")); - } - - @Test - public void accessMethod9ObjectParams() throws ScriptException { - assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.nineObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));")); - } - - @Test - public void accessMethodObjectEllipsis() throws ScriptException { - assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));")); - assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodObjectEllipsis()")); - assertArrayEquals(new Person[] { new Person(9) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(9))")); - } - - @Test - public void accessMethodPrimitiveEllipsis() throws ScriptException { - assertArrayEquals(new Person[] { new Person(1), new Person(3), new Person(2) }, (Person[])e.eval("o.methodPrimitiveEllipsis(1,3,2);")); - assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodPrimitiveEllipsis();")); - assertArrayEquals(o.methodPrimitiveEllipsis(9, 8, 7, 6, 5, 4, 3, 2, 1), (Person[])e.eval("o.methodPrimitiveEllipsis(9,8,7,6,5,4,3,2,1);")); - } - - @Test - public void accessMethodMixedEllipsis() throws ScriptException { - assertArrayEquals(new Object[] { new Person(1), 12, "hello", true }, (Object[])e.eval("o.methodMixedEllipsis(new Person(1),12,'hello',true);")); - assertArrayEquals(new Object[] {}, (Object[])e.eval("o.methodMixedEllipsis();")); - } - - @Test - public void accessMethodObjectWithEllipsis() throws ScriptException { - assertArrayEquals(new Object[] { "hello", 12, 15, 16 }, (Object[])e.eval("o.methodObjectWithEllipsis('hello',12,15,16);")); - assertArrayEquals(new Object[] { "hello" }, (Object[])e.eval("o.methodObjectWithEllipsis('hello');")); - } - - @Test - public void accessMethodPrimitiveWithEllipsis() throws ScriptException { - assertArrayEquals(new Object[] { 14, 12L, 15L, 16L }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(14,12,15,16);")); - assertArrayEquals(new Object[] { 12 }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(12);")); - } - - @Test - public void accessMethodMixedWithEllipsis() throws ScriptException { - assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80d }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);")); - assertArrayEquals(new Object[] { "Nashorn", 15 }, (Object[])e.eval("o.methodMixedWithEllipsis('Nashorn',15);")); - } - - @Test - public void accessMethodOverloaded() throws ScriptException { - assertEquals(0, e.eval("o.overloadedMethod(0);")); - assertEquals(2000, e.eval("o.overloadedMethod(1000);")); - assertEquals(2, e.eval("o.overloadedMethod('10');")); - assertEquals(7, e.eval("o.overloadedMethod('Nashorn');")); - assertEquals(4, e.eval("o.overloadedMethod('true');")); - assertEquals(1, e.eval("o.overloadedMethod(true);")); - assertEquals(0, e.eval("o.overloadedMethod(false);")); - assertEquals(44, e.eval("o.overloadedMethod(new Person(22));")); - assertEquals(0, e.eval("o.overloadedMethod(new Person());")); - } - - @Test - public void accessMethodDoubleVSintOverloaded() throws ScriptException { - assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.0);")); - assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(1000.0);")); - assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.01);")); - assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(100.02);")); - assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0);")); - assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000);")); - } - - @Test - public void accessJavaMethodIntFromJSFromJavaFromJS() throws ScriptException { - e.eval("function secondLevelMethodInt(a) {" - + "return o.thirdLevelMethodInt(a);" - + "}"); - assertEquals(50, e.eval("o.firstLevelMethodInt(10);")); - } - - @Test - public void accessJavaMethodIntegerFromJSFromJavaFromJS() throws ScriptException { - e.eval("function secondLevelMethodInteger(a) {" - + "return o.thirdLevelMethodInteger(a);" - + "}"); - assertEquals(100, e.eval("o.firstLevelMethodInteger(10);")); - } - - @Test - public void accessJavaMethodObjectFromJSFromJavaFromJS() throws ScriptException { - e.eval("function secondLevelMethodObject(p) {" - + "return o.thirdLevelMethodObject(p);" - + "}"); - assertEquals(new Person(100), e.eval("o.firstLevelMethodObject(new Person(10));")); - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/NumberAccessTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,789 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertTrue; -import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberAccessTest - * @run testng/othervm jdk.nashorn.api.javaaccess.NumberAccessTest - */ -@SuppressWarnings("javadoc") -public class NumberAccessTest { - - private static ScriptEngine e; - private static SharedObject o; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - // --------------------------------long - // tests------------------------------------ - @Test - public void accessFieldLong() throws ScriptException { - e.eval("var p_long = o.publicLong;"); - assertEquals(o.publicLong, e.get("p_long")); - e.eval("o.publicLong = 12;"); - assertEquals(12, o.publicLong); - } - - @Test - public void accessFieldLongArray() throws ScriptException { - e.eval("var p_long_array = o.publicLongArray;"); - assertEquals(o.publicLongArray[0], e.eval("o.publicLongArray[0];")); - assertArrayEquals(o.publicLongArray, (long[])e.get("p_long_array")); - e.eval("var t_long_arr = new (Java.type(\"long[]\"))(3);" + - "t_long_arr[0] = -189009;" + - "t_long_arr[1] = 456;" + - "t_long_arr[2] = 600000001;" + - "o.publicLongArray = t_long_arr;"); - // e.eval("o.publicIntArray = [-189009,456,600000001];"); - assertArrayEquals(new long[] { -189009, 456, 600000001 }, o.publicLongArray); - e.eval("o.publicLongArray[0] = 10;"); - assertEquals(10, o.publicLongArray[0]); - } - - @Test - public void accessStaticFieldLong() throws ScriptException { - e.eval("var ps_long = SharedObject.publicStaticLong;"); - assertEquals(SharedObject.publicStaticLong, e.get("ps_long")); - e.eval("SharedObject.publicStaticLong = 120;"); - assertEquals(120, SharedObject.publicStaticLong); - } - - @Test - public void accessStaticFieldLongArray() throws ScriptException { - e.eval("var ps_long_array = SharedObject.publicStaticLongArray;"); - assertEquals(SharedObject.publicStaticLongArray[0], e.eval("SharedObject.publicStaticLongArray[0];")); - assertArrayEquals(SharedObject.publicStaticLongArray, (long[])e.get("ps_long_array")); - e.eval("var ts_long_arr = new (Java.type(\"long[]\"))(3);" + - "ts_long_arr[0] = -189009;" + - "ts_long_arr[1] = 456;" + - "ts_long_arr[2] = 600000001;" + - "SharedObject.publicStaticLongArray = ts_long_arr;"); - // e.eval("o.publicIntArray = [-189009,456,600000001];"); - assertArrayEquals(new long[] { -189009, 456, 600000001 }, SharedObject.publicStaticLongArray); - e.eval("SharedObject.publicStaticLongArray[0] = 10;"); - assertEquals(10, SharedObject.publicStaticLongArray[0]); - } - - @Test - public void accessFinalFieldLong() throws ScriptException { - e.eval("var pf_long = o.publicFinalLong;"); - assertEquals(o.publicFinalLong, e.get("pf_long")); - e.eval("o.publicFinalLong = 120;"); - assertEquals(13353333333333333L, o.publicFinalLong); - } - - @Test - public void accessFinalFieldLongArray() throws ScriptException { - e.eval("var pf_long_array = o.publicFinalLongArray;"); - assertEquals(o.publicFinalLongArray[0], e.eval("o.publicFinalLongArray[0];")); - assertArrayEquals(o.publicFinalLongArray, (long[])e.get("pf_long_array")); - e.eval("var tf_long_arr = new (Java.type(\"long[]\"))(3);" + - "tf_long_arr[0] = -189009;" + - "tf_long_arr[1] = 456;" + - "tf_long_arr[2] = 600000001;" + - "o.publicFinalLongArray = tf_long_arr;"); - // e.eval("o.publicIntArray = [-189009,456,600000001];"); - assertArrayEquals(new long[] { 1901733333333L, -2247355555L, 3977377777L }, o.publicFinalLongArray); - e.eval("o.publicFinalLongArray[0] = 10;"); - assertEquals(10, o.publicFinalLongArray[0]); - } - - @Test - public void accessStaticFinalFieldLong() throws ScriptException { - e.eval("var psf_long = SharedObject.publicStaticFinalLong;"); - assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long")); - e.eval("SharedObject.publicStaticFinalLong = 120;"); - assertEquals(8333333333333L, SharedObject.publicStaticFinalLong); - } - - @Test - public void accessStaticFinalFieldLongArray() throws ScriptException { - e.eval("var psf_long_array = SharedObject.publicStaticFinalLongArray;"); - assertEquals(SharedObject.publicStaticFinalLongArray[0], e.eval("SharedObject.publicStaticFinalLongArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalLongArray, (long[])e.get("psf_long_array")); - e.eval("var tsf_long_arr = new (Java.type(\"long[]\"))(3);" + - "tsf_long_arr[0] = -189009;" + - "tsf_long_arr[1] = 456;" + - "tsf_long_arr[2] = 600000001;" + - "SharedObject.publicStaticFinalLongArray = tsf_long_arr;"); - // e.eval("o.publicIntArray = [-189009,456,600000001];"); - assertArrayEquals(new long[] { 19017383333L, -2247358L, 39773787L }, SharedObject.publicStaticFinalLongArray); - e.eval("SharedObject.publicStaticFinalLongArray[0] = 10;"); - assertEquals(10, SharedObject.publicStaticFinalLongArray[0]); - } - - // --------------------------------int - // tests------------------------------------ - @Test - public void accessFieldInt() throws ScriptException { - e.eval("var p_int = o.publicInt;"); - assertEquals(o.publicInt, e.get("p_int")); - e.eval("o.publicInt = 14;"); - assertEquals(14, o.publicInt); - } - - @Test - public void accessFieldIntArray() throws ScriptException { - e.eval("var p_int_array = o.publicIntArray;"); - assertEquals(o.publicIntArray[0], e.eval("o.publicIntArray[0];")); - assertArrayEquals(o.publicIntArray, (int[])e.get("p_int_array")); - e.eval("var t_int_arr = new (Java.type(\"int[]\"))(3);" + - "t_int_arr[0] = 4;" + - "t_int_arr[1] = 5;" + - "t_int_arr[2] = 6;" + - "o.publicIntArray = t_int_arr;"); - assertArrayEquals(new int[] { 4, 5, 6 }, o.publicIntArray); - e.eval("o.publicIntArray[0] = 100;"); - assertEquals(100, o.publicIntArray[0]); - } - - @Test - public void accessStaticFieldInt() throws ScriptException { - e.eval("var ps_int = SharedObject.publicStaticInt;"); - assertEquals(SharedObject.publicStaticInt, e.get("ps_int")); - e.eval("SharedObject.publicStaticInt = 140;"); - assertEquals(140, SharedObject.publicStaticInt); - } - - @Test - public void accessStaticFieldIntArray() throws ScriptException { - e.eval("var ps_int_array = SharedObject.publicStaticIntArray;"); - assertEquals(SharedObject.publicStaticIntArray[0], e.eval("SharedObject.publicStaticIntArray[0];")); - assertArrayEquals(SharedObject.publicStaticIntArray, (int[])e.get("ps_int_array")); - e.eval("var ts_int_arr = new (Java.type(\"int[]\"))(3);" + - "ts_int_arr[0] = 4;" + - "ts_int_arr[1] = 5;" + - "ts_int_arr[2] = 6;" + - "SharedObject.publicStaticIntArray = ts_int_arr;"); - assertArrayEquals(new int[] { 4, 5, 6 }, SharedObject.publicStaticIntArray); - e.eval("SharedObject.publicStaticIntArray[0] = 100;"); - assertEquals(100, SharedObject.publicStaticIntArray[0]); - } - - @Test - public void accessFinalFieldInt() throws ScriptException { - e.eval("var pf_int = o.publicFinalInt;"); - assertEquals(o.publicFinalInt, e.get("pf_int")); - - e.eval("o.publicFinalInt = 10;"); - assertEquals(20712023, o.publicFinalInt); - } - - @Test - public void accessFinalFieldIntArray() throws ScriptException { - e.eval("var pf_int_array = o.publicFinalIntArray;"); - assertEquals(o.publicFinalIntArray[0], e.eval("o.publicFinalIntArray[0];")); - assertArrayEquals(o.publicFinalIntArray, (int[])e.get("pf_int_array")); - e.eval("var tf_int_arr = new (Java.type(\"int[]\"))(3);" + - "tf_int_arr[0] = 4;" + - "tf_int_arr[1] = 5;" + - "tf_int_arr[2] = 6;" + - "o.publicFinalIntArray = tf_int_arr;"); - assertArrayEquals(new int[] { 50, 80, 130, 210, 340 }, o.publicFinalIntArray); - e.eval("o.publicFinalIntArray[0] = 100;"); - assertEquals(100, o.publicFinalIntArray[0]); - } - - @Test - public void accessStaticFinalFieldInt() throws ScriptException { - e.eval("var psf_int = SharedObject.publicStaticFinalInt;"); - assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int")); - e.eval("SharedObject.publicStaticFinalInt = 140;"); - assertEquals(207182023, SharedObject.publicStaticFinalInt); - } - - @Test - public void accessStaticFinalFieldIntArray() throws ScriptException { - e.eval("var psf_int_array = SharedObject.publicStaticFinalIntArray;"); - assertEquals(SharedObject.publicStaticFinalIntArray[0], e.eval("SharedObject.publicStaticFinalIntArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalIntArray, (int[])e.get("psf_int_array")); - e.eval("var tsf_int_arr = new (Java.type(\"int[]\"))(3);" + - "tsf_int_arr[0] = 4;" + - "tsf_int_arr[1] = 5;" + - "tsf_int_arr[2] = 6;" + - "SharedObject.publicStaticFinalIntArray = tsf_int_arr;"); - assertArrayEquals(new int[] { 1308, 210, 340 }, SharedObject.publicStaticFinalIntArray); - e.eval("SharedObject.publicStaticFinalIntArray[0] = 100;"); - assertEquals(100, SharedObject.publicStaticFinalIntArray[0]); - } - - // --------------------------------byte - // tests------------------------------------ - @Test - public void accessFieldByte() throws ScriptException { - e.eval("var p_byte = o.publicByte;"); - assertEquals((double)o.publicByte, ((Number)e.get("p_byte")).doubleValue()); - e.eval("o.publicByte = 16;"); - assertEquals(16, o.publicByte); - } - - @Test - public void accessFieldByteArray() throws ScriptException { - e.eval("var p_byte_array = o.publicByteArray;"); - assertEquals(o.publicByteArray[0], e.eval("o.publicByteArray[0];")); - assertArrayEquals(o.publicByteArray, (byte[])e.get("p_byte_array")); - e.eval("var t_byte_arr = new (Java.type(\"byte[]\"))(3);" + - "t_byte_arr[0] = -18;" + - "t_byte_arr[1] = 56;" + - "t_byte_arr[2] = 60;" + - "o.publicByteArray = t_byte_arr;"); - assertArrayEquals(new byte[] { -18, 56, 60 }, o.publicByteArray); - e.eval("o.publicByteArray[0] = 100;"); - assertEquals(100, o.publicByteArray[0]); - } - - @Test - public void accessStaticFieldByte() throws ScriptException { - e.eval("var ps_byte = SharedObject.publicStaticByte;"); - assertEquals((double)SharedObject.publicStaticByte, ((Number)e.get("ps_byte")).doubleValue()); - e.eval("SharedObject.publicStaticByte = 16;"); - assertEquals(16, SharedObject.publicStaticByte); - } - - @Test - public void accessStaticFieldByteArray() throws ScriptException { - e.eval("var ps_byte_array = SharedObject.publicStaticByteArray;"); - assertEquals(SharedObject.publicStaticByteArray[0], e.eval("SharedObject.publicStaticByteArray[0];")); - assertArrayEquals(SharedObject.publicStaticByteArray, (byte[])e.get("ps_byte_array")); - e.eval("var ts_byte_arr = new (Java.type(\"byte[]\"))(3);" + - "ts_byte_arr[0] = -18;" + - "ts_byte_arr[1] = 56;" + - "ts_byte_arr[2] = 60;" + - "SharedObject.publicStaticByteArray = ts_byte_arr;"); - assertArrayEquals(new byte[] { -18, 56, 60 }, SharedObject.publicStaticByteArray); - e.eval("SharedObject.publicStaticByteArray[0] = -90;"); - assertEquals(-90, SharedObject.publicStaticByteArray[0]); - } - - @Test - public void accessFinalFieldByte() throws ScriptException { - e.eval("var pf_byte = o.publicFinalByte;"); - assertEquals((double)o.publicFinalByte, ((Number)e.get("pf_byte")).doubleValue()); - e.eval("o.publicFinalByte = 16;"); - assertEquals(-7, o.publicFinalByte); - } - - @Test - public void accessFinalFieldByteArray() throws ScriptException { - e.eval("var pf_byte_array = o.publicFinalByteArray;"); - assertEquals(o.publicFinalByteArray[0], e.eval("o.publicFinalByteArray[0];")); - assertArrayEquals(o.publicFinalByteArray, (byte[])e.get("pf_byte_array")); - e.eval("var tf_byte_arr = new (Java.type(\"byte[]\"))(3);" + - "tf_byte_arr[0] = -18;" + - "tf_byte_arr[1] = 56;" + - "tf_byte_arr[2] = 60;" + - "o.publicFinalByteArray = tf_byte_arr;"); - assertArrayEquals(new byte[] { 1, 3, 6, 17, -128 }, o.publicFinalByteArray); - e.eval("o.publicFinalByteArray[0] = -90;"); - assertEquals(-90, o.publicFinalByteArray[0]); - } - - @Test - public void accessStaticFinalFieldByte() throws ScriptException { - e.eval("var psf_byte = SharedObject.publicStaticFinalByte;"); - assertEquals((double)SharedObject.publicStaticFinalByte, ((Number)e.get("psf_byte")).doubleValue()); - e.eval("SharedObject.publicStaticFinalByte = 16;"); - assertEquals(-70, SharedObject.publicStaticFinalByte); - } - - @Test - public void accessStaticFinalFieldByteArray() throws ScriptException { - e.eval("var psf_byte_array = SharedObject.publicStaticFinalByteArray;"); - assertEquals(SharedObject.publicStaticFinalByteArray[0], e.eval("SharedObject.publicStaticFinalByteArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalByteArray, (byte[])e.get("psf_byte_array")); - e.eval("var tsf_byte_arr = new (Java.type(\"byte[]\"))(3);" + - "tsf_byte_arr[0] = -18;" + - "tsf_byte_arr[1] = 56;" + - "tsf_byte_arr[2] = 60;" + - "SharedObject.publicStaticFinalByteArray = tsf_byte_arr;"); - assertArrayEquals(new byte[] { 17, -128, 81 }, SharedObject.publicStaticFinalByteArray); - e.eval("SharedObject.publicStaticFinalByteArray[0] = -90;"); - assertEquals(-90, SharedObject.publicStaticFinalByteArray[0]); - } - - // --------------------------------short - // tests------------------------------------ - @Test - public void accessFieldShort() throws ScriptException { - e.eval("var p_short = o.publicShort;"); - assertEquals((double)o.publicShort, ((Number)e.get("p_short")).doubleValue()); - e.eval("o.publicShort = 18;"); - assertEquals(18, o.publicShort); - } - - @Test - public void accessFieldShortArray() throws ScriptException { - e.eval("var p_short_array = o.publicShortArray;"); - assertEquals(o.publicShortArray[0], e.eval("o.publicShortArray[0];")); - assertArrayEquals(o.publicShortArray, (short[])e.get("p_short_array")); - e.eval("var t_short_arr = new (Java.type(\"short[]\"))(3);" + - "t_short_arr[0] = 90;" + - "t_short_arr[1] = 5;" + - "t_short_arr[2] = -6000;" + - "o.publicShortArray = t_short_arr;"); - assertArrayEquals(new short[] { 90, 5, -6000 }, o.publicShortArray); - e.eval("o.publicShortArray[0] = -1000;"); - assertEquals(-1000, o.publicShortArray[0]); - } - - @Test - public void accessStaticFieldShort() throws ScriptException { - e.eval("var ps_short = SharedObject.publicStaticShort;"); - assertEquals((double)SharedObject.publicStaticShort, ((Number)e.get("ps_short")).doubleValue()); - e.eval("SharedObject.publicStaticShort = 180;"); - assertEquals(180, SharedObject.publicStaticShort); - } - - @Test - public void accessStaticFieldShortArray() throws ScriptException { - e.eval("var ps_short_array = SharedObject.publicStaticShortArray;"); - assertEquals(SharedObject.publicStaticShortArray[0], e.eval("SharedObject.publicStaticShortArray[0];")); - assertArrayEquals(SharedObject.publicStaticShortArray, (short[])e.get("ps_short_array")); - e.eval("var ts_short_arr = new (Java.type(\"short[]\"))(3);" + - "ts_short_arr[0] = 90;" + - "ts_short_arr[1] = 5;" + - "ts_short_arr[2] = -6000;" + - "SharedObject.publicStaticShortArray = ts_short_arr;"); - assertArrayEquals(new short[] { 90, 5, -6000 }, SharedObject.publicStaticShortArray); - e.eval("SharedObject.publicStaticShortArray[0] = -1000;"); - assertEquals(-1000, SharedObject.publicStaticShortArray[0]); - } - - @Test - public void accessFinalFieldShort() throws ScriptException { - e.eval("var pf_short = o.publicFinalShort;"); - assertEquals((double)o.publicFinalShort, ((Number)e.get("pf_short")).doubleValue()); - e.eval("o.publicFinalShort = 180;"); - assertEquals(31220, o.publicFinalShort); - } - - @Test - public void accessFinalFieldShortArray() throws ScriptException { - e.eval("var pf_short_array = o.publicFinalShortArray;"); - assertEquals(o.publicFinalShortArray[0], e.eval("o.publicFinalShortArray[0];")); - assertArrayEquals(o.publicFinalShortArray, (short[])e.get("pf_short_array")); - e.eval("var tf_short_arr = new (Java.type(\"short[]\"))(3);" + - "tf_short_arr[0] = 90;" + - "tf_short_arr[1] = 5;" + - "tf_short_arr[2] = -6000;" + - "o.publicFinalShortArray = tf_short_arr;"); - assertArrayEquals(new short[] { 12240, 9200, -17289, 1200, 12 }, o.publicFinalShortArray); - e.eval("o.publicFinalShortArray[0] = -1000;"); - assertEquals(-1000, o.publicFinalShortArray[0]); - } - - @Test - public void accessStaticFinalFieldShort() throws ScriptException { - e.eval("var psf_short = SharedObject.publicStaticFinalShort;"); - assertEquals((double)SharedObject.publicStaticFinalShort, ((Number)e.get("psf_short")).doubleValue()); - e.eval("SharedObject.publicStaticFinalShort = 180;"); - assertEquals(8888, SharedObject.publicStaticFinalShort); - } - - @Test - public void accessStaticFinalFieldShortArray() throws ScriptException { - e.eval("var psf_short_array = SharedObject.publicStaticFinalShortArray;"); - assertEquals(SharedObject.publicStaticFinalShortArray[0], e.eval("SharedObject.publicStaticFinalShortArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalShortArray, (short[])e.get("psf_short_array")); - e.eval("var tsf_short_arr = new (Java.type(\"short[]\"))(3);" + - "tsf_short_arr[0] = 90;" + - "tsf_short_arr[1] = 5;" + - "tsf_short_arr[2] = -6000;" + - "SharedObject.publicStaticFinalShortArray = tsf_short_arr;"); - assertArrayEquals(new short[] { 8240, 9280, -1289, 120, 812 }, SharedObject.publicStaticFinalShortArray); - e.eval("SharedObject.publicStaticFinalShortArray[0] = -1000;"); - assertEquals(-1000, SharedObject.publicStaticFinalShortArray[0]); - } - - // --------------------------------char - // tests------------------------------------ - @Test - public void accessFieldChar() throws ScriptException { - e.eval("var p_char = o.publicChar;"); - assertEquals(o.publicChar, e.get("p_char")); - e.eval("o.publicChar = 'S';"); - assertEquals('S', o.publicChar); - e.eval("o.publicChar = 10;"); - assertEquals(10, o.publicChar); - e.eval("try {" - + " o.publicChar = 'Big string';" + - "} catch(e) {" + - " var isThrown = true;" + - "}"); - assertEquals("Exception thrown", true, e.get("isThrown")); - assertEquals(10, o.publicChar); - } - - @Test - public void accessFieldCharArray() throws ScriptException { - e.eval("var p_char_array = o.publicCharArray;"); - assertEquals(o.publicCharArray[0], e.eval("o.publicCharArray[0];")); - assertArrayEquals(o.publicCharArray, (char[])e.get("p_char_array")); - e.eval("var t_char_arr = new (Java.type(\"char[]\"))(3);" + - "t_char_arr[0] = 'F';" + - "t_char_arr[1] = 'o';" + - "t_char_arr[2] = 'o';" + - "o.publicCharArray = t_char_arr;"); - assertArrayEquals("Foo".toCharArray(), o.publicCharArray); - e.eval("o.publicCharArray[0] = 'Z';"); - assertEquals('Z', o.publicCharArray[0]); - } - - @Test - public void accessStaticFieldChar() throws ScriptException { - e.eval("var ps_char = SharedObject.publicStaticChar;"); - assertEquals(SharedObject.publicStaticChar, e.get("ps_char")); - e.eval("SharedObject.publicStaticChar = 'Z';"); - assertEquals('Z', SharedObject.publicStaticChar); - } - - @Test - public void accessStaticFieldCharArray() throws ScriptException { - e.eval("var ps_char_array = SharedObject.publicStaticCharArray;"); - assertEquals(SharedObject.publicStaticCharArray[0], e.eval("SharedObject.publicStaticCharArray[0];")); - assertArrayEquals(SharedObject.publicStaticCharArray, (char[])e.get("ps_char_array")); - e.eval("var ts_char_arr = new (Java.type(\"char[]\"))(3);" + - "ts_char_arr[0] = 'G';" + - "ts_char_arr[1] = 'o';" + - "ts_char_arr[2] = 'o';" + - "SharedObject.publicStaticCharArray = ts_char_arr;"); - assertArrayEquals("Goo".toCharArray(), SharedObject.publicStaticCharArray); - e.eval("SharedObject.publicStaticCharArray[0] = 'Z';"); - assertEquals('Z', SharedObject.publicStaticCharArray[0]); - } - - @Test - public void accessFinalFieldChar() throws ScriptException { - e.eval("var pf_char = o.publicFinalChar;"); - assertEquals(o.publicFinalChar, e.get("pf_char")); - e.eval("o.publicFinalChar = 'S';"); - assertEquals('E', o.publicFinalChar); - } - - @Test - public void accessFinalCharArray() throws ScriptException { - e.eval("var pf_char_array = o.publicFinalCharArray;"); - assertEquals(o.publicFinalCharArray[0], e.eval("o.publicFinalCharArray[0];")); - assertArrayEquals(o.publicFinalCharArray, (char[])e.get("pf_char_array")); - e.eval("var tf_char_arr = new (Java.type(\"char[]\"))(3);" + - "tf_char_arr[0] = 'F';" + - "tf_char_arr[1] = 'o';" + - "tf_char_arr[2] = 'o';" + - "o.publicFinalCharArray = tf_char_arr;"); - assertArrayEquals("Nashorn hello".toCharArray(), o.publicFinalCharArray); - e.eval("o.publicFinalCharArray[0] = 'Z';"); - assertEquals('Z', o.publicFinalCharArray[0]); - } - - @Test - public void accessStaticFinalFieldChar() throws ScriptException { - e.eval("var psf_char = SharedObject.publicStaticFinalChar;"); - assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char")); - e.eval("SharedObject.publicStaticFinalChar = 'Z';"); - assertEquals('K', SharedObject.publicStaticFinalChar); - } - - @Test - public void accessStaticFinalFieldCharArray() throws ScriptException { - e.eval("var psf_char_array = SharedObject.publicStaticFinalCharArray;"); - assertEquals(SharedObject.publicStaticFinalCharArray[0], e.eval("SharedObject.publicStaticFinalCharArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalCharArray, (char[])e.get("psf_char_array")); - e.eval("var tsf_char_arr = new (Java.type(\"char[]\"))(3);" + - "tsf_char_arr[0] = 'Z';" + - "tsf_char_arr[1] = 'o';" + - "tsf_char_arr[2] = 'o';" + - "SharedObject.publicStaticFinalCharArray = tsf_char_arr;"); - assertArrayEquals("StaticString".toCharArray(), SharedObject.publicStaticFinalCharArray); - e.eval("SharedObject.publicStaticFinalCharArray[0] = 'Z';"); - assertEquals('Z', SharedObject.publicStaticFinalCharArray[0]); - } - - // --------------------------------float - // tests------------------------------------ - @Test - public void accessFieldFloat() throws ScriptException { - e.eval("var p_float = o.publicFloat;"); - assertEquals((double)o.publicFloat, ((Number)e.get("p_float")).doubleValue()); - o.publicFloat = 0.0f / 0.0f; - assertEquals(true, e.eval("isNaN(o.publicFloat)")); - o.publicFloat = 1.0f / 0.0f; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloat")); - o.publicFloat = -1.0f / 0.0f; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloat")); - e.eval("o.publicFloat = 20;"); - assertEquals(20, o.publicFloat, 1e-10); - e.eval("o.publicFloat = 0.0/0.0;"); - assertTrue(Float.isNaN(o.publicFloat)); - e.eval("o.publicFloat = 1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloat)); - e.eval("o.publicFloat = -1.0/0.0;"); - assertEquals(Float.NEGATIVE_INFINITY, o.publicFloat, 1e-10); - } - - @Test - public void accessFieldFloatArray() throws ScriptException { - e.eval("var p_float_array = o.publicFloatArray;"); - assertEquals(o.publicFloatArray[0], e.eval("o.publicFloatArray[0];")); - assertArrayEquals(o.publicFloatArray, (float[])e.get("p_float_array"), 1e-10f); - e.eval("var t_float_arr = new (Java.type(\"float[]\"))(3);" + - "t_float_arr[0] = 9.0;" + - "t_float_arr[1] = 5.12345;" + - "t_float_arr[2] = -60.03;" + - "o.publicFloatArray = t_float_arr;"); - assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f); - e.eval("o.publicFloatArray[0] = -513.2;"); - assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f); - } - - @Test - public void accessStaticFieldFloat() throws ScriptException { - e.eval("var ps_float = SharedObject.publicStaticFloat;"); - assertEquals((double)SharedObject.publicStaticFloat, ((Number)e.get("ps_float")).doubleValue()); - SharedObject.publicStaticFloat = 0.0f / 0.0f; - assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)")); - SharedObject.publicStaticFloat = 1.0f / 0.0f; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat")); - SharedObject.publicStaticFloat = -1.0f / 0.0f; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat")); - e.eval("SharedObject.publicStaticFloat = 20.0;"); - assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10); - e.eval("SharedObject.publicStaticFloat = 0.0/0.0;"); - assertTrue(Float.isNaN(SharedObject.publicStaticFloat)); - e.eval("SharedObject.publicStaticFloat = 1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); - e.eval("SharedObject.publicStaticFloat = -1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); - } - - @Test - public void accessStaticFieldFloatArray() throws ScriptException { - e.eval("var ps_float_array = SharedObject.publicStaticFloatArray;"); - assertEquals(SharedObject.publicStaticFloatArray[0], e.eval("SharedObject.publicStaticFloatArray[0];")); - assertArrayEquals(SharedObject.publicStaticFloatArray, (float[])e.get("ps_float_array"), 1e-10f); - e.eval("var ts_float_arr = new (Java.type(\"float[]\"))(3);" + - "ts_float_arr[0] = 9.0;" + - "ts_float_arr[1] = 5.12345;" + - "ts_float_arr[2] = -60.03;" + - "SharedObject.publicStaticFloatArray = ts_float_arr;"); - assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f); - e.eval("SharedObject.publicStaticFloatArray[0] = -513.2;"); - assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f); - } - - @Test - public void accessFinalFloat() throws ScriptException { - e.eval("var pf_float = o.publicFinalFloat;"); - assertEquals((double)o.publicFinalFloat, ((Number)e.get("pf_float")).doubleValue()); - e.eval("o.publicFinalFloat = 20.0;"); - assertEquals(7.72e8f, o.publicFinalFloat, 1e-10); - } - - @Test - public void accessFinalFloatArray() throws ScriptException { - e.eval("var pf_float_array = o.publicFinalFloatArray;"); - assertEquals(o.publicFinalFloatArray[0], e.eval("o.publicFinalFloatArray[0];")); - assertArrayEquals(o.publicFinalFloatArray, (float[])e.get("pf_float_array"), 1e-10f); - e.eval("var tf_float_arr = new (Java.type(\"float[]\"))(3);" + - "tf_float_arr[0] = 9.0;" + - "tf_float_arr[1] = 5.12345;" + - "tf_float_arr[2] = -60.03;" + - "o.publicFinalFloatArray = tf_float_arr;"); - assertArrayEquals(new float[] { -131.012f, 189.32f, -31.32e8f, 3.72f }, o.publicFinalFloatArray, 1e-10f); - e.eval("o.publicFinalFloatArray[0] = -513.2;"); - assertEquals(-513.2f, o.publicFinalFloatArray[0], 1e-10f); - } - - @Test - public void accessStaticFinalFieldFloat() throws ScriptException { - e.eval("var psf_float = SharedObject.publicStaticFinalFloat;"); - assertEquals((double)SharedObject.publicStaticFinalFloat, ((Number)e.get("psf_float")).doubleValue()); - e.eval("SharedObject.publicStaticFinalFloat = 20.0;"); - assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10); - } - - @Test - public void accessStaticFinalFieldFloatArray() throws ScriptException { - e.eval("var psf_float_array = SharedObject.publicStaticFinalFloatArray;"); - assertEquals(SharedObject.publicStaticFinalFloatArray[0], e.eval("SharedObject.publicStaticFinalFloatArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalFloatArray, (float[])e.get("psf_float_array"), 1e-10f); - e.eval("var tsf_float_arr = new (Java.type(\"float[]\"))(3);" + - "tsf_float_arr[0] = 9.0;" + - "tsf_float_arr[1] = 5.12345;" + - "tsf_float_arr[2] = -60.03;" + - "SharedObject.publicStaticFinalFloatArray = tsf_float_arr;"); - assertArrayEquals(new float[] { -8131.012f, 9.32f, -138.32e8f, 0.72f }, SharedObject.publicStaticFinalFloatArray, 1e-10f); - e.eval("SharedObject.publicStaticFinalFloatArray[0] = -513.2;"); - assertEquals(-513.2f, SharedObject.publicStaticFinalFloatArray[0], 1e-10f); - } - - // --------------------------------double - // tests------------------------------------ - @Test - public void accessFieldDouble() throws ScriptException { - e.eval("var p_double = o.publicDouble;"); - assertEquals(o.publicDouble, e.get("p_double")); - o.publicDouble = 0.0 / 0.0; - assertEquals(true, e.eval("isNaN(o.publicDouble)")); - o.publicDouble = 1.0 / 0.0; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDouble")); - o.publicDouble = -1.0 / 0.0; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDouble")); - e.eval("o.publicDouble = 30;"); - assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDouble)); - e.eval("o.publicDouble = 0.0/0.0;"); - assertTrue(Double.isNaN(o.publicDouble)); - e.eval("o.publicDouble = 1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDouble)); - e.eval("o.publicDouble = -1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDouble)); - } - - @Test - public void accessFieldDoubleArrayRead() throws ScriptException { - e.eval("var p_double_array = o.publicDoubleArray;"); - assertEquals(o.publicDoubleArray[0], e.eval("o.publicDoubleArray[0];")); - assertArrayEquals(o.publicDoubleArray, (double[])e.get("p_double_array"), 1e-10); - e.eval("var t_double_arr = new (Java.type(\"double[]\"))(3);" + - "t_double_arr[0] = 9e10;" + - "t_double_arr[1] = 0.677777;" + - "t_double_arr[2] = -0.0000001;" + - "o.publicDoubleArray = t_double_arr;"); - assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, o.publicDoubleArray, 1e-10f); - e.eval("o.publicDoubleArray[0] = -5.2e10;"); - assertEquals(-5.2e10, o.publicDoubleArray[0], 1e-10f); - } - - @Test - public void accessStaticFieldDouble() throws ScriptException { - e.eval("var ps_double = SharedObject.publicStaticDouble;"); - assertEquals(SharedObject.publicStaticDouble, e.get("ps_double")); - SharedObject.publicStaticDouble = 0.0 / 0.0; - assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)")); - SharedObject.publicStaticDouble = 1.0 / 0.0; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble")); - SharedObject.publicStaticDouble = -1.0 / 0.0; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble")); - e.eval("SharedObject.publicStaticDouble = 40.0;"); - assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = 0.0/0.0;"); - assertTrue(Double.isNaN(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = 1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = -1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - } - - @Test - public void accessStaticFieldDoubleArrayRead() throws ScriptException { - e.eval("var ps_double_array = SharedObject.publicStaticDoubleArray;"); - assertEquals(SharedObject.publicStaticDoubleArray[0], e.eval("SharedObject.publicStaticDoubleArray[0];")); - assertArrayEquals(SharedObject.publicStaticDoubleArray, (double[])e.get("ps_double_array"), 1e-10); - e.eval("var ts_double_arr = new (Java.type(\"double[]\"))(3);" + - "ts_double_arr[0] = 9e10;" + - "ts_double_arr[1] = 0.677777;" + - "ts_double_arr[2] = -0.0000001;" + - "SharedObject.publicStaticDoubleArray = ts_double_arr;"); - assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, SharedObject.publicStaticDoubleArray, 1e-10f); - e.eval("SharedObject.publicStaticDoubleArray[0] = -5.2e10;"); - assertEquals(-5.2e10, SharedObject.publicStaticDoubleArray[0], 1e-10f); - } - - @Test - public void accessFinalFieldDouble() throws ScriptException { - e.eval("var pf_double = o.publicFinalDouble;"); - assertEquals(o.publicFinalDouble, e.get("pf_double")); - e.eval("o.publicFinalDouble = 30.0;"); - assertEquals(Double.doubleToLongBits(1.3412e20), Double.doubleToLongBits(o.publicFinalDouble)); - } - - @Test - public void accessFinalFieldDoubleArrayRead() throws ScriptException { - e.eval("var pf_double_array = o.publicFinalDoubleArray;"); - assertEquals(o.publicFinalDoubleArray[0], e.eval("o.publicFinalDoubleArray[0];")); - assertArrayEquals(o.publicFinalDoubleArray, (double[])e.get("pf_double_array"), 1e-10); - e.eval("var tf_double_arr = new (Java.type(\"double[]\"))(3);" + - "tf_double_arr[0] = 9e10;" + - "tf_double_arr[1] = 0.677777;" + - "tf_double_arr[2] = -0.0000001;" + - "o.publicFinalDoubleArray = tf_double_arr;"); - assertArrayEquals(new double[] { 0.725e80, 0.12e10, 8e-3, 1.00077 }, o.publicFinalDoubleArray, 1e-10f); - e.eval("o.publicFinalDoubleArray[0] = -5.2e10;"); - assertEquals(-5.2e10, o.publicFinalDoubleArray[0], 1e-10f); - } - - @Test - public void accessStaticFinalFieldDouble() throws ScriptException { - e.eval("var psf_double = SharedObject.publicStaticFinalDouble;"); - assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double")); - e.eval("SharedObject.publicStaticFinalDouble = 40.0;"); - assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble)); - } - - @Test - public void accessStaticFinalFieldDoubleArrayRead() throws ScriptException { - e.eval("var psf_double_array = SharedObject.publicStaticFinalDoubleArray;"); - assertEquals(SharedObject.publicStaticFinalDoubleArray[0], e.eval("SharedObject.publicStaticFinalDoubleArray[0];")); - assertArrayEquals(SharedObject.publicStaticFinalDoubleArray, (double[])e.get("psf_double_array"), 1e-10); - e.eval("var tsf_double_arr = new (Java.type(\"double[]\"))(3);" + - "tsf_double_arr[0] = 9e10;" + - "tsf_double_arr[1] = 0.677777;" + - "tsf_double_arr[2] = -0.0000001;" + - "SharedObject.publicStaticFinalDoubleArray = tsf_double_arr;"); - assertArrayEquals(new double[] { 8.725e80, 0.82e10, 18e-3, 1.08077 }, SharedObject.publicStaticFinalDoubleArray, 1e-10f); - e.eval("SharedObject.publicStaticFinalDoubleArray[0] = -5.2e10;"); - assertEquals(-5.2e10, SharedObject.publicStaticFinalDoubleArray[0], 1e-10f); - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/NumberBoxingTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,365 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.AssertJUnit.assertTrue; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.NumberBoxingTest - * @run testng/othervm jdk.nashorn.api.javaaccess.NumberBoxingTest - */ -@SuppressWarnings("javadoc") -public class NumberBoxingTest { - - private static ScriptEngine e; - private static SharedObject o; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - // --------------------------------long - // tests------------------------------------ - @Test - public void accessFieldLongBoxing() throws ScriptException { - e.eval("var p_long = o.publicLongBox;"); - assertEquals(o.publicLongBox, e.get("p_long")); - e.eval("o.publicLongBox = 12;"); - assertEquals(Long.valueOf(12), o.publicLongBox); - } - - @Test - public void accessStaticFieldLongBoxing() throws ScriptException { - e.eval("var ps_long = SharedObject.publicStaticLongBox;"); - assertEquals(SharedObject.publicStaticLongBox, e.get("ps_long")); - e.eval("SharedObject.publicStaticLongBox = 120;"); - assertEquals(120L, SharedObject.publicStaticLongBox.longValue()); - } - - @Test - public void accessFinalFieldLongBoxing() throws ScriptException { - e.eval("var pf_long = o.publicFinalLongBox;"); - assertEquals(o.publicFinalLongBox, e.get("pf_long")); - e.eval("o.publicFinalLongBox = 120;"); - assertEquals(Long.valueOf(9377333334L), o.publicFinalLongBox); - } - - @Test - public void accessStaticFinalFieldLongBoxing() throws ScriptException { - e.eval("var psf_long = SharedObject.publicStaticFinalLong;"); - assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long")); - e.eval("SharedObject.publicStaticFinalLong = 120;"); - assertEquals(8333333333333L, SharedObject.publicStaticFinalLong); - } - - // --------------------------------int - // tests------------------------------------ - @Test - public void accessFieldIntBoxing() throws ScriptException { - e.eval("var p_int = o.publicIntBox;"); - assertEquals(o.publicIntBox, e.get("p_int")); - e.eval("o.publicIntBox = 14;"); - assertEquals(Integer.valueOf(14), o.publicIntBox); - } - - @Test - public void accessStaticFieldIntBoxing() throws ScriptException { - e.eval("var ps_int = SharedObject.publicStaticInt;"); - assertEquals(SharedObject.publicStaticInt, e.get("ps_int")); - e.eval("SharedObject.publicStaticInt = 140;"); - assertEquals(140, SharedObject.publicStaticInt); - } - - @Test - public void accessFinalFieldIntBoxing() throws ScriptException { - e.eval("var pf_int = o.publicFinalIntBox;"); - assertEquals(o.publicFinalIntBox, e.get("pf_int")); - e.eval("o.publicFinalIntBox = 10;"); - assertEquals(Integer.valueOf(207512301), o.publicFinalIntBox); - } - - @Test - public void accessStaticFinalFieldIntBoxing() throws ScriptException { - e.eval("var psf_int = SharedObject.publicStaticFinalInt;"); - assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int")); - e.eval("SharedObject.publicStaticFinalInt = 140;"); - assertEquals(207182023, SharedObject.publicStaticFinalInt); - } - - // --------------------------------byte - // tests------------------------------------ - @Test - public void accessFieldByteBoxing() throws ScriptException { - e.eval("var p_byte = o.publicByteBox;"); - assertEqualsDouble(o.publicByteBox, "p_byte"); - e.eval("o.publicByteBox = 16;"); - assertEquals(Byte.valueOf((byte)16), o.publicByteBox); - } - - @Test - public void accessStaticFieldByteBoxing() throws ScriptException { - e.eval("var ps_byte = SharedObject.publicStaticByte;"); - assertEqualsDouble(SharedObject.publicStaticByte, "ps_byte"); - e.eval("SharedObject.publicStaticByte = 16;"); - assertEquals(16, SharedObject.publicStaticByte); - } - - @Test - public void accessFinalFieldByteBoxing() throws ScriptException { - e.eval("var pf_byte = o.publicFinalByteBox;"); - assertEqualsDouble(o.publicFinalByteBox, "pf_byte"); - e.eval("o.publicFinalByteBox = 16;"); - assertEquals(Byte.valueOf((byte)19), o.publicFinalByteBox); - } - - @Test - public void accessStaticFinalFieldByteBoxing() throws ScriptException { - e.eval("var psf_byte = SharedObject.publicStaticFinalByte;"); - assertEqualsDouble(SharedObject.publicStaticFinalByte, "psf_byte"); - e.eval("SharedObject.publicStaticFinalByte = 16;"); - assertEquals(-70, SharedObject.publicStaticFinalByte); - } - - // --------------------------------short - // tests------------------------------------ - @Test - public void accessFieldShortBoxing() throws ScriptException { - e.eval("var p_short = o.publicShortBox;"); - assertEqualsDouble(o.publicShortBox, "p_short"); - e.eval("o.publicShortBox = 18;"); - assertEquals(Short.valueOf((short)18), o.publicShortBox); - } - - private static void assertEqualsDouble(final Number n, final String name) { - assertEquals(n.doubleValue(), ((Number)e.get(name)).doubleValue()); - } - - @Test - public void accessStaticFieldShortBoxing() throws ScriptException { - e.eval("var ps_short = SharedObject.publicStaticShort;"); - assertEqualsDouble(SharedObject.publicStaticShort, "ps_short"); - e.eval("SharedObject.publicStaticShort = 180;"); - assertEquals(180, SharedObject.publicStaticShort); - } - - @Test - public void accessFinalFieldShortBoxing() throws ScriptException { - e.eval("var pf_short = o.publicFinalShortBox;"); - assertEqualsDouble(o.publicFinalShortBox, "pf_short"); - e.eval("o.publicFinalShortBox = 180;"); - assertEquals(Short.valueOf((short)-26777), o.publicFinalShortBox); - } - - @Test - public void accessStaticFinalFieldShortBoxing() throws ScriptException { - e.eval("var psf_short = SharedObject.publicStaticFinalShort;"); - assertEqualsDouble(SharedObject.publicStaticFinalShort, "psf_short"); - e.eval("SharedObject.publicStaticFinalShort = 180;"); - assertEquals(8888, SharedObject.publicStaticFinalShort); - } - - // --------------------------------char - // tests------------------------------------ - @Test - public void accessFieldCharBoxing() throws ScriptException { - e.eval("var p_char = o.publicCharBox;"); - assertEquals(o.publicCharBox, e.get("p_char")); - e.eval("o.publicCharBox = 'S';"); - assertEquals(Character.valueOf('S'), o.publicCharBox); - e.eval("try {" + - " o.publicCharBox = 'Big string';" + - "} catch(e) {" + - " var isThrown = true;" + - "}"); - assertEquals("Exception thrown", true, e.get("isThrown")); - assertEquals(Character.valueOf('S'), o.publicCharBox); - } - - @Test - public void accessStaticFieldCharBoxing() throws ScriptException { - e.eval("var ps_char = SharedObject.publicStaticChar;"); - assertEquals(SharedObject.publicStaticChar, e.get("ps_char")); - e.eval("SharedObject.publicStaticChar = 'Z';"); - assertEquals('Z', SharedObject.publicStaticChar); - } - - @Test - public void accessFinalFieldCharBoxing() throws ScriptException { - e.eval("var pf_char = o.publicFinalCharBox;"); - assertEquals(o.publicFinalCharBox, e.get("pf_char")); - e.eval("o.publicFinalCharBox = 'S';"); - assertEquals(Character.valueOf('F'), o.publicFinalCharBox); - } - - @Test - public void accessStaticFinalFieldCharBoxing() throws ScriptException { - e.eval("var psf_char = SharedObject.publicStaticFinalChar;"); - assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char")); - e.eval("SharedObject.publicStaticFinalChar = 'Z';"); - assertEquals('K', SharedObject.publicStaticFinalChar); - } - - // --------------------------------float - // tests------------------------------------ - @Test - public void accessFieldFloatBoxing() throws ScriptException { - e.eval("var p_float = o.publicFloatBox;"); - assertEqualsDouble(o.publicFloatBox, "p_float"); - o.publicFloatBox = 0.0f / 0.0f; - assertEquals(true, e.eval("isNaN(o.publicFloatBox)")); - o.publicFloatBox = 1.0f / 0.0f; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloatBox")); - o.publicFloatBox = -1.0f / 0.0f; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloatBox")); - e.eval("o.publicFloatBox = 20;"); - assertEquals(20, o.publicFloatBox, 1e-10); - e.eval("o.publicFloatBox = 0.0/0.0;"); - assertTrue(Float.isNaN(o.publicFloatBox)); - e.eval("o.publicFloatBox = 1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloatBox)); - e.eval("o.publicFloatBox = -1.0/0.0;"); - assertEquals(Float.NEGATIVE_INFINITY, o.publicFloatBox, 1e-10); - } - - @Test - public void accessStaticFieldFloatBoxing() throws ScriptException { - e.eval("var ps_float = SharedObject.publicStaticFloat;"); - assertEqualsDouble(SharedObject.publicStaticFloat, "ps_float"); - SharedObject.publicStaticFloat = 0.0f / 0.0f; - assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)")); - SharedObject.publicStaticFloat = 1.0f / 0.0f; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat")); - SharedObject.publicStaticFloat = -1.0f / 0.0f; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat")); - e.eval("SharedObject.publicStaticFloat = 20.0;"); - assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10); - e.eval("SharedObject.publicStaticFloat = 0.0/0.0;"); - assertTrue(Float.isNaN(SharedObject.publicStaticFloat)); - e.eval("SharedObject.publicStaticFloat = 1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); - e.eval("SharedObject.publicStaticFloat = -1.0/0.0;"); - assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); - } - - @Test - public void accessFinalFloatBoxing() throws ScriptException { - e.eval("var pf_float = o.publicFinalFloatBox;"); - assertEqualsDouble(o.publicFinalFloatBox, "pf_float"); - e.eval("o.publicFinalFloatBox = 20.0;"); - assertEquals(1.372e4f, o.publicFinalFloatBox, 1e-10); - } - - @Test - public void accessStaticFinalFieldFloatBoxing() throws ScriptException { - e.eval("var psf_float = SharedObject.publicStaticFinalFloat;"); - assertEqualsDouble(SharedObject.publicStaticFinalFloat, "psf_float"); - e.eval("SharedObject.publicStaticFinalFloat = 20.0;"); - assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10); - } - - // --------------------------------double - // tests------------------------------------ - @Test - public void accessFieldDoubleBoxing() throws ScriptException { - e.eval("var p_double = o.publicDoubleBox;"); - assertEquals(o.publicDoubleBox, e.get("p_double")); - o.publicDoubleBox = 0.0 / 0.0; - assertEquals(true, e.eval("isNaN(o.publicDoubleBox)")); - o.publicDoubleBox = 1.0 / 0.0; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDoubleBox")); - o.publicDoubleBox = -1.0 / 0.0; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDoubleBox")); - e.eval("o.publicDoubleBox = 30;"); - assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDoubleBox)); - e.eval("o.publicDoubleBox = 0.0/0.0;"); - assertTrue(Double.isNaN(o.publicDoubleBox)); - e.eval("o.publicDoubleBox = 1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox)); - e.eval("o.publicDoubleBox = -1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox)); - } - - @Test - public void accessStaticFieldDoubleBoxing() throws ScriptException { - e.eval("var ps_double = SharedObject.publicStaticDouble;"); - assertEquals(SharedObject.publicStaticDouble, e.get("ps_double")); - SharedObject.publicStaticDouble = 0.0 / 0.0; - assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)")); - SharedObject.publicStaticDouble = 1.0 / 0.0; - assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble")); - SharedObject.publicStaticDouble = -1.0 / 0.0; - assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble")); - e.eval("SharedObject.publicStaticDouble = 40.0;"); - assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = 0.0/0.0;"); - assertTrue(Double.isNaN(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = 1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - e.eval("SharedObject.publicStaticDouble = -1.0/0.0;"); - assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); - } - - @Test - public void accessFinalFieldDoubleBoxing() throws ScriptException { - e.eval("var pf_double = o.publicFinalDoubleBox;"); - assertEquals(o.publicFinalDoubleBox, e.get("pf_double")); - e.eval("o.publicFinalDoubleBox = 30.0;"); - assertEquals(Double.doubleToLongBits(1.412e-12), Double.doubleToLongBits(o.publicFinalDoubleBox)); - } - - @Test - public void accessStaticFinalFieldDoubleBoxing() throws ScriptException { - e.eval("var psf_double = SharedObject.publicStaticFinalDouble;"); - assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double")); - e.eval("SharedObject.publicStaticFinalDouble = 40.0;"); - assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble)); - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/ObjectAccessTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.ObjectAccessTest - * @run testng/othervm jdk.nashorn.api.javaaccess.ObjectAccessTest - */ -@SuppressWarnings("javadoc") -public class ObjectAccessTest { - - private static ScriptEngine e = null; - private static SharedObject o = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.Person;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - @Test - public void accessFieldObject() throws ScriptException { - e.eval("var p_object = o.publicObject;"); - assertEquals(o.publicObject, e.get("p_object")); - assertEquals("object", e.eval("typeof p_object;")); - e.eval("o.publicObject = new Person(14);"); - assertEquals(new Person(14), o.publicObject); - } - - @Test - public void accessFieldObjectArray() throws ScriptException { - e.eval("var p_object_array = o.publicObjectArray;"); - assertEquals(o.publicObjectArray[0], e.eval("o.publicObjectArray[0]")); - assertArrayEquals(o.publicObjectArray, (Object[])e.get("p_object_array")); - e.eval("var t_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.Person[]\"))(3);" + - "t_object_arr[0] = new Person(100);" + - "t_object_arr[1] = new Person(120);" + - "t_object_arr[2] = new Person(140);" + - "o.publicObjectArray = t_object_arr;"); - assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, o.publicObjectArray); - e.eval("o.publicObjectArray[0] = new Person(10);"); - assertEquals(new Person(10), o.publicObjectArray[0]); - } - - @Test - public void accessStaticFieldObject() throws ScriptException { - e.eval("var ps_object = SharedObject.publicStaticObject;"); - assertEquals(SharedObject.publicStaticObject, e.get("ps_object")); - assertEquals("object", e.eval("typeof ps_object;")); - e.eval("SharedObject.publicStaticObject = new Person(16);"); - assertEquals(new Person(16), SharedObject.publicStaticObject); - } - - @Test - public void accessStaticFieldObjectArray() throws ScriptException { - e.eval("var ps_object_array = SharedObject.publicStaticObjectArray;"); - assertEquals(SharedObject.publicStaticObjectArray[0], e.eval("SharedObject.publicStaticObjectArray[0]")); - assertArrayEquals(SharedObject.publicStaticObjectArray, (Object[])e.get("ps_object_array")); - e.eval("var ts_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.Person[]\"))(3);" + - "ts_object_arr[0] = new Person(100);" + - "ts_object_arr[1] = new Person(120);" + - "ts_object_arr[2] = new Person(140);" + - "SharedObject.publicStaticObjectArray = ts_object_arr;"); - assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, SharedObject.publicStaticObjectArray); - e.eval("SharedObject.publicStaticObjectArray[0] = new Person(10);"); - assertEquals(new Person(10), SharedObject.publicStaticObjectArray[0]); - } - - @Test - public void accessFinalFieldObject() throws ScriptException { - e.eval("var pf_object = o.publicFinalObject;"); - assertEquals(o.publicFinalObject, e.get("pf_object")); - assertEquals("object", e.eval("typeof pf_object;")); - e.eval("o.publicFinalObject = new Person(-999);"); - assertEquals(new Person(1024), o.publicFinalObject); - } - - @Test - public void accessFinalFieldObjectArray() throws ScriptException { - e.eval("var pf_object_array = o.publicFinalObjectArray;"); - assertEquals(o.publicFinalObjectArray[0], e.eval("o.publicFinalObjectArray[0]")); - assertArrayEquals(o.publicFinalObjectArray, (Object[])e.get("pf_object_array")); - e.eval("var tf_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.Person[]\"))(3);" + - "tf_object_arr[0] = new Person(100);" + - "tf_object_arr[1] = new Person(120);" + - "tf_object_arr[2] = new Person(140);" + - "o.publicOFinalbjectArray = tf_object_arr;"); - assertArrayEquals(new Person[] { new Person(-900), new Person(1000), new Person(180) }, o.publicFinalObjectArray); - e.eval("o.publicFinalObjectArray[0] = new Person(10);"); - assertEquals(new Person(10), o.publicFinalObjectArray[0]); - } - - @Test - public void accessStaticFinalFieldObject() throws ScriptException { - e.eval("var psf_object = SharedObject.publicStaticFinalObject;"); - assertEquals(SharedObject.publicStaticFinalObject, e.get("psf_object")); - assertEquals("object", e.eval("typeof psf_object;")); - e.eval("SharedObject.publicStaticFinalObject = new Person(6);"); - assertEquals(new Person(2048), SharedObject.publicStaticFinalObject); - } - - @Test - public void accessStaticFinalFieldObjectArray() throws ScriptException { - e.eval("var psf_object_array = SharedObject.publicStaticFinalObjectArray;"); - assertEquals(SharedObject.publicStaticFinalObjectArray[0], e.eval("SharedObject.publicStaticFinalObjectArray[0]")); - assertArrayEquals(SharedObject.publicStaticFinalObjectArray, (Object[])e.get("psf_object_array")); - e.eval("var tsf_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.Person[]\"))(3);" + - "tsf_object_arr[0] = new Person(100);" + - "tsf_object_arr[1] = new Person(120);" + - "tsf_object_arr[2] = new Person(140);" + - "SharedObject.publicStaticFinalObjectArray = tsf_object_arr;"); - assertArrayEquals(new Person[] { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) }, SharedObject.publicStaticFinalObjectArray); - e.eval("SharedObject.publicStaticFinalObjectArray[0] = new Person(90);"); - assertEquals(new Person(90), SharedObject.publicStaticFinalObjectArray[0]); - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/Person.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -@SuppressWarnings("javadoc") -public class Person { - - public int id = 0; - - public Person() { - } - - public Person(final int code) { - this.id = code; - } - - @Override - public boolean equals(final Object obj) { - if (obj != null && obj instanceof Person) { - final Person o = (Person)obj; - return this.id == o.id; - } - return false; - } - - @Override - public int hashCode() { - return id; - } - - @Override - public String toString() { - return "Person(" + id + ")"; - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/SharedObject.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,467 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import javax.script.Invocable; -import javax.script.ScriptEngine; -import javax.script.ScriptException; - -@SuppressWarnings("javadoc") -public class SharedObject { - - // Public fields - public String publicString = "PublicString"; - public String[] publicStringArray = { "ArrayString[0]", "ArrayString[1]", "ArrayString[2]", "ArrayString[3]" }; - public Person publicObject = new Person(256); - public Person[] publicObjectArray = { new Person(4), new Person(-422), new Person(14) }; - public boolean publicBoolean = true; - public boolean[] publicBooleanArray = { true, false, false, true }; - public Boolean publicBooleanBox = true; - public long publicLong = 933333333333333333L; - public long[] publicLongArray = { 99012333333333L, -124355555L, 89777777777L }; - public Long publicLongBox = 9333333333L; - public int publicInt = 2076543123; - public int[] publicIntArray = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 }; - public Integer publicIntBox = 20765123; - public byte publicByte = -128; - public byte[] publicByteArray = { 1, 2, 4, 8, 16, 32, 64, 127, -128 }; - public Byte publicByteBox = 127; - public short publicShort = 32000; - public short[] publicShortArray = { 3240, 8900, -16789, 1, 12 }; - public Short publicShortBox = Short.MIN_VALUE; - public float publicFloat = 0.7f; - public float[] publicFloatArray = { -32.01f, 89.3f, -1.3e8f, 3.1f }; - public Float publicFloatBox = 1.377e4f; - public double publicDouble = 1.34e20; - public double[] publicDoubleArray = { 0.75e80, 8e-43, 1.000077, 0.123e10 }; - public Double publicDoubleBox = 1.4e-19; - public char publicChar = 'A'; - public char[] publicCharArray = "Hello Nashorn".toCharArray(); - public Character publicCharBox = 'B'; - // Public static fields - public static String publicStaticString = "PublicStaticString"; - public static String[] publicStaticStringArray = { "StaticArrayString[0]", "StaticArrayString[1]", "StaticArrayString[2]", "StaticArrayString[3]" }; - public static Person publicStaticObject = new Person(512); - public static Person[] publicStaticObjectArray = { new Person(40), new Person(-22), new Person(18) }; - public static boolean publicStaticBoolean = true; - public static boolean[] publicStaticBooleanArray = { false, false, false, true }; - public static Boolean publicStaticBooleanBox = true; - public static long publicStaticLong = 13333333333333333L; - public static long[] publicStaticLongArray = { 19012333333333L, -224355555L, 39777777777L }; - public static Long publicStaticLongBox = 9333333334L; - public static int publicStaticInt = 207654323; - public static int[] publicStaticIntArray = { 5, 8, 13, 21, 34 }; - public static Integer publicStaticIntBox = 2075123; - public static byte publicStaticByte = -12; - public static byte[] publicStaticByteArray = { 16, 32, 64, 127, -128 }; - public static Byte publicStaticByteBox = 17; - public static short publicStaticShort = 320; - public static short[] publicStaticShortArray = { 1240, 900, -1789, 100, 12 }; - public static Short publicStaticShortBox = -16777; - public static float publicStaticFloat = 7.7e8f; - public static float[] publicStaticFloatArray = { -131.01f, 189.3f, -31.3e8f, 3.7f }; - public static Float publicStaticFloatBox = 1.37e4f; - public static double publicStaticDouble = 1.341e20; - public static double[] publicStaticDoubleArray = { 0.75e80, 0.123e10, 8e-43, 1.000077 }; - public static Double publicStaticDoubleBox = 1.41e-12; - public static char publicStaticChar = 'C'; - public static char[] publicStaticCharArray = "Nashorn".toCharArray(); - public static Character publicStaticCharBox = 'D'; - // Public final fields - public final String publicFinalString = "PublicFinalString"; - public final String[] publicFinalStringArray = { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" }; - public final Person publicFinalObject = new Person(1024); - public final Person[] publicFinalObjectArray = { new Person(-900), new Person(1000), new Person(180) }; - public final boolean publicFinalBoolean = true; - public final boolean[] publicFinalBooleanArray = { false, false, true, false }; - public final Boolean publicFinalBooleanBox = true; - public final long publicFinalLong = 13353333333333333L; - public final long[] publicFinalLongArray = { 1901733333333L, -2247355555L, 3977377777L }; - public final Long publicFinalLongBox = 9377333334L; - public final int publicFinalInt = 20712023; - public final int[] publicFinalIntArray = { 50, 80, 130, 210, 340 }; - public final Integer publicFinalIntBox = 207512301; - public final byte publicFinalByte = -7; - public final byte[] publicFinalByteArray = { 1, 3, 6, 17, -128 }; - public final Byte publicFinalByteBox = 19; - public final short publicFinalShort = 31220; - public final short[] publicFinalShortArray = { 12240, 9200, -17289, 1200, 12 }; - public final Short publicFinalShortBox = -26777; - public final float publicFinalFloat = 7.72e8f; - public final float[] publicFinalFloatArray = { -131.012f, 189.32f, -31.32e8f, 3.72f }; - public final Float publicFinalFloatBox = 1.372e4f; - public final double publicFinalDouble = 1.3412e20; - public final double[] publicFinalDoubleArray = { 0.725e80, 0.12e10, 8e-3, 1.00077 }; - public final Double publicFinalDoubleBox = 1.412e-12; - public final char publicFinalChar = 'E'; - public final char[] publicFinalCharArray = "Nashorn hello".toCharArray(); - public final Character publicFinalCharBox = 'F'; - // Public static final fields - public static final String publicStaticFinalString = "PublicStaticFinalString"; - public static final String[] publicStaticFinalStringArray = { "StaticFinalArrayString[0]", "StaticFinalArrayString[1]", "StaticFinalArrayString[2]", "StaticFinalArrayString[3]" }; - public static final Person publicStaticFinalObject = new Person(2048); - public static final Person[] publicStaticFinalObjectArray = { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) }; - public static final boolean publicStaticFinalBoolean = true; - public static final boolean[] publicStaticFinalBooleanArray = { false, true, false, false }; - public static final Boolean publicStaticFinalBooleanBox = true; - public static final long publicStaticFinalLong = 8333333333333L; - public static final long[] publicStaticFinalLongArray = { 19017383333L, -2247358L, 39773787L }; - public static final Long publicStaticFinalLongBox = 9377388334L; - public static final int publicStaticFinalInt = 207182023; - public static final int[] publicStaticFinalIntArray = { 1308, 210, 340 }; - public static final Integer publicStaticFinalIntBox = 2078301; - public static final byte publicStaticFinalByte = -70; - public static final byte[] publicStaticFinalByteArray = { 17, -128, 81 }; - public static final Byte publicStaticFinalByteBox = 91; - public static final short publicStaticFinalShort = 8888; - public static final short[] publicStaticFinalShortArray = { 8240, 9280, -1289, 120, 812 }; - public static final Short publicStaticFinalShortBox = -26; - public static final float publicStaticFinalFloat = 0.72e8f; - public static final float[] publicStaticFinalFloatArray = { -8131.012f, 9.32f, -138.32e8f, 0.72f }; - public static final Float publicStaticFinalFloatBox = 1.2e4f; - public static final double publicStaticFinalDouble = 1.8e12; - public static final double[] publicStaticFinalDoubleArray = { 8.725e80, 0.82e10, 18e-3, 1.08077 }; - public static final Double publicStaticFinalDoubleBox = 1.5612e-13; - public static final char publicStaticFinalChar = 'K'; - public static final char[] publicStaticFinalCharArray = "StaticString".toCharArray(); - public static final Character publicStaticFinalCharBox = 'L'; - - // Special vars - public volatile boolean volatileBoolean = true; - public transient boolean transientBoolean = true; - - // For methods testing - public boolean isAccessed = false; - public volatile boolean isFinished = false; - - private ScriptEngine engine; - - public ScriptEngine getEngine() { - return engine; - } - - public void setEngine(final ScriptEngine engine) { - this.engine = engine; - } - - public void voidMethod() { - isAccessed = true; - } - - public boolean booleanMethod(final boolean arg) { - return !arg; - } - - public Boolean booleanBoxingMethod(final Boolean arg) { - return !arg.booleanValue(); - } - - public boolean[] booleanArrayMethod(final boolean arg[]) { - final boolean[] res = new boolean[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = !arg[i]; - } - return res; - } - - public int intMethod(final int arg) { - return arg + arg; - } - - public Integer intBoxingMethod(final Integer arg) { - return arg + arg; - } - - public int[] intArrayMethod(final int arg[]) { - final int[] res = new int[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = arg[i] * 2; - } - return res; - } - - public long longMethod(final long arg) { - return arg + arg; - } - - public Long longBoxingMethod(final Long arg) { - return arg + arg; - } - - public long[] longArrayMethod(final long[] arg) { - final long[] res = new long[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = arg[i] * 2; - } - return res; - } - - public byte byteMethod(final byte arg) { - return (byte)(arg + arg); - } - - public Byte byteBoxingMethod(final Byte arg) { - return (byte)(arg + arg); - } - - public byte[] byteArrayMethod(final byte[] arg) { - final byte[] res = new byte[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = (byte)(arg[i] * 2); - } - return res; - } - - public char charMethod(final char arg) { - return Character.toUpperCase(arg); - } - - public Character charBoxingMethod(final Character arg) { - return Character.toUpperCase(arg); - } - - public char[] charArrayMethod(final char[] arg) { - final char[] res = new char[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = Character.toUpperCase(arg[i]); - } - return res; - } - - public short shortMethod(final short arg) { - return (short)(arg + arg); - } - - public Short shortBoxingMethod(final Short arg) { - return (short)(arg + arg); - } - - public short[] shortArrayMethod(final short[] arg) { - final short[] res = new short[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = (short)(arg[i] * 2); - } - return res; - } - - public float floatMethod(final float arg) { - return arg + arg; - } - - public Float floatBoxingMethod(final Float arg) { - return arg + arg; - } - - public float[] floatArrayMethod(final float[] arg) { - final float[] res = new float[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = arg[i] * 2; - } - return res; - } - - public double doubleMethod(final double arg) { - return arg + arg; - } - - public Double doubleBoxingMethod(final Double arg) { - return arg + arg; - } - - public double[] doubleArrayMethod(final double[] arg) { - final double[] res = new double[arg.length]; - for (int i = 0; i < arg.length; i++) { - res[i] = arg[i] * 2; - } - return res; - } - - public String stringMethod(final String str) { - return str + str; - } - - public String[] stringArrayMethod(final String[] arr) { - final int l = arr.length; - final String[] res = new String[l]; - for (int i = 0; i < l; i++) { - res[i] = arr[l - i - 1]; - } - return res; - } - - public Person[] objectArrayMethod(final Person[] arr) { - final Person[] res = new Person[arr.length]; - for (int i = 0; i < arr.length; i++) { - res[i] = new Person(i + 100); - } - return res; - } - - public Person objectMethod(final Person t) { - t.id *= 2; - return t; - } - - public int twoParamMethod(final long l, final double d) { - return (int)(l + d); - } - - public int threeParamMethod(final short s, final long l, final char c) { - return (int)(s + l + c); - } - - public Person[] twoObjectParamMethod(final Person arg1, final Person arg2) { - return new Person[] { arg2, arg1 }; - } - - public Person[] threeObjectParamMethod(final Person arg1, final Person arg2, final Person arg3) { - return new Person[] { arg3, arg2, arg1 }; - } - - public Person[] eightObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8) { - return new Person[] { arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 }; - } - - public Person[] nineObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8, final Person arg9) { - return new Person[] { arg9, arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 }; - } - - public Person[] methodObjectEllipsis(final Person... args) { - final int l = args.length; - final Person[] res = new Person[l]; - for (int i = 0; i < l; i++) { - res[i] = args[l - i - 1]; - } - return res; - } - - public Person[] methodPrimitiveEllipsis(final int... args) { - final int l = args.length; - final Person[] res = new Person[l]; - for (int i = 0; i < l; i++) { - res[i] = new Person(args[i]); - } - return res; - } - - public Object[] methodMixedEllipsis(final Object... args) { - return args; - } - - public Object[] methodObjectWithEllipsis(final String arg, final int... args) { - final Object[] res = new Object[args.length + 1]; - res[0] = arg; - for (int i = 0; i < args.length; i++) { - res[i + 1] = args[i]; - } - return res; - } - - public Object[] methodPrimitiveWithEllipsis(final int arg, final long... args) { - final Object[] res = new Object[args.length + 1]; - res[0] = arg; - for (int i = 0; i < args.length; i++) { - res[i + 1] = args[i]; - } - return res; - } - - public Object[] methodMixedWithEllipsis(final String arg1, final int arg2, final Object... args) { - final Object[] res = new Object[args.length + 2]; - res[0] = arg1; - res[1] = arg2; - System.arraycopy(args, 0, res, 2, args.length); - return res; - } - - public void methodStartsThread() { - isFinished = false; - - final Thread t = new Thread(new Runnable() { - @Override - public void run() { - try { - Thread.sleep(1000); - isFinished = true; - } catch (final InterruptedException e) { - e.printStackTrace(); - } - } - }); - - t.start(); - } - - public String overloadedMethodDoubleVSint(final int arg) { - return "int"; - } - - public String overloadedMethodDoubleVSint(final double arg) { - return "double"; - } - - public int overloadedMethod(final int arg) { - return arg*2; - } - - public int overloadedMethod(final String arg) { - return arg.length(); - } - - public int overloadedMethod(final boolean arg) { - return (arg) ? 1 : 0; - } - - public int overloadedMethod(final Person arg) { - return arg.id*2; - } - - public int firstLevelMethodInt(final int arg) throws ScriptException, NoSuchMethodException { - return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInt", arg); - } - - public int thirdLevelMethodInt(final int arg) { - return arg*5; - } - - public int firstLevelMethodInteger(final Integer arg) throws ScriptException, NoSuchMethodException { - return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInteger", arg); - } - - public int thirdLevelMethodInteger(final Integer arg) { - return arg*10; - } - - public Person firstLevelMethodObject(final Person p) throws ScriptException, NoSuchMethodException { - return (Person) ((Invocable)engine).invokeFunction("secondLevelMethodObject", p); - } - - public Person thirdLevelMethodObject(final Person p) { - p.id *= 10; - return p; - } - -}
--- a/test/src/jdk/nashorn/api/javaaccess/StringAccessTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,168 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.javaaccess; - -import static org.testng.AssertJUnit.assertEquals; -import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.TestNG; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * @test - * @build jdk.nashorn.api.javaaccess.SharedObject jdk.nashorn.api.javaaccess.Person jdk.nashorn.api.javaaccess.StringAccessTest - * @run testng/othervm jdk.nashorn.api.javaaccess.StringAccessTest - */ -@SuppressWarnings("javadoc") -public class StringAccessTest { - - private static ScriptEngine e = null; - private static SharedObject o = null; - - public static void main(final String[] args) { - TestNG.main(args); - } - - @BeforeClass - public static void setUpClass() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - e = m.getEngineByName("nashorn"); - o = new SharedObject(); - e.put("o", o); - e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.SharedObject;"); - } - - @AfterClass - public static void tearDownClass() { - e = null; - o = null; - } - - @Test - public void accessFieldString() throws ScriptException { - e.eval("var p_string = o.publicString;"); - assertEquals(o.publicString, e.get("p_string")); - assertEquals("string", e.eval("typeof p_string;")); - e.eval("o.publicString = 'changedString';"); - assertEquals("changedString", o.publicString); - } - - @Test - public void accessFieldStringArray() throws ScriptException { - e.eval("var p_string_array = o.publicStringArray;"); - assertEquals(o.publicStringArray[0], e.eval("o.publicStringArray[0]")); - assertArrayEquals(o.publicStringArray, (String[])e.get("p_string_array")); - e.eval("var t_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + - "t_string_arr[0] = 'abc';" + - "t_string_arr[1] = '123';" + - "t_string_arr[2] = 'xyzzzz';" + - "o.publicStringArray = t_string_arr;"); - assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, o.publicStringArray); - e.eval("o.publicStringArray[0] = 'nashorn';"); - assertEquals("nashorn", o.publicStringArray[0]); - } - - @Test - public void accessStaticFieldString() throws ScriptException { - e.eval("var ps_string = SharedObject.publicStaticString;"); - assertEquals(SharedObject.publicStaticString, e.get("ps_string")); - assertEquals("string", e.eval("typeof ps_string;")); - e.eval("SharedObject.publicStaticString = 'changedString';"); - assertEquals("changedString", SharedObject.publicStaticString); - } - - @Test - public void accessStaticFieldStringArray() throws ScriptException { - e.eval("var ps_string_array = SharedObject.publicStaticStringArray;"); - assertEquals(SharedObject.publicStaticStringArray[0], e.eval("SharedObject.publicStaticStringArray[0]")); - assertArrayEquals(SharedObject.publicStaticStringArray, (String[])e.get("ps_string_array")); - e.eval("var ts_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + - "ts_string_arr[0] = 'abc';" + - "ts_string_arr[1] = '123';" + - "ts_string_arr[2] = 'xyzzzz';" + - "SharedObject.publicStaticStringArray = ts_string_arr;"); - assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, SharedObject.publicStaticStringArray); - e.eval("SharedObject.publicStaticStringArray[0] = 'nashorn';"); - assertEquals("nashorn", SharedObject.publicStaticStringArray[0]); - } - - @Test - public void accessFinalFieldString() throws ScriptException { - e.eval("var pf_string = o.publicFinalString;"); - assertEquals(o.publicFinalString, e.get("pf_string")); - assertEquals("string", e.eval("typeof pf_string;")); - e.eval("o.publicFinalString = 'changedString';"); - assertEquals("PublicFinalString", o.publicFinalString); - } - - @Test - public void accessFinalFieldStringArray() throws ScriptException { - e.eval("var pf_string_array = o.publicFinalStringArray;"); - assertEquals(o.publicFinalStringArray[0], e.eval("o.publicFinalStringArray[0]")); - assertArrayEquals(o.publicFinalStringArray, (String[])e.get("pf_string_array")); - e.eval("var tf_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + - "tf_string_arr[0] = 'abc';" + - "tf_string_arr[1] = '123';" + - "tf_string_arr[2] = 'xyzzzz';" + - "o.publicFinalStringArray = tf_string_arr;"); - assertArrayEquals(new String[] { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" }, o.publicFinalStringArray); - e.eval("o.publicFinalStringArray[0] = 'nashorn';"); - assertEquals("nashorn", o.publicFinalStringArray[0]); - } - - @Test - public void accessStaticFinalFieldString() throws ScriptException { - e.eval("var psf_string = SharedObject.publicStaticFinalString;"); - assertEquals(SharedObject.publicStaticFinalString, e.get("psf_string")); - assertEquals("string", e.eval("typeof psf_string;")); - e.eval("SharedObject.publicStaticFinalString = 'changedString';"); - assertEquals("PublicStaticFinalString", SharedObject.publicStaticFinalString); - } - - @Test - public void accessStaticFinalFieldStringArray() throws ScriptException { - e.eval("var psf_string_array = SharedObject.publicStaticFinalStringArray;"); - assertEquals(SharedObject.publicStaticFinalStringArray[0], e.eval("SharedObject.publicStaticFinalStringArray[0]")); - assertArrayEquals(SharedObject.publicStaticFinalStringArray, (String[])e.get("psf_string_array")); - e.eval("var tsf_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + - "tsf_string_arr[0] = 'abc';" + - "tsf_string_arr[1] = '123';" + - "tsf_string_arr[2] = 'xyzzzz';" + - "SharedObject.publicStaticFinalStringArray = tsf_string_arr;"); - assertArrayEquals(new String[] { "StaticFinalArrayString[0]", - "StaticFinalArrayString[1]", - "StaticFinalArrayString[2]", - "StaticFinalArrayString[3]" }, - SharedObject.publicStaticFinalStringArray); - e.eval("SharedObject.publicStaticFinalStringArray[0] = 'nashorn';"); - assertEquals("nashorn", SharedObject.publicStaticFinalStringArray[0]); - } - -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/ArrayConversionTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; +import java.util.Arrays; +import java.util.List; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +@SuppressWarnings("javadoc") +public class ArrayConversionTest { + private static ScriptEngine e = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() { + e = new ScriptEngineManager().getEngineByName("nashorn"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + } + + @Test + public void testIntArrays() throws ScriptException { + runTest("assertNullIntArray", "null"); + runTest("assertEmptyIntArray", "[]"); + runTest("assertSingle42IntArray", "[42]"); + runTest("assertSingle42IntArray", "['42']"); + runTest("assertIntArrayConversions", "[false, true, NaN, Infinity, -Infinity, 0.4, 0.6, null, undefined, [], {}, [1], [1, 2]]"); + } + + @Test + public void testIntIntArrays() throws ScriptException { + runTest("assertNullIntIntArray", "null"); + runTest("assertEmptyIntIntArray", "[]"); + runTest("assertSingleEmptyIntIntArray", "[[]]"); + runTest("assertSingleNullIntIntArray", "[null]"); + runTest("assertLargeIntIntArray", "[[false], [1], [2, 3], [4, 5, 6], ['7', {valueOf: function() { return 8 }}]]"); + } + + @Test + public void testObjectObjectArrays() throws ScriptException { + runTest("assertLargeObjectObjectArray", "[[false], [1], ['foo', 42.3], [{x: 17}]]"); + } + + @Test + public void testBooleanArrays() throws ScriptException { + runTest("assertBooleanArrayConversions", "[false, true, '', 'false', 0, 1, 0.4, 0.6, {}, [], [false], [true], NaN, Infinity, null, undefined]"); + } + + @Test + public void testArrayAmbiguity() throws ScriptException { + runTest("x", "'abc'"); + runTest("x", "['foo', 'bar']"); + } + + @Test + public void testListArrays() throws ScriptException { + runTest("assertListArray", "[['foo', 'bar'], ['apple', 'orange']]"); + } + + @Test + public void testVarArgs() throws ScriptException { + // Sole NativeArray in vararg position becomes vararg array itself + runTest("assertVarArg_42_17", "[42, 17]"); + // NativeArray in vararg position becomes an argument if there are more arguments + runTest("assertVarArg_array_17", "[42], 18"); + // Only NativeArray is converted to vararg array, other objects (e.g. a function) aren't + runTest("assertVarArg_function", "function() { return 'Hello' }"); + } + + private static void runTest(final String testMethodName, final String argument) throws ScriptException { + e.eval("Java.type('" + ArrayConversionTest.class.getName() + "')." + testMethodName + "(" + argument + ")"); + } + + public static void assertNullIntArray(final int[] array) { + assertNull(array); + } + + public static void assertNullIntIntArray(final int[][] array) { + assertNull(array); + } + + public static void assertEmptyIntArray(final int[] array) { + assertEquals(0, array.length); + } + + public static void assertSingle42IntArray(final int[] array) { + assertEquals(1, array.length); + assertEquals(42, array[0]); + } + + + public static void assertIntArrayConversions(final int[] array) { + assertEquals(13, array.length); + assertEquals(0, array[0]); // false + assertEquals(1, array[1]); // true + assertEquals(0, array[2]); // NaN + assertEquals(0, array[3]); // Infinity + assertEquals(0, array[4]); // -Infinity + assertEquals(0, array[5]); // 0.4 + assertEquals(0, array[6]); // 0.6 - floor, not round + assertEquals(0, array[7]); // null + assertEquals(0, array[8]); // undefined + assertEquals(0, array[9]); // [] + assertEquals(0, array[10]); // {} + assertEquals(1, array[11]); // [1] + assertEquals(0, array[12]); // [1, 2] + } + + public static void assertEmptyIntIntArray(final int[][] array) { + assertEquals(0, array.length); + } + + public static void assertSingleEmptyIntIntArray(final int[][] array) { + assertEquals(1, array.length); + assertTrue(Arrays.equals(new int[0], array[0])); + } + + public static void assertSingleNullIntIntArray(final int[][] array) { + assertEquals(1, array.length); + assertNull(null, array[0]); + } + + public static void assertLargeIntIntArray(final int[][] array) { + assertEquals(5, array.length); + assertTrue(Arrays.equals(new int[] { 0 }, array[0])); + assertTrue(Arrays.equals(new int[] { 1 }, array[1])); + assertTrue(Arrays.equals(new int[] { 2, 3 }, array[2])); + assertTrue(Arrays.equals(new int[] { 4, 5, 6 }, array[3])); + assertTrue(Arrays.equals(new int[] { 7, 8 }, array[4])); + } + + public static void assertLargeObjectObjectArray(final Object[][] array) throws ScriptException { + assertEquals(4, array.length); + assertTrue(Arrays.equals(new Object[] { Boolean.FALSE }, array[0])); + assertTrue(Arrays.equals(new Object[] { 1 }, array[1])); + assertTrue(Arrays.equals(new Object[] { "foo", 42.3d }, array[2])); + assertEquals(1, array[3].length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("obj", array[3][0]); + assertEquals(17, e.eval("obj.x")); + } + + public static void assertBooleanArrayConversions(final boolean[] array) { + assertEquals(16, array.length); + assertFalse(array[0]); // false + assertTrue(array[1]); // true + assertFalse(array[2]); // '' + assertTrue(array[3]); // 'false' (yep, every non-empty string converts to true) + assertFalse(array[4]); // 0 + assertTrue(array[5]); // 1 + assertTrue(array[6]); // 0.4 + assertTrue(array[7]); // 0.6 + assertTrue(array[8]); // {} + assertTrue(array[9]); // [] + assertTrue(array[10]); // [false] + assertTrue(array[11]); // [true] + assertFalse(array[12]); // NaN + assertTrue(array[13]); // Infinity + assertFalse(array[14]); // null + assertFalse(array[15]); // undefined + } + + public static void assertListArray(final List<?>[] array) { + assertEquals(2, array.length); + assertEquals(Arrays.asList("foo", "bar"), array[0]); + assertEquals(Arrays.asList("apple", "orange"), array[1]); + } + + public static void assertVarArg_42_17(final Object... args) { + assertEquals(2, args.length); + assertEquals(42, ((Number)args[0]).intValue()); + assertEquals(17, ((Number)args[1]).intValue()); + } + + public static void assertVarArg_array_17(final Object... args) throws ScriptException { + assertEquals(2, args.length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("arr", args[0]); + assertTrue((Boolean)e.eval("arr instanceof Array && arr.length == 1 && arr[0] == 42")); + assertEquals(18, ((Number)args[1]).intValue()); + } + + public static void assertVarArg_function(final Object... args) throws ScriptException { + assertEquals(1, args.length); + e.getBindings(ScriptContext.ENGINE_SCOPE).put("fn", args[0]); + assertEquals("Hello", e.eval("fn()")); + } + + + + public static void x(final String y) { + assertEquals("abc", y); + } + public static void x(final String[] y) { + assertTrue(Arrays.equals(new String[] { "foo", "bar"}, y)); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/BooleanAccessTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; +import java.util.Arrays; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.BooleanAccessTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.BooleanAccessTest + */ +@SuppressWarnings("javadoc") +public class BooleanAccessTest { + + private static ScriptEngine e = null; + private static SharedObject o = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + @Test + public void accessFieldBoolean() throws ScriptException { + e.eval("var p_boolean = o.publicBoolean;"); + assertEquals(o.publicBoolean, e.get("p_boolean")); + assertEquals("boolean", e.eval("typeof p_boolean;")); + e.eval("o.publicBoolean = false;"); + assertEquals(false, o.publicBoolean); + } + + @Test + public void accessFieldBooleanArray() throws ScriptException { + e.eval("var p_boolean_array = o.publicBooleanArray;"); + assertEquals(o.publicBooleanArray[0], e.eval("o.publicBooleanArray[0]")); + assertTrue(Arrays.equals(o.publicBooleanArray, (boolean[])e.get("p_boolean_array"))); + e.eval("var t_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + + "t_boolean_arr[0] = true;" + + "t_boolean_arr[1] = false;" + + "t_boolean_arr[2] = false;" + + "o.publicBooleanArray = t_boolean_arr;"); + assertTrue(Arrays.equals(new boolean[] { true, false, false }, o.publicBooleanArray)); + e.eval("o.publicBooleanArray[0] = false;"); + assertEquals(false, o.publicBooleanArray[0]); + } + + @Test + public void accessStaticFieldBoolean() throws ScriptException { + e.eval("var ps_boolean = SharedObject.publicStaticBoolean;"); + assertEquals(SharedObject.publicStaticBoolean, e.get("ps_boolean")); + assertEquals("boolean", e.eval("typeof ps_boolean;")); + e.eval("SharedObject.publicStaticBoolean = false;"); + assertEquals(false, SharedObject.publicStaticBoolean); + } + + @Test + public void accessStaticFieldBooleanArray() throws ScriptException { + e.eval("var ps_boolean_array = SharedObject.publicStaticBooleanArray;"); + assertEquals(SharedObject.publicStaticBooleanArray[0], e.eval("SharedObject.publicStaticBooleanArray[0]")); + assertTrue(Arrays.equals(SharedObject.publicStaticBooleanArray, (boolean[])e.get("ps_boolean_array"))); + e.eval("var ts_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + + "ts_boolean_arr[0] = true;" + + "ts_boolean_arr[1] = false;" + + "ts_boolean_arr[2] = true;" + + "SharedObject.publicStaticBooleanArray = ts_boolean_arr;"); + assertTrue(Arrays.equals(new boolean[] { true, false, true }, SharedObject.publicStaticBooleanArray)); + e.eval("SharedObject.publicStaticBooleanArray[0] = false;"); + assertEquals(false, SharedObject.publicStaticBooleanArray[0]); + } + + @Test + public void accessFinalFieldBoolean() throws ScriptException { + e.eval("var pf_boolean = o.publicFinalBoolean;"); + assertEquals(o.publicFinalBoolean, e.get("pf_boolean")); + assertEquals("boolean", e.eval("typeof pf_boolean;")); + e.eval("o.publicFinalBoolean = false;"); + assertEquals(true, o.publicFinalBoolean); + } + + @Test + public void accessFinalFieldBooleanArray() throws ScriptException { + e.eval("var pf_boolean_array = o.publicFinalBooleanArray;"); + assertEquals(o.publicFinalBooleanArray[0], e.eval("o.publicFinalBooleanArray[0]")); + assertTrue(Arrays.equals(o.publicFinalBooleanArray, (boolean[])e.get("pf_boolean_array"))); + e.eval("var tf_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + + "tf_boolean_arr[0] = false;" + + "tf_boolean_arr[1] = false;" + + "tf_boolean_arr[2] = true;" + + "o.publicOFinalbjectArray = tf_boolean_arr;"); + assertTrue(Arrays.equals(new boolean[] { false, false, true, false }, o.publicFinalBooleanArray)); + e.eval("o.publicFinalBooleanArray[0] = true;"); + assertEquals(true, o.publicFinalBooleanArray[0]); + } + + @Test + public void accessStaticFinalFieldBoolean() throws ScriptException { + e.eval("var psf_boolean = SharedObject.publicStaticFinalBoolean;"); + assertEquals(SharedObject.publicStaticFinalBoolean, e.get("psf_boolean")); + assertEquals("boolean", e.eval("typeof psf_boolean;")); + e.eval("SharedObject.publicStaticFinalBoolean = false;"); + assertEquals(true, SharedObject.publicStaticFinalBoolean); + } + + @Test + public void accessStaticFinalFieldBooleanArray() throws ScriptException { + e.eval("var psf_boolean_array = SharedObject.publicStaticFinalBooleanArray;"); + assertEquals(SharedObject.publicStaticFinalBooleanArray[0], e.eval("SharedObject.publicStaticFinalBooleanArray[0]")); + assertTrue(Arrays.equals(SharedObject.publicStaticFinalBooleanArray, (boolean[])e.get("psf_boolean_array"))); + e.eval("var tsf_boolean_arr = new (Java.type(\"boolean[]\"))(3);" + + "tsf_boolean_arr[0] = false;" + + "tsf_boolean_arr[1] = true;" + + "tsf_boolean_arr[2] = false;" + + "SharedObject.publicStaticFinalBooleanArray = tsf_boolean_arr;"); + assertTrue(Arrays.equals(new boolean[] { false, true, false, false }, SharedObject.publicStaticFinalBooleanArray)); + e.eval("SharedObject.publicStaticFinalBooleanArray[0] = true;"); + assertEquals(true, SharedObject.publicStaticFinalBooleanArray[0]); + } + + @Test + public void accessFieldBooleanBoxing() throws ScriptException { + e.eval("var p_boolean_box = o.publicBooleanBox;"); + assertEquals(o.publicBooleanBox, e.get("p_boolean_box")); + assertEquals("boolean", e.eval("typeof p_boolean_box;")); + e.eval("o.publicBooleanBox = false;"); + assertEquals(false, (boolean)o.publicBooleanBox); + } + + @Test + public void accessStaticFieldBooleanBoxing() throws ScriptException { + e.eval("var ps_boolean_box = SharedObject.publicStaticBooleanBox;"); + assertEquals(SharedObject.publicStaticBooleanBox, e.get("ps_boolean_box")); + assertEquals("boolean", e.eval("typeof ps_boolean_box;")); + e.eval("SharedObject.publicStaticBooleanBox = false;"); + assertEquals(false, (boolean)SharedObject.publicStaticBooleanBox); + } + + @Test + public void accessFinalFieldBooleanBoxing() throws ScriptException { + e.eval("var pf_boolean_box = o.publicFinalBooleanBox;"); + assertEquals(o.publicFinalBooleanBox, e.get("pf_boolean_box")); + assertEquals("boolean", e.eval("typeof pf_boolean_box;")); + e.eval("o.publicFinalBooleanBox = false;"); + assertEquals(true, (boolean)o.publicFinalBooleanBox); + } + + @Test + public void accessStaticFinalFieldBooleanBoxing() throws ScriptException { + e.eval("var psf_boolean_box = SharedObject.publicStaticFinalBooleanBox;"); + assertEquals(SharedObject.publicStaticFinalBooleanBox, e.get("psf_boolean_box")); + assertEquals("boolean", e.eval("typeof psf_boolean_box;")); + e.eval("SharedObject.publicStaticFinalBooleanBox = false;"); + assertEquals(true, (boolean)SharedObject.publicStaticFinalBooleanBox); + } + + @Test + public void accessVolatileField() throws ScriptException { + e.eval("var pv_boolean = o.volatileBoolean;"); + assertEquals(o.volatileBoolean, e.get("pv_boolean")); + assertEquals("boolean", e.eval("typeof pv_boolean;")); + e.eval("o.volatileBoolean = false;"); + assertEquals(false, o.volatileBoolean); + } + + @Test + public void accessTransientField() throws ScriptException { + e.eval("var pt_boolean = o.transientBoolean;"); + assertEquals(o.transientBoolean, e.get("pt_boolean")); + assertEquals("boolean", e.eval("typeof pt_boolean;")); + e.eval("o.transientBoolean = false;"); + assertEquals(false, o.transientBoolean); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/ConsStringTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import java.util.HashMap; +import java.util.Map; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.JSObject; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +@SuppressWarnings("javadoc") +public class ConsStringTest { + private static ScriptEngine e = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() { + e = new ScriptEngineManager().getEngineByName("nashorn"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + } + + @Test + public void testConsStringFlattening() throws ScriptException { + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); + final Map<Object, Object> m = new HashMap<>(); + b.put("m", m); + e.eval("var x = 'f'; x += 'oo'; var y = 'b'; y += 'ar'; m.put(x, y)"); + assertEquals("bar", m.get("foo")); + } + + @Test + public void testConsStringFromMirror() throws ScriptException { + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); + //final Map<Object, Object> m = new HashMap<>(); + e.eval("var x = 'f'; x += 'oo'; var obj = {x: x};"); + assertEquals("foo", ((JSObject)b.get("obj")).getMember("x")); + } + + @Test + public void testArrayConsString() throws ScriptException { + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); + final ArrayHolder h = new ArrayHolder(); + b.put("h", h); + e.eval("var x = 'f'; x += 'oo'; h.array = [x];"); + assertEquals(1, h.array.length); + assertEquals("foo", h.array[0]); + } + + + public static class ArrayHolder { + private Object[] array; + + public void setArray(final Object[] array) { + this.array = array; + } + + public Object[] getArray() { + return array; + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/MethodAccessTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; +import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; +import java.util.Arrays; +import java.util.Calendar; +import java.util.Locale; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.MethodAccessTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.MethodAccessTest + */ +@SuppressWarnings("javadoc") +public class MethodAccessTest { + + private static ScriptEngine e = null; + private static SharedObject o = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + o.setEngine(e); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.test.Person;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + @Test + public void accessMethodthrowsCheckedException() throws ScriptException { + e.eval("try {" + + " var a = java.lang.Long.parseLong('foo');" + + "} catch(e) {" + + " var isThrown = true;" + + " var isNumberException = e instanceof java.lang.NumberFormatException;" + + "} finally {" + + " var isFinalized = true;" + + "}"); + assertEquals("Exception thrown", true, e.get("isThrown")); + assertEquals("Finally called", true, e.get("isFinalized")); + assertEquals("Type is NumberFormatException", true, e.get("isNumberException")); + } + + @Test + public void accessMethodthrowsUnCheckedException() throws ScriptException { + e.eval("try {" + + " var a = java.lang.String.valueOf(null);" + + "} catch(e) {" + + " var isThrown = true;" + + " var isNumberException = e instanceof java.lang.NullPointerException;" + + "} finally {" + + " var isFinalized = true;" + + "}"); + assertEquals(true, e.get("isThrown")); + assertEquals(true, e.get("isFinalized")); + assertEquals(true, e.get("isNumberException")); + } + + @Test + public void accessMethodStartsThread() throws ScriptException { + e.eval("o.methodStartsThread();"); + assertEquals(false, o.isFinished); + } + + @Test + public void accessStaticMethod() throws ScriptException { + assertEquals(10, e.eval("java.lang.Math.abs(-10);")); + } + + @Test + public void accessSynchronousMethod() throws ScriptException { + e.eval("var v = new java.util.Vector();" + "v.add(10);" + "v.add(20);" + "v.add(30);"); + assertEquals(10, e.eval("v[0]")); + assertEquals(20, e.eval("v[1]")); + assertEquals(30, e.eval("v[2]")); + assertEquals(3, e.eval("v.size()")); + } + + @Test + public void accessStaticSynchronousMethod() throws ScriptException { + e.eval("var locales = java.util.Calendar.getAvailableLocales();"); + final Locale[] locales = (Locale[])e.get("locales"); + assertEquals(locales.length, Calendar.getAvailableLocales().length); + } + + @Test + public void accessNativeMethod() throws ScriptException { + assertEquals(4.0, e.eval("java.lang.StrictMath.log10(10000);")); + } + + @Test + public void accessConstructorOfAbstractClass() throws ScriptException { + e.eval("try {" + + " var a = new java.util.AbstractList();" + + " print('fail');" + + "} catch(e) {" + + " var isThrown = true;" + + "}"); + assertEquals(true, e.get("isThrown")); + } + + @Test + public void accessMethodVoid() throws ScriptException { + o.isAccessed = false; + e.eval("o.voidMethod();"); + assertTrue(o.isAccessed); + } + + @Test + public void accessMethodBoolean() throws ScriptException { + assertEquals(true, e.eval("o.booleanMethod(false);")); + assertEquals(false, e.eval("o.booleanMethod(true);")); + assertEquals(false, e.eval("o.booleanMethod('false');")); + assertEquals(true, e.eval("o.booleanMethod('');")); + assertEquals(true, e.eval("o.booleanMethod(0);")); + } + + @Test + public void accessMethodInt() throws ScriptException { + assertEquals(0, e.eval("o.intMethod(0);")); + assertEquals(-200, e.eval("o.intMethod(-100);")); + assertEquals(0, e.eval("o.intMethod('0');")); + assertEquals(-200, e.eval("o.intMethod('-100');")); + } + + @Test + public void accessMethodLong() throws ScriptException { + assertEquals((long)0, e.eval("o.longMethod(0);")); + assertEquals((long)400, e.eval("o.longMethod(200);")); + assertEquals((long) 0, e.eval("o.longMethod('0');")); + assertEquals((long) 400, e.eval("o.longMethod('200');")); + } + + @Test + public void accessMethodByte() throws ScriptException { + assertEquals((byte) 0, e.eval("o.byteMethod(0);")); + assertEquals((byte) 10, e.eval("o.byteMethod(5);")); + assertEquals((byte) 0, e.eval("o.byteMethod('0');")); + assertEquals((byte) 10, e.eval("o.byteMethod('5');")); + } + + @Test + public void accessMethodShort() throws ScriptException { + assertEquals((short)0, e.eval("o.shortMethod(0);")); + assertEquals((short)8000, e.eval("o.shortMethod(4000);")); + assertEquals((short) 0, e.eval("o.shortMethod('0');")); + assertEquals((short) 8000, e.eval("o.shortMethod('4000');")); + } + + @Test + public void accessMethodChar() throws ScriptException { + assertEquals('A', e.eval("o.charMethod('a');")); + assertEquals('Z', e.eval("o.charMethod('z');")); + assertEquals(o.charMethod((char)0), e.eval("o.charMethod(0);")); + assertEquals(o.charMethod((char)3150), e.eval("o.charMethod(3150);")); + } + + @Test + public void accessMethodFloat() throws ScriptException { + assertEquals(0.0f, e.eval("o.floatMethod(0.0);")); + assertEquals(4.2f, e.eval("o.floatMethod(2.1);")); + assertEquals(0.0f, e.eval("o.floatMethod('0.0');")); + assertEquals(4.2f, e.eval("o.floatMethod('2.1');")); + } + + @Test + public void accessMethodDouble() throws ScriptException { + assertEquals(0.0, e.eval("o.doubleMethod(0.0);")); + assertEquals(14.0, e.eval("o.doubleMethod(7.0);")); + assertEquals(0.0, e.eval("o.doubleMethod('0.0');")); + assertEquals(14.0, e.eval("o.doubleMethod('7.0');")); + } + + @Test + public void accessMethodBooleanBoxing() throws ScriptException { + assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.FALSE);")); + assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod(java.lang.Boolean.TRUE);")); + assertEquals(Boolean.TRUE, e.eval("o.booleanBoxingMethod('');")); + assertEquals(Boolean.FALSE, e.eval("o.booleanBoxingMethod('false');")); + } + + @Test + public void accessMethodIntBoxing() throws ScriptException { + assertEquals(0, e.eval("o.intBoxingMethod(0);")); + assertEquals(-200, e.eval("o.intBoxingMethod(-100);")); + assertTrue((int)e.eval("(new java.lang.Integer(2)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodLongBoxing() throws ScriptException { + assertEquals((long) 0, e.eval("o.longBoxingMethod(0);")); + assertEquals((long) 400, e.eval("o.longBoxingMethod(200);")); + assertTrue((int)e.eval("(new java.lang.Long(2)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodByteBoxing() throws ScriptException { + assertEquals((byte) 0, e.eval("o.byteBoxingMethod(0);")); + assertEquals((byte) 10, e.eval("o.byteBoxingMethod(5);")); + assertTrue((int)e.eval("(new java.lang.Byte(2)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodShortBoxing() throws ScriptException { + assertEquals((short) 0, e.eval("o.shortBoxingMethod(0);")); + assertEquals((short) 8000, e.eval("o.shortBoxingMethod(4000);")); + assertTrue((int)e.eval("(new java.lang.Short(2)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodCharBoxing() throws ScriptException { + assertEquals('A', e.eval("o.charBoxingMethod('a');")); + assertEquals('Z', e.eval("o.charBoxingMethod('z');")); + assertTrue((int)e.eval("(new java.lang.Character(2)).compareTo(10)") < 0); + } + + @Test + public void accessMethodFloatBoxing() throws ScriptException { + assertEquals(0.0f, e.eval("o.floatBoxingMethod(0.0);")); + assertEquals(4.2f, e.eval("o.floatBoxingMethod(2.1);")); + assertTrue((int)e.eval("(new java.lang.Float(2.0)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodDoubleBoxing() throws ScriptException { + assertEquals(0.0, e.eval("o.doubleBoxingMethod(0.0);")); + assertEquals(14.0, e.eval("o.doubleBoxingMethod(7.0);")); + assertTrue((int)e.eval("(new java.lang.Double(2)).compareTo(10.0)") < 0); + } + + @Test + public void accessMethodString() throws ScriptException { + assertEquals("", e.eval("o.stringMethod('');")); + assertEquals("abcabc", e.eval("o.stringMethod('abc');")); + } + + @Test + public void accessMethodObject() throws ScriptException { + e.put("so", new Person(5)); + e.eval("var rso = o.objectMethod(so);"); + assertEquals(new Person(10), e.get("rso")); + } + + @Test + public void accessMethodBooleanArray() throws ScriptException { + assertTrue(Arrays.equals(o.booleanArrayMethod(o.publicBooleanArray), (boolean[])e.eval("o.booleanArrayMethod(o.publicBooleanArray);"))); + } + + @Test + public void accessMethodIntArray() throws ScriptException { + assertArrayEquals(o.intArrayMethod(o.publicIntArray), (int[])e.eval("o.intArrayMethod(o.publicIntArray);")); + } + + @Test + public void accessMethodLongArray() throws ScriptException { + assertArrayEquals(o.longArrayMethod(o.publicLongArray), (long[])e.eval("o.longArrayMethod(o.publicLongArray);")); + } + + @Test + public void accessMethodByteArray() throws ScriptException { + assertArrayEquals(o.byteArrayMethod(o.publicByteArray), (byte[])e.eval("o.byteArrayMethod(o.publicByteArray);")); + } + + @Test + public void accessMethodShortArray() throws ScriptException { + assertArrayEquals(o.shortArrayMethod(o.publicShortArray), (short[])e.eval("o.shortArrayMethod(o.publicShortArray);")); + } + + @Test + public void accessMethodCharArray() throws ScriptException { + assertArrayEquals(o.charArrayMethod(o.publicCharArray), (char[])e.eval("o.charArrayMethod(o.publicCharArray);")); + } + + @Test + public void accessMethodFloatArray() throws ScriptException { + assertArrayEquals(o.floatArrayMethod(o.publicFloatArray), (float[])e.eval("o.floatArrayMethod(o.publicFloatArray);"), 1e-10f); + } + + @Test + public void accessMethodDoubleArray() throws ScriptException { + assertArrayEquals(o.doubleArrayMethod(o.publicDoubleArray), (double[])e.eval("o.doubleArrayMethod(o.publicDoubleArray);"), 1e-10); + } + + @Test + public void accessMethodStringArray() throws ScriptException { + assertArrayEquals(o.stringArrayMethod(o.publicStringArray), (String[])e.eval("o.stringArrayMethod(o.publicStringArray);")); + } + + @Test + public void accessMethodObjectArray() throws ScriptException { + assertArrayEquals(o.objectArrayMethod(o.publicObjectArray), (Person[])e.eval("o.objectArrayMethod(o.publicObjectArray);")); + } + + @Test + public void accessDefaultConstructor() throws ScriptException { + e.eval("var dc = new Packages.jdk.nashorn.api.javaaccess.test.Person()"); + assertEquals(new Person(), e.get("dc")); + } + + @Test + public void accessCustomConstructor() throws ScriptException { + e.eval("var cc = new Packages.jdk.nashorn.api.javaaccess.test.Person(17)"); + assertEquals(new Person(17), e.get("cc")); + } + + @Test + public void accessMethod2PrimitiveParams() throws ScriptException { + assertEquals(o.twoParamMethod(50, 40.0), e.eval("o.twoParamMethod(50,40);")); + } + + @Test + public void accessMethod3PrimitiveParams() throws ScriptException { + assertEquals(o.threeParamMethod((short)10, 20L, 'b'), e.eval("o.threeParamMethod(10,20,'b');")); + } + + @Test + public void accessMethod2ObjectParams() throws ScriptException { + assertArrayEquals(new Person[] { new Person(200), new Person(300) }, (Person[])e.eval("o.twoObjectParamMethod(new Person(300),new Person(200));")); + } + + @Test + public void accessMethod3ObjectParams() throws ScriptException { + assertArrayEquals(new Person[] { new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.threeObjectParamMethod(new Person(1),new Person(2),new Person(3));")); + } + + @Test + public void accessMethod8ObjectParams() throws ScriptException { + assertArrayEquals(new Person[] { new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.eightObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6),new Person(7),new Person(8));")); + } + + @Test + public void accessMethod9ObjectParams() throws ScriptException { + assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.nineObjectParamMethod(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));")); + } + + @Test + public void accessMethodObjectEllipsis() throws ScriptException { + assertArrayEquals(new Person[] { new Person(9), new Person(8), new Person(7), new Person(6), new Person(5), new Person(4), new Person(3), new Person(2), new Person(1) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(1),new Person(2),new Person(3)," + "new Person(4),new Person(5),new Person(6)," + "new Person(7),new Person(8),new Person(9));")); + assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodObjectEllipsis()")); + assertArrayEquals(new Person[] { new Person(9) }, (Person[])e.eval("o.methodObjectEllipsis(new Person(9))")); + } + + @Test + public void accessMethodPrimitiveEllipsis() throws ScriptException { + assertArrayEquals(new Person[] { new Person(1), new Person(3), new Person(2) }, (Person[])e.eval("o.methodPrimitiveEllipsis(1,3,2);")); + assertArrayEquals(new Person[] {}, (Person[])e.eval("o.methodPrimitiveEllipsis();")); + assertArrayEquals(o.methodPrimitiveEllipsis(9, 8, 7, 6, 5, 4, 3, 2, 1), (Person[])e.eval("o.methodPrimitiveEllipsis(9,8,7,6,5,4,3,2,1);")); + } + + @Test + public void accessMethodMixedEllipsis() throws ScriptException { + assertArrayEquals(new Object[] { new Person(1), 12, "hello", true }, (Object[])e.eval("o.methodMixedEllipsis(new Person(1),12,'hello',true);")); + assertArrayEquals(new Object[] {}, (Object[])e.eval("o.methodMixedEllipsis();")); + } + + @Test + public void accessMethodObjectWithEllipsis() throws ScriptException { + assertArrayEquals(new Object[] { "hello", 12, 15, 16 }, (Object[])e.eval("o.methodObjectWithEllipsis('hello',12,15,16);")); + assertArrayEquals(new Object[] { "hello" }, (Object[])e.eval("o.methodObjectWithEllipsis('hello');")); + } + + @Test + public void accessMethodPrimitiveWithEllipsis() throws ScriptException { + assertArrayEquals(new Object[] { 14, 12L, 15L, 16L }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(14,12,15,16);")); + assertArrayEquals(new Object[] { 12 }, (Object[])e.eval("o.methodPrimitiveWithEllipsis(12);")); + } + + @Test + public void accessMethodMixedWithEllipsis() throws ScriptException { + assertArrayEquals(new Object[] { "Hello", 10, true, -100500, 80d }, (Object[])e.eval("o.methodMixedWithEllipsis('Hello', 10, true, -100500,80.0);")); + assertArrayEquals(new Object[] { "Nashorn", 15 }, (Object[])e.eval("o.methodMixedWithEllipsis('Nashorn',15);")); + } + + @Test + public void accessMethodOverloaded() throws ScriptException { + assertEquals(0, e.eval("o.overloadedMethod(0);")); + assertEquals(2000, e.eval("o.overloadedMethod(1000);")); + assertEquals(2, e.eval("o.overloadedMethod('10');")); + assertEquals(7, e.eval("o.overloadedMethod('Nashorn');")); + assertEquals(4, e.eval("o.overloadedMethod('true');")); + assertEquals(1, e.eval("o.overloadedMethod(true);")); + assertEquals(0, e.eval("o.overloadedMethod(false);")); + assertEquals(44, e.eval("o.overloadedMethod(new Person(22));")); + assertEquals(0, e.eval("o.overloadedMethod(new Person());")); + } + + @Test + public void accessMethodDoubleVSintOverloaded() throws ScriptException { + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.0);")); + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(1000.0);")); + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(0.01);")); + assertEquals("double", e.eval("o.overloadedMethodDoubleVSint(100.02);")); + assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(0);")); + assertEquals("int", e.eval("o.overloadedMethodDoubleVSint(1000);")); + } + + @Test + public void accessJavaMethodIntFromJSFromJavaFromJS() throws ScriptException { + e.eval("function secondLevelMethodInt(a) {" + + "return o.thirdLevelMethodInt(a);" + + "}"); + assertEquals(50, e.eval("o.firstLevelMethodInt(10);")); + } + + @Test + public void accessJavaMethodIntegerFromJSFromJavaFromJS() throws ScriptException { + e.eval("function secondLevelMethodInteger(a) {" + + "return o.thirdLevelMethodInteger(a);" + + "}"); + assertEquals(100, e.eval("o.firstLevelMethodInteger(10);")); + } + + @Test + public void accessJavaMethodObjectFromJSFromJavaFromJS() throws ScriptException { + e.eval("function secondLevelMethodObject(p) {" + + "return o.thirdLevelMethodObject(p);" + + "}"); + assertEquals(new Person(100), e.eval("o.firstLevelMethodObject(new Person(10));")); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/NumberAccessTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,789 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; +import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.NumberAccessTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.NumberAccessTest + */ +@SuppressWarnings("javadoc") +public class NumberAccessTest { + + private static ScriptEngine e; + private static SharedObject o; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + // --------------------------------long + // tests------------------------------------ + @Test + public void accessFieldLong() throws ScriptException { + e.eval("var p_long = o.publicLong;"); + assertEquals(o.publicLong, e.get("p_long")); + e.eval("o.publicLong = 12;"); + assertEquals(12, o.publicLong); + } + + @Test + public void accessFieldLongArray() throws ScriptException { + e.eval("var p_long_array = o.publicLongArray;"); + assertEquals(o.publicLongArray[0], e.eval("o.publicLongArray[0];")); + assertArrayEquals(o.publicLongArray, (long[])e.get("p_long_array")); + e.eval("var t_long_arr = new (Java.type(\"long[]\"))(3);" + + "t_long_arr[0] = -189009;" + + "t_long_arr[1] = 456;" + + "t_long_arr[2] = 600000001;" + + "o.publicLongArray = t_long_arr;"); + // e.eval("o.publicIntArray = [-189009,456,600000001];"); + assertArrayEquals(new long[] { -189009, 456, 600000001 }, o.publicLongArray); + e.eval("o.publicLongArray[0] = 10;"); + assertEquals(10, o.publicLongArray[0]); + } + + @Test + public void accessStaticFieldLong() throws ScriptException { + e.eval("var ps_long = SharedObject.publicStaticLong;"); + assertEquals(SharedObject.publicStaticLong, e.get("ps_long")); + e.eval("SharedObject.publicStaticLong = 120;"); + assertEquals(120, SharedObject.publicStaticLong); + } + + @Test + public void accessStaticFieldLongArray() throws ScriptException { + e.eval("var ps_long_array = SharedObject.publicStaticLongArray;"); + assertEquals(SharedObject.publicStaticLongArray[0], e.eval("SharedObject.publicStaticLongArray[0];")); + assertArrayEquals(SharedObject.publicStaticLongArray, (long[])e.get("ps_long_array")); + e.eval("var ts_long_arr = new (Java.type(\"long[]\"))(3);" + + "ts_long_arr[0] = -189009;" + + "ts_long_arr[1] = 456;" + + "ts_long_arr[2] = 600000001;" + + "SharedObject.publicStaticLongArray = ts_long_arr;"); + // e.eval("o.publicIntArray = [-189009,456,600000001];"); + assertArrayEquals(new long[] { -189009, 456, 600000001 }, SharedObject.publicStaticLongArray); + e.eval("SharedObject.publicStaticLongArray[0] = 10;"); + assertEquals(10, SharedObject.publicStaticLongArray[0]); + } + + @Test + public void accessFinalFieldLong() throws ScriptException { + e.eval("var pf_long = o.publicFinalLong;"); + assertEquals(o.publicFinalLong, e.get("pf_long")); + e.eval("o.publicFinalLong = 120;"); + assertEquals(13353333333333333L, o.publicFinalLong); + } + + @Test + public void accessFinalFieldLongArray() throws ScriptException { + e.eval("var pf_long_array = o.publicFinalLongArray;"); + assertEquals(o.publicFinalLongArray[0], e.eval("o.publicFinalLongArray[0];")); + assertArrayEquals(o.publicFinalLongArray, (long[])e.get("pf_long_array")); + e.eval("var tf_long_arr = new (Java.type(\"long[]\"))(3);" + + "tf_long_arr[0] = -189009;" + + "tf_long_arr[1] = 456;" + + "tf_long_arr[2] = 600000001;" + + "o.publicFinalLongArray = tf_long_arr;"); + // e.eval("o.publicIntArray = [-189009,456,600000001];"); + assertArrayEquals(new long[] { 1901733333333L, -2247355555L, 3977377777L }, o.publicFinalLongArray); + e.eval("o.publicFinalLongArray[0] = 10;"); + assertEquals(10, o.publicFinalLongArray[0]); + } + + @Test + public void accessStaticFinalFieldLong() throws ScriptException { + e.eval("var psf_long = SharedObject.publicStaticFinalLong;"); + assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long")); + e.eval("SharedObject.publicStaticFinalLong = 120;"); + assertEquals(8333333333333L, SharedObject.publicStaticFinalLong); + } + + @Test + public void accessStaticFinalFieldLongArray() throws ScriptException { + e.eval("var psf_long_array = SharedObject.publicStaticFinalLongArray;"); + assertEquals(SharedObject.publicStaticFinalLongArray[0], e.eval("SharedObject.publicStaticFinalLongArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalLongArray, (long[])e.get("psf_long_array")); + e.eval("var tsf_long_arr = new (Java.type(\"long[]\"))(3);" + + "tsf_long_arr[0] = -189009;" + + "tsf_long_arr[1] = 456;" + + "tsf_long_arr[2] = 600000001;" + + "SharedObject.publicStaticFinalLongArray = tsf_long_arr;"); + // e.eval("o.publicIntArray = [-189009,456,600000001];"); + assertArrayEquals(new long[] { 19017383333L, -2247358L, 39773787L }, SharedObject.publicStaticFinalLongArray); + e.eval("SharedObject.publicStaticFinalLongArray[0] = 10;"); + assertEquals(10, SharedObject.publicStaticFinalLongArray[0]); + } + + // --------------------------------int + // tests------------------------------------ + @Test + public void accessFieldInt() throws ScriptException { + e.eval("var p_int = o.publicInt;"); + assertEquals(o.publicInt, e.get("p_int")); + e.eval("o.publicInt = 14;"); + assertEquals(14, o.publicInt); + } + + @Test + public void accessFieldIntArray() throws ScriptException { + e.eval("var p_int_array = o.publicIntArray;"); + assertEquals(o.publicIntArray[0], e.eval("o.publicIntArray[0];")); + assertArrayEquals(o.publicIntArray, (int[])e.get("p_int_array")); + e.eval("var t_int_arr = new (Java.type(\"int[]\"))(3);" + + "t_int_arr[0] = 4;" + + "t_int_arr[1] = 5;" + + "t_int_arr[2] = 6;" + + "o.publicIntArray = t_int_arr;"); + assertArrayEquals(new int[] { 4, 5, 6 }, o.publicIntArray); + e.eval("o.publicIntArray[0] = 100;"); + assertEquals(100, o.publicIntArray[0]); + } + + @Test + public void accessStaticFieldInt() throws ScriptException { + e.eval("var ps_int = SharedObject.publicStaticInt;"); + assertEquals(SharedObject.publicStaticInt, e.get("ps_int")); + e.eval("SharedObject.publicStaticInt = 140;"); + assertEquals(140, SharedObject.publicStaticInt); + } + + @Test + public void accessStaticFieldIntArray() throws ScriptException { + e.eval("var ps_int_array = SharedObject.publicStaticIntArray;"); + assertEquals(SharedObject.publicStaticIntArray[0], e.eval("SharedObject.publicStaticIntArray[0];")); + assertArrayEquals(SharedObject.publicStaticIntArray, (int[])e.get("ps_int_array")); + e.eval("var ts_int_arr = new (Java.type(\"int[]\"))(3);" + + "ts_int_arr[0] = 4;" + + "ts_int_arr[1] = 5;" + + "ts_int_arr[2] = 6;" + + "SharedObject.publicStaticIntArray = ts_int_arr;"); + assertArrayEquals(new int[] { 4, 5, 6 }, SharedObject.publicStaticIntArray); + e.eval("SharedObject.publicStaticIntArray[0] = 100;"); + assertEquals(100, SharedObject.publicStaticIntArray[0]); + } + + @Test + public void accessFinalFieldInt() throws ScriptException { + e.eval("var pf_int = o.publicFinalInt;"); + assertEquals(o.publicFinalInt, e.get("pf_int")); + + e.eval("o.publicFinalInt = 10;"); + assertEquals(20712023, o.publicFinalInt); + } + + @Test + public void accessFinalFieldIntArray() throws ScriptException { + e.eval("var pf_int_array = o.publicFinalIntArray;"); + assertEquals(o.publicFinalIntArray[0], e.eval("o.publicFinalIntArray[0];")); + assertArrayEquals(o.publicFinalIntArray, (int[])e.get("pf_int_array")); + e.eval("var tf_int_arr = new (Java.type(\"int[]\"))(3);" + + "tf_int_arr[0] = 4;" + + "tf_int_arr[1] = 5;" + + "tf_int_arr[2] = 6;" + + "o.publicFinalIntArray = tf_int_arr;"); + assertArrayEquals(new int[] { 50, 80, 130, 210, 340 }, o.publicFinalIntArray); + e.eval("o.publicFinalIntArray[0] = 100;"); + assertEquals(100, o.publicFinalIntArray[0]); + } + + @Test + public void accessStaticFinalFieldInt() throws ScriptException { + e.eval("var psf_int = SharedObject.publicStaticFinalInt;"); + assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int")); + e.eval("SharedObject.publicStaticFinalInt = 140;"); + assertEquals(207182023, SharedObject.publicStaticFinalInt); + } + + @Test + public void accessStaticFinalFieldIntArray() throws ScriptException { + e.eval("var psf_int_array = SharedObject.publicStaticFinalIntArray;"); + assertEquals(SharedObject.publicStaticFinalIntArray[0], e.eval("SharedObject.publicStaticFinalIntArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalIntArray, (int[])e.get("psf_int_array")); + e.eval("var tsf_int_arr = new (Java.type(\"int[]\"))(3);" + + "tsf_int_arr[0] = 4;" + + "tsf_int_arr[1] = 5;" + + "tsf_int_arr[2] = 6;" + + "SharedObject.publicStaticFinalIntArray = tsf_int_arr;"); + assertArrayEquals(new int[] { 1308, 210, 340 }, SharedObject.publicStaticFinalIntArray); + e.eval("SharedObject.publicStaticFinalIntArray[0] = 100;"); + assertEquals(100, SharedObject.publicStaticFinalIntArray[0]); + } + + // --------------------------------byte + // tests------------------------------------ + @Test + public void accessFieldByte() throws ScriptException { + e.eval("var p_byte = o.publicByte;"); + assertEquals((double)o.publicByte, ((Number)e.get("p_byte")).doubleValue()); + e.eval("o.publicByte = 16;"); + assertEquals(16, o.publicByte); + } + + @Test + public void accessFieldByteArray() throws ScriptException { + e.eval("var p_byte_array = o.publicByteArray;"); + assertEquals(o.publicByteArray[0], e.eval("o.publicByteArray[0];")); + assertArrayEquals(o.publicByteArray, (byte[])e.get("p_byte_array")); + e.eval("var t_byte_arr = new (Java.type(\"byte[]\"))(3);" + + "t_byte_arr[0] = -18;" + + "t_byte_arr[1] = 56;" + + "t_byte_arr[2] = 60;" + + "o.publicByteArray = t_byte_arr;"); + assertArrayEquals(new byte[] { -18, 56, 60 }, o.publicByteArray); + e.eval("o.publicByteArray[0] = 100;"); + assertEquals(100, o.publicByteArray[0]); + } + + @Test + public void accessStaticFieldByte() throws ScriptException { + e.eval("var ps_byte = SharedObject.publicStaticByte;"); + assertEquals((double)SharedObject.publicStaticByte, ((Number)e.get("ps_byte")).doubleValue()); + e.eval("SharedObject.publicStaticByte = 16;"); + assertEquals(16, SharedObject.publicStaticByte); + } + + @Test + public void accessStaticFieldByteArray() throws ScriptException { + e.eval("var ps_byte_array = SharedObject.publicStaticByteArray;"); + assertEquals(SharedObject.publicStaticByteArray[0], e.eval("SharedObject.publicStaticByteArray[0];")); + assertArrayEquals(SharedObject.publicStaticByteArray, (byte[])e.get("ps_byte_array")); + e.eval("var ts_byte_arr = new (Java.type(\"byte[]\"))(3);" + + "ts_byte_arr[0] = -18;" + + "ts_byte_arr[1] = 56;" + + "ts_byte_arr[2] = 60;" + + "SharedObject.publicStaticByteArray = ts_byte_arr;"); + assertArrayEquals(new byte[] { -18, 56, 60 }, SharedObject.publicStaticByteArray); + e.eval("SharedObject.publicStaticByteArray[0] = -90;"); + assertEquals(-90, SharedObject.publicStaticByteArray[0]); + } + + @Test + public void accessFinalFieldByte() throws ScriptException { + e.eval("var pf_byte = o.publicFinalByte;"); + assertEquals((double)o.publicFinalByte, ((Number)e.get("pf_byte")).doubleValue()); + e.eval("o.publicFinalByte = 16;"); + assertEquals(-7, o.publicFinalByte); + } + + @Test + public void accessFinalFieldByteArray() throws ScriptException { + e.eval("var pf_byte_array = o.publicFinalByteArray;"); + assertEquals(o.publicFinalByteArray[0], e.eval("o.publicFinalByteArray[0];")); + assertArrayEquals(o.publicFinalByteArray, (byte[])e.get("pf_byte_array")); + e.eval("var tf_byte_arr = new (Java.type(\"byte[]\"))(3);" + + "tf_byte_arr[0] = -18;" + + "tf_byte_arr[1] = 56;" + + "tf_byte_arr[2] = 60;" + + "o.publicFinalByteArray = tf_byte_arr;"); + assertArrayEquals(new byte[] { 1, 3, 6, 17, -128 }, o.publicFinalByteArray); + e.eval("o.publicFinalByteArray[0] = -90;"); + assertEquals(-90, o.publicFinalByteArray[0]); + } + + @Test + public void accessStaticFinalFieldByte() throws ScriptException { + e.eval("var psf_byte = SharedObject.publicStaticFinalByte;"); + assertEquals((double)SharedObject.publicStaticFinalByte, ((Number)e.get("psf_byte")).doubleValue()); + e.eval("SharedObject.publicStaticFinalByte = 16;"); + assertEquals(-70, SharedObject.publicStaticFinalByte); + } + + @Test + public void accessStaticFinalFieldByteArray() throws ScriptException { + e.eval("var psf_byte_array = SharedObject.publicStaticFinalByteArray;"); + assertEquals(SharedObject.publicStaticFinalByteArray[0], e.eval("SharedObject.publicStaticFinalByteArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalByteArray, (byte[])e.get("psf_byte_array")); + e.eval("var tsf_byte_arr = new (Java.type(\"byte[]\"))(3);" + + "tsf_byte_arr[0] = -18;" + + "tsf_byte_arr[1] = 56;" + + "tsf_byte_arr[2] = 60;" + + "SharedObject.publicStaticFinalByteArray = tsf_byte_arr;"); + assertArrayEquals(new byte[] { 17, -128, 81 }, SharedObject.publicStaticFinalByteArray); + e.eval("SharedObject.publicStaticFinalByteArray[0] = -90;"); + assertEquals(-90, SharedObject.publicStaticFinalByteArray[0]); + } + + // --------------------------------short + // tests------------------------------------ + @Test + public void accessFieldShort() throws ScriptException { + e.eval("var p_short = o.publicShort;"); + assertEquals((double)o.publicShort, ((Number)e.get("p_short")).doubleValue()); + e.eval("o.publicShort = 18;"); + assertEquals(18, o.publicShort); + } + + @Test + public void accessFieldShortArray() throws ScriptException { + e.eval("var p_short_array = o.publicShortArray;"); + assertEquals(o.publicShortArray[0], e.eval("o.publicShortArray[0];")); + assertArrayEquals(o.publicShortArray, (short[])e.get("p_short_array")); + e.eval("var t_short_arr = new (Java.type(\"short[]\"))(3);" + + "t_short_arr[0] = 90;" + + "t_short_arr[1] = 5;" + + "t_short_arr[2] = -6000;" + + "o.publicShortArray = t_short_arr;"); + assertArrayEquals(new short[] { 90, 5, -6000 }, o.publicShortArray); + e.eval("o.publicShortArray[0] = -1000;"); + assertEquals(-1000, o.publicShortArray[0]); + } + + @Test + public void accessStaticFieldShort() throws ScriptException { + e.eval("var ps_short = SharedObject.publicStaticShort;"); + assertEquals((double)SharedObject.publicStaticShort, ((Number)e.get("ps_short")).doubleValue()); + e.eval("SharedObject.publicStaticShort = 180;"); + assertEquals(180, SharedObject.publicStaticShort); + } + + @Test + public void accessStaticFieldShortArray() throws ScriptException { + e.eval("var ps_short_array = SharedObject.publicStaticShortArray;"); + assertEquals(SharedObject.publicStaticShortArray[0], e.eval("SharedObject.publicStaticShortArray[0];")); + assertArrayEquals(SharedObject.publicStaticShortArray, (short[])e.get("ps_short_array")); + e.eval("var ts_short_arr = new (Java.type(\"short[]\"))(3);" + + "ts_short_arr[0] = 90;" + + "ts_short_arr[1] = 5;" + + "ts_short_arr[2] = -6000;" + + "SharedObject.publicStaticShortArray = ts_short_arr;"); + assertArrayEquals(new short[] { 90, 5, -6000 }, SharedObject.publicStaticShortArray); + e.eval("SharedObject.publicStaticShortArray[0] = -1000;"); + assertEquals(-1000, SharedObject.publicStaticShortArray[0]); + } + + @Test + public void accessFinalFieldShort() throws ScriptException { + e.eval("var pf_short = o.publicFinalShort;"); + assertEquals((double)o.publicFinalShort, ((Number)e.get("pf_short")).doubleValue()); + e.eval("o.publicFinalShort = 180;"); + assertEquals(31220, o.publicFinalShort); + } + + @Test + public void accessFinalFieldShortArray() throws ScriptException { + e.eval("var pf_short_array = o.publicFinalShortArray;"); + assertEquals(o.publicFinalShortArray[0], e.eval("o.publicFinalShortArray[0];")); + assertArrayEquals(o.publicFinalShortArray, (short[])e.get("pf_short_array")); + e.eval("var tf_short_arr = new (Java.type(\"short[]\"))(3);" + + "tf_short_arr[0] = 90;" + + "tf_short_arr[1] = 5;" + + "tf_short_arr[2] = -6000;" + + "o.publicFinalShortArray = tf_short_arr;"); + assertArrayEquals(new short[] { 12240, 9200, -17289, 1200, 12 }, o.publicFinalShortArray); + e.eval("o.publicFinalShortArray[0] = -1000;"); + assertEquals(-1000, o.publicFinalShortArray[0]); + } + + @Test + public void accessStaticFinalFieldShort() throws ScriptException { + e.eval("var psf_short = SharedObject.publicStaticFinalShort;"); + assertEquals((double)SharedObject.publicStaticFinalShort, ((Number)e.get("psf_short")).doubleValue()); + e.eval("SharedObject.publicStaticFinalShort = 180;"); + assertEquals(8888, SharedObject.publicStaticFinalShort); + } + + @Test + public void accessStaticFinalFieldShortArray() throws ScriptException { + e.eval("var psf_short_array = SharedObject.publicStaticFinalShortArray;"); + assertEquals(SharedObject.publicStaticFinalShortArray[0], e.eval("SharedObject.publicStaticFinalShortArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalShortArray, (short[])e.get("psf_short_array")); + e.eval("var tsf_short_arr = new (Java.type(\"short[]\"))(3);" + + "tsf_short_arr[0] = 90;" + + "tsf_short_arr[1] = 5;" + + "tsf_short_arr[2] = -6000;" + + "SharedObject.publicStaticFinalShortArray = tsf_short_arr;"); + assertArrayEquals(new short[] { 8240, 9280, -1289, 120, 812 }, SharedObject.publicStaticFinalShortArray); + e.eval("SharedObject.publicStaticFinalShortArray[0] = -1000;"); + assertEquals(-1000, SharedObject.publicStaticFinalShortArray[0]); + } + + // --------------------------------char + // tests------------------------------------ + @Test + public void accessFieldChar() throws ScriptException { + e.eval("var p_char = o.publicChar;"); + assertEquals(o.publicChar, e.get("p_char")); + e.eval("o.publicChar = 'S';"); + assertEquals('S', o.publicChar); + e.eval("o.publicChar = 10;"); + assertEquals(10, o.publicChar); + e.eval("try {" + + " o.publicChar = 'Big string';" + + "} catch(e) {" + + " var isThrown = true;" + + "}"); + assertEquals("Exception thrown", true, e.get("isThrown")); + assertEquals(10, o.publicChar); + } + + @Test + public void accessFieldCharArray() throws ScriptException { + e.eval("var p_char_array = o.publicCharArray;"); + assertEquals(o.publicCharArray[0], e.eval("o.publicCharArray[0];")); + assertArrayEquals(o.publicCharArray, (char[])e.get("p_char_array")); + e.eval("var t_char_arr = new (Java.type(\"char[]\"))(3);" + + "t_char_arr[0] = 'F';" + + "t_char_arr[1] = 'o';" + + "t_char_arr[2] = 'o';" + + "o.publicCharArray = t_char_arr;"); + assertArrayEquals("Foo".toCharArray(), o.publicCharArray); + e.eval("o.publicCharArray[0] = 'Z';"); + assertEquals('Z', o.publicCharArray[0]); + } + + @Test + public void accessStaticFieldChar() throws ScriptException { + e.eval("var ps_char = SharedObject.publicStaticChar;"); + assertEquals(SharedObject.publicStaticChar, e.get("ps_char")); + e.eval("SharedObject.publicStaticChar = 'Z';"); + assertEquals('Z', SharedObject.publicStaticChar); + } + + @Test + public void accessStaticFieldCharArray() throws ScriptException { + e.eval("var ps_char_array = SharedObject.publicStaticCharArray;"); + assertEquals(SharedObject.publicStaticCharArray[0], e.eval("SharedObject.publicStaticCharArray[0];")); + assertArrayEquals(SharedObject.publicStaticCharArray, (char[])e.get("ps_char_array")); + e.eval("var ts_char_arr = new (Java.type(\"char[]\"))(3);" + + "ts_char_arr[0] = 'G';" + + "ts_char_arr[1] = 'o';" + + "ts_char_arr[2] = 'o';" + + "SharedObject.publicStaticCharArray = ts_char_arr;"); + assertArrayEquals("Goo".toCharArray(), SharedObject.publicStaticCharArray); + e.eval("SharedObject.publicStaticCharArray[0] = 'Z';"); + assertEquals('Z', SharedObject.publicStaticCharArray[0]); + } + + @Test + public void accessFinalFieldChar() throws ScriptException { + e.eval("var pf_char = o.publicFinalChar;"); + assertEquals(o.publicFinalChar, e.get("pf_char")); + e.eval("o.publicFinalChar = 'S';"); + assertEquals('E', o.publicFinalChar); + } + + @Test + public void accessFinalCharArray() throws ScriptException { + e.eval("var pf_char_array = o.publicFinalCharArray;"); + assertEquals(o.publicFinalCharArray[0], e.eval("o.publicFinalCharArray[0];")); + assertArrayEquals(o.publicFinalCharArray, (char[])e.get("pf_char_array")); + e.eval("var tf_char_arr = new (Java.type(\"char[]\"))(3);" + + "tf_char_arr[0] = 'F';" + + "tf_char_arr[1] = 'o';" + + "tf_char_arr[2] = 'o';" + + "o.publicFinalCharArray = tf_char_arr;"); + assertArrayEquals("Nashorn hello".toCharArray(), o.publicFinalCharArray); + e.eval("o.publicFinalCharArray[0] = 'Z';"); + assertEquals('Z', o.publicFinalCharArray[0]); + } + + @Test + public void accessStaticFinalFieldChar() throws ScriptException { + e.eval("var psf_char = SharedObject.publicStaticFinalChar;"); + assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char")); + e.eval("SharedObject.publicStaticFinalChar = 'Z';"); + assertEquals('K', SharedObject.publicStaticFinalChar); + } + + @Test + public void accessStaticFinalFieldCharArray() throws ScriptException { + e.eval("var psf_char_array = SharedObject.publicStaticFinalCharArray;"); + assertEquals(SharedObject.publicStaticFinalCharArray[0], e.eval("SharedObject.publicStaticFinalCharArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalCharArray, (char[])e.get("psf_char_array")); + e.eval("var tsf_char_arr = new (Java.type(\"char[]\"))(3);" + + "tsf_char_arr[0] = 'Z';" + + "tsf_char_arr[1] = 'o';" + + "tsf_char_arr[2] = 'o';" + + "SharedObject.publicStaticFinalCharArray = tsf_char_arr;"); + assertArrayEquals("StaticString".toCharArray(), SharedObject.publicStaticFinalCharArray); + e.eval("SharedObject.publicStaticFinalCharArray[0] = 'Z';"); + assertEquals('Z', SharedObject.publicStaticFinalCharArray[0]); + } + + // --------------------------------float + // tests------------------------------------ + @Test + public void accessFieldFloat() throws ScriptException { + e.eval("var p_float = o.publicFloat;"); + assertEquals((double)o.publicFloat, ((Number)e.get("p_float")).doubleValue()); + o.publicFloat = 0.0f / 0.0f; + assertEquals(true, e.eval("isNaN(o.publicFloat)")); + o.publicFloat = 1.0f / 0.0f; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloat")); + o.publicFloat = -1.0f / 0.0f; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloat")); + e.eval("o.publicFloat = 20;"); + assertEquals(20, o.publicFloat, 1e-10); + e.eval("o.publicFloat = 0.0/0.0;"); + assertTrue(Float.isNaN(o.publicFloat)); + e.eval("o.publicFloat = 1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloat)); + e.eval("o.publicFloat = -1.0/0.0;"); + assertEquals(Float.NEGATIVE_INFINITY, o.publicFloat, 1e-10); + } + + @Test + public void accessFieldFloatArray() throws ScriptException { + e.eval("var p_float_array = o.publicFloatArray;"); + assertEquals(o.publicFloatArray[0], e.eval("o.publicFloatArray[0];")); + assertArrayEquals(o.publicFloatArray, (float[])e.get("p_float_array"), 1e-10f); + e.eval("var t_float_arr = new (Java.type(\"float[]\"))(3);" + + "t_float_arr[0] = 9.0;" + + "t_float_arr[1] = 5.12345;" + + "t_float_arr[2] = -60.03;" + + "o.publicFloatArray = t_float_arr;"); + assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f); + e.eval("o.publicFloatArray[0] = -513.2;"); + assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, o.publicFloatArray, 1e-10f); + } + + @Test + public void accessStaticFieldFloat() throws ScriptException { + e.eval("var ps_float = SharedObject.publicStaticFloat;"); + assertEquals((double)SharedObject.publicStaticFloat, ((Number)e.get("ps_float")).doubleValue()); + SharedObject.publicStaticFloat = 0.0f / 0.0f; + assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)")); + SharedObject.publicStaticFloat = 1.0f / 0.0f; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat")); + SharedObject.publicStaticFloat = -1.0f / 0.0f; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat")); + e.eval("SharedObject.publicStaticFloat = 20.0;"); + assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10); + e.eval("SharedObject.publicStaticFloat = 0.0/0.0;"); + assertTrue(Float.isNaN(SharedObject.publicStaticFloat)); + e.eval("SharedObject.publicStaticFloat = 1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); + e.eval("SharedObject.publicStaticFloat = -1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); + } + + @Test + public void accessStaticFieldFloatArray() throws ScriptException { + e.eval("var ps_float_array = SharedObject.publicStaticFloatArray;"); + assertEquals(SharedObject.publicStaticFloatArray[0], e.eval("SharedObject.publicStaticFloatArray[0];")); + assertArrayEquals(SharedObject.publicStaticFloatArray, (float[])e.get("ps_float_array"), 1e-10f); + e.eval("var ts_float_arr = new (Java.type(\"float[]\"))(3);" + + "ts_float_arr[0] = 9.0;" + + "ts_float_arr[1] = 5.12345;" + + "ts_float_arr[2] = -60.03;" + + "SharedObject.publicStaticFloatArray = ts_float_arr;"); + assertArrayEquals(new float[] { 9.0f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f); + e.eval("SharedObject.publicStaticFloatArray[0] = -513.2;"); + assertArrayEquals(new float[] { -513.2f, 5.12345f, -60.03f }, SharedObject.publicStaticFloatArray, 1e-10f); + } + + @Test + public void accessFinalFloat() throws ScriptException { + e.eval("var pf_float = o.publicFinalFloat;"); + assertEquals((double)o.publicFinalFloat, ((Number)e.get("pf_float")).doubleValue()); + e.eval("o.publicFinalFloat = 20.0;"); + assertEquals(7.72e8f, o.publicFinalFloat, 1e-10); + } + + @Test + public void accessFinalFloatArray() throws ScriptException { + e.eval("var pf_float_array = o.publicFinalFloatArray;"); + assertEquals(o.publicFinalFloatArray[0], e.eval("o.publicFinalFloatArray[0];")); + assertArrayEquals(o.publicFinalFloatArray, (float[])e.get("pf_float_array"), 1e-10f); + e.eval("var tf_float_arr = new (Java.type(\"float[]\"))(3);" + + "tf_float_arr[0] = 9.0;" + + "tf_float_arr[1] = 5.12345;" + + "tf_float_arr[2] = -60.03;" + + "o.publicFinalFloatArray = tf_float_arr;"); + assertArrayEquals(new float[] { -131.012f, 189.32f, -31.32e8f, 3.72f }, o.publicFinalFloatArray, 1e-10f); + e.eval("o.publicFinalFloatArray[0] = -513.2;"); + assertEquals(-513.2f, o.publicFinalFloatArray[0], 1e-10f); + } + + @Test + public void accessStaticFinalFieldFloat() throws ScriptException { + e.eval("var psf_float = SharedObject.publicStaticFinalFloat;"); + assertEquals((double)SharedObject.publicStaticFinalFloat, ((Number)e.get("psf_float")).doubleValue()); + e.eval("SharedObject.publicStaticFinalFloat = 20.0;"); + assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10); + } + + @Test + public void accessStaticFinalFieldFloatArray() throws ScriptException { + e.eval("var psf_float_array = SharedObject.publicStaticFinalFloatArray;"); + assertEquals(SharedObject.publicStaticFinalFloatArray[0], e.eval("SharedObject.publicStaticFinalFloatArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalFloatArray, (float[])e.get("psf_float_array"), 1e-10f); + e.eval("var tsf_float_arr = new (Java.type(\"float[]\"))(3);" + + "tsf_float_arr[0] = 9.0;" + + "tsf_float_arr[1] = 5.12345;" + + "tsf_float_arr[2] = -60.03;" + + "SharedObject.publicStaticFinalFloatArray = tsf_float_arr;"); + assertArrayEquals(new float[] { -8131.012f, 9.32f, -138.32e8f, 0.72f }, SharedObject.publicStaticFinalFloatArray, 1e-10f); + e.eval("SharedObject.publicStaticFinalFloatArray[0] = -513.2;"); + assertEquals(-513.2f, SharedObject.publicStaticFinalFloatArray[0], 1e-10f); + } + + // --------------------------------double + // tests------------------------------------ + @Test + public void accessFieldDouble() throws ScriptException { + e.eval("var p_double = o.publicDouble;"); + assertEquals(o.publicDouble, e.get("p_double")); + o.publicDouble = 0.0 / 0.0; + assertEquals(true, e.eval("isNaN(o.publicDouble)")); + o.publicDouble = 1.0 / 0.0; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDouble")); + o.publicDouble = -1.0 / 0.0; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDouble")); + e.eval("o.publicDouble = 30;"); + assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDouble)); + e.eval("o.publicDouble = 0.0/0.0;"); + assertTrue(Double.isNaN(o.publicDouble)); + e.eval("o.publicDouble = 1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDouble)); + e.eval("o.publicDouble = -1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDouble)); + } + + @Test + public void accessFieldDoubleArrayRead() throws ScriptException { + e.eval("var p_double_array = o.publicDoubleArray;"); + assertEquals(o.publicDoubleArray[0], e.eval("o.publicDoubleArray[0];")); + assertArrayEquals(o.publicDoubleArray, (double[])e.get("p_double_array"), 1e-10); + e.eval("var t_double_arr = new (Java.type(\"double[]\"))(3);" + + "t_double_arr[0] = 9e10;" + + "t_double_arr[1] = 0.677777;" + + "t_double_arr[2] = -0.0000001;" + + "o.publicDoubleArray = t_double_arr;"); + assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, o.publicDoubleArray, 1e-10f); + e.eval("o.publicDoubleArray[0] = -5.2e10;"); + assertEquals(-5.2e10, o.publicDoubleArray[0], 1e-10f); + } + + @Test + public void accessStaticFieldDouble() throws ScriptException { + e.eval("var ps_double = SharedObject.publicStaticDouble;"); + assertEquals(SharedObject.publicStaticDouble, e.get("ps_double")); + SharedObject.publicStaticDouble = 0.0 / 0.0; + assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)")); + SharedObject.publicStaticDouble = 1.0 / 0.0; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble")); + SharedObject.publicStaticDouble = -1.0 / 0.0; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble")); + e.eval("SharedObject.publicStaticDouble = 40.0;"); + assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = 0.0/0.0;"); + assertTrue(Double.isNaN(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = 1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = -1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + } + + @Test + public void accessStaticFieldDoubleArrayRead() throws ScriptException { + e.eval("var ps_double_array = SharedObject.publicStaticDoubleArray;"); + assertEquals(SharedObject.publicStaticDoubleArray[0], e.eval("SharedObject.publicStaticDoubleArray[0];")); + assertArrayEquals(SharedObject.publicStaticDoubleArray, (double[])e.get("ps_double_array"), 1e-10); + e.eval("var ts_double_arr = new (Java.type(\"double[]\"))(3);" + + "ts_double_arr[0] = 9e10;" + + "ts_double_arr[1] = 0.677777;" + + "ts_double_arr[2] = -0.0000001;" + + "SharedObject.publicStaticDoubleArray = ts_double_arr;"); + assertArrayEquals(new double[] { 9e10, 0.677777, -0.0000001 }, SharedObject.publicStaticDoubleArray, 1e-10f); + e.eval("SharedObject.publicStaticDoubleArray[0] = -5.2e10;"); + assertEquals(-5.2e10, SharedObject.publicStaticDoubleArray[0], 1e-10f); + } + + @Test + public void accessFinalFieldDouble() throws ScriptException { + e.eval("var pf_double = o.publicFinalDouble;"); + assertEquals(o.publicFinalDouble, e.get("pf_double")); + e.eval("o.publicFinalDouble = 30.0;"); + assertEquals(Double.doubleToLongBits(1.3412e20), Double.doubleToLongBits(o.publicFinalDouble)); + } + + @Test + public void accessFinalFieldDoubleArrayRead() throws ScriptException { + e.eval("var pf_double_array = o.publicFinalDoubleArray;"); + assertEquals(o.publicFinalDoubleArray[0], e.eval("o.publicFinalDoubleArray[0];")); + assertArrayEquals(o.publicFinalDoubleArray, (double[])e.get("pf_double_array"), 1e-10); + e.eval("var tf_double_arr = new (Java.type(\"double[]\"))(3);" + + "tf_double_arr[0] = 9e10;" + + "tf_double_arr[1] = 0.677777;" + + "tf_double_arr[2] = -0.0000001;" + + "o.publicFinalDoubleArray = tf_double_arr;"); + assertArrayEquals(new double[] { 0.725e80, 0.12e10, 8e-3, 1.00077 }, o.publicFinalDoubleArray, 1e-10f); + e.eval("o.publicFinalDoubleArray[0] = -5.2e10;"); + assertEquals(-5.2e10, o.publicFinalDoubleArray[0], 1e-10f); + } + + @Test + public void accessStaticFinalFieldDouble() throws ScriptException { + e.eval("var psf_double = SharedObject.publicStaticFinalDouble;"); + assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double")); + e.eval("SharedObject.publicStaticFinalDouble = 40.0;"); + assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble)); + } + + @Test + public void accessStaticFinalFieldDoubleArrayRead() throws ScriptException { + e.eval("var psf_double_array = SharedObject.publicStaticFinalDoubleArray;"); + assertEquals(SharedObject.publicStaticFinalDoubleArray[0], e.eval("SharedObject.publicStaticFinalDoubleArray[0];")); + assertArrayEquals(SharedObject.publicStaticFinalDoubleArray, (double[])e.get("psf_double_array"), 1e-10); + e.eval("var tsf_double_arr = new (Java.type(\"double[]\"))(3);" + + "tsf_double_arr[0] = 9e10;" + + "tsf_double_arr[1] = 0.677777;" + + "tsf_double_arr[2] = -0.0000001;" + + "SharedObject.publicStaticFinalDoubleArray = tsf_double_arr;"); + assertArrayEquals(new double[] { 8.725e80, 0.82e10, 18e-3, 1.08077 }, SharedObject.publicStaticFinalDoubleArray, 1e-10f); + e.eval("SharedObject.publicStaticFinalDoubleArray[0] = -5.2e10;"); + assertEquals(-5.2e10, SharedObject.publicStaticFinalDoubleArray[0], 1e-10f); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/NumberBoxingTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,365 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.NumberBoxingTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.NumberBoxingTest + */ +@SuppressWarnings("javadoc") +public class NumberBoxingTest { + + private static ScriptEngine e; + private static SharedObject o; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + // --------------------------------long + // tests------------------------------------ + @Test + public void accessFieldLongBoxing() throws ScriptException { + e.eval("var p_long = o.publicLongBox;"); + assertEquals(o.publicLongBox, e.get("p_long")); + e.eval("o.publicLongBox = 12;"); + assertEquals(Long.valueOf(12), o.publicLongBox); + } + + @Test + public void accessStaticFieldLongBoxing() throws ScriptException { + e.eval("var ps_long = SharedObject.publicStaticLongBox;"); + assertEquals(SharedObject.publicStaticLongBox, e.get("ps_long")); + e.eval("SharedObject.publicStaticLongBox = 120;"); + assertEquals(120L, SharedObject.publicStaticLongBox.longValue()); + } + + @Test + public void accessFinalFieldLongBoxing() throws ScriptException { + e.eval("var pf_long = o.publicFinalLongBox;"); + assertEquals(o.publicFinalLongBox, e.get("pf_long")); + e.eval("o.publicFinalLongBox = 120;"); + assertEquals(Long.valueOf(9377333334L), o.publicFinalLongBox); + } + + @Test + public void accessStaticFinalFieldLongBoxing() throws ScriptException { + e.eval("var psf_long = SharedObject.publicStaticFinalLong;"); + assertEquals(SharedObject.publicStaticFinalLong, e.get("psf_long")); + e.eval("SharedObject.publicStaticFinalLong = 120;"); + assertEquals(8333333333333L, SharedObject.publicStaticFinalLong); + } + + // --------------------------------int + // tests------------------------------------ + @Test + public void accessFieldIntBoxing() throws ScriptException { + e.eval("var p_int = o.publicIntBox;"); + assertEquals(o.publicIntBox, e.get("p_int")); + e.eval("o.publicIntBox = 14;"); + assertEquals(Integer.valueOf(14), o.publicIntBox); + } + + @Test + public void accessStaticFieldIntBoxing() throws ScriptException { + e.eval("var ps_int = SharedObject.publicStaticInt;"); + assertEquals(SharedObject.publicStaticInt, e.get("ps_int")); + e.eval("SharedObject.publicStaticInt = 140;"); + assertEquals(140, SharedObject.publicStaticInt); + } + + @Test + public void accessFinalFieldIntBoxing() throws ScriptException { + e.eval("var pf_int = o.publicFinalIntBox;"); + assertEquals(o.publicFinalIntBox, e.get("pf_int")); + e.eval("o.publicFinalIntBox = 10;"); + assertEquals(Integer.valueOf(207512301), o.publicFinalIntBox); + } + + @Test + public void accessStaticFinalFieldIntBoxing() throws ScriptException { + e.eval("var psf_int = SharedObject.publicStaticFinalInt;"); + assertEquals(SharedObject.publicStaticFinalInt, e.get("psf_int")); + e.eval("SharedObject.publicStaticFinalInt = 140;"); + assertEquals(207182023, SharedObject.publicStaticFinalInt); + } + + // --------------------------------byte + // tests------------------------------------ + @Test + public void accessFieldByteBoxing() throws ScriptException { + e.eval("var p_byte = o.publicByteBox;"); + assertEqualsDouble(o.publicByteBox, "p_byte"); + e.eval("o.publicByteBox = 16;"); + assertEquals(Byte.valueOf((byte)16), o.publicByteBox); + } + + @Test + public void accessStaticFieldByteBoxing() throws ScriptException { + e.eval("var ps_byte = SharedObject.publicStaticByte;"); + assertEqualsDouble(SharedObject.publicStaticByte, "ps_byte"); + e.eval("SharedObject.publicStaticByte = 16;"); + assertEquals(16, SharedObject.publicStaticByte); + } + + @Test + public void accessFinalFieldByteBoxing() throws ScriptException { + e.eval("var pf_byte = o.publicFinalByteBox;"); + assertEqualsDouble(o.publicFinalByteBox, "pf_byte"); + e.eval("o.publicFinalByteBox = 16;"); + assertEquals(Byte.valueOf((byte)19), o.publicFinalByteBox); + } + + @Test + public void accessStaticFinalFieldByteBoxing() throws ScriptException { + e.eval("var psf_byte = SharedObject.publicStaticFinalByte;"); + assertEqualsDouble(SharedObject.publicStaticFinalByte, "psf_byte"); + e.eval("SharedObject.publicStaticFinalByte = 16;"); + assertEquals(-70, SharedObject.publicStaticFinalByte); + } + + // --------------------------------short + // tests------------------------------------ + @Test + public void accessFieldShortBoxing() throws ScriptException { + e.eval("var p_short = o.publicShortBox;"); + assertEqualsDouble(o.publicShortBox, "p_short"); + e.eval("o.publicShortBox = 18;"); + assertEquals(Short.valueOf((short)18), o.publicShortBox); + } + + private static void assertEqualsDouble(final Number n, final String name) { + assertEquals(n.doubleValue(), ((Number)e.get(name)).doubleValue()); + } + + @Test + public void accessStaticFieldShortBoxing() throws ScriptException { + e.eval("var ps_short = SharedObject.publicStaticShort;"); + assertEqualsDouble(SharedObject.publicStaticShort, "ps_short"); + e.eval("SharedObject.publicStaticShort = 180;"); + assertEquals(180, SharedObject.publicStaticShort); + } + + @Test + public void accessFinalFieldShortBoxing() throws ScriptException { + e.eval("var pf_short = o.publicFinalShortBox;"); + assertEqualsDouble(o.publicFinalShortBox, "pf_short"); + e.eval("o.publicFinalShortBox = 180;"); + assertEquals(Short.valueOf((short)-26777), o.publicFinalShortBox); + } + + @Test + public void accessStaticFinalFieldShortBoxing() throws ScriptException { + e.eval("var psf_short = SharedObject.publicStaticFinalShort;"); + assertEqualsDouble(SharedObject.publicStaticFinalShort, "psf_short"); + e.eval("SharedObject.publicStaticFinalShort = 180;"); + assertEquals(8888, SharedObject.publicStaticFinalShort); + } + + // --------------------------------char + // tests------------------------------------ + @Test + public void accessFieldCharBoxing() throws ScriptException { + e.eval("var p_char = o.publicCharBox;"); + assertEquals(o.publicCharBox, e.get("p_char")); + e.eval("o.publicCharBox = 'S';"); + assertEquals(Character.valueOf('S'), o.publicCharBox); + e.eval("try {" + + " o.publicCharBox = 'Big string';" + + "} catch(e) {" + + " var isThrown = true;" + + "}"); + assertEquals("Exception thrown", true, e.get("isThrown")); + assertEquals(Character.valueOf('S'), o.publicCharBox); + } + + @Test + public void accessStaticFieldCharBoxing() throws ScriptException { + e.eval("var ps_char = SharedObject.publicStaticChar;"); + assertEquals(SharedObject.publicStaticChar, e.get("ps_char")); + e.eval("SharedObject.publicStaticChar = 'Z';"); + assertEquals('Z', SharedObject.publicStaticChar); + } + + @Test + public void accessFinalFieldCharBoxing() throws ScriptException { + e.eval("var pf_char = o.publicFinalCharBox;"); + assertEquals(o.publicFinalCharBox, e.get("pf_char")); + e.eval("o.publicFinalCharBox = 'S';"); + assertEquals(Character.valueOf('F'), o.publicFinalCharBox); + } + + @Test + public void accessStaticFinalFieldCharBoxing() throws ScriptException { + e.eval("var psf_char = SharedObject.publicStaticFinalChar;"); + assertEquals(SharedObject.publicStaticFinalChar, e.get("psf_char")); + e.eval("SharedObject.publicStaticFinalChar = 'Z';"); + assertEquals('K', SharedObject.publicStaticFinalChar); + } + + // --------------------------------float + // tests------------------------------------ + @Test + public void accessFieldFloatBoxing() throws ScriptException { + e.eval("var p_float = o.publicFloatBox;"); + assertEqualsDouble(o.publicFloatBox, "p_float"); + o.publicFloatBox = 0.0f / 0.0f; + assertEquals(true, e.eval("isNaN(o.publicFloatBox)")); + o.publicFloatBox = 1.0f / 0.0f; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicFloatBox")); + o.publicFloatBox = -1.0f / 0.0f; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicFloatBox")); + e.eval("o.publicFloatBox = 20;"); + assertEquals(20, o.publicFloatBox, 1e-10); + e.eval("o.publicFloatBox = 0.0/0.0;"); + assertTrue(Float.isNaN(o.publicFloatBox)); + e.eval("o.publicFloatBox = 1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(o.publicFloatBox)); + e.eval("o.publicFloatBox = -1.0/0.0;"); + assertEquals(Float.NEGATIVE_INFINITY, o.publicFloatBox, 1e-10); + } + + @Test + public void accessStaticFieldFloatBoxing() throws ScriptException { + e.eval("var ps_float = SharedObject.publicStaticFloat;"); + assertEqualsDouble(SharedObject.publicStaticFloat, "ps_float"); + SharedObject.publicStaticFloat = 0.0f / 0.0f; + assertEquals(true, e.eval("isNaN(SharedObject.publicStaticFloat)")); + SharedObject.publicStaticFloat = 1.0f / 0.0f; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticFloat")); + SharedObject.publicStaticFloat = -1.0f / 0.0f; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticFloat")); + e.eval("SharedObject.publicStaticFloat = 20.0;"); + assertEquals(20.0f, SharedObject.publicStaticFloat, 1e-10); + e.eval("SharedObject.publicStaticFloat = 0.0/0.0;"); + assertTrue(Float.isNaN(SharedObject.publicStaticFloat)); + e.eval("SharedObject.publicStaticFloat = 1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.POSITIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); + e.eval("SharedObject.publicStaticFloat = -1.0/0.0;"); + assertEquals(Float.floatToIntBits(Float.NEGATIVE_INFINITY), Float.floatToIntBits(SharedObject.publicStaticFloat)); + } + + @Test + public void accessFinalFloatBoxing() throws ScriptException { + e.eval("var pf_float = o.publicFinalFloatBox;"); + assertEqualsDouble(o.publicFinalFloatBox, "pf_float"); + e.eval("o.publicFinalFloatBox = 20.0;"); + assertEquals(1.372e4f, o.publicFinalFloatBox, 1e-10); + } + + @Test + public void accessStaticFinalFieldFloatBoxing() throws ScriptException { + e.eval("var psf_float = SharedObject.publicStaticFinalFloat;"); + assertEqualsDouble(SharedObject.publicStaticFinalFloat, "psf_float"); + e.eval("SharedObject.publicStaticFinalFloat = 20.0;"); + assertEquals(0.72e8f, SharedObject.publicStaticFinalFloat, 1e-10); + } + + // --------------------------------double + // tests------------------------------------ + @Test + public void accessFieldDoubleBoxing() throws ScriptException { + e.eval("var p_double = o.publicDoubleBox;"); + assertEquals(o.publicDoubleBox, e.get("p_double")); + o.publicDoubleBox = 0.0 / 0.0; + assertEquals(true, e.eval("isNaN(o.publicDoubleBox)")); + o.publicDoubleBox = 1.0 / 0.0; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === o.publicDoubleBox")); + o.publicDoubleBox = -1.0 / 0.0; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === o.publicDoubleBox")); + e.eval("o.publicDoubleBox = 30;"); + assertEquals(Double.doubleToLongBits(30.0), Double.doubleToLongBits(o.publicDoubleBox)); + e.eval("o.publicDoubleBox = 0.0/0.0;"); + assertTrue(Double.isNaN(o.publicDoubleBox)); + e.eval("o.publicDoubleBox = 1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox)); + e.eval("o.publicDoubleBox = -1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(o.publicDoubleBox)); + } + + @Test + public void accessStaticFieldDoubleBoxing() throws ScriptException { + e.eval("var ps_double = SharedObject.publicStaticDouble;"); + assertEquals(SharedObject.publicStaticDouble, e.get("ps_double")); + SharedObject.publicStaticDouble = 0.0 / 0.0; + assertEquals(true, e.eval("isNaN(SharedObject.publicStaticDouble)")); + SharedObject.publicStaticDouble = 1.0 / 0.0; + assertEquals(true, e.eval("Number.POSITIVE_INFINITY === SharedObject.publicStaticDouble")); + SharedObject.publicStaticDouble = -1.0 / 0.0; + assertEquals(true, e.eval("Number.NEGATIVE_INFINITY === SharedObject.publicStaticDouble")); + e.eval("SharedObject.publicStaticDouble = 40.0;"); + assertEquals(Double.doubleToLongBits(40.0), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = 0.0/0.0;"); + assertTrue(Double.isNaN(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = 1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.POSITIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + e.eval("SharedObject.publicStaticDouble = -1.0/0.0;"); + assertEquals(Double.doubleToLongBits(Double.NEGATIVE_INFINITY), Double.doubleToLongBits(SharedObject.publicStaticDouble)); + } + + @Test + public void accessFinalFieldDoubleBoxing() throws ScriptException { + e.eval("var pf_double = o.publicFinalDoubleBox;"); + assertEquals(o.publicFinalDoubleBox, e.get("pf_double")); + e.eval("o.publicFinalDoubleBox = 30.0;"); + assertEquals(Double.doubleToLongBits(1.412e-12), Double.doubleToLongBits(o.publicFinalDoubleBox)); + } + + @Test + public void accessStaticFinalFieldDoubleBoxing() throws ScriptException { + e.eval("var psf_double = SharedObject.publicStaticFinalDouble;"); + assertEquals(SharedObject.publicStaticFinalDouble, e.get("psf_double")); + e.eval("SharedObject.publicStaticFinalDouble = 40.0;"); + assertEquals(Double.doubleToLongBits(1.8e12), Double.doubleToLongBits(SharedObject.publicStaticFinalDouble)); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/ObjectAccessTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.ObjectAccessTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.ObjectAccessTest + */ +@SuppressWarnings("javadoc") +public class ObjectAccessTest { + + private static ScriptEngine e = null; + private static SharedObject o = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + e.eval("var Person = Packages.jdk.nashorn.api.javaaccess.test.Person;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + @Test + public void accessFieldObject() throws ScriptException { + e.eval("var p_object = o.publicObject;"); + assertEquals(o.publicObject, e.get("p_object")); + assertEquals("object", e.eval("typeof p_object;")); + e.eval("o.publicObject = new Person(14);"); + assertEquals(new Person(14), o.publicObject); + } + + @Test + public void accessFieldObjectArray() throws ScriptException { + e.eval("var p_object_array = o.publicObjectArray;"); + assertEquals(o.publicObjectArray[0], e.eval("o.publicObjectArray[0]")); + assertArrayEquals(o.publicObjectArray, (Object[])e.get("p_object_array")); + e.eval("var t_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.test.Person[]\"))(3);" + + "t_object_arr[0] = new Person(100);" + + "t_object_arr[1] = new Person(120);" + + "t_object_arr[2] = new Person(140);" + + "o.publicObjectArray = t_object_arr;"); + assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, o.publicObjectArray); + e.eval("o.publicObjectArray[0] = new Person(10);"); + assertEquals(new Person(10), o.publicObjectArray[0]); + } + + @Test + public void accessStaticFieldObject() throws ScriptException { + e.eval("var ps_object = SharedObject.publicStaticObject;"); + assertEquals(SharedObject.publicStaticObject, e.get("ps_object")); + assertEquals("object", e.eval("typeof ps_object;")); + e.eval("SharedObject.publicStaticObject = new Person(16);"); + assertEquals(new Person(16), SharedObject.publicStaticObject); + } + + @Test + public void accessStaticFieldObjectArray() throws ScriptException { + e.eval("var ps_object_array = SharedObject.publicStaticObjectArray;"); + assertEquals(SharedObject.publicStaticObjectArray[0], e.eval("SharedObject.publicStaticObjectArray[0]")); + assertArrayEquals(SharedObject.publicStaticObjectArray, (Object[])e.get("ps_object_array")); + e.eval("var ts_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.test.Person[]\"))(3);" + + "ts_object_arr[0] = new Person(100);" + + "ts_object_arr[1] = new Person(120);" + + "ts_object_arr[2] = new Person(140);" + + "SharedObject.publicStaticObjectArray = ts_object_arr;"); + assertArrayEquals(new Person[] { new Person(100), new Person(120), new Person(140) }, SharedObject.publicStaticObjectArray); + e.eval("SharedObject.publicStaticObjectArray[0] = new Person(10);"); + assertEquals(new Person(10), SharedObject.publicStaticObjectArray[0]); + } + + @Test + public void accessFinalFieldObject() throws ScriptException { + e.eval("var pf_object = o.publicFinalObject;"); + assertEquals(o.publicFinalObject, e.get("pf_object")); + assertEquals("object", e.eval("typeof pf_object;")); + e.eval("o.publicFinalObject = new Person(-999);"); + assertEquals(new Person(1024), o.publicFinalObject); + } + + @Test + public void accessFinalFieldObjectArray() throws ScriptException { + e.eval("var pf_object_array = o.publicFinalObjectArray;"); + assertEquals(o.publicFinalObjectArray[0], e.eval("o.publicFinalObjectArray[0]")); + assertArrayEquals(o.publicFinalObjectArray, (Object[])e.get("pf_object_array")); + e.eval("var tf_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.test.Person[]\"))(3);" + + "tf_object_arr[0] = new Person(100);" + + "tf_object_arr[1] = new Person(120);" + + "tf_object_arr[2] = new Person(140);" + + "o.publicOFinalbjectArray = tf_object_arr;"); + assertArrayEquals(new Person[] { new Person(-900), new Person(1000), new Person(180) }, o.publicFinalObjectArray); + e.eval("o.publicFinalObjectArray[0] = new Person(10);"); + assertEquals(new Person(10), o.publicFinalObjectArray[0]); + } + + @Test + public void accessStaticFinalFieldObject() throws ScriptException { + e.eval("var psf_object = SharedObject.publicStaticFinalObject;"); + assertEquals(SharedObject.publicStaticFinalObject, e.get("psf_object")); + assertEquals("object", e.eval("typeof psf_object;")); + e.eval("SharedObject.publicStaticFinalObject = new Person(6);"); + assertEquals(new Person(2048), SharedObject.publicStaticFinalObject); + } + + @Test + public void accessStaticFinalFieldObjectArray() throws ScriptException { + e.eval("var psf_object_array = SharedObject.publicStaticFinalObjectArray;"); + assertEquals(SharedObject.publicStaticFinalObjectArray[0], e.eval("SharedObject.publicStaticFinalObjectArray[0]")); + assertArrayEquals(SharedObject.publicStaticFinalObjectArray, (Object[])e.get("psf_object_array")); + e.eval("var tsf_object_arr = new (Java.type(\"jdk.nashorn.api.javaaccess.test.Person[]\"))(3);" + + "tsf_object_arr[0] = new Person(100);" + + "tsf_object_arr[1] = new Person(120);" + + "tsf_object_arr[2] = new Person(140);" + + "SharedObject.publicStaticFinalObjectArray = tsf_object_arr;"); + assertArrayEquals(new Person[] { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) }, SharedObject.publicStaticFinalObjectArray); + e.eval("SharedObject.publicStaticFinalObjectArray[0] = new Person(90);"); + assertEquals(new Person(90), SharedObject.publicStaticFinalObjectArray[0]); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/Person.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +@SuppressWarnings("javadoc") +public class Person { + + public int id = 0; + + public Person() { + } + + public Person(final int code) { + this.id = code; + } + + @Override + public boolean equals(final Object obj) { + if (obj != null && obj instanceof Person) { + final Person o = (Person)obj; + return this.id == o.id; + } + return false; + } + + @Override + public int hashCode() { + return id; + } + + @Override + public String toString() { + return "Person(" + id + ")"; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/SharedObject.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,467 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import javax.script.Invocable; +import javax.script.ScriptEngine; +import javax.script.ScriptException; + +@SuppressWarnings("javadoc") +public class SharedObject { + + // Public fields + public String publicString = "PublicString"; + public String[] publicStringArray = { "ArrayString[0]", "ArrayString[1]", "ArrayString[2]", "ArrayString[3]" }; + public Person publicObject = new Person(256); + public Person[] publicObjectArray = { new Person(4), new Person(-422), new Person(14) }; + public boolean publicBoolean = true; + public boolean[] publicBooleanArray = { true, false, false, true }; + public Boolean publicBooleanBox = true; + public long publicLong = 933333333333333333L; + public long[] publicLongArray = { 99012333333333L, -124355555L, 89777777777L }; + public Long publicLongBox = 9333333333L; + public int publicInt = 2076543123; + public int[] publicIntArray = { 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 }; + public Integer publicIntBox = 20765123; + public byte publicByte = -128; + public byte[] publicByteArray = { 1, 2, 4, 8, 16, 32, 64, 127, -128 }; + public Byte publicByteBox = 127; + public short publicShort = 32000; + public short[] publicShortArray = { 3240, 8900, -16789, 1, 12 }; + public Short publicShortBox = Short.MIN_VALUE; + public float publicFloat = 0.7f; + public float[] publicFloatArray = { -32.01f, 89.3f, -1.3e8f, 3.1f }; + public Float publicFloatBox = 1.377e4f; + public double publicDouble = 1.34e20; + public double[] publicDoubleArray = { 0.75e80, 8e-43, 1.000077, 0.123e10 }; + public Double publicDoubleBox = 1.4e-19; + public char publicChar = 'A'; + public char[] publicCharArray = "Hello Nashorn".toCharArray(); + public Character publicCharBox = 'B'; + // Public static fields + public static String publicStaticString = "PublicStaticString"; + public static String[] publicStaticStringArray = { "StaticArrayString[0]", "StaticArrayString[1]", "StaticArrayString[2]", "StaticArrayString[3]" }; + public static Person publicStaticObject = new Person(512); + public static Person[] publicStaticObjectArray = { new Person(40), new Person(-22), new Person(18) }; + public static boolean publicStaticBoolean = true; + public static boolean[] publicStaticBooleanArray = { false, false, false, true }; + public static Boolean publicStaticBooleanBox = true; + public static long publicStaticLong = 13333333333333333L; + public static long[] publicStaticLongArray = { 19012333333333L, -224355555L, 39777777777L }; + public static Long publicStaticLongBox = 9333333334L; + public static int publicStaticInt = 207654323; + public static int[] publicStaticIntArray = { 5, 8, 13, 21, 34 }; + public static Integer publicStaticIntBox = 2075123; + public static byte publicStaticByte = -12; + public static byte[] publicStaticByteArray = { 16, 32, 64, 127, -128 }; + public static Byte publicStaticByteBox = 17; + public static short publicStaticShort = 320; + public static short[] publicStaticShortArray = { 1240, 900, -1789, 100, 12 }; + public static Short publicStaticShortBox = -16777; + public static float publicStaticFloat = 7.7e8f; + public static float[] publicStaticFloatArray = { -131.01f, 189.3f, -31.3e8f, 3.7f }; + public static Float publicStaticFloatBox = 1.37e4f; + public static double publicStaticDouble = 1.341e20; + public static double[] publicStaticDoubleArray = { 0.75e80, 0.123e10, 8e-43, 1.000077 }; + public static Double publicStaticDoubleBox = 1.41e-12; + public static char publicStaticChar = 'C'; + public static char[] publicStaticCharArray = "Nashorn".toCharArray(); + public static Character publicStaticCharBox = 'D'; + // Public final fields + public final String publicFinalString = "PublicFinalString"; + public final String[] publicFinalStringArray = { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" }; + public final Person publicFinalObject = new Person(1024); + public final Person[] publicFinalObjectArray = { new Person(-900), new Person(1000), new Person(180) }; + public final boolean publicFinalBoolean = true; + public final boolean[] publicFinalBooleanArray = { false, false, true, false }; + public final Boolean publicFinalBooleanBox = true; + public final long publicFinalLong = 13353333333333333L; + public final long[] publicFinalLongArray = { 1901733333333L, -2247355555L, 3977377777L }; + public final Long publicFinalLongBox = 9377333334L; + public final int publicFinalInt = 20712023; + public final int[] publicFinalIntArray = { 50, 80, 130, 210, 340 }; + public final Integer publicFinalIntBox = 207512301; + public final byte publicFinalByte = -7; + public final byte[] publicFinalByteArray = { 1, 3, 6, 17, -128 }; + public final Byte publicFinalByteBox = 19; + public final short publicFinalShort = 31220; + public final short[] publicFinalShortArray = { 12240, 9200, -17289, 1200, 12 }; + public final Short publicFinalShortBox = -26777; + public final float publicFinalFloat = 7.72e8f; + public final float[] publicFinalFloatArray = { -131.012f, 189.32f, -31.32e8f, 3.72f }; + public final Float publicFinalFloatBox = 1.372e4f; + public final double publicFinalDouble = 1.3412e20; + public final double[] publicFinalDoubleArray = { 0.725e80, 0.12e10, 8e-3, 1.00077 }; + public final Double publicFinalDoubleBox = 1.412e-12; + public final char publicFinalChar = 'E'; + public final char[] publicFinalCharArray = "Nashorn hello".toCharArray(); + public final Character publicFinalCharBox = 'F'; + // Public static final fields + public static final String publicStaticFinalString = "PublicStaticFinalString"; + public static final String[] publicStaticFinalStringArray = { "StaticFinalArrayString[0]", "StaticFinalArrayString[1]", "StaticFinalArrayString[2]", "StaticFinalArrayString[3]" }; + public static final Person publicStaticFinalObject = new Person(2048); + public static final Person[] publicStaticFinalObjectArray = { new Person(-9), new Person(110), new Person(Integer.MAX_VALUE) }; + public static final boolean publicStaticFinalBoolean = true; + public static final boolean[] publicStaticFinalBooleanArray = { false, true, false, false }; + public static final Boolean publicStaticFinalBooleanBox = true; + public static final long publicStaticFinalLong = 8333333333333L; + public static final long[] publicStaticFinalLongArray = { 19017383333L, -2247358L, 39773787L }; + public static final Long publicStaticFinalLongBox = 9377388334L; + public static final int publicStaticFinalInt = 207182023; + public static final int[] publicStaticFinalIntArray = { 1308, 210, 340 }; + public static final Integer publicStaticFinalIntBox = 2078301; + public static final byte publicStaticFinalByte = -70; + public static final byte[] publicStaticFinalByteArray = { 17, -128, 81 }; + public static final Byte publicStaticFinalByteBox = 91; + public static final short publicStaticFinalShort = 8888; + public static final short[] publicStaticFinalShortArray = { 8240, 9280, -1289, 120, 812 }; + public static final Short publicStaticFinalShortBox = -26; + public static final float publicStaticFinalFloat = 0.72e8f; + public static final float[] publicStaticFinalFloatArray = { -8131.012f, 9.32f, -138.32e8f, 0.72f }; + public static final Float publicStaticFinalFloatBox = 1.2e4f; + public static final double publicStaticFinalDouble = 1.8e12; + public static final double[] publicStaticFinalDoubleArray = { 8.725e80, 0.82e10, 18e-3, 1.08077 }; + public static final Double publicStaticFinalDoubleBox = 1.5612e-13; + public static final char publicStaticFinalChar = 'K'; + public static final char[] publicStaticFinalCharArray = "StaticString".toCharArray(); + public static final Character publicStaticFinalCharBox = 'L'; + + // Special vars + public volatile boolean volatileBoolean = true; + public transient boolean transientBoolean = true; + + // For methods testing + public boolean isAccessed = false; + public volatile boolean isFinished = false; + + private ScriptEngine engine; + + public ScriptEngine getEngine() { + return engine; + } + + public void setEngine(final ScriptEngine engine) { + this.engine = engine; + } + + public void voidMethod() { + isAccessed = true; + } + + public boolean booleanMethod(final boolean arg) { + return !arg; + } + + public Boolean booleanBoxingMethod(final Boolean arg) { + return !arg.booleanValue(); + } + + public boolean[] booleanArrayMethod(final boolean arg[]) { + final boolean[] res = new boolean[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = !arg[i]; + } + return res; + } + + public int intMethod(final int arg) { + return arg + arg; + } + + public Integer intBoxingMethod(final Integer arg) { + return arg + arg; + } + + public int[] intArrayMethod(final int arg[]) { + final int[] res = new int[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = arg[i] * 2; + } + return res; + } + + public long longMethod(final long arg) { + return arg + arg; + } + + public Long longBoxingMethod(final Long arg) { + return arg + arg; + } + + public long[] longArrayMethod(final long[] arg) { + final long[] res = new long[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = arg[i] * 2; + } + return res; + } + + public byte byteMethod(final byte arg) { + return (byte)(arg + arg); + } + + public Byte byteBoxingMethod(final Byte arg) { + return (byte)(arg + arg); + } + + public byte[] byteArrayMethod(final byte[] arg) { + final byte[] res = new byte[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = (byte)(arg[i] * 2); + } + return res; + } + + public char charMethod(final char arg) { + return Character.toUpperCase(arg); + } + + public Character charBoxingMethod(final Character arg) { + return Character.toUpperCase(arg); + } + + public char[] charArrayMethod(final char[] arg) { + final char[] res = new char[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = Character.toUpperCase(arg[i]); + } + return res; + } + + public short shortMethod(final short arg) { + return (short)(arg + arg); + } + + public Short shortBoxingMethod(final Short arg) { + return (short)(arg + arg); + } + + public short[] shortArrayMethod(final short[] arg) { + final short[] res = new short[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = (short)(arg[i] * 2); + } + return res; + } + + public float floatMethod(final float arg) { + return arg + arg; + } + + public Float floatBoxingMethod(final Float arg) { + return arg + arg; + } + + public float[] floatArrayMethod(final float[] arg) { + final float[] res = new float[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = arg[i] * 2; + } + return res; + } + + public double doubleMethod(final double arg) { + return arg + arg; + } + + public Double doubleBoxingMethod(final Double arg) { + return arg + arg; + } + + public double[] doubleArrayMethod(final double[] arg) { + final double[] res = new double[arg.length]; + for (int i = 0; i < arg.length; i++) { + res[i] = arg[i] * 2; + } + return res; + } + + public String stringMethod(final String str) { + return str + str; + } + + public String[] stringArrayMethod(final String[] arr) { + final int l = arr.length; + final String[] res = new String[l]; + for (int i = 0; i < l; i++) { + res[i] = arr[l - i - 1]; + } + return res; + } + + public Person[] objectArrayMethod(final Person[] arr) { + final Person[] res = new Person[arr.length]; + for (int i = 0; i < arr.length; i++) { + res[i] = new Person(i + 100); + } + return res; + } + + public Person objectMethod(final Person t) { + t.id *= 2; + return t; + } + + public int twoParamMethod(final long l, final double d) { + return (int)(l + d); + } + + public int threeParamMethod(final short s, final long l, final char c) { + return (int)(s + l + c); + } + + public Person[] twoObjectParamMethod(final Person arg1, final Person arg2) { + return new Person[] { arg2, arg1 }; + } + + public Person[] threeObjectParamMethod(final Person arg1, final Person arg2, final Person arg3) { + return new Person[] { arg3, arg2, arg1 }; + } + + public Person[] eightObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8) { + return new Person[] { arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 }; + } + + public Person[] nineObjectParamMethod(final Person arg1, final Person arg2, final Person arg3, final Person arg4, final Person arg5, final Person arg6, final Person arg7, final Person arg8, final Person arg9) { + return new Person[] { arg9, arg8, arg7, arg6, arg5, arg4, arg3, arg2, arg1 }; + } + + public Person[] methodObjectEllipsis(final Person... args) { + final int l = args.length; + final Person[] res = new Person[l]; + for (int i = 0; i < l; i++) { + res[i] = args[l - i - 1]; + } + return res; + } + + public Person[] methodPrimitiveEllipsis(final int... args) { + final int l = args.length; + final Person[] res = new Person[l]; + for (int i = 0; i < l; i++) { + res[i] = new Person(args[i]); + } + return res; + } + + public Object[] methodMixedEllipsis(final Object... args) { + return args; + } + + public Object[] methodObjectWithEllipsis(final String arg, final int... args) { + final Object[] res = new Object[args.length + 1]; + res[0] = arg; + for (int i = 0; i < args.length; i++) { + res[i + 1] = args[i]; + } + return res; + } + + public Object[] methodPrimitiveWithEllipsis(final int arg, final long... args) { + final Object[] res = new Object[args.length + 1]; + res[0] = arg; + for (int i = 0; i < args.length; i++) { + res[i + 1] = args[i]; + } + return res; + } + + public Object[] methodMixedWithEllipsis(final String arg1, final int arg2, final Object... args) { + final Object[] res = new Object[args.length + 2]; + res[0] = arg1; + res[1] = arg2; + System.arraycopy(args, 0, res, 2, args.length); + return res; + } + + public void methodStartsThread() { + isFinished = false; + + final Thread t = new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(1000); + isFinished = true; + } catch (final InterruptedException e) { + e.printStackTrace(); + } + } + }); + + t.start(); + } + + public String overloadedMethodDoubleVSint(final int arg) { + return "int"; + } + + public String overloadedMethodDoubleVSint(final double arg) { + return "double"; + } + + public int overloadedMethod(final int arg) { + return arg*2; + } + + public int overloadedMethod(final String arg) { + return arg.length(); + } + + public int overloadedMethod(final boolean arg) { + return (arg) ? 1 : 0; + } + + public int overloadedMethod(final Person arg) { + return arg.id*2; + } + + public int firstLevelMethodInt(final int arg) throws ScriptException, NoSuchMethodException { + return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInt", arg); + } + + public int thirdLevelMethodInt(final int arg) { + return arg*5; + } + + public int firstLevelMethodInteger(final Integer arg) throws ScriptException, NoSuchMethodException { + return (int) ((Invocable)engine).invokeFunction("secondLevelMethodInteger", arg); + } + + public int thirdLevelMethodInteger(final Integer arg) { + return arg*10; + } + + public Person firstLevelMethodObject(final Person p) throws ScriptException, NoSuchMethodException { + return (Person) ((Invocable)engine).invokeFunction("secondLevelMethodObject", p); + } + + public Person thirdLevelMethodObject(final Person p) { + p.id *= 10; + return p; + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/javaaccess/test/StringAccessTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,168 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.javaaccess.test; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.TestNG; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * @test + * @build jdk.nashorn.api.javaaccess.test.SharedObject jdk.nashorn.api.javaaccess.test.Person jdk.nashorn.api.javaaccess.test.StringAccessTest + * @run testng/othervm jdk.nashorn.api.javaaccess.test.StringAccessTest + */ +@SuppressWarnings("javadoc") +public class StringAccessTest { + + private static ScriptEngine e = null; + private static SharedObject o = null; + + public static void main(final String[] args) { + TestNG.main(args); + } + + @BeforeClass + public static void setUpClass() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + e = m.getEngineByName("nashorn"); + o = new SharedObject(); + e.put("o", o); + e.eval("var SharedObject = Packages.jdk.nashorn.api.javaaccess.test.SharedObject;"); + } + + @AfterClass + public static void tearDownClass() { + e = null; + o = null; + } + + @Test + public void accessFieldString() throws ScriptException { + e.eval("var p_string = o.publicString;"); + assertEquals(o.publicString, e.get("p_string")); + assertEquals("string", e.eval("typeof p_string;")); + e.eval("o.publicString = 'changedString';"); + assertEquals("changedString", o.publicString); + } + + @Test + public void accessFieldStringArray() throws ScriptException { + e.eval("var p_string_array = o.publicStringArray;"); + assertEquals(o.publicStringArray[0], e.eval("o.publicStringArray[0]")); + assertArrayEquals(o.publicStringArray, (String[])e.get("p_string_array")); + e.eval("var t_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + + "t_string_arr[0] = 'abc';" + + "t_string_arr[1] = '123';" + + "t_string_arr[2] = 'xyzzzz';" + + "o.publicStringArray = t_string_arr;"); + assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, o.publicStringArray); + e.eval("o.publicStringArray[0] = 'nashorn';"); + assertEquals("nashorn", o.publicStringArray[0]); + } + + @Test + public void accessStaticFieldString() throws ScriptException { + e.eval("var ps_string = SharedObject.publicStaticString;"); + assertEquals(SharedObject.publicStaticString, e.get("ps_string")); + assertEquals("string", e.eval("typeof ps_string;")); + e.eval("SharedObject.publicStaticString = 'changedString';"); + assertEquals("changedString", SharedObject.publicStaticString); + } + + @Test + public void accessStaticFieldStringArray() throws ScriptException { + e.eval("var ps_string_array = SharedObject.publicStaticStringArray;"); + assertEquals(SharedObject.publicStaticStringArray[0], e.eval("SharedObject.publicStaticStringArray[0]")); + assertArrayEquals(SharedObject.publicStaticStringArray, (String[])e.get("ps_string_array")); + e.eval("var ts_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + + "ts_string_arr[0] = 'abc';" + + "ts_string_arr[1] = '123';" + + "ts_string_arr[2] = 'xyzzzz';" + + "SharedObject.publicStaticStringArray = ts_string_arr;"); + assertArrayEquals(new String[] { "abc", "123", "xyzzzz" }, SharedObject.publicStaticStringArray); + e.eval("SharedObject.publicStaticStringArray[0] = 'nashorn';"); + assertEquals("nashorn", SharedObject.publicStaticStringArray[0]); + } + + @Test + public void accessFinalFieldString() throws ScriptException { + e.eval("var pf_string = o.publicFinalString;"); + assertEquals(o.publicFinalString, e.get("pf_string")); + assertEquals("string", e.eval("typeof pf_string;")); + e.eval("o.publicFinalString = 'changedString';"); + assertEquals("PublicFinalString", o.publicFinalString); + } + + @Test + public void accessFinalFieldStringArray() throws ScriptException { + e.eval("var pf_string_array = o.publicFinalStringArray;"); + assertEquals(o.publicFinalStringArray[0], e.eval("o.publicFinalStringArray[0]")); + assertArrayEquals(o.publicFinalStringArray, (String[])e.get("pf_string_array")); + e.eval("var tf_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + + "tf_string_arr[0] = 'abc';" + + "tf_string_arr[1] = '123';" + + "tf_string_arr[2] = 'xyzzzz';" + + "o.publicFinalStringArray = tf_string_arr;"); + assertArrayEquals(new String[] { "FinalArrayString[0]", "FinalArrayString[1]", "FinalArrayString[2]", "FinalArrayString[3]" }, o.publicFinalStringArray); + e.eval("o.publicFinalStringArray[0] = 'nashorn';"); + assertEquals("nashorn", o.publicFinalStringArray[0]); + } + + @Test + public void accessStaticFinalFieldString() throws ScriptException { + e.eval("var psf_string = SharedObject.publicStaticFinalString;"); + assertEquals(SharedObject.publicStaticFinalString, e.get("psf_string")); + assertEquals("string", e.eval("typeof psf_string;")); + e.eval("SharedObject.publicStaticFinalString = 'changedString';"); + assertEquals("PublicStaticFinalString", SharedObject.publicStaticFinalString); + } + + @Test + public void accessStaticFinalFieldStringArray() throws ScriptException { + e.eval("var psf_string_array = SharedObject.publicStaticFinalStringArray;"); + assertEquals(SharedObject.publicStaticFinalStringArray[0], e.eval("SharedObject.publicStaticFinalStringArray[0]")); + assertArrayEquals(SharedObject.publicStaticFinalStringArray, (String[])e.get("psf_string_array")); + e.eval("var tsf_string_arr = new (Java.type(\"java.lang.String[]\"))(3);" + + "tsf_string_arr[0] = 'abc';" + + "tsf_string_arr[1] = '123';" + + "tsf_string_arr[2] = 'xyzzzz';" + + "SharedObject.publicStaticFinalStringArray = tsf_string_arr;"); + assertArrayEquals(new String[] { "StaticFinalArrayString[0]", + "StaticFinalArrayString[1]", + "StaticFinalArrayString[2]", + "StaticFinalArrayString[3]" }, + SharedObject.publicStaticFinalStringArray); + e.eval("SharedObject.publicStaticFinalStringArray[0] = 'nashorn';"); + assertEquals("nashorn", SharedObject.publicStaticFinalStringArray[0]); + } + +}
--- a/test/src/jdk/nashorn/api/scripting/InvocableTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,539 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; -import java.util.Objects; -import java.util.function.Function; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * Tests for javax.script.Invocable implementation of nashorn. - */ -@SuppressWarnings("javadoc") -public class InvocableTest { - - private static void log(final String msg) { - org.testng.Reporter.log(msg, true); - } - - @Test - public void invokeMethodTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); - final Object obj = e.get("myExample"); - final Object res = ((Invocable) e).invokeMethod(obj, "hello"); - assertEquals(res, "Hello World!"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - /** - * Check that we can call invokeMethod on an object that we got by - * evaluating script with different Context set. - */ - public void invokeMethodDifferentContextTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - // define an object with method on it - final Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); - - final ScriptContext ctxt = new SimpleScriptContext(); - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); - e.setContext(ctxt); - - // invoke 'func' on obj - but with current script context changed - final Object res = ((Invocable) e).invokeMethod(obj, "hello"); - assertEquals(res, "Hello World!"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - /** - * Check that invokeMethod throws NPE on null method name. - */ - public void invokeMethodNullNameTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - final Object obj = e.eval("({})"); - ((Invocable) e).invokeMethod(obj, null); - fail("should have thrown NPE"); - } catch (final Exception exp) { - if (!(exp instanceof NullPointerException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that invokeMethod throws NoSuchMethodException on missing method. - */ - public void invokeMethodMissingTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - final Object obj = e.eval("({})"); - ((Invocable) e).invokeMethod(obj, "nonExistentMethod"); - fail("should have thrown NoSuchMethodException"); - } catch (final Exception exp) { - if (!(exp instanceof NoSuchMethodException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that calling method on non-script object 'thiz' results in - * IllegalArgumentException. - */ - public void invokeMethodNonScriptObjectThizTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable) e).invokeMethod(new Object(), "toString"); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that calling method on null 'thiz' results in - * IllegalArgumentException. - */ - public void invokeMethodNullThizTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable) e).invokeMethod(null, "toString"); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that calling method on mirror created by another engine results in - * IllegalArgumentException. - */ - public void invokeMethodMixEnginesTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine engine1 = m.getEngineByName("nashorn"); - final ScriptEngine engine2 = m.getEngineByName("nashorn"); - - try { - final Object obj = engine1.eval("({ run: function() {} })"); - // pass object from engine1 to engine2 as 'thiz' for invokeMethod - ((Invocable) engine2).invokeMethod(obj, "run"); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - public void getInterfaceTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Invocable inv = (Invocable) e; - - // try to get interface from global functions - try { - e.eval("function run() { print('run'); };"); - final Runnable runnable = inv.getInterface(Runnable.class); - runnable.run(); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - - // try interface on specific script object - try { - e.eval("var obj = { run: function() { print('run from obj'); } };"); - final Object obj = e.get("obj"); - final Runnable runnable = inv.getInterface(obj, Runnable.class); - runnable.run(); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - public interface Foo { - - public void bar(); - } - - public interface Foo2 extends Foo { - - public void bar2(); - } - - @Test - public void getInterfaceMissingTest() { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine engine = manager.getEngineByName("nashorn"); - - // don't define any function. - try { - engine.eval(""); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - - Runnable runnable = ((Invocable) engine).getInterface(Runnable.class); - if (runnable != null) { - fail("runnable is not null!"); - } - - // now define "run" - try { - engine.eval("function run() { print('this is run function'); }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - runnable = ((Invocable) engine).getInterface(Runnable.class); - // should not return null now! - runnable.run(); - - // define only one method of "Foo2" - try { - engine.eval("function bar() { print('bar function'); }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - - Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class); - if (foo2 != null) { - throw new RuntimeException("foo2 is not null!"); - } - - // now define other method of "Foo2" - try { - engine.eval("function bar2() { print('bar2 function'); }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - foo2 = ((Invocable) engine).getInterface(Foo2.class); - foo2.bar(); - foo2.bar2(); - } - - @Test - /** - * Try passing non-interface Class object for interface implementation. - */ - public void getNonInterfaceGetInterfaceTest() { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine engine = manager.getEngineByName("nashorn"); - try { - log(Objects.toString(((Invocable) engine).getInterface(Object.class))); - fail("Should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - fail("IllegalArgumentException expected, got " + exp); - } - } - } - - @Test - /** - * Check that we can get interface out of a script object even after - * switching to use different ScriptContext. - */ - public void getInterfaceDifferentContext() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final Object obj = e.eval("({ run: function() { } })"); - - // change script context - final ScriptContext ctxt = new SimpleScriptContext(); - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); - e.setContext(ctxt); - - final Runnable r = ((Invocable) e).getInterface(obj, Runnable.class); - r.run(); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - /** - * Check that getInterface on non-script object 'thiz' results in - * IllegalArgumentException. - */ - public void getInterfaceNonScriptObjectThizTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable) e).getInterface(new Object(), Runnable.class); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that getInterface on null 'thiz' results in - * IllegalArgumentException. - */ - public void getInterfaceNullThizTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable) e).getInterface(null, Runnable.class); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that calling getInterface on mirror created by another engine - * results in IllegalArgumentException. - */ - public void getInterfaceMixEnginesTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine engine1 = m.getEngineByName("nashorn"); - final ScriptEngine engine2 = m.getEngineByName("nashorn"); - - try { - final Object obj = engine1.eval("({ run: function() {} })"); - // pass object from engine1 to engine2 as 'thiz' for getInterface - ((Invocable) engine2).getInterface(obj, Runnable.class); - fail("should have thrown IllegalArgumentException"); - } catch (final Exception exp) { - if (!(exp instanceof IllegalArgumentException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * check that null function name results in NPE. - */ - public void invokeFunctionNullNameTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable)e).invokeFunction(null); - fail("should have thrown NPE"); - } catch (final Exception exp) { - if (!(exp instanceof NullPointerException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that attempt to call missing function results in - * NoSuchMethodException. - */ - public void invokeFunctionMissingTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - ((Invocable)e).invokeFunction("NonExistentFunc"); - fail("should have thrown NoSuchMethodException"); - } catch (final Exception exp) { - if (!(exp instanceof NoSuchMethodException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - /** - * Check that invokeFunction calls functions only from current context's - * Bindings. - */ - public void invokeFunctionDifferentContextTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - // define an object with method on it - e.eval("function hello() { return 'Hello World!'; }"); - final ScriptContext ctxt = new SimpleScriptContext(); - ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); - // change engine's current context - e.setContext(ctxt); - - ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context! - fail("should have thrown NoSuchMethodException"); - } catch (final Exception exp) { - if (!(exp instanceof NoSuchMethodException)) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - } - - @Test - public void invokeFunctionExceptionTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("function func() { throw new TypeError(); }"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - - try { - ((Invocable) e).invokeFunction("func"); - fail("should have thrown exception"); - } catch (final ScriptException se) { - // ECMA TypeError property wrapped as a ScriptException - log("got " + se + " as expected"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - } - - @Test - public void invokeMethodExceptionTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - - try { - final Object sobj = e.get("sobj"); - ((Invocable) e).invokeMethod(sobj, "foo"); - fail("should have thrown exception"); - } catch (final ScriptException se) { - // ECMA TypeError property wrapped as a ScriptException - log("got " + se + " as expected"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - } - - @Test - /** - * Tests whether invocation of a JavaScript method through a variable arity - * Java method will pass the vararg array. Both non-vararg and vararg - * JavaScript methods are tested. - * - * @throws ScriptException - */ - public void variableArityInterfaceTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.eval( - "function test1(i, strings) {" - + " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" - + "}" - + "function test2() {" - + " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" - + "}"); - final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class); - Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); - Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); - } - - @Test - public void defaultMethodTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Invocable inv = (Invocable) e; - - final Object obj = e.eval("({ apply: function(arg) { return arg.toUpperCase(); }})"); - @SuppressWarnings("unchecked") - final Function<String, String> func = inv.getInterface(obj, Function.class); - assertEquals(func.apply("hello"), "HELLO"); - } -}
--- a/test/src/jdk/nashorn/api/scripting/MultipleEngineTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.annotations.Test; - -/** - * Test that we can create multiple, independent script engines and use those - * independently. - * - * @test - * @run testng jdk.nashorn.api.scripting.MultipleEngineTest - */ -@SuppressWarnings("javadoc") -public class MultipleEngineTest { - @Test - public void createAndUseManyEngine() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - - final ScriptEngine e1 = m.getEngineByName("nashorn"); - e1.eval("var x = 33; print(x);"); - - final ScriptEngine e2 = m.getEngineByName("nashorn"); - e2.eval("try { print(x) } catch(e) { print(e); }"); - } -}
--- a/test/src/jdk/nashorn/api/scripting/PluggableJSObjectTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.fail; - -import java.nio.IntBuffer; -import java.util.Collection; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Set; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import org.testng.annotations.Test; - -/** - * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject. - * - * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external - * JSObject implementations. - */ -@SuppressWarnings("javadoc") -public class PluggableJSObjectTest { - public static class MapWrapperObject extends AbstractJSObject { - private final HashMap<String, Object> map = new LinkedHashMap<>(); - - public HashMap<String, Object> getMap() { - return map; - } - - @Override - public Object getMember(final String name) { - return map.get(name); - } - - @Override - public void setMember(final String name, final Object value) { - map.put(name, value); - } - - @Override - public boolean hasMember(final String name) { - return map.containsKey(name); - } - - @Override - public void removeMember(final String name) { - map.remove(name); - } - - @Override - public Set<String> keySet() { - return map.keySet(); - } - - @Override - public Collection<Object> values() { - return map.values(); - } - } - - @Test - // Named property access on a JSObject - public void namedAccessTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final MapWrapperObject obj = new MapWrapperObject(); - e.put("obj", obj); - obj.getMap().put("foo", "bar"); - - // property-like access on MapWrapperObject objects - assertEquals(e.eval("obj.foo"), "bar"); - e.eval("obj.foo = 'hello'"); - assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); - assertEquals(e.eval("obj.foo"), "hello"); - assertEquals(obj.getMap().get("foo"), "hello"); - e.eval("delete obj.foo"); - assertFalse(obj.getMap().containsKey("foo")); - assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - // @bug 8062030: Nashorn bug retrieving array property after key string concatenation - @Test - // ConsString attribute access on a JSObject - public void consStringTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final MapWrapperObject obj = new MapWrapperObject(); - e.put("obj", obj); - e.put("f", "f"); - e.eval("obj[f + 'oo'] = 'bar';"); - - assertEquals(obj.getMap().get("foo"), "bar"); - assertEquals(e.eval("obj[f + 'oo']"), "bar"); - assertEquals(e.eval("obj['foo']"), "bar"); - assertEquals(e.eval("f + 'oo' in obj"), Boolean.TRUE); - assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); - e.eval("delete obj[f + 'oo']"); - assertFalse(obj.getMap().containsKey("foo")); - assertEquals(e.eval("obj[f + 'oo']"), null); - assertEquals(e.eval("obj['foo']"), null); - assertEquals(e.eval("f + 'oo' in obj"), Boolean.FALSE); - assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - public static class BufferObject extends AbstractJSObject { - private final IntBuffer buf; - - public BufferObject(final int size) { - buf = IntBuffer.allocate(size); - } - - public IntBuffer getBuffer() { - return buf; - } - - @Override - public Object getMember(final String name) { - return name.equals("length")? buf.capacity() : null; - } - - @Override - public boolean hasSlot(final int i) { - return i > -1 && i < buf.capacity(); - } - - @Override - public Object getSlot(final int i) { - return buf.get(i); - } - - @Override - public void setSlot(final int i, final Object value) { - buf.put(i, ((Number)value).intValue()); - } - - @Override - public boolean isArray() { - return true; - } - } - - @Test - // array-like indexed access for a JSObject - public void indexedAccessTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final BufferObject buf = new BufferObject(2); - e.put("buf", buf); - - // array-like access on BufferObject objects - assertEquals(e.eval("buf.length"), buf.getBuffer().capacity()); - e.eval("buf[0] = 23"); - assertEquals(buf.getBuffer().get(0), 23); - assertEquals(e.eval("buf[0]"), 23); - assertEquals(e.eval("buf[1]"), 0); - buf.getBuffer().put(1, 42); - assertEquals(e.eval("buf[1]"), 42); - assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - public static class Adder extends AbstractJSObject { - @Override - public Object call(final Object thiz, final Object... args) { - double res = 0.0; - for (final Object arg : args) { - res += ((Number)arg).doubleValue(); - } - return res; - } - - @Override - public boolean isFunction() { - return true; - } - } - - @Test - // a callable JSObject - public void callableJSObjectTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.put("sum", new Adder()); - // check callability of Adder objects - assertEquals(e.eval("typeof sum"), "function"); - assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - public static class Factory extends AbstractJSObject { - @SuppressWarnings("unused") - @Override - public Object newObject(final Object... args) { - return new HashMap<Object, Object>(); - } - - @Override - public boolean isFunction() { - return true; - } - } - - @Test - // a factory JSObject - public void factoryJSObjectTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.put("Factory", new Factory()); - - // check new on Factory - assertEquals(e.eval("typeof Factory"), "function"); - assertEquals(e.eval("typeof new Factory()"), "object"); - assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - // iteration tests - public void iteratingJSObjectTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final MapWrapperObject obj = new MapWrapperObject(); - obj.setMember("foo", "hello"); - obj.setMember("bar", "world"); - e.put("obj", obj); - - // check for..in - Object val = e.eval("var str = ''; for (i in obj) str += i; str"); - assertEquals(val.toString(), "foobar"); - - // check for..each..in - val = e.eval("var str = ''; for each (i in obj) str += i; str"); - assertEquals(val.toString(), "helloworld"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } -}
--- a/test/src/jdk/nashorn/api/scripting/ScopeTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,779 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleBindings; -import javax.script.SimpleScriptContext; -import org.testng.Assert; -import org.testng.annotations.Test; - -/** - * Tests for jsr223 Bindings "scope" (engine, global scopes) - */ -@SuppressWarnings("javadoc") -public class ScopeTest { - - @Test - public void createBindingsTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - b.put("foo", 42.0); - Object res = null; - try { - res = e.eval("foo == 42.0", b); - } catch (final ScriptException | NullPointerException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - - assertEquals(res, Boolean.TRUE); - } - - @Test - public void engineScopeTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); - - // check few ECMA standard built-in global properties - assertNotNull(engineScope.get("Object")); - assertNotNull(engineScope.get("TypeError")); - assertNotNull(engineScope.get("eval")); - - // can access via ScriptEngine.get as well - assertNotNull(e.get("Object")); - assertNotNull(e.get("TypeError")); - assertNotNull(e.get("eval")); - - // Access by either way should return same object - assertEquals(engineScope.get("Array"), e.get("Array")); - assertEquals(engineScope.get("EvalError"), e.get("EvalError")); - assertEquals(engineScope.get("undefined"), e.get("undefined")); - - // try exposing a new variable from scope - engineScope.put("myVar", "foo"); - try { - assertEquals(e.eval("myVar"), "foo"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - - // update "myVar" in script an check the value from scope - try { - e.eval("myVar = 'nashorn';"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - - // now check modified value from scope and engine - assertEquals(engineScope.get("myVar"), "nashorn"); - assertEquals(e.get("myVar"), "nashorn"); - } - - @Test - public void multiGlobalTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - try { - final Object obj1 = e.eval("Object"); - final Object obj2 = e.eval("Object", newCtxt); - Assert.assertNotEquals(obj1, obj2); - Assert.assertNotNull(obj1); - Assert.assertNotNull(obj2); - Assert.assertEquals(obj1.toString(), obj2.toString()); - - e.eval("x = 'hello'"); - e.eval("x = 'world'", newCtxt); - Object x1 = e.getContext().getAttribute("x"); - Object x2 = newCtxt.getAttribute("x"); - Assert.assertNotEquals(x1, x2); - Assert.assertEquals(x1, "hello"); - Assert.assertEquals(x2, "world"); - - x1 = e.eval("x"); - x2 = e.eval("x", newCtxt); - Assert.assertNotEquals(x1, x2); - Assert.assertEquals(x1, "hello"); - Assert.assertEquals(x2, "world"); - - final ScriptContext origCtxt = e.getContext(); - e.setContext(newCtxt); - e.eval("y = new Object()"); - e.eval("y = new Object()", origCtxt); - - final Object y1 = origCtxt.getAttribute("y"); - final Object y2 = newCtxt.getAttribute("y"); - Assert.assertNotEquals(y1, y2); - final Object yeval1 = e.eval("y"); - final Object yeval2 = e.eval("y", origCtxt); - Assert.assertNotEquals(yeval1, yeval2); - Assert.assertEquals("[object Object]", y1.toString()); - Assert.assertEquals("[object Object]", y2.toString()); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - } - - @Test - public void userEngineScopeBindingsTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.eval("function func() {}"); - - final ScriptContext newContext = new SimpleScriptContext(); - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); - // we are using a new bindings - so it should have 'func' defined - final Object value = e.eval("typeof func", newContext); - assertTrue(value.equals("undefined")); - } - - @Test - public void userEngineScopeBindingsNoLeakTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptContext newContext = new SimpleScriptContext(); - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); - e.eval("function foo() {}", newContext); - - // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist - assertTrue(e.eval("typeof foo").equals("undefined")); - } - - @Test - public void userEngineScopeBindingsRetentionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptContext newContext = new SimpleScriptContext(); - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); - e.eval("function foo() {}", newContext); - - // definition retained with user's ENGINE_SCOPE Binding - assertTrue(e.eval("typeof foo", newContext).equals("function")); - - final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE); - // but not in another ENGINE_SCOPE binding - newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); - assertTrue(e.eval("typeof foo", newContext).equals("undefined")); - - // restore ENGINE_SCOPE and check again - newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE); - assertTrue(e.eval("typeof foo", newContext).equals("function")); - } - - @Test - // check that engine.js definitions are visible in all new global instances - public void checkBuiltinsInNewBindingsTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - // check default global instance has engine.js definitions - final Bindings g = (Bindings) e.eval("this"); - Object value = g.get("__noSuchProperty__"); - assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); - value = g.get("print"); - assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); - - // check new global instance created has engine.js definitions - final Bindings b = e.createBindings(); - value = b.get("__noSuchProperty__"); - assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); - value = b.get("print"); - assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); - - // put a mapping into GLOBAL_SCOPE - final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE); - globalScope.put("x", "hello"); - - // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval - assertTrue(e.eval("x").equals("hello")); - - final ScriptContext ctx = new SimpleScriptContext(); - ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE); - ctx.setBindings(b, ScriptContext.ENGINE_SCOPE); - - // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval - assertTrue(e.eval("x", ctx).equals("hello")); - - // try some arbitray Bindings for ENGINE_SCOPE - final Bindings sb = new SimpleBindings(); - ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE); - - // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval - assertTrue(e.eval("x", ctx).equals("hello")); - - // engine.js builtins are still defined even with arbitrary Bindings - assertTrue(e.eval("typeof print", ctx).equals("function")); - assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function")); - - // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition - sb.put("x", "newX"); - assertTrue(e.eval("x", ctx).equals("newX")); - } - - /** - * Test multi-threaded access to defined global variables for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedVarTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - final String sharedScript = "foo"; - - assertEquals(e.eval("var foo = 'original context';", origContext), null); - assertEquals(e.eval("var foo = 'new context';", newCtxt), null); - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - assertEquals(e.eval("var foo = 'newer context';", newCtxt), null); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - - assertEquals(e.eval(sharedScript), "original context"); - assertEquals(e.eval(sharedScript, newCtxt), "newer context"); - } - - /** - * Test multi-threaded access to undefined global variables for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - assertEquals(e.eval("foo = 'original context';", origContext), "original context"); - assertEquals(e.eval("foo = 'new context';", newCtxt), "new context"); - final String sharedScript = "foo"; - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - final Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt); - assertEquals(obj3, "newer context"); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - - Assert.assertEquals(e.eval(sharedScript), "original context"); - Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context"); - } - - /** - * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedIncTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - assertEquals(e.eval("var x = 0;", origContext), null); - assertEquals(e.eval("var x = 2;", newCtxt), null); - final String sharedScript = "x++;"; - - final Thread t1 = new Thread(new Runnable() { - @Override - public void run() { - try { - for (int i = 0; i < 1000; i++) { - assertEquals(e.eval(sharedScript, origContext), (double)i); - } - } catch (final ScriptException se) { - fail(se.toString()); - } - } - }); - final Thread t2 = new Thread(new Runnable() { - @Override - public void run() { - try { - for (int i = 2; i < 1000; i++) { - assertEquals(e.eval(sharedScript, newCtxt), (double)i); - } - } catch (final ScriptException se) { - fail(se.toString()); - } - } - }); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - } - - /** - * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - final Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext); - final Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt); - assertEquals(obj1, "original context"); - assertEquals(obj2, "new context"); - final String sharedScript = "''.foo"; - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); - assertEquals(obj3, "newer context"); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - - Assert.assertEquals(e.eval(sharedScript), "original context"); - Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context"); - } - - - /** - * Test multi-threaded access to prototype user accessor properties for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedAccessorTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'original context' })", origContext); - e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'new context', configurable: true })", newCtxt); - final String sharedScript = "({}).foo"; - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - final Object obj3 = e.eval("delete Object.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); - assertEquals(obj3, "newer context"); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - } - - /** - * Test multi-threaded access to primitive prototype user accessor properties for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedPrimitiveAccessorTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'original context' })", origContext); - e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'new context' })", newCtxt); - final String sharedScript = "''.foo"; - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); - assertEquals(obj3, "newer context"); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - } - - /** - * Test multi-threaded scope function invocation for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext); - assertEquals(origContext.getAttribute("scopeVar"), 1); - assertEquals(e.eval("scopeTest()"), 1); - - e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt); - assertEquals(newCtxt.getAttribute("scopeVar"), 1); - assertEquals(e.eval("scopeTest();", newCtxt), 1); - - assertEquals(e.eval("scopeVar = 3;", newCtxt), 3); - assertEquals(newCtxt.getAttribute("scopeVar"), 3); - - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000)); - - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - } - - /** - * Test multi-threaded access to global getters and setters for shared script classes with multiple globals. - */ - @Test - public static void getterSetterTest() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - final String sharedScript = "accessor1"; - - e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext); - assertEquals(e.eval("accessor1 = 1;"), 1); - assertEquals(e.eval(sharedScript), 1); - - e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt); - assertEquals(e.eval("accessor1 = 2;", newCtxt), 2); - assertEquals(e.eval(sharedScript, newCtxt), 2); - - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000)); - - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - assertEquals(e.eval(sharedScript), 1); - assertEquals(e.eval(sharedScript, newCtxt), 2); - assertEquals(e.eval("v"), 1); - assertEquals(e.eval("v", newCtxt), 2); - } - - /** - * Test multi-threaded access to global getters and setters for shared script classes with multiple globals. - */ - @Test - public static void getterSetter2Test() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - final String sharedScript = "accessor2"; - - e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext); - assertEquals(e.eval("accessor2 = 1;"), 1); - assertEquals(e.eval(sharedScript), 1); - - e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt); - assertEquals(e.eval("accessor2 = 2;", newCtxt), 2); - assertEquals(e.eval(sharedScript, newCtxt), 2); - - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000)); - - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - assertEquals(e.eval(sharedScript), 1); - assertEquals(e.eval(sharedScript, newCtxt), 2); - assertEquals(e.eval("x"), 1); - assertEquals(e.eval("x", newCtxt), 2); - } - - // @bug 8058422: Users should be able to overwrite "context" and "engine" variables - @Test - public static void contextOverwriteTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = new SimpleBindings(); - b.put("context", "hello"); - b.put("foo", 32); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - e.setContext(newCtxt); - assertEquals(e.eval("context"), "hello"); - assertEquals(((Number)e.eval("foo")).intValue(), 32); - } - - // @bug 8058422: Users should be able to overwrite "context" and "engine" variables - @Test - public static void contextOverwriteInScriptTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.put("foo", 32); - - assertEquals(((Number)e.eval("foo")).intValue(), 32); - assertEquals(e.eval("context = 'bar'"), "bar"); - assertEquals(((Number)e.eval("foo")).intValue(), 32); - } - - // @bug 8058422: Users should be able to overwrite "context" and "engine" variables - @Test - public static void engineOverwriteTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Bindings b = new SimpleBindings(); - b.put("engine", "hello"); - b.put("foo", 32); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - e.setContext(newCtxt); - assertEquals(e.eval("engine"), "hello"); - assertEquals(((Number)e.eval("foo")).intValue(), 32); - } - - // @bug 8058422: Users should be able to overwrite "context" and "engine" variables - @Test - public static void engineOverwriteInScriptTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.put("foo", 32); - - assertEquals(((Number)e.eval("foo")).intValue(), 32); - assertEquals(e.eval("engine = 'bar'"), "bar"); - assertEquals(((Number)e.eval("foo")).intValue(), 32); - } - - // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook - @Test - public static void testMegamorphicGetInGlobal() throws Exception { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine engine = m.getEngineByName("nashorn"); - final String script = "foo"; - // "foo" is megamorphic because of different global scopes. - // Make sure ScriptContext variable search works even after - // it becomes megamorphic. - for (int index = 0; index < 25; index++) { - final Bindings bindings = new SimpleBindings(); - bindings.put("foo", index); - final Number value = (Number)engine.eval(script, bindings); - assertEquals(index, value.intValue()); - } - } - - /** - * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals. - * @throws ScriptException - * @throws InterruptedException - */ - @Test - public static void testSlowScope() throws ScriptException, InterruptedException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - for (int i = 0; i < 100; i++) { - final Bindings b = e.createBindings(); - final ScriptContext ctxt = new SimpleScriptContext(); - ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - - e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt); - assertEquals(e.eval("a", ctxt), 1); - assertEquals(b.get("a"), 1); - assertEquals(e.eval("b", ctxt), 3); - assertEquals(b.get("b"), 3); - assertEquals(e.eval("c", ctxt), 10); - assertEquals(b.get("c"), 10); - } - } - - private static class ScriptRunner implements Runnable { - - final ScriptEngine engine; - final ScriptContext context; - final String source; - final Object expected; - final int iterations; - - ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) { - this.engine = engine; - this.context = context; - this.source = source; - this.expected = expected; - this.iterations = iterations; - } - - @Override - public void run() { - try { - for (int i = 0; i < iterations; i++) { - assertEquals(engine.eval(source, context), expected); - } - } catch (final ScriptException se) { - throw new RuntimeException(se); - } - } - } - - // @bug 8071678: NashornScriptEngine returns javax.script.ScriptContext instance - // with get/setAttribute methods insonsistent for GLOBAL_SCOPE - @Test - public void testGlobalScopeSearch() throws Exception { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptContext c = e.getContext(); - c.setAttribute("name1234", "value", ScriptContext.GLOBAL_SCOPE); - assertEquals(c.getAttribute("name1234"), "value"); - assertEquals(c.getAttributesScope("name1234"), - ScriptContext.GLOBAL_SCOPE); - } - - // @bug 8071594: NashornScriptEngine returns javax.script.ScriptContext instance - // which doesn't completely conform to the spec regarding exceptions throwing - @Test - public void testScriptContext_NPE_IAE() throws Exception { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptContext c = e.getContext(); - try { - c.getAttribute(""); - throw new AssertionError("should have thrown IAE"); - } catch (IllegalArgumentException iae1) {} - - try { - c.getAttribute(null); - throw new AssertionError("should have thrown NPE"); - } catch (NullPointerException npe1) {} - - try { - c.getAttribute("", ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown IAE"); - } catch (IllegalArgumentException iae2) {} - - try { - c.getAttribute(null, ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown NPE"); - } catch (NullPointerException npe2) {} - - try { - c.removeAttribute("", ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown IAE"); - } catch (IllegalArgumentException iae3) {} - - try { - c.removeAttribute(null, ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown NPE"); - } catch (NullPointerException npe3) {} - - try { - c.setAttribute("", "value", ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown IAE"); - } catch (IllegalArgumentException iae4) {} - - try { - c.setAttribute(null, "value", ScriptContext.ENGINE_SCOPE); - throw new AssertionError("should have thrown NPE"); - } catch (NullPointerException npe4) {} - - try { - c.getAttributesScope(""); - throw new AssertionError("should have thrown IAE"); - } catch (IllegalArgumentException iae5) {} - - try { - c.getAttributesScope(null); - throw new AssertionError("should have thrown NPE"); - } catch (NullPointerException npe5) {} - } -}
--- a/test/src/jdk/nashorn/api/scripting/ScriptEngineSecurityTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,311 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.fail; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.annotations.Test; - -/** - * jsr223 tests for security access checks. - */ -@SuppressWarnings("javadoc") -public class ScriptEngineSecurityTest { - - private static void log(final String msg) { - org.testng.Reporter.log(msg, true); - } - - @Test - public void securityPackagesTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("var v = Packages.sun.misc.Unsafe;"); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (exp instanceof SecurityException) { - log("got " + exp + " as expected"); - } else { - fail(exp.getMessage()); - } - } - } - - @Test - public void securityJavaTypeTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("var v = Java.type('sun.misc.Unsafe');"); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (exp instanceof SecurityException) { - log("got " + exp + " as expected"); - } else { - fail(exp.getMessage()); - } - } - } - - @Test - public void securityClassForNameTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');"); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (exp instanceof SecurityException) { - log("got " + exp + " as expected"); - } else { - fail(exp.getMessage()); - } - } - } - - @Test - public void securitySystemExit() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("java.lang.System.exit(0);"); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (exp instanceof SecurityException) { - log("got " + exp + " as expected"); - } else { - fail(exp.getMessage()); - } - } - } - - - @Test - public void securitySystemExitFromFinalizerThread() throws ScriptException { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" + - "new o(new java.util.ArrayList().iterator())"); - System.gc(); - System.runFinalization(); - // NOTE: this test just exits the VM if it fails. - } - - @Test - public void securitySystemLoadLibrary() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("java.lang.System.loadLibrary('foo');"); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (exp instanceof SecurityException) { - log("got " + exp + " as expected"); - } else { - fail(exp.getMessage()); - } - } - } - - // @bug 8032948: Nashorn linkages awry - @SuppressWarnings("serial") - public static class FakeProxy extends Proxy { - public FakeProxy(final InvocationHandler ih) { - super(ih); - } - - public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) { - return Proxy.getProxyClass(cl, ifaces); - } - } - - @Test - public void fakeProxySubclassAccessCheckTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - e.put("name", ScriptEngineSecurityTest.class.getName()); - e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); - e.put("intfs", new Class[] { Runnable.class }); - - final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);"; - - // Should not be able to call static methods of Proxy via fake subclass - try { - e.eval(getClass); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (! (exp instanceof SecurityException)) { - fail("SecurityException expected, got " + exp); - } - } - } - - @Test - public void fakeProxySubclassAccessCheckTest2() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - e.put("name", ScriptEngineSecurityTest.class.getName()); - e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); - e.put("intfs", new Class[] { Runnable.class }); - - final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);"; - - // Should not be able to call static methods of Proxy via fake subclass - try { - e.eval(getClass); - fail("should have thrown SecurityException"); - } catch (final Exception exp) { - if (! (exp instanceof SecurityException)) { - fail("SecurityException expected, got " + exp); - } - } - } - - @Test - public static void proxyStaticAccessCheckTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Runnable r = (Runnable)Proxy.newProxyInstance( - ScriptEngineTest.class.getClassLoader(), - new Class[] { Runnable.class }, - new InvocationHandler() { - @Override - public Object invoke(final Object p, final Method mtd, final Object[] a) { - return null; - } - }); - - e.put("rc", r.getClass()); - e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); - e.put("intfs", new Class[] { Runnable.class }); - - // make sure static methods of Proxy is not accessible via subclass - try { - e.eval("rc.static.getProxyClass(cl, intfs)"); - fail("Should have thrown SecurityException"); - } catch (final Exception exp) { - if (! (exp instanceof SecurityException)) { - fail("SecurityException expected, got " + exp); - } - } - } - - - @Test - public void nashornConfigSecurityTest() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine(new ClassFilter() { - @Override - public boolean exposeToScripts(final String name) { - return true; - } - }); - fail("SecurityException should have been thrown"); - } catch (final SecurityException e) { - //empty - } - } - - @Test - public void nashornConfigSecurityTest2() { - if (System.getSecurityManager() == null) { - // pass vacuously - return; - } - - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine(new String[0], null, new ClassFilter() { - @Override - public boolean exposeToScripts(final String name) { - return true; - } - }); - fail("SecurityException should have been thrown"); - } catch (final SecurityException e) { - //empty - } - } -}
--- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,915 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -import java.io.StringReader; -import java.io.StringWriter; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.util.Collections; -import java.util.concurrent.Callable; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.function.Consumer; -import java.util.function.Function; -import javax.script.Bindings; -import javax.script.Compilable; -import javax.script.CompiledScript; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; -import org.testng.annotations.Test; - -/** - * Tests for JSR-223 script engine for Nashorn. - * - * @test - * @build jdk.nashorn.api.scripting.Window jdk.nashorn.api.scripting.WindowEventHandler jdk.nashorn.api.scripting.VariableArityTestInterface jdk.nashorn.api.scripting.ScriptEngineTest - * @run testng/othervm jdk.nashorn.api.scripting.ScriptEngineTest - */ -@SuppressWarnings("javadoc") -public class ScriptEngineTest { - - private static void log(final String msg) { - org.testng.Reporter.log(msg, true); - } - - @Test - public void argumentsTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - final String[] args = new String[] { "hello", "world" }; - try { - e.put("arguments", args); - final Object arg0 = e.eval("arguments[0]"); - final Object arg1 = e.eval("arguments[1]"); - assertEquals(args[0], arg0); - assertEquals(args[1], arg1); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void argumentsWithTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - final String[] args = new String[] { "hello", "world" }; - try { - e.put("arguments", args); - final Object arg0 = e.eval("var imports = new JavaImporter(java.io); " + - " with(imports) { arguments[0] }"); - final Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " + - " with(imports) { arguments[1] }"); - assertEquals(args[0], arg0); - assertEquals(args[1], arg1); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void argumentsEmptyTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - assertEquals(e.eval("arguments instanceof Array"), true); - assertEquals(e.eval("arguments.length == 0"), true); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void factoryTests() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - assertNotNull(e); - - final ScriptEngineFactory fac = e.getFactory(); - - assertEquals(fac.getLanguageName(), "ECMAScript"); - assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); - assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); - assertEquals(fac.getEngineName(), "Oracle Nashorn"); - assertEquals(fac.getOutputStatement("context"), "print(context)"); - assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');"); - assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); - - boolean seenJS = false; - for (final String ext : fac.getExtensions()) { - if (ext.equals("js")) { - seenJS = true; - } - } - - assertEquals(seenJS, true); - final String str = fac.getMethodCallSyntax("obj", "foo", "x"); - assertEquals(str, "obj.foo(x)"); - - boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false; - for (final String name : fac.getNames()) { - switch (name) { - case "nashorn": seenNashorn = true; break; - case "javascript": seenJavaScript = true; break; - case "ECMAScript": seenECMAScript = true; break; - default: - break; - } - } - - assertTrue(seenNashorn); - assertTrue(seenJavaScript); - assertTrue(seenECMAScript); - - boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false; - for (final String mime : fac.getMimeTypes()) { - switch (mime) { - case "application/javascript": seenAppJS = true; break; - case "application/ecmascript": seenAppECMA = true; break; - case "text/javascript": seenTextJS = true; break; - case "text/ecmascript": seenTextECMA = true; break; - default: - break; - } - } - - assertTrue(seenAppJS); - assertTrue(seenAppECMA); - assertTrue(seenTextJS); - assertTrue(seenTextECMA); - } - - @Test - public void evalTests() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.put(ScriptEngine.FILENAME, "myfile.js"); - - try { - e.eval("print('hello')"); - } catch (final ScriptException se) { - fail(se.getMessage()); - } - try { - e.eval("print('hello)"); - fail("script exception expected"); - } catch (final ScriptException se) { - assertEquals(se.getLineNumber(), 1); - assertEquals(se.getColumnNumber(), 13); - assertEquals(se.getFileName(), "myfile.js"); - // se.printStackTrace(); - } - - try { - Object obj = e.eval("34 + 41"); - assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue()); - obj = e.eval("x = 5"); - assertTrue(5.0 == ((Number)obj).doubleValue()); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - } - - @Test - public void compileTests() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - CompiledScript script = null; - - try { - script = ((Compilable)e).compile("print('hello')"); - } catch (final ScriptException se) { - fail(se.getMessage()); - } - - try { - script.eval(); - } catch (final ScriptException | NullPointerException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - - // try to compile from a Reader - try { - script = ((Compilable)e).compile(new StringReader("print('world')")); - } catch (final ScriptException se) { - fail(se.getMessage()); - } - - try { - script.eval(); - } catch (final ScriptException | NullPointerException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - } - - @Test - public void compileAndEvalInDiffContextTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine engine = m.getEngineByName("js"); - final Compilable compilable = (Compilable) engine; - final CompiledScript compiledScript = compilable.compile("foo"); - final ScriptContext ctxt = new SimpleScriptContext(); - ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); - assertEquals(compiledScript.eval(ctxt), "hello"); - } - - @Test - public void accessGlobalTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - e.eval("var x = 'hello'"); - assertEquals(e.get("x"), "hello"); - } catch (final ScriptException exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void exposeGlobalTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - e.put("y", "foo"); - e.eval("print(y)"); - } catch (final ScriptException exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void putGlobalFunctionTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - e.put("callable", new Callable<String>() { - @Override - public String call() throws Exception { - return "callable was called"; - } - }); - - try { - e.eval("print(callable.call())"); - } catch (final ScriptException exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void windowAlertTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Window window = new Window(); - - try { - e.put("window", window); - e.eval("print(window.alert)"); - e.eval("window.alert('calling window.alert...')"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void windowLocationTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Window window = new Window(); - - try { - e.put("window", window); - e.eval("print(window.location)"); - final Object locationValue = e.eval("window.getLocation()"); - assertEquals(locationValue, "http://localhost:8080/window"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void windowItemTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Window window = new Window(); - - try { - e.put("window", window); - final String item1 = (String)e.eval("window.item(65535)"); - assertEquals(item1, "ffff"); - final String item2 = (String)e.eval("window.item(255)"); - assertEquals(item2, "ff"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void windowEventTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Window window = new Window(); - - try { - e.put("window", window); - e.eval("window.onload = function() { print('window load event fired'); return true }"); - assertTrue((Boolean)e.eval("window.onload.loaded()")); - final WindowEventHandler handler = window.getOnload(); - assertNotNull(handler); - assertTrue(handler.loaded()); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void throwTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.put(ScriptEngine.FILENAME, "throwtest.js"); - - try { - e.eval("throw 'foo'"); - } catch (final ScriptException exp) { - log(exp.getMessage()); - assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0"); - assertEquals(exp.getFileName(), "throwtest.js"); - assertEquals(exp.getLineNumber(), 1); - } - } - - @Test - public void setTimeoutTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final Window window = new Window(); - - try { - final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class }; - final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes); - assertNotNull(setTimeout); - e.put("window", window); - e.eval("window.setTimeout('foo()', 100)"); - - // try to make setTimeout global - e.put("setTimeout", setTimeout); - // TODO: java.lang.ClassCastException: required class - // java.lang.Integer but encountered class java.lang.Double - // e.eval("setTimeout('foo2()', 200)"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void setWriterTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final StringWriter sw = new StringWriter(); - e.getContext().setWriter(sw); - - try { - e.eval("print('hello world')"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - assertEquals(sw.toString(), println("hello world")); - } - - @Test - public void redefineEchoTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - try { - e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - @Test - public void noEnumerablePropertiesTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("for (i in this) { throw 'found property: ' + i }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void noRefErrorForGlobalThisAccessTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("this.foo"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void refErrorForUndeclaredAccessTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void typeErrorForGlobalThisCallTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void refErrorForUndeclaredCallTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - // check that print function prints arg followed by newline char - public void printTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final StringWriter sw = new StringWriter(); - e.getContext().setWriter(sw); - try { - e.eval("print('hello')"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - - assertEquals(sw.toString(), println("hello")); - } - - @Test - // check that print prints all arguments (more than one) - public void printManyTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final StringWriter sw = new StringWriter(); - e.getContext().setWriter(sw); - try { - e.eval("print(34, true, 'hello')"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - - assertEquals(sw.toString(), println("34 true hello")); - } - - @Test - public void scriptObjectAutoConversionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.eval("obj = { foo: 'hello' }"); - e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window")); - assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); - assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello"); - assertEquals(e.eval("Window.funcMap(obj)"), "hello"); - assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); - } - - // @bug 8032948: Nashorn linkages awry - @Test - public void checkProxyAccess() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final boolean[] reached = new boolean[1]; - final Runnable r = (Runnable)Proxy.newProxyInstance( - ScriptEngineTest.class.getClassLoader(), - new Class[] { Runnable.class }, - new InvocationHandler() { - @Override - public Object invoke(final Object p, final Method mtd, final Object[] a) { - reached[0] = true; - return null; - } - }); - - e.put("r", r); - e.eval("r.run()"); - - assertTrue(reached[0]); - } - - // properties that can be read by any code - private static String[] propNames = { - "java.version", - "java.vendor", - "java.vendor.url", - "java.class.version", - "os.name", - "os.version", - "os.arch", - "file.separator", - "path.separator", - "line.separator", - "java.specification.version", - "java.specification.vendor", - "java.specification.name", - "java.vm.specification.version", - "java.vm.specification.vendor", - "java.vm.specification.name", - "java.vm.version", - "java.vm.vendor", - "java.vm.name" - }; - - // @bug 8033924: Default permissions are not given for eval code - @Test - public void checkPropertyReadPermissions() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - for (final String name : propNames) { - checkProperty(e, name); - } - } - - // @bug 8046013: TypeError: Cannot apply "with" to non script object - @Test - public void withOnMirrorTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - final Object obj = e.eval("({ foo: 'hello'})"); - final Object[] arr = new Object[1]; - arr[0] = obj; - e.put("arr", arr); - final Object res = e.eval("var res; with(arr[0]) { res = foo; }; res"); - assertEquals(res, "hello"); - } - - // @bug 8054223: Nashorn: AssertionError when use __DIR__ and ScriptEngine.eval() - @Test - public void check__DIR__Test() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - e.eval("__DIR__"); - } - - // @bug 8050432:javax.script.filename variable should not be enumerable - // with nashorn engine's ENGINE_SCOPE bindings - @Test - public void enumerableGlobalsTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - e.put(ScriptEngine.FILENAME, "test"); - final Object enumerable = e.eval( - "Object.getOwnPropertyDescriptor(this, " + - " 'javax.script.filename').enumerable"); - assertEquals(enumerable, Boolean.FALSE); - } - - public static class Context { - private Object myobj; - - public void set(final Object o) { - myobj = o; - } - - public Object get() { - return myobj; - } - } - - // @bug 8050977: Java8 Javascript Nashorn exception: - // no current Global instance for nashorn - @Test - public void currentGlobalMissingTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - - final Context ctx = new Context(); - e.put("ctx", ctx); - e.eval("var obj = { foo: function(str) { return str.toUpperCase() } }"); - e.eval("ctx.set(obj)"); - final Invocable inv = (Invocable)e; - assertEquals("HELLO", inv.invokeMethod(ctx.get(), "foo", "hello")); - // try object literal - e.eval("ctx.set({ bar: function(str) { return str.toLowerCase() } })"); - assertEquals("hello", inv.invokeMethod(ctx.get(), "bar", "HELLO")); - // try array literal - e.eval("var arr = [ 'hello', 'world' ]"); - e.eval("ctx.set(arr)"); - assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", "")); - } - - // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. - @Test - public void functionalInterfaceStringTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - final AtomicBoolean invoked = new AtomicBoolean(false); - e.put("f", new Function<String, String>() { - @Override - public String apply(String t) { - invoked.set(true); - return t; - } - }); - assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); - assertTrue(invoked.get()); - } - - // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. - @Test - public void functionalInterfaceObjectTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - final AtomicBoolean invoked = new AtomicBoolean(false); - e.put("c", new Consumer<Object>() { - @Override - public void accept(Object t) { - assertTrue(t instanceof ScriptObjectMirror); - assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); - invoked.set(true); - } - }); - e.eval("var x = 'xy'; x += 'z';c({a:x})"); - assertTrue(invoked.get()); - } - - // @bug 8068524: NashornScriptEngineFactory.getParameter() throws IAE - // for an unknown key, doesn't conform to the general spec - @Test - public void getParameterInvalidKeyTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - // no exception expected here! - Object value = e.getFactory().getParameter("no value assigned to this key"); - assertNull(value); - } - - // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. - @Test - public void functionalInterfaceStringTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - final AtomicBoolean invoked = new AtomicBoolean(false); - e.put("f", new Function<String, String>() { - @Override - public String apply(String t) { - invoked.set(true); - return t; - } - }); - assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); - assertTrue(invoked.get()); - } - - // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. - @Test - public void functionalInterfaceObjectTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - final AtomicBoolean invoked = new AtomicBoolean(false); - e.put("c", new Consumer<Object>() { - @Override - public void accept(Object t) { - assertTrue(t instanceof ScriptObjectMirror); - assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); - invoked.set(true); - } - }); - e.eval("var x = 'xy'; x += 'z';c({a:x})"); - assertTrue(invoked.get()); - } - - @Test - public void testLengthOnArrayLikeObjects() throws Exception { - final ScriptEngine e = new ScriptEngineManager().getEngineByName("nashorn"); - final Object val = e.eval("var arr = { length: 1, 0: 1}; arr.length"); - - assertTrue(Number.class.isAssignableFrom(val.getClass())); - assertTrue(((Number)val).intValue() == 1); - } - - // @bug JDK-8068603: NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions - @Test - public void illegalBindingsValuesTest() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - - try { - e.put(null, "null-value"); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - e.put("", "empty-value"); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - - final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); - assertTrue(b instanceof ScriptObjectMirror); - - try { - b.put(null, "null-value"); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.put("", "empty-value"); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - - try { - b.get(null); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.get(""); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - - try { - b.get(1); - fail(); - } catch (ClassCastException x) { - // expected - } - - try { - b.remove(null); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.remove(""); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - - try { - b.remove(1); - fail(); - } catch (ClassCastException x) { - // expected - } - - try { - b.containsKey(null); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.containsKey(""); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - - try { - b.containsKey(1); - fail(); - } catch (ClassCastException x) { - // expected - } - - try { - b.putAll(null); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.putAll(Collections.singletonMap((String)null, "null-value")); - fail(); - } catch (NullPointerException x) { - // expected - } - - try { - b.putAll(Collections.singletonMap("", "empty-value")); - fail(); - } catch (IllegalArgumentException x) { - // expected - } - } - - // @bug 8071989: NashornScriptEngine returns javax.script.ScriptContext instance - // with insonsistent get/remove methods behavior for undefined attributes - @Test - public void testScriptContextGetRemoveUndefined() throws Exception { - final ScriptEngineManager manager = new ScriptEngineManager(); - final ScriptEngine e = manager.getEngineByName("nashorn"); - final ScriptContext ctx = e.getContext(); - assertNull(ctx.getAttribute("undefinedname", ScriptContext.ENGINE_SCOPE)); - assertNull(ctx.removeAttribute("undefinedname", ScriptContext.ENGINE_SCOPE)); - } - - private static void checkProperty(final ScriptEngine e, final String name) - throws ScriptException { - final String value = System.getProperty(name); - e.put("name", name); - assertEquals(value, e.eval("java.lang.System.getProperty(name)")); - } - - private static final String LINE_SEPARATOR = System.getProperty("line.separator"); - - // Returns String that would be the result of calling PrintWriter.println - // of the given String. (This is to handle platform specific newline). - private static String println(final String str) { - return str + LINE_SEPARATOR; - } -}
--- a/test/src/jdk/nashorn/api/scripting/ScriptObjectMirrorTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,387 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; - -import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.function.Function; -import javax.script.Bindings; -import javax.script.Invocable; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import org.testng.annotations.Test; - -/** - * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API. - */ -@SuppressWarnings("javadoc") -public class ScriptObjectMirrorTest { - - @SuppressWarnings("unchecked") - @Test - public void reflectionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - - e.eval("var obj = { x: 344, y: 'nashorn' }"); - - int count = 0; - Map<Object, Object> map = (Map<Object, Object>) e.get("obj"); - assertFalse(map.isEmpty()); - assertTrue(map.keySet().contains("x")); - assertTrue(map.containsKey("x")); - assertTrue(map.values().contains("nashorn")); - assertTrue(map.containsValue("nashorn")); - for (final Map.Entry<?, ?> ex : map.entrySet()) { - final Object key = ex.getKey(); - if (key.equals("x")) { - assertTrue(344 == ((Number) ex.getValue()).doubleValue()); - count++; - } else if (key.equals("y")) { - assertEquals(ex.getValue(), "nashorn"); - count++; - } - } - assertEquals(2, count); - assertEquals(2, map.size()); - - // add property - map.put("z", "hello"); - assertEquals(e.eval("obj.z"), "hello"); - assertEquals(map.get("z"), "hello"); - assertTrue(map.keySet().contains("z")); - assertTrue(map.containsKey("z")); - assertTrue(map.values().contains("hello")); - assertTrue(map.containsValue("hello")); - assertEquals(map.size(), 3); - - final Map<Object, Object> newMap = new HashMap<>(); - newMap.put("foo", 23.0); - newMap.put("bar", true); - map.putAll(newMap); - - assertEquals(e.eval("obj.foo"), 23.0); - assertEquals(e.eval("obj.bar"), true); - - // remove using map method - map.remove("foo"); - assertEquals(e.eval("typeof obj.foo"), "undefined"); - - count = 0; - e.eval("var arr = [ true, 'hello' ]"); - map = (Map<Object, Object>) e.get("arr"); - assertFalse(map.isEmpty()); - assertTrue(map.containsKey("length")); - assertTrue(map.containsValue("hello")); - for (final Map.Entry<?, ?> ex : map.entrySet()) { - final Object key = ex.getKey(); - if (key.equals("0")) { - assertEquals(ex.getValue(), Boolean.TRUE); - count++; - } else if (key.equals("1")) { - assertEquals(ex.getValue(), "hello"); - count++; - } - } - assertEquals(count, 2); - assertEquals(map.size(), 2); - - // add element - map.put("2", "world"); - assertEquals(map.get("2"), "world"); - assertEquals(map.size(), 3); - - // remove all - map.clear(); - assertTrue(map.isEmpty()); - assertEquals(e.eval("typeof arr[0]"), "undefined"); - assertEquals(e.eval("typeof arr[1]"), "undefined"); - assertEquals(e.eval("typeof arr[2]"), "undefined"); - } - - @Test - public void jsobjectTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); - final ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj"); - - // try basic get on existing properties - if (!obj.getMember("bar").equals("hello")) { - fail("obj.bar != 'hello'"); - } - - if (!obj.getSlot(1).equals("world")) { - fail("obj[1] != 'world'"); - } - - if (!obj.callMember("func", new Object[0]).equals("hello")) { - fail("obj.func() != 'hello'"); - } - - // try setting properties - obj.setMember("bar", "new-bar"); - obj.setSlot(1, "new-element-1"); - if (!obj.getMember("bar").equals("new-bar")) { - fail("obj.bar != 'new-bar'"); - } - - if (!obj.getSlot(1).equals("new-element-1")) { - fail("obj[1] != 'new-element-1'"); - } - - // try adding properties - obj.setMember("prop", "prop-value"); - obj.setSlot(12, "element-12"); - if (!obj.getMember("prop").equals("prop-value")) { - fail("obj.prop != 'prop-value'"); - } - - if (!obj.getSlot(12).equals("element-12")) { - fail("obj[12] != 'element-12'"); - } - - // delete properties - obj.removeMember("prop"); - if ("prop-value".equals(obj.getMember("prop"))) { - fail("obj.prop is not deleted!"); - } - - // Simple eval tests - assertEquals(obj.eval("typeof Object"), "function"); - assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); - } catch (final Exception exp) { - exp.printStackTrace(); - fail(exp.getMessage()); - } - } - - @Test - public void scriptObjectMirrorToStringTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - try { - final Object obj = e.eval("new TypeError('wrong type')"); - assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - - try { - final Object obj = e.eval("function func() { print('hello'); }"); - assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); - } catch (final Throwable t) { - t.printStackTrace(); - fail(t.getMessage()); - } - } - - @Test - public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptEngine e2 = m.getEngineByName("nashorn"); - - e.eval("function func() {}"); - e2.put("foo", e.get("func")); - final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); - final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); - assertTrue(newObj instanceof ScriptObjectMirror); - } - - @Test - public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptEngine e2 = m.getEngineByName("nashorn"); - - e.eval("function func() {}"); - e2.put("func", e.get("func")); - final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); - final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); - assertTrue(newObj instanceof ScriptObjectMirror); - } - - @Test - public void indexPropertiesExternalBufferTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptObjectMirror obj = (ScriptObjectMirror)e.eval("var obj = {}; obj"); - final ByteBuffer buf = ByteBuffer.allocate(5); - int i; - for (i = 0; i < 5; i++) { - buf.put(i, (byte)(i+10)); - } - obj.setIndexedPropertiesToExternalArrayData(buf); - - for (i = 0; i < 5; i++) { - assertEquals((byte)(i+10), ((Number)e.eval("obj[" + i + "]")).byteValue()); - } - - e.eval("for (i = 0; i < 5; i++) obj[i] = 0"); - for (i = 0; i < 5; i++) { - assertEquals((byte)0, ((Number)e.eval("obj[" + i + "]")).byteValue()); - assertEquals((byte)0, buf.get(i)); - } - } - - @Test - public void conversionTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]"); - final int[] intArr = arr.to(int[].class); - assertEquals(intArr[0], 33); - assertEquals(intArr[1], 45); - assertEquals(intArr[2], 23); - - final List<?> list = arr.to(List.class); - assertEquals(list.get(0), 33); - assertEquals(list.get(1), 45); - assertEquals(list.get(2), 23); - - ScriptObjectMirror obj = (ScriptObjectMirror)e.eval( - "({ valueOf: function() { return 42 } })"); - assertEquals(Double.valueOf(42.0), obj.to(Double.class)); - - obj = (ScriptObjectMirror)e.eval( - "({ toString: function() { return 'foo' } })"); - assertEquals("foo", obj.to(String.class)); - } - - // @bug 8044000: Access to undefined property yields "null" instead of "undefined" - @Test - public void mapScriptObjectMirrorCallsiteTest() throws ScriptException { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine engine = m.getEngineByName("nashorn"); - final String TEST_SCRIPT = "typeof obj.foo"; - - final Bindings global = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE); - engine.eval("var obj = java.util.Collections.emptyMap()"); - // this will drive callsite "obj.foo" of TEST_SCRIPT - // to use "obj instanceof Map" as it's guard - engine.eval(TEST_SCRIPT, global); - // redefine 'obj' to be a script object - engine.eval("obj = {}"); - - final Bindings newGlobal = engine.createBindings(); - // transfer 'obj' from default global to new global - // new global will get a ScriptObjectMirror wrapping 'obj' - newGlobal.put("obj", global.get("obj")); - - // Every ScriptObjectMirror is a Map! If callsite "obj.foo" - // does not see the new 'obj' is a ScriptObjectMirror, it'll - // continue to use Map's get("obj.foo") instead of ScriptObjectMirror's - // getMember("obj.foo") - thereby getting null instead of undefined - assertEquals("undefined", engine.eval(TEST_SCRIPT, newGlobal)); - } - - public interface MirrorCheckExample { - Object test1(Object arg); - Object test2(Object arg); - boolean compare(Object o1, Object o2); - } - - // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface - @Test - public void checkMirrorToObject() throws Exception { - final ScriptEngineManager engineManager = new ScriptEngineManager(); - final ScriptEngine engine = engineManager.getEngineByName("nashorn"); - final Invocable invocable = (Invocable)engine; - - engine.eval("function test1(arg) { return { arg: arg }; }"); - engine.eval("function test2(arg) { return arg; }"); - engine.eval("function compare(arg1, arg2) { return arg1 == arg2; }"); - - final Map<String, Object> map = new HashMap<>(); - map.put("option", true); - - final MirrorCheckExample example = invocable.getInterface(MirrorCheckExample.class); - - final Object value1 = invocable.invokeFunction("test1", map); - final Object value2 = example.test1(map); - final Object value3 = invocable.invokeFunction("test2", value2); - final Object value4 = example.test2(value2); - - // check that Object type argument receives a ScriptObjectMirror - // when ScriptObject is passed - assertEquals(ScriptObjectMirror.class, value1.getClass()); - assertEquals(ScriptObjectMirror.class, value2.getClass()); - assertEquals(ScriptObjectMirror.class, value3.getClass()); - assertEquals(ScriptObjectMirror.class, value4.getClass()); - assertTrue((boolean)invocable.invokeFunction("compare", value1, value1)); - assertTrue(example.compare(value1, value1)); - assertTrue((boolean)invocable.invokeFunction("compare", value3, value4)); - assertTrue(example.compare(value3, value4)); - } - - // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface - @Test - public void mirrorUnwrapInterfaceMethod() throws Exception { - final ScriptEngineManager engineManager = new ScriptEngineManager(); - final ScriptEngine engine = engineManager.getEngineByName("nashorn"); - final Invocable invocable = (Invocable)engine; - engine.eval("function apply(obj) { " + - " return obj instanceof Packages.jdk.nashorn.api.scripting.ScriptObjectMirror; " + - "}"); - @SuppressWarnings("unchecked") - final Function<Object,Object> func = invocable.getInterface(Function.class); - assertFalse((boolean)func.apply(engine.eval("({ x: 2 })"))); - } - - // @bug 8055687: Wrong "this" passed to JSObject.eval call - @Test - public void checkThisForJSObjectEval() throws Exception { - final ScriptEngineManager engineManager = new ScriptEngineManager(); - final ScriptEngine e = engineManager.getEngineByName("nashorn"); - final JSObject jsobj = (JSObject)e.eval("({foo: 23, bar: 'hello' })"); - assertEquals(((Number)jsobj.eval("this.foo")).intValue(), 23); - assertEquals(jsobj.eval("this.bar"), "hello"); - assertEquals(jsobj.eval("String(this)"), "[object Object]"); - final Object global = e.eval("this"); - assertFalse(global.equals(jsobj.eval("this"))); - } - - @Test - public void topLevelAnonFuncStatement() throws Exception { - final ScriptEngineManager engineManager = new ScriptEngineManager(); - final ScriptEngine e = engineManager.getEngineByName("nashorn"); - final JSObject func = (JSObject)e.eval("function(x) { return x + ' world' }"); - assertTrue(func.isFunction()); - assertEquals(func.call(e.eval("this"), "hello"), "hello world"); - } -}
--- a/test/src/jdk/nashorn/api/scripting/VariableArityTestInterface.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -@SuppressWarnings("javadoc") -public interface VariableArityTestInterface { - public String test1(int i, String... strings); - public String test2(int i, String... strings); -}
--- a/test/src/jdk/nashorn/api/scripting/Window.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -import java.util.Map; -import javax.script.Bindings; - -@SuppressWarnings("javadoc") -public class Window { - - private String location = "http://localhost:8080/window"; - - private WindowEventHandler onload = null; - - public void alert(final String message) { - System.out.println("alert: " + message); - } - - public String getLocation() { - return location; - } - - public void setLocation(final String location) { - this.location = location; - } - - public String item(final int index) { - return Integer.toHexString(index); - } - - public WindowEventHandler getOnload() { - return onload; - } - - public void setOnload(final WindowEventHandler onload) { - this.onload = onload; - } - - public static int setTimeout(final Window self, final String code, final int delay) { - return self.setTimeout(code, delay); - } - - public int setTimeout(final String code, final int delay) { - System.out.println("window.setTimeout: " + delay + ", code: " + code); - return 0; - } - - public static Object funcJSObject(final JSObject jsobj) { - return jsobj.getMember("foo"); - } - - public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) { - return sobj.get("foo"); - } - - public static Object funcMap(final Map<?,?> map) { - return map.get("foo"); - } - - public static Object funcBindings(final Bindings bindings) { - return bindings.get("foo"); - } -}
--- a/test/src/jdk/nashorn/api/scripting/WindowEventHandler.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.api.scripting; - -@SuppressWarnings("javadoc") -public interface WindowEventHandler { - public boolean loaded(); -}
--- a/test/src/jdk/nashorn/api/scripting/resources/func.js Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. - -var scopeVar = 1; -var global = this; -undefGlobal = this; - -function scopeTest() { - if (this !== global) { - throw new Error("this !== global"); - } - if (this !== undefGlobal) { - throw new Error("this !== undefinedGlobal") - } - return scopeVar; -} - -scopeTest();
--- a/test/src/jdk/nashorn/api/scripting/resources/gettersetter.js Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. - -var v; - -Object.defineProperty(this, "accessor1", { - get: function() { return v; }, - set: function(n) { v = n; } -}); - -Object.defineProperty(this, "accessor2", { - get: function() { return x; }, - set: function(n) { x = n; } -});
--- a/test/src/jdk/nashorn/api/scripting/resources/witheval.js Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. - -var a; - -function outer(p, e) { - eval(e); - with(p) { - function inner() { - a = 1; - c = 10; - if (a !== 1) { - throw new Error("a !== 1"); - } - if (b !== 3) { - throw new Error("b !== 3"); - } - if (c !== 10) { - throw new Error("c !== 10"); - } - } - inner(); - } -} - -outer({}, "b = 3;"); - -if (a !== 1) { - throw new Error("a !== 1"); -} -if (b !== 3) { - throw new Error("b !== 3"); -} -if (c !== 10) { - throw new Error("c !== 10"); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/InvocableTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; +import java.util.Objects; +import java.util.function.Function; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Tests for javax.script.Invocable implementation of nashorn. + */ +@SuppressWarnings("javadoc") +public class InvocableTest { + + private static void log(final String msg) { + org.testng.Reporter.log(msg, true); + } + + @Test + public void invokeMethodTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + e.eval("var Example = function() { this.hello = function() { return 'Hello World!'; };}; myExample = new Example();"); + final Object obj = e.get("myExample"); + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); + assertEquals(res, "Hello World!"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + /** + * Check that we can call invokeMethod on an object that we got by + * evaluating script with different Context set. + */ + public void invokeMethodDifferentContextTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + // define an object with method on it + final Object obj = e.eval("({ hello: function() { return 'Hello World!'; } })"); + + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); + e.setContext(ctxt); + + // invoke 'func' on obj - but with current script context changed + final Object res = ((Invocable) e).invokeMethod(obj, "hello"); + assertEquals(res, "Hello World!"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + /** + * Check that invokeMethod throws NPE on null method name. + */ + public void invokeMethodNullNameTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + final Object obj = e.eval("({})"); + ((Invocable) e).invokeMethod(obj, null); + fail("should have thrown NPE"); + } catch (final Exception exp) { + if (!(exp instanceof NullPointerException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that invokeMethod throws NoSuchMethodException on missing method. + */ + public void invokeMethodMissingTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + final Object obj = e.eval("({})"); + ((Invocable) e).invokeMethod(obj, "nonExistentMethod"); + fail("should have thrown NoSuchMethodException"); + } catch (final Exception exp) { + if (!(exp instanceof NoSuchMethodException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that calling method on non-script object 'thiz' results in + * IllegalArgumentException. + */ + public void invokeMethodNonScriptObjectThizTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable) e).invokeMethod(new Object(), "toString"); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that calling method on null 'thiz' results in + * IllegalArgumentException. + */ + public void invokeMethodNullThizTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable) e).invokeMethod(null, "toString"); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that calling method on mirror created by another engine results in + * IllegalArgumentException. + */ + public void invokeMethodMixEnginesTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine1 = m.getEngineByName("nashorn"); + final ScriptEngine engine2 = m.getEngineByName("nashorn"); + + try { + final Object obj = engine1.eval("({ run: function() {} })"); + // pass object from engine1 to engine2 as 'thiz' for invokeMethod + ((Invocable) engine2).invokeMethod(obj, "run"); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + public void getInterfaceTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Invocable inv = (Invocable) e; + + // try to get interface from global functions + try { + e.eval("function run() { print('run'); };"); + final Runnable runnable = inv.getInterface(Runnable.class); + runnable.run(); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + + // try interface on specific script object + try { + e.eval("var obj = { run: function() { print('run from obj'); } };"); + final Object obj = e.get("obj"); + final Runnable runnable = inv.getInterface(obj, Runnable.class); + runnable.run(); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public interface Foo { + + public void bar(); + } + + public interface Foo2 extends Foo { + + public void bar2(); + } + + @Test + public void getInterfaceMissingTest() { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine engine = manager.getEngineByName("nashorn"); + + // don't define any function. + try { + engine.eval(""); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + + Runnable runnable = ((Invocable) engine).getInterface(Runnable.class); + if (runnable != null) { + fail("runnable is not null!"); + } + + // now define "run" + try { + engine.eval("function run() { print('this is run function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + runnable = ((Invocable) engine).getInterface(Runnable.class); + // should not return null now! + runnable.run(); + + // define only one method of "Foo2" + try { + engine.eval("function bar() { print('bar function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + + Foo2 foo2 = ((Invocable) engine).getInterface(Foo2.class); + if (foo2 != null) { + throw new RuntimeException("foo2 is not null!"); + } + + // now define other method of "Foo2" + try { + engine.eval("function bar2() { print('bar2 function'); }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + foo2 = ((Invocable) engine).getInterface(Foo2.class); + foo2.bar(); + foo2.bar2(); + } + + @Test + /** + * Try passing non-interface Class object for interface implementation. + */ + public void getNonInterfaceGetInterfaceTest() { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine engine = manager.getEngineByName("nashorn"); + try { + log(Objects.toString(((Invocable) engine).getInterface(Object.class))); + fail("Should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + fail("IllegalArgumentException expected, got " + exp); + } + } + } + + @Test + /** + * Check that we can get interface out of a script object even after + * switching to use different ScriptContext. + */ + public void getInterfaceDifferentContext() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final Object obj = e.eval("({ run: function() { } })"); + + // change script context + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); + e.setContext(ctxt); + + final Runnable r = ((Invocable) e).getInterface(obj, Runnable.class); + r.run(); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + /** + * Check that getInterface on non-script object 'thiz' results in + * IllegalArgumentException. + */ + public void getInterfaceNonScriptObjectThizTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable) e).getInterface(new Object(), Runnable.class); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that getInterface on null 'thiz' results in + * IllegalArgumentException. + */ + public void getInterfaceNullThizTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable) e).getInterface(null, Runnable.class); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that calling getInterface on mirror created by another engine + * results in IllegalArgumentException. + */ + public void getInterfaceMixEnginesTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine1 = m.getEngineByName("nashorn"); + final ScriptEngine engine2 = m.getEngineByName("nashorn"); + + try { + final Object obj = engine1.eval("({ run: function() {} })"); + // pass object from engine1 to engine2 as 'thiz' for getInterface + ((Invocable) engine2).getInterface(obj, Runnable.class); + fail("should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (!(exp instanceof IllegalArgumentException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * check that null function name results in NPE. + */ + public void invokeFunctionNullNameTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable)e).invokeFunction(null); + fail("should have thrown NPE"); + } catch (final Exception exp) { + if (!(exp instanceof NullPointerException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that attempt to call missing function results in + * NoSuchMethodException. + */ + public void invokeFunctionMissingTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + ((Invocable)e).invokeFunction("NonExistentFunc"); + fail("should have thrown NoSuchMethodException"); + } catch (final Exception exp) { + if (!(exp instanceof NoSuchMethodException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + /** + * Check that invokeFunction calls functions only from current context's + * Bindings. + */ + public void invokeFunctionDifferentContextTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + // define an object with method on it + e.eval("function hello() { return 'Hello World!'; }"); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); + // change engine's current context + e.setContext(ctxt); + + ((Invocable) e).invokeFunction("hello"); // no 'hello' in new context! + fail("should have thrown NoSuchMethodException"); + } catch (final Exception exp) { + if (!(exp instanceof NoSuchMethodException)) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + } + + @Test + public void invokeFunctionExceptionTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("function func() { throw new TypeError(); }"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + + try { + ((Invocable) e).invokeFunction("func"); + fail("should have thrown exception"); + } catch (final ScriptException se) { + // ECMA TypeError property wrapped as a ScriptException + log("got " + se + " as expected"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + } + + @Test + public void invokeMethodExceptionTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("var sobj = {}; sobj.foo = function func() { throw new TypeError(); }"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + + try { + final Object sobj = e.get("sobj"); + ((Invocable) e).invokeMethod(sobj, "foo"); + fail("should have thrown exception"); + } catch (final ScriptException se) { + // ECMA TypeError property wrapped as a ScriptException + log("got " + se + " as expected"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + } + + @Test + /** + * Tests whether invocation of a JavaScript method through a variable arity + * Java method will pass the vararg array. Both non-vararg and vararg + * JavaScript methods are tested. + * + * @throws ScriptException + */ + public void variableArityInterfaceTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.eval( + "function test1(i, strings) {" + + " return 'i == ' + i + ', strings instanceof java.lang.String[] == ' + (strings instanceof Java.type('java.lang.String[]')) + ', strings == ' + java.util.Arrays.toString(strings)" + + "}" + + "function test2() {" + + " return 'arguments[0] == ' + arguments[0] + ', arguments[1] instanceof java.lang.String[] == ' + (arguments[1] instanceof Java.type('java.lang.String[]')) + ', arguments[1] == ' + java.util.Arrays.toString(arguments[1])" + + "}"); + final VariableArityTestInterface itf = ((Invocable) e).getInterface(VariableArityTestInterface.class); + Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); + Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); + } + + @Test + public void defaultMethodTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Invocable inv = (Invocable) e; + + final Object obj = e.eval("({ apply: function(arg) { return arg.toUpperCase(); }})"); + @SuppressWarnings("unchecked") + final Function<String, String> func = inv.getInterface(obj, Function.class); + assertEquals(func.apply("hello"), "HELLO"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/MultipleEngineTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import org.testng.annotations.Test; + +/** + * Test that we can create multiple, independent script engines and use those + * independently. + * + * @test + * @run testng jdk.nashorn.api.scripting.test.MultipleEngineTest + */ +@SuppressWarnings("javadoc") +public class MultipleEngineTest { + @Test + public void createAndUseManyEngine() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + + final ScriptEngine e1 = m.getEngineByName("nashorn"); + e1.eval("var x = 33; print(x);"); + + final ScriptEngine e2 = m.getEngineByName("nashorn"); + e2.eval("try { print(x) } catch(e) { print(e); }"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/PluggableJSObjectTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,289 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.fail; + +import java.nio.IntBuffer; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Set; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import jdk.nashorn.api.scripting.AbstractJSObject; +import org.testng.annotations.Test; + +/** + * Tests for pluggable external impls. of jdk.nashorn.api.scripting.JSObject. + * + * JDK-8024615: Refactor ScriptObjectMirror and JSObject to support external + * JSObject implementations. + */ +@SuppressWarnings("javadoc") +public class PluggableJSObjectTest { + public static class MapWrapperObject extends AbstractJSObject { + private final HashMap<String, Object> map = new LinkedHashMap<>(); + + public HashMap<String, Object> getMap() { + return map; + } + + @Override + public Object getMember(final String name) { + return map.get(name); + } + + @Override + public void setMember(final String name, final Object value) { + map.put(name, value); + } + + @Override + public boolean hasMember(final String name) { + return map.containsKey(name); + } + + @Override + public void removeMember(final String name) { + map.remove(name); + } + + @Override + public Set<String> keySet() { + return map.keySet(); + } + + @Override + public Collection<Object> values() { + return map.values(); + } + } + + @Test + // Named property access on a JSObject + public void namedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + obj.getMap().put("foo", "bar"); + + // property-like access on MapWrapperObject objects + assertEquals(e.eval("obj.foo"), "bar"); + e.eval("obj.foo = 'hello'"); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + assertEquals(e.eval("obj.foo"), "hello"); + assertEquals(obj.getMap().get("foo"), "hello"); + e.eval("delete obj.foo"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + // @bug 8062030: Nashorn bug retrieving array property after key string concatenation + @Test + // ConsString attribute access on a JSObject + public void consStringTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + e.put("obj", obj); + e.put("f", "f"); + e.eval("obj[f + 'oo'] = 'bar';"); + + assertEquals(obj.getMap().get("foo"), "bar"); + assertEquals(e.eval("obj[f + 'oo']"), "bar"); + assertEquals(e.eval("obj['foo']"), "bar"); + assertEquals(e.eval("f + 'oo' in obj"), Boolean.TRUE); + assertEquals(e.eval("'foo' in obj"), Boolean.TRUE); + e.eval("delete obj[f + 'oo']"); + assertFalse(obj.getMap().containsKey("foo")); + assertEquals(e.eval("obj[f + 'oo']"), null); + assertEquals(e.eval("obj['foo']"), null); + assertEquals(e.eval("f + 'oo' in obj"), Boolean.FALSE); + assertEquals(e.eval("'foo' in obj"), Boolean.FALSE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class BufferObject extends AbstractJSObject { + private final IntBuffer buf; + + public BufferObject(final int size) { + buf = IntBuffer.allocate(size); + } + + public IntBuffer getBuffer() { + return buf; + } + + @Override + public Object getMember(final String name) { + return name.equals("length")? buf.capacity() : null; + } + + @Override + public boolean hasSlot(final int i) { + return i > -1 && i < buf.capacity(); + } + + @Override + public Object getSlot(final int i) { + return buf.get(i); + } + + @Override + public void setSlot(final int i, final Object value) { + buf.put(i, ((Number)value).intValue()); + } + + @Override + public boolean isArray() { + return true; + } + } + + @Test + // array-like indexed access for a JSObject + public void indexedAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final BufferObject buf = new BufferObject(2); + e.put("buf", buf); + + // array-like access on BufferObject objects + assertEquals(e.eval("buf.length"), buf.getBuffer().capacity()); + e.eval("buf[0] = 23"); + assertEquals(buf.getBuffer().get(0), 23); + assertEquals(e.eval("buf[0]"), 23); + assertEquals(e.eval("buf[1]"), 0); + buf.getBuffer().put(1, 42); + assertEquals(e.eval("buf[1]"), 42); + assertEquals(e.eval("Array.isArray(buf)"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Adder extends AbstractJSObject { + @Override + public Object call(final Object thiz, final Object... args) { + double res = 0.0; + for (final Object arg : args) { + res += ((Number)arg).doubleValue(); + } + return res; + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a callable JSObject + public void callableJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("sum", new Adder()); + // check callability of Adder objects + assertEquals(e.eval("typeof sum"), "function"); + assertEquals(((Number)e.eval("sum(1, 2, 3, 4, 5)")).intValue(), 15); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + public static class Factory extends AbstractJSObject { + @SuppressWarnings("unused") + @Override + public Object newObject(final Object... args) { + return new HashMap<Object, Object>(); + } + + @Override + public boolean isFunction() { + return true; + } + } + + @Test + // a factory JSObject + public void factoryJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.put("Factory", new Factory()); + + // check new on Factory + assertEquals(e.eval("typeof Factory"), "function"); + assertEquals(e.eval("typeof new Factory()"), "object"); + assertEquals(e.eval("(new Factory()) instanceof java.util.Map"), Boolean.TRUE); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + // iteration tests + public void iteratingJSObjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final MapWrapperObject obj = new MapWrapperObject(); + obj.setMember("foo", "hello"); + obj.setMember("bar", "world"); + e.put("obj", obj); + + // check for..in + Object val = e.eval("var str = ''; for (i in obj) str += i; str"); + assertEquals(val.toString(), "foobar"); + + // check for..each..in + val = e.eval("var str = ''; for each (i in obj) str += i; str"); + assertEquals(val.toString(), "helloworld"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/ScopeTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,781 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleBindings; +import javax.script.SimpleScriptContext; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import jdk.nashorn.api.scripting.URLReader; +import org.testng.Assert; +import org.testng.annotations.Test; + +/** + * Tests for jsr223 Bindings "scope" (engine, global scopes) + */ +@SuppressWarnings("javadoc") +public class ScopeTest { + + @Test + public void createBindingsTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + b.put("foo", 42.0); + Object res = null; + try { + res = e.eval("foo == 42.0", b); + } catch (final ScriptException | NullPointerException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + + assertEquals(res, Boolean.TRUE); + } + + @Test + public void engineScopeTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings engineScope = e.getBindings(ScriptContext.ENGINE_SCOPE); + + // check few ECMA standard built-in global properties + assertNotNull(engineScope.get("Object")); + assertNotNull(engineScope.get("TypeError")); + assertNotNull(engineScope.get("eval")); + + // can access via ScriptEngine.get as well + assertNotNull(e.get("Object")); + assertNotNull(e.get("TypeError")); + assertNotNull(e.get("eval")); + + // Access by either way should return same object + assertEquals(engineScope.get("Array"), e.get("Array")); + assertEquals(engineScope.get("EvalError"), e.get("EvalError")); + assertEquals(engineScope.get("undefined"), e.get("undefined")); + + // try exposing a new variable from scope + engineScope.put("myVar", "foo"); + try { + assertEquals(e.eval("myVar"), "foo"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + + // update "myVar" in script an check the value from scope + try { + e.eval("myVar = 'nashorn';"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + + // now check modified value from scope and engine + assertEquals(engineScope.get("myVar"), "nashorn"); + assertEquals(e.get("myVar"), "nashorn"); + } + + @Test + public void multiGlobalTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + try { + final Object obj1 = e.eval("Object"); + final Object obj2 = e.eval("Object", newCtxt); + Assert.assertNotEquals(obj1, obj2); + Assert.assertNotNull(obj1); + Assert.assertNotNull(obj2); + Assert.assertEquals(obj1.toString(), obj2.toString()); + + e.eval("x = 'hello'"); + e.eval("x = 'world'", newCtxt); + Object x1 = e.getContext().getAttribute("x"); + Object x2 = newCtxt.getAttribute("x"); + Assert.assertNotEquals(x1, x2); + Assert.assertEquals(x1, "hello"); + Assert.assertEquals(x2, "world"); + + x1 = e.eval("x"); + x2 = e.eval("x", newCtxt); + Assert.assertNotEquals(x1, x2); + Assert.assertEquals(x1, "hello"); + Assert.assertEquals(x2, "world"); + + final ScriptContext origCtxt = e.getContext(); + e.setContext(newCtxt); + e.eval("y = new Object()"); + e.eval("y = new Object()", origCtxt); + + final Object y1 = origCtxt.getAttribute("y"); + final Object y2 = newCtxt.getAttribute("y"); + Assert.assertNotEquals(y1, y2); + final Object yeval1 = e.eval("y"); + final Object yeval2 = e.eval("y", origCtxt); + Assert.assertNotEquals(yeval1, yeval2); + Assert.assertEquals("[object Object]", y1.toString()); + Assert.assertEquals("[object Object]", y2.toString()); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + } + + @Test + public void userEngineScopeBindingsTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.eval("function func() {}"); + + final ScriptContext newContext = new SimpleScriptContext(); + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); + // we are using a new bindings - so it should have 'func' defined + final Object value = e.eval("typeof func", newContext); + assertTrue(value.equals("undefined")); + } + + @Test + public void userEngineScopeBindingsNoLeakTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptContext newContext = new SimpleScriptContext(); + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); + e.eval("function foo() {}", newContext); + + // in the default context's ENGINE_SCOPE, 'foo' shouldn't exist + assertTrue(e.eval("typeof foo").equals("undefined")); + } + + @Test + public void userEngineScopeBindingsRetentionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptContext newContext = new SimpleScriptContext(); + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); + e.eval("function foo() {}", newContext); + + // definition retained with user's ENGINE_SCOPE Binding + assertTrue(e.eval("typeof foo", newContext).equals("function")); + + final Bindings oldBindings = newContext.getBindings(ScriptContext.ENGINE_SCOPE); + // but not in another ENGINE_SCOPE binding + newContext.setBindings(new SimpleBindings(), ScriptContext.ENGINE_SCOPE); + assertTrue(e.eval("typeof foo", newContext).equals("undefined")); + + // restore ENGINE_SCOPE and check again + newContext.setBindings(oldBindings, ScriptContext.ENGINE_SCOPE); + assertTrue(e.eval("typeof foo", newContext).equals("function")); + } + + @Test + // check that engine.js definitions are visible in all new global instances + public void checkBuiltinsInNewBindingsTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + // check default global instance has engine.js definitions + final Bindings g = (Bindings) e.eval("this"); + Object value = g.get("__noSuchProperty__"); + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); + value = g.get("print"); + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); + + // check new global instance created has engine.js definitions + final Bindings b = e.createBindings(); + value = b.get("__noSuchProperty__"); + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); + value = b.get("print"); + assertTrue(value instanceof ScriptObjectMirror && ((ScriptObjectMirror)value).isFunction()); + + // put a mapping into GLOBAL_SCOPE + final Bindings globalScope = e.getContext().getBindings(ScriptContext.GLOBAL_SCOPE); + globalScope.put("x", "hello"); + + // GLOBAL_SCOPE mapping should be visible from default ScriptContext eval + assertTrue(e.eval("x").equals("hello")); + + final ScriptContext ctx = new SimpleScriptContext(); + ctx.setBindings(globalScope, ScriptContext.GLOBAL_SCOPE); + ctx.setBindings(b, ScriptContext.ENGINE_SCOPE); + + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval + assertTrue(e.eval("x", ctx).equals("hello")); + + // try some arbitray Bindings for ENGINE_SCOPE + final Bindings sb = new SimpleBindings(); + ctx.setBindings(sb, ScriptContext.ENGINE_SCOPE); + + // GLOBAL_SCOPE mapping should be visible from non-default ScriptContext eval + assertTrue(e.eval("x", ctx).equals("hello")); + + // engine.js builtins are still defined even with arbitrary Bindings + assertTrue(e.eval("typeof print", ctx).equals("function")); + assertTrue(e.eval("typeof __noSuchProperty__", ctx).equals("function")); + + // ENGINE_SCOPE definition should 'hide' GLOBAL_SCOPE definition + sb.put("x", "newX"); + assertTrue(e.eval("x", ctx).equals("newX")); + } + + /** + * Test multi-threaded access to defined global variables for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedVarTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + final String sharedScript = "foo"; + + assertEquals(e.eval("var foo = 'original context';", origContext), null); + assertEquals(e.eval("var foo = 'new context';", newCtxt), null); + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + assertEquals(e.eval("var foo = 'newer context';", newCtxt), null); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + + assertEquals(e.eval(sharedScript), "original context"); + assertEquals(e.eval(sharedScript, newCtxt), "newer context"); + } + + /** + * Test multi-threaded access to undefined global variables for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedGlobalTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + assertEquals(e.eval("foo = 'original context';", origContext), "original context"); + assertEquals(e.eval("foo = 'new context';", newCtxt), "new context"); + final String sharedScript = "foo"; + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + final Object obj3 = e.eval("delete foo; foo = 'newer context';", newCtxt); + assertEquals(obj3, "newer context"); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + + Assert.assertEquals(e.eval(sharedScript), "original context"); + Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context"); + } + + /** + * Test multi-threaded access using the postfix ++ operator for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedIncTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + assertEquals(e.eval("var x = 0;", origContext), null); + assertEquals(e.eval("var x = 2;", newCtxt), null); + final String sharedScript = "x++;"; + + final Thread t1 = new Thread(new Runnable() { + @Override + public void run() { + try { + for (int i = 0; i < 1000; i++) { + assertEquals(e.eval(sharedScript, origContext), (double)i); + } + } catch (final ScriptException se) { + fail(se.toString()); + } + } + }); + final Thread t2 = new Thread(new Runnable() { + @Override + public void run() { + try { + for (int i = 2; i < 1000; i++) { + assertEquals(e.eval(sharedScript, newCtxt), (double)i); + } + } catch (final ScriptException se) { + fail(se.toString()); + } + } + }); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + } + + /** + * Test multi-threaded access to primitive prototype properties for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedPrimitiveTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + final Object obj1 = e.eval("String.prototype.foo = 'original context';", origContext); + final Object obj2 = e.eval("String.prototype.foo = 'new context';", newCtxt); + assertEquals(obj1, "original context"); + assertEquals(obj2, "new context"); + final String sharedScript = "''.foo"; + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); + assertEquals(obj3, "newer context"); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + + Assert.assertEquals(e.eval(sharedScript), "original context"); + Assert.assertEquals(e.eval(sharedScript, newCtxt), "newer context"); + } + + + /** + * Test multi-threaded access to prototype user accessor properties for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedAccessorTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'original context' })", origContext); + e.eval("Object.defineProperty(Object.prototype, 'foo', { get: function() 'new context', configurable: true })", newCtxt); + final String sharedScript = "({}).foo"; + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + final Object obj3 = e.eval("delete Object.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); + assertEquals(obj3, "newer context"); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + } + + /** + * Test multi-threaded access to primitive prototype user accessor properties for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedPrimitiveAccessorTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'original context' })", origContext); + e.eval("Object.defineProperty(String.prototype, 'foo', { get: function() 'new context' })", newCtxt); + final String sharedScript = "''.foo"; + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + final Object obj3 = e.eval("delete String.prototype.foo; Object.prototype.foo = 'newer context';", newCtxt); + assertEquals(obj3, "newer context"); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + } + + /** + * Test multi-threaded scope function invocation for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedFunctionTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), origContext); + assertEquals(origContext.getAttribute("scopeVar"), 1); + assertEquals(e.eval("scopeTest()"), 1); + + e.eval(new URLReader(ScopeTest.class.getResource("resources/func.js")), newCtxt); + assertEquals(newCtxt.getAttribute("scopeVar"), 1); + assertEquals(e.eval("scopeTest();", newCtxt), 1); + + assertEquals(e.eval("scopeVar = 3;", newCtxt), 3); + assertEquals(newCtxt.getAttribute("scopeVar"), 3); + + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, "scopeTest()", 1, 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, "scopeTest()", 3, 1000)); + + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + } + + /** + * Test multi-threaded access to global getters and setters for shared script classes with multiple globals. + */ + @Test + public static void getterSetterTest() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + final String sharedScript = "accessor1"; + + e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext); + assertEquals(e.eval("accessor1 = 1;"), 1); + assertEquals(e.eval(sharedScript), 1); + + e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt); + assertEquals(e.eval("accessor1 = 2;", newCtxt), 2); + assertEquals(e.eval(sharedScript, newCtxt), 2); + + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000)); + + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + assertEquals(e.eval(sharedScript), 1); + assertEquals(e.eval(sharedScript, newCtxt), 2); + assertEquals(e.eval("v"), 1); + assertEquals(e.eval("v", newCtxt), 2); + } + + /** + * Test multi-threaded access to global getters and setters for shared script classes with multiple globals. + */ + @Test + public static void getterSetter2Test() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + final String sharedScript = "accessor2"; + + e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), origContext); + assertEquals(e.eval("accessor2 = 1;"), 1); + assertEquals(e.eval(sharedScript), 1); + + e.eval(new URLReader(ScopeTest.class.getResource("resources/gettersetter.js")), newCtxt); + assertEquals(e.eval("accessor2 = 2;", newCtxt), 2); + assertEquals(e.eval(sharedScript, newCtxt), 2); + + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, 1, 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, 2, 1000)); + + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + assertEquals(e.eval(sharedScript), 1); + assertEquals(e.eval(sharedScript, newCtxt), 2); + assertEquals(e.eval("x"), 1); + assertEquals(e.eval("x", newCtxt), 2); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void contextOverwriteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = new SimpleBindings(); + b.put("context", "hello"); + b.put("foo", 32); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + e.setContext(newCtxt); + assertEquals(e.eval("context"), "hello"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void contextOverwriteInScriptTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put("foo", 32); + + assertEquals(((Number)e.eval("foo")).intValue(), 32); + assertEquals(e.eval("context = 'bar'"), "bar"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void engineOverwriteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Bindings b = new SimpleBindings(); + b.put("engine", "hello"); + b.put("foo", 32); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + e.setContext(newCtxt); + assertEquals(e.eval("engine"), "hello"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8058422: Users should be able to overwrite "context" and "engine" variables + @Test + public static void engineOverwriteInScriptTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put("foo", 32); + + assertEquals(((Number)e.eval("foo")).intValue(), 32); + assertEquals(e.eval("engine = 'bar'"), "bar"); + assertEquals(((Number)e.eval("foo")).intValue(), 32); + } + + // @bug 8044750: megamorphic getter for scope objects does not call __noSuchProperty__ hook + @Test + public static void testMegamorphicGetInGlobal() throws Exception { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("nashorn"); + final String script = "foo"; + // "foo" is megamorphic because of different global scopes. + // Make sure ScriptContext variable search works even after + // it becomes megamorphic. + for (int index = 0; index < 25; index++) { + final Bindings bindings = new SimpleBindings(); + bindings.put("foo", index); + final Number value = (Number)engine.eval(script, bindings); + assertEquals(index, value.intValue()); + } + } + + /** + * Test "slow" scopes involving {@code with} and {@code eval} statements for shared script classes with multiple globals. + * @throws ScriptException + * @throws InterruptedException + */ + @Test + public static void testSlowScope() throws ScriptException, InterruptedException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + for (int i = 0; i < 100; i++) { + final Bindings b = e.createBindings(); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + + e.eval(new URLReader(ScopeTest.class.getResource("resources/witheval.js")), ctxt); + assertEquals(e.eval("a", ctxt), 1); + assertEquals(b.get("a"), 1); + assertEquals(e.eval("b", ctxt), 3); + assertEquals(b.get("b"), 3); + assertEquals(e.eval("c", ctxt), 10); + assertEquals(b.get("c"), 10); + } + } + + private static class ScriptRunner implements Runnable { + + final ScriptEngine engine; + final ScriptContext context; + final String source; + final Object expected; + final int iterations; + + ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) { + this.engine = engine; + this.context = context; + this.source = source; + this.expected = expected; + this.iterations = iterations; + } + + @Override + public void run() { + try { + for (int i = 0; i < iterations; i++) { + assertEquals(engine.eval(source, context), expected); + } + } catch (final ScriptException se) { + throw new RuntimeException(se); + } + } + } + + // @bug 8071678: NashornScriptEngine returns javax.script.ScriptContext instance + // with get/setAttribute methods insonsistent for GLOBAL_SCOPE + @Test + public void testGlobalScopeSearch() throws Exception { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptContext c = e.getContext(); + c.setAttribute("name1234", "value", ScriptContext.GLOBAL_SCOPE); + assertEquals(c.getAttribute("name1234"), "value"); + assertEquals(c.getAttributesScope("name1234"), + ScriptContext.GLOBAL_SCOPE); + } + + // @bug 8071594: NashornScriptEngine returns javax.script.ScriptContext instance + // which doesn't completely conform to the spec regarding exceptions throwing + @Test + public void testScriptContext_NPE_IAE() throws Exception { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptContext c = e.getContext(); + try { + c.getAttribute(""); + throw new AssertionError("should have thrown IAE"); + } catch (IllegalArgumentException iae1) {} + + try { + c.getAttribute(null); + throw new AssertionError("should have thrown NPE"); + } catch (NullPointerException npe1) {} + + try { + c.getAttribute("", ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown IAE"); + } catch (IllegalArgumentException iae2) {} + + try { + c.getAttribute(null, ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown NPE"); + } catch (NullPointerException npe2) {} + + try { + c.removeAttribute("", ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown IAE"); + } catch (IllegalArgumentException iae3) {} + + try { + c.removeAttribute(null, ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown NPE"); + } catch (NullPointerException npe3) {} + + try { + c.setAttribute("", "value", ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown IAE"); + } catch (IllegalArgumentException iae4) {} + + try { + c.setAttribute(null, "value", ScriptContext.ENGINE_SCOPE); + throw new AssertionError("should have thrown NPE"); + } catch (NullPointerException npe4) {} + + try { + c.getAttributesScope(""); + throw new AssertionError("should have thrown IAE"); + } catch (IllegalArgumentException iae5) {} + + try { + c.getAttributesScope(null); + throw new AssertionError("should have thrown NPE"); + } catch (NullPointerException npe5) {} + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/ScriptEngineSecurityTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,313 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.fail; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.ClassFilter; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import org.testng.annotations.Test; + +/** + * jsr223 tests for security access checks. + */ +@SuppressWarnings("javadoc") +public class ScriptEngineSecurityTest { + + private static void log(final String msg) { + org.testng.Reporter.log(msg, true); + } + + @Test + public void securityPackagesTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("var v = Packages.sun.misc.Unsafe;"); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (exp instanceof SecurityException) { + log("got " + exp + " as expected"); + } else { + fail(exp.getMessage()); + } + } + } + + @Test + public void securityJavaTypeTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("var v = Java.type('sun.misc.Unsafe');"); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (exp instanceof SecurityException) { + log("got " + exp + " as expected"); + } else { + fail(exp.getMessage()); + } + } + } + + @Test + public void securityClassForNameTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');"); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (exp instanceof SecurityException) { + log("got " + exp + " as expected"); + } else { + fail(exp.getMessage()); + } + } + } + + @Test + public void securitySystemExit() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("java.lang.System.exit(0);"); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (exp instanceof SecurityException) { + log("got " + exp + " as expected"); + } else { + fail(exp.getMessage()); + } + } + } + + + @Test + public void securitySystemExitFromFinalizerThread() throws ScriptException { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" + + "new o(new java.util.ArrayList().iterator())"); + System.gc(); + System.runFinalization(); + // NOTE: this test just exits the VM if it fails. + } + + @Test + public void securitySystemLoadLibrary() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("java.lang.System.loadLibrary('foo');"); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (exp instanceof SecurityException) { + log("got " + exp + " as expected"); + } else { + fail(exp.getMessage()); + } + } + } + + // @bug 8032948: Nashorn linkages awry + @SuppressWarnings("serial") + public static class FakeProxy extends Proxy { + public FakeProxy(final InvocationHandler ih) { + super(ih); + } + + public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) { + return Proxy.getProxyClass(cl, ifaces); + } + } + + @Test + public void fakeProxySubclassAccessCheckTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + e.put("name", ScriptEngineSecurityTest.class.getName()); + e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); + e.put("intfs", new Class[] { Runnable.class }); + + final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);"; + + // Should not be able to call static methods of Proxy via fake subclass + try { + e.eval(getClass); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (! (exp instanceof SecurityException)) { + fail("SecurityException expected, got " + exp); + } + } + } + + @Test + public void fakeProxySubclassAccessCheckTest2() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + e.put("name", ScriptEngineSecurityTest.class.getName()); + e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); + e.put("intfs", new Class[] { Runnable.class }); + + final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);"; + + // Should not be able to call static methods of Proxy via fake subclass + try { + e.eval(getClass); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (! (exp instanceof SecurityException)) { + fail("SecurityException expected, got " + exp); + } + } + } + + @Test + public static void proxyStaticAccessCheckTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Runnable r = (Runnable)Proxy.newProxyInstance( + ScriptEngineTest.class.getClassLoader(), + new Class[] { Runnable.class }, + new InvocationHandler() { + @Override + public Object invoke(final Object p, final Method mtd, final Object[] a) { + return null; + } + }); + + e.put("rc", r.getClass()); + e.put("cl", ScriptEngineSecurityTest.class.getClassLoader()); + e.put("intfs", new Class[] { Runnable.class }); + + // make sure static methods of Proxy is not accessible via subclass + try { + e.eval("rc.static.getProxyClass(cl, intfs)"); + fail("Should have thrown SecurityException"); + } catch (final Exception exp) { + if (! (exp instanceof SecurityException)) { + fail("SecurityException expected, got " + exp); + } + } + } + + + @Test + public void nashornConfigSecurityTest() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine(new ClassFilter() { + @Override + public boolean exposeToScripts(final String name) { + return true; + } + }); + fail("SecurityException should have been thrown"); + } catch (final SecurityException e) { + //empty + } + } + + @Test + public void nashornConfigSecurityTest2() { + if (System.getSecurityManager() == null) { + // pass vacuously + return; + } + + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine(new String[0], null, new ClassFilter() { + @Override + public boolean exposeToScripts(final String name) { + return true; + } + }); + fail("SecurityException should have been thrown"); + } catch (final SecurityException e) { + //empty + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/ScriptEngineTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,916 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertNull; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.io.StringReader; +import java.io.StringWriter; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.Collections; +import java.util.concurrent.Callable; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import java.util.function.Function; +import javax.script.Bindings; +import javax.script.Compilable; +import javax.script.CompiledScript; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import org.testng.annotations.Test; + +/** + * Tests for JSR-223 script engine for Nashorn. + * + * @test + * @build jdk.nashorn.api.scripting.test.Window jdk.nashorn.api.scripting.test.WindowEventHandler jdk.nashorn.api.scripting.test.VariableArityTestInterface jdk.nashorn.api.scripting.test.ScriptEngineTest + * @run testng/othervm jdk.nashorn.api.scripting.test.ScriptEngineTest + */ +@SuppressWarnings("javadoc") +public class ScriptEngineTest { + + private static void log(final String msg) { + org.testng.Reporter.log(msg, true); + } + + @Test + public void argumentsTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + final String[] args = new String[] { "hello", "world" }; + try { + e.put("arguments", args); + final Object arg0 = e.eval("arguments[0]"); + final Object arg1 = e.eval("arguments[1]"); + assertEquals(args[0], arg0); + assertEquals(args[1], arg1); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void argumentsWithTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + final String[] args = new String[] { "hello", "world" }; + try { + e.put("arguments", args); + final Object arg0 = e.eval("var imports = new JavaImporter(java.io); " + + " with(imports) { arguments[0] }"); + final Object arg1 = e.eval("var imports = new JavaImporter(java.util, java.io); " + + " with(imports) { arguments[1] }"); + assertEquals(args[0], arg0); + assertEquals(args[1], arg1); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void argumentsEmptyTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + assertEquals(e.eval("arguments instanceof Array"), true); + assertEquals(e.eval("arguments.length == 0"), true); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void factoryTests() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + assertNotNull(e); + + final ScriptEngineFactory fac = e.getFactory(); + + assertEquals(fac.getLanguageName(), "ECMAScript"); + assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); + assertEquals(fac.getLanguageVersion(), "ECMA - 262 Edition 5.1"); + assertEquals(fac.getEngineName(), "Oracle Nashorn"); + assertEquals(fac.getOutputStatement("context"), "print(context)"); + assertEquals(fac.getProgram("print('hello')", "print('world')"), "print('hello');print('world');"); + assertEquals(fac.getParameter(ScriptEngine.NAME), "javascript"); + + boolean seenJS = false; + for (final String ext : fac.getExtensions()) { + if (ext.equals("js")) { + seenJS = true; + } + } + + assertEquals(seenJS, true); + final String str = fac.getMethodCallSyntax("obj", "foo", "x"); + assertEquals(str, "obj.foo(x)"); + + boolean seenNashorn = false, seenJavaScript = false, seenECMAScript = false; + for (final String name : fac.getNames()) { + switch (name) { + case "nashorn": seenNashorn = true; break; + case "javascript": seenJavaScript = true; break; + case "ECMAScript": seenECMAScript = true; break; + default: + break; + } + } + + assertTrue(seenNashorn); + assertTrue(seenJavaScript); + assertTrue(seenECMAScript); + + boolean seenAppJS = false, seenAppECMA = false, seenTextJS = false, seenTextECMA = false; + for (final String mime : fac.getMimeTypes()) { + switch (mime) { + case "application/javascript": seenAppJS = true; break; + case "application/ecmascript": seenAppECMA = true; break; + case "text/javascript": seenTextJS = true; break; + case "text/ecmascript": seenTextECMA = true; break; + default: + break; + } + } + + assertTrue(seenAppJS); + assertTrue(seenAppECMA); + assertTrue(seenTextJS); + assertTrue(seenTextECMA); + } + + @Test + public void evalTests() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put(ScriptEngine.FILENAME, "myfile.js"); + + try { + e.eval("print('hello')"); + } catch (final ScriptException se) { + fail(se.getMessage()); + } + try { + e.eval("print('hello)"); + fail("script exception expected"); + } catch (final ScriptException se) { + assertEquals(se.getLineNumber(), 1); + assertEquals(se.getColumnNumber(), 13); + assertEquals(se.getFileName(), "myfile.js"); + // se.printStackTrace(); + } + + try { + Object obj = e.eval("34 + 41"); + assertTrue(34.0 + 41.0 == ((Number)obj).doubleValue()); + obj = e.eval("x = 5"); + assertTrue(5.0 == ((Number)obj).doubleValue()); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + } + + @Test + public void compileTests() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + CompiledScript script = null; + + try { + script = ((Compilable)e).compile("print('hello')"); + } catch (final ScriptException se) { + fail(se.getMessage()); + } + + try { + script.eval(); + } catch (final ScriptException | NullPointerException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + + // try to compile from a Reader + try { + script = ((Compilable)e).compile(new StringReader("print('world')")); + } catch (final ScriptException se) { + fail(se.getMessage()); + } + + try { + script.eval(); + } catch (final ScriptException | NullPointerException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + } + + @Test + public void compileAndEvalInDiffContextTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("js"); + final Compilable compilable = (Compilable) engine; + final CompiledScript compiledScript = compilable.compile("foo"); + final ScriptContext ctxt = new SimpleScriptContext(); + ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE); + assertEquals(compiledScript.eval(ctxt), "hello"); + } + + @Test + public void accessGlobalTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + e.eval("var x = 'hello'"); + assertEquals(e.get("x"), "hello"); + } catch (final ScriptException exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void exposeGlobalTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + e.put("y", "foo"); + e.eval("print(y)"); + } catch (final ScriptException exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void putGlobalFunctionTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + e.put("callable", new Callable<String>() { + @Override + public String call() throws Exception { + return "callable was called"; + } + }); + + try { + e.eval("print(callable.call())"); + } catch (final ScriptException exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void windowAlertTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Window window = new Window(); + + try { + e.put("window", window); + e.eval("print(window.alert)"); + e.eval("window.alert('calling window.alert...')"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void windowLocationTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Window window = new Window(); + + try { + e.put("window", window); + e.eval("print(window.location)"); + final Object locationValue = e.eval("window.getLocation()"); + assertEquals(locationValue, "http://localhost:8080/window"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void windowItemTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Window window = new Window(); + + try { + e.put("window", window); + final String item1 = (String)e.eval("window.item(65535)"); + assertEquals(item1, "ffff"); + final String item2 = (String)e.eval("window.item(255)"); + assertEquals(item2, "ff"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void windowEventTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Window window = new Window(); + + try { + e.put("window", window); + e.eval("window.onload = function() { print('window load event fired'); return true }"); + assertTrue((Boolean)e.eval("window.onload.loaded()")); + final WindowEventHandler handler = window.getOnload(); + assertNotNull(handler); + assertTrue(handler.loaded()); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void throwTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.put(ScriptEngine.FILENAME, "throwtest.js"); + + try { + e.eval("throw 'foo'"); + } catch (final ScriptException exp) { + log(exp.getMessage()); + assertEquals(exp.getMessage(), "foo in throwtest.js at line number 1 at column number 0"); + assertEquals(exp.getFileName(), "throwtest.js"); + assertEquals(exp.getLineNumber(), 1); + } + } + + @Test + public void setTimeoutTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Window window = new Window(); + + try { + final Class<?> setTimeoutParamTypes[] = { Window.class, String.class, int.class }; + final Method setTimeout = Window.class.getDeclaredMethod("setTimeout", setTimeoutParamTypes); + assertNotNull(setTimeout); + e.put("window", window); + e.eval("window.setTimeout('foo()', 100)"); + + // try to make setTimeout global + e.put("setTimeout", setTimeout); + // TODO: java.lang.ClassCastException: required class + // java.lang.Integer but encountered class java.lang.Double + // e.eval("setTimeout('foo2()', 200)"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void setWriterTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final StringWriter sw = new StringWriter(); + e.getContext().setWriter(sw); + + try { + e.eval("print('hello world')"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + assertEquals(sw.toString(), println("hello world")); + } + + @Test + public void redefineEchoTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + try { + e.eval("var echo = {}; if (typeof echo !== 'object') { throw 'echo is a '+typeof echo; }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + @Test + public void noEnumerablePropertiesTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("for (i in this) { throw 'found property: ' + i }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void noRefErrorForGlobalThisAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("this.foo"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void refErrorForUndeclaredAccessTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("try { print(foo); throw 'no ref error' } catch (e) { if (!(e instanceof ReferenceError)) throw e; }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void typeErrorForGlobalThisCallTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("try { this.foo() } catch(e) { if (! (e instanceof TypeError)) throw 'no type error' }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void refErrorForUndeclaredCallTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("try { foo() } catch(e) { if (! (e instanceof ReferenceError)) throw 'no ref error' }"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + // check that print function prints arg followed by newline char + public void printTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final StringWriter sw = new StringWriter(); + e.getContext().setWriter(sw); + try { + e.eval("print('hello')"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + + assertEquals(sw.toString(), println("hello")); + } + + @Test + // check that print prints all arguments (more than one) + public void printManyTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final StringWriter sw = new StringWriter(); + e.getContext().setWriter(sw); + try { + e.eval("print(34, true, 'hello')"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + + assertEquals(sw.toString(), println("34 true hello")); + } + + @Test + public void scriptObjectAutoConversionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.eval("obj = { foo: 'hello' }"); + e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.test.Window")); + assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); + assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello"); + assertEquals(e.eval("Window.funcMap(obj)"), "hello"); + assertEquals(e.eval("Window.funcJSObject(obj)"), "hello"); + } + + // @bug 8032948: Nashorn linkages awry + @Test + public void checkProxyAccess() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final boolean[] reached = new boolean[1]; + final Runnable r = (Runnable)Proxy.newProxyInstance( + ScriptEngineTest.class.getClassLoader(), + new Class[] { Runnable.class }, + new InvocationHandler() { + @Override + public Object invoke(final Object p, final Method mtd, final Object[] a) { + reached[0] = true; + return null; + } + }); + + e.put("r", r); + e.eval("r.run()"); + + assertTrue(reached[0]); + } + + // properties that can be read by any code + private static String[] propNames = { + "java.version", + "java.vendor", + "java.vendor.url", + "java.class.version", + "os.name", + "os.version", + "os.arch", + "file.separator", + "path.separator", + "line.separator", + "java.specification.version", + "java.specification.vendor", + "java.specification.name", + "java.vm.specification.version", + "java.vm.specification.vendor", + "java.vm.specification.name", + "java.vm.version", + "java.vm.vendor", + "java.vm.name" + }; + + // @bug 8033924: Default permissions are not given for eval code + @Test + public void checkPropertyReadPermissions() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + for (final String name : propNames) { + checkProperty(e, name); + } + } + + // @bug 8046013: TypeError: Cannot apply "with" to non script object + @Test + public void withOnMirrorTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + final Object obj = e.eval("({ foo: 'hello'})"); + final Object[] arr = new Object[1]; + arr[0] = obj; + e.put("arr", arr); + final Object res = e.eval("var res; with(arr[0]) { res = foo; }; res"); + assertEquals(res, "hello"); + } + + // @bug 8054223: Nashorn: AssertionError when use __DIR__ and ScriptEngine.eval() + @Test + public void check__DIR__Test() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + e.eval("__DIR__"); + } + + // @bug 8050432:javax.script.filename variable should not be enumerable + // with nashorn engine's ENGINE_SCOPE bindings + @Test + public void enumerableGlobalsTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + e.put(ScriptEngine.FILENAME, "test"); + final Object enumerable = e.eval( + "Object.getOwnPropertyDescriptor(this, " + + " 'javax.script.filename').enumerable"); + assertEquals(enumerable, Boolean.FALSE); + } + + public static class Context { + private Object myobj; + + public void set(final Object o) { + myobj = o; + } + + public Object get() { + return myobj; + } + } + + // @bug 8050977: Java8 Javascript Nashorn exception: + // no current Global instance for nashorn + @Test + public void currentGlobalMissingTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + + final Context ctx = new Context(); + e.put("ctx", ctx); + e.eval("var obj = { foo: function(str) { return str.toUpperCase() } }"); + e.eval("ctx.set(obj)"); + final Invocable inv = (Invocable)e; + assertEquals("HELLO", inv.invokeMethod(ctx.get(), "foo", "hello")); + // try object literal + e.eval("ctx.set({ bar: function(str) { return str.toLowerCase() } })"); + assertEquals("hello", inv.invokeMethod(ctx.get(), "bar", "HELLO")); + // try array literal + e.eval("var arr = [ 'hello', 'world' ]"); + e.eval("ctx.set(arr)"); + assertEquals("helloworld", inv.invokeMethod(ctx.get(), "join", "")); + } + + // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. + @Test + public void functionalInterfaceStringTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("f", new Function<String, String>() { + @Override + public String apply(String t) { + invoked.set(true); + return t; + } + }); + assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); + assertTrue(invoked.get()); + } + + // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. + @Test + public void functionalInterfaceObjectTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("c", new Consumer<Object>() { + @Override + public void accept(Object t) { + assertTrue(t instanceof ScriptObjectMirror); + assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); + invoked.set(true); + } + }); + e.eval("var x = 'xy'; x += 'z';c({a:x})"); + assertTrue(invoked.get()); + } + + // @bug 8068524: NashornScriptEngineFactory.getParameter() throws IAE + // for an unknown key, doesn't conform to the general spec + @Test + public void getParameterInvalidKeyTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + // no exception expected here! + Object value = e.getFactory().getParameter("no value assigned to this key"); + assertNull(value); + } + + // @bug JDK-8068889: ConsString arguments to a functional interface wasn't converted to string. + @Test + public void functionalInterfaceStringTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("f", new Function<String, String>() { + @Override + public String apply(String t) { + invoked.set(true); + return t; + } + }); + assertEquals(e.eval("var x = 'a'; x += 'b'; f(x)"), "ab"); + assertTrue(invoked.get()); + } + + // @bug JDK-8068889: ScriptObject arguments to a functional interface wasn't converted to a mirror. + @Test + public void functionalInterfaceObjectTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final AtomicBoolean invoked = new AtomicBoolean(false); + e.put("c", new Consumer<Object>() { + @Override + public void accept(Object t) { + assertTrue(t instanceof ScriptObjectMirror); + assertEquals(((ScriptObjectMirror)t).get("a"), "xyz"); + invoked.set(true); + } + }); + e.eval("var x = 'xy'; x += 'z';c({a:x})"); + assertTrue(invoked.get()); + } + + @Test + public void testLengthOnArrayLikeObjects() throws Exception { + final ScriptEngine e = new ScriptEngineManager().getEngineByName("nashorn"); + final Object val = e.eval("var arr = { length: 1, 0: 1}; arr.length"); + + assertTrue(Number.class.isAssignableFrom(val.getClass())); + assertTrue(((Number)val).intValue() == 1); + } + + // @bug JDK-8068603: NashornScriptEngine.put/get() impls don't conform to NPE, IAE spec assertions + @Test + public void illegalBindingsValuesTest() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + + try { + e.put(null, "null-value"); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + e.put("", "empty-value"); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + + final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE); + assertTrue(b instanceof ScriptObjectMirror); + + try { + b.put(null, "null-value"); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.put("", "empty-value"); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + + try { + b.get(null); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.get(""); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + + try { + b.get(1); + fail(); + } catch (ClassCastException x) { + // expected + } + + try { + b.remove(null); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.remove(""); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + + try { + b.remove(1); + fail(); + } catch (ClassCastException x) { + // expected + } + + try { + b.containsKey(null); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.containsKey(""); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + + try { + b.containsKey(1); + fail(); + } catch (ClassCastException x) { + // expected + } + + try { + b.putAll(null); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.putAll(Collections.singletonMap((String)null, "null-value")); + fail(); + } catch (NullPointerException x) { + // expected + } + + try { + b.putAll(Collections.singletonMap("", "empty-value")); + fail(); + } catch (IllegalArgumentException x) { + // expected + } + } + + // @bug 8071989: NashornScriptEngine returns javax.script.ScriptContext instance + // with insonsistent get/remove methods behavior for undefined attributes + @Test + public void testScriptContextGetRemoveUndefined() throws Exception { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine e = manager.getEngineByName("nashorn"); + final ScriptContext ctx = e.getContext(); + assertNull(ctx.getAttribute("undefinedname", ScriptContext.ENGINE_SCOPE)); + assertNull(ctx.removeAttribute("undefinedname", ScriptContext.ENGINE_SCOPE)); + } + + private static void checkProperty(final ScriptEngine e, final String name) + throws ScriptException { + final String value = System.getProperty(name); + e.put("name", name); + assertEquals(value, e.eval("java.lang.System.getProperty(name)")); + } + + private static final String LINE_SEPARATOR = System.getProperty("line.separator"); + + // Returns String that would be the result of calling PrintWriter.println + // of the given String. (This is to handle platform specific newline). + private static String println(final String str) { + return str + LINE_SEPARATOR; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,389 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; + +import java.nio.ByteBuffer; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Function; +import javax.script.Bindings; +import javax.script.Invocable; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; +import org.testng.annotations.Test; + +/** + * Tests to check jdk.nashorn.api.scripting.ScriptObjectMirror API. + */ +@SuppressWarnings("javadoc") +public class ScriptObjectMirrorTest { + + @SuppressWarnings("unchecked") + @Test + public void reflectionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + + e.eval("var obj = { x: 344, y: 'nashorn' }"); + + int count = 0; + Map<Object, Object> map = (Map<Object, Object>) e.get("obj"); + assertFalse(map.isEmpty()); + assertTrue(map.keySet().contains("x")); + assertTrue(map.containsKey("x")); + assertTrue(map.values().contains("nashorn")); + assertTrue(map.containsValue("nashorn")); + for (final Map.Entry<?, ?> ex : map.entrySet()) { + final Object key = ex.getKey(); + if (key.equals("x")) { + assertTrue(344 == ((Number) ex.getValue()).doubleValue()); + count++; + } else if (key.equals("y")) { + assertEquals(ex.getValue(), "nashorn"); + count++; + } + } + assertEquals(2, count); + assertEquals(2, map.size()); + + // add property + map.put("z", "hello"); + assertEquals(e.eval("obj.z"), "hello"); + assertEquals(map.get("z"), "hello"); + assertTrue(map.keySet().contains("z")); + assertTrue(map.containsKey("z")); + assertTrue(map.values().contains("hello")); + assertTrue(map.containsValue("hello")); + assertEquals(map.size(), 3); + + final Map<Object, Object> newMap = new HashMap<>(); + newMap.put("foo", 23.0); + newMap.put("bar", true); + map.putAll(newMap); + + assertEquals(e.eval("obj.foo"), 23.0); + assertEquals(e.eval("obj.bar"), true); + + // remove using map method + map.remove("foo"); + assertEquals(e.eval("typeof obj.foo"), "undefined"); + + count = 0; + e.eval("var arr = [ true, 'hello' ]"); + map = (Map<Object, Object>) e.get("arr"); + assertFalse(map.isEmpty()); + assertTrue(map.containsKey("length")); + assertTrue(map.containsValue("hello")); + for (final Map.Entry<?, ?> ex : map.entrySet()) { + final Object key = ex.getKey(); + if (key.equals("0")) { + assertEquals(ex.getValue(), Boolean.TRUE); + count++; + } else if (key.equals("1")) { + assertEquals(ex.getValue(), "hello"); + count++; + } + } + assertEquals(count, 2); + assertEquals(map.size(), 2); + + // add element + map.put("2", "world"); + assertEquals(map.get("2"), "world"); + assertEquals(map.size(), 3); + + // remove all + map.clear(); + assertTrue(map.isEmpty()); + assertEquals(e.eval("typeof arr[0]"), "undefined"); + assertEquals(e.eval("typeof arr[1]"), "undefined"); + assertEquals(e.eval("typeof arr[2]"), "undefined"); + } + + @Test + public void jsobjectTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + e.eval("var obj = { '1': 'world', func: function() { return this.bar; }, bar: 'hello' }"); + final ScriptObjectMirror obj = (ScriptObjectMirror) e.get("obj"); + + // try basic get on existing properties + if (!obj.getMember("bar").equals("hello")) { + fail("obj.bar != 'hello'"); + } + + if (!obj.getSlot(1).equals("world")) { + fail("obj[1] != 'world'"); + } + + if (!obj.callMember("func", new Object[0]).equals("hello")) { + fail("obj.func() != 'hello'"); + } + + // try setting properties + obj.setMember("bar", "new-bar"); + obj.setSlot(1, "new-element-1"); + if (!obj.getMember("bar").equals("new-bar")) { + fail("obj.bar != 'new-bar'"); + } + + if (!obj.getSlot(1).equals("new-element-1")) { + fail("obj[1] != 'new-element-1'"); + } + + // try adding properties + obj.setMember("prop", "prop-value"); + obj.setSlot(12, "element-12"); + if (!obj.getMember("prop").equals("prop-value")) { + fail("obj.prop != 'prop-value'"); + } + + if (!obj.getSlot(12).equals("element-12")) { + fail("obj[12] != 'element-12'"); + } + + // delete properties + obj.removeMember("prop"); + if ("prop-value".equals(obj.getMember("prop"))) { + fail("obj.prop is not deleted!"); + } + + // Simple eval tests + assertEquals(obj.eval("typeof Object"), "function"); + assertEquals(obj.eval("'nashorn'.substring(3)"), "horn"); + } catch (final Exception exp) { + exp.printStackTrace(); + fail(exp.getMessage()); + } + } + + @Test + public void scriptObjectMirrorToStringTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + try { + final Object obj = e.eval("new TypeError('wrong type')"); + assertEquals(obj.toString(), "TypeError: wrong type", "toString returns wrong value"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + + try { + final Object obj = e.eval("function func() { print('hello'); }"); + assertEquals(obj.toString(), "function func() { print('hello'); }", "toString returns wrong value"); + } catch (final Throwable t) { + t.printStackTrace(); + fail(t.getMessage()); + } + } + + @Test + public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptEngine e2 = m.getEngineByName("nashorn"); + + e.eval("function func() {}"); + e2.put("foo", e.get("func")); + final ScriptObjectMirror e2global = (ScriptObjectMirror)e2.eval("this"); + final Object newObj = ((ScriptObjectMirror)e2global.getMember("foo")).newObject(); + assertTrue(newObj instanceof ScriptObjectMirror); + } + + @Test + public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptEngine e2 = m.getEngineByName("nashorn"); + + e.eval("function func() {}"); + e2.put("func", e.get("func")); + final ScriptObjectMirror e2obj = (ScriptObjectMirror)e2.eval("({ foo: func })"); + final Object newObj = ((ScriptObjectMirror)e2obj.getMember("foo")).newObject(); + assertTrue(newObj instanceof ScriptObjectMirror); + } + + @Test + public void indexPropertiesExternalBufferTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptObjectMirror obj = (ScriptObjectMirror)e.eval("var obj = {}; obj"); + final ByteBuffer buf = ByteBuffer.allocate(5); + int i; + for (i = 0; i < 5; i++) { + buf.put(i, (byte)(i+10)); + } + obj.setIndexedPropertiesToExternalArrayData(buf); + + for (i = 0; i < 5; i++) { + assertEquals((byte)(i+10), ((Number)e.eval("obj[" + i + "]")).byteValue()); + } + + e.eval("for (i = 0; i < 5; i++) obj[i] = 0"); + for (i = 0; i < 5; i++) { + assertEquals((byte)0, ((Number)e.eval("obj[" + i + "]")).byteValue()); + assertEquals((byte)0, buf.get(i)); + } + } + + @Test + public void conversionTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final ScriptObjectMirror arr = (ScriptObjectMirror)e.eval("[33, 45, 23]"); + final int[] intArr = arr.to(int[].class); + assertEquals(intArr[0], 33); + assertEquals(intArr[1], 45); + assertEquals(intArr[2], 23); + + final List<?> list = arr.to(List.class); + assertEquals(list.get(0), 33); + assertEquals(list.get(1), 45); + assertEquals(list.get(2), 23); + + ScriptObjectMirror obj = (ScriptObjectMirror)e.eval( + "({ valueOf: function() { return 42 } })"); + assertEquals(Double.valueOf(42.0), obj.to(Double.class)); + + obj = (ScriptObjectMirror)e.eval( + "({ toString: function() { return 'foo' } })"); + assertEquals("foo", obj.to(String.class)); + } + + // @bug 8044000: Access to undefined property yields "null" instead of "undefined" + @Test + public void mapScriptObjectMirrorCallsiteTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine engine = m.getEngineByName("nashorn"); + final String TEST_SCRIPT = "typeof obj.foo"; + + final Bindings global = engine.getContext().getBindings(ScriptContext.ENGINE_SCOPE); + engine.eval("var obj = java.util.Collections.emptyMap()"); + // this will drive callsite "obj.foo" of TEST_SCRIPT + // to use "obj instanceof Map" as it's guard + engine.eval(TEST_SCRIPT, global); + // redefine 'obj' to be a script object + engine.eval("obj = {}"); + + final Bindings newGlobal = engine.createBindings(); + // transfer 'obj' from default global to new global + // new global will get a ScriptObjectMirror wrapping 'obj' + newGlobal.put("obj", global.get("obj")); + + // Every ScriptObjectMirror is a Map! If callsite "obj.foo" + // does not see the new 'obj' is a ScriptObjectMirror, it'll + // continue to use Map's get("obj.foo") instead of ScriptObjectMirror's + // getMember("obj.foo") - thereby getting null instead of undefined + assertEquals("undefined", engine.eval(TEST_SCRIPT, newGlobal)); + } + + public interface MirrorCheckExample { + Object test1(Object arg); + Object test2(Object arg); + boolean compare(Object o1, Object o2); + } + + // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface + @Test + public void checkMirrorToObject() throws Exception { + final ScriptEngineManager engineManager = new ScriptEngineManager(); + final ScriptEngine engine = engineManager.getEngineByName("nashorn"); + final Invocable invocable = (Invocable)engine; + + engine.eval("function test1(arg) { return { arg: arg }; }"); + engine.eval("function test2(arg) { return arg; }"); + engine.eval("function compare(arg1, arg2) { return arg1 == arg2; }"); + + final Map<String, Object> map = new HashMap<>(); + map.put("option", true); + + final MirrorCheckExample example = invocable.getInterface(MirrorCheckExample.class); + + final Object value1 = invocable.invokeFunction("test1", map); + final Object value2 = example.test1(map); + final Object value3 = invocable.invokeFunction("test2", value2); + final Object value4 = example.test2(value2); + + // check that Object type argument receives a ScriptObjectMirror + // when ScriptObject is passed + assertEquals(ScriptObjectMirror.class, value1.getClass()); + assertEquals(ScriptObjectMirror.class, value2.getClass()); + assertEquals(ScriptObjectMirror.class, value3.getClass()); + assertEquals(ScriptObjectMirror.class, value4.getClass()); + assertTrue((boolean)invocable.invokeFunction("compare", value1, value1)); + assertTrue(example.compare(value1, value1)); + assertTrue((boolean)invocable.invokeFunction("compare", value3, value4)); + assertTrue(example.compare(value3, value4)); + } + + // @bug 8053910: ScriptObjectMirror causing havoc with Invocation interface + @Test + public void mirrorUnwrapInterfaceMethod() throws Exception { + final ScriptEngineManager engineManager = new ScriptEngineManager(); + final ScriptEngine engine = engineManager.getEngineByName("nashorn"); + final Invocable invocable = (Invocable)engine; + engine.eval("function apply(obj) { " + + " return obj instanceof Packages.jdk.nashorn.api.scripting.ScriptObjectMirror; " + + "}"); + @SuppressWarnings("unchecked") + final Function<Object,Object> func = invocable.getInterface(Function.class); + assertFalse((boolean)func.apply(engine.eval("({ x: 2 })"))); + } + + // @bug 8055687: Wrong "this" passed to JSObject.eval call + @Test + public void checkThisForJSObjectEval() throws Exception { + final ScriptEngineManager engineManager = new ScriptEngineManager(); + final ScriptEngine e = engineManager.getEngineByName("nashorn"); + final JSObject jsobj = (JSObject)e.eval("({foo: 23, bar: 'hello' })"); + assertEquals(((Number)jsobj.eval("this.foo")).intValue(), 23); + assertEquals(jsobj.eval("this.bar"), "hello"); + assertEquals(jsobj.eval("String(this)"), "[object Object]"); + final Object global = e.eval("this"); + assertFalse(global.equals(jsobj.eval("this"))); + } + + @Test + public void topLevelAnonFuncStatement() throws Exception { + final ScriptEngineManager engineManager = new ScriptEngineManager(); + final ScriptEngine e = engineManager.getEngineByName("nashorn"); + final JSObject func = (JSObject)e.eval("function(x) { return x + ' world' }"); + assertTrue(func.isFunction()); + assertEquals(func.call(e.eval("this"), "hello"), "hello world"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/VariableArityTestInterface.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +@SuppressWarnings("javadoc") +public interface VariableArityTestInterface { + public String test1(int i, String... strings); + public String test2(int i, String... strings); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/Window.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +import java.util.Map; +import javax.script.Bindings; +import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; + +@SuppressWarnings("javadoc") +public class Window { + + private String location = "http://localhost:8080/window"; + + private WindowEventHandler onload = null; + + public void alert(final String message) { + System.out.println("alert: " + message); + } + + public String getLocation() { + return location; + } + + public void setLocation(final String location) { + this.location = location; + } + + public String item(final int index) { + return Integer.toHexString(index); + } + + public WindowEventHandler getOnload() { + return onload; + } + + public void setOnload(final WindowEventHandler onload) { + this.onload = onload; + } + + public static int setTimeout(final Window self, final String code, final int delay) { + return self.setTimeout(code, delay); + } + + public int setTimeout(final String code, final int delay) { + System.out.println("window.setTimeout: " + delay + ", code: " + code); + return 0; + } + + public static Object funcJSObject(final JSObject jsobj) { + return jsobj.getMember("foo"); + } + + public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) { + return sobj.get("foo"); + } + + public static Object funcMap(final Map<?,?> map) { + return map.get("foo"); + } + + public static Object funcBindings(final Bindings bindings) { + return bindings.get("foo"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/WindowEventHandler.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.scripting.test; + +@SuppressWarnings("javadoc") +public interface WindowEventHandler { + public boolean loaded(); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/resources/func.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. + +var scopeVar = 1; +var global = this; +undefGlobal = this; + +function scopeTest() { + if (this !== global) { + throw new Error("this !== global"); + } + if (this !== undefGlobal) { + throw new Error("this !== undefinedGlobal") + } + return scopeVar; +} + +scopeTest();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/resources/gettersetter.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. + +var v; + +Object.defineProperty(this, "accessor1", { + get: function() { return v; }, + set: function(n) { v = n; } +}); + +Object.defineProperty(this, "accessor2", { + get: function() { return x; }, + set: function(n) { x = n; } +});
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/scripting/test/resources/witheval.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +// This script is loaded from jdk.nashorn.api.scripting.ScopeTest to test script class sharing and reuse. + +var a; + +function outer(p, e) { + eval(e); + with(p) { + function inner() { + a = 1; + c = 10; + if (a !== 1) { + throw new Error("a !== 1"); + } + if (b !== 3) { + throw new Error("b !== 3"); + } + if (c !== 10) { + throw new Error("c !== 10"); + } + } + inner(); + } +} + +outer({}, "b = 3;"); + +if (a !== 1) { + throw new Error("a !== 1"); +} +if (b !== 3) { + throw new Error("b !== 3"); +} +if (c !== 10) { + throw new Error("c !== 10"); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/api/test/NashornSQLDriver.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.api.test; + +import java.sql.Connection; +import java.sql.Driver; +import java.sql.DriverManager; +import java.sql.DriverPropertyInfo; +import java.sql.SQLException; +import java.sql.SQLFeatureNotSupportedException; +import java.util.Properties; +import java.util.logging.Logger; + +/** + * A dummy SQL driver for testing purpose. + */ +public final class NashornSQLDriver implements Driver { + static { + try { + DriverManager.registerDriver(new NashornSQLDriver(), null); + } catch (final SQLException se) { + throw new RuntimeException(se); + } + } + + @Override + public boolean acceptsURL(final String url) { + return url.startsWith("jdbc:nashorn:"); + } + + @Override + public Connection connect(final String url, final Properties info) { + throw new UnsupportedOperationException("I am a dummy!!"); + } + + @Override + public int getMajorVersion() { + return -1; + } + + @Override + public int getMinorVersion() { + return -1; + } + + @Override + public DriverPropertyInfo[] getPropertyInfo(final String url, final Properties info) { + return new DriverPropertyInfo[0]; + } + + @Override + public boolean jdbcCompliant() { + // no way! + return false; + } + + @Override + public Logger getParentLogger() throws SQLFeatureNotSupportedException { + throw new SQLFeatureNotSupportedException(); + } +}
--- a/test/src/jdk/nashorn/internal/codegen/CompilerTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,209 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.codegen; - -import static jdk.nashorn.internal.runtime.Source.readFully; -import static jdk.nashorn.internal.runtime.Source.sourceFor; -import java.io.File; -import java.io.PrintWriter; -import java.io.StringWriter; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ErrorManager; -import jdk.nashorn.internal.runtime.ScriptFunction; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.options.Options; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * Tests to check Nashorn JS compiler - just compiler and not execution of scripts. - */ -@SuppressWarnings("javadoc") -public class CompilerTest { - private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("compilertest.verbose")); - private static final boolean TEST262 = Boolean.valueOf(System.getProperty("compilertest.test262")); - private static final String TEST_BASIC_DIR = System.getProperty("test.basic.dir"); - private static final String TEST_NODE_DIR = System.getProperty("test.node.dir"); - private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); - - interface TestFilter { - public boolean exclude(File file, String content); - } - - private static void log(final String msg) { - org.testng.Reporter.log(msg, true); - } - - private Context context; - private Global global; - - @BeforeClass - public void setupTest() { - final Options options = new Options("nashorn"); - options.set("anon.functions", true); - options.set("compile.only", true); - options.set("print.ast", true); - options.set("print.parse", true); - options.set("scripting", true); - options.set("const.as.var", true); - options.set("verify.code", true); - - final ErrorManager errors = new ErrorManager() { - @Override - public void error(final String msg) { - log(msg); - } - }; - - final StringWriter sw = new StringWriter(); - final PrintWriter pw = new PrintWriter(sw); - this.context = new Context(options, errors, pw, pw, Thread.currentThread().getContextClassLoader()); - this.global = context.createGlobal(); - } - - @AfterClass - public void tearDownTest() { - this.context = null; - this.global = null; - } - - @Test - public void compileAllTests() { - if (TEST262) { - compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() { - @Override - public boolean exclude(final File file, final String content) { - return content != null && content.contains("@negative"); - } - }); - } - compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() { - @Override - public boolean exclude(final File file, final String content) { - return file.getName().equals("es6"); - } - }); - compileTestSet(new File(TEST_NODE_DIR, "node"), null); - compileTestSet(new File(TEST_NODE_DIR, "src"), null); - } - - private void compileTestSet(final File testSetDir, final TestFilter filter) { - passed = 0; - failed = 0; - skipped = 0; - if (! testSetDir.isDirectory()) { - log("WARNING: " + testSetDir + " not found or not a directory"); - return; - } - log(testSetDir.getAbsolutePath()); - compileJSDirectory(testSetDir, filter); - - log(testSetDir + " compile done!"); - log("compile ok: " + passed); - log("compile failed: " + failed); - log("compile skipped: " + skipped); - if (failed != 0) { - Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath()); - } - } - - // number of scripts that compiled fine - private int passed; - // number of scripts resulting in compile failure - private int failed; - // scripts that were skipped - all tests with @negative are - // skipped for now. - private int skipped; - - private void compileJSDirectory(final File dir, final TestFilter filter) { - if (filter != null && filter.exclude(dir, null)) { - return; - } - for (final File f : dir.listFiles()) { - if (f.isDirectory()) { - compileJSDirectory(f, filter); - } else if (f.getName().endsWith(".js")) { - compileJSFile(f, filter); - } - } - } - - private void compileJSFile(final File file, final TestFilter filter) { - if (VERBOSE) { - log("Begin compiling " + file.getAbsolutePath()); - } - - final Global oldGlobal = Context.getGlobal(); - final boolean globalChanged = (oldGlobal != global); - - try { - final char[] buffer = readFully(file); - boolean excluded = false; - - if (filter != null) { - final String content = new String(buffer); - excluded = filter.exclude(file, content); - } - - if (excluded) { - if (VERBOSE) { - log("Skipping " + file.getAbsolutePath()); - } - skipped++; - return; - } - - if (globalChanged) { - Context.setGlobal(global); - } - final Source source = sourceFor(file.getAbsolutePath(), buffer); - final ScriptFunction script = context.compileScript(source, global); - if (script == null || context.getErrorManager().getNumberOfErrors() > 0) { - log("Compile failed: " + file.getAbsolutePath()); - failed++; - } else { - passed++; - } - } catch (final Throwable t) { - log("Compile failed: " + file.getAbsolutePath() + " : " + t); - if (VERBOSE) { - t.printStackTrace(System.out); - } - failed++; - } finally { - if (globalChanged) { - Context.setGlobal(oldGlobal); - } - } - - if (VERBOSE) { - log("Done compiling " + file.getAbsolutePath()); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/codegen/test/CompilerTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen.test; + +import static jdk.nashorn.internal.runtime.Source.readFully; +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import java.io.File; +import java.io.PrintWriter; +import java.io.StringWriter; +import jdk.nashorn.internal.objects.Global; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.Source; +import jdk.nashorn.internal.runtime.options.Options; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Tests to check Nashorn JS compiler - just compiler and not execution of scripts. + */ +@SuppressWarnings("javadoc") +public class CompilerTest { + private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("compilertest.verbose")); + private static final boolean TEST262 = Boolean.valueOf(System.getProperty("compilertest.test262")); + private static final String TEST_BASIC_DIR = System.getProperty("test.basic.dir"); + private static final String TEST_NODE_DIR = System.getProperty("test.node.dir"); + private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); + + interface TestFilter { + public boolean exclude(File file, String content); + } + + private static void log(final String msg) { + org.testng.Reporter.log(msg, true); + } + + private Context context; + private Global global; + + @BeforeClass + public void setupTest() { + final Options options = new Options("nashorn"); + options.set("anon.functions", true); + options.set("compile.only", true); + options.set("print.ast", true); + options.set("print.parse", true); + options.set("scripting", true); + options.set("const.as.var", true); + options.set("verify.code", true); + + final ErrorManager errors = new ErrorManager() { + @Override + public void error(final String msg) { + log(msg); + } + }; + + final StringWriter sw = new StringWriter(); + final PrintWriter pw = new PrintWriter(sw); + this.context = new Context(options, errors, pw, pw, Thread.currentThread().getContextClassLoader()); + this.global = context.createGlobal(); + } + + @AfterClass + public void tearDownTest() { + this.context = null; + this.global = null; + } + + @Test + public void compileAllTests() { + if (TEST262) { + compileTestSet(new File(TEST262_SUITE_DIR), new TestFilter() { + @Override + public boolean exclude(final File file, final String content) { + return content != null && content.contains("@negative"); + } + }); + } + compileTestSet(new File(TEST_BASIC_DIR), new TestFilter() { + @Override + public boolean exclude(final File file, final String content) { + return file.getName().equals("es6"); + } + }); + compileTestSet(new File(TEST_NODE_DIR, "node"), null); + compileTestSet(new File(TEST_NODE_DIR, "src"), null); + } + + private void compileTestSet(final File testSetDir, final TestFilter filter) { + passed = 0; + failed = 0; + skipped = 0; + if (! testSetDir.isDirectory()) { + log("WARNING: " + testSetDir + " not found or not a directory"); + return; + } + log(testSetDir.getAbsolutePath()); + compileJSDirectory(testSetDir, filter); + + log(testSetDir + " compile done!"); + log("compile ok: " + passed); + log("compile failed: " + failed); + log("compile skipped: " + skipped); + if (failed != 0) { + Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath()); + } + } + + // number of scripts that compiled fine + private int passed; + // number of scripts resulting in compile failure + private int failed; + // scripts that were skipped - all tests with @negative are + // skipped for now. + private int skipped; + + private void compileJSDirectory(final File dir, final TestFilter filter) { + if (filter != null && filter.exclude(dir, null)) { + return; + } + for (final File f : dir.listFiles()) { + if (f.isDirectory()) { + compileJSDirectory(f, filter); + } else if (f.getName().endsWith(".js")) { + compileJSFile(f, filter); + } + } + } + + private void compileJSFile(final File file, final TestFilter filter) { + if (VERBOSE) { + log("Begin compiling " + file.getAbsolutePath()); + } + + final Global oldGlobal = Context.getGlobal(); + final boolean globalChanged = (oldGlobal != global); + + try { + final char[] buffer = readFully(file); + boolean excluded = false; + + if (filter != null) { + final String content = new String(buffer); + excluded = filter.exclude(file, content); + } + + if (excluded) { + if (VERBOSE) { + log("Skipping " + file.getAbsolutePath()); + } + skipped++; + return; + } + + if (globalChanged) { + Context.setGlobal(global); + } + final Source source = sourceFor(file.getAbsolutePath(), buffer); + final ScriptFunction script = context.compileScript(source, global); + if (script == null || context.getErrorManager().getNumberOfErrors() > 0) { + log("Compile failed: " + file.getAbsolutePath()); + failed++; + } else { + passed++; + } + } catch (final Throwable t) { + log("Compile failed: " + file.getAbsolutePath() + " : " + t); + if (VERBOSE) { + t.printStackTrace(System.out); + } + failed++; + } finally { + if (globalChanged) { + Context.setGlobal(oldGlobal); + } + } + + if (VERBOSE) { + log("Done compiling " + file.getAbsolutePath()); + } + } +}
--- a/test/src/jdk/nashorn/internal/parser/ParserTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,189 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.parser; - -import static jdk.nashorn.internal.runtime.Source.readFully; -import static jdk.nashorn.internal.runtime.Source.sourceFor; -import java.io.File; -import jdk.nashorn.internal.runtime.Context; -import jdk.nashorn.internal.runtime.ErrorManager; -import jdk.nashorn.internal.runtime.Source; -import jdk.nashorn.internal.runtime.options.Options; -import org.testng.Assert; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -/** - * Run tests to check Nashorn's parser. - */ -@SuppressWarnings("javadoc") -public class ParserTest { - private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("parsertest.verbose")); - private static final boolean TEST262 = Boolean.valueOf(System.getProperty("parsertest.test262")); - - private static final String TEST_BASIC_DIR = System.getProperty("test.basic.dir"); - private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); - - - interface TestFilter { - public boolean exclude(File file, String content); - } - - private static void log(final String msg) { - org.testng.Reporter.log(msg, true); - } - - private Context context; - - @BeforeClass - public void setupTest() { - final Options options = new Options("nashorn"); - options.set("anon.functions", true); - options.set("parse.only", true); - options.set("scripting", true); - options.set("const.as.var", true); - - final ErrorManager errors = new ErrorManager(); - this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader()); - } - - @AfterClass - public void tearDownTest() { - this.context = null; - } - - @Test - public void parseAllTests() { - if (TEST262) { - parseTestSet(TEST262_SUITE_DIR, new TestFilter() { - @Override - public boolean exclude(final File file, final String content) { - return content != null && content.contains("@negative"); - } - }); - } - parseTestSet(TEST_BASIC_DIR, new TestFilter() { - @Override - public boolean exclude(final File file, final String content) { - return file.getName().equals("es6"); - } - }); - } - - private void parseTestSet(final String testSet, final TestFilter filter) { - passed = 0; - failed = 0; - skipped = 0; - - final File testSetDir = new File(testSet); - if (! testSetDir.isDirectory()) { - log("WARNING: " + testSetDir + " not found or not a directory"); - return; - } - log(testSetDir.getAbsolutePath()); - parseJSDirectory(testSetDir, filter); - - log(testSet + " parse done!"); - log("parse ok: " + passed); - log("parse failed: " + failed); - log("parse skipped: " + skipped); - if (failed != 0) { - Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath()); - } - } - - // number of scripts that parsed fine - private int passed; - // number of scripts resulting in parse failure - private int failed; - // scripts that were skipped - all tests with @negative are - // skipped for now. - private int skipped; - - private void parseJSDirectory(final File dir, final TestFilter filter) { - if (filter != null && filter.exclude(dir, null)) { - return; - } - for (final File f : dir.listFiles()) { - if (f.isDirectory()) { - parseJSDirectory(f, filter); - } else if (f.getName().endsWith(".js")) { - parseJSFile(f, filter); - } - } - } - - private void parseJSFile(final File file, final TestFilter filter) { - if (VERBOSE) { - log("Begin parsing " + file.getAbsolutePath()); - } - - try { - final char[] buffer = readFully(file); - boolean excluded = false; - if (filter != null) { - final String content = new String(buffer); - excluded = filter.exclude(file, content); - } - - if (excluded) { - if (VERBOSE) { - log("Skipping " + file.getAbsolutePath()); - } - skipped++; - return; - } - - final ErrorManager errors = new ErrorManager() { - @Override - public void error(final String msg) { - log(msg); - } - }; - errors.setLimit(0); - final Source source = sourceFor(file.getAbsolutePath(), buffer); - new Parser(context.getEnv(), source, errors, context.getEnv()._strict, null).parse(); - if (errors.getNumberOfErrors() > 0) { - log("Parse failed: " + file.getAbsolutePath()); - failed++; - } else { - passed++; - } - } catch (final Throwable exp) { - exp.printStackTrace(); - log("Parse failed: " + file.getAbsolutePath() + " : " + exp); - if (VERBOSE) { - exp.printStackTrace(System.out); - } - failed++; - } - - if (VERBOSE) { - log("Done parsing " + file.getAbsolutePath()); - } - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/parser/test/ParserTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.parser.test; + +import static jdk.nashorn.internal.runtime.Source.readFully; +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import java.io.File; +import jdk.nashorn.internal.parser.Parser; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.Source; +import jdk.nashorn.internal.runtime.options.Options; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +/** + * Run tests to check Nashorn's parser. + */ +@SuppressWarnings("javadoc") +public class ParserTest { + private static final boolean VERBOSE = Boolean.valueOf(System.getProperty("parsertest.verbose")); + private static final boolean TEST262 = Boolean.valueOf(System.getProperty("parsertest.test262")); + + private static final String TEST_BASIC_DIR = System.getProperty("test.basic.dir"); + private static final String TEST262_SUITE_DIR = System.getProperty("test262.suite.dir"); + + + interface TestFilter { + public boolean exclude(File file, String content); + } + + private static void log(final String msg) { + org.testng.Reporter.log(msg, true); + } + + private Context context; + + @BeforeClass + public void setupTest() { + final Options options = new Options("nashorn"); + options.set("anon.functions", true); + options.set("parse.only", true); + options.set("scripting", true); + options.set("const.as.var", true); + + final ErrorManager errors = new ErrorManager(); + this.context = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + } + + @AfterClass + public void tearDownTest() { + this.context = null; + } + + @Test + public void parseAllTests() { + if (TEST262) { + parseTestSet(TEST262_SUITE_DIR, new TestFilter() { + @Override + public boolean exclude(final File file, final String content) { + return content != null && content.contains("@negative"); + } + }); + } + parseTestSet(TEST_BASIC_DIR, new TestFilter() { + @Override + public boolean exclude(final File file, final String content) { + return file.getName().equals("es6"); + } + }); + } + + private void parseTestSet(final String testSet, final TestFilter filter) { + passed = 0; + failed = 0; + skipped = 0; + + final File testSetDir = new File(testSet); + if (! testSetDir.isDirectory()) { + log("WARNING: " + testSetDir + " not found or not a directory"); + return; + } + log(testSetDir.getAbsolutePath()); + parseJSDirectory(testSetDir, filter); + + log(testSet + " parse done!"); + log("parse ok: " + passed); + log("parse failed: " + failed); + log("parse skipped: " + skipped); + if (failed != 0) { + Assert.fail(failed + " tests failed to compile in " + testSetDir.getAbsolutePath()); + } + } + + // number of scripts that parsed fine + private int passed; + // number of scripts resulting in parse failure + private int failed; + // scripts that were skipped - all tests with @negative are + // skipped for now. + private int skipped; + + private void parseJSDirectory(final File dir, final TestFilter filter) { + if (filter != null && filter.exclude(dir, null)) { + return; + } + for (final File f : dir.listFiles()) { + if (f.isDirectory()) { + parseJSDirectory(f, filter); + } else if (f.getName().endsWith(".js")) { + parseJSFile(f, filter); + } + } + } + + private void parseJSFile(final File file, final TestFilter filter) { + if (VERBOSE) { + log("Begin parsing " + file.getAbsolutePath()); + } + + try { + final char[] buffer = readFully(file); + boolean excluded = false; + if (filter != null) { + final String content = new String(buffer); + excluded = filter.exclude(file, content); + } + + if (excluded) { + if (VERBOSE) { + log("Skipping " + file.getAbsolutePath()); + } + skipped++; + return; + } + + final ErrorManager errors = new ErrorManager() { + @Override + public void error(final String msg) { + log(msg); + } + }; + errors.setLimit(0); + final Source source = sourceFor(file.getAbsolutePath(), buffer); + new Parser(context.getEnv(), source, errors, context.getEnv()._strict, null).parse(); + if (errors.getNumberOfErrors() > 0) { + log("Parse failed: " + file.getAbsolutePath()); + failed++; + } else { + passed++; + } + } catch (final Throwable exp) { + exp.printStackTrace(); + log("Parse failed: " + file.getAbsolutePath() + " : " + exp); + if (VERBOSE) { + exp.printStackTrace(System.out); + } + failed++; + } + + if (VERBOSE) { + log("Done parsing " + file.getAbsolutePath()); + } + } +}
--- a/test/src/jdk/nashorn/internal/runtime/ClassFilterTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.fail; -import java.io.File; -import javax.script.ScriptEngine; -import javax.script.ScriptException; -import jdk.nashorn.api.scripting.ClassFilter; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import jdk.nashorn.api.scripting.URLReader; -import jdk.nashorn.internal.test.framework.TestFinder; -import org.testng.annotations.Test; - -@SuppressWarnings("javadoc") -public class ClassFilterTest { - private static final String NASHORN_CODE_CACHE = "nashorn.persistent.code.cache"; - private static final String CLASSFILTER_CODE_CACHE = "build/classfilter_nashorn_code_cache"; - - // @Test - // This test takes too much time for basic "ant clean test" run. - // Given that "allow-all-java-classes" is equivalent to no java class - // filter and external tests don't access any java, not sure if this - // test contributes much. We need faster "ant clean test" cycle for - // developers. - public void runExternalJsTest() { - final String[] paths = new String[]{ - "test/script/basic/compile-octane.js", - "test/script/basic/jquery.js", - "test/script/basic/prototype.js", - "test/script/basic/runsunspider.js", - "test/script/basic/underscore.js", - "test/script/basic/yui.js", - "test/script/basic/run-octane.js" - }; - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - for (final String path : paths) { - final ScriptEngine engine = factory.getScriptEngine(new String[]{"-scripting"}, getClass().getClassLoader(), getClassFilter()); - try { - engine.eval(new URLReader(new File(path).toURI().toURL())); - } catch (final Exception e) { - fail("Script " + path + " fails with exception :" + e.getMessage()); - } - } - } - - @Test - public void noJavaOptionTest() { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine engine = factory.getScriptEngine(new String[]{"--no-java"}, getClass().getClassLoader(), getClassFilter()); - try { - engine.eval("var str = Java.type('java.lang.String');"); - fail("TypeError should have been thrown"); - } catch (final ScriptException e) { - //emtpy - } - } - - @Test - public void securityTest() { - if (System.getSecurityManager() == null) { - return; - } - - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine engine = factory.getScriptEngine(getClassFilter()); - try { - engine.eval("var thread = Java.type('sun.misc.Unsafe')"); - fail("SecurityException should have been thrown"); - } catch (final Exception e) { - //empty - } - try { - engine.eval("var thread = new sun.misc.Unsafe()"); - fail("SecurityException should have been thrown"); - } catch (final Exception e) { - //empty - } - try { - engine.eval("var thread = Java.extend(sun.misc.Unsafe, {})"); - fail("TypeError should have been thrown"); - } catch (final Exception e) { - //empty - } - try { - engine.eval("java.lang.System.exit(0)"); - fail("SecurityException should have been thrown"); - } catch (final Exception e) { - //empty - } - - } - - @Test - public void persistentCacheTest() { - final String oldCodeCache = System.getProperty(NASHORN_CODE_CACHE); - System.setProperty(NASHORN_CODE_CACHE, CLASSFILTER_CODE_CACHE); - try { - persistentCacheTestImpl(); - } finally { - if (oldCodeCache != null) { - System.setProperty(NASHORN_CODE_CACHE, oldCodeCache); - } - } - } - - private void persistentCacheTestImpl() { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine engine = factory.getScriptEngine( - TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}), - getClass().getClassLoader(), - getClassFilter() - ); - final String testScript = "var a = Java.type('java.lang.String');" + generateCodeForPersistentStore(); - try { - engine.eval(testScript); - } catch (final ScriptException exc) { - fail(exc.getMessage()); - } - final ScriptEngine engineSafe = factory.getScriptEngine( - TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}), - getClass().getClassLoader(), - new ClassFilter() { - @Override - public boolean exposeToScripts(final String s) { - return false; - } - } - ); - try { - engineSafe.eval(testScript); - fail("ClassNotFoundException should have been thrown"); - } catch (final Exception exc) { - if (!(exc.getCause() instanceof ClassNotFoundException)) { - fail("ClassNotFoundException expected, got " + exc.getClass()); - } - } - } - - private static String generateCodeForPersistentStore() { - final StringBuilder stringBuilder = new StringBuilder(); - for (int i=0; i < 100; i++) { - stringBuilder.append("function i") - .append(i) - .append("(y, z) { var x") - .append(i) - .append(" = ") - .append(i) - .append(";}"); - } - return stringBuilder.toString(); - } - - private static ClassFilter getClassFilter() { - return new ClassFilter() { - @Override - public boolean exposeToScripts(final String s) { - return true; - } - }; - } -}
--- a/test/src/jdk/nashorn/internal/runtime/CodeStoreAndPathTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,188 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import java.io.File; -import java.io.IOException; -import java.nio.file.DirectoryStream; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import javax.script.ScriptEngine; -import javax.script.ScriptException; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.testng.annotations.Test; - -/** - * @test - * @bug 8039185 8039403 - * @summary Test for persistent code cache and path handling - * @run testng jdk.nashorn.internal.runtime.CodeStoreAndPathTest - */ -@SuppressWarnings("javadoc") -public class CodeStoreAndPathTest { - - final String code1 = "var code1; var x = 'Hello Script'; var x1 = 'Hello Script'; " - + "var x2 = 'Hello Script'; var x3 = 'Hello Script'; " - + "var x4 = 'Hello Script'; var x5 = 'Hello Script';" - + "var x6 = 'Hello Script'; var x7 = 'Hello Script'; " - + "var x8 = 'Hello Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';" - + "function f() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function g() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function h() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function i() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}"; - final String code2 = "var code2; var x = 'Hello Script'; var x1 = 'Hello Script'; " - + "var x2 = 'Hello Script'; var x3 = 'Hello Script'; " - + "var x4 = 'Hello Script'; var x5 = 'Hello Script';" - + "var x6 = 'Hello Script'; var x7 = 'Hello Script'; " - + "var x8 = 'Hello Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';" - + "function f() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function g() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function h() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}" - + "function i() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" - + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" - + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " - + "var x10 = 'Hello Script';}"; - // Script size < Default minimum size for storing a compiled script class - final String code3 = "var code3; var x = 'Hello Script'; var x1 = 'Hello Script'; "; - final String codeCache = "build/nashorn_code_cache"; - final String oldUserDir = System.getProperty("user.dir"); - - private static final String[] ENGINE_OPTIONS_OPT = new String[]{"--persistent-code-cache", "--optimistic-types=true"}; - private static final String[] ENGINE_OPTIONS_NOOPT = new String[]{"--persistent-code-cache", "--optimistic-types=false"}; - - @Test - public void pathHandlingTest() { - System.setProperty("nashorn.persistent.code.cache", codeCache); - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - - fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); - - final Path expectedCodeCachePath = FileSystems.getDefault().getPath(oldUserDir + File.separator + codeCache); - final Path actualCodeCachePath = FileSystems.getDefault().getPath(System.getProperty( - "nashorn.persistent.code.cache")).toAbsolutePath(); - // Check that nashorn code cache is created in current working directory - assertEquals(actualCodeCachePath, expectedCodeCachePath); - // Check that code cache dir exists and it's not empty - final File file = new File(actualCodeCachePath.toUri()); - assertFalse(!file.isDirectory(), "No code cache directory was created!"); - assertFalse(file.list().length == 0, "Code cache directory is empty!"); - } - - @Test - public void changeUserDirTest() throws ScriptException, IOException { - System.setProperty("nashorn.persistent.code.cache", codeCache); - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); - final Path codeCachePath = getCodeCachePath(false); - final String newUserDir = "build/newUserDir"; - // Now changing current working directory - System.setProperty("user.dir", System.getProperty("user.dir") + File.separator + newUserDir); - try { - // Check that a new compiled script is stored in existing code cache - e.eval(code1); - final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); - checkCompiledScripts(stream, 1); - // Setting to default current working dir - } finally { - System.setProperty("user.dir", oldUserDir); - } - } - - @Test - public void codeCacheTest() throws ScriptException, IOException { - System.setProperty("nashorn.persistent.code.cache", codeCache); - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); - final Path codeCachePath = getCodeCachePath(false); - e.eval(code1); - e.eval(code2); - e.eval(code3);// less than minimum size for storing - // adding code1 and code2. - final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); - checkCompiledScripts(stream, 2); - } - - @Test - public void codeCacheTestOpt() throws ScriptException, IOException { - System.setProperty("nashorn.persistent.code.cache", codeCache); - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_OPT); - final Path codeCachePath = getCodeCachePath(true); - e.eval(code1); - e.eval(code2); - e.eval(code3);// less than minimum size for storing - // adding code1 and code2. - final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); - checkCompiledScripts(stream, 2); - } - - private static Path getCodeCachePath(final boolean optimistic) { - final String codeCache = System.getProperty("nashorn.persistent.code.cache"); - final Path codeCachePath = FileSystems.getDefault().getPath(codeCache).toAbsolutePath(); - final String[] files = codeCachePath.toFile().list(); - for (final String file : files) { - if (file.endsWith("_opt") == optimistic) { - return codeCachePath.resolve(file); - } - } - throw new AssertionError("Code cache path not found"); - } - - private static void checkCompiledScripts(final DirectoryStream<Path> stream, final int numberOfScripts) throws IOException { - int n = numberOfScripts; - for (@SuppressWarnings("unused") final Path file : stream) { - n--; - } - stream.close(); - assertEquals(n, 0); - } - -}
--- a/test/src/jdk/nashorn/internal/runtime/ConsStringTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,131 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.assertEquals; - -import org.testng.annotations.Test; - -/** - * Tests for JSType methods. - * - * @test - * @run testng jdk.nashorn.internal.runtime.ConsStringTest - */ -public class ConsStringTest { - - /** - * Test toString conversion - */ - @Test - public void testConsStringToString() { - final ConsString cs1 = new ConsString("b", "c"); - final ConsString cs2 = new ConsString("d", "e"); - final ConsString cs3 = new ConsString(cs1, cs2); - final ConsString cs4 = new ConsString(cs3, "f"); - final ConsString cs5 = new ConsString("a", cs4); - assertEquals(cs5.toString(), "abcdef"); - assertEquals(cs4.toString(), "bcdef"); - assertEquals(cs3.toString(), "bcde"); - assertEquals(cs2.toString(), "de"); - assertEquals(cs1.toString(), "bc"); - // ConsStrings should be flattened now - assertEquals(cs1.getComponents()[0], "bc"); - assertEquals(cs1.getComponents()[1], ""); - assertEquals(cs2.getComponents()[0], "de"); - assertEquals(cs2.getComponents()[1], ""); - assertEquals(cs3.getComponents()[0], "bcde"); - assertEquals(cs3.getComponents()[1], ""); - assertEquals(cs4.getComponents()[0], "bcdef"); - assertEquals(cs4.getComponents()[1], ""); - assertEquals(cs5.getComponents()[0], "abcdef"); - assertEquals(cs5.getComponents()[1], ""); - } - - /** - * Test charAt - */ - @Test - public void testConsStringCharAt() { - final ConsString cs1 = new ConsString("b", "c"); - final ConsString cs2 = new ConsString("d", "e"); - final ConsString cs3 = new ConsString(cs1, cs2); - final ConsString cs4 = new ConsString(cs3, "f"); - final ConsString cs5 = new ConsString("a", cs4); - assertEquals(cs1.charAt(1), 'c'); - assertEquals(cs2.charAt(0), 'd'); - assertEquals(cs3.charAt(3), 'e'); - assertEquals(cs4.charAt(1), 'c'); - assertEquals(cs5.charAt(2), 'c'); - // ConsStrings should be flattened now - assertEquals(cs1.getComponents()[0], "bc"); - assertEquals(cs1.getComponents()[1], ""); - assertEquals(cs2.getComponents()[0], "de"); - assertEquals(cs2.getComponents()[1], ""); - assertEquals(cs3.getComponents()[0], "bcde"); - assertEquals(cs3.getComponents()[1], ""); - assertEquals(cs4.getComponents()[0], "bcdef"); - assertEquals(cs4.getComponents()[1], ""); - assertEquals(cs5.getComponents()[0], "abcdef"); - assertEquals(cs5.getComponents()[1], ""); - } - - - /** - * Test flattening of top-level and internal ConsStrings - */ - @Test - public void testConsStringFlattening() { - final ConsString cs1 = new ConsString("b", "c"); - final ConsString cs2 = new ConsString("d", "e"); - final ConsString cs3 = new ConsString(cs1, cs2); - final ConsString cs4 = new ConsString(cs3, "f"); - - final ConsString cs5 = new ConsString("a", cs4); - // top-level ConsString should not yet be flattened - assert(cs5.getComponents()[0] == "a"); - assert(cs5.getComponents()[1] == cs4); - assertEquals(cs5.toString(), "abcdef"); - // top-level ConsString should be flattened - assertEquals(cs5.getComponents()[0], "abcdef"); - assertEquals(cs5.getComponents()[1], ""); - // internal ConsString should not yet be flattened after first traversal - assertEquals(cs4.getComponents()[0], cs3); - assertEquals(cs4.getComponents()[1], "f"); - - final ConsString cs6 = new ConsString("a", cs4); - // top-level ConsString should not yet be flattened - assertEquals(cs6.getComponents()[0], "a"); - assertEquals(cs6.getComponents()[1], cs4); - assertEquals(cs6.toString(), "abcdef"); - // top-level ConsString should be flattened - assertEquals(cs6.getComponents()[0], "abcdef"); - assertEquals(cs6.getComponents()[1], ""); - // internal ConsString should have been flattened after second traversal - assertEquals(cs4.getComponents()[0], "bcdef"); - assertEquals(cs4.getComponents()[1], ""); - } -}
--- a/test/src/jdk/nashorn/internal/runtime/ContextTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static jdk.nashorn.internal.runtime.Source.sourceFor; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; -import java.util.Map; -import jdk.nashorn.internal.objects.Global; -import jdk.nashorn.internal.runtime.options.Options; -import org.testng.annotations.Test; - -/** - * Basic Context API tests. - * - * @test - * @run testng jdk.nashorn.internal.runtime.ContextTest - */ -@SuppressWarnings("javadoc") -public class ContextTest { - // basic context eval test - @Test - public void evalTest() { - final Options options = new Options(""); - final ErrorManager errors = new ErrorManager(); - final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); - final Global oldGlobal = Context.getGlobal(); - Context.setGlobal(cx.createGlobal()); - try { - String code = "22 + 10"; - assertTrue(32.0 == ((Number)(eval(cx, "<evalTest>", code))).doubleValue()); - - code = "obj = { js: 'nashorn' }; obj.js"; - assertEquals(eval(cx, "<evalTest2>", code), "nashorn"); - } finally { - Context.setGlobal(oldGlobal); - } - } - - // Make sure trying to compile an invalid script returns null - see JDK-8046215. - @Test - public void compileErrorTest() { - final Options options = new Options(""); - final ErrorManager errors = new ErrorManager(); - final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); - final Global oldGlobal = Context.getGlobal(); - Context.setGlobal(cx.createGlobal()); - try { - final ScriptFunction script = cx.compileScript(sourceFor("<evalCompileErrorTest>", "*/"), Context.getGlobal()); - if (script != null) { - fail("Invalid script compiled without errors"); - } - if (errors.getNumberOfErrors() != 1) { - fail("Wrong number of errors: " + errors.getNumberOfErrors()); - } - } finally { - Context.setGlobal(oldGlobal); - } - } - - // basic check for JS reflection access - java.util.Map-like access on ScriptObject - @Test - public void reflectionTest() { - final Options options = new Options(""); - final ErrorManager errors = new ErrorManager(); - final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); - final boolean strict = cx.getEnv()._strict; - final Global oldGlobal = Context.getGlobal(); - Context.setGlobal(cx.createGlobal()); - - try { - final String code = "var obj = { x: 344, y: 42 }"; - eval(cx, "<reflectionTest>", code); - - final Object obj = Context.getGlobal().get("obj"); - - assertTrue(obj instanceof ScriptObject); - - final ScriptObject sobj = (ScriptObject)obj; - int count = 0; - for (final Map.Entry<?, ?> ex : sobj.entrySet()) { - final Object key = ex.getKey(); - if (key.equals("x")) { - assertTrue(ex.getValue() instanceof Number); - assertTrue(344.0 == ((Number)ex.getValue()).doubleValue()); - - count++; - } else if (key.equals("y")) { - assertTrue(ex.getValue() instanceof Number); - assertTrue(42.0 == ((Number)ex.getValue()).doubleValue()); - - count++; - } - } - assertEquals(count, 2); - assertEquals(sobj.size(), 2); - - // add property - sobj.put("zee", "hello", strict); - assertEquals(sobj.get("zee"), "hello"); - assertEquals(sobj.size(), 3); - - } finally { - Context.setGlobal(oldGlobal); - } - } - - private static Object eval(final Context cx, final String name, final String code) { - final Source source = sourceFor(name, code); - final ScriptObject global = Context.getGlobal(); - final ScriptFunction func = cx.compileScript(source, global); - return func != null ? ScriptRuntime.apply(func, global) : null; - } -}
--- a/test/src/jdk/nashorn/internal/runtime/ExceptionsNotSerializable.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.fail; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.NotSerializableException; -import java.io.ObjectOutputStream; -import javax.script.ScriptEngine; -import javax.script.ScriptException; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.testng.annotations.Test; - -/** - * JDK-8044518: Ensure exceptions related to optimistic recompilation are not serializable - * - * @test - * @run testng jdk.nashorn.internal.runtime.ExceptionsNotSerializable - */ -@SuppressWarnings("javadoc") -public class ExceptionsNotSerializable { - @Test - public void rewriteExceptionNotSerializable() throws ScriptException { - // NOTE: we must create a RewriteException in a context of a Nashorn engine, as it uses Global.newIntance() - // internally. - final ScriptEngine e = new NashornScriptEngineFactory().getScriptEngine(); - e.put("f", new Runnable() { - @Override - public void run() { - tryToSerialize(RewriteException.create(null, new Object[0], new String[0])); - } - }); - e.eval("f()"); - } - - @Test - public void unwarrantedOptimismExceptionNotSerializable() { - tryToSerialize(new UnwarrantedOptimismException(new Double(1.0), 128)); - } - - private static void tryToSerialize(final Object obj) { - try { - new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(obj); - fail(); - } catch (final NotSerializableException e) { - assertEquals(e.getMessage(), obj.getClass().getName()); - } catch (final IOException e) { - fail("", e); - } - - } -}
--- a/test/src/jdk/nashorn/internal/runtime/JSTypeTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -import org.testng.annotations.Test; - -/** - * Tests for JSType methods. - * - * @test - * @run testng jdk.nashorn.internal.runtime.JSTypeTest - */ -public class JSTypeTest { - /** - * Test of isPrimitive method, of class Runtime. - */ - @Test - public void testIsPrimitive() { - assertTrue(JSType.isPrimitive(null)); - assertTrue(JSType.isPrimitive(ScriptRuntime.UNDEFINED)); - assertTrue(JSType.isPrimitive(Double.NaN)); - assertTrue(JSType.isPrimitive(Double.NEGATIVE_INFINITY)); - assertTrue(JSType.isPrimitive(Double.POSITIVE_INFINITY)); - assertTrue(JSType.isPrimitive(0.0)); - assertTrue(JSType.isPrimitive(3.14)); - assertTrue(JSType.isPrimitive("hello")); - assertTrue(JSType.isPrimitive("")); - assertFalse(JSType.isPrimitive(new Object())); - } - - /** - * Test of toBoolean method, of class Runtime. - */ - @Test - public void testToBoolean() { - assertFalse(JSType.toBoolean(ScriptRuntime.UNDEFINED)); - assertFalse(JSType.toBoolean(null)); - assertFalse(JSType.toBoolean(Boolean.FALSE)); - assertTrue(JSType.toBoolean(Boolean.TRUE)); - assertFalse(JSType.toBoolean(-0.0)); - assertFalse(JSType.toBoolean(0.0)); - assertFalse(JSType.toBoolean(Double.NaN)); - assertTrue(JSType.toBoolean(3.14)); - assertFalse(JSType.toBoolean("")); - assertTrue(JSType.toBoolean("javascript")); - assertTrue(JSType.toBoolean(new Object())); - } - - /** - * Test of toNumber method, of class Runtime. - */ - @Test - public void testToNumber_Object() { - assertTrue(Double.isNaN(JSType.toNumber(ScriptRuntime.UNDEFINED))); - assertEquals(JSType.toNumber((Object)null), 0.0, 0.0); - assertEquals(JSType.toNumber(Boolean.TRUE), 1.0, 0.0); - assertEquals(JSType.toNumber(Boolean.FALSE), 0.0, 0.0); - assertEquals(JSType.toNumber(3.14), 3.14, 0.0); - // FIXME: add more assertions for specific String to number cases - // FIXME: add case for Object type (JSObject with getDefaultValue) - } - - /** - * Test of toString method, of class Runtime. - */ - @Test - public void testToString_Object() { - assertEquals(JSType.toString(ScriptRuntime.UNDEFINED), "undefined"); - assertEquals(JSType.toString(null), "null"); - assertEquals(JSType.toString(Boolean.TRUE), "true"); - assertEquals(JSType.toString(Boolean.FALSE), "false"); - assertEquals(JSType.toString(""), ""); - assertEquals(JSType.toString("nashorn"), "nashorn"); - assertEquals(JSType.toString(Double.NaN), "NaN"); - assertEquals(JSType.toString(Double.POSITIVE_INFINITY), "Infinity"); - assertEquals(JSType.toString(Double.NEGATIVE_INFINITY), "-Infinity"); - assertEquals(JSType.toString(0.0), "0"); - // FIXME: add more number-to-string test cases - // FIXME: add case for Object type (JSObject with getDefaultValue) - } - - /** - * Test of JSType.toUint32(double) - */ - @Test - public void testToUint32() { - assertEquals(JSType.toUint32(+0.0), 0); - assertEquals(JSType.toUint32(-0.0), 0); - assertEquals(JSType.toUint32(Double.NaN), 0); - assertEquals(JSType.toUint32(Double.POSITIVE_INFINITY), 0); - assertEquals(JSType.toUint32(Double.NEGATIVE_INFINITY), 0); - assertEquals(JSType.toUint32(9223372036854775807.0d), 0); - assertEquals(JSType.toUint32(-9223372036854775807.0d), 0); - assertEquals(JSType.toUint32(1099511627776.0d), 0); - assertEquals(JSType.toUint32(-1099511627776.0d), 0); - assertEquals(JSType.toUint32(4294967295.0d), 4294967295l); - assertEquals(JSType.toUint32(4294967296.0d), 0); - assertEquals(JSType.toUint32(4294967297.0d), 1); - assertEquals(JSType.toUint32(-4294967295.0d), 1); - assertEquals(JSType.toUint32(-4294967296.0d), 0); - assertEquals(JSType.toUint32(-4294967297.0d), 4294967295l); - assertEquals(JSType.toUint32(4294967295.6d), 4294967295l); - assertEquals(JSType.toUint32(4294967296.6d), 0); - assertEquals(JSType.toUint32(4294967297.6d), 1); - assertEquals(JSType.toUint32(-4294967295.6d), 1); - assertEquals(JSType.toUint32(-4294967296.6d), 0); - assertEquals(JSType.toUint32(-4294967297.6d), 4294967295l); - } - - /** - * Test of JSType.toInt32(double) - */ - @Test - public void testToInt32() { - assertEquals(JSType.toInt32(+0.0), 0); - assertEquals(JSType.toInt32(-0.0), 0); - assertEquals(JSType.toInt32(Double.NaN), 0); - assertEquals(JSType.toInt32(Double.POSITIVE_INFINITY), 0); - assertEquals(JSType.toInt32(Double.NEGATIVE_INFINITY), 0); - assertEquals(JSType.toInt32(9223372036854775807.0d), 0); - assertEquals(JSType.toInt32(-9223372036854775807.0d), 0); - assertEquals(JSType.toInt32(1099511627776.0d), 0); - assertEquals(JSType.toInt32(-1099511627776.0d), 0); - assertEquals(JSType.toInt32(4294967295.0d), -1); - assertEquals(JSType.toInt32(4294967296.0d), 0); - assertEquals(JSType.toInt32(4294967297.0d), 1); - assertEquals(JSType.toInt32(-4294967295.0d), 1); - assertEquals(JSType.toInt32(-4294967296.0d), 0); - assertEquals(JSType.toInt32(-4294967297.d), -1); - assertEquals(JSType.toInt32(4294967295.6d), -1); - assertEquals(JSType.toInt32(4294967296.6d), 0); - assertEquals(JSType.toInt32(4294967297.6d), 1); - assertEquals(JSType.toInt32(-4294967295.6d), 1); - assertEquals(JSType.toInt32(-4294967296.6d), 0); - assertEquals(JSType.toInt32(-4294967297.6d), -1); - } - - /** - * Test of JSType.toUint16(double) - */ - @Test - public void testToUint16() { - assertEquals(JSType.toUint16(+0.0), 0); - assertEquals(JSType.toUint16(-0.0), 0); - assertEquals(JSType.toUint16(Double.NaN), 0); - assertEquals(JSType.toUint16(Double.POSITIVE_INFINITY), 0); - assertEquals(JSType.toUint16(Double.NEGATIVE_INFINITY), 0); - assertEquals(JSType.toUint16(9223372036854775807.0d), 0); - assertEquals(JSType.toUint16(-9223372036854775807.0d), 0); - assertEquals(JSType.toUint16(1099511627776.0d), 0); - assertEquals(JSType.toUint16(-1099511627776.0d), 0); - assertEquals(JSType.toUint16(4294967295.0d), 65535); - assertEquals(JSType.toUint16(4294967296.0d), 0); - assertEquals(JSType.toUint16(4294967297.0d), 1); - assertEquals(JSType.toUint16(-4294967295.0d), 1); - assertEquals(JSType.toUint16(-4294967296.0d), 0); - assertEquals(JSType.toUint16(-4294967297.0d), 65535); - assertEquals(JSType.toUint16(4294967295.6d), 65535); - assertEquals(JSType.toUint16(4294967296.6d), 0); - assertEquals(JSType.toUint16(4294967297.6d), 1); - assertEquals(JSType.toUint16(-4294967295.6d), 1); - assertEquals(JSType.toUint16(-4294967296.6d), 0); - assertEquals(JSType.toUint16(-4294967297.6d), 65535); - } - -}
--- a/test/src/jdk/nashorn/internal/runtime/LexicalBindingTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.testng.annotations.Test; - -import javax.script.Bindings; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; - -import static org.testng.Assert.assertEquals; - -/** - * Top-level lexical binding tests. - * - * @test - * @run testng jdk.nashorn.internal.runtime.LexicalBindingTest - */ -@SuppressWarnings("javadoc") -public class LexicalBindingTest { - - final static String LANGUAGE_ES6 = "--language=es6"; - final static int NUMBER_OF_CONTEXTS = 20; - final static int MEGAMORPHIC_LOOP_COUNT = 20; - - /** - * Test access to global var-declared variables for shared script classes with multiple globals. - */ - @Test - public static void megamorphicVarTest() throws ScriptException, InterruptedException { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine e = factory.getScriptEngine(); - final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS]; - final String sharedScript = "foo"; - - - for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { - final ScriptContext context = contexts[i] = new SimpleScriptContext(); - final Bindings b = e.createBindings(); - context.setBindings(b, ScriptContext.ENGINE_SCOPE); - assertEquals(e.eval("var foo = '" + i + "';", context), null); - } - - for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { - final ScriptContext context = contexts[i]; - assertEquals(e.eval(sharedScript, context), String.valueOf(i)); - } - } - - /** - * Test access to global lexically declared variables for shared script classes with multiple globals. - */ - @Test - public static void megamorphicMultiGlobalLetTest() throws ScriptException, InterruptedException { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); - final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS]; - final String sharedScript = "foo"; - - - for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { - final ScriptContext context = contexts[i] = new SimpleScriptContext(); - final Bindings b = e.createBindings(); - context.setBindings(b, ScriptContext.ENGINE_SCOPE); - assertEquals(e.eval("let foo = '" + i + "';", context), null); - } - - for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { - final ScriptContext context = contexts[i]; - assertEquals(e.eval(sharedScript, context), String.valueOf(i)); - } - } - - - /** - * Test access to global lexically declared variables for shared script classes with single global. - */ - @Test - public static void megamorphicSingleGlobalLetTest() throws ScriptException, InterruptedException { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); - final String sharedGetterScript = "foo"; - final String sharedSetterScript = "foo = 1"; - - for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) { - assertEquals(e.eval(sharedSetterScript), 1); - assertEquals(e.eval(sharedGetterScript), 1); - assertEquals(e.eval("delete foo; a" + i + " = 1; foo = " + i + ";"), i); - assertEquals(e.eval(sharedGetterScript), i); - } - - assertEquals(e.eval("let foo = 'foo';"), null); - assertEquals(e.eval(sharedGetterScript), "foo"); - assertEquals(e.eval(sharedSetterScript), 1); - assertEquals(e.eval(sharedGetterScript), 1); - assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1); - } - - /** - * Test access to global lexically declared variables for shared script classes with single global. - */ - @Test - public static void megamorphicInheritedGlobalLetTest() throws ScriptException, InterruptedException { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); - final String sharedGetterScript = "foo"; - final String sharedSetterScript = "foo = 1"; - - for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) { - assertEquals(e.eval(sharedSetterScript), 1); - assertEquals(e.eval(sharedGetterScript), 1); - assertEquals(e.eval("delete foo; a" + i + " = 1; Object.prototype.foo = " + i + ";"), i); - assertEquals(e.eval(sharedGetterScript), i); - } - - assertEquals(e.eval("let foo = 'foo';"), null); - assertEquals(e.eval(sharedGetterScript), "foo"); - assertEquals(e.eval(sharedSetterScript), 1); - assertEquals(e.eval(sharedGetterScript), 1); - assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1); - } - - /** - * Test multi-threaded access to global lexically declared variables for shared script classes with multiple globals. - */ - @Test - public static void multiThreadedLetTest() throws ScriptException, InterruptedException { - final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); - final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); - final Bindings b = e.createBindings(); - final ScriptContext origContext = e.getContext(); - final ScriptContext newCtxt = new SimpleScriptContext(); - newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); - final String sharedScript = "foo"; - - assertEquals(e.eval("let foo = 'original context';", origContext), null); - assertEquals(e.eval("let foo = 'new context';", newCtxt), null); - - final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); - t1.start(); - t2.start(); - t1.join(); - t2.join(); - - assertEquals(e.eval("foo = 'newer context';", newCtxt), "newer context"); - final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); - final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); - - t3.start(); - t4.start(); - t3.join(); - t4.join(); - - assertEquals(e.eval(sharedScript), "original context"); - assertEquals(e.eval(sharedScript, newCtxt), "newer context"); - } - - private static class ScriptRunner implements Runnable { - - final ScriptEngine engine; - final ScriptContext context; - final String source; - final Object expected; - final int iterations; - - ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) { - this.engine = engine; - this.context = context; - this.source = source; - this.expected = expected; - this.iterations = iterations; - } - - @Override - public void run() { - try { - for (int i = 0; i < iterations; i++) { - assertEquals(engine.eval(source, context), expected); - } - } catch (final ScriptException se) { - throw new RuntimeException(se); - } - } - } -}
--- a/test/src/jdk/nashorn/internal/runtime/NoPersistenceCachingTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.fail; -import java.io.ByteArrayOutputStream; -import java.io.PrintStream; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import javax.script.SimpleScriptContext; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.testng.annotations.AfterTest; -import org.testng.annotations.BeforeTest; -import org.testng.annotations.Test; - -/** - * @test - * @bug 8037378 - * @summary Sanity tests for no persistence caching - * @run testng/othervm jdk.nashorn.internal.runtime.NoPersistenceCachingTest - */ -@SuppressWarnings("javadoc") -public class NoPersistenceCachingTest { - - private ScriptEngine engine; - private ScriptContext context1, context2, context3; - private ByteArrayOutputStream stderr; - private PrintStream prevStderr; - - @BeforeTest - public void setupTest() { - stderr = new ByteArrayOutputStream(); - prevStderr = System.err; - System.setErr(new PrintStream(stderr)); - NashornScriptEngineFactory nashornFactory = null; - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - nashornFactory = (NashornScriptEngineFactory) fac; - break; - } - } - if (nashornFactory == null) { - fail("Cannot find nashorn factory!"); - } - // fine is enough for cache hits, finest produces way too much information - // TODO this should be ported to use the RuntimeEvents instead of screen scraping - // logs, as obviously this is very brittle - final String[] options = new String[]{"--log=compiler:fine"}; - engine = nashornFactory.getScriptEngine(options); - context1 = engine.getContext(); - context2 = new SimpleScriptContext(); - context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); - context3 = new SimpleScriptContext(); - context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); - } - - @AfterTest - public void setErrTest() { - System.setErr(prevStderr); - } - - public void runTest(final int numberOfContext, final String expectedOutputPattern, - final int expectedPatternOccurrence) { - - try { - switch (numberOfContext) { - case 2: - final String scriptTwoContexts = "print('HelloTwoContexts')"; - engine.eval(scriptTwoContexts, context1); - engine.eval(scriptTwoContexts, context2); - break; - case 3: - final String scriptThreeContexts = "print('HelloThreeContexts')"; - engine.eval(scriptThreeContexts, context1); - engine.eval(scriptThreeContexts, context2); - engine.eval(scriptThreeContexts, context3); - break; - default: - break; - } - } catch (final Exception se) { - se.printStackTrace(); - fail(se.getMessage()); - } - final Pattern deoptimizing = Pattern.compile(expectedOutputPattern); - final Matcher matcher = deoptimizing.matcher(stderr.toString()); - int matches = 0; - while (matcher.find()) { - matches++; - } - if (matches != expectedPatternOccurrence) { - fail("Number of cache hit is not correct, expected: " - + expectedPatternOccurrence + " and found: " + matches + "\n" - + stderr); - } - stderr.reset(); - } - - private static String getCodeCachePattern() { - return ("\\[compiler\\]\\sCode\\scache\\shit\\sfor\\s<eval>\\savoiding\\srecompile."); - } - - @Test - public void twoContextTest() { - runTest(2, getCodeCachePattern(), 1); - - } - - @Test - public void threeContextTest() { - runTest(3, getCodeCachePattern(), 2); - } -}
--- a/test/src/jdk/nashorn/internal/runtime/SourceTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static jdk.nashorn.internal.runtime.Source.sourceFor; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; -import java.io.File; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.Reader; -import java.net.URL; -import java.util.Arrays; -import jdk.nashorn.api.scripting.URLReader; -import org.testng.annotations.Test; - -/** - * Tests different Source representations. - */ -@SuppressWarnings("javadoc") -public class SourceTest { - - final private static String SOURCE_NAME = "source.js"; - final private static String SOURCE_STRING = "var x = 1;"; - final private static char[] SOURCE_CHARS = SOURCE_STRING.toCharArray(); - final private static String RESOURCE_PATH = "resources/load_test.js"; - final private static File SOURCE_FILE = new File("build/test/classes/jdk/nashorn/internal/runtime/" + RESOURCE_PATH); - final private static URL SOURCE_URL = SourceTest.class.getResource(RESOURCE_PATH); - - - @Test - public void testStringSource() { - testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_STRING)); - testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_CHARS)); - } - - @Test - public void testCharArraySource() { - testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_CHARS)); - testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_STRING)); - } - - @Test - public void testURLSource() { - try { - testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, SOURCE_URL)); - testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); - - } catch (final IOException e) { - fail(e.toString()); - } - } - - @Test - public void testURLReaderSource() { - try { - System.err.println(SourceTest.class.getResource("")); - testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); - testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, SOURCE_URL)); - } catch (final IOException e) { - fail(e.toString()); - } - } - - @Test - public void testReaderSource() { - try { - testSources(sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH)), sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH))); - } catch (final IOException e) { - fail(e.toString()); - } - } - - @Test - public void testFileSource() { - try { - testSources(sourceFor(SOURCE_NAME, SOURCE_FILE), sourceFor(SOURCE_NAME, SOURCE_FILE)); - } catch (final IOException e) { - fail(e.toString()); - } - } - - private static Reader getReader(final String path) { - return new InputStreamReader(SourceTest.class.getResourceAsStream(path)); - } - - private static void testSources(final Source source1, final Source source2) { - final char[] chars1 = source1.getContent(); - final char[] chars2 = source2.getContent(); - final String str1 = source1.getString(); - final String str2 = source2.getString(); - assertTrue(Arrays.equals(chars1, chars2)); - assertEquals(str1, str2); - assertEquals(source1.hashCode(), source2.hashCode()); - assertTrue(source1.equals(source2)); - assertTrue(Arrays.equals(source1.getContent(), str1.toCharArray())); - assertTrue(Arrays.equals(source1.getContent(), chars1)); - assertTrue(Arrays.equals(source1.getContent(), source2.getContent())); - } -}
--- a/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,362 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertTrue; -import static org.testng.Assert.fail; -import javax.script.ScriptContext; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineFactory; -import javax.script.ScriptEngineManager; -import javax.script.ScriptException; -import javax.script.SimpleScriptContext; -import jdk.nashorn.api.scripting.ClassFilter; -import jdk.nashorn.api.scripting.NashornScriptEngineFactory; -import org.testng.annotations.Test; - -/** - * Tests for trusted client usage of nashorn script engine factory extension API - */ -@SuppressWarnings("javadoc") -public class TrustedScriptEngineTest { - @Test - public void versionTest() { - final ScriptEngineManager m = new ScriptEngineManager(); - final ScriptEngine e = m.getEngineByName("nashorn"); - assertEquals(e.getFactory().getEngineVersion(), Version.version()); - } - - private static class MyClassLoader extends ClassLoader { - // to check if script engine uses the specified class loader - private final boolean[] reached = new boolean[1]; - - @Override - protected Class<?> findClass(final String name) throws ClassNotFoundException { - // flag that it reached here - reached[0] = true; - return super.findClass(name); - } - - public boolean reached() { - return reached[0]; - } - } - - // These are for "private" extension API of NashornScriptEngineFactory that - // accepts a ClassLoader and/or command line options. - - @Test - public void factoryClassLoaderTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - final MyClassLoader loader = new MyClassLoader(); - // set the classloader as app class loader - final ScriptEngine e = nfac.getScriptEngine(loader); - try { - e.eval("Packages.foo"); - // check that the class loader was attempted - assertTrue(loader.reached(), "did not reach class loader!"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - return; - } - } - - fail("Cannot find nashorn factory!"); - } - - @Test - public void factoryClassLoaderAndOptionsTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - final String[] options = new String[] { "-strict" }; - final MyClassLoader loader = new MyClassLoader(); - // set the classloader as app class loader - final ScriptEngine e = nfac.getScriptEngine(options, loader); - try { - e.eval("Packages.foo"); - // check that the class loader was attempted - assertTrue(loader.reached(), "did not reach class loader!"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - - try { - // strict mode - delete of a var should throw SyntaxError - e.eval("var d = 2; delete d;"); - } catch (final ScriptException se) { - // check that the error message contains "SyntaxError" - assertTrue(se.getMessage().contains("SyntaxError")); - } - - return; - } - } - - fail("Cannot find nashorn factory!"); - } - - @Test - public void factoryOptionsTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - // specify --no-syntax-extensions flag - final String[] options = new String[] { "--no-syntax-extensions" }; - final ScriptEngine e = nfac.getScriptEngine(options); - try { - // try nashorn specific extension - e.eval("var f = funtion(x) 2*x;"); - fail("should have thrown exception!"); - } catch (final Exception ex) { - //empty - } - return; - } - } - - fail("Cannot find nashorn factory!"); - } - - @Test - /** - * Test repeated evals with --loader-per-compile=false - * We used to get "class redefinition error". - */ - public void noLoaderPerCompilerTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - final String[] options = new String[] { "--loader-per-compile=false" }; - final ScriptEngine e = nfac.getScriptEngine(options); - try { - e.eval("2 + 3"); - e.eval("4 + 4"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - return; - } - } - fail("Cannot find nashorn factory!"); - } - - @Test - /** - * Test that we can use same script name in repeated evals with --loader-per-compile=false - * We used to get "class redefinition error" as name was derived from script name. - */ - public void noLoaderPerCompilerWithSameNameTest() { - final ScriptEngineManager sm = new ScriptEngineManager(); - for (final ScriptEngineFactory fac : sm.getEngineFactories()) { - if (fac instanceof NashornScriptEngineFactory) { - final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; - final String[] options = new String[] { "--loader-per-compile=false" }; - final ScriptEngine e = nfac.getScriptEngine(options); - e.put(ScriptEngine.FILENAME, "test.js"); - try { - e.eval("2 + 3"); - e.eval("4 + 4"); - } catch (final ScriptException se) { - se.printStackTrace(); - fail(se.getMessage()); - } - return; - } - } - fail("Cannot find nashorn factory!"); - } - - @Test - public void globalPerEngineTest() throws ScriptException { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final String[] options = new String[] { "--global-per-engine" }; - final ScriptEngine e = fac.getScriptEngine(options); - - e.eval("function foo() {}"); - - final ScriptContext newCtx = new SimpleScriptContext(); - newCtx.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); - - // all global definitions shared and so 'foo' should be - // visible in new Bindings as well. - assertTrue(e.eval("typeof foo", newCtx).equals("function")); - - e.eval("function bar() {}", newCtx); - - // bar should be visible in default context - assertTrue(e.eval("typeof bar").equals("function")); - } - - @Test - public void classFilterTest() throws ScriptException { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine e = fac.getScriptEngine(new ClassFilter() { - @Override - public boolean exposeToScripts(final String fullName) { - // don't allow anything that is not "java." - return fullName.startsWith("java."); - } - }); - - assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); - assertEquals(e.eval("typeof java.util.Vector"), "function"); - - try { - e.eval("Java.type('javax.script.ScriptContext')"); - fail("should not reach here"); - } catch (final ScriptException | RuntimeException se) { - if (! (se.getCause() instanceof ClassNotFoundException)) { - fail("ClassNotFoundException expected"); - } - } - } - - @Test - public void classFilterTest2() throws ScriptException { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine e = fac.getScriptEngine(new String[0], Thread.currentThread().getContextClassLoader(), - new ClassFilter() { - @Override - public boolean exposeToScripts(final String fullName) { - // don't allow anything that is not "java." - return fullName.startsWith("java."); - } - }); - - assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); - assertEquals(e.eval("typeof java.util.Vector"), "function"); - - try { - e.eval("Java.type('javax.script.ScriptContext')"); - fail("should not reach here"); - } catch (final ScriptException | RuntimeException se) { - if (! (se.getCause() instanceof ClassNotFoundException)) { - fail("ClassNotFoundException expected"); - } - } - } - - @Test - public void nullClassFilterTest() { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine((ClassFilter)null); - fail("should have thrown NPE"); - } catch (final NullPointerException e) { - //empty - } - } - - @Test - public void nullClassFilterTest2() { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine(new String[0], null, null); - fail("should have thrown NPE"); - } catch (final NullPointerException e) { - //empty - } - } - - @Test - public void nullArgsTest() { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine((String[])null); - fail("should have thrown NPE"); - } catch (final NullPointerException e) { - //empty - } - } - - @Test - public void nullArgsTest2() { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - try { - fac.getScriptEngine(null, null, new ClassFilter() { - @Override - public boolean exposeToScripts(final String name) { - return true; - } - }); - fail("should have thrown NPE"); - } catch (final NullPointerException e) { - //empty - } - } - - @Test - public void nashornSwallowsConstKeyword() throws Exception { - final NashornScriptEngineFactory f = new NashornScriptEngineFactory(); - final String[] args = new String[] { "--const-as-var" }; - final ScriptEngine engine = f.getScriptEngine(args); - - final Object ret = engine.eval("" - + "(function() {\n" - + " const x = 10;\n" - + " return x;\n" - + "})();" - ); - assertEquals(ret, 10, "Parsed and executed OK"); - } - - @Test - public void evalDefaultFileNameTest() throws ScriptException { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); - // default FILENAME being "<eval>" make sure generated code bytecode verifies. - engine.eval("var a = 3;"); - } - - @Test - public void evalFileNameWithSpecialCharsTest() throws ScriptException { - final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); - final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); - final ScriptContext ctxt = new SimpleScriptContext(); - // use file name with "dangerous" chars. - ctxt.setAttribute(ScriptEngine.FILENAME, "<myscript>", ScriptContext.ENGINE_SCOPE); - engine.eval("var a = 3;"); - ctxt.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE); - engine.eval("var h = 'hello';"); - ctxt.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE); - engine.eval("var foo = 'world';"); - // name used by jjs shell tool for the interactive mode - ctxt.setAttribute(ScriptEngine.FILENAME, "<shell>", ScriptContext.ENGINE_SCOPE); - engine.eval("var foo = 'world';"); - } -}
--- a/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime.regexp; - -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertTrue; - -import org.testng.annotations.Test; - -/** - * Basic tests for the JDK based RegExp implementation. - * - * @test - * @run testng jdk.nashorn.internal.runtime.regexp.JdkRegExpTest - */ -public class JdkRegExpTest { - - /** - * Compile a regular expression using the JDK implementation - */ - @Test - public void testMatcher() { - final RegExp regexp = new RegExpFactory().compile("f(o)o", ""); - final RegExpMatcher matcher = regexp.match("foo"); - assertNotNull(matcher); - assertTrue(matcher.search(0)); - assertEquals(matcher.getInput(), "foo"); - assertEquals(matcher.groupCount(), 1); - assertEquals(matcher.group(), "foo"); - assertEquals(matcher.start(), 0); - assertEquals(matcher.end(), 3); - assertEquals(matcher.group(1), "o"); - assertEquals(matcher.start(1), 1); - assertEquals(matcher.end(1), 2); - } -}
--- a/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.nashorn.internal.runtime.regexp.joni; - -import org.testng.annotations.Test; - -/** - * Joni coverage tests - * - * @test - * @run testng jdk.nashorn.internal.runtime.regexp.joni.JoniTest - */ -@SuppressWarnings("javadoc") -public class JoniTest { - - @Test - public void testDump() { - new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpTree(); - new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpByteCode(); - new Regex("(abc){4,}{2,5}").dumpTree(); - new Regex("(abc){4,}{2,5}").dumpByteCode(); - new Regex("aaa|aa|bbbb|ccc").dumpTree(); - new Regex("aaa|aa|bbbb|ccc").dumpByteCode(); - new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpTree(); - new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpByteCode(); - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/regexp/joni/test/JoniTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.regexp.joni.test; + +import jdk.nashorn.internal.runtime.regexp.joni.Regex; +import org.testng.annotations.Test; + +/** + * Joni coverage tests + * + * @test + * @run testng jdk.nashorn.internal.runtime.regexp.joni.test.JoniTest + */ +@SuppressWarnings("javadoc") +public class JoniTest { + + @Test + public void testDump() { + new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpTree(); + new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpByteCode(); + new Regex("(abc){4,}{2,5}").dumpTree(); + new Regex("(abc){4,}{2,5}").dumpByteCode(); + new Regex("aaa|aa|bbbb|ccc").dumpTree(); + new Regex("aaa|aa|bbbb|ccc").dumpByteCode(); + new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpTree(); + new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpByteCode(); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/regexp/test/JdkRegExpTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.regexp.test; + +import jdk.nashorn.internal.runtime.regexp.RegExp; +import jdk.nashorn.internal.runtime.regexp.RegExpFactory; +import jdk.nashorn.internal.runtime.regexp.RegExpMatcher; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertNotNull; +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.Test; + +/** + * Basic tests for the JDK based RegExp implementation. + * + * @test + * @run testng jdk.nashorn.internal.runtime.regexp.test.JdkRegExpTest + */ +public class JdkRegExpTest { + + /** + * Compile a regular expression using the JDK implementation + */ + @Test + public void testMatcher() { + final RegExp regexp = new RegExpFactory().compile("f(o)o", ""); + final RegExpMatcher matcher = regexp.match("foo"); + assertNotNull(matcher); + assertTrue(matcher.search(0)); + assertEquals(matcher.getInput(), "foo"); + assertEquals(matcher.groupCount(), 1); + assertEquals(matcher.group(), "foo"); + assertEquals(matcher.start(), 0); + assertEquals(matcher.end(), 3); + assertEquals(matcher.group(1), "o"); + assertEquals(matcher.start(1), 1); + assertEquals(matcher.end(1), 2); + } +}
--- a/test/src/jdk/nashorn/internal/runtime/resources/load_test.js Wed Apr 15 14:45:25 2015 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -function loadedFunc(arg) { - return arg.toUpperCase(); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/ClassFilterTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.fail; +import java.io.File; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.ClassFilter; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import jdk.nashorn.api.scripting.URLReader; +import jdk.nashorn.internal.test.framework.TestFinder; +import org.testng.annotations.Test; + +@SuppressWarnings("javadoc") +public class ClassFilterTest { + private static final String NASHORN_CODE_CACHE = "nashorn.persistent.code.cache"; + private static final String CLASSFILTER_CODE_CACHE = "build/classfilter_nashorn_code_cache"; + + // @Test + // This test takes too much time for basic "ant clean test" run. + // Given that "allow-all-java-classes" is equivalent to no java class + // filter and external tests don't access any java, not sure if this + // test contributes much. We need faster "ant clean test" cycle for + // developers. + public void runExternalJsTest() { + final String[] paths = new String[]{ + "test/script/basic/compile-octane.js", + "test/script/basic/jquery.js", + "test/script/basic/prototype.js", + "test/script/basic/runsunspider.js", + "test/script/basic/underscore.js", + "test/script/basic/yui.js", + "test/script/basic/run-octane.js" + }; + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + for (final String path : paths) { + final ScriptEngine engine = factory.getScriptEngine(new String[]{"-scripting"}, getClass().getClassLoader(), getClassFilter()); + try { + engine.eval(new URLReader(new File(path).toURI().toURL())); + } catch (final Exception e) { + fail("Script " + path + " fails with exception :" + e.getMessage()); + } + } + } + + @Test + public void noJavaOptionTest() { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine engine = factory.getScriptEngine(new String[]{"--no-java"}, getClass().getClassLoader(), getClassFilter()); + try { + engine.eval("var str = Java.type('java.lang.String');"); + fail("TypeError should have been thrown"); + } catch (final ScriptException e) { + //emtpy + } + } + + @Test + public void securityTest() { + if (System.getSecurityManager() == null) { + return; + } + + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine engine = factory.getScriptEngine(getClassFilter()); + try { + engine.eval("var thread = Java.type('sun.misc.Unsafe')"); + fail("SecurityException should have been thrown"); + } catch (final Exception e) { + //empty + } + try { + engine.eval("var thread = new sun.misc.Unsafe()"); + fail("SecurityException should have been thrown"); + } catch (final Exception e) { + //empty + } + try { + engine.eval("var thread = Java.extend(sun.misc.Unsafe, {})"); + fail("TypeError should have been thrown"); + } catch (final Exception e) { + //empty + } + try { + engine.eval("java.lang.System.exit(0)"); + fail("SecurityException should have been thrown"); + } catch (final Exception e) { + //empty + } + + } + + @Test + public void persistentCacheTest() { + final String oldCodeCache = System.getProperty(NASHORN_CODE_CACHE); + System.setProperty(NASHORN_CODE_CACHE, CLASSFILTER_CODE_CACHE); + try { + persistentCacheTestImpl(); + } finally { + if (oldCodeCache != null) { + System.setProperty(NASHORN_CODE_CACHE, oldCodeCache); + } + } + } + + private void persistentCacheTestImpl() { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine engine = factory.getScriptEngine( + TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}), + getClass().getClassLoader(), + getClassFilter() + ); + final String testScript = "var a = Java.type('java.lang.String');" + generateCodeForPersistentStore(); + try { + engine.eval(testScript); + } catch (final ScriptException exc) { + fail(exc.getMessage()); + } + final ScriptEngine engineSafe = factory.getScriptEngine( + TestFinder.addExplicitOptimisticTypes(new String[]{"--persistent-code-cache", "--optimistic-types=true"}), + getClass().getClassLoader(), + new ClassFilter() { + @Override + public boolean exposeToScripts(final String s) { + return false; + } + } + ); + try { + engineSafe.eval(testScript); + fail("ClassNotFoundException should have been thrown"); + } catch (final Exception exc) { + if (!(exc.getCause() instanceof ClassNotFoundException)) { + fail("ClassNotFoundException expected, got " + exc.getClass()); + } + } + } + + private static String generateCodeForPersistentStore() { + final StringBuilder stringBuilder = new StringBuilder(); + for (int i=0; i < 100; i++) { + stringBuilder.append("function i") + .append(i) + .append("(y, z) { var x") + .append(i) + .append(" = ") + .append(i) + .append(";}"); + } + return stringBuilder.toString(); + } + + private static ClassFilter getClassFilter() { + return new ClassFilter() { + @Override + public boolean exposeToScripts(final String s) { + return true; + } + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/CodeStoreAndPathTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import java.io.File; +import java.io.IOException; +import java.nio.file.DirectoryStream; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.nio.file.Path; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import org.testng.annotations.Test; + +/** + * @ignore Fails with jtreg, but passes with ant test run. Ignore for now. + * @test + * @bug 8039185 8039403 + * @summary Test for persistent code cache and path handling + * @run testng jdk.nashorn.internal.runtime.test.CodeStoreAndPathTest + */ +@SuppressWarnings("javadoc") +public class CodeStoreAndPathTest { + + final String code1 = "var code1; var x = 'Hello Script'; var x1 = 'Hello Script'; " + + "var x2 = 'Hello Script'; var x3 = 'Hello Script'; " + + "var x4 = 'Hello Script'; var x5 = 'Hello Script';" + + "var x6 = 'Hello Script'; var x7 = 'Hello Script'; " + + "var x8 = 'Hello Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';" + + "function f() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function g() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function h() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function i() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}"; + final String code2 = "var code2; var x = 'Hello Script'; var x1 = 'Hello Script'; " + + "var x2 = 'Hello Script'; var x3 = 'Hello Script'; " + + "var x4 = 'Hello Script'; var x5 = 'Hello Script';" + + "var x6 = 'Hello Script'; var x7 = 'Hello Script'; " + + "var x8 = 'Hello Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';" + + "function f() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function g() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function h() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}" + + "function i() {x ='Bye Script'; x1 ='Bye Script'; x2='Bye Script';" + + "x3='Bye Script'; x4='Bye Script'; x5='Bye Script'; x6='Bye Script';" + + "x7='Bye Script'; x8='Bye Script'; var x9 = 'Hello Script'; " + + "var x10 = 'Hello Script';}"; + // Script size < Default minimum size for storing a compiled script class + final String code3 = "var code3; var x = 'Hello Script'; var x1 = 'Hello Script'; "; + final String codeCache = "build/nashorn_code_cache"; + final String oldUserDir = System.getProperty("user.dir"); + + private static final String[] ENGINE_OPTIONS_OPT = new String[]{"--persistent-code-cache", "--optimistic-types=true"}; + private static final String[] ENGINE_OPTIONS_NOOPT = new String[]{"--persistent-code-cache", "--optimistic-types=false"}; + + @Test + public void pathHandlingTest() { + System.setProperty("nashorn.persistent.code.cache", codeCache); + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + + fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); + + final Path expectedCodeCachePath = FileSystems.getDefault().getPath(oldUserDir + File.separator + codeCache); + final Path actualCodeCachePath = FileSystems.getDefault().getPath(System.getProperty( + "nashorn.persistent.code.cache")).toAbsolutePath(); + // Check that nashorn code cache is created in current working directory + assertEquals(actualCodeCachePath, expectedCodeCachePath); + // Check that code cache dir exists and it's not empty + final File file = new File(actualCodeCachePath.toUri()); + assertFalse(!file.isDirectory(), "No code cache directory was created!"); + assertFalse(file.list().length == 0, "Code cache directory is empty!"); + } + + @Test + public void changeUserDirTest() throws ScriptException, IOException { + System.setProperty("nashorn.persistent.code.cache", codeCache); + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); + final Path codeCachePath = getCodeCachePath(false); + final String newUserDir = "build/newUserDir"; + // Now changing current working directory + System.setProperty("user.dir", System.getProperty("user.dir") + File.separator + newUserDir); + try { + // Check that a new compiled script is stored in existing code cache + e.eval(code1); + final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); + checkCompiledScripts(stream, 1); + // Setting to default current working dir + } finally { + System.setProperty("user.dir", oldUserDir); + } + } + + @Test + public void codeCacheTest() throws ScriptException, IOException { + System.setProperty("nashorn.persistent.code.cache", codeCache); + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_NOOPT); + final Path codeCachePath = getCodeCachePath(false); + e.eval(code1); + e.eval(code2); + e.eval(code3);// less than minimum size for storing + // adding code1 and code2. + final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); + checkCompiledScripts(stream, 2); + } + + @Test + public void codeCacheTestOpt() throws ScriptException, IOException { + System.setProperty("nashorn.persistent.code.cache", codeCache); + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine e = fac.getScriptEngine(ENGINE_OPTIONS_OPT); + final Path codeCachePath = getCodeCachePath(true); + e.eval(code1); + e.eval(code2); + e.eval(code3);// less than minimum size for storing + // adding code1 and code2. + final DirectoryStream<Path> stream = Files.newDirectoryStream(codeCachePath); + checkCompiledScripts(stream, 2); + } + + private static Path getCodeCachePath(final boolean optimistic) { + final String codeCache = System.getProperty("nashorn.persistent.code.cache"); + final Path codeCachePath = FileSystems.getDefault().getPath(codeCache).toAbsolutePath(); + final String[] files = codeCachePath.toFile().list(); + for (final String file : files) { + if (file.endsWith("_opt") == optimistic) { + return codeCachePath.resolve(file); + } + } + throw new AssertionError("Code cache path not found"); + } + + private static void checkCompiledScripts(final DirectoryStream<Path> stream, final int numberOfScripts) throws IOException { + int n = numberOfScripts; + for (@SuppressWarnings("unused") final Path file : stream) { + n--; + } + stream.close(); + assertEquals(n, 0); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/ConsStringTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import jdk.nashorn.internal.runtime.ConsString; +import static org.testng.Assert.assertEquals; + +import org.testng.annotations.Test; + +/** + * Tests for JSType methods. + * + * @test + * @run testng jdk.nashorn.internal.runtime.test.ConsStringTest + */ +public class ConsStringTest { + + /** + * Test toString conversion + */ + @Test + public void testConsStringToString() { + final ConsString cs1 = new ConsString("b", "c"); + final ConsString cs2 = new ConsString("d", "e"); + final ConsString cs3 = new ConsString(cs1, cs2); + final ConsString cs4 = new ConsString(cs3, "f"); + final ConsString cs5 = new ConsString("a", cs4); + assertEquals(cs5.toString(), "abcdef"); + assertEquals(cs4.toString(), "bcdef"); + assertEquals(cs3.toString(), "bcde"); + assertEquals(cs2.toString(), "de"); + assertEquals(cs1.toString(), "bc"); + // ConsStrings should be flattened now + assertEquals(cs1.getComponents()[0], "bc"); + assertEquals(cs1.getComponents()[1], ""); + assertEquals(cs2.getComponents()[0], "de"); + assertEquals(cs2.getComponents()[1], ""); + assertEquals(cs3.getComponents()[0], "bcde"); + assertEquals(cs3.getComponents()[1], ""); + assertEquals(cs4.getComponents()[0], "bcdef"); + assertEquals(cs4.getComponents()[1], ""); + assertEquals(cs5.getComponents()[0], "abcdef"); + assertEquals(cs5.getComponents()[1], ""); + } + + /** + * Test charAt + */ + @Test + public void testConsStringCharAt() { + final ConsString cs1 = new ConsString("b", "c"); + final ConsString cs2 = new ConsString("d", "e"); + final ConsString cs3 = new ConsString(cs1, cs2); + final ConsString cs4 = new ConsString(cs3, "f"); + final ConsString cs5 = new ConsString("a", cs4); + assertEquals(cs1.charAt(1), 'c'); + assertEquals(cs2.charAt(0), 'd'); + assertEquals(cs3.charAt(3), 'e'); + assertEquals(cs4.charAt(1), 'c'); + assertEquals(cs5.charAt(2), 'c'); + // ConsStrings should be flattened now + assertEquals(cs1.getComponents()[0], "bc"); + assertEquals(cs1.getComponents()[1], ""); + assertEquals(cs2.getComponents()[0], "de"); + assertEquals(cs2.getComponents()[1], ""); + assertEquals(cs3.getComponents()[0], "bcde"); + assertEquals(cs3.getComponents()[1], ""); + assertEquals(cs4.getComponents()[0], "bcdef"); + assertEquals(cs4.getComponents()[1], ""); + assertEquals(cs5.getComponents()[0], "abcdef"); + assertEquals(cs5.getComponents()[1], ""); + } + + + /** + * Test flattening of top-level and internal ConsStrings + */ + @Test + public void testConsStringFlattening() { + final ConsString cs1 = new ConsString("b", "c"); + final ConsString cs2 = new ConsString("d", "e"); + final ConsString cs3 = new ConsString(cs1, cs2); + final ConsString cs4 = new ConsString(cs3, "f"); + + final ConsString cs5 = new ConsString("a", cs4); + // top-level ConsString should not yet be flattened + assert(cs5.getComponents()[0] == "a"); + assert(cs5.getComponents()[1] == cs4); + assertEquals(cs5.toString(), "abcdef"); + // top-level ConsString should be flattened + assertEquals(cs5.getComponents()[0], "abcdef"); + assertEquals(cs5.getComponents()[1], ""); + // internal ConsString should not yet be flattened after first traversal + assertEquals(cs4.getComponents()[0], cs3); + assertEquals(cs4.getComponents()[1], "f"); + + final ConsString cs6 = new ConsString("a", cs4); + // top-level ConsString should not yet be flattened + assertEquals(cs6.getComponents()[0], "a"); + assertEquals(cs6.getComponents()[1], cs4); + assertEquals(cs6.toString(), "abcdef"); + // top-level ConsString should be flattened + assertEquals(cs6.getComponents()[0], "abcdef"); + assertEquals(cs6.getComponents()[1], ""); + // internal ConsString should have been flattened after second traversal + assertEquals(cs4.getComponents()[0], "bcdef"); + assertEquals(cs4.getComponents()[1], ""); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/ContextTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; +import java.util.Map; +import jdk.nashorn.internal.objects.Global; +import jdk.nashorn.internal.runtime.Context; +import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.ScriptFunction; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.Source; +import jdk.nashorn.internal.runtime.options.Options; +import org.testng.annotations.Test; + +/** + * Basic Context API tests. + * + * @test + * @run testng jdk.nashorn.internal.runtime.test.ContextTest + */ +@SuppressWarnings("javadoc") +public class ContextTest { + // basic context eval test + @Test + public void evalTest() { + final Options options = new Options(""); + final ErrorManager errors = new ErrorManager(); + final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final Global oldGlobal = Context.getGlobal(); + Context.setGlobal(cx.createGlobal()); + try { + String code = "22 + 10"; + assertTrue(32.0 == ((Number)(eval(cx, "<evalTest>", code))).doubleValue()); + + code = "obj = { js: 'nashorn' }; obj.js"; + assertEquals(eval(cx, "<evalTest2>", code), "nashorn"); + } finally { + Context.setGlobal(oldGlobal); + } + } + + // Make sure trying to compile an invalid script returns null - see JDK-8046215. + @Test + public void compileErrorTest() { + final Options options = new Options(""); + final ErrorManager errors = new ErrorManager(); + final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final Global oldGlobal = Context.getGlobal(); + Context.setGlobal(cx.createGlobal()); + try { + final ScriptFunction script = cx.compileScript(sourceFor("<evalCompileErrorTest>", "*/"), Context.getGlobal()); + if (script != null) { + fail("Invalid script compiled without errors"); + } + if (errors.getNumberOfErrors() != 1) { + fail("Wrong number of errors: " + errors.getNumberOfErrors()); + } + } finally { + Context.setGlobal(oldGlobal); + } + } + + // basic check for JS reflection access - java.util.Map-like access on ScriptObject + @Test + public void reflectionTest() { + final Options options = new Options(""); + final ErrorManager errors = new ErrorManager(); + final Context cx = new Context(options, errors, Thread.currentThread().getContextClassLoader()); + final boolean strict = cx.getEnv()._strict; + final Global oldGlobal = Context.getGlobal(); + Context.setGlobal(cx.createGlobal()); + + try { + final String code = "var obj = { x: 344, y: 42 }"; + eval(cx, "<reflectionTest>", code); + + final Object obj = Context.getGlobal().get("obj"); + + assertTrue(obj instanceof ScriptObject); + + final ScriptObject sobj = (ScriptObject)obj; + int count = 0; + for (final Map.Entry<?, ?> ex : sobj.entrySet()) { + final Object key = ex.getKey(); + if (key.equals("x")) { + assertTrue(ex.getValue() instanceof Number); + assertTrue(344.0 == ((Number)ex.getValue()).doubleValue()); + + count++; + } else if (key.equals("y")) { + assertTrue(ex.getValue() instanceof Number); + assertTrue(42.0 == ((Number)ex.getValue()).doubleValue()); + + count++; + } + } + assertEquals(count, 2); + assertEquals(sobj.size(), 2); + + // add property + sobj.put("zee", "hello", strict); + assertEquals(sobj.get("zee"), "hello"); + assertEquals(sobj.size(), 3); + + } finally { + Context.setGlobal(oldGlobal); + } + } + + private static Object eval(final Context cx, final String name, final String code) { + final Source source = sourceFor(name, code); + final ScriptObject global = Context.getGlobal(); + final ScriptFunction func = cx.compileScript(source, global); + return func != null ? ScriptRuntime.apply(func, global) : null; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/ExceptionsNotSerializable.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.fail; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.NotSerializableException; +import java.io.ObjectOutputStream; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import jdk.nashorn.internal.runtime.RewriteException; +import jdk.nashorn.internal.runtime.UnwarrantedOptimismException; +import org.testng.annotations.Test; + +/** + * JDK-8044518: Ensure exceptions related to optimistic recompilation are not serializable + * + * @test + * @run testng jdk.nashorn.internal.runtime.test.ExceptionsNotSerializable + */ +@SuppressWarnings("javadoc") +public class ExceptionsNotSerializable { + @Test + public void rewriteExceptionNotSerializable() throws ScriptException { + // NOTE: we must create a RewriteException in a context of a Nashorn engine, as it uses Global.newIntance() + // internally. + final ScriptEngine e = new NashornScriptEngineFactory().getScriptEngine(); + e.put("f", new Runnable() { + @Override + public void run() { + tryToSerialize(RewriteException.create(null, new Object[0], new String[0])); + } + }); + e.eval("f()"); + } + + @Test + public void unwarrantedOptimismExceptionNotSerializable() { + tryToSerialize(new UnwarrantedOptimismException(new Double(1.0), 128)); + } + + private static void tryToSerialize(final Object obj) { + try { + new ObjectOutputStream(new ByteArrayOutputStream()).writeObject(obj); + fail(); + } catch (final NotSerializableException e) { + assertEquals(e.getMessage(), obj.getClass().getName()); + } catch (final IOException e) { + fail("", e); + } + + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/JSTypeTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertFalse; +import static org.testng.Assert.assertTrue; + +import org.testng.annotations.Test; + +/** + * Tests for JSType methods. + * + * @test + * @run testng jdk.nashorn.internal.runtime.test.JSTypeTest + */ +public class JSTypeTest { + /** + * Test of isPrimitive method, of class Runtime. + */ + @Test + public void testIsPrimitive() { + assertTrue(JSType.isPrimitive(null)); + assertTrue(JSType.isPrimitive(ScriptRuntime.UNDEFINED)); + assertTrue(JSType.isPrimitive(Double.NaN)); + assertTrue(JSType.isPrimitive(Double.NEGATIVE_INFINITY)); + assertTrue(JSType.isPrimitive(Double.POSITIVE_INFINITY)); + assertTrue(JSType.isPrimitive(0.0)); + assertTrue(JSType.isPrimitive(3.14)); + assertTrue(JSType.isPrimitive("hello")); + assertTrue(JSType.isPrimitive("")); + assertFalse(JSType.isPrimitive(new Object())); + } + + /** + * Test of toBoolean method, of class Runtime. + */ + @Test + public void testToBoolean() { + assertFalse(JSType.toBoolean(ScriptRuntime.UNDEFINED)); + assertFalse(JSType.toBoolean(null)); + assertFalse(JSType.toBoolean(Boolean.FALSE)); + assertTrue(JSType.toBoolean(Boolean.TRUE)); + assertFalse(JSType.toBoolean(-0.0)); + assertFalse(JSType.toBoolean(0.0)); + assertFalse(JSType.toBoolean(Double.NaN)); + assertTrue(JSType.toBoolean(3.14)); + assertFalse(JSType.toBoolean("")); + assertTrue(JSType.toBoolean("javascript")); + assertTrue(JSType.toBoolean(new Object())); + } + + /** + * Test of toNumber method, of class Runtime. + */ + @Test + public void testToNumber_Object() { + assertTrue(Double.isNaN(JSType.toNumber(ScriptRuntime.UNDEFINED))); + assertEquals(JSType.toNumber((Object)null), 0.0, 0.0); + assertEquals(JSType.toNumber(Boolean.TRUE), 1.0, 0.0); + assertEquals(JSType.toNumber(Boolean.FALSE), 0.0, 0.0); + assertEquals(JSType.toNumber(3.14), 3.14, 0.0); + // FIXME: add more assertions for specific String to number cases + // FIXME: add case for Object type (JSObject with getDefaultValue) + } + + /** + * Test of toString method, of class Runtime. + */ + @Test + public void testToString_Object() { + assertEquals(JSType.toString(ScriptRuntime.UNDEFINED), "undefined"); + assertEquals(JSType.toString(null), "null"); + assertEquals(JSType.toString(Boolean.TRUE), "true"); + assertEquals(JSType.toString(Boolean.FALSE), "false"); + assertEquals(JSType.toString(""), ""); + assertEquals(JSType.toString("nashorn"), "nashorn"); + assertEquals(JSType.toString(Double.NaN), "NaN"); + assertEquals(JSType.toString(Double.POSITIVE_INFINITY), "Infinity"); + assertEquals(JSType.toString(Double.NEGATIVE_INFINITY), "-Infinity"); + assertEquals(JSType.toString(0.0), "0"); + // FIXME: add more number-to-string test cases + // FIXME: add case for Object type (JSObject with getDefaultValue) + } + + /** + * Test of JSType.toUint32(double) + */ + @Test + public void testToUint32() { + assertEquals(JSType.toUint32(+0.0), 0); + assertEquals(JSType.toUint32(-0.0), 0); + assertEquals(JSType.toUint32(Double.NaN), 0); + assertEquals(JSType.toUint32(Double.POSITIVE_INFINITY), 0); + assertEquals(JSType.toUint32(Double.NEGATIVE_INFINITY), 0); + assertEquals(JSType.toUint32(9223372036854775807.0d), 0); + assertEquals(JSType.toUint32(-9223372036854775807.0d), 0); + assertEquals(JSType.toUint32(1099511627776.0d), 0); + assertEquals(JSType.toUint32(-1099511627776.0d), 0); + assertEquals(JSType.toUint32(4294967295.0d), 4294967295l); + assertEquals(JSType.toUint32(4294967296.0d), 0); + assertEquals(JSType.toUint32(4294967297.0d), 1); + assertEquals(JSType.toUint32(-4294967295.0d), 1); + assertEquals(JSType.toUint32(-4294967296.0d), 0); + assertEquals(JSType.toUint32(-4294967297.0d), 4294967295l); + assertEquals(JSType.toUint32(4294967295.6d), 4294967295l); + assertEquals(JSType.toUint32(4294967296.6d), 0); + assertEquals(JSType.toUint32(4294967297.6d), 1); + assertEquals(JSType.toUint32(-4294967295.6d), 1); + assertEquals(JSType.toUint32(-4294967296.6d), 0); + assertEquals(JSType.toUint32(-4294967297.6d), 4294967295l); + } + + /** + * Test of JSType.toInt32(double) + */ + @Test + public void testToInt32() { + assertEquals(JSType.toInt32(+0.0), 0); + assertEquals(JSType.toInt32(-0.0), 0); + assertEquals(JSType.toInt32(Double.NaN), 0); + assertEquals(JSType.toInt32(Double.POSITIVE_INFINITY), 0); + assertEquals(JSType.toInt32(Double.NEGATIVE_INFINITY), 0); + assertEquals(JSType.toInt32(9223372036854775807.0d), 0); + assertEquals(JSType.toInt32(-9223372036854775807.0d), 0); + assertEquals(JSType.toInt32(1099511627776.0d), 0); + assertEquals(JSType.toInt32(-1099511627776.0d), 0); + assertEquals(JSType.toInt32(4294967295.0d), -1); + assertEquals(JSType.toInt32(4294967296.0d), 0); + assertEquals(JSType.toInt32(4294967297.0d), 1); + assertEquals(JSType.toInt32(-4294967295.0d), 1); + assertEquals(JSType.toInt32(-4294967296.0d), 0); + assertEquals(JSType.toInt32(-4294967297.d), -1); + assertEquals(JSType.toInt32(4294967295.6d), -1); + assertEquals(JSType.toInt32(4294967296.6d), 0); + assertEquals(JSType.toInt32(4294967297.6d), 1); + assertEquals(JSType.toInt32(-4294967295.6d), 1); + assertEquals(JSType.toInt32(-4294967296.6d), 0); + assertEquals(JSType.toInt32(-4294967297.6d), -1); + } + + /** + * Test of JSType.toUint16(double) + */ + @Test + public void testToUint16() { + assertEquals(JSType.toUint16(+0.0), 0); + assertEquals(JSType.toUint16(-0.0), 0); + assertEquals(JSType.toUint16(Double.NaN), 0); + assertEquals(JSType.toUint16(Double.POSITIVE_INFINITY), 0); + assertEquals(JSType.toUint16(Double.NEGATIVE_INFINITY), 0); + assertEquals(JSType.toUint16(9223372036854775807.0d), 0); + assertEquals(JSType.toUint16(-9223372036854775807.0d), 0); + assertEquals(JSType.toUint16(1099511627776.0d), 0); + assertEquals(JSType.toUint16(-1099511627776.0d), 0); + assertEquals(JSType.toUint16(4294967295.0d), 65535); + assertEquals(JSType.toUint16(4294967296.0d), 0); + assertEquals(JSType.toUint16(4294967297.0d), 1); + assertEquals(JSType.toUint16(-4294967295.0d), 1); + assertEquals(JSType.toUint16(-4294967296.0d), 0); + assertEquals(JSType.toUint16(-4294967297.0d), 65535); + assertEquals(JSType.toUint16(4294967295.6d), 65535); + assertEquals(JSType.toUint16(4294967296.6d), 0); + assertEquals(JSType.toUint16(4294967297.6d), 1); + assertEquals(JSType.toUint16(-4294967295.6d), 1); + assertEquals(JSType.toUint16(-4294967296.6d), 0); + assertEquals(JSType.toUint16(-4294967297.6d), 65535); + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/LexicalBindingTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import org.testng.annotations.Test; + +import javax.script.Bindings; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; + +import static org.testng.Assert.assertEquals; + +/** + * Top-level lexical binding tests. + * + * @test + * @run testng jdk.nashorn.internal.runtime.test.LexicalBindingTest + */ +@SuppressWarnings("javadoc") +public class LexicalBindingTest { + + final static String LANGUAGE_ES6 = "--language=es6"; + final static int NUMBER_OF_CONTEXTS = 20; + final static int MEGAMORPHIC_LOOP_COUNT = 20; + + /** + * Test access to global var-declared variables for shared script classes with multiple globals. + */ + @Test + public static void megamorphicVarTest() throws ScriptException, InterruptedException { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine e = factory.getScriptEngine(); + final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS]; + final String sharedScript = "foo"; + + + for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { + final ScriptContext context = contexts[i] = new SimpleScriptContext(); + final Bindings b = e.createBindings(); + context.setBindings(b, ScriptContext.ENGINE_SCOPE); + assertEquals(e.eval("var foo = '" + i + "';", context), null); + } + + for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { + final ScriptContext context = contexts[i]; + assertEquals(e.eval(sharedScript, context), String.valueOf(i)); + } + } + + /** + * Test access to global lexically declared variables for shared script classes with multiple globals. + */ + @Test + public static void megamorphicMultiGlobalLetTest() throws ScriptException, InterruptedException { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); + final ScriptContext[] contexts = new ScriptContext[NUMBER_OF_CONTEXTS]; + final String sharedScript = "foo"; + + + for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { + final ScriptContext context = contexts[i] = new SimpleScriptContext(); + final Bindings b = e.createBindings(); + context.setBindings(b, ScriptContext.ENGINE_SCOPE); + assertEquals(e.eval("let foo = '" + i + "';", context), null); + } + + for (int i = 0; i < NUMBER_OF_CONTEXTS; i++) { + final ScriptContext context = contexts[i]; + assertEquals(e.eval(sharedScript, context), String.valueOf(i)); + } + } + + + /** + * Test access to global lexically declared variables for shared script classes with single global. + */ + @Test + public static void megamorphicSingleGlobalLetTest() throws ScriptException, InterruptedException { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); + final String sharedGetterScript = "foo"; + final String sharedSetterScript = "foo = 1"; + + for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) { + assertEquals(e.eval(sharedSetterScript), 1); + assertEquals(e.eval(sharedGetterScript), 1); + assertEquals(e.eval("delete foo; a" + i + " = 1; foo = " + i + ";"), i); + assertEquals(e.eval(sharedGetterScript), i); + } + + assertEquals(e.eval("let foo = 'foo';"), null); + assertEquals(e.eval(sharedGetterScript), "foo"); + assertEquals(e.eval(sharedSetterScript), 1); + assertEquals(e.eval(sharedGetterScript), 1); + assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1); + } + + /** + * Test access to global lexically declared variables for shared script classes with single global. + */ + @Test + public static void megamorphicInheritedGlobalLetTest() throws ScriptException, InterruptedException { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); + final String sharedGetterScript = "foo"; + final String sharedSetterScript = "foo = 1"; + + for (int i = 0; i < MEGAMORPHIC_LOOP_COUNT; i++) { + assertEquals(e.eval(sharedSetterScript), 1); + assertEquals(e.eval(sharedGetterScript), 1); + assertEquals(e.eval("delete foo; a" + i + " = 1; Object.prototype.foo = " + i + ";"), i); + assertEquals(e.eval(sharedGetterScript), i); + } + + assertEquals(e.eval("let foo = 'foo';"), null); + assertEquals(e.eval(sharedGetterScript), "foo"); + assertEquals(e.eval(sharedSetterScript), 1); + assertEquals(e.eval(sharedGetterScript), 1); + assertEquals(e.eval("this.foo"), MEGAMORPHIC_LOOP_COUNT - 1); + } + + /** + * Test multi-threaded access to global lexically declared variables for shared script classes with multiple globals. + */ + @Test + public static void multiThreadedLetTest() throws ScriptException, InterruptedException { + final NashornScriptEngineFactory factory = new NashornScriptEngineFactory(); + final ScriptEngine e = factory.getScriptEngine(LANGUAGE_ES6); + final Bindings b = e.createBindings(); + final ScriptContext origContext = e.getContext(); + final ScriptContext newCtxt = new SimpleScriptContext(); + newCtxt.setBindings(b, ScriptContext.ENGINE_SCOPE); + final String sharedScript = "foo"; + + assertEquals(e.eval("let foo = 'original context';", origContext), null); + assertEquals(e.eval("let foo = 'new context';", newCtxt), null); + + final Thread t1 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t2 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "new context", 1000)); + t1.start(); + t2.start(); + t1.join(); + t2.join(); + + assertEquals(e.eval("foo = 'newer context';", newCtxt), "newer context"); + final Thread t3 = new Thread(new ScriptRunner(e, origContext, sharedScript, "original context", 1000)); + final Thread t4 = new Thread(new ScriptRunner(e, newCtxt, sharedScript, "newer context", 1000)); + + t3.start(); + t4.start(); + t3.join(); + t4.join(); + + assertEquals(e.eval(sharedScript), "original context"); + assertEquals(e.eval(sharedScript, newCtxt), "newer context"); + } + + private static class ScriptRunner implements Runnable { + + final ScriptEngine engine; + final ScriptContext context; + final String source; + final Object expected; + final int iterations; + + ScriptRunner(final ScriptEngine engine, final ScriptContext context, final String source, final Object expected, final int iterations) { + this.engine = engine; + this.context = context; + this.source = source; + this.expected = expected; + this.iterations = iterations; + } + + @Override + public void run() { + try { + for (int i = 0; i < iterations; i++) { + assertEquals(engine.eval(source, context), expected); + } + } catch (final ScriptException se) { + throw new RuntimeException(se); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/NoPersistenceCachingTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.fail; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; +import javax.script.SimpleScriptContext; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.Test; + +/** + * @test + * @bug 8037378 + * @summary Sanity tests for no persistence caching + * @run testng/othervm jdk.nashorn.internal.runtime.test.NoPersistenceCachingTest + */ +@SuppressWarnings("javadoc") +public class NoPersistenceCachingTest { + + private ScriptEngine engine; + private ScriptContext context1, context2, context3; + private ByteArrayOutputStream stderr; + private PrintStream prevStderr; + + @BeforeTest + public void setupTest() { + stderr = new ByteArrayOutputStream(); + prevStderr = System.err; + System.setErr(new PrintStream(stderr)); + NashornScriptEngineFactory nashornFactory = null; + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + nashornFactory = (NashornScriptEngineFactory) fac; + break; + } + } + if (nashornFactory == null) { + fail("Cannot find nashorn factory!"); + } + // fine is enough for cache hits, finest produces way too much information + // TODO this should be ported to use the RuntimeEvents instead of screen scraping + // logs, as obviously this is very brittle + final String[] options = new String[]{"--log=compiler:fine"}; + engine = nashornFactory.getScriptEngine(options); + context1 = engine.getContext(); + context2 = new SimpleScriptContext(); + context2.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); + context3 = new SimpleScriptContext(); + context3.setBindings(engine.createBindings(), ScriptContext.ENGINE_SCOPE); + } + + @AfterTest + public void setErrTest() { + System.setErr(prevStderr); + } + + public void runTest(final int numberOfContext, final String expectedOutputPattern, + final int expectedPatternOccurrence) { + + try { + switch (numberOfContext) { + case 2: + final String scriptTwoContexts = "print('HelloTwoContexts')"; + engine.eval(scriptTwoContexts, context1); + engine.eval(scriptTwoContexts, context2); + break; + case 3: + final String scriptThreeContexts = "print('HelloThreeContexts')"; + engine.eval(scriptThreeContexts, context1); + engine.eval(scriptThreeContexts, context2); + engine.eval(scriptThreeContexts, context3); + break; + default: + break; + } + } catch (final Exception se) { + se.printStackTrace(); + fail(se.getMessage()); + } + final Pattern deoptimizing = Pattern.compile(expectedOutputPattern); + final Matcher matcher = deoptimizing.matcher(stderr.toString()); + int matches = 0; + while (matcher.find()) { + matches++; + } + if (matches != expectedPatternOccurrence) { + fail("Number of cache hit is not correct, expected: " + + expectedPatternOccurrence + " and found: " + matches + "\n" + + stderr); + } + stderr.reset(); + } + + private static String getCodeCachePattern() { + return ("\\[compiler\\]\\sCode\\scache\\shit\\sfor\\s<eval>\\savoiding\\srecompile."); + } + + @Test + public void twoContextTest() { + runTest(2, getCodeCachePattern(), 1); + + } + + @Test + public void threeContextTest() { + runTest(3, getCodeCachePattern(), 2); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/SourceTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import static jdk.nashorn.internal.runtime.Source.sourceFor; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.Reader; +import java.net.URL; +import java.util.Arrays; +import jdk.nashorn.api.scripting.URLReader; +import jdk.nashorn.internal.runtime.Source; +import org.testng.annotations.Test; + +/** + * Tests different Source representations. + */ +@SuppressWarnings("javadoc") +public class SourceTest { + + final private static String SOURCE_NAME = "source.js"; + final private static String SOURCE_STRING = "var x = 1;"; + final private static char[] SOURCE_CHARS = SOURCE_STRING.toCharArray(); + final private static String RESOURCE_PATH = "resources/load_test.js"; + final private static File SOURCE_FILE = new File("build/test/classes/jdk/nashorn/internal/runtime/test/" + RESOURCE_PATH); + final private static URL SOURCE_URL = SourceTest.class.getResource(RESOURCE_PATH); + + + @Test + public void testStringSource() { + testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_STRING)); + testSources(sourceFor(SOURCE_NAME, SOURCE_STRING), sourceFor(SOURCE_NAME, SOURCE_CHARS)); + } + + @Test + public void testCharArraySource() { + testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_CHARS)); + testSources(sourceFor(SOURCE_NAME, SOURCE_CHARS), sourceFor(SOURCE_NAME, SOURCE_STRING)); + } + + @Test + public void testURLSource() { + try { + testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, SOURCE_URL)); + testSources(sourceFor(SOURCE_NAME, SOURCE_URL), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); + + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testURLReaderSource() { + try { + System.err.println(SourceTest.class.getResource("")); + testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL))); + testSources(sourceFor(SOURCE_NAME, new URLReader(SOURCE_URL)), sourceFor(SOURCE_NAME, SOURCE_URL)); + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testReaderSource() { + try { + testSources(sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH)), sourceFor(SOURCE_NAME, getReader(RESOURCE_PATH))); + } catch (final IOException e) { + fail(e.toString()); + } + } + + @Test + public void testFileSource() { + try { + testSources(sourceFor(SOURCE_NAME, SOURCE_FILE), sourceFor(SOURCE_NAME, SOURCE_FILE)); + } catch (final IOException e) { + fail(e.toString()); + } + } + + private static Reader getReader(final String path) { + return new InputStreamReader(SourceTest.class.getResourceAsStream(path)); + } + + private static void testSources(final Source source1, final Source source2) { + final char[] chars1 = source1.getContent(); + final char[] chars2 = source2.getContent(); + final String str1 = source1.getString(); + final String str2 = source2.getString(); + assertTrue(Arrays.equals(chars1, chars2)); + assertEquals(str1, str2); + assertEquals(source1.hashCode(), source2.hashCode()); + assertTrue(source1.equals(source2)); + assertTrue(Arrays.equals(source1.getContent(), str1.toCharArray())); + assertTrue(Arrays.equals(source1.getContent(), chars1)); + assertTrue(Arrays.equals(source1.getContent(), source2.getContent())); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/TrustedScriptEngineTest.java Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.runtime.test; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; +import static org.testng.Assert.fail; +import javax.script.ScriptContext; +import javax.script.ScriptEngine; +import javax.script.ScriptEngineFactory; +import javax.script.ScriptEngineManager; +import javax.script.ScriptException; +import javax.script.SimpleScriptContext; +import jdk.nashorn.api.scripting.ClassFilter; +import jdk.nashorn.api.scripting.NashornScriptEngineFactory; +import jdk.nashorn.internal.runtime.Version; +import org.testng.annotations.Test; + +/** + * Tests for trusted client usage of nashorn script engine factory extension API + */ +@SuppressWarnings("javadoc") +public class TrustedScriptEngineTest { + @Test + public void versionTest() { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + assertEquals(e.getFactory().getEngineVersion(), Version.version()); + } + + private static class MyClassLoader extends ClassLoader { + // to check if script engine uses the specified class loader + private final boolean[] reached = new boolean[1]; + + @Override + protected Class<?> findClass(final String name) throws ClassNotFoundException { + // flag that it reached here + reached[0] = true; + return super.findClass(name); + } + + public boolean reached() { + return reached[0]; + } + } + + // These are for "private" extension API of NashornScriptEngineFactory that + // accepts a ClassLoader and/or command line options. + + @Test + public void factoryClassLoaderTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final MyClassLoader loader = new MyClassLoader(); + // set the classloader as app class loader + final ScriptEngine e = nfac.getScriptEngine(loader); + try { + e.eval("Packages.foo"); + // check that the class loader was attempted + assertTrue(loader.reached(), "did not reach class loader!"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + return; + } + } + + fail("Cannot find nashorn factory!"); + } + + @Test + public void factoryClassLoaderAndOptionsTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final String[] options = new String[] { "-strict" }; + final MyClassLoader loader = new MyClassLoader(); + // set the classloader as app class loader + final ScriptEngine e = nfac.getScriptEngine(options, loader); + try { + e.eval("Packages.foo"); + // check that the class loader was attempted + assertTrue(loader.reached(), "did not reach class loader!"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + + try { + // strict mode - delete of a var should throw SyntaxError + e.eval("var d = 2; delete d;"); + } catch (final ScriptException se) { + // check that the error message contains "SyntaxError" + assertTrue(se.getMessage().contains("SyntaxError")); + } + + return; + } + } + + fail("Cannot find nashorn factory!"); + } + + @Test + public void factoryOptionsTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + // specify --no-syntax-extensions flag + final String[] options = new String[] { "--no-syntax-extensions" }; + final ScriptEngine e = nfac.getScriptEngine(options); + try { + // try nashorn specific extension + e.eval("var f = funtion(x) 2*x;"); + fail("should have thrown exception!"); + } catch (final Exception ex) { + //empty + } + return; + } + } + + fail("Cannot find nashorn factory!"); + } + + @Test + /** + * Test repeated evals with --loader-per-compile=false + * We used to get "class redefinition error". + */ + public void noLoaderPerCompilerTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final String[] options = new String[] { "--loader-per-compile=false" }; + final ScriptEngine e = nfac.getScriptEngine(options); + try { + e.eval("2 + 3"); + e.eval("4 + 4"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + return; + } + } + fail("Cannot find nashorn factory!"); + } + + @Test + /** + * Test that we can use same script name in repeated evals with --loader-per-compile=false + * We used to get "class redefinition error" as name was derived from script name. + */ + public void noLoaderPerCompilerWithSameNameTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (final ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final String[] options = new String[] { "--loader-per-compile=false" }; + final ScriptEngine e = nfac.getScriptEngine(options); + e.put(ScriptEngine.FILENAME, "test.js"); + try { + e.eval("2 + 3"); + e.eval("4 + 4"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + return; + } + } + fail("Cannot find nashorn factory!"); + } + + @Test + public void globalPerEngineTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final String[] options = new String[] { "--global-per-engine" }; + final ScriptEngine e = fac.getScriptEngine(options); + + e.eval("function foo() {}"); + + final ScriptContext newCtx = new SimpleScriptContext(); + newCtx.setBindings(e.createBindings(), ScriptContext.ENGINE_SCOPE); + + // all global definitions shared and so 'foo' should be + // visible in new Bindings as well. + assertTrue(e.eval("typeof foo", newCtx).equals("function")); + + e.eval("function bar() {}", newCtx); + + // bar should be visible in default context + assertTrue(e.eval("typeof bar").equals("function")); + } + + @Test + public void classFilterTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine e = fac.getScriptEngine(new ClassFilter() { + @Override + public boolean exposeToScripts(final String fullName) { + // don't allow anything that is not "java." + return fullName.startsWith("java."); + } + }); + + assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); + assertEquals(e.eval("typeof java.util.Vector"), "function"); + + try { + e.eval("Java.type('javax.script.ScriptContext')"); + fail("should not reach here"); + } catch (final ScriptException | RuntimeException se) { + if (! (se.getCause() instanceof ClassNotFoundException)) { + fail("ClassNotFoundException expected"); + } + } + } + + @Test + public void classFilterTest2() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine e = fac.getScriptEngine(new String[0], Thread.currentThread().getContextClassLoader(), + new ClassFilter() { + @Override + public boolean exposeToScripts(final String fullName) { + // don't allow anything that is not "java." + return fullName.startsWith("java."); + } + }); + + assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); + assertEquals(e.eval("typeof java.util.Vector"), "function"); + + try { + e.eval("Java.type('javax.script.ScriptContext')"); + fail("should not reach here"); + } catch (final ScriptException | RuntimeException se) { + if (! (se.getCause() instanceof ClassNotFoundException)) { + fail("ClassNotFoundException expected"); + } + } + } + + @Test + public void nullClassFilterTest() { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine((ClassFilter)null); + fail("should have thrown NPE"); + } catch (final NullPointerException e) { + //empty + } + } + + @Test + public void nullClassFilterTest2() { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine(new String[0], null, null); + fail("should have thrown NPE"); + } catch (final NullPointerException e) { + //empty + } + } + + @Test + public void nullArgsTest() { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine((String[])null); + fail("should have thrown NPE"); + } catch (final NullPointerException e) { + //empty + } + } + + @Test + public void nullArgsTest2() { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + try { + fac.getScriptEngine(null, null, new ClassFilter() { + @Override + public boolean exposeToScripts(final String name) { + return true; + } + }); + fail("should have thrown NPE"); + } catch (final NullPointerException e) { + //empty + } + } + + @Test + public void nashornSwallowsConstKeyword() throws Exception { + final NashornScriptEngineFactory f = new NashornScriptEngineFactory(); + final String[] args = new String[] { "--const-as-var" }; + final ScriptEngine engine = f.getScriptEngine(args); + + final Object ret = engine.eval("" + + "(function() {\n" + + " const x = 10;\n" + + " return x;\n" + + "})();" + ); + assertEquals(ret, 10, "Parsed and executed OK"); + } + + @Test + public void evalDefaultFileNameTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); + // default FILENAME being "<eval>" make sure generated code bytecode verifies. + engine.eval("var a = 3;"); + } + + @Test + public void evalFileNameWithSpecialCharsTest() throws ScriptException { + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); + final ScriptEngine engine = fac.getScriptEngine(new String[] { "--verify-code=true" }); + final ScriptContext ctxt = new SimpleScriptContext(); + // use file name with "dangerous" chars. + ctxt.setAttribute(ScriptEngine.FILENAME, "<myscript>", ScriptContext.ENGINE_SCOPE); + engine.eval("var a = 3;"); + ctxt.setAttribute(ScriptEngine.FILENAME, "[myscript]", ScriptContext.ENGINE_SCOPE); + engine.eval("var h = 'hello';"); + ctxt.setAttribute(ScriptEngine.FILENAME, ";/\\$.", ScriptContext.ENGINE_SCOPE); + engine.eval("var foo = 'world';"); + // name used by jjs shell tool for the interactive mode + ctxt.setAttribute(ScriptEngine.FILENAME, "<shell>", ScriptContext.ENGINE_SCOPE); + engine.eval("var foo = 'world';"); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/src/jdk/nashorn/internal/runtime/test/resources/load_test.js Thu Apr 16 16:01:11 2015 -0700 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +function loadedFunc(arg) { + return arg.toUpperCase(); +}