diff --git a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java index f7191f7679f68347731e72d47ea3a39e6698919e..9134bcf22eae294c2b9342b23451f1396e1819ed 100644 --- a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java +++ b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java @@ -184,7 +184,7 @@ import java.security.PrivilegedAction; for (int i=0; i 88; + if (lam.get() == 88) { + System.out.println("Sanity passed: Lambda worked."); + } else { + throw new RuntimeException("Sanity failed: bad lambda execution"); + } + + // Verify that all the new constant pool constant types are present + String clsName = testClassPath + File.separator + testClassName + ".class"; + ClassConstantChecker ccc = new ClassConstantChecker(clsName); + ccc.checkFound(CONSTANT_METHODHANDLE); + ccc.checkFound(CONSTANT_METHODTYPE); + ccc.checkFound(CONSTANT_INVOKEDYNAMIC); + + // Heart of test: read the class file with the new constant types + exerciseClassDefinition(); + System.out.println("ClassDefinition read without failure.\n"); + } + + /** + * Failure is seen when getClassDefinition causes class read + */ + void exerciseClassDefinition() throws Exception { + BatchEnvironment env = new BatchEnvironment(System.out, + BatchEnvironment.createClassPath(testClassPath, null, null), + null); + try { + ClassDeclaration decl = env.getClassDeclaration( + Identifier.lookup(testClassName)); + decl.getClassDefinition(env); + } finally { + env.flushErrors(); + env.shutdown(); + } + } + + private class ClassConstantChecker { + + private DataInputStream in; + private boolean[] found; + + ClassConstantChecker(String clsName) throws IOException { + in = new DataInputStream(new FileInputStream(clsName)); + found = new boolean[CONSTANT_INVOKEDYNAMIC + 20]; + try { + check(); + } finally { + in.close(); + } + } + + void checkFound(int tag) throws Exception { + if (found[tag]) { + System.out.printf("Constant pool tag found: %d\n", tag); + } else { + throw new RuntimeException("Insufficient test, constant pool tag NOT found: " + tag); + } + } + + private void skip(int n) throws IOException { + if (in.skipBytes(n) != n) { + throw new EOFException(); + } + } + + private void check() throws IOException { + skip(8); // magic, version + int count = in.readUnsignedShort(); + for (int i = 1; i < count; i++) { + int j = i; + // JVM 4.4 cp_info.tag + int tag = in.readByte(); + found[tag] = true; + switch (tag) { + case CONSTANT_UTF8: + in.readUTF(); + break; + case CONSTANT_LONG: + case CONSTANT_DOUBLE: + skip(8); + break; + case CONSTANT_CLASS: + case CONSTANT_STRING: + skip(2); + break; + case CONSTANT_INTEGER: + case CONSTANT_FLOAT: + case CONSTANT_FIELD: + case CONSTANT_METHOD: + case CONSTANT_INTERFACEMETHOD: + case CONSTANT_NAMEANDTYPE: + skip(4); + break; + + case CONSTANT_METHODHANDLE: + skip(3); + break; + case CONSTANT_METHODTYPE: + skip(2); + break; + case CONSTANT_INVOKEDYNAMIC: + skip(4); + break; + + case 0: + default: + throw new ClassFormatError("invalid constant type: " + tag); + } + } + } + } +}