/** * Gets whether the method being translated is static. * * @return whether the method being translated is static */ private boolean isStatic() { int accessFlags = method.getAccessFlags(); return (accessFlags & AccessFlags.ACC_STATIC) != 0; }
/** * Gets the minimum label for unreserved use. * * @return {@code >= 0;} the minimum label */ private int getMinimumUnreservedLabel() { /* * The labels below (maxLabel + method.getCatches().size() + SPECIAL_LABEL_COUNT) are * reserved for particular uses. */ return maxLabel + method.getCatches().size() + SPECIAL_LABEL_COUNT; }
/** * Constructs an instance. * * @param machine {@code non-null;} machine to use when simulating * @param method {@code non-null;} method data to use */ public Simulator(Machine machine, ConcreteMethod method) { if (machine == null) { throw new NullPointerException("machine == null"); } if (method == null) { throw new NullPointerException("method == null"); } this.machine = machine; this.code = method.getCode(); this.localVariables = method.getLocalVariables(); this.visitor = new SimVisitor(); }
private void warn(String reason) { String warning = String.format("WARNING in %s.%s: %s", method.getDefiningClass().toHuman(), method.getNat().toHuman(), reason); dexOptions.err.println(warning); } }
/** * Constructs an instance. * * @param ropper {@code non-null;} ropper controlling this instance * @param method {@code non-null;} method being converted * @param advice {@code non-null;} translation advice to use */ public RopperMachine(Ropper ropper, ConcreteMethod method, TranslationAdvice advice) { super(method.getEffectiveDescriptor()); if (ropper == null) { throw new NullPointerException("ropper == null"); } if (advice == null) { throw new NullPointerException("advice == null"); } this.ropper = ropper; this.method = method; this.advice = advice; this.maxLocals = method.getMaxLocals(); this.insns = new ArrayList<Insn>(25); this.catches = null; this.catchesUsed = false; this.returns = false; this.primarySuccessorIndex = -1; this.extraBlockCount = 0; this.blockCanThrow = false; this.returnOp = null; this.returnPosition = null; }
LocalVariableList localVariables = method.getLocalVariables(); SourcePosition pos = method.makeSourcePosistion(0); Prototype desc = method.getEffectiveDescriptor(); StdTypeList params = desc.getParameterTypes(); int sz = params.size(); RegisterSpecList.EMPTY, StdTypeList.EMPTY, method.getDefiningClass()); insns = new InsnList(1); insns.set(0, insn);
new ConcreteMethod((Method) member, classFile, true, true); TranslationAdvice advice = DexTranslationAdvice.THE_ONE; RopMethod rmeth = Ropper.convert(meth, advice); SsaMethod ssaMeth = null; boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); int paramWidth = computeParamWidth(meth, isStatic);
this.blocks = BasicBlocker.identifyBlocks(method); this.maxLabel = blocks.getMaxLabel(); this.maxLocals = method.getMaxLocals(); this.machine = new RopperMachine(this, method, advice); this.sim = new Simulator(machine, method); startFrames[0] = new Frame(maxLocals, method.getMaxStack());
/** * Computes the total width, in register-units, of the parameters for * this method. * @param meth method to process * @return width in register-units */ static int computeParamWidth(ConcreteMethod meth, boolean isStatic) { return meth.getEffectiveDescriptor().getParameterTypes(). getWordCount(); }
private void checkInterfaceMethodDeclaration(ConcreteMethod declaredMethod) { if (!dexOptions.apiIsSupported(DexFormat.API_DEFINE_INTERFACE_METHODS)) { String reason = String.format( "defining a %s interface method requires --min-sdk-version >= %d (currently %d)" + " for interface methods: %s.%s", declaredMethod.isStaticMethod() ? "static" : "default", DexFormat.API_DEFINE_INTERFACE_METHODS, dexOptions.minSdkVersion, declaredMethod.getDefiningClass().toHuman(), declaredMethod.getNat().toHuman()); warn(reason); } }
/** * Constructs an instance. * * @param machine {@code non-null;} machine to use when simulating * @param method {@code non-null;} method data to use * @param dexOptions {@code non-null;} options for dex output */ public Simulator(Machine machine, ConcreteMethod method, DexOptions dexOptions) { if (machine == null) { throw new NullPointerException("machine == null"); } if (method == null) { throw new NullPointerException("method == null"); } if (dexOptions == null) { throw new NullPointerException("dexOptions == null"); } this.machine = machine; this.code = method.getCode(); this.method = method; this.localVariables = method.getLocalVariables(); this.visitor = new SimVisitor(); this.dexOptions = dexOptions; // This check assumes class is initialized (accesses dexOptions). if (method.isDefaultOrStaticInterfaceMethod()) { checkInterfaceMethodDeclaration(method); } }
/** * Tests whether the method is being defined on an interface. * @return true if the method is being defined on an interface. */ public final boolean isDefaultOrStaticInterfaceMethod() { return (classFile.getAccessFlags() & AccessFlags.ACC_INTERFACE) != 0 && !getNat().isClassInit(); }
/** * Gets the total number of registers used for "normal" purposes (i.e., * for the straightforward translation from the original Java). * * @return {@code >= 0;} the total number of registers used */ private int getNormalRegCount() { return maxLocals + method.getMaxStack(); }
/** {@inheritDoc} */ @Override public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) { if (!(member instanceof Method)) { return; } if (!shouldDumpMethod(name)) { return; } ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true); if (rop) { ropDump(meth); } else { regularDump(meth); } }
/** * Constructs an instance. This class is not publicly instantiable; use * {@link #identifyBlocks}. * * @param method {@code non-null;} method to convert */ private BasicBlocker(ConcreteMethod method) { if (method == null) { throw new NullPointerException("method == null"); } this.method = method; /* * The "+1" below is so the idx-past-end is also valid, * avoiding a special case, but without preventing * flow-of-control falling past the end of the method from * getting properly reported. */ int sz = method.getCode().size() + 1; workSet = Bits.makeBitSet(sz); liveSet = Bits.makeBitSet(sz); blockSet = Bits.makeBitSet(sz); targetLists = new IntList[sz]; catchLists = new ByteCatchList[sz]; previousOffset = -1; }
(ref.getDefiningClass() == method.getDefiningClass()) || !method.getAccSuper()) { return RegOps.INVOKE_DIRECT;
BytecodeArray bytes = method.getCode(); ByteCatchList catches = method.getCatches(); int catchSz = catches.size();
if (ref.getDefiningClass().equals(method.getDefiningClass())) { for (int i = 0; i < methods.size(); ++i) { final Method m = methods.get(i); if (ref.isInstanceInit()) { return RegOps.INVOKE_DIRECT; } else if (ref.getDefiningClass().equals(method.getDefiningClass())) { for (int i = 0; i < methods.size(); ++i) { final Method m = methods.get(i);
LocalVariableList localVariables = method.getLocalVariables(); SourcePosition pos = method.makeSourcePosistion(0); Prototype desc = method.getEffectiveDescriptor(); StdTypeList params = desc.getParameterTypes(); int sz = params.size(); RegisterSpecList.EMPTY, StdTypeList.EMPTY, method.getDefiningClass()); insns = new InsnList(1); insns.set(0, insn);
new ConcreteMethod((Method) member, classFile, true, true); TranslationAdvice advice = DexTranslationAdvice.THE_ONE; RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods()); SsaMethod ssaMeth = null; boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags()); int paramWidth = computeParamWidth(meth, isStatic);