⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 removepopanalyzer.java

📁 Java Optimize and Decompile Environment 源代码
💻 JAVA
字号:
/* RemovePopAnalyzer Copyright (C) 1999-2002 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: RemovePopAnalyzer.java.in,v 1.1.2.1 2002/05/28 17:34:17 hoenicke Exp $ */package jode.obfuscator.modules;import jode.bytecode.*;import jode.obfuscator.*;import jode.AssertError;import jode.GlobalOptions;import java.util.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;	    }	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -