use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class J2IRConverter method dfs.
private void dfs(BitSet[] exBranch, BitSet handlers, BitSet access, Interpreter<JvmValue> interpreter) throws AnalyzerException {
currentEmit = preEmit;
JvmFrame first = initFirstFrame(methodNode, target);
if (parentCount[0] > 1) {
merge(first, 0);
} else {
frames[0] = first;
}
Stack<AbstractInsnNode> stack = new Stack<>();
stack.push(insnList.getFirst());
JvmFrame tmp = new JvmFrame(methodNode.maxLocals, methodNode.maxStack);
while (!stack.isEmpty()) {
AbstractInsnNode p = stack.pop();
int index = insnList.indexOf(p);
if (!access.get(index)) {
access.set(index);
} else {
continue;
}
JvmFrame frame = frames[index];
setCurrentEmit(index);
if (p.getType() == AbstractInsnNode.LABEL) {
emit(getLabel((LabelNode) p));
if (handlers.get(index)) {
Local ex = newLocal();
emit(Stmts.nIdentity(ex, Exprs.nExceptionRef("Ljava/lang/Throwable;")));
frame.clearStack();
frame.push(new JvmValue(1, ex));
}
}
BitSet ex = exBranch[index];
if (ex != null) {
for (int i = ex.nextSetBit(0); i >= 0; i = ex.nextSetBit(i + 1)) {
mergeEx(frame, i);
stack.push(insnList.get(i));
}
}
tmp.init(frame);
tmp.execute(p, interpreter);
int op = p.getOpcode();
if (p.getType() == AbstractInsnNode.JUMP_INSN) {
JumpInsnNode jump = (JumpInsnNode) p;
stack.push(jump.label);
merge(tmp, insnList.indexOf(jump.label));
}
if (op == Opcodes.TABLESWITCH || op == Opcodes.LOOKUPSWITCH) {
if (op == Opcodes.TABLESWITCH) {
TableSwitchInsnNode tsin = (TableSwitchInsnNode) p;
for (LabelNode label : tsin.labels) {
stack.push(label);
merge(tmp, insnList.indexOf(label));
}
stack.push(tsin.dflt);
merge(tmp, insnList.indexOf(tsin.dflt));
} else {
LookupSwitchInsnNode lsin = (LookupSwitchInsnNode) p;
for (LabelNode label : lsin.labels) {
stack.push(label);
merge(tmp, insnList.indexOf(label));
}
stack.push(lsin.dflt);
merge(tmp, insnList.indexOf(lsin.dflt));
}
}
if ((op >= Opcodes.GOTO && op <= Opcodes.RETURN) || op == Opcodes.ATHROW) {
// can't continue
} else {
stack.push(p.getNext());
merge(tmp, index + 1);
}
// cleanup frame it is useless
if (parentCount[index] <= 1) {
frames[index] = null;
}
}
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class J2IRConverter method buildInterpreter.
private Interpreter<JvmValue> buildInterpreter() {
return new Interpreter<JvmValue>(Opcodes.ASM4) {
@Override
public JvmValue newValue(Type type) {
return null;
}
@Override
public JvmValue newOperation(AbstractInsnNode insn) throws AnalyzerException {
switch(insn.getOpcode()) {
case ACONST_NULL:
return b(1, Exprs.nNull());
case ICONST_M1:
case ICONST_0:
case ICONST_1:
case ICONST_2:
case ICONST_3:
case ICONST_4:
case ICONST_5:
return b(1, Exprs.nInt(insn.getOpcode() - ICONST_0));
case LCONST_0:
case LCONST_1:
return b(2, Exprs.nLong(insn.getOpcode() - LCONST_0));
case FCONST_0:
case FCONST_1:
case FCONST_2:
return b(1, Exprs.nFloat(insn.getOpcode() - FCONST_0));
case DCONST_0:
case DCONST_1:
return b(2, Exprs.nDouble(insn.getOpcode() - DCONST_0));
case BIPUSH:
case SIPUSH:
return b(1, Exprs.nInt(((IntInsnNode) insn).operand));
case LDC:
Object cst = ((LdcInsnNode) insn).cst;
if (cst instanceof Integer) {
return b(1, Exprs.nInt((Integer) cst));
} else if (cst instanceof Float) {
return b(1, Exprs.nFloat((Float) cst));
} else if (cst instanceof Long) {
return b(2, Exprs.nLong((Long) cst));
} else if (cst instanceof Double) {
return b(2, Exprs.nDouble((Double) cst));
} else if (cst instanceof String) {
return b(1, Exprs.nString((String) cst));
} else if (cst instanceof Type) {
Type type = (Type) cst;
int sort = type.getSort();
if (sort == Type.OBJECT || sort == Type.ARRAY) {
return b(1, Exprs.nType(type.getDescriptor()));
} else if (sort == Type.METHOD) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
} else if (cst instanceof Handle) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
throw new IllegalArgumentException("Illegal LDC constant " + cst);
}
case JSR:
throw new UnsupportedOperationException("Not supported yet.");
case GETSTATIC:
FieldInsnNode fin = (FieldInsnNode) insn;
return b(Type.getType(fin.desc).getSize(), Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc));
case NEW:
return b(1, Exprs.nNew("L" + ((TypeInsnNode) insn).desc + ";"));
default:
throw new Error("Internal error.");
}
}
@Override
public JvmValue copyOperation(AbstractInsnNode insn, JvmValue value) throws AnalyzerException {
return b(value.getSize(), getLocal(value));
}
@Override
public JvmValue unaryOperation(AbstractInsnNode insn, JvmValue value0) throws AnalyzerException {
Local local = value0 == null ? null : getLocal(value0);
switch(insn.getOpcode()) {
case INEG:
return b(1, Exprs.nNeg(local, "I"));
case IINC:
return b(1, Exprs.nAdd(local, Exprs.nInt(((IincInsnNode) insn).incr), "I"));
case L2I:
return b(1, Exprs.nCast(local, "J", "I"));
case F2I:
return b(1, Exprs.nCast(local, "F", "I"));
case D2I:
return b(1, Exprs.nCast(local, "D", "I"));
case I2B:
return b(1, Exprs.nCast(local, "I", "B"));
case I2C:
return b(1, Exprs.nCast(local, "I", "C"));
case I2S:
return b(1, Exprs.nCast(local, "I", "S"));
case FNEG:
return b(1, Exprs.nNeg(local, "F"));
case I2F:
return b(1, Exprs.nCast(local, "I", "F"));
case L2F:
return b(1, Exprs.nCast(local, "J", "F"));
case D2F:
return b(1, Exprs.nCast(local, "D", "F"));
case LNEG:
return b(2, Exprs.nNeg(local, "J"));
case I2L:
return b(2, Exprs.nCast(local, "I", "J"));
case F2L:
return b(2, Exprs.nCast(local, "F", "J"));
case D2L:
return b(2, Exprs.nCast(local, "D", "J"));
case DNEG:
return b(2, Exprs.nNeg(local, "D"));
case I2D:
return b(2, Exprs.nCast(local, "I", "D"));
case L2D:
return b(2, Exprs.nCast(local, "J", "D"));
case F2D:
return b(2, Exprs.nCast(local, "F", "D"));
case IFEQ:
emit(Stmts.nIf(Exprs.nEq(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFNE:
emit(Stmts.nIf(Exprs.nNe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFLT:
emit(Stmts.nIf(Exprs.nLt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFGE:
emit(Stmts.nIf(Exprs.nGe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFGT:
emit(Stmts.nIf(Exprs.nGt(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFLE:
emit(Stmts.nIf(Exprs.nLe(local, Exprs.nInt(0), "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case TABLESWITCH:
{
TableSwitchInsnNode ts = (TableSwitchInsnNode) insn;
LabelStmt[] targets = new LabelStmt[ts.labels.size()];
for (int i = 0; i < ts.labels.size(); i++) {
targets[i] = getLabel((LabelNode) ts.labels.get(i));
}
emit(Stmts.nTableSwitch(local, ts.min, targets, getLabel(ts.dflt)));
return null;
}
case LOOKUPSWITCH:
{
LookupSwitchInsnNode ls = (LookupSwitchInsnNode) insn;
LabelStmt[] targets = new LabelStmt[ls.labels.size()];
int[] lookupValues = new int[ls.labels.size()];
for (int i = 0; i < ls.labels.size(); i++) {
targets[i] = getLabel((LabelNode) ls.labels.get(i));
lookupValues[i] = (Integer) ls.keys.get(i);
}
emit(Stmts.nLookupSwitch(local, lookupValues, targets, getLabel(ls.dflt)));
return null;
}
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
// skip, move to returnOperation
return null;
case PUTSTATIC:
{
FieldInsnNode fin = (FieldInsnNode) insn;
emit(Stmts.nAssign(Exprs.nStaticField("L" + fin.owner + ";", fin.name, fin.desc), local));
return null;
}
case GETFIELD:
{
FieldInsnNode fin = (FieldInsnNode) insn;
Type fieldType = Type.getType(fin.desc);
return b(fieldType.getSize(), Exprs.nField(local, "L" + fin.owner + ";", fin.name, fin.desc));
}
case NEWARRAY:
switch(((IntInsnNode) insn).operand) {
case T_BOOLEAN:
return b(1, Exprs.nNewArray("Z", local));
case T_CHAR:
return b(1, Exprs.nNewArray("C", local));
case T_BYTE:
return b(1, Exprs.nNewArray("B", local));
case T_SHORT:
return b(1, Exprs.nNewArray("S", local));
case T_INT:
return b(1, Exprs.nNewArray("I", local));
case T_FLOAT:
return b(1, Exprs.nNewArray("F", local));
case T_DOUBLE:
return b(1, Exprs.nNewArray("D", local));
case T_LONG:
return b(1, Exprs.nNewArray("D", local));
default:
throw new AnalyzerException(insn, "Invalid array type");
}
case ANEWARRAY:
String desc = "L" + ((TypeInsnNode) insn).desc + ";";
return b(1, Exprs.nNewArray(desc, local));
case ARRAYLENGTH:
return b(1, Exprs.nLength(local));
case ATHROW:
emit(Stmts.nThrow(local));
return null;
case CHECKCAST:
String orgDesc = ((TypeInsnNode) insn).desc;
desc = orgDesc.startsWith("[") ? orgDesc : ("L" + orgDesc + ";");
return b(1, Exprs.nCheckCast(local, desc));
case INSTANCEOF:
return b(1, Exprs.nInstanceOf(local, "L" + ((TypeInsnNode) insn).desc + ";"));
case MONITORENTER:
emit(Stmts.nLock(local));
return null;
case MONITOREXIT:
emit(Stmts.nUnLock(local));
return null;
case IFNULL:
emit(Stmts.nIf(Exprs.nEq(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IFNONNULL:
emit(Stmts.nIf(Exprs.nNe(local, Exprs.nNull(), "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case // special case
GOTO:
emit(Stmts.nGoto(getLabel(((JumpInsnNode) insn).label)));
return null;
default:
throw new Error("Internal error.");
}
}
JvmValue b(int size, com.googlecode.dex2jar.ir.expr.Value value) {
Local local = newLocal();
emit(Stmts.nAssign(local, value));
return new JvmValue(size, local);
}
@Override
public JvmValue binaryOperation(AbstractInsnNode insn, JvmValue value10, JvmValue value20) throws AnalyzerException {
Local local1 = getLocal(value10);
Local local2 = getLocal(value20);
switch(insn.getOpcode()) {
case IALOAD:
return b(1, Exprs.nArray(local1, local2, "I"));
case BALOAD:
return b(1, Exprs.nArray(local1, local2, "B"));
case CALOAD:
return b(1, Exprs.nArray(local1, local2, "C"));
case SALOAD:
return b(1, Exprs.nArray(local1, local2, "S"));
case FALOAD:
return b(1, Exprs.nArray(local1, local2, "F"));
case AALOAD:
return b(1, Exprs.nArray(local1, local2, "L"));
case DALOAD:
return b(1, Exprs.nArray(local1, local2, "D"));
case LALOAD:
return b(1, Exprs.nArray(local1, local2, "J"));
case IADD:
return b(1, Exprs.nAdd(local1, local2, "I"));
case ISUB:
return b(1, Exprs.nSub(local1, local2, "I"));
case IMUL:
return b(1, Exprs.nMul(local1, local2, "I"));
case IDIV:
return b(1, Exprs.nDiv(local1, local2, "I"));
case IREM:
return b(1, Exprs.nRem(local1, local2, "I"));
case ISHL:
return b(1, Exprs.nShl(local1, local2, "I"));
case ISHR:
return b(1, Exprs.nShr(local1, local2, "I"));
case IUSHR:
return b(1, Exprs.nUshr(local1, local2, "I"));
case IAND:
return b(1, Exprs.nAnd(local1, local2, "I"));
case IOR:
return b(1, Exprs.nOr(local1, local2, "I"));
case IXOR:
return b(1, Exprs.nXor(local1, local2, "I"));
case FADD:
return b(1, Exprs.nAdd(local1, local2, "F"));
case FSUB:
return b(1, Exprs.nSub(local1, local2, "F"));
case FMUL:
return b(1, Exprs.nMul(local1, local2, "F"));
case FDIV:
return b(1, Exprs.nDiv(local1, local2, "F"));
case FREM:
return b(1, Exprs.nRem(local1, local2, "F"));
case LADD:
return b(2, Exprs.nAdd(local1, local2, "J"));
case LSUB:
return b(2, Exprs.nSub(local1, local2, "J"));
case LMUL:
return b(2, Exprs.nMul(local1, local2, "J"));
case LDIV:
return b(2, Exprs.nDiv(local1, local2, "J"));
case LREM:
return b(2, Exprs.nRem(local1, local2, "J"));
case LSHL:
return b(2, Exprs.nShl(local1, local2, "J"));
case LSHR:
return b(2, Exprs.nShr(local1, local2, "J"));
case LUSHR:
return b(2, Exprs.nUshr(local1, local2, "J"));
case LAND:
return b(2, Exprs.nAnd(local1, local2, "J"));
case LOR:
return b(2, Exprs.nOr(local1, local2, "J"));
case LXOR:
return b(2, Exprs.nXor(local1, local2, "J"));
case DADD:
return b(2, Exprs.nAdd(local1, local2, "D"));
case DSUB:
return b(2, Exprs.nSub(local1, local2, "D"));
case DMUL:
return b(2, Exprs.nMul(local1, local2, "D"));
case DDIV:
return b(2, Exprs.nDiv(local1, local2, "D"));
case DREM:
return b(2, Exprs.nRem(local1, local2, "D"));
case LCMP:
return b(2, Exprs.nLCmp(local1, local2));
case FCMPL:
return b(1, Exprs.nFCmpl(local1, local2));
case FCMPG:
return b(1, Exprs.nFCmpg(local1, local2));
case DCMPL:
return b(2, Exprs.nDCmpl(local1, local2));
case DCMPG:
return b(2, Exprs.nDCmpg(local1, local2));
case IF_ICMPEQ:
emit(Stmts.nIf(Exprs.nEq(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPNE:
emit(Stmts.nIf(Exprs.nNe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPLT:
emit(Stmts.nIf(Exprs.nLt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPGE:
emit(Stmts.nIf(Exprs.nGe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPGT:
emit(Stmts.nIf(Exprs.nGt(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ICMPLE:
emit(Stmts.nIf(Exprs.nLe(local1, local2, "I"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ACMPEQ:
emit(Stmts.nIf(Exprs.nEq(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case IF_ACMPNE:
emit(Stmts.nIf(Exprs.nNe(local1, local2, "L"), getLabel(((JumpInsnNode) insn).label)));
return null;
case PUTFIELD:
FieldInsnNode fin = (FieldInsnNode) insn;
emit(Stmts.nAssign(Exprs.nField(local1, "L" + fin.owner + ";", fin.name, fin.desc), local2));
return null;
default:
throw new Error("Internal error.");
}
}
@Override
public JvmValue ternaryOperation(AbstractInsnNode insn, JvmValue value1, JvmValue value2, JvmValue value3) throws AnalyzerException {
Local local1 = getLocal(value1);
Local local2 = getLocal(value2);
Local local3 = getLocal(value3);
switch(insn.getOpcode()) {
case IASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "I"), local3));
break;
case LASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "J"), local3));
break;
case FASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "F"), local3));
break;
case DASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "D"), local3));
break;
case AASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "L"), local3));
break;
case BASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "B"), local3));
break;
case CASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "C"), local3));
break;
case SASTORE:
emit(Stmts.nAssign(Exprs.nArray(local1, local2, "S"), local3));
break;
}
return null;
}
public String[] toDescArray(Type[] ts) {
String[] ds = new String[ts.length];
for (int i = 0; i < ts.length; i++) {
ds[i] = ts[i].getDescriptor();
}
return ds;
}
@Override
public JvmValue naryOperation(AbstractInsnNode insn, List<? extends JvmValue> xvalues) throws AnalyzerException {
com.googlecode.dex2jar.ir.expr.Value[] values = new com.googlecode.dex2jar.ir.expr.Value[xvalues.size()];
for (int i = 0; i < xvalues.size(); i++) {
values[i] = getLocal(xvalues.get(i));
}
if (insn.getOpcode() == MULTIANEWARRAY) {
throw new UnsupportedOperationException("Not supported yet.");
} else {
MethodInsnNode mi = (MethodInsnNode) insn;
com.googlecode.dex2jar.ir.expr.Value v = null;
String ret = Type.getReturnType(mi.desc).getDescriptor();
String owner = "L" + mi.owner + ";";
String[] ps = toDescArray(Type.getArgumentTypes(mi.desc));
switch(insn.getOpcode()) {
case INVOKEVIRTUAL:
v = Exprs.nInvokeVirtual(values, owner, mi.name, ps, ret);
break;
case INVOKESPECIAL:
v = Exprs.nInvokeSpecial(values, owner, mi.name, ps, ret);
break;
case INVOKESTATIC:
v = Exprs.nInvokeStatic(values, owner, mi.name, ps, ret);
break;
case INVOKEINTERFACE:
v = Exprs.nInvokeInterface(values, owner, mi.name, ps, ret);
break;
case INVOKEDYNAMIC:
throw new UnsupportedOperationException("Not supported yet.");
}
if ("V".equals(ret)) {
emit(Stmts.nVoidInvoke(v));
return null;
} else {
return b(Type.getReturnType(mi.desc).getSize(), v);
}
}
}
@Override
public JvmValue merge(JvmValue v, JvmValue w) {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void returnOperation(AbstractInsnNode insn, JvmValue value, JvmValue expected) throws AnalyzerException {
switch(insn.getOpcode()) {
case IRETURN:
case LRETURN:
case FRETURN:
case DRETURN:
case ARETURN:
emit(Stmts.nReturn(getLocal(value)));
break;
case RETURN:
emit(Stmts.nReturnVoid());
break;
}
}
};
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class Dex2IrAdapter method visitMethodStmt.
@Override
public void visitMethodStmt(Op op, int[] args, Method method) {
Value[] vs;
if (args.length > 0) {
int i = 0;
List<Local> ps = new ArrayList<Local>(args.length);
if (op == Op.INVOKE_STATIC || op == Op.INVOKE_STATIC_RANGE) {
;
} else {
ps.add(locals[args[i]]);
i++;
}
for (String t : method.getParameterTypes()) {
ps.add(locals[args[i]]);
if (t.equals("J") || t.equals("D")) {
i += 2;
} else {
i++;
}
}
vs = ps.toArray(new Value[ps.size()]);
} else {
vs = new Value[0];
}
Value invoke = null;
switch(op) {
case INVOKE_VIRTUAL_RANGE:
case INVOKE_VIRTUAL:
invoke = nInvokeVirtual(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
break;
case INVOKE_SUPER_RANGE:
case INVOKE_DIRECT_RANGE:
case INVOKE_SUPER:
case INVOKE_DIRECT:
invoke = nInvokeSpecial(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
break;
case INVOKE_STATIC_RANGE:
case INVOKE_STATIC:
invoke = nInvokeStatic(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
break;
case INVOKE_INTERFACE_RANGE:
case INVOKE_INTERFACE:
invoke = nInvokeInterface(vs, method.getOwner(), method.getName(), method.getParameterTypes(), method.getReturnType());
break;
default:
throw new RuntimeException();
}
if ("V".equals(method.getReturnType())) {
x(nVoidInvoke(invoke));
} else {
x(nAssign(tmpLocal, invoke));
}
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class Dex2IrAdapter method visitFilledNewArrayStmt.
@Override
public void visitFilledNewArrayStmt(Op opc, int[] args, String type) {
Local array = tmpLocal;
String elem = type.substring(1);
list.add(nAssign(array, nNewArray(elem, nInt(args.length))));
for (int i = 0; i < args.length; i++) {
list.add(nAssign(nArray(array, nInt(i), elem), locals[args[i]]));
}
}
use of com.googlecode.dex2jar.ir.expr.Local in project dex2jar by pxb1988.
the class Dex2IrAdapter method visitStmt1R.
@Override
public void visitStmt1R(Op op, int reg) {
Local va = locals[reg];
switch(op) {
case MONITOR_ENTER:
x(nLock(va));
break;
case MONITOR_EXIT:
x(nUnLock(va));
break;
case RETURN:
case RETURN_WIDE:
case RETURN_OBJECT:
x(nReturn(va));
break;
case THROW:
x(nThrow(va));
break;
case MOVE_RESULT:
case MOVE_RESULT_WIDE:
case MOVE_RESULT_OBJECT:
if (lastIsInvokeOrFilledNewArray) {
// right position
x(nAssign(va, tmpLocal));
} else {
// wrong position, replace with throw new RuntimeExceptoin("...");
System.err.println("WARN: find wrong position of " + op + " in method " + method);
x(nThrow(nInvokeNew(new Value[] { nString("d2j: wrong position of " + op) }, new String[] { "Ljava/lang/String;" }, "Ljava/lang/RuntimeException;")));
}
break;
case MOVE_EXCEPTION:
x(nIdentity(va, nExceptionRef("Ljava/lang/Throwable;")));
break;
default:
throw new RuntimeException();
}
}
Aggregations