/*
* Copyright (c) 2009-2012 Panxiaobo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.googlecode.dex2jar.util;
import com.googlecode.dex2jar.DexLabel;
import com.googlecode.dex2jar.DexOpcodes;
import com.googlecode.dex2jar.Field;
import com.googlecode.dex2jar.Method;
import com.googlecode.dex2jar.visitors.OdexCodeVisitor;
/**
* @author <a href="mailto:pxb1988@gmail.com">Panxiaobo</a>
* @version $Rev$
*/
public class ASMifierCodeV implements OdexCodeVisitor, DexOpcodes {
Out m;
public ASMifierCodeV(Out m) {
this.m = m;
}
@Override
public void visitArrayStmt(int opcode, int formOrToReg, int arrayReg, int indexReg, int xt) {
m.s("code.visitArrayStmt(%s,%s,%s,%s,%s);", op(opcode), formOrToReg, arrayReg, indexReg, xt(xt));
}
@Override
public void visitBinopLitXStmt(int opcode, int distReg, int srcReg, int content) {
m.s("code.visitBinopLitXStmt(%s,%s,%s,%s);", op(opcode), distReg, srcReg, content);
}
@Override
public void visitBinopStmt(int opcode, int toReg, int r1, int r2, int xt) {
m.s("code.visitBinopStmt(%s,%s,%s,%s,%s);", op(opcode), toReg, r1, r2, xt(xt));
}
@Override
public void visitClassStmt(int opcode, int a, int b, String type) {
m.s("code.visitClassStmt(%s,%s,%s,%s);", op(opcode), a, b, Escape.v(type));
}
@Override
public void visitClassStmt(int opcode, int saveTo, String type) {
m.s("code.visitClassStmt(%s,%s,%s);", op(opcode), saveTo, Escape.v(type));
}
@Override
public void visitCmpStmt(int opcode, int distReg, int bB, int cC, int xt) {
m.s("code.visitCmpStmt(%s,%s,%s,%s,%s);", op(opcode), distReg, bB, cC, xt(xt));
}
@Override
public void visitConstStmt(int opcode, int toReg, Object value, int xt) {
if (value instanceof Integer) {
m.s("code.visitConstStmt(%s,%s,%s,%s); // int: 0x%08x float:%f", op(opcode), toReg, Escape.v(value),
xt(xt), value, Float.intBitsToFloat((Integer) value));
} else if (value instanceof Long) {
m.s("code.visitConstStmt(%s,%s,%s,%s); // long: 0x%016x double:%f", op(opcode), toReg, Escape.v(value),
xt(xt), value, Double.longBitsToDouble((Long) value));
} else {
m.s("code.visitConstStmt(%s,%s,%s,%s);", op(opcode), toReg, Escape.v(value), xt(xt));
}
}
@Override
public void visitFieldStmt(int opcode, int fromOrToReg, Field field, int xt) {
m.s("code.visitFieldStmt(%s,%s,%s,%s);", op(opcode), fromOrToReg, Escape.v(field), xt(xt));
}
@Override
public void visitFieldStmt(int opcode, int fromOrToReg, int objReg, Field field, int xt) {
m.s("code.visitFieldStmt(%s,%s,%s,%s,%s);", op(opcode), fromOrToReg, objReg, Escape.v(field), xt(xt));
}
@Override
public void visitFillArrayStmt(int opcode, int aA, int elemWidth, int initLength, Object[] values) {
m.s("code.visitFillArrayStmt(%s,%s,%s,%s,%s);", op(opcode), aA, elemWidth, initLength, Escape.v(values));
}
@Override
public void visitFilledNewArrayStmt(int opcode, int[] args, String type) {
m.s("code.visitFilledNewArrayStmt(%s,%s,%s);", op(opcode), Escape.v(args), Escape.v(type));
}
int i = 0;
public String v(DexLabel[] labels) {
StringBuilder sb = new StringBuilder("new DexLabel[]{");
boolean first = true;
for (DexLabel dexLabel : labels) {
if (first) {
first = false;
} else {
sb.append(",");
}
sb.append(v(dexLabel));
}
return sb.append("}").toString();
}
private Object v(DexLabel l) {
if (l.info == null) {
l.info = "L" + i++;
m.s("DexLabel %s=new DexLabel();", l.info);
}
return l.info;
}
String op(int op) {
return "OP_" + DexOpcodeDump.dump(op);
}
String xt(int vt) {
switch (vt) {
case 0:
return "TYPE_SINGLE";
case 1:
return "TYPE_WIDE";
case 2:
return "TYPE_OBJECT";
case 3:
return "TYPE_BOOLEAN";
case 4:
return "TYPE_BYTE";
case 5:
return "TYPE_CHAR";
case 6:
return "TYPE_SHORT";
case 7:
return "TYPE_INT";
case 8:
return "TYPE_FLOAT";
case 9:
return "TYPE_LONG";
case 10:
return "TYPE_DOUBLE";
default:
return Integer.toString(vt);
}
}
@Override
public void visitJumpStmt(int opcode, int a, int b, DexLabel label) {
m.s("code.visitJumpStmt(%s,%s,%s,%s);", op(opcode), a, b, v(label));
}
@Override
public void visitJumpStmt(int opcode, int reg, DexLabel label) {
m.s("code.visitJumpStmt(%s,%s,%s);", op(opcode), reg, v(label));
}
@Override
public void visitJumpStmt(int opcode, DexLabel label) {
m.s("code.visitJumpStmt(%s,%s);", op(opcode), v(label));
}
@Override
public void visitLookupSwitchStmt(int opcode, int aA, DexLabel label, int[] cases, DexLabel[] labels) {
m.s("code.visitLookupSwitchStmt(%s,%s,%s,%s,%s);", op(opcode), aA, v(label), Escape.v(cases), v(labels));
}
@Override
public void visitMethodStmt(int opcode, int[] args, Method method) {
m.s("code.visitMethodStmt(%s,%s,%s);", op(opcode), Escape.v(args), Escape.v(method));
}
@Override
public void visitMonitorStmt(int opcode, int reg) {
m.s("code.visitMonitorStmt(%s,%s);", op(opcode), reg);
}
@Override
public void visitMoveStmt(int opcode, int toReg, int xt) {
m.s("code.visitMoveStmt(%s,%s,%s);", op(opcode), toReg, xt(xt));
}
@Override
public void visitMoveStmt(int opcode, int toReg, int fromReg, int xt) {
m.s("code.visitMoveStmt(%s,%s,%s,%s);", op(opcode), toReg, fromReg, xt(xt));
}
@Override
public void visitReturnStmt(int opcode) {
m.s("code.visitReturnStmt(%s);", op(opcode));
}
@Override
public void visitReturnStmt(int opcode, int reg, int xt) {
m.s("code.visitReturnStmt(%s,%s,%s);", op(opcode), reg, xt(xt));
}
@Override
public void visitTableSwitchStmt(int opcode, int aA, DexLabel label, int first_case, int last_case,
DexLabel[] labels) {
m.s("code.visitTableSwitchStmt(%s,%s,%s,%s,%s,%s);", op(opcode), aA, v(label), first_case, last_case, v(labels));
}
@Override
public void visitUnopStmt(int opcode, int toReg, int fromReg, int xt) {
m.s("code.visitUnopStmt(%s,%s,%s,%s);", op(opcode), toReg, fromReg, xt(xt));
}
@Override
public void visitUnopStmt(int opcode, int toReg, int fromReg, int xta, int xtb) {
m.s("code.visitUnopStmt(%s,%s,%s,%s,%s);", op(opcode), toReg, fromReg, xt(xta), xt(xtb));
}
@Override
public void visitTryCatch(DexLabel start, DexLabel end, DexLabel[] handlers, String[] types) {
m.s("code.visitTryCatch(%s,%s,%s,%s);", v(start), v(end), v(handlers), Escape.v(types));
}
@Override
public void visitArguments(int total, int[] args) {
m.s("code.visitArguments(%s,%s);", total, Escape.v(args));
}
@Override
public void visitEnd() {
m.s("code.visitEnd();");
}
@Override
public void visitLabel(DexLabel label) {
m.s("code.visitLabel(%s);", v(label));
}
@Override
public void visitLineNumber(int line, DexLabel label) {
m.s("code.visitLineNumber(%s,%s);", line, v(label));
}
@Override
public void visitLocalVariable(String name, String type, String signature, DexLabel start, DexLabel end, int reg) {
m.s("code.visitLocalVariable(%s,%s,%s,%s,%s,%s);", Escape.v(name), Escape.v(type), Escape.v(signature),
v(start), v(end), reg);
}
@Override
public void visitReturnStmt(int opcode, int cause, Object ref) {
m.s("((OdexCodeVisitor)code).visitReturnStmt(%s,%s,%s);", op(opcode), cause, Escape.v(ref));
}
@Override
public void visitMethodStmt(int opcode, int[] args, int a) {
m.s("((OdexCodeVisitor)code).visitMethodStmt(%s,%s,%s);", op(opcode), Escape.v(args), a);
}
@Override
public void visitFieldStmt(int opcode, int fromOrToReg, int objReg, int fieldoff, int xt) {
m.s("((OdexCodeVisitor)code).visitFieldStmt(%s,%s,%s,%s,%s);", op(opcode), fromOrToReg, objReg, fieldoff,
xt(xt));
}
}