@Override public void visitRestartLocal(int reg, DexLabel label) { out.s(".restart local %s", reg(reg)); } };
@Override public void visitStmt1R(Op op, int a) { out.s(op.displayName + " " + reg(a)); }
@Override public void visitEndLocal(int reg, DexLabel label) { out.s(".end local %s", reg(reg)); }
@Override public void visitFieldStmt(Op op, int a, int b, Field field) { if (op.format == InstructionFormat.kFmt22c) {// iget,iput out.s("%s %s, %s, %s", op.displayName, reg(a), reg(b), BaksmaliDumper.escapeField(field)); } else { out.s("%s %s, %s", op.displayName, reg(a), BaksmaliDumper.escapeField(field)); } }
@Override public void visitFillArrayDataStmt(Op op, int ra, Object array) { DexLabel dx = new DexLabel(); dx.displayName = "L" + nextLabelNumber++; usedLabel.add(dx); out.s("%s %s, %s", op.displayName, reg(ra), xLabel(dx)); appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, array)); }
@Override public void visitJumpStmt(Op op, int a, int b, DexLabel label) { if (op.format == InstructionFormat.kFmt21t || op.format == InstructionFormat.kFmt31t) { out.s(op.displayName + " " + reg(a) + ", " + xLabel(label)); } else if (op.format == InstructionFormat.kFmt22t) { out.s(op.displayName + " " + reg(a) + ", " + reg(b) + ", " + xLabel(label)); } else { out.s(op.displayName + " " + xLabel(label)); } }
@Override public void visitFilledNewArrayStmt(Op op, int[] args, String type) { if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %d .. %d }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), BaksmaliDumper.escapeType(type)); } else { StringBuilder buff = new StringBuilder(); boolean first = true; for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, BaksmaliDumper.escapeType(type)); } } else { out.s("%s { }, %s", op.displayName, BaksmaliDumper.escapeType(type)); } }
@Override public void visitMethodStmt(Op op, int[] args, String name, Proto proto, MethodHandle bsm, Object... bsmArgs) { StringBuilder sb = new StringBuilder(); sb.append("{ ").append( BaksmaliDumper.escapeValue(bsm)).append(", ").append(BaksmaliDumper.escapeValue(name)).append(", ").append(BaksmaliDumper.escapeMethodDesc(proto)); for(Object o: bsmArgs) { sb.append(", ").append(BaksmaliDumper.escapeValue(o)); } sb.append("}"); if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %s .. %s }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), sb); } else { boolean first = true; StringBuilder buff = new StringBuilder(); for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, sb); } } else { out.s("%s { }, %s", op.displayName, sb); } }
@Override public void visitMethodStmt(Op op, int[] args, Method method) { if (args.length > 0) { if (op.format == InstructionFormat.kFmt3rc) { // invoke-x/range out.s("%s { %s .. %s }, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), BaksmaliDumper.escapeMethod(method)); } else { boolean first = true; StringBuilder buff = new StringBuilder(); for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s", op.displayName, buff, BaksmaliDumper.escapeMethod(method)); } } else { out.s("%s { }, %s", op.displayName, BaksmaliDumper.escapeMethod(method)); } }
@Override public void visitPackedSwitchStmt(Op op, int ra, int first_case, DexLabel[] labels) { DexLabel dx = new DexLabel(); dx.displayName = "L" + nextLabelNumber++; usedLabel.add(dx); out.s(op.displayName + " " + reg(ra) + ", " + xLabel(dx)); appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new PackedSwitchStmt(first_case, labels))); }
@Override public void visitSparseSwitchStmt(Op op, int ra, int[] cases, DexLabel[] labels) { DexLabel dx = new DexLabel(); dx.displayName = "L" + nextLabelNumber++; usedLabel.add(dx); out.s(op.displayName + " " + reg(ra) + ", " + xLabel(dx)); appendLast.add(new AbstractMap.SimpleEntry<DexLabel, Object>(dx, new SparseSwitchStmt(cases, labels))); }
@Override public void visitStartLocal(int reg, DexLabel label, String name, String type, String signature) { super.visitStartLocal(reg, label, name, type, signature); if (signature == null) { out.s(".local %s, %s:%s", reg(reg), BaksmaliDumper.escapeValue(name), type); } else { out.s(".local %s, %s:%s, %s", reg(reg), BaksmaliDumper.escapeValue(name), type, BaksmaliDumper.escapeValue(signature)); } }
@Override public void visitMethodStmt(Op op, int[] args, Method method, Proto proto) { if (args.length > 0) { if (op.format == InstructionFormat.kFmt4rcc) { // invoke-x/range out.s("%s { %s .. %s }, %s, %s", op.displayName, reg(args[0]), reg(args[args.length - 1]), BaksmaliDumper.escapeMethod(method), BaksmaliDumper.escapeMethodDesc(proto)); } else { boolean first = true; StringBuilder buff = new StringBuilder(); for (int i : args) { if (first) { first = false; } else { buff.append(", "); } buff.append(reg(i)); } out.s("%s { %s }, %s, %s", op.displayName, buff, BaksmaliDumper.escapeMethod(method), BaksmaliDumper.escapeMethodDesc(proto)); } } else { out.s("%s { }, %s, %s", op.displayName, BaksmaliDumper.escapeMethod(method), BaksmaliDumper.escapeMethodDesc(proto)); } }
@SuppressWarnings("incomplete-switch") @Override public void visitConstStmt(Op op, int ra, Object value) { switch (op) { case CONST_WIDE_16: { Long v = (Long) value; value = (int) v.shortValue(); break; } case CONST_WIDE_HIGH16: { Long v = (Long) value; value = (int) ((short) (v >> 48)); break; } case CONST_WIDE_32: { Long v = (Long) value; value = (int) v.intValue(); break; } case CONST_HIGH16: { Integer v = (Integer) value; value = (int) v.intValue() >> 16; break; } } out.s("%s %s, %s", op.displayName, reg(ra), BaksmaliDumper.escapeValue(value)); super.visitConstStmt(op, ra, value); }