From 5b19b17d7bce56352d1f9989010bce1c9f71d127 Mon Sep 17 00:00:00 2001 From: rfield Date: Fri, 12 Apr 2013 10:02:33 -0700 Subject: [PATCH] 8011805: Update sun.tools.java class file reading/writing support to include the new constant pool entries Reviewed-by: mduigou, alanb --- .../invoke/InnerClassLambdaMetafactory.java | 2 +- .../sun/tools/java/BinaryConstantPool.java | 24 +++ .../sun/tools/java/RuntimeConstants.java | 3 + test/sun/tools/java/CFCTest.java | 181 ++++++++++++++++++ 4 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 test/sun/tools/java/CFCTest.java diff --git a/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java b/src/share/classes/java/lang/invoke/InnerClassLambdaMetafactory.java index f7191f767..9134bcf22 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); + } + } + } + } +} -- GitLab