--- a/indy.patch Thu Jun 04 21:28:20 2009 -0700
+++ b/indy.patch Mon Jun 08 23:03:51 2009 -0700
@@ -243,7 +243,39 @@ diff --git a/src/share/classes/java/dyn/
* </ol>
* @author John Rose, JSR 292 EG
*/
-@@ -135,10 +136,30 @@
+@@ -68,10 +69,21 @@
+
+ //// Method handle creation from ordinary methods.
+
++ /** Create a {@link Lookup} lookup object on the caller.
++ *
++ */
+ public static Lookup lookup() {
+ return new Lookup();
+ }
+
++ /** Version of lookup which is trusted minimally.
++ * It can only be used to create method handles to
++ * publicly accessible members.
++ */
++ public static Lookup publicLookup() {
++ return Lookup.PUBLIC_LOOKUP;
++ }
++
+ /**
+ * <em>PROVISIONAL API, WORK IN PROGRESS:</em>
+ * A factory object for creating method handles, when the creation
+@@ -121,7 +133,8 @@
+ /** Which class is performing the lookup? It is this class against
+ * which checks are performed for visibility and access permissions.
+ * <p>
+- * This value is null if and only if this lookup is {@link #PUBLIC_LOOKUP}.
++ * This value is null if and only if this lookup was produced
++ * by {@link MethodHandles#publicLookup}.
+ */
+ public Class<?> lookupClass() {
+ return lookupClass;
+@@ -135,23 +148,46 @@
* an access$N method.
*/
Lookup() {
@@ -278,7 +310,31 @@ diff --git a/src/share/classes/java/dyn/
}
private Lookup(Class<?> lookupClass) {
-@@ -184,6 +205,9 @@
+ this.lookupClass = lookupClass;
+ }
+
++ // Make sure outer class is initialized first.
++ static { IMPL_TOKEN.getClass(); }
++
+ private static final Class<?> PUBLIC_ONLY = sun.dyn.empty.Empty.class;
+
+ /** Version of lookup which is trusted minimally.
+ * It can only be used to create method handles to
+ * publicly accessible members.
+ */
+- public static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
++ static final Lookup PUBLIC_LOOKUP = new Lookup(PUBLIC_ONLY);
+
+ /** Package-private version of lookup which is trusted. */
+ static final Lookup IMPL_LOOKUP = new Lookup(null);
+@@ -178,12 +214,16 @@
+ // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
+ // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
+ // Note: This should be the only use of getCallerClass in this file.
++ assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
+ return Reflection.getCallerClass(CALLER_DEPTH);
+ }
+
/**
* Produce a method handle for a static method.
* The type of the method handle will be that of the method.
@@ -288,7 +344,7 @@ diff --git a/src/share/classes/java/dyn/
* The method and all its argument types must be accessible to the lookup class.
* If the method's class has not yet been initialized, that is done
* immediately, before the method handle is returned.
-@@ -196,10 +220,11 @@
+@@ -196,10 +236,11 @@
*/
public
MethodHandle findStatic(Class<?> defc, String name, MethodType type) throws NoAccessException {
@@ -303,7 +359,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -228,9 +253,10 @@
+@@ -228,9 +269,10 @@
* @exception NoAccessException if the method does not exist or access checking fails
*/
public MethodHandle findVirtual(Class<?> defc, String name, MethodType type) throws NoAccessException {
@@ -317,7 +373,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -259,15 +285,17 @@
+@@ -259,15 +301,17 @@
*/
public MethodHandle findSpecial(Class<?> defc, String name, MethodType type,
Class<?> specialCaller) throws NoAccessException {
@@ -340,7 +396,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -275,13 +303,19 @@
+@@ -275,13 +319,19 @@
* The receiver must have a supertype {@code defc} in which a method
* of the given name and type is accessible to the lookup class.
* The method and all its argument types must be accessible to the lookup class.
@@ -363,7 +419,7 @@ diff --git a/src/share/classes/java/dyn/
* @param receiver the object from which the method is accessed
* @param name the name of the method
* @param type the type of the method, with the receiver argument omitted
-@@ -292,16 +326,18 @@
+@@ -292,16 +342,18 @@
public MethodHandle bind(Object receiver, String name, MethodType type) throws NoAccessException {
Class<? extends Object> rcvc = receiver.getClass(); // may get NPE
MemberName reference = new MemberName(rcvc, name, type);
@@ -386,7 +442,7 @@ diff --git a/src/share/classes/java/dyn/
* Make a direct method handle to <i>m</i>, if the lookup class has permission.
* If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
* If <i>m</i> is virtual, overriding is respected on every call.
-@@ -316,10 +352,11 @@
+@@ -316,10 +368,11 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflect(Method m) throws NoAccessException {
@@ -399,7 +455,7 @@ diff --git a/src/share/classes/java/dyn/
* Produce a method handle for a reflected method.
* It will bypass checks for overriding methods on the receiver,
* as if by the {@code invokespecial} instruction.
-@@ -333,37 +370,41 @@
+@@ -333,37 +386,41 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws NoAccessException {
@@ -450,7 +506,7 @@ diff --git a/src/share/classes/java/dyn/
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
-@@ -371,16 +412,17 @@
+@@ -371,16 +428,17 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectGetter(Field f) throws NoAccessException {
@@ -472,7 +528,7 @@ diff --git a/src/share/classes/java/dyn/
* If the method's {@code accessible} flag is not set,
* access checking is performed immediately on behalf of the lookup class.
* @param f the reflected field
-@@ -388,59 +430,60 @@
+@@ -388,59 +446,63 @@
* @exception NoAccessException if access checking fails
*/
public MethodHandle unreflectSetter(Field f) throws NoAccessException {
@@ -539,6 +595,9 @@ diff --git a/src/share/classes/java/dyn/
} else {
- constraint = VerifyAccess.isAccessible(defc, mods, doDispatch, lookupClass);
+ constraint = VerifyAccess.isAccessible(defc, mods, doDispatch, lookup.lookupClass());
++ }
++ if (constraint == null) {
++ throw newNoAccessException(m, lookup);
}
if (constraint != defc && !constraint.isAssignableFrom(defc)) {
if (!defc.isAssignableFrom(constraint))
@@ -552,7 +611,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -515,45 +558,107 @@
+@@ -515,45 +577,107 @@
if (argc <= 4) {
MethodHandle invoker = invokers(type).genericInvoker();
switch (argc) {
@@ -672,7 +731,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -703,26 +808,15 @@
+@@ -703,26 +827,15 @@
* arguments and return types. Let T0 and T1 be the differing
* new and old parameter types (or old and new return types)
* for corresponding values passed by the new and old method types.
@@ -705,7 +764,7 @@ diff --git a/src/share/classes/java/dyn/
* <li>If T0 and T1 are primitives, then a Java casting
* conversion (JLS 5.5) is applied, if one exists.
* <li>If T0 and T1 are primitives and one is boolean,
-@@ -745,9 +839,9 @@
+@@ -745,9 +858,9 @@
* if necessary to T1 by one of the preceding conversions.
* Otherwise, T0 is converted directly to the wrapper type for T1,
* which is then unboxed.
@@ -718,7 +777,7 @@ diff --git a/src/share/classes/java/dyn/
* </ul>
* @param target the method handle to invoke after arguments are retyped
* @param newType the expected type of the new method handle
-@@ -872,20 +966,14 @@
+@@ -872,20 +985,14 @@
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
* Produce a method handle which adapts the type of the
* given method handle to a new type, by collecting a series of
@@ -741,7 +800,7 @@ diff --git a/src/share/classes/java/dyn/
* @param target the method handle to invoke after the argument is prepended
* @param newType the expected type of the new method handle
* @return a new method handle which collects some trailings argument
-@@ -900,24 +988,27 @@
+@@ -900,24 +1007,27 @@
int numCollect = (inargs - collectPos);
if (collectPos < 0 || numCollect < 0)
throw newIllegalArgumentException("wrong number of arguments");
@@ -780,7 +839,7 @@ diff --git a/src/share/classes/java/dyn/
* @param target the method handle to invoke after the argument is inserted
* @param pos where to insert the argument (zero for the first)
* @param value the argument to insert
-@@ -925,25 +1016,40 @@
+@@ -925,25 +1035,40 @@
* before calling the original method handle
*/
public static
@@ -834,7 +893,7 @@ diff --git a/src/share/classes/java/dyn/
}
/**
-@@ -953,10 +1059,25 @@
+@@ -953,10 +1078,25 @@
* The type of the new method handle will insert the given argument
* type(s), at that position, into the original handle's type.
* <p>
@@ -861,7 +920,7 @@ diff --git a/src/share/classes/java/dyn/
* @param target the method handle to invoke after the argument is dropped
* @param valueTypes the type(s) of the argument to drop
* @param pos which argument to drop (zero for the first)
-@@ -1040,65 +1161,123 @@
+@@ -1040,65 +1180,123 @@
/**
* <em>PROVISIONAL API, WORK IN PROGRESS:</em>
@@ -1663,6 +1722,17 @@ diff --git a/src/share/classes/sun/dyn/M
import static sun.dyn.MemberName.newIllegalArgumentException;
import static sun.dyn.MemberName.newNoAccessException;
+@@ -106,8 +110,8 @@
+ }
+
+ static {
+- // Force initialization:
+- Lookup.PUBLIC_LOOKUP.lookupClass();
++ // Force initialization of Lookup, so it calls us back as initLookup:
++ MethodHandles.publicLookup();
+ if (IMPL_LOOKUP_INIT == null)
+ throw new InternalError();
+ }
@@ -203,8 +207,11 @@
if (info instanceof DirectMethodHandle) {
DirectMethodHandle dmh = (DirectMethodHandle) info;