void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges) throws InvalidIndex, UnexpectedEntry, ConstantPoolException { Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); LocalVariableTable_attribute lvt = (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable)); List<String> infoFromRanges = convertToStringList(ranges); List<String> infoFromLVT = convertToStringList(constantPool, lvt); // infoFromRanges most be contained in infoFromLVT int i = 0; int j = 0; while (i < infoFromRanges.size() && j < infoFromLVT.size()) { int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j)); if (comparison == 0) { i++; j++; } else if (comparison > 0) { j++; } else { break; } } if (i < infoFromRanges.size()) { error(infoFromLVT, infoFromRanges, method.getName(constantPool).toString()); } }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { String aName = e.getKey(); TypeAnnotation.Position expected = e.getValue(); TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); if (actual == null) throw new ComparisionException("Expected annotation not found: " + aName); if (!areEquals(expected, actual.position)) { throw new ComparisionException("Unexpected position for annotation : " + aName + "\n Expected: " + expected.toString() + "\n Found: " + actual.position.toString()); } } return true; }
private void readCP(ClassFile c) throws IOException { cpool = new Element("ConstantPool", c.constant_pool.size()); ConstantPoolVisitor cpv = new ConstantPoolVisitor(cpool, c, c.constant_pool.size()); for (int i = 1 ; i < c.constant_pool.size() ; i++) { try { cpv.visit(c.constant_pool.get(i), i); } catch (InvalidIndex ex) { // can happen periodically when accessing doubles etc. ignore it // ex.printStackTrace(); } } thePool = cpv.getPoolList(); if (verbose) { for (int i = 0; i < thePool.size(); i++) { System.out.println("[" + i + "]: " + thePool.get(i)); } } if (keepCP) { cfile.add(cpool); } }
@Override public String visitNameAndType(CONSTANT_NameAndType_info c, Integer p) { String value = slist.get(p); if (value == null) { try { value = visit(cfpool.get(c.name_index), c.name_index); value = value.concat(" " + visit(cfpool.get(c.type_index), c.type_index)); slist.set(p, value); xpool.add(new Element("CONSTANT_NameAndType", new String[]{"id", p.toString()}, value)); } catch (InvalidIndex ex) { ex.printStackTrace(); } } return value; }
public static boolean compare(Map<String, TypeAnnotation.Position> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Map.Entry<String, TypeAnnotation.Position> e : expectedAnnos.entrySet()) { String aName = e.getKey(); TypeAnnotation.Position expected = e.getValue(); TypeAnnotation actual = findAnnotation(aName, actualAnnos, cf); if (actual == null) throw new ComparisionException("Expected annotation not found: " + aName); // TODO: you currently get an exception if the test case does not use all necessary // annotation attributes, e.g. forgetting the offset for a local variable. // It would be nicer to give an understandable warning instead. if (!areEquals(expected, actual.position)) { throw new ComparisionException("Unexpected position for annotation : " + aName + "\n Expected: " + expected.toString() + "\n Found: " + actual.position.toString()); } } return true; }
void checkMethod(ConstantPool constantPool, Method method, AliveRanges ranges) throws InvalidIndex, UnexpectedEntry { Code_attribute code = (Code_attribute) method.attributes.get(Attribute.Code); LocalVariableTable_attribute lvt = (LocalVariableTable_attribute) (code.attributes.get(Attribute.LocalVariableTable)); List<String> infoFromRanges = convertToStringList(ranges); List<String> infoFromLVT = convertToStringList(constantPool, lvt); // infoFromRanges most be contained in infoFromLVT int i = 0; int j = 0; while (i < infoFromRanges.size() && j < infoFromLVT.size()) { int comparison = infoFromRanges.get(i).compareTo(infoFromLVT.get(j)); if (comparison == 0) { i++; j++; } else if (comparison > 0) { j++; } else { break; } } if (i < infoFromRanges.size()) { error(infoFromLVT, infoFromRanges); } }
public static boolean compare(List<Pair<String, TypeAnnotation.Position>> expectedAnnos, List<TypeAnnotation> actualAnnos, ClassFile cf) throws InvalidIndex, UnexpectedEntry { if (actualAnnos.size() != expectedAnnos.size()) { throw new ComparisionException("Wrong number of annotations", expectedAnnos, actualAnnos); } for (Pair<String, TypeAnnotation.Position> e : expectedAnnos) { String aName = e.first; TypeAnnotation.Position expected = e.second; TypeAnnotation actual = findAnnotation(aName, expected, actualAnnos, cf); if (actual == null) { throw new ComparisionException("Expected annotation not found: " + aName + " position: " + expected, expectedAnnos, actualAnnos); } } return true; }
Object convertElementValue(ConstantPool cp, element_value val) throws InvalidIndex, ConstantPoolException { switch (val.tag) { case 'Z': return ((CONSTANT_Integer_info) cp.get(((Primitive_element_value) val).const_value_index)).value != 0; case 'B': return (byte) ((CONSTANT_Integer_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'C': return (char) ((CONSTANT_Integer_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'S': return (short) ((CONSTANT_Integer_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'I': return ((CONSTANT_Integer_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'J': return ((CONSTANT_Long_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'F': return ((CONSTANT_Float_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'D': return ((CONSTANT_Double_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 's': return ((CONSTANT_Utf8_info) cp.get(((Primitive_element_value) val).const_value_index)).value; case 'e': return new EnumConstant(cp.getUTF8Value(((Enum_element_value) val).type_name_index), cp.getUTF8Value(((Enum_element_value) val).const_name_index)); case 'c': return new ClassConstant(cp.getUTF8Value(((Class_element_value) val).class_info_index)); case '@': return annotation2Description(cp, ((Annotation_element_value) val).annotation_value); case '[': List<Object> values = new ArrayList<>(); for (element_value elem : ((Array_element_value) val).values) { values.add(convertElementValue(cp, elem)); } return values; default: throw new IllegalStateException("Currently unhandled tag: " + val.tag); } }
/** * Indicate whether an annotation matches this expected * annotation. * * @param ConstantPool The constant pool to use. * @param anno The annotation to check. * @return Whether the annotation matches. */ protected boolean checkMatch(ConstantPool cpool, Annotation anno) { try { return cpool.getUTF8Info(anno.type_index).value.equals("L" + expectedName + ";"); } catch (InvalidIndex | UnexpectedEntry e) { return false; } }
List<String> convertToStringList(ConstantPool constantPool, LocalVariableTable_attribute lvt) throws InvalidIndex, UnexpectedEntry { List<String> result = new ArrayList<>(); for (Entry entry : lvt.local_variable_table) { String str = formatLocalVariableData(constantPool.getUTF8Value(entry.name_index), entry.start_pc, entry.length); result.add(str); } Collections.sort(result); return result; }
void checkIndirectRefToString(int cp_index) { try { CPInfo cInfo = constantPool.get(cp_index); if (cInfo instanceof CONSTANT_String_info) { CONSTANT_String_info strInfo = (CONSTANT_String_info)cInfo; if (strInfo.string_index == utf8Index) { numberOfRefToStr++; } } } catch (InvalidIndex ex) { throw new AssertionError("invalid constant pool index at " + cp_index); } }
private static TypeAnnotation findAnnotation(String name, List<TypeAnnotation> annotations, ClassFile cf) throws InvalidIndex, UnexpectedEntry { String properName = "L" + name + ";"; for (TypeAnnotation anno : annotations) { String actualName = cf.constant_pool.getUTF8Value(anno.annotation.type_index); if (properName.equals(actualName)) return anno; } return null; }
private List<String> readBSM() { BootstrapMethods_attribute bsmAttr = (BootstrapMethods_attribute) cf.getAttribute(Attribute.BootstrapMethods); if (bsmAttr != null) { List<String> out = new ArrayList<>(bsmAttr.bootstrap_method_specifiers.length); for (BootstrapMethods_attribute.BootstrapMethodSpecifier bsms : bsmAttr.bootstrap_method_specifiers) { int index = bsms.bootstrap_method_ref; try { String value = slist.get(index); String bsmStr = value; if (value == null) { value = visit(cfpool.get(index), index); slist.set(index, value); } bsmStr = value; for (int idx : bsms.bootstrap_arguments) { value = slist.get(idx); if (value == null) { value = visit(cfpool.get(idx), idx); slist.set(idx, value); } bsmStr = bsmStr.concat("," + value); } out.add(bsmStr); } catch (InvalidIndex ex) { ex.printStackTrace(); } } return out; } return new ArrayList<>(0); }