--- a/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Fri Oct 24 06:18:00 2014 -0700
+++ b/jdk/src/java.base/share/classes/sun/invoke/util/Wrapper.java Fri Oct 24 08:22:17 2014 -0700
@@ -26,19 +26,19 @@
package sun.invoke.util;
public enum Wrapper {
- BOOLEAN(Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned(1)),
+ // wrapperType primitiveType char zero emptyArray format
+ BOOLEAN( Boolean.class, boolean.class, 'Z', (Boolean)false, new boolean[0], Format.unsigned( 1)),
// These must be in the order defined for widening primitive conversions in JLS 5.1.2
- BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
- SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
- CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
- INT(Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed(32)),
- LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
- FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
- DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
- //NULL(Null.class, null.class, 'N', null, null, Format.other(1)),
- OBJECT(Object.class, Object.class, 'L', null, new Object[0], Format.other(1)),
+ BYTE ( Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed( 8)),
+ SHORT ( Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed( 16)),
+ CHAR (Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
+ INT ( Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed( 32)),
+ LONG ( Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed( 64)),
+ FLOAT ( Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
+ DOUBLE ( Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
+ OBJECT ( Object.class, Object.class, 'L', null, new Object[0], Format.other( 1)),
// VOID must be the last type, since it is "assignable" from any other type:
- VOID(Void.class, void.class, 'V', null, null, Format.other(0)),
+ VOID ( Void.class, void.class, 'V', null, null, Format.other( 0)),
;
private final Class<?> wrapperType;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/invoke/ExplicitCastArgumentsTest.java Fri Oct 24 08:22:17 2014 -0700
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ *
+ * 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 java.lang.invoke;
+
+import sun.invoke.util.Wrapper;
+
+/* @test
+ * @summary unit tests for MethodHandles.explicitCastArguments()
+ *
+ * @run main/bootclasspath java.lang.invoke.ExplicitCastArgumentsTest
+ */
+public class ExplicitCastArgumentsTest {
+ private static final boolean VERBOSE = Boolean.getBoolean("verbose");
+
+ public static void main(String[] args) throws Throwable {
+ for (Wrapper from : Wrapper.values()) {
+ for (Wrapper to : Wrapper.values()) {
+ if (from == Wrapper.VOID || to == Wrapper.VOID) continue;
+ testRef2Prim (from, to);
+ }
+ }
+ System.out.println("TEST PASSED");
+ }
+
+ public static void testRef2Prim(Wrapper from, Wrapper to) throws Throwable {
+ // MHs.eCA javadoc:
+ // If T0 is a reference and T1 a primitive, and if the reference is null at runtime, a zero value is introduced.
+ test(from.wrapperType(), to.primitiveType(), null, false);
+ }
+
+ public static void test(Class<?> from, Class<?> to, Object param, boolean failureExpected) throws Throwable {
+ if (VERBOSE) System.out.printf("%-10s => %-10s: %5s: ", from.getSimpleName(), to.getSimpleName(), param);
+
+ MethodHandle original = MethodHandles.identity(from);
+ MethodType newType = original.type().changeReturnType(to);
+
+ try {
+ MethodHandle target = MethodHandles.explicitCastArguments(original, newType);
+ Object result = target.invokeWithArguments(param);
+
+ if (VERBOSE) {
+ String resultStr;
+ if (result != null) {
+ resultStr = String.format("%10s (%10s)", "'"+result+"'", result.getClass().getSimpleName());
+ } else {
+ resultStr = String.format("%10s", result);
+ }
+ System.out.println(resultStr);
+ }
+
+ if (failureExpected) {
+ String msg = String.format("No exception thrown: %s => %s; parameter: %s", from, to, param);
+ throw new AssertionError(msg);
+ }
+ } catch (AssertionError e) {
+ throw e; // report test failure
+ } catch (Throwable e) {
+ if (VERBOSE) System.out.printf("%s: %s\n", e.getClass(), e.getMessage());
+ if (!failureExpected) {
+ String msg = String.format("Unexpected exception was thrown: %s => %s; parameter: %s", from, to, param);
+ throw new AssertionError(msg, e);
+ }
+ }
+ }
+}