/** * Returns the number of registered required to hold this local. */ int size() { return type.ropType.getCategory(); }
TypeId(com.android.dx.rop.type.Type ropType) { this(ropType.getDescriptor(), ropType); }
private void checkPrototype(Prototype proto) { checkDescriptor(proto.getReturnType().getDescriptor()); StdTypeList args = proto.getParameterTypes(); for (int i = 0; i < args.size(); i++) { checkDescriptor(args.get(i).getDescriptor()); } } private void checkDescriptor(String typeDescriptor) {
private void addClassWithHierachy(String classBinaryName) { if (classNames.contains(classBinaryName)) { return; } try { DirectClassFile classFile = path.getClass(classBinaryName + CLASS_EXTENSION); classNames.add(classBinaryName); CstType superClass = classFile.getSuperclass(); if (superClass != null) { addClassWithHierachy(superClass.getClassType().getClassName()); } TypeList interfaceList = classFile.getInterfaces(); int interfaceNumber = interfaceList.size(); for (int i = 0; i < interfaceNumber; i++) { addClassWithHierachy(interfaceList.getType(i).getClassName()); } } catch (FileNotFoundException e) { // Ignore: The referenced type is not in the path it must be part of the libraries. } } }
private StdTypeList toTypeList(List<TypeId<?>> types) { StdTypeList result = new StdTypeList(types.size()); for (int i = 0; i < types.size(); i++) { result.set(i, types.get(i).ropType); } return result; }
private void addDependencies(DirectClassFile classFile) { for (Constant constant : classFile.getConstantPool().getEntries()) { if (constant instanceof CstType) { checkDescriptor(((CstType) constant).getClassType().getDescriptor()); } else if (constant instanceof CstFieldRef) { checkDescriptor(((CstFieldRef) constant).getType().getDescriptor()); } else if (constant instanceof CstBaseMethodRef) { checkPrototype(((CstBaseMethodRef) constant).getPrototype()); } } FieldList fields = classFile.getFields(); int nbField = fields.size(); for (int i = 0; i < nbField; i++) { checkDescriptor(fields.get(i).getDescriptor().getString()); } MethodList methods = classFile.getMethods(); int nbMethods = methods.size(); for (int i = 0; i < nbMethods; i++) { checkPrototype(Prototype.intern(methods.get(i).getDescriptor().getString())); } } private void checkPrototype(Prototype proto) {
/** * Gets the category of this instance's type. This is just a convenient * shorthand for {@code getType().getCategory()}. * * @see #isCategory1 * @see #isCategory2 * @return {@code 1..2;} the category of this instance's type */ public int getCategory() { return type.getType().getCategory(); }
/** * Check if an int or reference equals to zero. If the comparison is true, * execution jumps to {@code trueLabel}. If it is false, execution continues to * the next instruction. */ public <T> void compareZ(Comparison comparison, Label trueLabel, Local<?> a) { adopt(trueLabel); Rop rop = comparison.rop(StdTypeList.make(a.type.ropType)); addInstruction(new PlainInsn(rop, sourcePosition, null, RegisterSpecList.make(a.spec())), trueLabel); }
/** * Gets the register that begins the method's parameter range (including * the 'this' parameter for non-static methods). The range continues until * {@code regSize} * * @return register as noted above. */ private int getParamBase() { return regSize - desc.getParameterTypes().getWordCount() - (isStatic? 0 : 1); }
Prototype prototype(boolean includeThis) { return Prototype.intern(descriptor(includeThis)); }
private Rop getCastRop(com.android.dx.rop.type.Type sourceType, com.android.dx.rop.type.Type targetType) { if (sourceType.getBasicType() == BT_INT) { switch (targetType.getBasicType()) { case BT_SHORT: return Rops.TO_SHORT; case BT_CHAR: return Rops.TO_CHAR; case BT_BYTE: return Rops.TO_BYTE; } } return Rops.opConv(targetType, sourceType); }
/** * @param name a descriptor like "Ljava/lang/Class;". */ public static <T> TypeId<T> get(String name) { return new TypeId<>(name, com.android.dx.rop.type.Type.internReturnType(name)); }
if (source.getType().ropType.isReference()) { addInstruction(new ThrowingCstInsn(Rops.CHECK_CAST, sourcePosition, RegisterSpecList.make(source.spec()), catches, target.type.constant));
public void addSupperClass(String name){ if (name.endsWith(CLASS_EXTENSION)) { classNames.add(name.substring(0, name.length() - CLASS_EXTENSION.length())); } if (name.endsWith(CLASS_EXTENSION)) { DirectClassFile classFile; try { classFile = path.getClass(name); CstType superClass = classFile.getSuperclass(); if (superClass != null) { String superClassName=superClass.getClassType().getClassName(); classNames.add(superClassName); } } catch (FileNotFoundException e) { // throw new IOException("Class " + name + // " is missing form original class path " + path, e); } } } public void addRootsV2(String name){
private void addDependencies(ConstantPool pool) { for (Constant constant : pool.getEntries()) { if (constant instanceof CstType) { checkDescriptor(((CstType) constant).getClassType()); } else if (constant instanceof CstFieldRef) { checkDescriptor(((CstFieldRef) constant).getType()); } else if (constant instanceof CstMethodRef) { Prototype proto = ((CstMethodRef) constant).getPrototype(); checkDescriptor(proto.getReturnType()); StdTypeList args = proto.getParameterTypes(); for (int i = 0; i < args.size(); i++) { checkDescriptor(args.get(i)); } } } }
addClassWithHierachy(superClass.getClassType().getClassName()); int interfaceNumber = interfaceList.size(); for (int i = 0; i < interfaceNumber; i++) { addClassWithHierachy(interfaceList.getType(i).getClassName());
TypeList(TypeId<?>[] types) { this.types = types.clone(); this.ropTypes = new StdTypeList(types.length); for (int i = 0; i < types.length; i++) { ropTypes.set(i, types[i].ropType); } }
/** * Compare ints or references. If the comparison is true, execution jumps to * {@code trueLabel}. If it is false, execution continues to the next * instruction. */ public <T> void compare(Comparison comparison, Label trueLabel, Local<T> a, Local<T> b) { adopt(trueLabel); Rop rop = comparison.rop(StdTypeList.make(a.type.ropType, b.type.ropType)); addInstruction(new PlainInsn(rop, sourcePosition, null, RegisterSpecList.make(a.spec(), b.spec())), trueLabel); }
private void checkDescriptor(Type type) { String descriptor = type.getDescriptor(); if (descriptor.endsWith(";")) { // System.out.println("=====descriptor:" + descriptor); int lastBrace = descriptor.lastIndexOf('['); if (lastBrace < 0) { addClassWithHierachy(descriptor.substring(1, descriptor.length() - 1)); } else { assert descriptor.length() > lastBrace + 3 && descriptor.charAt(lastBrace + 1) == 'L'; addClassWithHierachy(descriptor.substring(lastBrace + 2, descriptor.length() - 1)); } } }
/** * Executes {@code op} and sets {@code target} to the result. For most * binary operations, the types of {@code a} and {@code b} must be the same. * Shift operations (like {@link BinaryOp#SHIFT_LEFT}) require {@code b} to * be an {@code int}, even when {@code a} is a {@code long}. */ public <T1, T2> void op(BinaryOp op, Local<T1> target, Local<T1> a, Local<T2> b) { Rop rop = op.rop(StdTypeList.make(a.type.ropType, b.type.ropType)); RegisterSpecList sources = RegisterSpecList.make(a.spec(), b.spec()); if (rop.getBranchingness() == BRANCH_NONE) { addInstruction(new PlainInsn(rop, sourcePosition, target.spec(), sources)); } else { addInstruction(new ThrowingInsn(rop, sourcePosition, sources, catches)); moveResult(target, true); } }