TypeProto objectRegisterTypeProto = objectRegisterType.type;
assert objectRegisterTypeProto != null;
TypeProto classTypeProto = classPath.getClass(objectRegisterTypeProto.getType());
FieldReference resolvedField = classTypeProto.getFieldByOffset(fieldOffset);
if (resolvedField == null) {
throw new AnalysisException("Could not resolve the field in class %s at offset %d",
objectRegisterType.type.getType(), fieldOffset);
}
ClassDef thisClass = classPath.getClassDef(method.getDefiningClass());
if (!canAccessClass(thisClass, classPath.getClassDef(resolvedField.getDefiningClass()))) {
// the class is not accessible. So we start looking at objectRegisterTypeProto (which may be different
// than resolvedField.getDefiningClass()), and walk up the class hierarchy.
ClassDef fieldClass = classPath.getClassDef(objectRegisterTypeProto.getType());
while (!canAccessClass(thisClass, fieldClass)) {
String superclass = fieldClass.getSuperclass();
if (superclass == null) {
throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
ReferenceUtil.getShortFieldDescriptor(resolvedField));
}
fieldClass = classPath.getClassDef(superclass);
}
// fieldClass is now the first accessible class found. Now. we need to make sure that the field is
// actually valid for this class
resolvedField = classPath.getClass(fieldClass.getType()).getFieldByOffset(fieldOffset);
if (resolvedField == null) {
throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
ReferenceUtil.getShortFieldDescriptor(resolvedField));
}
resolvedField = new ImmutableFieldReference(fieldClass.getType(), resolvedField.getName(),
resolvedField.getType());
}
String fieldType = resolvedField.getType();
Opcode opcode = OdexedFieldInstructionMapper.getAndCheckDeodexedOpcodeForOdexedOpcode(fieldType,
instruction.getOpcode());
Instruction22c deodexedInstruction = new ImmutableInstruction22c(opcode, (byte)instruction.getRegisterA(),