@Nonnull public SparseArray<FieldReference> getInstanceFields() { if (classPath.isArt()) { return artInstanceFieldsSupplier.get(); } else { return dalvikInstanceFieldsSupplier.get(); } }
@Nonnull public List<Method> getVtable() { if (!classPath.isArt() || classPath.oatVersion < 72) { return preDefaultMethodVtableSupplier.get(); } else if (classPath.oatVersion < 87) { return buggyPostDefaultMethodVtableSupplier.get(); } else { return postDefaultMethodVtableSupplier.get(); } }
@Override public OdexedFieldInstructionMapper get() { return new OdexedFieldInstructionMapper(isArt()); } });
/** * Returns the set of interfaces that this class implements as a Map<String, ClassDef>. * * The ClassDef value will be present only for the interfaces that this class directly implements (including any * interfaces transitively implemented), but not for any interfaces that are only implemented by a superclass of * this class * * For any interfaces that are only implemented by a superclass (or the class itself, if the class is an interface), * the value will be null. * * If any interface couldn't be resolved, then the interfacesFullyResolved field will be set to false upon return. * * @return the set of interfaces that this class implements as a Map<String, ClassDef>. */ @Nonnull protected LinkedHashMap<String, ClassDef> getInterfaces() { if (!classPath.isArt() || classPath.oatVersion < 72) { return preDefaultMethodInterfaceSupplier.get(); } else { return postDefaultMethodInterfaceSupplier.get(); } }
private int getNextFieldOffset() { SparseArray<FieldReference> instanceFields = getInstanceFields(); if (instanceFields.size() == 0) { return classPath.isArt() ? 0 : 8; } int lastItemIndex = instanceFields.size()-1; int fieldOffset = instanceFields.keyAt(lastItemIndex); FieldReference lastField = instanceFields.valueAt(lastItemIndex); if (classPath.isArt()) { return fieldOffset + getTypeSize(lastField.getType().charAt(0)); } else { switch (lastField.getType().charAt(0)) { case 'J': case 'D': return fieldOffset + 8; default: return fieldOffset + 4; } } }
static boolean canPropagateTypeAfterInstanceOf(AnalyzedInstruction analyzedInstanceOfInstruction, AnalyzedInstruction analyzedIfInstruction, ClassPath classPath) { if (!classPath.isArt()) { return false; } Instruction ifInstruction = analyzedIfInstruction.instruction; if (((Instruction21t)ifInstruction).getRegisterA() == analyzedInstanceOfInstruction.getDestinationRegister()) { Reference reference = ((Instruction22c)analyzedInstanceOfInstruction.getInstruction()).getReference(); RegisterType registerType = RegisterType.getRegisterType(classPath, (TypeReference)reference); try { if (registerType.type != null && !registerType.type.isInterface()) { int objectRegister = ((TwoRegisterInstruction)analyzedInstanceOfInstruction.getInstruction()) .getRegisterB(); RegisterType originalType = analyzedIfInstruction.getPreInstructionRegisterType(objectRegister); return isNotWideningConversion(originalType, registerType); } } catch (UnresolvedClassException ex) { return false; } } return false; }
if (classPath.isArt()) { int instructionIndex = analyzedInstruction.getInstructionIndex(); if (instructionIndex > 0) {
@Nonnull public SparseArray<FieldReference> getInstanceFields() { if (classPath.isArt()) { return artInstanceFieldsSupplier.get(); } else { return dalvikInstanceFieldsSupplier.get(); } }
@Nonnull public List<Method> getVtable() { if (!classPath.isArt() || classPath.oatVersion < 72) { return preDefaultMethodVtableSupplier.get(); } else if (classPath.oatVersion < 87) { return buggyPostDefaultMethodVtableSupplier.get(); } else { return postDefaultMethodVtableSupplier.get(); } }
/** * Returns the set of interfaces that this class implements as a Map<String, ClassDef>. * * The ClassDef value will be present only for the interfaces that this class directly implements (including any * interfaces transitively implemented), but not for any interfaces that are only implemented by a superclass of * this class * * For any interfaces that are only implemented by a superclass (or the class itself, if the class is an interface), * the value will be null. * * If any interface couldn't be resolved, then the interfacesFullyResolved field will be set to false upon return. * * @return the set of interfaces that this class implements as a Map<String, ClassDef>. */ @Nonnull protected LinkedHashMap<String, ClassDef> getInterfaces() { if (!classPath.isArt() || classPath.oatVersion < 72) { return preDefaultMethodInterfaceSupplier.get(); } else { return postDefaultMethodInterfaceSupplier.get(); } }
@Override public OdexedFieldInstructionMapper get() { return new OdexedFieldInstructionMapper(isArt()); } });
private int getNextFieldOffset() { SparseArray<FieldReference> instanceFields = getInstanceFields(); if (instanceFields.size() == 0) { return classPath.isArt() ? 0 : 8; } int lastItemIndex = instanceFields.size()-1; int fieldOffset = instanceFields.keyAt(lastItemIndex); FieldReference lastField = instanceFields.valueAt(lastItemIndex); if (classPath.isArt()) { return fieldOffset + getTypeSize(lastField.getType().charAt(0)); } else { switch (lastField.getType().charAt(0)) { case 'J': case 'D': return fieldOffset + 8; default: return fieldOffset + 4; } } }
static boolean canPropagateTypeAfterInstanceOf(AnalyzedInstruction analyzedInstanceOfInstruction, AnalyzedInstruction analyzedIfInstruction, ClassPath classPath) { if (!classPath.isArt()) { return false; } Instruction ifInstruction = analyzedIfInstruction.instruction; if (((Instruction21t)ifInstruction).getRegisterA() == analyzedInstanceOfInstruction.getDestinationRegister()) { Reference reference = ((Instruction22c)analyzedInstanceOfInstruction.getInstruction()).getReference(); RegisterType registerType = RegisterType.getRegisterType(classPath, (TypeReference)reference); try { if (registerType.type != null && !registerType.type.isInterface()) { int objectRegister = ((TwoRegisterInstruction)analyzedInstanceOfInstruction.getInstruction()) .getRegisterB(); RegisterType originalType = analyzedIfInstruction.getPreInstructionRegisterType(objectRegister); return isNotWideningConversion(originalType, registerType); } } catch (UnresolvedClassException ex) { return false; } } return false; }
methodAnalyzer.getClassPath().isArt() && getPredecessorCount() == 1 && (instruction.getOpcode() == Opcode.IF_EQZ || instruction.getOpcode() == Opcode.IF_NEZ)) {
methodAnalyzer.getClassPath().isArt() && getPredecessorCount() == 1 && (instruction.getOpcode() == Opcode.IF_EQZ || instruction.getOpcode() == Opcode.IF_NEZ)) {
if (classPath.isArt()) { int instructionIndex = analyzedInstruction.getInstructionIndex(); if (instructionIndex > 0) {
methodAnalyzer.getClassPath().isArt() && getPredecessorCount() == 1 && (instruction.getOpcode() == Opcode.IF_EQZ || instruction.getOpcode() == Opcode.IF_NEZ)) {
methodAnalyzer.getClassPath().isArt() && getPredecessorCount() == 1 && (instruction.getOpcode() == Opcode.IF_EQZ || instruction.getOpcode() == Opcode.IF_NEZ)) {