private Dop findExpandedOpcodeForInsn(DalvInsn insn) { Dop result = findOpcodeForInsn(insn.getLowRegVersion(), insn.getOpcode()); if (result == null) { throw new DexException("No expanded opcode for " + insn); } return result; }
/** * Gets the address immediately after this instance. This is only * calculable if this instance's address is known, and it is equal * to the address plus the length of the instruction format of this * instance's opcode. * * @return {@code >= 0;} the next address */ public final int getNextAddress() { return getAddress() + codeSize(); }
/** {@inheritDoc} */ @Override public boolean isCompatible(DalvInsn insn) { return (insn instanceof SimpleInsn) && (insn.getRegisters().size() == 0); }
/** * Helper for {@link #assignAddressesAndFixBranches}, which * assigns an address to each instruction, in order. */ private void assignAddresses() { int address = 0; int size = insns.size(); for (int i = 0; i < size; i++) { DalvInsn insn = insns.get(i); insn.setAddress(address); address += insn.codeSize(); } }
/** * Gets the instruction that is equivalent to this one, except that * it uses sequential registers starting at {@code 0} (storing * the result, if any, in register {@code 0} as well). * * @return {@code non-null;} the replacement */ public DalvInsn getLowRegVersion() { RegisterSpecList regs = registers.withExpandedRegisters(0, hasResult(), null); return withRegisters(regs); }
/** {@inheritDoc} */ @Override public final String toString() { StringBuffer sb = new StringBuffer(100); sb.append(identifierString()); sb.append(' '); sb.append(position); sb.append(": "); sb.append(opcode.getName()); boolean needComma = false; if (registers.size() != 0) { sb.append(registers.toHuman(" ", ", ", null)); needComma = true; } String extra = argString(); if (extra != null) { if (needComma) { sb.append(','); } sb.append(' '); sb.append(extra); } return sb.toString(); }
SourcePosition pos = insn.getPosition(); arr[at] = new PositionList.Entry(insn.getAddress(), pos); at++;
/** * Gets the instruction suffix required, if any, to use in a high * register transformed version of this instance. * * @see #hrVersion * * @return {@code null-ok;} the suffix, if any */ public DalvInsn hrSuffix() { if (hasResult()) { RegisterSpec r = registers.get(0); return makeMove(position, r, r.withReg(0)); } else { return null; } }
/** * Gets the size of this instance, in 16-bit code units. This will only * return a meaningful result if the instructions in this instance all * have valid addresses. * * @return {@code >= 0;} the size */ public int codeSize() { int sz = size(); if (sz == 0) { return 0; } DalvInsn last = get(sz - 1); return last.getNextAddress(); }
/** * Helper for {@link #add}, * which updates the position and local info flags. * * @param insn {@code non-null;} an instruction that was just introduced */ private void updateInfo(DalvInsn insn) { if (! hasAnyPositionInfo) { SourcePosition pos = insn.getPosition(); if (pos.getLine() >= 0) { hasAnyPositionInfo = true; } } if (! hasAnyLocalInfo) { if (hasLocalInfo(insn)) { hasAnyLocalInfo = true; } } }
int reserve= insn.getMinimumRegisterRequirement(); if (reserve > newReservedCount)
/** * Helper for {@link #finishProcessingAndGetList}, which extracts * the opcode out of each instruction into a separate array, to be * further manipulated as things progress. * * @return {@code non-null;} the array of opcodes */ private Dop[] makeOpcodesArray() { int size = insns.size(); Dop[] result = new Dop[size]; for (int i = 0; i < size; i++) { result[i] = insns.get(i).getOpcode(); } return result; }
/** * Returns whether the given instruction is part of the given catch block. */ private static boolean isInstructionInCatchRange(DalvInsn instruction, Entry catchEntry) { return instruction.getAddress() >= catchEntry.getStart() && instruction.getAddress() < catchEntry.getEnd(); }
/** {@inheritDoc} */ @Override public String insnArgString(DalvInsn insn) { return regRangeString(insn.getRegisters()) + ", " + insn.cstString(); }
/** * Gets the instruction prefix required, if any, to use in an expanded * version of this instance. Will not generate moves for registers * marked compatible to the format by the given BitSet. * * @see #expandedVersion * * @param compatRegs {@code non-null;} set of compatible registers * @return {@code null-ok;} the prefix, if any */ public DalvInsn expandedPrefix(BitSet compatRegs) { RegisterSpecList regs = registers; boolean firstBit = compatRegs.get(0); if (hasResult()) compatRegs.set(0); regs = regs.subset(compatRegs); if (hasResult()) compatRegs.set(0, firstBit); if (regs.size() == 0) return null; return new HighRegisterPrefix(position, regs); }
/** * Gets the instruction that is equivalent to this one, except that * it uses sequential registers starting at {@code 0} (storing * the result, if any, in register {@code 0} as well). * * @return {@code non-null;} the replacement */ public DalvInsn getLowRegVersion() { RegisterSpecList regs = registers.withExpandedRegisters(0, hasResult(), null); return withRegisters(regs); }
/** {@inheritDoc} */ @Override public final String toString() { StringBuilder sb = new StringBuilder(100); sb.append(identifierString()); sb.append(' '); sb.append(position); sb.append(": "); sb.append(opcode.getName()); boolean needComma = false; if (registers.size() != 0) { sb.append(registers.toHuman(" ", ", ", null)); needComma = true; } String extra = argString(); if (extra != null) { if (needComma) { sb.append(','); } sb.append(' '); sb.append(extra); } return sb.toString(); }
/** * Helper for {@link #assignAddressesAndFixBranches}, which * assigns an address to each instruction, in order. */ private void assignAddresses() { int address = 0; int size = insns.size(); for (int i = 0; i < size; i++) { DalvInsn insn = insns.get(i); insn.setAddress(address); address += insn.codeSize(); } }
SourcePosition pos = insn.getPosition(); arr[at] = new PositionList.Entry(insn.getAddress(), pos); at++;
/** * Gets the instruction suffix required, if any, to use in an expanded * version of this instance. Will not generate a move for a register * marked compatible to the format by the given BitSet. * * @see #expandedVersion * * @param compatRegs {@code non-null;} set of compatible registers * @return {@code null-ok;} the suffix, if any */ public DalvInsn expandedSuffix(BitSet compatRegs) { if (hasResult() && !compatRegs.get(0)) { RegisterSpec r = registers.get(0); return makeMove(position, r, r.withReg(0)); } else { return null; } }