--- old/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2017-02-07 13:13:25.356690084 +0000 +++ new/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2017-02-07 13:13:25.183678202 +0000 @@ -25,8 +25,6 @@ package java.lang.invoke; -import jdk.internal.org.objectweb.asm.ClassWriter; -import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import jdk.internal.vm.annotation.ForceInline; @@ -111,13 +109,17 @@ /** * Returns a {@link Lookup lookup object} which is trusted minimally. - * It can only be used to create method handles to public members in + * The lookup has the {@code PUBLIC} and {@code UNCONDITIONAL} modes. + * It can only be used to create method handles to public members of * public classes in packages that are exported unconditionally. *

- * For now, the {@linkplain Lookup#lookupClass lookup class} of this lookup - * object is in an unnamed module. - * Consequently, the lookup context of this lookup object will be the bootstrap - * class loader, which means it cannot find user classes. + * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class} + * of this lookup object will be {@link java.lang.Object}. + * + * @apiNote The use of Object is conventional, and because the lookup modes are + * limited, there is no special access provided to the internals of Object, its package + * or its module. Consequently, the lookup context of this lookup object will be the + * bootstrap class loader, which means it cannot find user classes. * *

* Discussion: @@ -129,17 +131,12 @@ * Also, it cannot access * caller sensitive methods. * @return a lookup object which is trusted minimally + * + * @revised 9 + * @spec JPMS */ public static Lookup publicLookup() { - // During VM startup then only classes in the java.base module can be - // loaded and linked. This is because java.base exports aren't setup until - // the module system is initialized, hence types in the unnamed module - // (or any named module) can't link to java/lang/Object. - if (!jdk.internal.misc.VM.isModuleSystemInited()) { - return new Lookup(Object.class, Lookup.PUBLIC); - } else { - return LookupHelper.PUBLIC_LOOKUP; - } + return Lookup.PUBLIC_LOOKUP; } /** @@ -172,6 +169,7 @@ * @throws IllegalAccessException if the access check specified above fails * @throws SecurityException if denied by the security manager * @since 9 + * @spec JPMS * @see Lookup#dropLookupMode */ public static Lookup privateLookupIn(Class targetClass, Lookup lookup) throws IllegalAccessException { @@ -183,11 +181,11 @@ throw new IllegalArgumentException(targetClass + " is an array class"); Module targetModule = targetClass.getModule(); Module callerModule = lookup.lookupClass().getModule(); - if (callerModule != targetModule && targetModule.isNamed()) { - if (!callerModule.canRead(targetModule)) - throw new IllegalAccessException(callerModule + " does not read " + targetModule); + if (!callerModule.canRead(targetModule)) + throw new IllegalAccessException(callerModule + " does not read " + targetModule); + if (targetModule.isNamed()) { String pn = targetClass.getPackageName(); - assert pn != null && pn.length() > 0 : "unnamed package cannot be in named module"; + assert pn.length() > 0 : "unnamed package cannot be in named module"; if (!targetModule.isOpen(pn, callerModule)) throw new IllegalAccessException(targetModule + " does not open " + pn + " to " + callerModule); } @@ -601,6 +599,8 @@ * so that there can be a secure foundation for lookups. * Nearly all other methods in the JSR 292 API rely on lookup * objects to check access requests. + * + * @revised 9 */ public static final class Lookup { @@ -647,15 +647,32 @@ * lookup class and public types in packages exported by other modules * to the module of the lookup class. * @since 9 + * @spec JPMS */ public static final int MODULE = PACKAGE << 1; - private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE); + /** A single-bit mask representing {@code unconditional} access + * which may contribute to the result of {@link #lookupModes lookupModes}. + * The value is {@code 0x20}, which does not correspond meaningfully to + * any particular {@linkplain java.lang.reflect.Modifier modifier bit}. + * A {@code Lookup} with this lookup mode assumes {@linkplain + * java.lang.reflect.Module#canRead(java.lang.reflect.Module) readability}. + * In conjunction with the {@code PUBLIC} modifier bit, a {@code Lookup} + * with this lookup mode can access all public members of public types + * of all modules where the type is in a package that is {@link + * java.lang.reflect.Module#isExported(String) exported unconditionally}. + * @see #publicLookup() + * @since 9 + */ + public static final int UNCONDITIONAL = PACKAGE << 2; + + private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE | MODULE | UNCONDITIONAL); + private static final int FULL_POWER_MODES = (ALL_MODES & ~UNCONDITIONAL); private static final int TRUSTED = -1; private static int fixmods(int mods) { - mods &= (ALL_MODES - PACKAGE - MODULE); - return (mods != 0) ? mods : (PACKAGE | MODULE); + mods &= (ALL_MODES - PACKAGE - MODULE - UNCONDITIONAL); + return (mods != 0) ? mods : (PACKAGE | MODULE | UNCONDITIONAL); } /** Tells which class is performing the lookup. It is this class against @@ -682,13 +699,14 @@ * {@linkplain #PRIVATE PRIVATE (0x02)}, * {@linkplain #PROTECTED PROTECTED (0x04)}, * {@linkplain #PACKAGE PACKAGE (0x08)}, - * and {@linkplain #MODULE MODULE (0x10)}. + * {@linkplain #MODULE MODULE (0x10)}, + * and {@linkplain #UNCONDITIONAL UNCONDITIONAL (0x20)}. *

* A freshly-created lookup object - * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} - * has all possible bits set, since the caller class can access all its own members, - * all public types in the caller's module, and all public types in packages exported - * by other modules to the caller's module. + * on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class} has + * all possible bits set, except {@code UNCONDITIONAL}. The lookup can be used to + * access all members of the caller's class, all public types in the caller's module, + * and all public types in packages exported by other modules to the caller's module. * A lookup object on a new lookup class * {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object} * may have some mode bits set to zero. @@ -701,6 +719,9 @@ * @return the lookup modes, which limit the kinds of access performed by this lookup object * @see #in * @see #dropLookupMode + * + * @revised 9 + * @spec JPMS */ public int lookupModes() { return allowedModes & ALL_MODES; @@ -712,9 +733,9 @@ * which in turn is called by a method not in this package. */ Lookup(Class lookupClass) { - this(lookupClass, ALL_MODES); + this(lookupClass, FULL_POWER_MODES); // make sure we haven't accidentally picked up a privileged class: - checkUnprivilegedlookupClass(lookupClass, ALL_MODES); + checkUnprivilegedlookupClass(lookupClass, FULL_POWER_MODES); } private Lookup(Class lookupClass, int allowedModes) { @@ -730,19 +751,20 @@ * However, the resulting {@code Lookup} object is guaranteed * to have no more access capabilities than the original. * In particular, access capabilities can be lost as follows: