Almost compiled java.lang.invoke, except the parts that deal with Asm bytecode generator
1.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/CallSite.java Sun Aug 10 05:56:32 2014 +0200
1.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/CallSite.java Sun Aug 10 06:13:36 2014 +0200
1.3 @@ -232,21 +232,13 @@
1.4 throw new IllegalStateException("uninitialized call site");
1.5 }
1.6
1.7 - // unsafe stuff:
1.8 - private static final long TARGET_OFFSET;
1.9 - static {
1.10 - try {
1.11 - TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
1.12 - } catch (Exception ex) { throw new Error(ex); }
1.13 - }
1.14 -
1.15 /*package-private*/
1.16 void setTargetNormal(MethodHandle newTarget) {
1.17 MethodHandleNatives.setCallSiteTargetNormal(this, newTarget);
1.18 }
1.19 /*package-private*/
1.20 MethodHandle getTargetVolatile() {
1.21 - return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
1.22 + return target;
1.23 }
1.24 /*package-private*/
1.25 void setTargetVolatile(MethodHandle newTarget) {
2.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/InnerClassLambdaMetafactory.java Sun Aug 10 05:56:32 2014 +0200
2.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/InnerClassLambdaMetafactory.java Sun Aug 10 06:13:36 2014 +0200
2.3 @@ -83,16 +83,6 @@
2.4 // Used to ensure that each spun class name is unique
2.5 private static final AtomicInteger counter = new AtomicInteger(0);
2.6
2.7 - // For dumping generated classes to disk, for debugging purposes
2.8 - private static final ProxyClassesDumper dumper;
2.9 -
2.10 - static {
2.11 - final String key = "jdk.internal.lambda.dumpProxyClasses";
2.12 - String path = AccessController.doPrivileged(
2.13 - new GetPropertyAction(key), null,
2.14 - new PropertyPermission(key , "read"));
2.15 - dumper = (null == path) ? null : ProxyClassesDumper.getInstance(path);
2.16 - }
2.17
2.18 // See context values in AbstractValidatingLambdaMetafactory
2.19 private final String implMethodClassName; // Name of type containing implementation "CC"
3.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandle.java Sun Aug 10 05:56:32 2014 +0200
3.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandle.java Sun Aug 10 06:13:36 2014 +0200
3.3 @@ -28,7 +28,6 @@
3.4
3.5 import java.util.*;
3.6 import sun.invoke.util.*;
3.7 -import sun.misc.Unsafe;
3.8
3.9 import static java.lang.invoke.MethodHandleStatics.*;
3.10 import java.util.logging.Level;
3.11 @@ -434,7 +433,7 @@
3.12 @interface PolymorphicSignature { }
3.13
3.14 private final MethodType type;
3.15 - /*private*/ final LambdaForm form;
3.16 + /*private*/ LambdaForm form;
3.17 // form is not private so that invokers can easily fetch it
3.18 /*private*/ MethodHandle asTypeCache;
3.19 // asTypeCache is not private so that invokers can easily fetch it
3.20 @@ -1395,7 +1394,7 @@
3.21
3.22 // CURRENT RESTRICTIONS
3.23 // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others)
3.24 - assert pos == 0 && basicType == 'L' && value instanceof Unsafe;
3.25 +// assert pos == 0 && basicType == 'L' && value instanceof Unsafe;
3.26 MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver!
3.27 LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos
3.28 return copyWith(type2, form2);
3.29 @@ -1489,17 +1488,7 @@
3.30 /*non-public*/
3.31 void updateForm(LambdaForm newForm) {
3.32 if (form == newForm) return;
3.33 - // ISSUE: Should we have a memory fence here?
3.34 - UNSAFE.putObject(this, FORM_OFFSET, newForm);
3.35 + this.form = newForm;
3.36 this.form.prepare(); // as in MethodHandle.<init>
3.37 }
3.38 -
3.39 - private static final long FORM_OFFSET;
3.40 - static {
3.41 - try {
3.42 - FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
3.43 - } catch (ReflectiveOperationException ex) {
3.44 - throw newInternalError(ex);
3.45 - }
3.46 - }
3.47 }
4.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleImpl.java Sun Aug 10 05:56:32 2014 +0200
4.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleImpl.java Sun Aug 10 06:13:36 2014 +0200
4.3 @@ -34,8 +34,6 @@
4.4 import sun.invoke.util.ValueConversions;
4.5 import sun.invoke.util.VerifyType;
4.6 import sun.invoke.util.Wrapper;
4.7 -import sun.reflect.CallerSensitive;
4.8 -import sun.reflect.Reflection;
4.9 import static java.lang.invoke.LambdaForm.*;
4.10 import static java.lang.invoke.MethodHandleStatics.*;
4.11 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
4.12 @@ -842,6 +840,8 @@
4.13 }
4.14
4.15 private static MethodHandle makeInjectedInvoker(Class<?> hostClass) {
4.16 + throw new IllegalStateException("Implement me too!");
4.17 + /*
4.18 Class<?> bcc = UNSAFE.defineAnonymousClass(hostClass, T_BYTES, null);
4.19 if (hostClass.getClassLoader() != bcc.getClassLoader())
4.20 throw new InternalError(hostClass.getName()+" (CL)");
4.21 @@ -873,6 +873,7 @@
4.22 throw new InternalError(ex);
4.23 }
4.24 return bccInvoker;
4.25 + */
4.26 }
4.27 private static ClassValue<MethodHandle> CV_makeInjectedInvoker = new ClassValue<MethodHandle>() {
4.28 @Override protected MethodHandle computeValue(Class<?> hostClass) {
4.29 @@ -905,7 +906,7 @@
4.30 private static final MethodHandle MH_checkCallerClass;
4.31 static {
4.32 final Class<?> THIS_CLASS = BindCaller.class;
4.33 - assert(checkCallerClass(THIS_CLASS, THIS_CLASS));
4.34 +// assert(checkCallerClass(THIS_CLASS, THIS_CLASS));
4.35 try {
4.36 MH_checkCallerClass = IMPL_LOOKUP
4.37 .findStatic(THIS_CLASS, "checkCallerClass",
4.38 @@ -916,16 +917,16 @@
4.39 }
4.40 }
4.41
4.42 - @CallerSensitive
4.43 - private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
4.44 - // This method is called via MH_checkCallerClass and so it's
4.45 - // correct to ask for the immediate caller here.
4.46 - Class<?> actual = Reflection.getCallerClass();
4.47 - if (actual != expected && actual != expected2)
4.48 - throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
4.49 - +(expected == expected2 ? "" : ", or else "+expected2.getName()));
4.50 - return true;
4.51 - }
4.52 +// @CallerSensitive
4.53 +// private static boolean checkCallerClass(Class<?> expected, Class<?> expected2) {
4.54 +// // This method is called via MH_checkCallerClass and so it's
4.55 +// // correct to ask for the immediate caller here.
4.56 +// Class<?> actual = Reflection.getCallerClass();
4.57 +// if (actual != expected && actual != expected2)
4.58 +// throw new InternalError("found "+actual.getName()+", expected "+expected.getName()
4.59 +// +(expected == expected2 ? "" : ", or else "+expected2.getName()));
4.60 +// return true;
4.61 +// }
4.62
4.63 private static final byte[] T_BYTES;
4.64 static {
5.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleNatives.java Sun Aug 10 05:56:32 2014 +0200
5.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleNatives.java Sun Aug 10 06:13:36 2014 +0200
5.3 @@ -265,7 +265,7 @@
5.4 continue;
5.5 }
5.6 throw new InternalError(err);
5.7 - } catch (NoSuchFieldException | IllegalAccessException ex) {
5.8 + } catch (IllegalAccessException ex) {
5.9 String err = (name+": JVM has "+vmval+" which Java does not define");
5.10 // ignore exotic ops the JVM cares about; we just wont issue them
5.11 //System.err.println("warning: "+err);
5.12 @@ -488,7 +488,7 @@
5.13 Class<?> defc = mem.getDeclaringClass();
5.14 switch (mem.getName()) {
5.15 case "checkMemberAccess":
5.16 - return canBeCalledVirtual(mem, java.lang.SecurityManager.class);
5.17 + return true; //canBeCalledVirtual(mem, java.lang.SecurityManager.class);
5.18 case "getContextClassLoader":
5.19 return canBeCalledVirtual(mem, java.lang.Thread.class);
5.20 }
6.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleProxies.java Sun Aug 10 05:56:32 2014 +0200
6.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleProxies.java Sun Aug 10 06:13:36 2014 +0200
6.3 @@ -30,9 +30,9 @@
6.4 import java.security.PrivilegedAction;
6.5 import sun.invoke.WrapperInstance;
6.6 import java.util.ArrayList;
6.7 -import sun.reflect.CallerSensitive;
6.8 -import sun.reflect.Reflection;
6.9 -import sun.reflect.misc.ReflectUtil;
6.10 +//import sun.reflect.CallerSensitive;
6.11 +//import sun.reflect.Reflection;
6.12 +//import sun.reflect.misc.ReflectUtil;
6.13
6.14 /**
6.15 * This class consists exclusively of static methods that help adapt
6.16 @@ -144,17 +144,17 @@
6.17 // entry points, must be covered by hand-written or automatically
6.18 // generated adapter classes.
6.19 //
6.20 - @CallerSensitive
6.21 +// @CallerSensitive
6.22 public static
6.23 <T> T asInterfaceInstance(final Class<T> intfc, final MethodHandle target) {
6.24 if (!intfc.isInterface() || !Modifier.isPublic(intfc.getModifiers()))
6.25 throw new IllegalArgumentException("not a public interface: "+intfc.getName());
6.26 final MethodHandle mh;
6.27 - if (System.getSecurityManager() != null) {
6.28 - final Class<?> caller = Reflection.getCallerClass();
6.29 - final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
6.30 - ReflectUtil.checkProxyPackageAccess(ccl, intfc);
6.31 - mh = ccl != null ? bindCaller(target, caller) : target;
6.32 + if (false) {//System.getSecurityManager() != null) {
6.33 +// final Class<?> caller = Reflection.getCallerClass();
6.34 +// final ClassLoader ccl = caller != null ? caller.getClassLoader() : null;
6.35 +// ReflectUtil.checkProxyPackageAccess(ccl, intfc);
6.36 +// mh = ccl != null ? bindCaller(target, caller) : target;
6.37 } else {
6.38 mh = target;
6.39 }
6.40 @@ -194,7 +194,7 @@
6.41 };
6.42
6.43 final Object proxy;
6.44 - if (System.getSecurityManager() != null) {
6.45 + if (false) { // System.getSecurityManager() != null) {
6.46 // sun.invoke.WrapperInstance is a restricted interface not accessible
6.47 // by any non-null class loader.
6.48 final ClassLoader loader = proxyLoader;
7.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleStatics.java Sun Aug 10 05:56:32 2014 +0200
7.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandleStatics.java Sun Aug 10 06:13:36 2014 +0200
7.3 @@ -27,7 +27,7 @@
7.4
7.5 import java.security.AccessController;
7.6 import java.security.PrivilegedAction;
7.7 -import sun.misc.Unsafe;
7.8 +//import sun.misc.Unsafe;
7.9
7.10 /**
7.11 * This class consists exclusively of static names internal to the
7.12 @@ -39,7 +39,7 @@
7.13
7.14 private MethodHandleStatics() { } // do not instantiate
7.15
7.16 - static final Unsafe UNSAFE = Unsafe.getUnsafe();
7.17 +// static final Unsafe UNSAFE = Unsafe.getUnsafe();
7.18
7.19 static final boolean DEBUG_METHOD_HANDLE_NAMES;
7.20 static final boolean DUMP_CLASS_FILES;
8.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandles.java Sun Aug 10 05:56:32 2014 +0200
8.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodHandles.java Sun Aug 10 06:13:36 2014 +0200
8.3 @@ -33,14 +33,9 @@
8.4 import sun.invoke.util.ValueConversions;
8.5 import sun.invoke.util.VerifyAccess;
8.6 import sun.invoke.util.Wrapper;
8.7 -import sun.reflect.CallerSensitive;
8.8 -import sun.reflect.Reflection;
8.9 -import sun.reflect.misc.ReflectUtil;
8.10 -import sun.security.util.SecurityConstants;
8.11 import static java.lang.invoke.MethodHandleStatics.*;
8.12 import static java.lang.invoke.MethodHandleNatives.Constants.*;
8.13 import java.util.concurrent.ConcurrentHashMap;
8.14 -import sun.security.util.SecurityConstants;
8.15
8.16 /**
8.17 * This class consists exclusively of static methods that operate on or return
8.18 @@ -85,9 +80,10 @@
8.19 * executing in the same caller class {@code C}.
8.20 * @return a lookup object for the caller of this method, with private access
8.21 */
8.22 - @CallerSensitive
8.23 +// @CallerSensitive
8.24 public static Lookup lookup() {
8.25 - return new Lookup(Reflection.getCallerClass());
8.26 + throw new IllegalStateException("Implement me!");
8.27 +// return new Lookup(Reflection.getCallerClass());
8.28 }
8.29
8.30 /**
8.31 @@ -138,14 +134,14 @@
8.32 */
8.33 public static <T extends Member> T
8.34 reflectAs(Class<T> expected, MethodHandle target) {
8.35 - SecurityManager smgr = System.getSecurityManager();
8.36 - if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION);
8.37 +// SecurityManager smgr = System.getSecurityManager();
8.38 +// if (smgr != null) smgr.checkPermission(ACCESS_PERMISSION);
8.39 Lookup lookup = Lookup.IMPL_LOOKUP; // use maximally privileged lookup
8.40 return lookup.revealDirect(target).reflectAs(expected, lookup);
8.41 }
8.42 // Copied from AccessibleObject, as used by Method.setAccessible, etc.:
8.43 - static final private java.security.Permission ACCESS_PERMISSION =
8.44 - new ReflectPermission("suppressAccessChecks");
8.45 +// static final private java.security.Permission ACCESS_PERMISSION =
8.46 +// new ReflectPermission("suppressAccessChecks");
8.47
8.48 /**
8.49 * A <em>lookup object</em> is a factory for creating method handles,
8.50 @@ -1428,28 +1424,28 @@
8.51 * If this lookup object has private access, then the caller class is the lookupClass.
8.52 */
8.53 void checkSecurityManager(Class<?> refc, MemberName m) {
8.54 - SecurityManager smgr = System.getSecurityManager();
8.55 - if (smgr == null) return;
8.56 - if (allowedModes == TRUSTED) return;
8.57 -
8.58 - // Step 1:
8.59 - boolean fullPowerLookup = hasPrivateAccess();
8.60 - if (!fullPowerLookup ||
8.61 - !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
8.62 - ReflectUtil.checkPackageAccess(refc);
8.63 - }
8.64 -
8.65 - // Step 2:
8.66 - if (m.isPublic()) return;
8.67 - if (!fullPowerLookup) {
8.68 - smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
8.69 - }
8.70 -
8.71 - // Step 3:
8.72 - Class<?> defc = m.getDeclaringClass();
8.73 - if (!fullPowerLookup && defc != refc) {
8.74 - ReflectUtil.checkPackageAccess(defc);
8.75 - }
8.76 +// SecurityManager smgr = System.getSecurityManager();
8.77 +// if (smgr == null) return;
8.78 +// if (allowedModes == TRUSTED) return;
8.79 +//
8.80 +// // Step 1:
8.81 +// boolean fullPowerLookup = hasPrivateAccess();
8.82 +// if (!fullPowerLookup ||
8.83 +// !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
8.84 +// ReflectUtil.checkPackageAccess(refc);
8.85 +// }
8.86 +//
8.87 +// // Step 2:
8.88 +// if (m.isPublic()) return;
8.89 +// if (!fullPowerLookup) {
8.90 +// smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
8.91 +// }
8.92 +//
8.93 +// // Step 3:
8.94 +// Class<?> defc = m.getDeclaringClass();
8.95 +// if (!fullPowerLookup && defc != refc) {
8.96 +// ReflectUtil.checkPackageAccess(defc);
8.97 +// }
8.98 }
8.99
8.100 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
8.101 @@ -1749,17 +1745,17 @@
8.102 return false;
8.103 }
8.104 ClassLoader loader = defc.getClassLoader();
8.105 - if (!sun.misc.VM.isSystemDomainLoader(loader)) {
8.106 - ClassLoader sysl = ClassLoader.getSystemClassLoader();
8.107 - boolean found = false;
8.108 - while (sysl != null) {
8.109 - if (loader == sysl) { found = true; break; }
8.110 - sysl = sysl.getParent();
8.111 - }
8.112 - if (!found) {
8.113 - return false;
8.114 - }
8.115 - }
8.116 +// if (!sun.misc.VM.isSystemDomainLoader(loader)) {
8.117 +// ClassLoader sysl = ClassLoader.getSystemClassLoader();
8.118 +// boolean found = false;
8.119 +// while (sysl != null) {
8.120 +// if (loader == sysl) { found = true; break; }
8.121 +// sysl = sysl.getParent();
8.122 +// }
8.123 +// if (!found) {
8.124 +// return false;
8.125 +// }
8.126 +// }
8.127 try {
8.128 MemberName resolved2 = publicLookup().resolveOrFail(refKind,
8.129 new MemberName(refKind, defc, member.getName(), member.getType()));
9.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/MethodType.java Sun Aug 10 05:56:32 2014 +0200
9.2 +++ b/rt/emul/compact/src/main/java/java/lang/invoke/MethodType.java Sun Aug 10 06:13:36 2014 +0200
9.3 @@ -948,60 +948,60 @@
9.4 */
9.5 private static final java.io.ObjectStreamField[] serialPersistentFields = { };
9.6
9.7 - /**
9.8 - * Save the {@code MethodType} instance to a stream.
9.9 - *
9.10 - * @serialData
9.11 - * For portability, the serialized format does not refer to named fields.
9.12 - * Instead, the return type and parameter type arrays are written directly
9.13 - * from the {@code writeObject} method, using two calls to {@code s.writeObject}
9.14 - * as follows:
9.15 - * <blockquote><pre>{@code
9.16 -s.writeObject(this.returnType());
9.17 -s.writeObject(this.parameterArray());
9.18 - * }</pre></blockquote>
9.19 - * <p>
9.20 - * The deserialized field values are checked as if they were
9.21 - * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
9.22 - * For example, null values, or {@code void} parameter types,
9.23 - * will lead to exceptions during deserialization.
9.24 - * @param s the stream to write the object to
9.25 - * @throws java.io.IOException if there is a problem writing the object
9.26 - */
9.27 - private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
9.28 - s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
9.29 - s.writeObject(returnType());
9.30 - s.writeObject(parameterArray());
9.31 - }
9.32 -
9.33 - /**
9.34 - * Reconstitute the {@code MethodType} instance from a stream (that is,
9.35 - * deserialize it).
9.36 - * This instance is a scratch object with bogus final fields.
9.37 - * It provides the parameters to the factory method called by
9.38 - * {@link #readResolve readResolve}.
9.39 - * After that call it is discarded.
9.40 - * @param s the stream to read the object from
9.41 - * @throws java.io.IOException if there is a problem reading the object
9.42 - * @throws ClassNotFoundException if one of the component classes cannot be resolved
9.43 - * @see #MethodType()
9.44 - * @see #readResolve
9.45 - * @see #writeObject
9.46 - */
9.47 - private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
9.48 - s.defaultReadObject(); // requires serialPersistentFields to be an empty array
9.49 -
9.50 - Class<?> returnType = (Class<?>) s.readObject();
9.51 - Class<?>[] parameterArray = (Class<?>[]) s.readObject();
9.52 -
9.53 - // Probably this object will never escape, but let's check
9.54 - // the field values now, just to be sure.
9.55 - checkRtype(returnType);
9.56 - checkPtypes(parameterArray);
9.57 -
9.58 - parameterArray = parameterArray.clone(); // make sure it is unshared
9.59 - MethodType_init(returnType, parameterArray);
9.60 - }
9.61 +// /**
9.62 +// * Save the {@code MethodType} instance to a stream.
9.63 +// *
9.64 +// * @serialData
9.65 +// * For portability, the serialized format does not refer to named fields.
9.66 +// * Instead, the return type and parameter type arrays are written directly
9.67 +// * from the {@code writeObject} method, using two calls to {@code s.writeObject}
9.68 +// * as follows:
9.69 +// * <blockquote><pre>{@code
9.70 +//s.writeObject(this.returnType());
9.71 +//s.writeObject(this.parameterArray());
9.72 +// * }</pre></blockquote>
9.73 +// * <p>
9.74 +// * The deserialized field values are checked as if they were
9.75 +// * provided to the factory method {@link #methodType(Class,Class[]) methodType}.
9.76 +// * For example, null values, or {@code void} parameter types,
9.77 +// * will lead to exceptions during deserialization.
9.78 +// * @param s the stream to write the object to
9.79 +// * @throws java.io.IOException if there is a problem writing the object
9.80 +// */
9.81 +// private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException {
9.82 +// s.defaultWriteObject(); // requires serialPersistentFields to be an empty array
9.83 +// s.writeObject(returnType());
9.84 +// s.writeObject(parameterArray());
9.85 +// }
9.86 +//
9.87 +// /**
9.88 +// * Reconstitute the {@code MethodType} instance from a stream (that is,
9.89 +// * deserialize it).
9.90 +// * This instance is a scratch object with bogus final fields.
9.91 +// * It provides the parameters to the factory method called by
9.92 +// * {@link #readResolve readResolve}.
9.93 +// * After that call it is discarded.
9.94 +// * @param s the stream to read the object from
9.95 +// * @throws java.io.IOException if there is a problem reading the object
9.96 +// * @throws ClassNotFoundException if one of the component classes cannot be resolved
9.97 +// * @see #MethodType()
9.98 +// * @see #readResolve
9.99 +// * @see #writeObject
9.100 +// */
9.101 +// private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {
9.102 +// s.defaultReadObject(); // requires serialPersistentFields to be an empty array
9.103 +//
9.104 +// Class<?> returnType = (Class<?>) s.readObject();
9.105 +// Class<?>[] parameterArray = (Class<?>[]) s.readObject();
9.106 +//
9.107 +// // Probably this object will never escape, but let's check
9.108 +// // the field values now, just to be sure.
9.109 +// checkRtype(returnType);
9.110 +// checkPtypes(parameterArray);
9.111 +//
9.112 +// parameterArray = parameterArray.clone(); // make sure it is unshared
9.113 +// MethodType_init(returnType, parameterArray);
9.114 +// }
9.115
9.116 /**
9.117 * For serialization only.
9.118 @@ -1011,27 +1011,27 @@
9.119 this.rtype = null;
9.120 this.ptypes = null;
9.121 }
9.122 - private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
9.123 - // In order to communicate these values to readResolve, we must
9.124 - // store them into the implementation-specific final fields.
9.125 - checkRtype(rtype);
9.126 - checkPtypes(ptypes);
9.127 - UNSAFE.putObject(this, rtypeOffset, rtype);
9.128 - UNSAFE.putObject(this, ptypesOffset, ptypes);
9.129 - }
9.130 +// private void MethodType_init(Class<?> rtype, Class<?>[] ptypes) {
9.131 +// // In order to communicate these values to readResolve, we must
9.132 +// // store them into the implementation-specific final fields.
9.133 +// checkRtype(rtype);
9.134 +// checkPtypes(ptypes);
9.135 +// UNSAFE.putObject(this, rtypeOffset, rtype);
9.136 +// UNSAFE.putObject(this, ptypesOffset, ptypes);
9.137 +// }
9.138
9.139 // Support for resetting final fields while deserializing
9.140 - private static final long rtypeOffset, ptypesOffset;
9.141 - static {
9.142 - try {
9.143 - rtypeOffset = UNSAFE.objectFieldOffset
9.144 - (MethodType.class.getDeclaredField("rtype"));
9.145 - ptypesOffset = UNSAFE.objectFieldOffset
9.146 - (MethodType.class.getDeclaredField("ptypes"));
9.147 - } catch (Exception ex) {
9.148 - throw new Error(ex);
9.149 - }
9.150 - }
9.151 +// private static final long rtypeOffset, ptypesOffset;
9.152 +// static {
9.153 +// try {
9.154 +// rtypeOffset = UNSAFE.objectFieldOffset
9.155 +// (MethodType.class.getDeclaredField("rtype"));
9.156 +// ptypesOffset = UNSAFE.objectFieldOffset
9.157 +// (MethodType.class.getDeclaredField("ptypes"));
9.158 +// } catch (Exception ex) {
9.159 +// throw new Error(ex);
9.160 +// }
9.161 +// }
9.162
9.163 /**
9.164 * Resolves and initializes a {@code MethodType} object
10.1 --- a/rt/emul/compact/src/main/java/java/lang/invoke/ProxyClassesDumper.java Sun Aug 10 05:56:32 2014 +0200
10.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
10.3 @@ -1,147 +0,0 @@
10.4 -/*
10.5 - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
10.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
10.7 - *
10.8 - * This code is free software; you can redistribute it and/or modify it
10.9 - * under the terms of the GNU General Public License version 2 only, as
10.10 - * published by the Free Software Foundation. Oracle designates this
10.11 - * particular file as subject to the "Classpath" exception as provided
10.12 - * by Oracle in the LICENSE file that accompanied this code.
10.13 - *
10.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
10.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10.17 - * version 2 for more details (a copy is included in the LICENSE file that
10.18 - * accompanied this code).
10.19 - *
10.20 - * You should have received a copy of the GNU General Public License version
10.21 - * 2 along with this work; if not, write to the Free Software Foundation,
10.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
10.23 - *
10.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
10.25 - * or visit www.oracle.com if you need additional information or have any
10.26 - * questions.
10.27 - */
10.28 -package java.lang.invoke;
10.29 -
10.30 -import sun.util.logging.PlatformLogger;
10.31 -
10.32 -import java.io.FilePermission;
10.33 -import java.nio.file.Files;
10.34 -import java.nio.file.InvalidPathException;
10.35 -import java.nio.file.Path;
10.36 -import java.nio.file.Paths;
10.37 -import java.security.AccessController;
10.38 -import java.security.PrivilegedAction;
10.39 -import java.util.Objects;
10.40 -import java.util.concurrent.atomic.AtomicBoolean;
10.41 -
10.42 -/**
10.43 - * Helper class used by InnerClassLambdaMetafactory to log generated classes
10.44 - *
10.45 - * @implNote
10.46 - * <p> Because this class is called by LambdaMetafactory, make use
10.47 - * of lambda lead to recursive calls cause stack overflow.
10.48 - */
10.49 -final class ProxyClassesDumper {
10.50 - private static final char[] HEX = {
10.51 - '0', '1', '2', '3', '4', '5', '6', '7',
10.52 - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
10.53 - };
10.54 - private static final char[] BAD_CHARS = {
10.55 - '\\', ':', '*', '?', '"', '<', '>', '|'
10.56 - };
10.57 - private static final String[] REPLACEMENT = {
10.58 - "%5C", "%3A", "%2A", "%3F", "%22", "%3C", "%3E", "%7C"
10.59 - };
10.60 -
10.61 - private final Path dumpDir;
10.62 -
10.63 - public static ProxyClassesDumper getInstance(String path) {
10.64 - if (null == path) {
10.65 - return null;
10.66 - }
10.67 - try {
10.68 - path = path.trim();
10.69 - final Path dir = Paths.get(path.length() == 0 ? "." : path);
10.70 - AccessController.doPrivileged(new PrivilegedAction<Void>() {
10.71 - @Override
10.72 - public Void run() {
10.73 - validateDumpDir(dir);
10.74 - return null;
10.75 - }
10.76 - }, null, new FilePermission("<<ALL FILES>>", "read, write"));
10.77 - return new ProxyClassesDumper(dir);
10.78 - } catch (InvalidPathException ex) {
10.79 - PlatformLogger.getLogger(ProxyClassesDumper.class.getName())
10.80 - .warning("Path " + path + " is not valid - dumping disabled", ex);
10.81 - } catch (IllegalArgumentException iae) {
10.82 - PlatformLogger.getLogger(ProxyClassesDumper.class.getName())
10.83 - .warning(iae.getMessage() + " - dumping disabled");
10.84 - }
10.85 - return null;
10.86 - }
10.87 -
10.88 - private ProxyClassesDumper(Path path) {
10.89 - dumpDir = Objects.requireNonNull(path);
10.90 - }
10.91 -
10.92 - private static void validateDumpDir(Path path) {
10.93 - if (!Files.exists(path)) {
10.94 - throw new IllegalArgumentException("Directory " + path + " does not exist");
10.95 - } else if (!Files.isDirectory(path)) {
10.96 - throw new IllegalArgumentException("Path " + path + " is not a directory");
10.97 - } else if (!Files.isWritable(path)) {
10.98 - throw new IllegalArgumentException("Directory " + path + " is not writable");
10.99 - }
10.100 - }
10.101 -
10.102 - public static String encodeForFilename(String className) {
10.103 - final int len = className.length();
10.104 - StringBuilder sb = new StringBuilder(len);
10.105 -
10.106 - for (int i = 0; i < len; i++) {
10.107 - char c = className.charAt(i);
10.108 - // control characters
10.109 - if (c <= 31) {
10.110 - sb.append('%');
10.111 - sb.append(HEX[c >> 4 & 0x0F]);
10.112 - sb.append(HEX[c & 0x0F]);
10.113 - } else {
10.114 - int j = 0;
10.115 - for (; j < BAD_CHARS.length; j++) {
10.116 - if (c == BAD_CHARS[j]) {
10.117 - sb.append(REPLACEMENT[j]);
10.118 - break;
10.119 - }
10.120 - }
10.121 - if (j >= BAD_CHARS.length) {
10.122 - sb.append(c);
10.123 - }
10.124 - }
10.125 - }
10.126 -
10.127 - return sb.toString();
10.128 - }
10.129 -
10.130 - public void dumpClass(String className, final byte[] classBytes) {
10.131 - Path file;
10.132 - try {
10.133 - file = dumpDir.resolve(encodeForFilename(className) + ".class");
10.134 - } catch (InvalidPathException ex) {
10.135 - PlatformLogger.getLogger(ProxyClassesDumper.class.getName())
10.136 - .warning("Invalid path for class " + className);
10.137 - return;
10.138 - }
10.139 -
10.140 - try {
10.141 - Path dir = file.getParent();
10.142 - Files.createDirectories(dir);
10.143 - Files.write(file, classBytes);
10.144 - } catch (Exception ignore) {
10.145 - PlatformLogger.getLogger(ProxyClassesDumper.class.getName())
10.146 - .warning("Exception writing to path at " + file.toString());
10.147 - // simply don't care if this operation failed
10.148 - }
10.149 - }
10.150 -}
11.1 --- a/rt/emul/compact/src/main/java/sun/invoke/anon/AnonymousClassLoader.java Sun Aug 10 05:56:32 2014 +0200
11.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
11.3 @@ -1,230 +0,0 @@
11.4 -/*
11.5 - * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
11.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
11.7 - *
11.8 - * This code is free software; you can redistribute it and/or modify it
11.9 - * under the terms of the GNU General Public License version 2 only, as
11.10 - * published by the Free Software Foundation. Oracle designates this
11.11 - * particular file as subject to the "Classpath" exception as provided
11.12 - * by Oracle in the LICENSE file that accompanied this code.
11.13 - *
11.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
11.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11.17 - * version 2 for more details (a copy is included in the LICENSE file that
11.18 - * accompanied this code).
11.19 - *
11.20 - * You should have received a copy of the GNU General Public License version
11.21 - * 2 along with this work; if not, write to the Free Software Foundation,
11.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
11.23 - *
11.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
11.25 - * or visit www.oracle.com if you need additional information or have any
11.26 - * questions.
11.27 - */
11.28 -
11.29 -package sun.invoke.anon;
11.30 -
11.31 -import java.io.IOException;
11.32 -import java.lang.reflect.InvocationTargetException;
11.33 -import java.lang.reflect.Method;
11.34 -import sun.misc.IOUtils;
11.35 -
11.36 -/**
11.37 - * Anonymous class loader. Will load any valid classfile, producing
11.38 - * a {@link Class} metaobject, without installing that class in the
11.39 - * system dictionary. Therefore, {@link Class#forName(String)} will never
11.40 - * produce a reference to an anonymous class.
11.41 - * <p>
11.42 - * The access permissions of the anonymous class are borrowed from
11.43 - * a <em>host class</em>. The new class behaves as if it were an
11.44 - * inner class of the host class. It can access the host's private
11.45 - * members, if the creator of the class loader has permission to
11.46 - * do so (or to create accessible reflective objects).
11.47 - * <p>
11.48 - * When the anonymous class is loaded, elements of its constant pool
11.49 - * can be patched to new values. This provides a hook to pre-resolve
11.50 - * named classes in the constant pool to other classes, including
11.51 - * anonymous ones. Also, string constants can be pre-resolved to
11.52 - * any reference. (The verifier treats non-string, non-class reference
11.53 - * constants as plain objects.)
11.54 - * <p>
11.55 - * Why include the patching function? It makes some use cases much easier.
11.56 - * Second, the constant pool needed some internal patching anyway,
11.57 - * to anonymize the loaded class itself. Finally, if you are going
11.58 - * to use this seriously, you'll want to build anonymous classes
11.59 - * on top of pre-existing anonymous classes, and that requires patching.
11.60 - *
11.61 - * <p>%%% TO-DO:
11.62 - * <ul>
11.63 - * <li>needs better documentation</li>
11.64 - * <li>needs more security work (for safe delegation)</li>
11.65 - * <li>needs a clearer story about error processing</li>
11.66 - * <li>patch member references also (use ';' as delimiter char)</li>
11.67 - * <li>patch method references to (conforming) method handles</li>
11.68 - * </ul>
11.69 - *
11.70 - * @author jrose
11.71 - * @author Remi Forax
11.72 - * @see <a href="http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm">
11.73 - * http://blogs.sun.com/jrose/entry/anonymous_classes_in_the_vm</a>
11.74 - */
11.75 -
11.76 -public class AnonymousClassLoader {
11.77 - final Class<?> hostClass;
11.78 -
11.79 - // Privileged constructor.
11.80 - private AnonymousClassLoader(Class<?> hostClass) {
11.81 - this.hostClass = hostClass;
11.82 - }
11.83 -
11.84 - public static AnonymousClassLoader make(sun.misc.Unsafe unsafe, Class<?> hostClass) {
11.85 - if (unsafe == null) throw new NullPointerException();
11.86 - return new AnonymousClassLoader(hostClass);
11.87 - }
11.88 -
11.89 - public Class<?> loadClass(byte[] classFile) {
11.90 - if (defineAnonymousClass == null) {
11.91 - // no JVM support; try to fake an approximation
11.92 - try {
11.93 - return fakeLoadClass(new ConstantPoolParser(classFile).createPatch());
11.94 - } catch (InvalidConstantPoolFormatException ee) {
11.95 - throw new IllegalArgumentException(ee);
11.96 - }
11.97 - }
11.98 - return loadClass(classFile, null);
11.99 - }
11.100 -
11.101 - public Class<?> loadClass(ConstantPoolPatch classPatch) {
11.102 - if (defineAnonymousClass == null) {
11.103 - // no JVM support; try to fake an approximation
11.104 - return fakeLoadClass(classPatch);
11.105 - }
11.106 - Object[] patches = classPatch.patchArray;
11.107 - // Convert class names (this late in the game)
11.108 - // to use slash '/' instead of dot '.'.
11.109 - // Java likes dots, but the JVM likes slashes.
11.110 - for (int i = 0; i < patches.length; i++) {
11.111 - Object value = patches[i];
11.112 - if (value != null) {
11.113 - byte tag = classPatch.getTag(i);
11.114 - switch (tag) {
11.115 - case ConstantPoolVisitor.CONSTANT_Class:
11.116 - if (value instanceof String) {
11.117 - if (patches == classPatch.patchArray)
11.118 - patches = patches.clone();
11.119 - patches[i] = ((String)value).replace('.', '/');
11.120 - }
11.121 - break;
11.122 - case ConstantPoolVisitor.CONSTANT_Fieldref:
11.123 - case ConstantPoolVisitor.CONSTANT_Methodref:
11.124 - case ConstantPoolVisitor.CONSTANT_InterfaceMethodref:
11.125 - case ConstantPoolVisitor.CONSTANT_NameAndType:
11.126 - // When/if the JVM supports these patches,
11.127 - // we'll probably need to reformat them also.
11.128 - // Meanwhile, let the class loader create the error.
11.129 - break;
11.130 - }
11.131 - }
11.132 - }
11.133 - return loadClass(classPatch.outer.classFile, classPatch.patchArray);
11.134 - }
11.135 -
11.136 - private Class<?> loadClass(byte[] classFile, Object[] patchArray) {
11.137 - try {
11.138 - return (Class<?>)
11.139 - defineAnonymousClass.invoke(unsafe,
11.140 - hostClass, classFile, patchArray);
11.141 - } catch (Exception ex) {
11.142 - throwReflectedException(ex);
11.143 - throw new RuntimeException("error loading into "+hostClass, ex);
11.144 - }
11.145 - }
11.146 -
11.147 - private static void throwReflectedException(Exception ex) {
11.148 - if (ex instanceof InvocationTargetException) {
11.149 - Throwable tex = ((InvocationTargetException)ex).getTargetException();
11.150 - if (tex instanceof Error)
11.151 - throw (Error) tex;
11.152 - ex = (Exception) tex;
11.153 - }
11.154 - if (ex instanceof RuntimeException) {
11.155 - throw (RuntimeException) ex;
11.156 - }
11.157 - }
11.158 -
11.159 - private Class<?> fakeLoadClass(ConstantPoolPatch classPatch) {
11.160 - // Implementation:
11.161 - // 1. Make up a new name nobody has used yet.
11.162 - // 2. Inspect the tail-header of the class to find the this_class index.
11.163 - // 3. Patch the CONSTANT_Class for this_class to the new name.
11.164 - // 4. Add other CP entries required by (e.g.) string patches.
11.165 - // 5. Flatten Class constants down to their names, making sure that
11.166 - // the host class loader can pick them up again accurately.
11.167 - // 6. Generate the edited class file bytes.
11.168 - //
11.169 - // Potential limitations:
11.170 - // * The class won't be truly anonymous, and may interfere with others.
11.171 - // * Flattened class constants might not work, because of loader issues.
11.172 - // * Pseudo-string constants will not flatten down to real strings.
11.173 - // * Method handles will (of course) fail to flatten to linkage strings.
11.174 - if (true) throw new UnsupportedOperationException("NYI");
11.175 - Object[] cpArray;
11.176 - try {
11.177 - cpArray = classPatch.getOriginalCP();
11.178 - } catch (InvalidConstantPoolFormatException ex) {
11.179 - throw new RuntimeException(ex);
11.180 - }
11.181 - int thisClassIndex = classPatch.getParser().getThisClassIndex();
11.182 - String thisClassName = (String) cpArray[thisClassIndex];
11.183 - synchronized (AnonymousClassLoader.class) {
11.184 - thisClassName = thisClassName+"\\|"+(++fakeNameCounter);
11.185 - }
11.186 - classPatch.putUTF8(thisClassIndex, thisClassName);
11.187 - byte[] classFile = null;
11.188 - return unsafe.defineClass(null, classFile, 0, classFile.length,
11.189 - hostClass.getClassLoader(),
11.190 - hostClass.getProtectionDomain());
11.191 - }
11.192 - private static int fakeNameCounter = 99999;
11.193 -
11.194 - // ignore two warnings on this line:
11.195 - private static sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
11.196 - // preceding line requires that this class be on the boot class path
11.197 -
11.198 - static private final Method defineAnonymousClass;
11.199 - static {
11.200 - Method dac = null;
11.201 - Class<? extends sun.misc.Unsafe> unsafeClass = unsafe.getClass();
11.202 - try {
11.203 - dac = unsafeClass.getMethod("defineAnonymousClass",
11.204 - Class.class,
11.205 - byte[].class,
11.206 - Object[].class);
11.207 - } catch (Exception ee) {
11.208 - dac = null;
11.209 - }
11.210 - defineAnonymousClass = dac;
11.211 - }
11.212 -
11.213 - private static void noJVMSupport() {
11.214 - throw new UnsupportedOperationException("no JVM support for anonymous classes");
11.215 - }
11.216 -
11.217 -
11.218 - private static native Class<?> loadClassInternal(Class<?> hostClass,
11.219 - byte[] classFile,
11.220 - Object[] patchArray);
11.221 -
11.222 - public static byte[] readClassFile(Class<?> templateClass) throws IOException {
11.223 - String templateName = templateClass.getName();
11.224 - int lastDot = templateName.lastIndexOf('.');
11.225 - java.net.URL url = templateClass.getResource(templateName.substring(lastDot+1)+".class");
11.226 - java.net.URLConnection connection = url.openConnection();
11.227 - int contentLength = connection.getContentLength();
11.228 - if (contentLength < 0)
11.229 - throw new IOException("invalid content length "+contentLength);
11.230 -
11.231 - return IOUtils.readFully(connection.getInputStream(), contentLength, true);
11.232 - }
11.233 -}
12.1 --- a/rt/emul/compact/src/main/java/sun/invoke/anon/ConstantPoolParser.java Sun Aug 10 05:56:32 2014 +0200
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,368 +0,0 @@
12.4 -/*
12.5 - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
12.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
12.7 - *
12.8 - * This code is free software; you can redistribute it and/or modify it
12.9 - * under the terms of the GNU General Public License version 2 only, as
12.10 - * published by the Free Software Foundation. Oracle designates this
12.11 - * particular file as subject to the "Classpath" exception as provided
12.12 - * by Oracle in the LICENSE file that accompanied this code.
12.13 - *
12.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
12.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12.17 - * version 2 for more details (a copy is included in the LICENSE file that
12.18 - * accompanied this code).
12.19 - *
12.20 - * You should have received a copy of the GNU General Public License version
12.21 - * 2 along with this work; if not, write to the Free Software Foundation,
12.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
12.23 - *
12.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
12.25 - * or visit www.oracle.com if you need additional information or have any
12.26 - * questions.
12.27 - */
12.28 -
12.29 -package sun.invoke.anon;
12.30 -
12.31 -import java.io.IOException;
12.32 -import java.io.OutputStream;
12.33 -import java.nio.BufferUnderflowException;
12.34 -import java.nio.ByteBuffer;
12.35 -
12.36 -import static sun.invoke.anon.ConstantPoolVisitor.*;
12.37 -
12.38 -/** A constant pool parser.
12.39 - */
12.40 -public class ConstantPoolParser {
12.41 - final byte[] classFile;
12.42 - final byte[] tags;
12.43 - final char[] firstHeader; // maghi, maglo, minor, major, cplen
12.44 -
12.45 - // these are filled in on first parse:
12.46 - int endOffset;
12.47 - char[] secondHeader; // flags, this_class, super_class, intlen
12.48 -
12.49 - // used to decode UTF8 array
12.50 - private char[] charArray = new char[80];
12.51 -
12.52 - /** Creates a constant pool parser.
12.53 - * @param classFile an array of bytes containing a class.
12.54 - * @throws InvalidConstantPoolFormatException if the header of the class has errors.
12.55 - */
12.56 - public ConstantPoolParser(byte[] classFile) throws InvalidConstantPoolFormatException {
12.57 - this.classFile = classFile;
12.58 - this.firstHeader = parseHeader(classFile);
12.59 - this.tags = new byte[firstHeader[4]];
12.60 - }
12.61 -
12.62 - /** Create a constant pool parser by loading the bytecodes of the
12.63 - * class taken as argument.
12.64 - *
12.65 - * @param templateClass the class to parse.
12.66 - *
12.67 - * @throws IOException raised if an I/O occurs when loading
12.68 - * the bytecode of the template class.
12.69 - * @throws InvalidConstantPoolFormatException if the header of the class has errors.
12.70 - *
12.71 - * @see #ConstantPoolParser(byte[])
12.72 - * @see AnonymousClassLoader#readClassFile(Class)
12.73 - */
12.74 - public ConstantPoolParser(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
12.75 - this(AnonymousClassLoader.readClassFile(templateClass));
12.76 - }
12.77 -
12.78 - /** Creates an empty patch to patch the class file
12.79 - * used by the current parser.
12.80 - * @return a new class patch.
12.81 - */
12.82 - public ConstantPoolPatch createPatch() {
12.83 - return new ConstantPoolPatch(this);
12.84 - }
12.85 -
12.86 - /** Report the tag of the indicated CP entry.
12.87 - * @param index
12.88 - * @return one of {@link ConstantPoolVisitor#CONSTANT_Utf8}, etc.
12.89 - */
12.90 - public byte getTag(int index) {
12.91 - getEndOffset(); // trigger an exception if we haven't parsed yet
12.92 - return tags[index];
12.93 - }
12.94 -
12.95 - /** Report the length of the constant pool. */
12.96 - public int getLength() {
12.97 - return firstHeader[4];
12.98 - }
12.99 -
12.100 - /** Report the offset, within the class file, of the start of the constant pool. */
12.101 - public int getStartOffset() {
12.102 - return firstHeader.length * 2;
12.103 - }
12.104 -
12.105 - /** Report the offset, within the class file, of the end of the constant pool. */
12.106 - public int getEndOffset() {
12.107 - if (endOffset == 0)
12.108 - throw new IllegalStateException("class file has not yet been parsed");
12.109 - return endOffset;
12.110 - }
12.111 -
12.112 - /** Report the CP index of this class's own name. */
12.113 - public int getThisClassIndex() {
12.114 - getEndOffset(); // provoke exception if not yet parsed
12.115 - return secondHeader[1];
12.116 - }
12.117 -
12.118 - /** Report the total size of the class file. */
12.119 - public int getTailLength() {
12.120 - return classFile.length - getEndOffset();
12.121 - }
12.122 -
12.123 - /** Write the head (header plus constant pool)
12.124 - * of the class file to the indicated stream.
12.125 - */
12.126 - public void writeHead(OutputStream out) throws IOException {
12.127 - out.write(classFile, 0, getEndOffset());
12.128 - }
12.129 -
12.130 - /** Write the head (header plus constant pool)
12.131 - * of the class file to the indicated stream,
12.132 - * incorporating the non-null entries of the given array
12.133 - * as patches.
12.134 - */
12.135 - void writePatchedHead(OutputStream out, Object[] patchArray) {
12.136 - // this will be useful to partially emulate the class loader on old JVMs
12.137 - throw new UnsupportedOperationException("Not yet implemented");
12.138 - }
12.139 -
12.140 - /** Write the tail (everything after the constant pool)
12.141 - * of the class file to the indicated stream.
12.142 - */
12.143 - public void writeTail(OutputStream out) throws IOException {
12.144 - out.write(classFile, getEndOffset(), getTailLength());
12.145 - }
12.146 -
12.147 - private static char[] parseHeader(byte[] classFile) throws InvalidConstantPoolFormatException {
12.148 - char[] result = new char[5];
12.149 - ByteBuffer buffer = ByteBuffer.wrap(classFile);
12.150 - for (int i = 0; i < result.length; i++)
12.151 - result[i] = (char) getUnsignedShort(buffer);
12.152 - int magic = result[0] << 16 | result[1] << 0;
12.153 - if (magic != 0xCAFEBABE)
12.154 - throw new InvalidConstantPoolFormatException("invalid magic number "+magic);
12.155 - // skip major, minor version
12.156 - int len = result[4];
12.157 - if (len < 1)
12.158 - throw new InvalidConstantPoolFormatException("constant pool length < 1");
12.159 - return result;
12.160 - }
12.161 -
12.162 - /** Parse the constant pool of the class
12.163 - * calling a method visit* each time a constant pool entry is parsed.
12.164 - *
12.165 - * The order of the calls to visit* is not guaranteed to be the same
12.166 - * than the order of the constant pool entry in the bytecode array.
12.167 - *
12.168 - * @param visitor
12.169 - * @throws InvalidConstantPoolFormatException
12.170 - */
12.171 - public void parse(ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
12.172 - ByteBuffer buffer = ByteBuffer.wrap(classFile);
12.173 - buffer.position(getStartOffset()); //skip header
12.174 -
12.175 - Object[] values = new Object[getLength()];
12.176 - try {
12.177 - parseConstantPool(buffer, values, visitor);
12.178 - } catch(BufferUnderflowException e) {
12.179 - throw new InvalidConstantPoolFormatException(e);
12.180 - }
12.181 - if (endOffset == 0) {
12.182 - endOffset = buffer.position();
12.183 - secondHeader = new char[4];
12.184 - for (int i = 0; i < secondHeader.length; i++) {
12.185 - secondHeader[i] = (char) getUnsignedShort(buffer);
12.186 - }
12.187 - }
12.188 - resolveConstantPool(values, visitor);
12.189 - }
12.190 -
12.191 - private char[] getCharArray(int utfLength) {
12.192 - if (utfLength <= charArray.length)
12.193 - return charArray;
12.194 - return charArray = new char[utfLength];
12.195 - }
12.196 -
12.197 - private void parseConstantPool(ByteBuffer buffer, Object[] values, ConstantPoolVisitor visitor) throws InvalidConstantPoolFormatException {
12.198 - for (int i = 1; i < tags.length; ) {
12.199 - byte tag = (byte) getUnsignedByte(buffer);
12.200 - assert(tags[i] == 0 || tags[i] == tag);
12.201 - tags[i] = tag;
12.202 - switch (tag) {
12.203 - case CONSTANT_Utf8:
12.204 - int utfLen = getUnsignedShort(buffer);
12.205 - String value = getUTF8(buffer, utfLen, getCharArray(utfLen));
12.206 - visitor.visitUTF8(i, CONSTANT_Utf8, value);
12.207 - tags[i] = tag;
12.208 - values[i++] = value;
12.209 - break;
12.210 - case CONSTANT_Integer:
12.211 - visitor.visitConstantValue(i, tag, buffer.getInt());
12.212 - i++;
12.213 - break;
12.214 - case CONSTANT_Float:
12.215 - visitor.visitConstantValue(i, tag, buffer.getFloat());
12.216 - i++;
12.217 - break;
12.218 - case CONSTANT_Long:
12.219 - visitor.visitConstantValue(i, tag, buffer.getLong());
12.220 - i+=2;
12.221 - break;
12.222 - case CONSTANT_Double:
12.223 - visitor.visitConstantValue(i, tag, buffer.getDouble());
12.224 - i+=2;
12.225 - break;
12.226 -
12.227 - case CONSTANT_Class: // fall through:
12.228 - case CONSTANT_String:
12.229 - tags[i] = tag;
12.230 - values[i++] = new int[] { getUnsignedShort(buffer) };
12.231 - break;
12.232 -
12.233 - case CONSTANT_Fieldref: // fall through:
12.234 - case CONSTANT_Methodref: // fall through:
12.235 - case CONSTANT_InterfaceMethodref: // fall through:
12.236 - case CONSTANT_NameAndType:
12.237 - tags[i] = tag;
12.238 - values[i++] = new int[] { getUnsignedShort(buffer), getUnsignedShort(buffer) };
12.239 - break;
12.240 - default:
12.241 - throw new AssertionError("invalid constant "+tag);
12.242 - }
12.243 - }
12.244 - }
12.245 -
12.246 - private void resolveConstantPool(Object[] values, ConstantPoolVisitor visitor) {
12.247 - // clean out the int[] values, which are temporary
12.248 - for (int beg = 1, end = values.length-1, beg2, end2;
12.249 - beg <= end;
12.250 - beg = beg2, end = end2) {
12.251 - beg2 = end; end2 = beg-1;
12.252 - //System.out.println("CP resolve pass: "+beg+".."+end);
12.253 - for (int i = beg; i <= end; i++) {
12.254 - Object value = values[i];
12.255 - if (!(value instanceof int[]))
12.256 - continue;
12.257 - int[] array = (int[]) value;
12.258 - byte tag = tags[i];
12.259 - switch (tag) {
12.260 - case CONSTANT_String:
12.261 - String stringBody = (String) values[array[0]];
12.262 - visitor.visitConstantString(i, tag, stringBody, array[0]);
12.263 - values[i] = null;
12.264 - break;
12.265 - case CONSTANT_Class: {
12.266 - String className = (String) values[array[0]];
12.267 - // use the external form favored by Class.forName:
12.268 - className = className.replace('/', '.');
12.269 - visitor.visitConstantString(i, tag, className, array[0]);
12.270 - values[i] = className;
12.271 - break;
12.272 - }
12.273 - case CONSTANT_NameAndType: {
12.274 - String memberName = (String) values[array[0]];
12.275 - String signature = (String) values[array[1]];
12.276 - visitor.visitDescriptor(i, tag, memberName, signature,
12.277 - array[0], array[1]);
12.278 - values[i] = new String[] {memberName, signature};
12.279 - break;
12.280 - }
12.281 - case CONSTANT_Fieldref: // fall through:
12.282 - case CONSTANT_Methodref: // fall through:
12.283 - case CONSTANT_InterfaceMethodref: {
12.284 - Object className = values[array[0]];
12.285 - Object nameAndType = values[array[1]];
12.286 - if (!(className instanceof String) ||
12.287 - !(nameAndType instanceof String[])) {
12.288 - // one more pass is needed
12.289 - if (beg2 > i) beg2 = i;
12.290 - if (end2 < i) end2 = i;
12.291 - continue;
12.292 - }
12.293 - String[] nameAndTypeArray = (String[]) nameAndType;
12.294 - visitor.visitMemberRef(i, tag,
12.295 - (String)className,
12.296 - nameAndTypeArray[0],
12.297 - nameAndTypeArray[1],
12.298 - array[0], array[1]);
12.299 - values[i] = null;
12.300 - }
12.301 - break;
12.302 - default:
12.303 - continue;
12.304 - }
12.305 - }
12.306 - }
12.307 - }
12.308 -
12.309 - private static int getUnsignedByte(ByteBuffer buffer) {
12.310 - return buffer.get() & 0xFF;
12.311 - }
12.312 -
12.313 - private static int getUnsignedShort(ByteBuffer buffer) {
12.314 - int b1 = getUnsignedByte(buffer);
12.315 - int b2 = getUnsignedByte(buffer);
12.316 - return (b1 << 8) + (b2 << 0);
12.317 - }
12.318 -
12.319 - private static String getUTF8(ByteBuffer buffer, int utfLen, char[] charArray) throws InvalidConstantPoolFormatException {
12.320 - int utfLimit = buffer.position() + utfLen;
12.321 - int index = 0;
12.322 - while (buffer.position() < utfLimit) {
12.323 - int c = buffer.get() & 0xff;
12.324 - if (c > 127) {
12.325 - buffer.position(buffer.position() - 1);
12.326 - return getUTF8Extended(buffer, utfLimit, charArray, index);
12.327 - }
12.328 - charArray[index++] = (char)c;
12.329 - }
12.330 - return new String(charArray, 0, index);
12.331 - }
12.332 -
12.333 - private static String getUTF8Extended(ByteBuffer buffer, int utfLimit, char[] charArray, int index) throws InvalidConstantPoolFormatException {
12.334 - int c, c2, c3;
12.335 - while (buffer.position() < utfLimit) {
12.336 - c = buffer.get() & 0xff;
12.337 - switch (c >> 4) {
12.338 - case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
12.339 - /* 0xxxxxxx*/
12.340 - charArray[index++] = (char)c;
12.341 - break;
12.342 - case 12: case 13:
12.343 - /* 110x xxxx 10xx xxxx*/
12.344 - c2 = buffer.get();
12.345 - if ((c2 & 0xC0) != 0x80)
12.346 - throw new InvalidConstantPoolFormatException(
12.347 - "malformed input around byte " + buffer.position());
12.348 - charArray[index++] = (char)(((c & 0x1F) << 6) |
12.349 - (c2 & 0x3F));
12.350 - break;
12.351 - case 14:
12.352 - /* 1110 xxxx 10xx xxxx 10xx xxxx */
12.353 - c2 = buffer.get();
12.354 - c3 = buffer.get();
12.355 - if (((c2 & 0xC0) != 0x80) || ((c3 & 0xC0) != 0x80))
12.356 - throw new InvalidConstantPoolFormatException(
12.357 - "malformed input around byte " + (buffer.position()));
12.358 - charArray[index++] = (char)(((c & 0x0F) << 12) |
12.359 - ((c2 & 0x3F) << 6) |
12.360 - ((c3 & 0x3F) << 0));
12.361 - break;
12.362 - default:
12.363 - /* 10xx xxxx, 1111 xxxx */
12.364 - throw new InvalidConstantPoolFormatException(
12.365 - "malformed input around byte " + buffer.position());
12.366 - }
12.367 - }
12.368 - // The number of chars produced may be less than utflen
12.369 - return new String(charArray, 0, index);
12.370 - }
12.371 -}
13.1 --- a/rt/emul/compact/src/main/java/sun/invoke/anon/ConstantPoolPatch.java Sun Aug 10 05:56:32 2014 +0200
13.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
13.3 @@ -1,503 +0,0 @@
13.4 -/*
13.5 - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
13.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
13.7 - *
13.8 - * This code is free software; you can redistribute it and/or modify it
13.9 - * under the terms of the GNU General Public License version 2 only, as
13.10 - * published by the Free Software Foundation. Oracle designates this
13.11 - * particular file as subject to the "Classpath" exception as provided
13.12 - * by Oracle in the LICENSE file that accompanied this code.
13.13 - *
13.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
13.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13.17 - * version 2 for more details (a copy is included in the LICENSE file that
13.18 - * accompanied this code).
13.19 - *
13.20 - * You should have received a copy of the GNU General Public License version
13.21 - * 2 along with this work; if not, write to the Free Software Foundation,
13.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
13.23 - *
13.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
13.25 - * or visit www.oracle.com if you need additional information or have any
13.26 - * questions.
13.27 - */
13.28 -
13.29 -package sun.invoke.anon;
13.30 -
13.31 -import java.io.IOException;
13.32 -import java.io.OutputStream;
13.33 -import java.util.Arrays;
13.34 -import java.util.HashSet;
13.35 -import java.util.IdentityHashMap;
13.36 -import java.util.Map;
13.37 -
13.38 -import static sun.invoke.anon.ConstantPoolVisitor.*;
13.39 -
13.40 -/** A class and its patched constant pool.
13.41 - *
13.42 - * This class allow to modify (patch) a constant pool
13.43 - * by changing the value of its entry.
13.44 - * Entry are referenced using index that can be get
13.45 - * by parsing the constant pool using
13.46 - * {@link ConstantPoolParser#parse(ConstantPoolVisitor)}.
13.47 - *
13.48 - * @see ConstantPoolVisitor
13.49 - * @see ConstantPoolParser#createPatch()
13.50 - */
13.51 -public class ConstantPoolPatch {
13.52 - final ConstantPoolParser outer;
13.53 - final Object[] patchArray;
13.54 -
13.55 - ConstantPoolPatch(ConstantPoolParser outer) {
13.56 - this.outer = outer;
13.57 - this.patchArray = new Object[outer.getLength()];
13.58 - }
13.59 -
13.60 - /** Create a {@link ConstantPoolParser} and
13.61 - * a {@link ConstantPoolPatch} in one step.
13.62 - * Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}.
13.63 - *
13.64 - * @param classFile an array of bytes containing a class.
13.65 - * @see #ConstantPoolParser(Class)
13.66 - */
13.67 - public ConstantPoolPatch(byte[] classFile) throws InvalidConstantPoolFormatException {
13.68 - this(new ConstantPoolParser(classFile));
13.69 - }
13.70 -
13.71 - /** Create a {@link ConstantPoolParser} and
13.72 - * a {@link ConstantPoolPatch} in one step.
13.73 - * Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}.
13.74 - *
13.75 - * @param templateClass the class to parse.
13.76 - * @see #ConstantPoolParser(Class)
13.77 - */
13.78 - public ConstantPoolPatch(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
13.79 - this(new ConstantPoolParser(templateClass));
13.80 - }
13.81 -
13.82 -
13.83 - /** Creates a patch from an existing patch.
13.84 - * All changes are copied from that patch.
13.85 - * @param patch a patch
13.86 - *
13.87 - * @see ConstantPoolParser#createPatch()
13.88 - */
13.89 - public ConstantPoolPatch(ConstantPoolPatch patch) {
13.90 - outer = patch.outer;
13.91 - patchArray = patch.patchArray.clone();
13.92 - }
13.93 -
13.94 - /** Which parser built this patch? */
13.95 - public ConstantPoolParser getParser() {
13.96 - return outer;
13.97 - }
13.98 -
13.99 - /** Report the tag at the given index in the constant pool. */
13.100 - public byte getTag(int index) {
13.101 - return outer.getTag(index);
13.102 - }
13.103 -
13.104 - /** Report the current patch at the given index of the constant pool.
13.105 - * Null means no patch will be made.
13.106 - * To observe the unpatched entry at the given index, use
13.107 - * {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)}
13.108 - */
13.109 - public Object getPatch(int index) {
13.110 - Object value = patchArray[index];
13.111 - if (value == null) return null;
13.112 - switch (getTag(index)) {
13.113 - case CONSTANT_Fieldref:
13.114 - case CONSTANT_Methodref:
13.115 - case CONSTANT_InterfaceMethodref:
13.116 - if (value instanceof String)
13.117 - value = stripSemis(2, (String) value);
13.118 - break;
13.119 - case CONSTANT_NameAndType:
13.120 - if (value instanceof String)
13.121 - value = stripSemis(1, (String) value);
13.122 - break;
13.123 - }
13.124 - return value;
13.125 - }
13.126 -
13.127 - /** Clear all patches. */
13.128 - public void clear() {
13.129 - Arrays.fill(patchArray, null);
13.130 - }
13.131 -
13.132 - /** Clear one patch. */
13.133 - public void clear(int index) {
13.134 - patchArray[index] = null;
13.135 - }
13.136 -
13.137 - /** Produce the patches as an array. */
13.138 - public Object[] getPatches() {
13.139 - return patchArray.clone();
13.140 - }
13.141 -
13.142 - /** Produce the original constant pool as an array. */
13.143 - public Object[] getOriginalCP() throws InvalidConstantPoolFormatException {
13.144 - return getOriginalCP(0, patchArray.length, -1);
13.145 - }
13.146 -
13.147 - /** Walk the constant pool, applying patches using the given map.
13.148 - *
13.149 - * @param utf8Map Utf8 strings to modify, if encountered
13.150 - * @param classMap Classes (or their names) to modify, if encountered
13.151 - * @param valueMap Constant values to modify, if encountered
13.152 - * @param deleteUsedEntries if true, delete map entries that are used
13.153 - */
13.154 - public void putPatches(final Map<String,String> utf8Map,
13.155 - final Map<String,Object> classMap,
13.156 - final Map<Object,Object> valueMap,
13.157 - boolean deleteUsedEntries) throws InvalidConstantPoolFormatException {
13.158 - final HashSet<String> usedUtf8Keys;
13.159 - final HashSet<String> usedClassKeys;
13.160 - final HashSet<Object> usedValueKeys;
13.161 - if (deleteUsedEntries) {
13.162 - usedUtf8Keys = (utf8Map == null) ? null : new HashSet<String>();
13.163 - usedClassKeys = (classMap == null) ? null : new HashSet<String>();
13.164 - usedValueKeys = (valueMap == null) ? null : new HashSet<Object>();
13.165 - } else {
13.166 - usedUtf8Keys = null;
13.167 - usedClassKeys = null;
13.168 - usedValueKeys = null;
13.169 - }
13.170 -
13.171 - outer.parse(new ConstantPoolVisitor() {
13.172 -
13.173 - @Override
13.174 - public void visitUTF8(int index, byte tag, String utf8) {
13.175 - putUTF8(index, utf8Map.get(utf8));
13.176 - if (usedUtf8Keys != null) usedUtf8Keys.add(utf8);
13.177 - }
13.178 -
13.179 - @Override
13.180 - public void visitConstantValue(int index, byte tag, Object value) {
13.181 - putConstantValue(index, tag, valueMap.get(value));
13.182 - if (usedValueKeys != null) usedValueKeys.add(value);
13.183 - }
13.184 -
13.185 - @Override
13.186 - public void visitConstantString(int index, byte tag, String name, int nameIndex) {
13.187 - if (tag == CONSTANT_Class) {
13.188 - putConstantValue(index, tag, classMap.get(name));
13.189 - if (usedClassKeys != null) usedClassKeys.add(name);
13.190 - } else {
13.191 - assert(tag == CONSTANT_String);
13.192 - visitConstantValue(index, tag, name);
13.193 - }
13.194 - }
13.195 - });
13.196 - if (usedUtf8Keys != null) utf8Map.keySet().removeAll(usedUtf8Keys);
13.197 - if (usedClassKeys != null) classMap.keySet().removeAll(usedClassKeys);
13.198 - if (usedValueKeys != null) valueMap.keySet().removeAll(usedValueKeys);
13.199 - }
13.200 -
13.201 - Object[] getOriginalCP(final int startIndex,
13.202 - final int endIndex,
13.203 - final int tagMask) throws InvalidConstantPoolFormatException {
13.204 - final Object[] cpArray = new Object[endIndex - startIndex];
13.205 - outer.parse(new ConstantPoolVisitor() {
13.206 -
13.207 - void show(int index, byte tag, Object value) {
13.208 - if (index < startIndex || index >= endIndex) return;
13.209 - if (((1 << tag) & tagMask) == 0) return;
13.210 - cpArray[index - startIndex] = value;
13.211 - }
13.212 -
13.213 - @Override
13.214 - public void visitUTF8(int index, byte tag, String utf8) {
13.215 - show(index, tag, utf8);
13.216 - }
13.217 -
13.218 - @Override
13.219 - public void visitConstantValue(int index, byte tag, Object value) {
13.220 - assert(tag != CONSTANT_String);
13.221 - show(index, tag, value);
13.222 - }
13.223 -
13.224 - @Override
13.225 - public void visitConstantString(int index, byte tag,
13.226 - String value, int j) {
13.227 - show(index, tag, value);
13.228 - }
13.229 -
13.230 - @Override
13.231 - public void visitMemberRef(int index, byte tag,
13.232 - String className, String memberName,
13.233 - String signature,
13.234 - int j, int k) {
13.235 - show(index, tag, new String[]{ className, memberName, signature });
13.236 - }
13.237 -
13.238 - @Override
13.239 - public void visitDescriptor(int index, byte tag,
13.240 - String memberName, String signature,
13.241 - int j, int k) {
13.242 - show(index, tag, new String[]{ memberName, signature });
13.243 - }
13.244 - });
13.245 - return cpArray;
13.246 - }
13.247 -
13.248 - /** Write the head (header plus constant pool)
13.249 - * of the patched class file to the indicated stream.
13.250 - */
13.251 - void writeHead(OutputStream out) throws IOException {
13.252 - outer.writePatchedHead(out, patchArray);
13.253 - }
13.254 -
13.255 - /** Write the tail (everything after the constant pool)
13.256 - * of the patched class file to the indicated stream.
13.257 - */
13.258 - void writeTail(OutputStream out) throws IOException {
13.259 - outer.writeTail(out);
13.260 - }
13.261 -
13.262 - private void checkConstantTag(byte tag, Object value) {
13.263 - if (value == null)
13.264 - throw new IllegalArgumentException(
13.265 - "invalid null constant value");
13.266 - if (classForTag(tag) != value.getClass())
13.267 - throw new IllegalArgumentException(
13.268 - "invalid constant value"
13.269 - + (tag == CONSTANT_None ? ""
13.270 - : " for tag "+tagName(tag))
13.271 - + " of class "+value.getClass());
13.272 - }
13.273 -
13.274 - private void checkTag(int index, byte putTag) {
13.275 - byte tag = outer.tags[index];
13.276 - if (tag != putTag)
13.277 - throw new IllegalArgumentException(
13.278 - "invalid put operation"
13.279 - + " for " + tagName(putTag)
13.280 - + " at index " + index + " found " + tagName(tag));
13.281 - }
13.282 -
13.283 - private void checkTagMask(int index, int tagBitMask) {
13.284 - byte tag = outer.tags[index];
13.285 - int tagBit = ((tag & 0x1F) == tag) ? (1 << tag) : 0;
13.286 - if ((tagBit & tagBitMask) == 0)
13.287 - throw new IllegalArgumentException(
13.288 - "invalid put operation"
13.289 - + " at index " + index + " found " + tagName(tag));
13.290 - }
13.291 -
13.292 - private static void checkMemberName(String memberName) {
13.293 - if (memberName.indexOf(';') >= 0)
13.294 - throw new IllegalArgumentException("memberName " + memberName + " contains a ';'");
13.295 - }
13.296 -
13.297 - /** Set the entry of the constant pool indexed by index to
13.298 - * a new string.
13.299 - *
13.300 - * @param index an index to a constant pool entry containing a
13.301 - * {@link ConstantPoolVisitor#CONSTANT_Utf8} value.
13.302 - * @param utf8 a string
13.303 - *
13.304 - * @see ConstantPoolVisitor#visitUTF8(int, byte, String)
13.305 - */
13.306 - public void putUTF8(int index, String utf8) {
13.307 - if (utf8 == null) { clear(index); return; }
13.308 - checkTag(index, CONSTANT_Utf8);
13.309 - patchArray[index] = utf8;
13.310 - }
13.311 -
13.312 - /** Set the entry of the constant pool indexed by index to
13.313 - * a new value, depending on its dynamic type.
13.314 - *
13.315 - * @param index an index to a constant pool entry containing a
13.316 - * one of the following structures:
13.317 - * {@link ConstantPoolVisitor#CONSTANT_Integer},
13.318 - * {@link ConstantPoolVisitor#CONSTANT_Float},
13.319 - * {@link ConstantPoolVisitor#CONSTANT_Long},
13.320 - * {@link ConstantPoolVisitor#CONSTANT_Double},
13.321 - * {@link ConstantPoolVisitor#CONSTANT_String}, or
13.322 - * {@link ConstantPoolVisitor#CONSTANT_Class}
13.323 - * @param value a boxed int, float, long or double; or a string or class object
13.324 - * @throws IllegalArgumentException if the type of the constant does not
13.325 - * match the constant pool entry type,
13.326 - * as reported by {@link #getTag(int)}
13.327 - *
13.328 - * @see #putConstantValue(int, byte, Object)
13.329 - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
13.330 - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
13.331 - */
13.332 - public void putConstantValue(int index, Object value) {
13.333 - if (value == null) { clear(index); return; }
13.334 - byte tag = tagForConstant(value.getClass());
13.335 - checkConstantTag(tag, value);
13.336 - checkTag(index, tag);
13.337 - patchArray[index] = value;
13.338 - }
13.339 -
13.340 - /** Set the entry of the constant pool indexed by index to
13.341 - * a new value.
13.342 - *
13.343 - * @param index an index to a constant pool entry matching the given tag
13.344 - * @param tag one of the following values:
13.345 - * {@link ConstantPoolVisitor#CONSTANT_Integer},
13.346 - * {@link ConstantPoolVisitor#CONSTANT_Float},
13.347 - * {@link ConstantPoolVisitor#CONSTANT_Long},
13.348 - * {@link ConstantPoolVisitor#CONSTANT_Double},
13.349 - * {@link ConstantPoolVisitor#CONSTANT_String}, or
13.350 - * {@link ConstantPoolVisitor#CONSTANT_Class}
13.351 - * @param value a boxed number, string, or class object
13.352 - * @throws IllegalArgumentException if the type of the constant does not
13.353 - * match the constant pool entry type, or if a class name contains
13.354 - * '/' or ';'
13.355 - *
13.356 - * @see #putConstantValue(int, Object)
13.357 - * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
13.358 - * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
13.359 - */
13.360 - public void putConstantValue(int index, byte tag, Object value) {
13.361 - if (value == null) { clear(index); return; }
13.362 - checkTag(index, tag);
13.363 - if (tag == CONSTANT_Class && value instanceof String) {
13.364 - checkClassName((String) value);
13.365 - } else if (tag == CONSTANT_String) {
13.366 - // the JVM accepts any object as a patch for a string
13.367 - } else {
13.368 - // make sure the incoming value is the right type
13.369 - checkConstantTag(tag, value);
13.370 - }
13.371 - checkTag(index, tag);
13.372 - patchArray[index] = value;
13.373 - }
13.374 -
13.375 - /** Set the entry of the constant pool indexed by index to
13.376 - * a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
13.377 - *
13.378 - * @param index an index to a constant pool entry containing a
13.379 - * {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
13.380 - * @param memberName a memberName
13.381 - * @param signature a signature
13.382 - * @throws IllegalArgumentException if memberName contains the character ';'
13.383 - *
13.384 - * @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int)
13.385 - */
13.386 - public void putDescriptor(int index, String memberName, String signature) {
13.387 - checkTag(index, CONSTANT_NameAndType);
13.388 - checkMemberName(memberName);
13.389 - patchArray[index] = addSemis(memberName, signature);
13.390 - }
13.391 -
13.392 - /** Set the entry of the constant pool indexed by index to
13.393 - * a new {@link ConstantPoolVisitor#CONSTANT_Fieldref},
13.394 - * {@link ConstantPoolVisitor#CONSTANT_Methodref}, or
13.395 - * {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value.
13.396 - *
13.397 - * @param index an index to a constant pool entry containing a member reference
13.398 - * @param className a class name
13.399 - * @param memberName a field or method name
13.400 - * @param signature a field or method signature
13.401 - * @throws IllegalArgumentException if memberName contains the character ';'
13.402 - * or signature is not a correct signature
13.403 - *
13.404 - * @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int)
13.405 - */
13.406 - public void putMemberRef(int index, byte tag,
13.407 - String className, String memberName, String signature) {
13.408 - checkTagMask(tag, CONSTANT_MemberRef_MASK);
13.409 - checkTag(index, tag);
13.410 - checkClassName(className);
13.411 - checkMemberName(memberName);
13.412 - if (signature.startsWith("(") == (tag == CONSTANT_Fieldref))
13.413 - throw new IllegalArgumentException("bad signature: "+signature);
13.414 - patchArray[index] = addSemis(className, memberName, signature);
13.415 - }
13.416 -
13.417 - static private final int CONSTANT_MemberRef_MASK =
13.418 - CONSTANT_Fieldref
13.419 - | CONSTANT_Methodref
13.420 - | CONSTANT_InterfaceMethodref;
13.421 -
13.422 - private static final Map<Class<?>, Byte> CONSTANT_VALUE_CLASS_TAG
13.423 - = new IdentityHashMap<Class<?>, Byte>();
13.424 - private static final Class<?>[] CONSTANT_VALUE_CLASS = new Class<?>[16];
13.425 - static {
13.426 - Object[][] values = {
13.427 - {Integer.class, CONSTANT_Integer},
13.428 - {Long.class, CONSTANT_Long},
13.429 - {Float.class, CONSTANT_Float},
13.430 - {Double.class, CONSTANT_Double},
13.431 - {String.class, CONSTANT_String},
13.432 - {Class.class, CONSTANT_Class}
13.433 - };
13.434 - for (Object[] value : values) {
13.435 - Class<?> cls = (Class<?>)value[0];
13.436 - Byte tag = (Byte) value[1];
13.437 - CONSTANT_VALUE_CLASS_TAG.put(cls, tag);
13.438 - CONSTANT_VALUE_CLASS[(byte)tag] = cls;
13.439 - }
13.440 - }
13.441 -
13.442 - static Class<?> classForTag(byte tag) {
13.443 - if ((tag & 0xFF) >= CONSTANT_VALUE_CLASS.length)
13.444 - return null;
13.445 - return CONSTANT_VALUE_CLASS[tag];
13.446 - }
13.447 -
13.448 - static byte tagForConstant(Class<?> cls) {
13.449 - Byte tag = CONSTANT_VALUE_CLASS_TAG.get(cls);
13.450 - return (tag == null) ? CONSTANT_None : (byte)tag;
13.451 - }
13.452 -
13.453 - private static void checkClassName(String className) {
13.454 - if (className.indexOf('/') >= 0 || className.indexOf(';') >= 0)
13.455 - throw new IllegalArgumentException("invalid class name " + className);
13.456 - }
13.457 -
13.458 - static String addSemis(String name, String... names) {
13.459 - StringBuilder buf = new StringBuilder(name.length() * 5);
13.460 - buf.append(name);
13.461 - for (String name2 : names) {
13.462 - buf.append(';').append(name2);
13.463 - }
13.464 - String res = buf.toString();
13.465 - assert(stripSemis(names.length, res)[0].equals(name));
13.466 - assert(stripSemis(names.length, res)[1].equals(names[0]));
13.467 - assert(names.length == 1 ||
13.468 - stripSemis(names.length, res)[2].equals(names[1]));
13.469 - return res;
13.470 - }
13.471 -
13.472 - static String[] stripSemis(int count, String string) {
13.473 - String[] res = new String[count+1];
13.474 - int pos = 0;
13.475 - for (int i = 0; i < count; i++) {
13.476 - int pos2 = string.indexOf(';', pos);
13.477 - if (pos2 < 0) pos2 = string.length(); // yuck
13.478 - res[i] = string.substring(pos, pos2);
13.479 - pos = pos2;
13.480 - }
13.481 - res[count] = string.substring(pos);
13.482 - return res;
13.483 - }
13.484 -
13.485 - public String toString() {
13.486 - StringBuilder buf = new StringBuilder(this.getClass().getName());
13.487 - buf.append("{");
13.488 - Object[] origCP = null;
13.489 - for (int i = 0; i < patchArray.length; i++) {
13.490 - if (patchArray[i] == null) continue;
13.491 - if (origCP != null) {
13.492 - buf.append(", ");
13.493 - } else {
13.494 - try {
13.495 - origCP = getOriginalCP();
13.496 - } catch (InvalidConstantPoolFormatException ee) {
13.497 - origCP = new Object[0];
13.498 - }
13.499 - }
13.500 - Object orig = (i < origCP.length) ? origCP[i] : "?";
13.501 - buf.append(orig).append("=").append(patchArray[i]);
13.502 - }
13.503 - buf.append("}");
13.504 - return buf.toString();
13.505 - }
13.506 -}
14.1 --- a/rt/emul/compact/src/main/java/sun/invoke/anon/ConstantPoolVisitor.java Sun Aug 10 05:56:32 2014 +0200
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,192 +0,0 @@
14.4 -/*
14.5 - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
14.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
14.7 - *
14.8 - * This code is free software; you can redistribute it and/or modify it
14.9 - * under the terms of the GNU General Public License version 2 only, as
14.10 - * published by the Free Software Foundation. Oracle designates this
14.11 - * particular file as subject to the "Classpath" exception as provided
14.12 - * by Oracle in the LICENSE file that accompanied this code.
14.13 - *
14.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
14.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14.17 - * version 2 for more details (a copy is included in the LICENSE file that
14.18 - * accompanied this code).
14.19 - *
14.20 - * You should have received a copy of the GNU General Public License version
14.21 - * 2 along with this work; if not, write to the Free Software Foundation,
14.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
14.23 - *
14.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
14.25 - * or visit www.oracle.com if you need additional information or have any
14.26 - * questions.
14.27 - */
14.28 -
14.29 -package sun.invoke.anon;
14.30 -
14.31 -/**
14.32 - * A visitor called by {@link ConstantPoolParser#parse(ConstantPoolVisitor)}
14.33 - * when a constant pool entry is parsed.
14.34 - * <p>
14.35 - * A visit* method is called when a constant pool entry is parsed.
14.36 - * The first argument is always the constant pool index.
14.37 - * The second argument is always the constant pool tag,
14.38 - * even for methods like {@link #visitUTF8(int, byte, String)} which only apply to one tag.
14.39 - * String arguments refer to Utf8 or NameAndType entries declared elsewhere,
14.40 - * and are always accompanied by the indexes of those entries.
14.41 - * <p>
14.42 - * The order of the calls to the visit* methods is not necessarily related
14.43 - * to the order of the entries in the constant pool.
14.44 - * If one entry has a reference to another entry, the latter (lower-level)
14.45 - * entry will be visited first.
14.46 - * <p>
14.47 - * The following table shows the relation between constant pool entry
14.48 - * types and the corresponding visit* methods:
14.49 - *
14.50 - * <table border=1 cellpadding=5 summary="constant pool visitor methods">
14.51 - * <tr><th>Tag(s)</th><th>Method</th></tr>
14.52 - * <tr>
14.53 - * <td>{@link #CONSTANT_Utf8}</td>
14.54 - * <td>{@link #visitUTF8(int, byte, String)}</td>
14.55 - * </tr><tr>
14.56 - * <td>{@link #CONSTANT_Integer}, {@link #CONSTANT_Float},
14.57 - * {@link #CONSTANT_Long}, {@link #CONSTANT_Double}</td>
14.58 - * <td>{@link #visitConstantValue(int, byte, Object)}</td>
14.59 - * </tr><tr>
14.60 - * <td>{@link #CONSTANT_String}, {@link #CONSTANT_Class}</td>
14.61 - * <td>{@link #visitConstantString(int, byte, String, int)}</td>
14.62 - * </tr><tr>
14.63 - * <td>{@link #CONSTANT_NameAndType}</td>
14.64 - * <td>{@link #visitDescriptor(int, byte, String, String, int, int)}</td>
14.65 - * </tr><tr>
14.66 - * <td>{@link #CONSTANT_Fieldref},
14.67 - * {@link #CONSTANT_Methodref},
14.68 - * {@link #CONSTANT_InterfaceMethodref}</td>
14.69 - * <td>{@link #visitMemberRef(int, byte, String, String, String, int, int)}</td>
14.70 - * </tr>
14.71 - * </table>
14.72 - *
14.73 - * @see ConstantPoolPatch
14.74 - * @author Remi Forax
14.75 - * @author jrose
14.76 - */
14.77 -public class ConstantPoolVisitor {
14.78 - /** Called each time an UTF8 constant pool entry is found.
14.79 - * @param index the constant pool index
14.80 - * @param tag always {@link #CONSTANT_Utf8}
14.81 - * @param utf8 string encoded in modified UTF-8 format passed as a {@code String}
14.82 - *
14.83 - * @see ConstantPoolPatch#putUTF8(int, String)
14.84 - */
14.85 - public void visitUTF8(int index, byte tag, String utf8) {
14.86 - // do nothing
14.87 - }
14.88 -
14.89 - /** Called for each constant pool entry that encodes an integer,
14.90 - * a float, a long, or a double.
14.91 - * Constant strings and classes are not managed by this method but
14.92 - * by {@link #visitConstantString(int, byte, String, int)}.
14.93 - *
14.94 - * @param index the constant pool index
14.95 - * @param tag one of {@link #CONSTANT_Integer},
14.96 - * {@link #CONSTANT_Float},
14.97 - * {@link #CONSTANT_Long},
14.98 - * or {@link #CONSTANT_Double}
14.99 - * @param value encoded value
14.100 - *
14.101 - * @see ConstantPoolPatch#putConstantValue(int, Object)
14.102 - */
14.103 - public void visitConstantValue(int index, byte tag, Object value) {
14.104 - // do nothing
14.105 - }
14.106 -
14.107 - /** Called for each constant pool entry that encodes a string or a class.
14.108 - * @param index the constant pool index
14.109 - * @param tag one of {@link #CONSTANT_String},
14.110 - * {@link #CONSTANT_Class},
14.111 - * @param name string body or class name (using dot separator)
14.112 - * @param nameIndex the index of the Utf8 string for the name
14.113 - *
14.114 - * @see ConstantPoolPatch#putConstantValue(int, byte, Object)
14.115 - */
14.116 - public void visitConstantString(int index, byte tag,
14.117 - String name, int nameIndex) {
14.118 - // do nothing
14.119 - }
14.120 -
14.121 - /** Called for each constant pool entry that encodes a name and type.
14.122 - * @param index the constant pool index
14.123 - * @param tag always {@link #CONSTANT_NameAndType}
14.124 - * @param memberName a field or method name
14.125 - * @param signature the member signature
14.126 - * @param memberNameIndex index of the Utf8 string for the member name
14.127 - * @param signatureIndex index of the Utf8 string for the signature
14.128 - *
14.129 - * @see ConstantPoolPatch#putDescriptor(int, String, String)
14.130 - */
14.131 - public void visitDescriptor(int index, byte tag,
14.132 - String memberName, String signature,
14.133 - int memberNameIndex, int signatureIndex) {
14.134 - // do nothing
14.135 - }
14.136 -
14.137 - /** Called for each constant pool entry that encodes a field or method.
14.138 - * @param index the constant pool index
14.139 - * @param tag one of {@link #CONSTANT_Fieldref},
14.140 - * or {@link #CONSTANT_Methodref},
14.141 - * or {@link #CONSTANT_InterfaceMethodref}
14.142 - * @param className the class name (using dot separator)
14.143 - * @param memberName name of the field or method
14.144 - * @param signature the field or method signature
14.145 - * @param classNameIndex index of the Utf8 string for the class name
14.146 - * @param descriptorIndex index of the NameAndType descriptor constant
14.147 - *
14.148 - * @see ConstantPoolPatch#putMemberRef(int, byte, String, String, String)
14.149 - */
14.150 - public void visitMemberRef(int index, byte tag,
14.151 - String className, String memberName, String signature,
14.152 - int classNameIndex, int descriptorIndex) {
14.153 - // do nothing
14.154 - }
14.155 -
14.156 - public static final byte
14.157 - CONSTANT_None = 0,
14.158 - CONSTANT_Utf8 = 1,
14.159 - //CONSTANT_Unicode = 2, /* unused */
14.160 - CONSTANT_Integer = 3,
14.161 - CONSTANT_Float = 4,
14.162 - CONSTANT_Long = 5,
14.163 - CONSTANT_Double = 6,
14.164 - CONSTANT_Class = 7,
14.165 - CONSTANT_String = 8,
14.166 - CONSTANT_Fieldref = 9,
14.167 - CONSTANT_Methodref = 10,
14.168 - CONSTANT_InterfaceMethodref = 11,
14.169 - CONSTANT_NameAndType = 12;
14.170 -
14.171 - private static String[] TAG_NAMES = {
14.172 - "Empty",
14.173 - "Utf8",
14.174 - null, //"Unicode",
14.175 - "Integer",
14.176 - "Float",
14.177 - "Long",
14.178 - "Double",
14.179 - "Class",
14.180 - "String",
14.181 - "Fieldref",
14.182 - "Methodref",
14.183 - "InterfaceMethodref",
14.184 - "NameAndType"
14.185 - };
14.186 -
14.187 - public static String tagName(byte tag) {
14.188 - String name = null;
14.189 - if ((tag & 0xFF) < TAG_NAMES.length)
14.190 - name = TAG_NAMES[tag];
14.191 - if (name == null)
14.192 - name = "Unknown#"+(tag&0xFF);
14.193 - return name;
14.194 - }
14.195 -}
15.1 --- a/rt/emul/compact/src/main/java/sun/invoke/anon/InvalidConstantPoolFormatException.java Sun Aug 10 05:56:32 2014 +0200
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,45 +0,0 @@
15.4 -/*
15.5 - * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
15.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
15.7 - *
15.8 - * This code is free software; you can redistribute it and/or modify it
15.9 - * under the terms of the GNU General Public License version 2 only, as
15.10 - * published by the Free Software Foundation. Oracle designates this
15.11 - * particular file as subject to the "Classpath" exception as provided
15.12 - * by Oracle in the LICENSE file that accompanied this code.
15.13 - *
15.14 - * This code is distributed in the hope that it will be useful, but WITHOUT
15.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15.17 - * version 2 for more details (a copy is included in the LICENSE file that
15.18 - * accompanied this code).
15.19 - *
15.20 - * You should have received a copy of the GNU General Public License version
15.21 - * 2 along with this work; if not, write to the Free Software Foundation,
15.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
15.23 - *
15.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
15.25 - * or visit www.oracle.com if you need additional information or have any
15.26 - * questions.
15.27 - */
15.28 -
15.29 -package sun.invoke.anon;
15.30 -
15.31 -/** Exception used when there is an error in the constant pool
15.32 - * format.
15.33 - */
15.34 -public class InvalidConstantPoolFormatException extends Exception {
15.35 - private static final long serialVersionUID=-6103888330523770949L;
15.36 -
15.37 - public InvalidConstantPoolFormatException(String message,Throwable cause) {
15.38 - super(message,cause);
15.39 - }
15.40 -
15.41 - public InvalidConstantPoolFormatException(String message) {
15.42 - super(message);
15.43 - }
15.44 -
15.45 - public InvalidConstantPoolFormatException(Throwable cause) {
15.46 - super(cause);
15.47 - }
15.48 -}
16.1 --- a/rt/emul/compact/src/main/java/sun/invoke/util/VerifyAccess.java Sun Aug 10 05:56:32 2014 +0200
16.2 +++ b/rt/emul/compact/src/main/java/sun/invoke/util/VerifyAccess.java Sun Aug 10 06:13:36 2014 +0200
16.3 @@ -27,7 +27,6 @@
16.4
16.5 import java.lang.reflect.Modifier;
16.6 import static java.lang.reflect.Modifier.*;
16.7 -import sun.reflect.Reflection;
16.8
16.9 /**
16.10 * This class centralizes information about the JVM's linkage access control.
16.11 @@ -144,7 +143,8 @@
16.12 // ...But arrays and primitives are synthesized with their own odd flags:
16.13 if (c.isArray() || c.isPrimitive())
16.14 return c.getModifiers();
16.15 - return Reflection.getClassAccessFlags(c);
16.16 + return c.getModifiers();
16.17 +// return Reflection.getClassAccessFlags(c);
16.18 }
16.19
16.20 /**
16.21 @@ -263,10 +263,11 @@
16.22 }
16.23
16.24 private static Class<?> getOutermostEnclosingClass(Class<?> c) {
16.25 - Class<?> pkgmem = c;
16.26 - for (Class<?> enc = c; (enc = enc.getEnclosingClass()) != null; )
16.27 - pkgmem = enc;
16.28 - return pkgmem;
16.29 + throw new IllegalStateException("Needed?");
16.30 +// Class<?> pkgmem = c;
16.31 +// for (Class<?> enc = c; (enc = enc.getEnclosingClass()) != null; )
16.32 +// pkgmem = enc;
16.33 +// return pkgmem;
16.34 }
16.35
16.36 private static boolean loadersAreRelated(ClassLoader loader1, ClassLoader loader2,