changeset 31:912e00503502

update projects to API tweaks
author jrose
date Mon, 12 Oct 2009 16:30:53 -0700
parents b3c0a99a49f6
children 7caa97f6f7b6
files netbeans/indy-demo/build.xml netbeans/indy-demo/nbproject/project.properties netbeans/indy-demo/src/recipes/Curry.java netbeans/indy-demo/src/recipes/FastAndSlow.java netbeans/meth/nbproject/project.properties netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java
diffstat 6 files changed, 185 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/netbeans/indy-demo/build.xml	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/indy-demo/build.xml	Mon Oct 12 16:30:53 2009 -0700
@@ -5,6 +5,6 @@
     <target name="-post-jar">
         <delete file="dist/README.TXT"/>
 	<copy file="README.txt" todir="dist"/>
-	<echo>To run this project, you will need the JVM option -XX:+EnableInvokeDynamic</echo>
+	<echo>To run this project, you will need the JVM option -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic</echo>
     </target>
 </project>
--- a/netbeans/indy-demo/nbproject/project.properties	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/indy-demo/nbproject/project.properties	Mon Oct 12 16:30:53 2009 -0700
@@ -61,7 +61,7 @@
 # Space-separated list of JVM arguments used when running the project
 # (you may also define separate properties like run-sys-prop.name=value instead of -Dname=value
 # or test-sys-prop.name=value to set system properties for unit tests):
-run.jvmargs=-ea -esa -XX:+EnableInvokeDynamic ${config.run.jvmargs} -Xbootclasspath/p:"${run.classpath}:${libs.junit_4.classpath}"
+run.jvmargs=-ea -esa -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic ${config.run.jvmargs} -Xbootclasspath/p:"${run.classpath}:${libs.junit_4.classpath}"
 #manual hack: override ${config.run.jvmargs} in ${config}.properties
 config.run.jvmargs=
 run.test.classpath=\
--- a/netbeans/indy-demo/src/recipes/Curry.java	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/indy-demo/src/recipes/Curry.java	Mon Oct 12 16:30:53 2009 -0700
@@ -41,13 +41,13 @@
 
         MethodHandle list2 = Utensil.list(2);
         println(list2);  // list2 = {(x,y) => Arrays.asList(x,y)}
-        println(invoke(list2, "chicken", "rice"));  // [chicken, rice]
+        println(invokeVarargs(list2, "chicken", "rice"));  // [chicken, rice]
 
         // curry with chicken or rice:
         MethodHandle partialApp = insertArguments(list2, 0, "curry");
         println(partialApp); // partialApp = {x => list2("curry", x)}
-        println(invoke(partialApp, "chicken"));  // [curry, chicken]
-        println(invoke(partialApp, "rice"));     // [curry, rice]
+        println(invokeVarargs(partialApp, "chicken"));  // [curry, chicken]
+        println(invokeVarargs(partialApp, "rice"));     // [curry, rice]
 
         // ----
 
@@ -57,7 +57,7 @@
         MethodHandle partialApp2 = insertArguments(list3, 0, "curry");
         // partialApp2 = {(x, y) => list3("curry", x, y)}
         println(partialApp2);
-        println(invoke(partialApp2, "chicken", "rice"));
+        println(invokeVarargs(partialApp2, "chicken", "rice"));
                                             // [curry, chicken, rice]
 
         // ----
@@ -66,13 +66,13 @@
         MethodHandle pa3 = insertArguments(list3, 0, "curry", "chutney");
         // pa3 = {x => list3("curry", "chutney", x)}
         println(pa3);
-        println(invoke(pa3, "tofu")); //[curry, chutney, tofu]
+        println(invokeVarargs(pa3, "tofu")); //[curry, chutney, tofu]
 
         // triple curry:
         MethodHandle pa4 = insertArguments(pa3, 0, "yak");
         // pa4 = { => list3("curry", "chutney", "yak")}
         println(pa4);
-        println(invoke(pa4));  // [curry, chutney, yak]
+        println(invokeVarargs(pa4));  // [curry, chutney, yak]
     }
 
     static void stronglyTyped() throws Throwable {
--- a/netbeans/indy-demo/src/recipes/FastAndSlow.java	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/indy-demo/src/recipes/FastAndSlow.java	Mon Oct 12 16:30:53 2009 -0700
@@ -76,9 +76,9 @@
                 methodType(boolean.class, Object.class, Object.class));
         fastAdd = convertArguments(fastAdd, slowAdd.type());
         MethodHandle combo = guardWithTest(bothInts, fastAdd, slowAdd);
-        println(invoke(combo, 2, 3));
-        println(invoke(combo, 2.1, 3.1));
-        println(invoke(combo, Integer.MAX_VALUE, -1));
-        println(invoke(combo, Integer.MAX_VALUE, 1));
+        println(invokeVarargs(combo, 2, 3));
+        println(invokeVarargs(combo, 2.1, 3.1));
+        println(invokeVarargs(combo, Integer.MAX_VALUE, -1));
+        println(invokeVarargs(combo, Integer.MAX_VALUE, 1));
     }
 }
