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

📄 constantanalyzer.java

📁 Java Optimize and Decompile Environment 源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	    ConstValue[] argValues = new ConstValue[paramTypes.length];	    for (int i = paramTypes.length - 1; i >= 0; i--) {		size += TypeSignature.getTypeSize(paramTypes[i]);		Object value = (argValues[i] = info.getStack(size)).value;		if (value != ConstValue.VOLATILE)		    args[i] = value;		else		    constant = false;	    }	    	    if (opcode != opc_invokestatic) {		size++;		clsValue = info.getStack(size);		cls = clsValue.value;		if (cls == ConstValue.VOLATILE || cls == null)		    constant = false;	    }	    String retType = TypeSignature.getReturnType(ref.getType());	    if (retType.equals("V")) {		handleReference(ref, opcode == opc_invokevirtual 				|| opcode == opc_invokeinterface);		mergeInfo(instr.getNextByAddr(), info.pop(size));		break;	    }	    if (constant && !runtime.isWhite(retType)) {		/* This is not a valid constant type */		constant = false;	    }	    Object methodResult = null;	    if (constant) {		try {		    methodResult = runtime.invokeMethod			(ref, opcode != opc_invokespecial, cls, args);		} catch (InterpreterException ex) {		    constant = false;		    if (jode.GlobalOptions.verboseLevel > 3)			GlobalOptions.err.println("Can't interpret "+ref+": "						  + ex.getMessage());		    /* result is not constant */		} catch (InvocationTargetException ex) {		    constant = false;		    if (jode.GlobalOptions.verboseLevel > 3)			GlobalOptions.err.println("Method "+ref						  +" throwed exception: "						  + ex.getTargetException());		    /* method always throws exception ? */		}	    }	    ConstValue returnVal;	    if (!constant) {		handleReference(ref, opcode == opc_invokevirtual 				|| opcode == opc_invokeinterface);		int retsize = TypeSignature.getTypeSize(retType);		returnVal = unknownValue[retsize - 1];	    } else {		info.constInfo = new ConstantInfo(CONSTANT, methodResult);		returnVal = new ConstValue(methodResult);		returnVal.addConstantListener(info.constInfo);		if (clsValue != null)		    clsValue.addConstantListener(returnVal);		for (int i=0; i< argValues.length; i++)		    argValues[i].addConstantListener(returnVal);	    }	    mergeInfo(instr.getNextByAddr(), info.poppush(size, returnVal));	    break;	}        case opc_new: {	    handleClass(instr.getClazzType());	    mergeInfo(instr.getNextByAddr(), info.poppush(0, unknownValue[0]));	    break;        }        case opc_arraylength: {//  	    ConstValue array = info.getStack(1);//  	    if (array.value != ConstValue.VOLATILE//  		&& array.value != null) {//  		Integer newValue = new Integer(Array.getLength(array.value));//  		info.constInfo = new ConstantInfo(CONSTANT, newValue);//  		result = new ConstValue(newValue);//  		result.addConstantListener(info.constInfo);//  		array.addConstantListener(result);//  	    } else	    result = unknownValue[0];	    mergeInfo(instr.getNextByAddr(), info.poppush(1, result));	    break;	}        case opc_checkcast: {	    handleClass(instr.getClazzType());	    mergeInfo(instr.getNextByAddr(), info.pop(0));	    break;        }        case opc_instanceof: {	    handleClass(instr.getClazzType());	    mergeInfo(instr.getNextByAddr(), info.poppush(1, unknownValue[0]));	    break;        }        case opc_monitorenter:        case opc_monitorexit:	    mergeInfo(instr.getNextByAddr(), info.pop(1));	    break;        case opc_multianewarray:	    handleClass(instr.getClazzType());	    mergeInfo(instr.getNextByAddr(), 		      info.poppush(instr.getDimensions(), unknownValue[0]));	    break;        default:            throw new IllegalArgumentException("Invalid opcode "+opcode);        }    }    public void fieldNotConstant(FieldIdentifier fi) {	for (Iterator iter = bytecode.getInstructions().iterator(); 	     iter.hasNext(); ) {	    Instruction instr = (Instruction) iter.next();	    if (instr.getOpcode() == opc_getfield		|| instr.getOpcode() == opc_getstatic) {		Reference ref = instr.getReference();		if (ref.getName().equals(fi.getName())		    && ref.getType().equals(fi.getType())		    && instr.getTmpInfo() != null) {		    ((StackLocalInfo) instr.getTmpInfo()).enqueue();		}	    }	}    }    public void dumpStackLocalInfo() {	for (Iterator iter = bytecode.getInstructions().iterator(); 	     iter.hasNext(); ) {	    Instruction instr = (Instruction) iter.next();	    System.err.println(""+instr.getTmpInfo());	    System.err.println(instr.getDescription());	}    }    public void analyzeCode(MethodIdentifier methodIdent, 			    BytecodeInfo bytecode) {	this.bytecode = bytecode;	TodoQueue modifiedQueue = new TodoQueue();	MethodInfo minfo = bytecode.getMethodInfo();	for (Iterator iter = bytecode.getInstructions().iterator(); 	     iter.hasNext(); ) {	    Instruction instr = (Instruction) iter.next();	    instr.setTmpInfo(null);	}	StackLocalInfo firstInfo = new StackLocalInfo 	    (bytecode.getMaxLocals(), minfo.isStatic(), minfo.getType(), 	     modifiedQueue);	firstInfo.instr = (Instruction) bytecode.getInstructions().get(0);	firstInfo.instr.setTmpInfo(firstInfo);	firstInfo.enqueue();	runtime.setFieldListener(methodIdent);	while (modifiedQueue.first != null) {	    StackLocalInfo info = modifiedQueue.first;	    modifiedQueue.first = info.nextOnQueue;	    info.nextOnQueue = null;	    handleOpcode(info, methodIdent);	}	runtime.setFieldListener(null);	Handler[] handlers = bytecode.getExceptionHandlers();	for (int i=0; i< handlers.length; i++) {	    if (handlers[i].catcher.getTmpInfo() != null 		&& handlers[i].type != null)		Main.getClassBundle().reachableClass(handlers[i].type);	}	for (Iterator iter = bytecode.getInstructions().iterator(); 	     iter.hasNext(); ) {	    Instruction instr = (Instruction) iter.next();	    StackLocalInfo info = (StackLocalInfo) instr.getTmpInfo();	    if (info != null) {		if (info.constInfo.flags == 0)		    instr.setTmpInfo(unknownConstInfo);		else		    instr.setTmpInfo(info.constInfo);	    }	}    }    public static void replaceWith(ListIterator iter, Instruction instr,				   Instruction replacement) {	switch(instr.getOpcode()) {	case opc_goto:        case opc_ldc:        case opc_ldc2_w:        case opc_iload: case opc_lload:         case opc_fload: case opc_dload: case opc_aload:	case opc_getstatic:	    if (replacement == null)		iter.remove();	    else		iter.set(replacement);	    return;	case opc_ifeq: case opc_ifne: 	case opc_iflt: case opc_ifge: 	case opc_ifgt: case opc_ifle:	case opc_ifnull: case opc_ifnonnull:	case opc_arraylength:	case opc_getfield:        case opc_i2l: case opc_i2f: case opc_i2d:        case opc_f2i: case opc_f2l: case opc_f2d:        case opc_i2b: case opc_i2c: case opc_i2s:        case opc_ineg: case opc_fneg: 	    iter.set(new Instruction(opc_pop));	    break;	case opc_lcmp: 	case opc_dcmpg: case opc_dcmpl:         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:	    iter.set(new Instruction(opc_pop2));	    iter.add(new Instruction(opc_pop2));	    break;	case opc_if_icmpeq: case opc_if_icmpne:	case opc_if_icmplt: case opc_if_icmpge: 	case opc_if_icmpgt: case opc_if_icmple: 	case opc_if_acmpeq: case opc_if_acmpne:	case opc_fcmpg: case opc_fcmpl:        case opc_l2i: case opc_l2f: case opc_l2d:        case opc_d2i: case opc_d2l: case opc_d2f:	case opc_lneg: case opc_dneg:        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_iaload: case opc_laload:         case opc_faload: case opc_daload: case opc_aaload:        case opc_baload: case opc_caload: case opc_saload:	    iter.set(new Instruction(opc_pop2));	    break;	case opc_lshl: case opc_lshr: case opc_lushr:	    iter.set(new Instruction(opc_pop));	    iter.add(new Instruction(opc_pop2));	    break;	case opc_putstatic:	case opc_putfield:	    if (TypeSignature		.getTypeSize(instr.getReference().getType()) == 2) {		iter.set(new Instruction(opc_pop2));		if (instr.getOpcode() == opc_putfield)		    iter.add(new Instruction(opc_pop));	    } else		iter.set(new Instruction(instr.getOpcode() == opc_putfield					 ? opc_pop2 : opc_pop));	    break;	case opc_invokespecial:	case opc_invokestatic:	case opc_invokeinterface:	case opc_invokevirtual: {	    Reference ref = instr.getReference();	    String[] pt = TypeSignature.getParameterTypes(ref.getType());	    int len = pt.length;	    if (len > 0) {		iter.set(new Instruction(TypeSignature.getTypeSize(pt[--len])					 + opc_pop - 1));		for (int i = len - 1; i >= 0; i--)		    iter.add(new Instruction(TypeSignature.getTypeSize(pt[i])					     + opc_pop - 1));		if (instr.getOpcode() != opc_invokestatic)		    iter.add(new Instruction(opc_pop));	    } else if (instr.getOpcode() != opc_invokestatic) {		iter.set(new Instruction(opc_pop));	    } else {		if (replacement == null)		    iter.remove();		else		    iter.set(replacement);		return;	    }	    	}	}	if (replacement != null)	    iter.add(replacement);    }        public void appendJump(ListIterator iter, Instruction dest) {	/* Add a goto instruction after this opcode. */	Instruction gotoInstr = new Instruction(Instruction.opc_goto);	gotoInstr.setSuccs(dest);	iter.add(gotoInstr);    }        public void transformCode(BytecodeInfo bytecode) {	for (ListIterator iter = bytecode.getInstructions().listIterator();	     iter.hasNext(); ) {	    Instruction instr = (Instruction) iter.next();	    ConstantInfo info = (ConstantInfo) instr.getTmpInfo();	    instr.setTmpInfo(null);	    if (info == null		|| (info.flags & (RETURNINGJSR | RETASTORE)) == RETASTORE) {		/* This instruction can't be reached logically, or		 * it is a return value astore, that should be removed */		iter.remove();	    } else if ((info.flags & CONSTANT) != 0) {		if (instr.getOpcode() > opc_ldc2_w) {		    Instruction ldcInstr			= new Instruction(info.constant instanceof Long					  || info.constant instanceof Double					  ? opc_ldc2_w : opc_ldc);		    ldcInstr.setConstant(info.constant);		    replaceWith(iter, instr, ldcInstr);		    if (GlobalOptions.verboseLevel > 2)			GlobalOptions.err.println			    (bytecode + ": Replacing " + instr			     + " with constant " + info.constant);		}	    } else if ((info.flags & CONSTANTFLOW) != 0) {		Instruction pc = (Instruction) info.constant;		if (instr.getOpcode() >= opc_if_icmpeq		    && instr.getOpcode() <= opc_if_acmpne)		    iter.set(new Instruction(opc_pop2));		else		    iter.set(new Instruction(opc_pop));		if (GlobalOptions.verboseLevel > 2)		    GlobalOptions.err.println			(bytecode + ": Replacing " + instr			 + " with goto " + pc.getAddr());		while (iter.hasNext()) {		    ConstantInfo nextinfo = (ConstantInfo) 			((Instruction) iter.next()).getTmpInfo();		    if (nextinfo != null) {			Instruction nextInstr = (Instruction) iter.previous();			if (pc != nextInstr)			    appendJump(iter, pc);			break;		    }		    /* Next instruction can't be reached logically */		    iter.remove();		}			    } else {		int opcode = instr.getOpcode();		switch (opcode) {		case opc_nop:		    iter.remove();		    break;		case opc_jsr:		    ConstantInfo jsrinfo = (ConstantInfo)			instr.getSingleSucc().getTmpInfo();		    if ((jsrinfo.flags & RETURNINGJSR) != 0)			/* A normal jsr, don't change it */			break;		    /* This means, the jsr will never return.  We		     * replace it with a goto,  the jsr will transform		     * itself to remove the astore operation.		     */		    Instruction gotoInstr = new Instruction(opc_goto);		    gotoInstr.setSuccs(instr.getSingleSucc());		    iter.set(gotoInstr);		    /* fall through */		case opc_goto:		case opc_ifeq: case opc_ifne: 		case opc_iflt: case opc_ifge: 		case opc_ifgt: case opc_ifle:		case opc_ifnull: case opc_ifnonnull:		case opc_if_icmpeq: case opc_if_icmpne:		case opc_if_icmplt: case opc_if_icmpge: 		case opc_if_icmpgt: case opc_if_icmple: 		case opc_if_acmpeq: case opc_if_acmpne:		    while (iter.hasNext()) {			ConstantInfo nextinfo = (ConstantInfo) 			    ((Instruction) iter.next()).getTmpInfo();			if (nextinfo != null			    && ((nextinfo.flags & (RETURNINGJSR | RETASTORE))				!= RETASTORE)) {			    Instruction nextInstr				= (Instruction) iter.previous();			    if (instr.getSingleSucc() == nextInstr) {				/* put iter in sane state */				iter.previous();				iter.next();				replaceWith(iter, instr, null);			    }			    break;			}			/* Next instruction can be removed */			iter.remove();		    }		    break;		case opc_putstatic:		case opc_putfield: {		    Reference ref = instr.getReference();		    FieldIdentifier fi = (FieldIdentifier) 			Main.getClassBundle().getIdentifier(ref);		    if (fi != null			&& (Main.stripping & Main.STRIP_UNREACH) != 0			&& !fi.isReachable()) {			replaceWith(iter, instr, null);		    }		    break;		}		}	    }	}    }}

⌨️ 快捷键说明

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