@Override public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = c.reference_kind.name(); value = value.concat(" " + visit(cfpool.get(c.reference_index), c.reference_index)); slist.set(p, value); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
@Override public String visitInterfaceMethodref(CONSTANT_InterfaceMethodref_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.class_index), c.class_index); value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index)); slist.set(p, value); xpool.add(new Element("CONSTANT_InterfaceMethodref", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
public static void main(String[] args) throws IOException, ConstantPoolException { Path outdir = Paths.get("."); ToolBox tb = new ToolBox(); final Path moduleInfo = Paths.get("module-info.java"); tb.writeFile(moduleInfo, "module test_module{}"); new JavacTask(tb) .outdir(outdir) .files(moduleInfo) .run(); AccessFlags accessFlags = ClassFile.read(outdir.resolve("module-info.class")) .access_flags; if (!accessFlags.is(AccessFlags.ACC_MODULE)) { throw new RuntimeException("Classfile doesn't have module access flag"); } }
public Element readFrom(InputStream in) throws IOException { try { this.in = in; ClassFile c = ClassFile.read(in); // read the file header if (c.magic != 0xCAFEBABE) { throw new RuntimeException("bad magic number " + Integer.toHexString(c.magic)); } cfile.setAttr("magic", "" + c.magic); int minver = c.minor_version; int majver = c.major_version; cfile.setAttr("minver", "" + minver); cfile.setAttr("majver", "" + majver); readCP(c); readClass(c); return result(); } catch (InvalidDescriptor | ConstantPoolException ex) { throw new IOException("Fatal error", ex); } }
private void readClass(ClassFile c) throws IOException, ConstantPoolException, InvalidDescriptor { klass = new Element("Class"); cfile.add(klass); String thisk = c.getName(); klass.setAttr("name", thisk); AccessFlags af = new AccessFlags(c.access_flags.flags); klass.setAttr("flags", flagString(af, klass)); if (!"java/lang/Object".equals(thisk)) { klass.setAttr("super", c.getSuperclassName()); } for (int i : c.interfaces) { klass.add(new Element("Interface", "name", getCpString(i))); } readFields(c, klass); readMethods(c, klass); readAttributesFor(c, c.attributes, klass); klass.trimToSize(); }
@Override public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = bsmlist.get(c.bootstrap_method_attr_index) + " " + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index); slist.set(p, value); xpool.add(new Element("CONSTANT_InvokeDynamic", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
@Override public String visitPackage(CONSTANT_Package_info info, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(info.name_index), info.name_index); slist.set(p, value); xpool.add(new Element("CONSTANT_Package", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
@Override public String visitMethodHandle(CONSTANT_MethodHandle_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = c.reference_kind.name(); value = value.concat(" " + visit(cfpool.get(c.reference_index), c.reference_index)); slist.set(p, value); xpool.add(new Element("CONSTANT_MethodHandle", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
void checkClassFile(File file) throws IOException, ConstantPoolException, InvalidDescriptor { ClassFile classFile = ClassFile.read(file); ConstantPool constantPool = classFile.constant_pool; //lets get all the methods in the class file. for (Method method : classFile.methods) { for (ElementKey elementKey: aliveRangeMap.keySet()) { String methodDesc = method.getName(constantPool) + method.descriptor.getParameterTypes(constantPool).replace(" ", ""); if (methodDesc.equals(elementKey.elem.toString())) { checkMethod(constantPool, method, aliveRangeMap.get(elementKey)); seenAliveRanges.add(elementKey); } } } }
@Override public String visitMethodType(CONSTANT_MethodType_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.descriptor_index), c.descriptor_index); slist.set(p, value); xpool.add(new Element("CONSTANT_MethodType", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
@Override public String visitString(CONSTANT_String_info c, Integer p) { try { String value = slist.get(p); if (value == null) { value = c.getString(); slist.set(p, value); xpool.add(new Element("CONSTANT_String", new String[]{"id", p.toString()}, value)); } return value; } catch (ConstantPoolException ex) { throw new RuntimeException("Fatal error", ex); } }
Object convertConstantValue(CPInfo info, String descriptor) throws ConstantPoolException { if (info instanceof CONSTANT_Integer_info) { if ("Z".equals(descriptor)) return ((CONSTANT_Integer_info) info).value == 1; else return ((CONSTANT_Integer_info) info).value; } else if (info instanceof CONSTANT_Long_info) { return ((CONSTANT_Long_info) info).value; } else if (info instanceof CONSTANT_Float_info) { return ((CONSTANT_Float_info) info).value; } else if (info instanceof CONSTANT_Double_info) { return ((CONSTANT_Double_info) info).value; } else if (info instanceof CONSTANT_String_info) { return ((CONSTANT_String_info) info).getString(); } throw new IllegalStateException(info.getClass().getName()); }
@Override public void testElementValue( TestResult testResult, ClassFile classFile, Annotation.element_value element_value) throws ConstantPoolException { testTag(testResult, element_value.tag); Annotation ev = ((Annotation.Annotation_element_value) element_value).annotation_value; testResult.checkEquals( classFile.constant_pool.getUTF8Info(ev.type_index).value, String.format("L%s;", annotationName), "type_index"); for (int i = 0; i < ev.num_element_value_pairs; ++i) { Annotation.element_value_pair pair = ev.element_value_pairs[i]; Pair expectedPair = annotation.elementValues.get(i); expectedPair.elementValue.testElementValue(testResult, classFile, pair.value); testResult.checkEquals( classFile.constant_pool.getUTF8Info(pair.element_name_index).value, expectedPair.elementName, "element_name_index"); } }
@Override public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.class_index), c.class_index); value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index)); slist.set(p, value); xpool.add(new Element("CONSTANT_Fieldref", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
void check(String dir, String... fileNames) throws IOException, ConstantPoolException, Descriptor.InvalidDescriptor { for (String fileName : fileNames) { ClassFile classFileToCheck = ClassFile.read(new File(dir, fileName)); for (Method method : classFileToCheck.methods) { if ((method.access_flags.flags & ACC_STRICT) == 0) { errors.add(String.format(offendingMethodErrorMessage, method.getName(classFileToCheck.constant_pool), classFileToCheck.getName())); } } } }
private void checkDebugAttributes(byte[] strippedClassFile) throws IOException, ConstantPoolException { ClassFile classFile = ClassFile.read(new ByteArrayInputStream(strippedClassFile)); String[] debugAttributes = new String[]{ Attribute.LineNumberTable, Attribute.LocalVariableTable, Attribute.LocalVariableTypeTable }; for (Method method : classFile.methods) { String methodName = method.getName(classFile.constant_pool); Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); for (String attr : debugAttributes) { if (code.attributes.get(attr) != null) { throw new AssertionError("Debug attribute was not removed: " + attr + " from method " + classFile.getName() + "#" + methodName); } } } }
@Override public String visitClass(CONSTANT_Class_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.name_index), c.name_index); slist.set(p, value); xpool.add(new Element("CONSTANT_Class", new String[]{"id", p.toString()}, value)); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
void analyzeModule(StandardJavaFileManager fm, String moduleName) throws IOException, ConstantPoolException, InvalidDescriptor { JavaFileManager.Location location = fm.getLocationForModule(StandardLocation.SYSTEM_MODULES, moduleName); if (location == null) throw new AssertionError("can't find module " + moduleName); for (JavaFileObject file : fm.list(location, "", EnumSet.of(CLASS), true)) { String className = fm.inferBinaryName(location, file); int index = className.lastIndexOf('.'); String pckName = index == -1 ? "" : className.substring(0, index); if (shouldAnalyzePackage(pckName)) { analyzeClassFile(ClassFile.read(file.openInputStream())); } } }
private static boolean verifyClassFileAttributes(File classFile, TestCases tc) { ClassFile c = null; try { c = ClassFile.read(classFile); } catch (IOException | ConstantPoolException e) { e.printStackTrace(); } ConstantPoolVisitor cpv = new ConstantPoolVisitor(c, c.constant_pool.size()); Map<Integer, String> hm = cpv.getBSMMap(); List<String> expectedValList = tc.getExpectedArgValues(); expectedValList.add(tc.bsmSpecifier.specifier); if(!(hm.values().containsAll(new HashSet<String>(expectedValList)))) { System.out.println("Values do not match"); return false; } return true; }
@Override public String visitFieldref(CONSTANT_Fieldref_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.class_index), c.class_index); value = value.concat(" " + visit(cfpool.get(c.name_and_type_index), c.name_and_type_index)); slist.set(p, value); } catch (ConstantPoolException ex) { ex.printStackTrace(); } } return value; }
public void testAnnotation(TestResult testResult, ClassFile classFile, Annotation annotation) throws ConstantPoolException { testResult.checkEquals(classFile.constant_pool.getUTF8Value(annotation.type_index), String.format("L%s;", annotationName), "Testing annotation name : " + annotationName); testResult.checkEquals(annotation.num_element_value_pairs, elementValues.size(), "Number of element values"); if (!testResult.checkEquals(annotation.num_element_value_pairs, elementValues.size(), "Number of element value pairs")) { return; } for (int i = 0; i < annotation.num_element_value_pairs; ++i) { Annotation.element_value_pair pair = annotation.element_value_pairs[i]; testResult.checkEquals(classFile.constant_pool.getUTF8Value(pair.element_name_index), elementValues.get(i).elementName, "element_name_index : " + elementValues.get(i).elementName); elementValues.get(i).elementValue.testElementValue(testResult, classFile, pair.value); } }
protected ClassFile readClassFile(Path p) throws IOException { InputStream is = null; try { is = Files.newInputStream(p); return ClassFile.read(is); } catch (ConstantPoolException e) { throw new ClassFileError(e); } finally { if (is != null) { is.close(); } } }
protected ClassFile readClassFile(JarFile jarfile, JarEntry e) throws IOException { InputStream is = null; try { is = jarfile.getInputStream(e); return ClassFile.read(is); } catch (ConstantPoolException ex) { throw new ClassFileError(ex); } finally { if (is != null) is.close(); } }
String getJavaSuperclassName(ClassFile cf) { try { return getJavaName(cf.getSuperclassName()); } catch (ConstantPoolException e) { return report(e); } }
String getJavaInterfaceName(ClassFile cf, int index) { try { return getJavaName(cf.getInterfaceName(index)); } catch (ConstantPoolException e) { return report(e); } }
String getJavaException(Exceptions_attribute attr, int index) { try { return getJavaName(attr.getException(index, constant_pool)); } catch (ConstantPoolException e) { return report(e); } }
String getValue(Descriptor d) { try { return d.getValue(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
String getFieldName(Field f) { try { return f.getName(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
String getName(Method m) { try { return m.getName(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
String getSourceFile(SourceFile_attribute attr) { try { return attr.getSourceFile(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
private String getJavaClassName(EnclosingMethod_attribute a) { try { return getJavaName(a.getClassName(constant_pool)); } catch (ConstantPoolException e) { return report(e); } }
private String getMethodName(EnclosingMethod_attribute a) { try { return a.getMethodName(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
private String getJavaException(Exceptions_attribute attr, int index) { try { return getJavaName(attr.getException(index, constant_pool)); } catch (ConstantPoolException e) { return report(e); } }
private void checkModuleVersion(Path classfile, String version) throws IOException, ConstantPoolException { ClassFile cf = ClassFile.read(classfile); Module_attribute moduleAttribute = (Module_attribute) cf.attributes.get(Attribute.Module); if (moduleAttribute == null) { throw new AssertionError("Version attribute missing!"); } String actualVersion = cf.constant_pool.getUTF8Value(moduleAttribute.module_version_index); if (!version.equals(actualVersion)) { throw new AssertionError("Incorrect version in the classfile: " + actualVersion); } }
String getSignature(Signature_attribute info) { try { return info.getSignature(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
private String getSourceFile(SourceFile_attribute attr) { try { return attr.getSourceFile(constant_pool); } catch (ConstantPoolException e) { return report(e); } }
String getCheckedName(CONSTANT_Class_info info) { try { return checkName(info.getName()); } catch (ConstantPoolException e) { return report(e); } }
public String visitInvokeDynamic(CONSTANT_InvokeDynamic_info info, Void p) { try { String callee = stringValue(info.getNameAndTypeInfo()); return "#" + info.bootstrap_method_attr_index + ":" + callee; } catch (ConstantPoolException e) { return report(e); } }