--- a/netbeans/meth/nbproject/project.properties	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/meth/nbproject/project.properties	Mon Oct 12 16:30:53 2009 -0700
@@ -77,7 +77,7 @@
 # or test-sys-prop.name=value to set system properties for unit tests):
 run.jvmargs=-ea -esa ${config.run.jvmargs} -Xbootclasspath/p:"${run.classpath}:${libs.junit_4.classpath}"
 #manual hack: override ${config.run.jvmargs} in ${config}.properties
-config.run.jvmargs=-XX:+EnableMethodHandles
+config.run.jvmargs=-XX:+UnlockExperimentalVMOptions -XX:+EnableMethodHandles
 run.test.classpath=\
     ${javac.test.classpath}:\
     ${build.test.classes.dir}
--- a/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java	Mon Oct 12 16:27:58 2009 -0700
+++ b/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java	Mon Oct 12 16:30:53 2009 -0700
@@ -23,18 +23,22 @@
  * have any questions.
  */
 
+/* @test
+ * @summary unit tests for java.dyn.MethodHandles
+ * @compile -XDinvokedynamic MethodHandlesTest.java
+ * @run junit/othervm -XX:+UnlockExperimentalVMOptions -XX:+EnableInvokeDynamic jdk.java.dyn.MethodHandlesTest
+ */
+
 package jdk.java.dyn;
 
-import sun.dyn.MemberName;
-import sun.dyn.util.Wrapper;
 import java.dyn.*;
 import java.dyn.MethodHandles.Lookup;
 import java.lang.reflect.*;
 import java.util.*;
 import org.junit.*;
-import sun.dyn.util.ValueConversions;
 import static org.junit.Assert.*;
 
