public static boolean isNotWideningConversion(RegisterType originalType, RegisterType newType) { if (originalType.type == null || newType.type == null) { return true; } if (originalType.type.isInterface()) { return newType.type.implementsInterface(originalType.type.getType()); } else { TypeProto commonSuperclass = newType.type.getCommonSuperclass(originalType.type); if (commonSuperclass.getType().equals(originalType.type.getType())) { return true; } if (commonSuperclass.getType().equals(newType.type.getType())) { return false; } } return true; }
assert objectRegisterTypeProto != null; TypeProto classTypeProto = classPath.getClass(objectRegisterTypeProto.getType()); FieldReference resolvedField = classTypeProto.getFieldByOffset(fieldOffset); objectRegisterType.type.getType(), fieldOffset); ClassDef fieldClass = classPath.getClassDef(objectRegisterTypeProto.getType()); while (!TypeUtils.canAccessClass(thisClass.getType(), fieldClass)) { String superclass = fieldClass.getSuperclass(); FieldReference newResolvedField = classPath.getClass(fieldClass.getType()).getFieldByOffset(fieldOffset); if (newResolvedField == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving field %s",
TypeProto superType; String superclassType = typeProto.getSuperclass(); if (superclassType != null) { superType = classPath.getClass(superclassType); resolvedMethod = superType.getMethodByVtableIndex(methodIndex); } else { resolvedMethod = objectRegisterTypeProto.getMethodByVtableIndex(methodIndex); objectRegisterType.type.getType(), methodIndex); if (classPath.getClass(resolvedMethod.getDefiningClass()).isInterface()) { resolvedMethod = new ReparentedMethodReference(resolvedMethod, objectRegisterTypeProto.getType()); } else if (!isSuper && !TypeUtils.canAccessClass( thisClass.getType(), classPath.getClassDef(resolvedMethod.getDefiningClass()))) { ClassDef methodClass = classPath.getClassDef(objectRegisterTypeProto.getType()); while (!TypeUtils.canAccessClass(thisClass.getType(), methodClass)) { String superclass = methodClass.getSuperclass(); classPath.getClass(methodClass.getType()).getMethodByVtableIndex(methodIndex); if (newResolvedMethod == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s",
int methodIndex; try { methodIndex = typeProto.findMethodIndexInVtable(methodRef); } catch (UnresolvedClassException ex) { return null; Method replacementMethod = typeProto.getMethodByVtableIndex(methodIndex); assert replacementMethod != null; while (true) { String superType = typeProto.getSuperclass(); if (superType == null) { break; Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex); if (resolvedMethod == null) { break;
return other.getCommonSuperclass(this); if (this == other || getType().equals(other.getType())) { return this; if (other.getType().equals("Ljava/lang/Object;")) { return other; if (typeProto.getType().equals(otherChain.get(i).getType())) { return typeProto;
TypeProto thisClass = classPath.getClass(elementType); TypeProto otherClass = classPath.getClass(((ArrayProto)other).elementType); TypeProto mergedClass = thisClass.getCommonSuperclass(otherClass); if (thisClass == mergedClass) { return this; return other; return classPath.getClass(makeArrayType(mergedClass.getType(), dimensions)); if (other.isInterface()) { if (implementsInterface(other.getType())) { return other; return other.getCommonSuperclass(this);
public void writeTo(Writer writer) throws IOException { writer.write('('); writer.write(CATEGORY_NAMES[category]); if (type != null) { writer.write(','); writer.write(type.getType()); } writer.write(')'); }
TypeProto superType; String superclassType = typeProto.getSuperclass(); if (superclassType != null) { superType = classPath.getClass(superclassType); resolvedMethod = superType.getMethodByVtableIndex(methodIndex); } else{ resolvedMethod = objectRegisterTypeProto.getMethodByVtableIndex(methodIndex); objectRegisterType.type.getType(), methodIndex); ClassDef methodClass = classPath.getClassDef(objectRegisterTypeProto.getType()); while (!canAccessClass(thisClass, methodClass)) { String superclass = methodClass.getSuperclass(); resolvedMethod = classPath.getClass(methodClass.getType()).getMethodByVtableIndex(methodIndex); if (resolvedMethod == null) { throw new ExceptionWithContext("Couldn't find accessible class while resolving method %s",
@Nullable public static TypeProto getSuperclassAsTypeProto(@Nonnull TypeProto type) { try { String next = type.getSuperclass(); if (next != null) { return type.getClassPath().getClass(next); } else { return null; } } catch (UnresolvedClassException ex) { return type.getClassPath().getUnknownClass(); } }
public static boolean canAccess(@Nonnull TypeProto type, @Nonnull Method virtualMethod, boolean checkPackagePrivate, boolean checkProtected, boolean checkClass) { if (checkPackagePrivate && MethodUtil.isPackagePrivate(virtualMethod)) { String otherPackage = TypeUtils.getPackage(virtualMethod.getDefiningClass()); String thisPackage = TypeUtils.getPackage(type.getType()); if (!otherPackage.equals(thisPackage)) { return false; } } if (checkProtected && (virtualMethod.getAccessFlags() & AccessFlags.PROTECTED.getValue()) != 0) { if (!TypeProtoUtils.extendsFrom(type, virtualMethod.getDefiningClass())) { return false; } } if (checkClass) { ClassPath classPath = type.getClassPath(); ClassDef methodClassDef = classPath.getClassDef(virtualMethod.getDefiningClass()); if (!TypeUtils.canAccessClass(type.getType(), methodClassDef)) { return false; } } return true; } }
if (type != null) { if (other.type != null) { mergedType = type.getCommonSuperclass(other.type); } else { mergedType = type;
@Override @Nullable public Method getMethodByVtableIndex(int vtableIndex) { return classPath.getClass("Ljava/lang/Object;").getMethodByVtableIndex(vtableIndex); }
@Override @Nullable public FieldReference getFieldByOffset(int fieldOffset) { return classPath.getClass("Ljava/lang/Object;").getFieldByOffset(fieldOffset); }
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; }
@Override public int findMethodIndexInVtable(@Nonnull MethodReference method) { return classPath.getClass("Ljava/lang/Object;").findMethodIndexInVtable(method); } }
TypeProto thisClass = classPath.getClass(elementType); TypeProto otherClass = classPath.getClass(((ArrayProto)other).elementType); TypeProto mergedClass = thisClass.getCommonSuperclass(otherClass); if (thisClass == mergedClass) { return this; return other; return classPath.getClass(makeArrayType(mergedClass.getType(), dimensions)); if (other.isInterface()) { if (implementsInterface(other.getType())) { return other; return other.getCommonSuperclass(this);
/** * Creates a new ClassPath instance that can load classes from the given providers * * @param classProviders An iterable of ClassProviders. When loading a class, these providers will be searched in * order * @param checkPackagePrivateAccess Whether checkPackagePrivateAccess is needed, enabled for ONLY early API 17 by * default * @param oatVersion The applicable oat version, or NOT_ART */ public ClassPath(@Nonnull Iterable<? extends ClassProvider> classProviders, boolean checkPackagePrivateAccess, int oatVersion) { // add fallbacks for certain special classes that must be present unknownClass = new UnknownClassProto(this); loadedClasses.put(unknownClass.getType(), unknownClass); this.checkPackagePrivateAccess = checkPackagePrivateAccess; this.oatVersion = oatVersion; loadPrimitiveType("Z"); loadPrimitiveType("B"); loadPrimitiveType("S"); loadPrimitiveType("C"); loadPrimitiveType("I"); loadPrimitiveType("J"); loadPrimitiveType("F"); loadPrimitiveType("D"); loadPrimitiveType("L"); this.classProviders = Lists.newArrayList(classProviders); this.classProviders.add(getBasicClasses()); }
return other.getCommonSuperclass(this); if (this == other || getType().equals(other.getType())) { return this; if (other.getType().equals("Ljava/lang/Object;")) { return other; if (typeProto.getType().equals(otherChain.get(i).getType())) { return typeProto;
int methodIndex; try { methodIndex = typeProto.findMethodIndexInVtable(methodRef); } catch (UnresolvedClassException ex) { return null; Method replacementMethod = typeProto.getMethodByVtableIndex(methodIndex); assert replacementMethod != null; while (true) { String superType = typeProto.getSuperclass(); if (superType == null) { break; Method resolvedMethod = typeProto.getMethodByVtableIndex(methodIndex); if (resolvedMethod == null) { break;
@Nullable public static TypeProto getSuperclassAsTypeProto(@Nonnull TypeProto type) { try { String next = type.getSuperclass(); if (next != null) { return type.getClassPath().getClass(next); } else { return null; } } catch (UnresolvedClassException ex) { return type.getClassPath().getUnknownClass(); } }