public MethodAnalyzer(@Nonnull ClassPath classPath, @Nonnull Method method, @Nullable InlineMethodResolver inlineResolver, boolean normalizeVirtualMethods) { this.classPath = classPath; this.inlineResolver = inlineResolver; this.normalizeVirtualMethods = normalizeVirtualMethods; this.method = method; MethodImplementation methodImpl = method.getImplementation(); if (methodImpl == null) { throw new IllegalArgumentException("The method has no implementation"); } this.methodImpl = methodImpl; // Override AnalyzedInstruction and provide custom implementations of some of the methods, so that we don't // have to handle the case this special case of instruction being null, in the main class startOfMethod = new AnalyzedInstruction(this, new ImmutableInstruction10x(Opcode.NOP), -1, methodImpl.getRegisterCount()) { @Override protected boolean addPredecessor(AnalyzedInstruction predecessor) { throw new UnsupportedOperationException(); } @Override @Nonnull public RegisterType getPredecessorRegisterType(@Nonnull AnalyzedInstruction predecessor, int registerNumber) { throw new UnsupportedOperationException(); } }; buildInstructionList(); analyzedState = new BitSet(analyzedInstructions.size()); paramRegisterCount = MethodUtil.getParameterRegisterCount(method); analyze(); }
if (!MethodUtil.isStatic(method)) { int thisRegister = totalRegisters - parameterRegisters; if (MethodUtil.isConstructor(method)) { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS,
private int findMethodIndexInVtableReverse(@Nonnull List<Method> vtable, MethodReference method) { for (int i=vtable.size() - 1; i>=0; i--) { Method candidate = vtable.get(i); if (MethodUtil.methodSignaturesMatch(candidate, method)) { if (!classPath.shouldCheckPackagePrivateAccess() || AnalyzedMethodUtil.canAccess(this, candidate, true, false, false)) { return i; } } } return -1; }
public static int getParameterRegisterCount(@Nonnull Method method) { return getParameterRegisterCount(method, MethodUtil.isStatic(method)); }
@Override public boolean apply(@Nullable Method input) { return input != null && isDirect(input); } };
@Nonnull @Override public CharSequence getShorty(@Nonnull MethodProtoReference reference) { return MethodUtil.getShorty(reference.getParameterTypes(), reference.getReturnType()); }
public static String getShorty(Collection<? extends CharSequence> params, String returnType) { StringBuilder sb = new StringBuilder(params.size() + 1); sb.append(getShortyType(returnType)); for (CharSequence typeRef: params) { sb.append(getShortyType(typeRef)); } return sb.toString(); }
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; } }
public static int getParameterRegisterCount(@Nonnull Method method) { return getParameterRegisterCount(method, MethodUtil.isStatic(method)); }
@Override public boolean apply(@Nullable Method input) { return input != null && !isDirect(input); } };
@Nonnull @Override public CharSequence getShorty(@Nonnull MethodProtoReference reference) { return MethodUtil.getShorty(reference.getParameterTypes(), reference.getReturnType()); }
public static String getShorty(Collection<? extends CharSequence> params, String returnType) { StringBuilder sb = new StringBuilder(params.size() + 1); sb.append(getShortyType(returnType)); for (CharSequence typeRef: params) { sb.append(getShortyType(typeRef)); } return sb.toString(); }
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; } }
numParameterRegisters = MethodUtil.getParameterRegisterCount(method); if (!isStatic) { numParameterRegisters--;
public static int getParameterRegisterCount(@Nonnull Method method) { return getParameterRegisterCount(method, MethodUtil.isStatic(method)); }
@Override public boolean apply(@Nullable Method input) { return input != null && !isDirect(input); } };
if (!MethodUtil.isStatic(method)) { int thisRegister = totalRegisters - parameterRegisters; if (MethodUtil.isConstructor(method)) { setPostRegisterTypeAndPropagateChanges(startOfMethod, thisRegister, RegisterType.getRegisterType(RegisterType.UNINIT_THIS,
@Nonnull public BuilderProtoReference internProto(@Nonnull List<? extends CharSequence> parameters, @Nonnull String returnType) { ProtoKey key = new Key(parameters, returnType); BuilderProtoReference ret = internedItems.get(key); if (ret != null) { return ret; } BuilderProtoReference protoReference = new BuilderProtoReference( context.stringPool.internString(MethodUtil.getShorty(parameters, returnType)), context.typeListPool.internTypeList(parameters), context.typePool.internType(returnType)); ret = internedItems.putIfAbsent(protoReference, protoReference); return ret==null?protoReference:ret; }
public static String getShorty(Collection<? extends CharSequence> params, String returnType) { StringBuilder sb = new StringBuilder(params.size() + 1); sb.append(getShortyType(returnType)); for (CharSequence typeRef: params) { sb.append(getShortyType(typeRef)); } return sb.toString(); }
private int findMethodIndexInVtable(@Nonnull List<Method> vtable, MethodReference method) { for (int i=0; i<vtable.size(); i++) { Method candidate = vtable.get(i); if (MethodUtil.methodSignaturesMatch(candidate, method)) { if (!classPath.shouldCheckPackagePrivateAccess() || AnalyzedMethodUtil.canAccess(this, candidate, true, false, false)) { return i; } } } return -1; }