+
 /**
  *
  * @author jrose
@@ -152,14 +156,46 @@
             System.out.println("calling "+logEntry(name, args)+" on "+target);
     }
 
+    static Object castToWrapper(Object value, Class<?> dst) {
+        Object wrap = null;
+        if (value instanceof Number)
+            wrap = castToWrapperOrNull(((Number)value).longValue(), dst);
+        if (value instanceof Character)
+            wrap = castToWrapperOrNull((char)(Character)value, dst);
+        if (wrap != null)  return wrap;
+        return dst.cast(value);
+    }
+
+    static Object castToWrapperOrNull(long value, Class<?> dst) {
+        if (dst == int.class || dst == Integer.class)
+            return (int)(value);
+        if (dst == long.class || dst == Long.class)
+            return (long)(value);
+        if (dst == char.class || dst == Character.class)
+            return (char)(value);
+        if (dst == short.class || dst == Short.class)
+            return (short)(value);
+        if (dst == float.class || dst == Float.class)
+            return (float)(value);
+        if (dst == double.class || dst == Double.class)
+            return (double)(value);
+        return null;
+    }
+
     static int nextArg;
     static Object randomArg(Class<?> param) {
-        Wrapper wrap = Wrapper.forBasicType(param);
-        if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(param))
-            wrap = Wrapper.forWrapperType(param);
-        if (wrap != Wrapper.OBJECT)
-            return wrap.wrap(nextArg++);
-        else if (param.isInterface() || param.isAssignableFrom(String.class))
+        Object wrap = castToWrapperOrNull(nextArg, param);
+        if (wrap != null) {
+            nextArg++;
+            return wrap;
+        }
+//        import sun.dyn.util.Wrapper;
+//        Wrapper wrap = Wrapper.forBasicType(dst);
+//        if (wrap == Wrapper.OBJECT && Wrapper.isWrapperType(dst))
+//            wrap = Wrapper.forWrapperType(dst);
+//        if (wrap != Wrapper.OBJECT)
+//            return wrap.wrap(nextArg++);
+        if (param.isInterface() || param.isAssignableFrom(String.class))
             return "#"+(nextArg++);
         else
             try {
@@ -556,8 +592,7 @@
         } catch (NoSuchMethodException ex) {
             throw new NoAccessException(ex);
         }
-        MemberName mname = new MemberName(rmethod);
-        assertEquals(isStatic, mname.isStatic());
+        assertEquals(isStatic, Modifier.isStatic(rmethod.getModifiers()));
         try {
             target = lookup.unreflect(rmethod);
         } catch (NoAccessException ex) {
@@ -694,14 +729,14 @@
             Class<?> src = newType.parameterType(i);
             Class<?> dst = idType.parameterType(i);
             if (src != dst)
-                convArgs[i] = Wrapper.forPrimitiveType(dst).cast(convArgs[i], dst);
+                convArgs[i] = castToWrapper(convArgs[i], dst);
         }
         Object convResult = MethodHandles.invokeVarargs(id, convArgs);
         {
             Class<?> dst = newType.returnType();
             Class<?> src = idType.returnType();
             if (src != dst)
-                convResult = Wrapper.forPrimitiveType(dst).cast(convResult, dst);
+                convResult = castToWrapper(convResult, dst);
         }
         MethodHandle target = null;
         RuntimeException error = null;
@@ -1472,7 +1507,131 @@
     }
 
 }
+// Local abbreviated copy of sun.dyn.util.ValueConversions
+class ValueConversions {
+    private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
+    private static final Object[] NO_ARGS_ARRAY = {};
+    private static Object[] makeArray(Object... args) { return args; }
+    private static Object[] array() { return NO_ARGS_ARRAY; }
+    private static Object[] array(Object a0)
+                { return makeArray(a0); }
+    private static Object[] array(Object a0, Object a1)
+                { return makeArray(a0, a1); }
+    private static Object[] array(Object a0, Object a1, Object a2)
+                { return makeArray(a0, a1, a2); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3)
+                { return makeArray(a0, a1, a2, a3); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4)
+                { return makeArray(a0, a1, a2, a3, a4); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5)
+                { return makeArray(a0, a1, a2, a3, a4, a5); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6)
+                { return makeArray(a0, a1, a2, a3, a4, a5, a6); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7)
+                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7,
+                                  Object a8)
+                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+    private static Object[] array(Object a0, Object a1, Object a2, Object a3,
+                                  Object a4, Object a5, Object a6, Object a7,
+                                  Object a8, Object a9)
+                { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+    static MethodHandle[] makeArrays() {
+        ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+        MethodHandles.Lookup lookup = IMPL_LOOKUP;
+        for (;;) {
+            int nargs = arrays.size();
+            MethodType type = MethodType.makeGeneric(nargs).changeReturnType(Object[].class);
+            String name = "array";
+            MethodHandle array = null;
+            try {
+                array = lookup.findStatic(ValueConversions.class, name, type);
+            } catch (NoAccessException ex) {
+            }
+            if (array == null)  break;
+            arrays.add(array);
+        }
+        assert(arrays.size() == 11);  // current number of methods
+        return arrays.toArray(new MethodHandle[0]);
+    }
+    static final MethodHandle[] ARRAYS = makeArrays();
 
+    /** Return a method handle that takes the indicated number of Object
+     *  arguments and returns an Object array of them, as if for varargs.
+     */
+    public static MethodHandle varargsArray(int nargs) {
+        if (nargs < ARRAYS.length)
+            return ARRAYS[nargs];
+        // else need to spin bytecode or do something else fancy
+        throw new UnsupportedOperationException("NYI");
+    }
+
+    private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
+    private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
+    private static List<Object> list() { return NO_ARGS_LIST; }
+    private static List<Object> list(Object a0)
+                { return makeList(a0); }
+    private static List<Object> list(Object a0, Object a1)
+                { return makeList(a0, a1); }
+    private static List<Object> list(Object a0, Object a1, Object a2)
+                { return makeList(a0, a1, a2); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3)
+                { return makeList(a0, a1, a2, a3); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4)
+                { return makeList(a0, a1, a2, a3, a4); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4, Object a5)
+                { return makeList(a0, a1, a2, a3, a4, a5); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4, Object a5, Object a6)
+                { return makeList(a0, a1, a2, a3, a4, a5, a6); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4, Object a5, Object a6, Object a7)
+                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4, Object a5, Object a6, Object a7,
+                                     Object a8)
+                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
+    private static List<Object> list(Object a0, Object a1, Object a2, Object a3,
+                                     Object a4, Object a5, Object a6, Object a7,
+                                     Object a8, Object a9)
+                { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
+    static MethodHandle[] makeLists() {
+        ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+        MethodHandles.Lookup lookup = IMPL_LOOKUP;
+        for (;;) {
+            int nargs = arrays.size();
+            MethodType type = MethodType.makeGeneric(nargs).changeReturnType(List.class);
+            String name = "list";
+            MethodHandle array = null;
+            try {
+                array = lookup.findStatic(ValueConversions.class, name, type);
+            } catch (NoAccessException ex) {
+            }
+            if (array == null)  break;
+            arrays.add(array);
+        }
+        assert(arrays.size() == 11);  // current number of methods
+        return arrays.toArray(new MethodHandle[0]);
+    }
+    static final MethodHandle[] LISTS = makeLists();
+
+    /** Return a method handle that takes the indicated number of Object
+     *  arguments and returns List.
+     */
+    public static MethodHandle varargsList(int nargs) {
+        if (nargs < LISTS.length)
+            return LISTS[nargs];
+        // else need to spin bytecode or do something else fancy
+        throw new UnsupportedOperationException("NYI");
+    }
+}
 // This guy tests access from outside the same package member, but inside
 // the package itself.
 class PackageSibling {