/** * Gets the {@link Dop} with the given family/format combination, if * any. * * @param family {@code DalvOps.MIN_VALUE..DalvOps.MAX_VALUE;} the opcode family * @param format {@code non-null;} the opcode's instruction format * @return {@code null-ok;} the corresponding opcode, or {@code null} if * there is none */ public static Dop getOrNull(int family, InsnFormat format) { if (format == null) { throw new NullPointerException("format == null"); } int len = DOPS.length; // TODO: Linear search is bad. for (int i = 0; i < len; i++) { Dop dop = DOPS[i]; if ((dop != null) && (dop.getFamily() == family) && (dop.getFormat() == format)) { return dop; } } return null; }
/** {@inheritDoc} */ @Override public String toString() { return getName(); }
/** * Puts the given opcode into the table of all ops. * * @param opcode {@code non-null;} the opcode */ private static void set(Dop opcode) { int idx = opcode.getOpcode() - Opcodes.MIN_VALUE; DOPS[idx] = opcode; } }
/** {@inheritDoc} */ @Override public final void writeTo(AnnotatedOutput out) { getOpcode().getFormat().writeTo(out, this); }
/** * Returns whether this instance's opcode uses a result register. * This method is a convenient shorthand for * {@code getOpcode().hasResult()}. * * @return {@code true} iff this opcode uses a result register */ public final boolean hasResult() { return opcode.hasResult(); }
CstBaseMethodRef methodRef = (CstBaseMethodRef) cst; boolean isStatic = (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC); count = methodRef.getParameterWordCount(isStatic); if (insn.getOpcode().getFamily() != Opcodes.INVOKE_POLYMORPHIC) { throw new RuntimeException("Expecting invoke-polymorphic");
/** * Returns an instance that is just like this one, except that its * opcode has the opposite sense (as a test; e.g. a * {@code lt} test becomes a {@code ge}), and its branch * target is replaced by the one given, and all set-once values * associated with the class (such as its address) are reset. * * @param target {@code non-null;} the new branch target * @return {@code non-null;} an appropriately-constructed instance */ public TargetInsn withNewTargetAndReversed(CodeAddress target) { Dop opcode = getOpcode().getOppositeTest(); return new TargetInsn(opcode, getPosition(), getRegisters(), target); }
/** * Gets the next {@link Dop} in the instruction fitting chain after the * given instance, if any. * * @param opcode {@code non-null;} the opcode * @param options {@code non-null;} options, used to determine * which opcodes are potentially off-limits * @return {@code null-ok;} the next opcode in the same family, in the * chain of opcodes to try, or {@code null} if the given opcode is * the last in its chain */ public static Dop getNextOrNull(Dop opcode, DexOptions options) { int nextOpcode = opcode.getNextOpcode(); if (nextOpcode == Opcodes.NO_NEXT) { return null; } opcode = get(nextOpcode); return opcode; }
/** {@inheritDoc} */ @Override public final int codeSize() { return getOpcode().getFormat().codeSize(); }
/** * Returns whether this instance's opcode uses a result register. * This method is a convenient shorthand for * {@code getOpcode().hasResult()}. * * @return {@code true} iff this opcode uses a result register */ public final boolean hasResult() { return opcode.hasResult(); }
/** * Gets the size of the outgoing arguments area required by this * method. This is equal to the largest argument word count of any * method referred to by this instance. * * @return {@code >= 0;} the required outgoing arguments size */ public int getOutsSize() { int sz = size(); int result = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); if (!(insn instanceof CstInsn)) { continue; } Constant cst = ((CstInsn) insn).getConstant(); if (!(cst instanceof CstBaseMethodRef)) { continue; } boolean isStatic = (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC); int count = ((CstBaseMethodRef) cst).getParameterWordCount(isStatic); if (count > result) { result = count; } } return result; }
/** * Returns an instance that is just like this one, except that its * opcode has the opposite sense (as a test; e.g. a * {@code lt} test becomes a {@code ge}), and its branch * target is replaced by the one given, and all set-once values * associated with the class (such as its address) are reset. * * @param target {@code non-null;} the new branch target * @return {@code non-null;} an appropriately-constructed instance */ public TargetInsn withNewTargetAndReversed(CodeAddress target) { Dop opcode = getOpcode().getOppositeTest(); return new TargetInsn(opcode, getPosition(), getRegisters(), target); }
/** * Gets the next {@link Dop} in the instruction fitting chain after the * given instance, if any. * * @param opcode {@code non-null;} the opcode * @param options {@code non-null;} options, used to determine * which opcodes are potentially off-limits * @return {@code null-ok;} the next opcode in the same family, in the * chain of opcodes to try, or {@code null} if the given opcode is * the last in its chain */ public static Dop getNextOrNull(Dop opcode, DexOptions options) { int nextOpcode = opcode.getNextOpcode(); if (nextOpcode == Opcodes.NO_NEXT) { return null; } opcode = get(nextOpcode); return opcode; }
/** {@inheritDoc} */ @Override protected final String listingString0(boolean noteIndices) { return getOpcode().getFormat().listingString(this, noteIndices); } }
/** {@inheritDoc} */ @Override public String toString() { return getName(); }
/** * Puts the given opcode into the table of all ops. * * @param opcode {@code non-null;} the opcode */ private static void set(Dop opcode) { int idx = opcode.getOpcode() - Opcodes.MIN_VALUE; DOPS[idx] = opcode; } }
/** * Returns whether this instance's opcode uses a result register. * This method is a convenient shorthand for * {@code getOpcode().hasResult()}. * * @return {@code true} iff this opcode uses a result register */ public final boolean hasResult() { return opcode.hasResult(); }
/** * Gets the size of the outgoing arguments area required by this * method. This is equal to the largest argument word count of any * method referred to by this instance. * * @return {@code >= 0;} the required outgoing arguments size */ public int getOutsSize() { int sz = size(); int result = 0; for (int i = 0; i < sz; i++) { DalvInsn insn = (DalvInsn) get0(i); if (!(insn instanceof CstInsn)) { continue; } Constant cst = ((CstInsn) insn).getConstant(); if (!(cst instanceof CstBaseMethodRef)) { continue; } boolean isStatic = (insn.getOpcode().getFamily() == Opcodes.INVOKE_STATIC); int count = ((CstBaseMethodRef) cst).getParameterWordCount(isStatic); if (count > result) { result = count; } } return result; }