--- a/netbeans/indy-demo/build.xml Thu May 28 02:51:05 2009 -0700
+++ b/netbeans/indy-demo/build.xml Thu Jun 04 20:51:51 2009 -0700
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
-<project name="InvokeDynamicDemo" default="default" basedir=".">
- <description>Builds, tests, and runs the project InvokeDynamicDemo.</description>
+<project name="indy-demo" default="default" basedir=".">
+ <description>Builds, tests, and runs the project indy-demo.</description>
<import file="nbproject/build-impl.xml"/>
<target name="-post-jar">
<delete file="dist/README.TXT"/>
--- a/netbeans/indy-demo/nbproject/project.properties Thu May 28 02:51:05 2009 -0700
+++ b/netbeans/indy-demo/nbproject/project.properties Thu Jun 04 20:51:51 2009 -0700
@@ -49,7 +49,8 @@ manifest.file=manifest.mf
manifest.file=manifest.mf
meta.inf.dir=${src.dir}/META-INF
platform.active=JDK_7X
-file.reference.projects=${user.home}/Projects
+#file.reference.projects=${user.home}/Projects
+file.reference.projects=${project.davinci}/patches/netbeans
project.meth=${file.reference.projects}/meth
reference.meth.jar=${project.meth}/dist/meth.jar
run.classpath=\
--- a/netbeans/indy-demo/src/Main.java Thu May 28 02:51:05 2009 -0700
+++ b/netbeans/indy-demo/src/Main.java Thu Jun 04 20:51:51 2009 -0700
@@ -37,7 +37,10 @@ public class Main {
static final Class[] CLASSES = {
Hello.class,
GetNameDemo.class,
- FidgetDemo.class
+ FidgetDemo.class,
+ recipes.PlainOldJava.class,
+ recipes.FastAndSlow.class,
+ recipes.Curry.class
};
public static void main(String[] args) {
for (Class c : CLASSES) {
--- a/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java Thu May 28 02:51:05 2009 -0700
+++ b/netbeans/meth/test/jdk/java/dyn/MethodHandlesTest.java Thu Jun 04 20:51:51 2009 -0700
@@ -127,6 +127,12 @@ public class MethodHandlesTest {
args[i] = randomArg(params[i]);
return args;
}
+ static Object[] randomArgs(int nargs, Class<?> param) {
+ Object[] args = new Object[nargs];
+ for (int i = 0; i < args.length; i++)
+ args[i] = randomArg(param);
+ return args;
+ }
static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
return Arrays.copyOf(a, a.length, atype);
@@ -641,8 +647,8 @@ public class MethodHandlesTest {
} catch (RuntimeException ex) {
error = ex;
}
- System.out.println("convert "+id+ " to "+newType+" => "+target
- +(error == null ? "" : " !! "+error));
+ //System.out.println("convert "+id+ " to "+newType+" => "+target
+ // +(error == null ? "" : " !! "+error));
if (positive && error != null) throw error;
assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
if (!positive) return; // negative test failed as expected
@@ -651,7 +657,7 @@ public class MethodHandlesTest {
Object result = MethodHandles.invoke(target, args);
assertCalled(name, convArgs);
assertEquals(convResult, result);
- System.out.print(':');
+ //System.out.print(':');
}
@Test
@@ -714,42 +720,73 @@ public class MethodHandlesTest {
fail("The test case is a prototype.");
}
- @Test @Ignore("unimplemented")
- public void testInsertArgument_MethodHandle_Object() {
- System.out.println("insertArgument");
- MethodHandle target = null;
- Object value = null;
- MethodHandle expResult = null;
- MethodHandle result = MethodHandles.insertArgument(target, 0, value);
- assertEquals(expResult, result);
- fail("The test case is a prototype.");
- }
-
- @Test @Ignore("unimplemented")
- public void testAppendArgument() {
- System.out.println("appendArgument");
- MethodHandle target = null;
- Object value = null;
- MethodHandle expResult = null;
- MethodHandle result = MethodHandles.insertArgument(target, target.type().parameterCount(), value);
- assertEquals(expResult, result);
- fail("The test case is a prototype.");
- }
-
- @Test @Ignore("unimplemented")
- public void testInsertArgument_3args() {
- System.out.println("insertArgument");
- MethodHandle target = null;
- Object value = null;
- int pos = 0;
- MethodHandle expResult = null;
- MethodHandle result = MethodHandles.insertArgument(target, pos, value);
- assertEquals(expResult, result);
- fail("The test case is a prototype.");
+ @Test
+ public void testInsertArguments() {
+ if (CAN_SKIP_WORKING) return;
+ System.out.println("insertArguments");
+ for (int nargs = 0; nargs <= 4; nargs++) {
+ for (int ins = 0; ins <= 4; ins++) {
+ for (int pos = 0; pos <= nargs; pos++) {
+ testInsertArguments(nargs, pos, ins);
+ }
+ }
+ }
+ }
+
+ void testInsertArguments(int nargs, int pos, int ins) {
+ MethodHandle target = ValueConversions.varargsArray(nargs + ins);
+ Object[] args = randomArgs(target.type().parameterArray());
+ List<Object> resList = Arrays.asList(args);
+ List<Object> argsToPass = new ArrayList<Object>(resList);
+ List<Object> argsToInsert = argsToPass.subList(pos, pos + ins);
+ MethodHandle target2 = MethodHandles.insertArguments(target, pos,
+ (Object[]) argsToInsert.toArray());
+ //System.out.println("insert: "+argsToInsert+" into "+target2);
+ argsToInsert.clear(); // remove from argsToInsert
+ Object res2 = MethodHandles.invoke(target2, argsToPass.toArray());
+ Object res2List = Arrays.asList((Object[])res2);
+ //System.out.println("result: "+res2List);
+ //if (!resList.equals(res2List))
+ // System.out.println("*** fail at n/p/i = "+nargs+"/"+pos+"/"+ins+": "+resList+" => "+res2List);
+ assertEquals(resList, res2List);
+ }
+
+ @Test @Ignore("in progress")
+ public void testFoldArguments() {
+ //if (CAN_SKIP_WORKING) return;
+ System.out.println("foldArguments");
+ for (int nargs = 0; nargs <= 4; nargs++) {
+ for (int fold = 0; fold <= 4; fold++) {
+ for (int pos = 0; pos <= nargs; pos++) {
+ testFoldArguments(nargs, pos, fold);
+ }
+ }
+ }
+ }
+
+ void testFoldArguments(int nargs, int pos, int fold) {
+ if (pos != 0) return; // can fold only at pos=0 for now
+ MethodHandle target = ValueConversions.varargsList(1 + nargs);
+ MethodHandle combine = ValueConversions.varargsList(fold);
+ List<Object> argsToPass = Arrays.asList(randomArgs(fold + nargs, Object.class));
+ System.out.println("fold "+target+" with "+combine);
+ MethodHandle target2 = MethodHandles.foldArguments(target, combine, fold);
+ // Simulate expected effect of combiner on arglist:
+ List<Object> expected = new ArrayList<Object>(argsToPass);
+ List<Object> argsToFold = expected.subList(pos, pos + fold);
+ System.out.println("fold: "+argsToFold+" into "+target2);
+ Object foldedArgs = MethodHandles.invoke(combine, argsToFold.toArray());
+ argsToFold.clear(); argsToFold.add(foldedArgs);
+ Object result = MethodHandles.invoke(target2, argsToPass.toArray());
+ System.out.println("result: "+result);
+ if (!expected.equals(result))
+ System.out.println("*** fail at n/p/f = "+nargs+"/"+pos+"/"+fold+": "+argsToPass+" => "+result);
+ assertEquals(expected, result);
}
@Test
public void testDropArguments() {
+ if (CAN_SKIP_WORKING) return;
System.out.println("dropArguments");
for (int nargs = 0; nargs <= 4; nargs++) {
for (int drop = 1; drop <= 4; drop++) {
@@ -763,8 +800,6 @@ public class MethodHandlesTest {
void testDropArguments(int nargs, int pos, int drop) {
MethodHandle target = ValueConversions.varargsArray(nargs);
Object[] args = randomArgs(target.type().parameterArray());
- Object res = MethodHandles.invoke(target, args);
- assertArrayEquals(args, (Object[])res);
MethodHandle target2 = MethodHandles.dropArguments(target, pos,
Collections.nCopies(drop, Object.class).toArray(new Class[0]));
List<Object> resList = Arrays.asList(args);
@@ -774,8 +809,8 @@ public class MethodHandlesTest {
}
Object res2 = MethodHandles.invoke(target2, argsToDrop.toArray());
Object res2List = Arrays.asList((Object[])res2);
-// if (!resList.equals(res2List))
-// System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
+ //if (!resList.equals(res2List))
+ // System.out.println("*** fail at n/p/d = "+nargs+"/"+pos+"/"+drop+": "+argsToDrop+" => "+res2List);
assertEquals(resList, res2List);
}
@@ -828,7 +863,7 @@ public class MethodHandlesTest {
while (test.type().parameterCount() < nargs)
test = MethodHandles.dropArguments(test, test.type().parameterCount()-1, Object.class);
while (test.type().parameterCount() > nargs)
- test = MethodHandles.insertArgument(test, 0, MISSING_ARG);
+ test = MethodHandles.insertArguments(test, 0, MISSING_ARG);
if (argClass != Object.class) {
test = changeArgTypes(test, argClass);
target = changeArgTypes(target, argClass);
@@ -857,16 +892,78 @@ public class MethodHandlesTest {
}
}
- @Test @Ignore("unimplemented")
- public void testCombineArguments() {
- System.out.println("checkArguments");
- MethodHandle target = null;
- MethodHandle checker = null;
- int pos = 0;
- MethodHandle expResult = null;
- MethodHandle result = MethodHandles.combineArguments(target, pos, checker);
- assertEquals(expResult, result);
- fail("The test case is a prototype.");
+ @Test
+ public void testCatchException() {
+ if (CAN_SKIP_WORKING) return;
+ System.out.println("catchException");
+ for (int nargs = 2; nargs <= 6; nargs++) {
+ for (int ti = 0; ti <= 1; ti++) {
+ boolean throwIt = (ti != 0);
+ testCatchException(int.class, new ClassCastException("testing"), throwIt, nargs);
+ testCatchException(void.class, new java.io.IOException("testing"), throwIt, nargs);
+ testCatchException(String.class, new LinkageError("testing"), throwIt, nargs);
+ }
+ }
+ }
+
+ private static <T extends Throwable>
+ Object throwOrReturn(Object normal, T exception) throws T {
+ if (exception != null) throw exception;
+ return normal;
+ }
+
+ void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) {
+ Class<? extends Throwable> exType = thrown.getClass();
+ MethodHandle throwOrReturn
+ = PRIVATE.findStatic(MethodHandlesTest.class, "throwOrReturn",
+ MethodType.make(Object.class, Object.class, Throwable.class));
+ MethodHandle thrower = throwOrReturn;
+ while (thrower.type().parameterCount() < nargs)
+ thrower = MethodHandles.dropArguments(thrower, thrower.type().parameterCount(), Object.class);
+ MethodHandle target = MethodHandles.catchException(thrower,
+ thrown.getClass(), ValueConversions.varargsList(1+nargs));
+ assertEquals(thrower.type(), target.type());
+ //System.out.println("catching with "+target+" : "+throwOrReturn);
+ Object[] args = randomArgs(nargs, Object.class);
+ args[1] = (throwIt ? thrown : null);
+ Object returned = MethodHandles.invoke(target, args);
+ //System.out.println("return from "+target+" : "+returned);
+ if (!throwIt) {
+ assertSame(args[0], returned);
+ } else {
+ List<Object> catchArgs = new ArrayList<Object>(Arrays.asList(args));
+ catchArgs.add(0, thrown);
+ assertEquals(catchArgs, returned);
+ }
+ }
+
+ @Test
+ public void testThrowException() {
+ if (CAN_SKIP_WORKING) return;
+ System.out.println("throwException");
+ testThrowException(int.class, new ClassCastException("testing"));
+ testThrowException(void.class, new java.io.IOException("testing"));
+ testThrowException(String.class, new LinkageError("testing"));
+ }
+
+ void testThrowException(Class<?> returnType, Throwable thrown) {
+ Class<? extends Throwable> exType = thrown.getClass();
+ MethodHandle target = MethodHandles.throwException(returnType, exType);
+ //System.out.println("throwing with "+target+" : "+thrown);
+ MethodType expectedType = MethodType.make(returnType, exType);
+ assertEquals(expectedType, target.type());
+ Throwable caught = null;
+ try {
+ Object res = MethodHandles.invoke_1(target, thrown);
+ fail("got "+res+" instead of throwing "+thrown);
+ } catch (Throwable ex) {
+ if (ex != thrown) {
+ if (ex instanceof Error) throw (Error)ex;
+ if (ex instanceof RuntimeException) throw (RuntimeException)ex;
+ }
+ caught = ex;
+ }
+ assertSame(thrown, caught);
}
}
--- a/netbeans/meth/test/sun/dyn/util/ValueConversionsTest.java Thu May 28 02:51:05 2009 -0700
+++ b/netbeans/meth/test/sun/dyn/util/ValueConversionsTest.java Thu Jun 04 20:51:51 2009 -0700
@@ -26,7 +26,10 @@ package sun.dyn.util;
package sun.dyn.util;
import java.dyn.MethodHandle;
+import java.dyn.MethodHandles;
import java.io.Serializable;
+import java.util.Arrays;
+import org.junit.Ignore;
import org.junit.Test;
import static org.junit.Assert.*;
@@ -232,4 +235,29 @@ public class ValueConversionsTest {
assertEquals(expResult, result);
}
+ @Test
+ public void testVarargsArray() {
+ System.out.println("varargsArray");
+ for (int nargs = 0; nargs <= 5; nargs++) {
+ MethodHandle target = ValueConversions.varargsArray(nargs);
+ Object[] args = new Object[nargs];
+ for (int i = 0; i < nargs; i++)
+ args[i] = "#"+i;
+ Object res = MethodHandles.invoke(target, args);
+ assertArrayEquals(args, (Object[])res);
+ }
+ }
+
+ @Test
+ public void testVarargsList() {
+ System.out.println("varargsList");
+ for (int nargs = 0; nargs <= 5; nargs++) {
+ MethodHandle target = ValueConversions.varargsList(nargs);
+ Object[] args = new Object[nargs];
+ for (int i = 0; i < nargs; i++)
+ args[i] = "#"+i;
+ Object res = MethodHandles.invoke(target, args);
+ assertEquals(Arrays.asList(args), res);
+ }
+ }
}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/netbeans/indy-demo/src/recipes/Curry.java Thu Jun 04 20:51:51 2009 -0700
@@ -0,0 +1,118 @@
+/*
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package recipes;
+
+import java.dyn.*;
+import static java.dyn.MethodHandles.*;
+import static java.dyn.MethodType.*;
+import static recipes.Utensil.*;
+
+public class Curry {
+ public static void main(String... av) {
+ // ----
+
+ MethodHandle list2 = Utensil.list(2);
+ println(list2); // list2 = {(x,y) => Arrays.asList(x,y)}
+ println(invoke(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]
+
+ // ----
+
+ // curry with everything:
+ MethodHandle list3 = Utensil.list(3);
+ println(list3); // list3 = {(x,y,z) => Arrays.asList(x,y,z)}
+ MethodHandle partialApp2 = insertArguments(list3, 0, "curry");
+ // partialApp2 = {(x, y) => list3("curry", x, y)}
+ println(partialApp2);
+ println(invoke(partialApp2, "chicken", "rice"));
+ // [curry, chicken, rice]
+
+ // ----
+
+ // double curry:
+ MethodHandle pa3 = insertArguments(list3, 0, "curry", "chutney");
+ // pa3 = {x => list3("curry", "chutney", x)}
+ println(pa3);
+ println(invoke(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]
+ }
+
+ static void stronglyTyped() {
+ MethodHandle list2 = Utensil.list(2);
+ println(list2); // list2 = {(x,y) => Arrays.asList(x,y)}
+ MethodType s2t = make(Object.class, String.class, String.class);
+ //list2 = convertArguments(list2, s2t);
+ println(list2.invoke("chicken", "rice"));
+
+ // curry with chicken or rice:
+ MethodHandle partialApp
+ = MethodHandles.insertArguments(list2, 0, "curry");
+ println(partialApp); // partialApp = {x => list2("curry", x)}
+ println(partialApp.invoke("chicken")); // [curry, chicken]
+ println(partialApp.invoke("rice")); // [curry, rice]
+
+ // curry with everything:
+ MethodHandle list3 = Utensil.list(3);
+ println(list3); // list3 = {(x,y,z) => Arrays.asList(x,y,z)}
+ MethodType s3t = make(Object.class, String.class, String.class, String.class);
+ list3 = convertArguments(list3, s3t);
+ MethodHandle partialApp2
+ = MethodHandles.insertArguments(list3, 0, "curry");
+ // partialApp2 = {(x, y) => list3("curry", x, y)}
+ println(partialApp2);
+ println(partialApp2.invoke("chicken", "rice")); // [curry, chicken, rice]
+
+ // double curry:
+ MethodHandle partialApp3
+ = MethodHandles.insertArguments(list3, 0, "curry", "chutney");
+ // partialApp3 = {x => list3("curry", "chutney", x)}
+ println(partialApp3);
+ println(partialApp3.invoke("tofu")); // [curry, chutney, tofu]
+
+ // triple curry:
+ MethodHandle partialApp4
+ = MethodHandles.insertArguments(partialApp3, 0, "yak");
+ // partialApp4 = { => list3("curry", "chutney", "yak")}
+ println(partialApp4);
+ println(partialApp4.invoke()); // [curry, chutney, yak]
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/netbeans/indy-demo/src/recipes/FastAndSlow.java Thu Jun 04 20:51:51 2009 -0700
@@ -0,0 +1,85 @@
+/*
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package recipes;
+
+import java.dyn.*;
+import static java.dyn.MethodHandles.*;
+import static java.dyn.MethodType.*;
+import static recipes.Utensil.*;
+
+public class FastAndSlow {
+ private static final Lookup LOOKUP = lookup();
+
+ // ----
+
+ static Object fastAdd(int x, int y) {
+ int z = x+y;
+ if ((x ^ y) >= 0 && (x ^ z) < 0) {
+ println("oops, it's overflowing");
+ return slowAdd(x, y);
+ }
+ return z;
+ }
+
+ // ----
+
+ static Object slowAdd(Object x, Object y) {
+ double xd = ((Number)x).doubleValue();
+ double yd = ((Number)y).doubleValue();
+ println("I'm hungry; is it done yet?");
+ return xd + yd;
+ }
+
+ // ----
+
+ static boolean bothInts(Object x, Object y) {
+ return x instanceof Integer && y instanceof Integer;
+ }
+
+ public static void main(String... av) {
+ MethodHandle fastAdd =
+ LOOKUP.findStatic(FastAndSlow.class, "fastAdd",
+ make(Object.class, int.class, int.class));
+ MethodHandle slowAdd =
+ LOOKUP.findStatic(FastAndSlow.class, "slowAdd",
+ make(Object.class, Object.class, Object.class));
+ MethodHandle bothInts =
+ LOOKUP.findStatic(FastAndSlow.class, "bothInts",
+ make(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));
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/netbeans/indy-demo/src/recipes/PlainOldJava.java Thu Jun 04 20:51:51 2009 -0700
@@ -0,0 +1,125 @@
+/*
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package recipes;
+
+import java.dyn.*;
+import static java.dyn.MethodHandles.*;
+import static java.dyn.MethodType.*;
+import static recipes.Utensil.*;
+
+public class PlainOldJava {
+ private static final Lookup LOOKUP = lookup();
+
+ public static void main(String... av) {
+ for (int i = 0; i < 4; i++) {
+ test();
+ }
+ }
+ static void test() {
+ // ---
+
+ java.io.File file = new java.io.File("muffin.txt");
+ println(file.getName());
+ MethodHandle getName =
+ LOOKUP.findVirtual(file.getClass(), "getName",
+ MethodType.make(String.class));
+ println(getName.<String>invoke(file));
+
+ // ---
+
+ MethodHandle charAt =
+ LOOKUP.findVirtual(String.class, "charAt",
+ MethodType.make(char.class, int.class));
+ println(charAt.<char>invoke("foam", 3));
+
+ // ---
+
+ // invokedynamic
+ println(InvokeDynamic.<String>getName(file));
+ println(InvokeDynamic.<String>toString((CharSequence) "soy latte"));
+ println(InvokeDynamic.<String>
+ #"static:\=java\|lang\|Integer:toHexString"
+ (0xCAFE));
+ }
+
+ // Linkage logic for all invokedynamic call sites in this class.
+ private static MethodHandle linkDynamic(CallSite site) {
+ println("[link] linkDynamic "+site);
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ String name = site.name();
+ MethodType type = site.type(); // static type of call
+ MethodHandle target = null; // result of call linkage
+ Class<?> recvType = null; // receiver (1st arg) type if any
+ if (type.parameterCount() >= 1) {
+ recvType = type.parameterType(0);
+ if (recvType.isPrimitive()) recvType = null;
+ }
+ if (target == null && recvType != null) {
+ MethodType dropRecvType = type.dropParameterType(0);
+ target = lookup.findVirtual(recvType, name, dropRecvType);
+ }
+ if (target == null && recvType != null && name.startsWith("special:")) {
+ MethodType dropRecvType = type.dropParameterType(0);
+ target = lookup.findSpecial(recvType, name, dropRecvType, site.callerClass());
+ }
+ if (target == null && name.startsWith("static:\\=")) {
+ int cbeg = name.indexOf('=')+1;
+ int cend = name.indexOf(':', cbeg);
+ String cname = name.substring(cbeg, cend).replaceAll("[\\\\][|]", ".");
+ String mname = name.substring(cend+1);
+ try {
+ Class<?> cls = Class.forName(cname);
+ target = lookup.findStatic(cls, mname, type);
+ } catch (ClassNotFoundException ex) {
+ }
+ }
+ if (target == null) {
+ throw new InvokeDynamicBootstrapError("linkage failed: "+site);
+ }
+ return target;
+ }
+
+ // Set up a class-local bootstrap method.
+ static { Linkage.registerBootstrapMethod("bootstrapDynamic"); }
+ private static CallSite bootstrapDynamic(Class caller, String name, MethodType type) {
+ CallSite site = new CallSite(caller, name, type);
+ MethodHandle target = linkDynamic(site);
+ println("[link] set site target to "+target);
+ if (target.type() != site.type()) {
+ target = MethodHandles.convertArguments(target, site.type());
+ println("[link] with conversions "+target);
+ }
+ site.setTarget(target);
+ println("[link] site is linked; this is the last time for "+site.name());
+ return site;
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/netbeans/indy-demo/src/recipes/Utensil.java Thu Jun 04 20:51:51 2009 -0700
@@ -0,0 +1,112 @@
+/*
+ Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ - Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+ - Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ - Neither the name of Sun Microsystems nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package recipes;
+
+import java.util.*;
+import java.dyn.*;
+import static java.dyn.MethodHandles.*;
+
+class Utensil {
+ public static void println(Object x) {
+ //if (x instanceof MethodHandle)
+ // x = withType((MethodHandle)x);
+ System.out.println(x);
+ }
+ public static String withType(MethodHandle x) {
+ return x.toString() + x.type();
+ }
+
+ private static final Lookup LOOKUP = lookup();
+
+ /** Return the identity function from Object to Object. */
+ public static MethodHandle identity() {
+ return LOOKUP.findStatic(Utensil.class, "identity", MethodType.makeGeneric(1));
+ }
+
+ private static Object identity(Object x) { return x; }
+
+ private static final Object[] NO_ARGS_ARRAY = {};
+ private static Object[] array() { return NO_ARGS_ARRAY; }
+ private static Object[] makeArray(Object... args) { return args; }
+ 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); }
+
+ /** 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 array(int nargs) {
+ try {
+ MethodType type = MethodType.makeGeneric(nargs).changeReturnType(Object[].class);
+ return LOOKUP.findStatic(Utensil.class, "array", type);
+ } catch (NoAccessException ex) {
+ // kitchen accident; call 911
+ throw new RuntimeException(ex);
+ }
+ }
+
+ private static final List<Object> NO_ARGS_LIST = Arrays.asList(NO_ARGS_ARRAY);
+ private static List<Object> list() { return NO_ARGS_LIST; }
+ private static List<Object> makeList(Object... args) { return Arrays.asList(args); }
+ 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); }
+
+ /** 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 list(int nargs) {
+ try {
+ MethodType type = MethodType.makeGeneric(nargs).changeReturnType(List.class);
+ return LOOKUP.findStatic(Utensil.class, "list", type);
+ } catch (NoAccessException ex) {
+ // kitchen accident; call 911
+ throw new RuntimeException(ex);
+ }
+ }
+}