Use listIterator to manipulate bytecode Some bug fixes More use of TypeSignature, and prevent using of jode.type.Type git-svn-id: https://svn.code.sf.net/p/jode/code/trunk@1097 379699f6-c40d-0410-875b-85095c16579ebranch_1_1
parent
dcd5686bc2
commit
c3ead8b084
@ -1,262 +0,0 @@ |
|||||||
/* RemovePopAnalyzer Copyright (C) 1999 Jochen Hoenicke. |
|
||||||
* |
|
||||||
* This program is free software; you can redistribute it and/or modify |
|
||||||
* it under the terms of the GNU General Public License as published by |
|
||||||
* the Free Software Foundation; either version 2, or (at your option) |
|
||||||
* any later version. |
|
||||||
* |
|
||||||
* This program is distributed in the hope that it will be useful, |
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
||||||
* GNU General Public License for more details. |
|
||||||
* |
|
||||||
* You should have received a copy of the GNU General Public License |
|
||||||
* along with this program; see the file COPYING. If not, write to |
|
||||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
|
||||||
* |
|
||||||
* $Id$ |
|
||||||
*/ |
|
||||||
|
|
||||||
package jode.obfuscator; |
|
||||||
import jode.bytecode.*; |
|
||||||
import jode.AssertError; |
|
||||||
import jode.GlobalOptions; |
|
||||||
|
|
||||||
public class RemovePopAnalyzer implements CodeTransformer, Opcodes { |
|
||||||
public RemovePopAnalyzer() { |
|
||||||
} |
|
||||||
|
|
||||||
class PopInfo { |
|
||||||
int firstPop = 0; |
|
||||||
int[] pops; |
|
||||||
Instruction nextInstr; |
|
||||||
} |
|
||||||
|
|
||||||
static Instruction shrinkPop(Instruction popInstr, int amount) { |
|
||||||
int newPop = popInstr.getOpcode() - (opc_pop-1) - amount; |
|
||||||
if (newPop < 0) |
|
||||||
throw new jode.AssertError("pop1 on long or double"); |
|
||||||
if (newPop == 0) { |
|
||||||
Instruction nextInstr = popInstr.getNextByAddr(); |
|
||||||
popInstr.removeInstruction(); |
|
||||||
return nextInstr; |
|
||||||
} |
|
||||||
popInstr.replaceInstruction(opc_pop - 1 + newPop); |
|
||||||
return popInstr; |
|
||||||
} |
|
||||||
|
|
||||||
public void transformCode(BytecodeInfo bytecode) { |
|
||||||
int poppush[] = new int[2]; |
|
||||||
Instruction instr = bytecode.getFirstInstr(); |
|
||||||
while (instr != null) { |
|
||||||
switch (instr.getOpcode()) { |
|
||||||
case opc_nop: { |
|
||||||
Instruction nextInstr = instr.getNextByAddr(); |
|
||||||
instr.removeInstruction(); |
|
||||||
instr = nextInstr; |
|
||||||
continue; |
|
||||||
} |
|
||||||
case opc_pop: |
|
||||||
case opc_pop2: { |
|
||||||
/* find push instruction */ |
|
||||||
int count = 0; |
|
||||||
Instruction pushInstr = instr; |
|
||||||
while (true) { |
|
||||||
if (pushInstr.getPreds() != null) { |
|
||||||
pushInstr = null; |
|
||||||
break; |
|
||||||
} |
|
||||||
pushInstr = pushInstr.getPrevByAddr(); |
|
||||||
if (pushInstr == null |
|
||||||
|| pushInstr.getSuccs() != null |
|
||||||
|| pushInstr.doesAlwaysJump()) { |
|
||||||
pushInstr = null; |
|
||||||
break; |
|
||||||
} |
|
||||||
pushInstr.getStackPopPush(poppush); |
|
||||||
if (count < poppush[1]) |
|
||||||
break; |
|
||||||
count += poppush[0] - poppush[1]; |
|
||||||
} |
|
||||||
int opcode = pushInstr == null ? -1 : pushInstr.getOpcode(); |
|
||||||
|
|
||||||
if (count > 0) { |
|
||||||
/* If this is a dup and the instruction popped is the |
|
||||||
* duplicated element, remove the dup |
|
||||||
*/ |
|
||||||
if (count <= 2 && opcode == (opc_dup + count - 1)) { |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr = shrinkPop(instr, 1); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
if (instr.getOpcode() == opc_pop2 |
|
||||||
&& count > 1 && count <= 3 |
|
||||||
&& opcode == (opc_dup2 + count-2)) { |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr = shrinkPop(instr, 2); |
|
||||||
continue; |
|
||||||
} |
|
||||||
/* Otherwise popping is not possible */ |
|
||||||
opcode = -1; |
|
||||||
} |
|
||||||
switch (opcode) { |
|
||||||
case opc_ldc2_w: |
|
||||||
case opc_lload: case opc_dload: |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr = shrinkPop(instr, 2); |
|
||||||
continue; |
|
||||||
case opc_ldc: |
|
||||||
case opc_iload: case opc_fload: case opc_aload: |
|
||||||
case opc_dup: |
|
||||||
case opc_new: |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr = shrinkPop(instr, 1); |
|
||||||
continue; |
|
||||||
case opc_iaload: case opc_faload: case opc_aaload: |
|
||||||
case opc_baload: case opc_caload: case opc_saload: |
|
||||||
/* We have to pop one entry more. */ |
|
||||||
pushInstr.replaceInstruction(opc_pop); |
|
||||||
instr = pushInstr; |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_dup_x1: |
|
||||||
pushInstr.replaceInstruction(opc_swap); |
|
||||||
instr = shrinkPop(instr, 1); |
|
||||||
continue; |
|
||||||
case opc_dup2: |
|
||||||
if (instr.getOpcode() == opc_pop2) { |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr = shrinkPop(instr, 2); |
|
||||||
} |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_lneg: case opc_dneg: |
|
||||||
case opc_l2d: case opc_d2l: |
|
||||||
case opc_laload: case opc_daload: |
|
||||||
if (instr.getOpcode() != opc_pop2) |
|
||||||
break; |
|
||||||
/* fall through */ |
|
||||||
case opc_ineg: case opc_fneg: |
|
||||||
case opc_i2f: case opc_f2i: |
|
||||||
case opc_i2b: case opc_i2c: case opc_i2s: |
|
||||||
case opc_newarray: case opc_anewarray: |
|
||||||
case opc_arraylength: |
|
||||||
case opc_instanceof: |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_iadd: case opc_fadd: |
|
||||||
case opc_isub: case opc_fsub: |
|
||||||
case opc_imul: case opc_fmul: |
|
||||||
case opc_idiv: case opc_fdiv: |
|
||||||
case opc_irem: case opc_frem: |
|
||||||
case opc_iand: case opc_ior : case opc_ixor: |
|
||||||
case opc_ishl: case opc_ishr: case opc_iushr: |
|
||||||
case opc_fcmpl: case opc_fcmpg: |
|
||||||
case opc_l2i: case opc_l2f: |
|
||||||
case opc_d2i: case opc_d2f: |
|
||||||
pushInstr.replaceInstruction(opc_pop2); |
|
||||||
shrinkPop(instr, 1); |
|
||||||
instr = pushInstr; |
|
||||||
continue; |
|
||||||
case opc_ladd: case opc_dadd: |
|
||||||
case opc_lsub: case opc_dsub: |
|
||||||
case opc_lmul: case opc_dmul: |
|
||||||
case opc_ldiv: case opc_ddiv: |
|
||||||
case opc_lrem: case opc_drem: |
|
||||||
case opc_land: case opc_lor : case opc_lxor: |
|
||||||
if (instr.getOpcode() != opc_pop2) |
|
||||||
break; |
|
||||||
pushInstr.replaceInstruction(opc_pop2); |
|
||||||
instr = pushInstr; |
|
||||||
continue; |
|
||||||
case opc_lshl: case opc_lshr: case opc_lushr: |
|
||||||
if (instr.getOpcode() != opc_pop2) |
|
||||||
break; |
|
||||||
pushInstr.replaceInstruction(opc_pop); |
|
||||||
instr = pushInstr; |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_i2l: case opc_i2d: |
|
||||||
case opc_f2l: case opc_f2d: |
|
||||||
if (instr.getOpcode() != opc_pop2) |
|
||||||
break; |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
instr.replaceInstruction(opc_pop); |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_lcmp: |
|
||||||
case opc_dcmpl: case opc_dcmpg: |
|
||||||
pushInstr.replaceInstruction(opc_pop2); |
|
||||||
if (instr.getOpcode() == opc_pop) |
|
||||||
instr.replaceInstruction(opc_pop2); |
|
||||||
else { |
|
||||||
instr.appendInstruction(opc_pop); |
|
||||||
} |
|
||||||
instr = pushInstr; |
|
||||||
continue; |
|
||||||
|
|
||||||
case opc_getstatic: |
|
||||||
case opc_getfield: { |
|
||||||
Reference ref = pushInstr.getReference(); |
|
||||||
int size = TypeSignature.getTypeSize(ref.getType()); |
|
||||||
if (pushInstr.getOpcode() == opc_getfield) |
|
||||||
size--; |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
if (size > 0) |
|
||||||
instr = shrinkPop(instr, size); |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
case opc_multianewarray: { |
|
||||||
int dims = pushInstr.getIntData(); |
|
||||||
pushInstr.removeInstruction(); |
|
||||||
if (dims == 0) |
|
||||||
instr = shrinkPop(instr, 1); |
|
||||||
else { |
|
||||||
dims--; |
|
||||||
while (dims > 0) { |
|
||||||
instr = instr.insertInstruction(opc_pop); |
|
||||||
dims--; |
|
||||||
} |
|
||||||
} |
|
||||||
continue; |
|
||||||
} |
|
||||||
|
|
||||||
case opc_invokevirtual: |
|
||||||
case opc_invokespecial: |
|
||||||
case opc_invokestatic: |
|
||||||
case opc_invokeinterface: |
|
||||||
if (TypeSignature.getReturnSize |
|
||||||
(pushInstr.getReference().getType()) != 1) |
|
||||||
break; |
|
||||||
/* fall through */ |
|
||||||
case opc_checkcast: |
|
||||||
case -1: |
|
||||||
if (instr.getOpcode() == opc_pop2) { |
|
||||||
/* This is/may be a double pop on a single value |
|
||||||
* split it and continue with second half |
|
||||||
*/ |
|
||||||
instr.replaceInstruction(opc_pop); |
|
||||||
instr = instr.appendInstruction(opc_pop); |
|
||||||
continue; |
|
||||||
} |
|
||||||
} |
|
||||||
if (instr.getOpcode() == opc_pop |
|
||||||
&& instr.getPreds() == null |
|
||||||
&& instr.getPrevByAddr().getOpcode() == opc_pop) { |
|
||||||
/* merge two single pops together. */ |
|
||||||
instr.getPrevByAddr().removeInstruction(); |
|
||||||
instr.replaceInstruction(opc_pop2); |
|
||||||
} |
|
||||||
/* Cant do anything with this pop */ |
|
||||||
} |
|
||||||
/* fall through */ |
|
||||||
default: |
|
||||||
instr = instr.getNextByAddr(); |
|
||||||
continue; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
@ -0,0 +1,307 @@ |
|||||||
|
/* RemovePopAnalyzer Copyright (C) 1999 Jochen Hoenicke. |
||||||
|
* |
||||||
|
* This program is free software; you can redistribute it and/or modify |
||||||
|
* it under the terms of the GNU General Public License as published by |
||||||
|
* the Free Software Foundation; either version 2, or (at your option) |
||||||
|
* any later version. |
||||||
|
* |
||||||
|
* This program is distributed in the hope that it will be useful, |
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||||
|
* GNU General Public License for more details. |
||||||
|
* |
||||||
|
* You should have received a copy of the GNU General Public License |
||||||
|
* along with this program; see the file COPYING. If not, write to |
||||||
|
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. |
||||||
|
* |
||||||
|
* $Id$ |
||||||
|
*/ |
||||||
|
|
||||||
|
package jode.obfuscator; |
||||||
|
import jode.bytecode.*; |
||||||
|
import jode.AssertError; |
||||||
|
import jode.GlobalOptions; |
||||||
|
|
||||||
|
import @COLLECTIONS@.ListIterator; |
||||||
|
|
||||||
|
public class RemovePopAnalyzer implements CodeTransformer, Opcodes { |
||||||
|
public RemovePopAnalyzer() { |
||||||
|
} |
||||||
|
|
||||||
|
public void transformCode(BytecodeInfo bytecode) { |
||||||
|
int poppush[] = new int[2]; |
||||||
|
ListIterator iter = bytecode.getInstructions().listIterator(); |
||||||
|
next_pop: |
||||||
|
while (iter.hasNext()) { |
||||||
|
Instruction popInstr = (Instruction) iter.next(); |
||||||
|
boolean isPop2 = false; |
||||||
|
switch (popInstr.getOpcode()) { |
||||||
|
case opc_nop: { |
||||||
|
iter.remove(); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
case opc_pop2: |
||||||
|
isPop2 = true; |
||||||
|
case opc_pop: |
||||||
|
if (popInstr.getPreds() != null) |
||||||
|
// Can't handle pop with multiple predecessors
|
||||||
|
continue next_pop; |
||||||
|
Handler[] handlers = bytecode.getExceptionHandlers(); |
||||||
|
for (int i=0; i < handlers.length; i++) |
||||||
|
if (handlers[i].catcher == popInstr) |
||||||
|
continue next_pop; |
||||||
|
|
||||||
|
// remove pop, we will insert it again if something
|
||||||
|
// bad happened.
|
||||||
|
iter.remove(); |
||||||
|
|
||||||
|
// remember position of pop, so we can insert it again.
|
||||||
|
Instruction popPrevious = (Instruction) iter.previous(); |
||||||
|
Instruction instr = popPrevious; |
||||||
|
int count = 0; |
||||||
|
while (true) { |
||||||
|
if (instr.getSuccs() != null |
||||||
|
|| instr.doesAlwaysJump()) { |
||||||
|
instr = null; |
||||||
|
break; |
||||||
|
} |
||||||
|
instr.getStackPopPush(poppush); |
||||||
|
|
||||||
|
if (count < poppush[1]) { |
||||||
|
if (count == 0) |
||||||
|
break; |
||||||
|
|
||||||
|
int opcode = instr.getOpcode(); |
||||||
|
/* If this is a dup and the instruction popped is the |
||||||
|
* duplicated element, remove the dup and the pop |
||||||
|
*/ |
||||||
|
if (count <= 3 && opcode == (opc_dup + count - 1)) { |
||||||
|
iter.remove(); |
||||||
|
if (!isPop2) |
||||||
|
continue next_pop; |
||||||
|
|
||||||
|
// We have to consider a pop instead of a
|
||||||
|
// pop2 now.
|
||||||
|
popInstr = new Instruction(opc_pop); |
||||||
|
isPop2 = false; |
||||||
|
instr = (Instruction) iter.previous(); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
if (isPop2 |
||||||
|
&& count > 1 && count <= 4 |
||||||
|
&& opcode == (opc_dup2 + count-2)) { |
||||||
|
iter.remove(); |
||||||
|
continue next_pop; |
||||||
|
} |
||||||
|
/* Otherwise popping is not possible */ |
||||||
|
instr = null; |
||||||
|
break; |
||||||
|
} |
||||||
|
count += poppush[0] - poppush[1]; |
||||||
|
instr = (Instruction) iter.previous(); |
||||||
|
} |
||||||
|
|
||||||
|
if (instr == null) { |
||||||
|
// We insert the pop at the previous position
|
||||||
|
while (iter.next() != popPrevious) |
||||||
|
{} |
||||||
|
if (!isPop2 && popPrevious.getOpcode() == opc_pop) { |
||||||
|
// merge pop with popPrevious
|
||||||
|
iter.set(new Instruction(opc_pop2)); |
||||||
|
} else |
||||||
|
iter.add(popInstr); |
||||||
|
continue; |
||||||
|
} |
||||||
|
int opcode = instr.getOpcode(); |
||||||
|
switch (opcode) { |
||||||
|
case opc_ldc2_w: |
||||||
|
case opc_lload: case opc_dload: |
||||||
|
if (!isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
iter.remove(); |
||||||
|
continue; |
||||||
|
case opc_ldc: |
||||||
|
case opc_iload: case opc_fload: case opc_aload: |
||||||
|
case opc_dup: |
||||||
|
case opc_new: |
||||||
|
if (isPop2) |
||||||
|
iter.set(new Instruction(opc_pop)); |
||||||
|
else |
||||||
|
iter.remove(); |
||||||
|
continue; |
||||||
|
case opc_iaload: case opc_faload: case opc_aaload: |
||||||
|
case opc_baload: case opc_caload: case opc_saload: |
||||||
|
case opc_iadd: case opc_fadd: |
||||||
|
case opc_isub: case opc_fsub: |
||||||
|
case opc_imul: case opc_fmul: |
||||||
|
case opc_idiv: case opc_fdiv: |
||||||
|
case opc_irem: case opc_frem: |
||||||
|
case opc_iand: case opc_ior : case opc_ixor: |
||||||
|
case opc_ishl: case opc_ishr: case opc_iushr: |
||||||
|
case opc_fcmpl: case opc_fcmpg: |
||||||
|
/* We have to pop one entry more. */ |
||||||
|
iter.next(); |
||||||
|
iter.add(popInstr); |
||||||
|
iter.previous(); |
||||||
|
iter.previous(); |
||||||
|
iter.set(new Instruction(opc_pop)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_dup_x1: |
||||||
|
iter.set(new Instruction(opc_swap)); |
||||||
|
iter.next(); |
||||||
|
if (isPop2) |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_dup2: |
||||||
|
if (isPop2) { |
||||||
|
iter.remove(); |
||||||
|
continue; |
||||||
|
} |
||||||
|
break; |
||||||
|
case opc_swap: |
||||||
|
if (isPop2) { |
||||||
|
iter.set(popInstr); |
||||||
|
continue; |
||||||
|
} |
||||||
|
break; |
||||||
|
|
||||||
|
case opc_lneg: case opc_dneg: |
||||||
|
case opc_l2d: case opc_d2l: |
||||||
|
case opc_laload: case opc_daload: |
||||||
|
if (!isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
/* fall through */ |
||||||
|
case opc_ineg: case opc_fneg: |
||||||
|
case opc_i2f: case opc_f2i: |
||||||
|
case opc_i2b: case opc_i2c: case opc_i2s: |
||||||
|
case opc_newarray: case opc_anewarray: |
||||||
|
case opc_arraylength: |
||||||
|
case opc_instanceof: |
||||||
|
iter.set(popInstr); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_l2i: case opc_l2f: |
||||||
|
case opc_d2i: case opc_d2f: |
||||||
|
if (isPop2) { |
||||||
|
iter.next(); |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
iter.previous(); |
||||||
|
iter.previous(); |
||||||
|
} |
||||||
|
iter.set(new Instruction(opc_pop2)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_ladd: case opc_dadd: |
||||||
|
case opc_lsub: case opc_dsub: |
||||||
|
case opc_lmul: case opc_dmul: |
||||||
|
case opc_ldiv: case opc_ddiv: |
||||||
|
case opc_lrem: case opc_drem: |
||||||
|
case opc_land: case opc_lor : case opc_lxor: |
||||||
|
if (!isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
iter.next(); |
||||||
|
iter.add(popInstr); |
||||||
|
iter.previous(); |
||||||
|
iter.previous(); |
||||||
|
iter.set(new Instruction(opc_pop2)); |
||||||
|
continue; |
||||||
|
case opc_lshl: case opc_lshr: case opc_lushr: |
||||||
|
if (!isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
iter.next(); |
||||||
|
iter.add(popInstr); |
||||||
|
iter.previous(); |
||||||
|
iter.previous(); |
||||||
|
iter.set(new Instruction(opc_pop)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_i2l: case opc_i2d: |
||||||
|
case opc_f2l: case opc_f2d: |
||||||
|
if (!isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
iter.set(new Instruction(opc_pop)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_lcmp: |
||||||
|
case opc_dcmpl: case opc_dcmpg: |
||||||
|
iter.next(); |
||||||
|
iter.add(new Instruction(opc_pop2)); |
||||||
|
if (isPop2) { |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
iter.previous(); |
||||||
|
} |
||||||
|
iter.previous(); |
||||||
|
iter.previous(); |
||||||
|
iter.set(new Instruction(opc_pop2)); |
||||||
|
continue; |
||||||
|
|
||||||
|
case opc_getstatic: |
||||||
|
case opc_getfield: { |
||||||
|
Reference ref = instr.getReference(); |
||||||
|
int size = TypeSignature.getTypeSize(ref.getType()); |
||||||
|
if (size == 2 && !isPop2) |
||||||
|
throw new AssertError("pop on long"); |
||||||
|
if (opcode == opc_getfield) |
||||||
|
size--; |
||||||
|
switch (size) { |
||||||
|
case 0: |
||||||
|
iter.set(popInstr); |
||||||
|
break; |
||||||
|
case 1: |
||||||
|
if (isPop2) { |
||||||
|
iter.set(new Instruction(opc_pop)); |
||||||
|
break; |
||||||
|
} |
||||||
|
/* fall through */ |
||||||
|
case 2: |
||||||
|
iter.remove(); |
||||||
|
} |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
case opc_multianewarray: { |
||||||
|
int dims = instr.getDimensions(); |
||||||
|
if (--dims > 0) { |
||||||
|
iter.next(); |
||||||
|
while (dims-- > 0) { |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
iter.previous(); |
||||||
|
} |
||||||
|
iter.previous(); |
||||||
|
} |
||||||
|
iter.set(popInstr); |
||||||
|
continue; |
||||||
|
} |
||||||
|
|
||||||
|
case opc_invokevirtual: |
||||||
|
case opc_invokespecial: |
||||||
|
case opc_invokestatic: |
||||||
|
case opc_invokeinterface: |
||||||
|
if (TypeSignature.getReturnSize |
||||||
|
(instr.getReference().getType()) != 1) |
||||||
|
break; |
||||||
|
/* fall through */ |
||||||
|
case opc_checkcast: |
||||||
|
if (isPop2) { |
||||||
|
/* This is/may be a double pop on a single value |
||||||
|
* split it and continue with second half |
||||||
|
*/ |
||||||
|
iter.next(); |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
iter.add(new Instruction(opc_pop)); |
||||||
|
iter.previous(); |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
// append the pop behind the unresolvable opcode.
|
||||||
|
iter.next(); |
||||||
|
iter.add(popInstr); |
||||||
|
continue; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue