diff options
author | robm <none@none> | 2017-01-04 19:44:40 +0000 |
---|---|---|
committer | robm <none@none> | 2017-01-04 19:44:40 +0000 |
commit | b825ce88a014b466ad3a6f4c3812be1e00b77d03 (patch) | |
tree | a8097065b66f98bd17c37d6c36e09a7b91c54896 | |
parent | fb152de042bfc2020c9377fb3b4fa9846152e9b1 (diff) | |
parent | 9102bbfc23f2288eccfed2dc67a404a21fe4a27b (diff) | |
download | jdk8u_nashorn-b825ce88a014b466ad3a6f4c3812be1e00b77d03.tar.gz |
Merge
10 files changed, 329 insertions, 36 deletions
diff --git a/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/src/jdk/nashorn/internal/codegen/CodeGenerator.java index b2a31646..6b9b731f 100644 --- a/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -4016,7 +4016,7 @@ final class CodeGenerator extends NodeOperatorVisitor<CodeGeneratorLexicalContex void loadStack() { assert assignNode.getWidestOperandType() == Type.INT; if (isRhsZero(binaryNode)) { - loadExpressionAsType(binaryNode.lhs(), Type.INT); + loadExpression(binaryNode.lhs(), TypeBounds.INT, true); } else { loadBinaryOperands(binaryNode.lhs(), binaryNode.rhs(), TypeBounds.INT, true, false); method.shr(); diff --git a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java index 310a0875..63bafa71 100644 --- a/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java +++ b/src/jdk/nashorn/internal/codegen/LocalVariableTypesCalculator.java @@ -33,6 +33,7 @@ import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collections; import java.util.Deque; +import java.util.HashMap; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Iterator; @@ -122,9 +123,9 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { private final List<JumpOrigin> origins = new LinkedList<>(); private Map<Symbol, LvarType> types = Collections.emptyMap(); - void addOrigin(final JoinPredecessor originNode, final Map<Symbol, LvarType> originTypes) { + void addOrigin(final JoinPredecessor originNode, final Map<Symbol, LvarType> originTypes, final LocalVariableTypesCalculator calc) { origins.add(new JumpOrigin(originNode, originTypes)); - this.types = getUnionTypes(this.types, originTypes); + this.types = calc.getUnionTypes(this.types, originTypes); } } private enum LvarType { @@ -185,12 +186,15 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { } @SuppressWarnings("unchecked") - private static IdentityHashMap<Symbol, LvarType> cloneMap(final Map<Symbol, LvarType> map) { - return (IdentityHashMap<Symbol, LvarType>)((IdentityHashMap<?,?>)map).clone(); + private static HashMap<Symbol, LvarType> cloneMap(final Map<Symbol, LvarType> map) { + return (HashMap<Symbol, LvarType>)((HashMap<?,?>)map).clone(); } private LocalVariableConversion createConversion(final Symbol symbol, final LvarType branchLvarType, final Map<Symbol, LvarType> joinLvarTypes, final LocalVariableConversion next) { + if (invalidatedSymbols.contains(symbol)) { + return next; + } final LvarType targetType = joinLvarTypes.get(symbol); assert targetType != null; if(targetType == branchLvarType) { @@ -208,7 +212,7 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { return new LocalVariableConversion(symbol, branchLvarType.type, targetType.type, next); } - private static Map<Symbol, LvarType> getUnionTypes(final Map<Symbol, LvarType> types1, final Map<Symbol, LvarType> types2) { + private Map<Symbol, LvarType> getUnionTypes(final Map<Symbol, LvarType> types1, final Map<Symbol, LvarType> types2) { if(types1 == types2 || types1.isEmpty()) { return types2; } else if(types2.isEmpty()) { @@ -261,6 +265,11 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { final LvarType type2 = types2.get(symbol); union.put(symbol, widestLvarType(type1, type2)); } + // If the two sets of symbols differ, there's a good chance that some of + // symbols only appearing in one of the sets are lexically invalidated, + // so we remove them from further consideration. + // This is not strictly necessary, just a working set size optimization. + union.keySet().removeAll(invalidatedSymbols); return union; } @@ -359,8 +368,6 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { if(t1.ordinal() < LvarType.INT.ordinal() || t2.ordinal() < LvarType.INT.ordinal()) { return LvarType.OBJECT; } - // NOTE: we allow "widening" of long to double even though it can lose precision. ECMAScript doesn't have an - // Int64 type anyway, so this loss of precision is actually more conformant to the specification... return LvarType.values()[Math.max(t1.ordinal(), t2.ordinal())]; } private final Compiler compiler; @@ -368,7 +375,10 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { // Local variable type mapping at the currently evaluated point. No map instance is ever modified; setLvarType() always // allocates a new map. Immutability of maps allows for cheap snapshots by just keeping the reference to the current // value. - private Map<Symbol, LvarType> localVariableTypes = new IdentityHashMap<>(); + private Map<Symbol, LvarType> localVariableTypes = Collections.emptyMap(); + // Set of symbols whose lexical scope has already ended. + private final Set<Symbol> invalidatedSymbols = new HashSet<>(); + // Stack for evaluated expression types. private final Deque<LvarType> typeStack = new ArrayDeque<>(); @@ -464,9 +474,19 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { @Override public boolean enterBlock(final Block block) { + boolean cloned = false; for(final Symbol symbol: block.getSymbols()) { - if(symbol.isBytecodeLocal() && getLocalVariableTypeOrNull(symbol) == null) { - setType(symbol, LvarType.UNDEFINED); + if(symbol.isBytecodeLocal()) { + if (getLocalVariableTypeOrNull(symbol) == null) { + if (!cloned) { + cloneOrNewLocalVariableTypes(); + cloned = true; + } + localVariableTypes.put(symbol, LvarType.UNDEFINED); + } + // In case we're repeating analysis of a lexical scope (e.g. it's in a loop), + // make sure all symbols lexically scoped by the block become valid again. + invalidatedSymbols.remove(symbol); } } return true; @@ -1046,15 +1066,11 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { // throw an exception. reachable = true; catchBody.accept(this); - final Symbol exceptionSymbol = exception.getSymbol(); if(reachable) { - localVariableTypes = cloneMap(localVariableTypes); - localVariableTypes.remove(exceptionSymbol); jumpToLabel(catchBody, endLabel); canExit = true; } - localVariableTypes = cloneMap(afterConditionTypes); - localVariableTypes.remove(exceptionSymbol); + localVariableTypes = afterConditionTypes; } // NOTE: if we had one or more conditional catch blocks with no unconditional catch block following them, then // there will be an unconditional rethrow, so the join point can never be reached from the last @@ -1204,7 +1220,7 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { } private void jumpToLabel(final JoinPredecessor jumpOrigin, final Label label, final Map<Symbol, LvarType> types) { - getOrCreateJumpTarget(label).addOrigin(jumpOrigin, types); + getOrCreateJumpTarget(label).addOrigin(jumpOrigin, types, this); } @Override @@ -1226,16 +1242,18 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { boolean cloned = false; for(final Symbol symbol: block.getSymbols()) { - // Undefine the symbol outside the block - if(localVariableTypes.containsKey(symbol)) { - if(!cloned) { - localVariableTypes = cloneMap(localVariableTypes); - cloned = true; + if(symbol.hasSlot()) { + // Invalidate the symbol when its defining block ends + if (symbol.isBytecodeLocal()) { + if(localVariableTypes.containsKey(symbol)) { + if(!cloned) { + localVariableTypes = cloneMap(localVariableTypes); + cloned = true; + } + } + invalidateSymbol(symbol); } - localVariableTypes.remove(symbol); - } - if(symbol.hasSlot()) { final SymbolConversions conversions = symbolConversions.get(symbol); if(conversions != null) { // Potentially make some currently dead types live if they're needed as a source of a type @@ -1605,10 +1623,19 @@ final class LocalVariableTypesCalculator extends SimpleNodeVisitor { } assert symbol.hasSlot(); assert !symbol.isGlobal(); - localVariableTypes = localVariableTypes.isEmpty() ? new IdentityHashMap<Symbol, LvarType>() : cloneMap(localVariableTypes); + cloneOrNewLocalVariableTypes(); localVariableTypes.put(symbol, type); } + private void cloneOrNewLocalVariableTypes() { + localVariableTypes = localVariableTypes.isEmpty() ? new HashMap<Symbol, LvarType>() : cloneMap(localVariableTypes); + } + + private void invalidateSymbol(final Symbol symbol) { + localVariableTypes.remove(symbol); + invalidatedSymbols.add(symbol); + } + /** * Set a flag in the symbol marking it as needing to be able to store a value of a particular type. Every symbol for * a local variable will be assigned between 1 and 6 local variable slots for storing all types it is known to need diff --git a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java index bb8d61a5..fccad153 100644 --- a/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java +++ b/src/jdk/nashorn/internal/ir/debug/PrintVisitor.java @@ -397,7 +397,7 @@ public final class PrintVisitor extends SimpleNodeVisitor { @Override public boolean enterVarNode(final VarNode varNode) { - sb.append("var "); + sb.append(varNode.isConst() ? "const " : varNode.isLet() ? "let " : "var "); varNode.getName().toString(sb, printTypes); printLocalVariableConversion(varNode.getName()); final Node init = varNode.getInit(); diff --git a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java index e8e493b3..7eb23a9b 100644 --- a/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java +++ b/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java @@ -39,9 +39,13 @@ import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.nashorn.api.scripting.JSObject; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.lookup.MethodHandleFunctionality; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.objects.Global; /** * A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well @@ -141,9 +145,9 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { } private static GuardedInvocation findCallMethod(final CallSiteDescriptor desc) { - MethodHandle mh = JSOBJECT_CALL; + MethodHandle mh = NashornCallSiteDescriptor.isScope(desc)? JSOBJECT_SCOPE_CALL : JSOBJECT_CALL; if (NashornCallSiteDescriptor.isApplyToCall(desc)) { - mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, JSOBJECT_CALL); + mh = MH.insertArguments(JSOBJECT_CALL_TO_APPLY, 0, mh); } final MethodType type = desc.getMethodType(); mh = type.parameterType(type.parameterCount() - 1) == Object[].class ? @@ -214,6 +218,19 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { } } + // This is used when a JSObject is called as scope call to do undefined -> Global this translation. + @SuppressWarnings("unused") + private static Object jsObjectScopeCall(final JSObject jsObj, final Object thiz, final Object[] args) { + final Object modifiedThiz; + if (thiz == ScriptRuntime.UNDEFINED && !jsObj.isStrictFunction()) { + final Global global = Context.getGlobal(); + modifiedThiz = ScriptObjectMirror.wrap(global, global); + } else { + modifiedThiz = thiz; + } + return jsObj.call(modifiedThiz, args); + } + private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality(); // method handles of the current class @@ -225,6 +242,7 @@ final class JSObjectLinker implements TypeBasedGuardingDynamicLinker { private static final MethodHandle JSOBJECT_GETMEMBER = findJSObjectMH_V("getMember", Object.class, String.class); private static final MethodHandle JSOBJECT_SETMEMBER = findJSObjectMH_V("setMember", Void.TYPE, String.class, Object.class); private static final MethodHandle JSOBJECT_CALL = findJSObjectMH_V("call", Object.class, Object.class, Object[].class); + private static final MethodHandle JSOBJECT_SCOPE_CALL = findOwnMH_S("jsObjectScopeCall", Object.class, JSObject.class, Object.class, Object[].class); private static final MethodHandle JSOBJECT_CALL_TO_APPLY = findOwnMH_S("callToApply", Object.class, MethodHandle.class, JSObject.class, Object.class, Object[].class); private static final MethodHandle JSOBJECT_NEW = findJSObjectMH_V("newObject", Object.class, Object[].class); diff --git a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java index ddcbae1f..b8e01ffd 100644 --- a/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java +++ b/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java @@ -251,15 +251,15 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp @Override public Comparison compareConversion(final Class<?> sourceType, final Class<?> targetType1, final Class<?> targetType2) { if(sourceType == NativeArray.class) { - // Prefer lists, as they're less costly to create than arrays. - if(isList(targetType1)) { - if(!isList(targetType2)) { + // Prefer those types we can convert to with just a wrapper (cheaper than Java array creation). + if(isArrayPreferredTarget(targetType1)) { + if(!isArrayPreferredTarget(targetType2)) { return Comparison.TYPE_1_BETTER; } - } else if(isList(targetType2)) { + } else if(isArrayPreferredTarget(targetType2)) { return Comparison.TYPE_2_BETTER; } - // Then prefer arrays + // Then prefer Java arrays if(targetType1.isArray()) { if(!targetType2.isArray()) { return Comparison.TYPE_1_BETTER; @@ -281,8 +281,8 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp return Comparison.INDETERMINATE; } - private static boolean isList(final Class<?> clazz) { - return clazz == List.class || clazz == Deque.class; + private static boolean isArrayPreferredTarget(final Class<?> clazz) { + return clazz == List.class || clazz == Collection.class || clazz == Queue.class || clazz == Deque.class; } private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class)); diff --git a/test/script/basic/JDK-8170594.js b/test/script/basic/JDK-8170594.js new file mode 100644 index 00000000..6365500a --- /dev/null +++ b/test/script/basic/JDK-8170594.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016 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-8170594: >>>=0 generates invalid bytecode for BaseNode LHS + * + * @test + * @run + */ + +var obj1 = {x: "100"}; +(function (o, p) { + if (p) { + o.x >>>= 0; + } +})(obj1, true) +Assert.assertTrue(obj1.x === 100) + +var obj2 = ["100"]; +(function (o, p) { + if (p) { + o[0] >>>= 0; + } +})(obj2, true) +Assert.assertTrue(obj2[0] === 100) diff --git a/test/script/basic/JDK-8171849.js b/test/script/basic/JDK-8171849.js new file mode 100644 index 00000000..febc97ce --- /dev/null +++ b/test/script/basic/JDK-8171849.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2016 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-8171849: Collection and Queue conversions not prioritized for Arrays + * + * @test + * @run + */ + +var acp = new (Java.type("jdk.nashorn.test.models.ArrayConversionPreferences")) + +var a = [1, "", {}] + +Assert.assertTrue(acp.testCollectionOverMap(a)) +Assert.assertTrue(acp.testCollectionOverArray(a)) +Assert.assertTrue(acp.testListOverMap(a)) +Assert.assertTrue(acp.testListOverArray(a)) +Assert.assertTrue(acp.testListOverCollection(a)) +Assert.assertTrue(acp.testQueueOverMap(a)) +Assert.assertTrue(acp.testQueueOverArray(a)) +Assert.assertTrue(acp.testQueueOverCollection(a)) +Assert.assertTrue(acp.testDequeOverMap(a)) +Assert.assertTrue(acp.testDequeOverArray(a)) +Assert.assertTrue(acp.testDequeOverCollection(a)) +Assert.assertTrue(acp.testDequeOverQueue(a)) +Assert.assertTrue(acp.testArrayOverMap(a)) diff --git a/test/script/basic/es6/JDK-8168373.js b/test/script/basic/es6/JDK-8168373.js new file mode 100644 index 00000000..af26e735 --- /dev/null +++ b/test/script/basic/es6/JDK-8168373.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2016 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-8168373: don't emit conversions for symbols outside their lexical scope + * + * @test + * @run + * @option --language=es6 + */ + +function p() { return false } // "predicate" +function r(x) { return x } // "read" + +(function() { + try { // Try creates control flow edges from assignments into catch blocks. + // Lexically scoped, never read int variable (undefined at catch block) but still with a cf edge into catch block. + // Since it's never read, it's not written either (Nashorn optimizes some dead writes). + let x = 0; + if (p()) { throw {}; } // We need `p()` so this block doesn't get optimized away, for possibility of a `throw` + x = 0.0; // change the type of x to double + r(x); // read x otherwise it's optimized away + } catch (e) {} // under the bug, "throw" will try to widen unwritten int x to double for here and cause a verifier error +})() diff --git a/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java index f9c78fc7..7656dc6b 100644 --- a/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java +++ b/test/src/jdk/nashorn/api/scripting/test/ScriptObjectMirrorTest.java @@ -41,6 +41,7 @@ import javax.script.ScriptContext; import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; +import jdk.nashorn.api.scripting.AbstractJSObject; import jdk.nashorn.api.scripting.JSObject; import jdk.nashorn.api.scripting.ScriptObjectMirror; import org.testng.annotations.Test; @@ -386,4 +387,41 @@ public class ScriptObjectMirrorTest { assertTrue(func.isFunction()); assertEquals(func.call(e.eval("this"), "hello"), "hello world"); } + + // @bug 8170565: JSObject call() is passed undefined for the argument 'thiz' + @Test + public void jsObjectThisTest() throws Exception { + final ScriptEngineManager engineManager = new ScriptEngineManager(); + final ScriptEngine e = engineManager.getEngineByName("nashorn"); + e.put("func", new AbstractJSObject() { + @Override + public boolean isFunction() { return true; } + + @Override + public Object call(Object thiz, Object...args) { + return thiz; + } + }); + + assertTrue((boolean)e.eval("func() === this")); + + // check that there is no blind undefined->Global translation! + assertTrue((boolean)e.eval("typeof(Function.prototype.call.call(func, undefined)) == 'undefined'")); + + // make sure that strict functions don't get translated this for scope calls! + e.put("sfunc", new AbstractJSObject() { + @Override + public boolean isFunction() { return true; } + + @Override + public boolean isStrictFunction() { return true; } + + @Override + public Object call(Object thiz, Object...args) { + return thiz; + } + }); + + assertTrue((boolean)e.eval("typeof sfunc() == 'undefined'")); + } } diff --git a/test/src/jdk/nashorn/test/models/ArrayConversionPreferences.java b/test/src/jdk/nashorn/test/models/ArrayConversionPreferences.java new file mode 100644 index 00000000..a88f3c37 --- /dev/null +++ b/test/src/jdk/nashorn/test/models/ArrayConversionPreferences.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016, 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.test.models; + +import java.util.Collection; +import java.util.Deque; +import java.util.List; +import java.util.Map; +import java.util.Queue; + +public class ArrayConversionPreferences { + public boolean testCollectionOverMap(final Collection x) { return true; } + public boolean testCollectionOverMap(final Map x) { return false; } + + public boolean testCollectionOverArray(final Collection x) { return true; } + public boolean testCollectionOverArray(final Object[] x) { return false; } + + public boolean testListOverMap(final List x) { return true; } + public boolean testListOverMap(final Map x) { return false; } + + public boolean testListOverArray(final List x) { return true; } + public boolean testListOverArray(final Object[] x) { return false; } + + public boolean testListOverCollection(final List x) { return true; } + public boolean testListOverCollection(final Collection x) { return false; } + + public boolean testQueueOverMap(final Queue x) { return true; } + public boolean testQueueOverMap(final Map x) { return false; } + + public boolean testQueueOverArray(final Queue x) { return true; } + public boolean testQueueOverArray(final Object[] x) { return false; } + + public boolean testQueueOverCollection(final Queue x) { return true; } + public boolean testQueueOverCollection(final Collection x) { return false; } + + public boolean testDequeOverMap(final Deque x) { return true; } + public boolean testDequeOverMap(final Map x) { return false; } + + public boolean testDequeOverArray(final Deque x) { return true; } + public boolean testDequeOverArray(final Object[] x) { return false; } + + public boolean testDequeOverCollection(final Deque x) { return true; } + public boolean testDequeOverCollection(final Collection x) { return false; } + + public boolean testDequeOverQueue(final Deque x) { return true; } + public boolean testDequeOverQueue(final Queue x) { return false; } + + public boolean testArrayOverMap(final Object[] x) { return true; } + public boolean testArrayOverMap(final Map x) { return false; } +} + |