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

📄 constantanalyzer.java

📁 Java Optimize and Decompile Environment 源代码
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	    for (int i=0; i< locals.length; i++) {		if (locals[i] != null		    && locals[i].value instanceof JSRTargetInfo) {		    JSRTargetInfo jsrInfo = (JSRTargetInfo) locals[i].value;		    jsrInfo = jsrInfo.copy();		    locals[i] = locals[i].copy();		    locals[i].value = jsrInfo;		    for (int slot = 0; slot < locals.length; slot++) {			if (jsrTargetInfo.uses(slot))			    jsrInfo.addUsed(slot);		    }		}	    }	    for (int i=0; i< stack.length; i++) {		if (stack[i] != null		    && stack[i].value instanceof JSRTargetInfo) {		    JSRTargetInfo jsrInfo = (JSRTargetInfo)stack[i].value;		    jsrInfo = jsrInfo.copy();		    stack[i] = stack[i].copy();		    stack[i].value = jsrInfo;		    for (int slot = 0; slot < locals.length; slot++) {			if (jsrTargetInfo.uses(slot))			    jsrInfo.addUsed(slot);		    }		}	    }	    return this;	}		public void merge(StackLocalInfo other) {	    for (int i=0; i < locals.length; i++) {		if (locals[i] != null) {		    if (other.locals[i] == null) {			locals[i].constantChanged();			locals[i] = null;			enqueue();		    } else {			locals[i].merge(other.locals[i]);		    }		}	    }	    if (stack.length != other.stack.length)		throw new jode.AssertError("stack length differs");	    for (int i=0; i < stack.length; i++) {		if ((other.stack[i] == null) != (stack[i] == null))		    throw new jode.AssertError("stack types differ");		else if (stack[i] != null)		    stack[i].merge(other.stack[i]);	    }	}	public String toString() {	    return "Locals: "+Arrays.asList(locals)		+"Stack: "+Arrays.asList(stack)+ "Instr: "+instr;	}    }    private static class ConstantInfo implements ConstantListener {	ConstantInfo() {	    this(0, null);	}	ConstantInfo(int flags) {	    this(flags, null);	}	ConstantInfo(int flags, Object constant) {	    this.flags = flags;	    this.constant = constant;	}		int flags;	/**	 * The constant, may be an Instruction for CONSTANTFLOW.	 */	Object constant;	public void constantChanged() {	    constant = null;	    flags &= ~(CONSTANT | CONSTANTFLOW);	}    }    private static ConstValue[] unknownValue = {	new ConstValue(1), new ConstValue(2)    };    private static ConstantInfo unknownConstInfo = new ConstantInfo();    public ConstantAnalyzer() {    }    public void mergeInfo(Instruction instr, 			  StackLocalInfo info) {	if (instr.getTmpInfo() == null) {	    instr.setTmpInfo(info);	    info.instr = instr;	    info.enqueue();	} else	    ((StackLocalInfo)instr.getTmpInfo()).merge(info);    }    public void handleReference(Reference ref, boolean isVirtual) {	Main.getClassBundle().reachableReference(ref, isVirtual);    }    public void handleClass(String clName) {	int i = 0;	while (i < clName.length() && clName.charAt(i) == '[')	    i++;	if (i < clName.length() && clName.charAt(i) == 'L') {	    clName = clName.substring(i+1, clName.length()-1);	    Main.getClassBundle().reachableClass(clName);	}    }    public void handleOpcode(StackLocalInfo info, Identifier fieldListener) {	Instruction instr = info.instr;	info.constInfo = unknownConstInfo;	int opcode = instr.getOpcode();	Handler[] handlers = bytecode.getExceptionHandlers();	for (int i=0; i< handlers.length; i++) {	    if (handlers[i].start.getAddr() <= instr.getAddr()		&& handlers[i].end.getAddr() >= instr.getAddr())		mergeInfo(handlers[i].catcher, 			  info.poppush(info.stack.length, unknownValue[0]));	}	ConstValue result;	switch (opcode) {        case opc_nop:	    mergeInfo(instr.getNextByAddr(), info.pop(0));	    break;        case opc_ldc:        case opc_ldc2_w:	    result = new ConstValue(instr.getConstant());	    mergeInfo(instr.getNextByAddr(), info.poppush(0, result));	    break;        case opc_iload: case opc_lload:         case opc_fload: case opc_dload: case opc_aload:	    result = info.getLocal(instr.getLocalSlot());	    if (result == null) {		dumpStackLocalInfo();		System.err.println(info);		System.err.println(instr);	    }	    if (result.value != ConstValue.VOLATILE) {		info.constInfo = new ConstantInfo(CONSTANT, result.value);		result.addConstantListener(info.constInfo);	    }	    mergeInfo(instr.getNextByAddr(), 		      info.poppush(0, result)		      .setLocal(instr.getLocalSlot(), result.copy()));	    break;        case opc_iaload: case opc_laload:         case opc_faload: case opc_daload: case opc_aaload:        case opc_baload: case opc_caload: case opc_saload: {//  	    ConstValue array = info.getStack(2);//  	    ConstValue index = info.getStack(1);//  	    ConstValue newValue = null;//  	    if (index.value != index.ConstValue.VOLATILE//  		&& array.value != array.ConstValue.VOLATILE//  		&& array.value != null) {//  		int indexVal = ((Integer) index.value).intValue();//  		Object content;//  		switch(opcode) {//  		case opc_baload: //  		    content = new Integer//  			(array.value instanceof byte[]//  			 ? ((byte[])array.value)[indexVal]//  			 : ((boolean[])array.value)[indexVal] ? 1 : 0);//  		case opc_caload: //  		    content = new Integer(((char[])array.value)[indexVal]);//  		    break;//  		case opc_saload://  		    content = new Integer(((short[])array.value)[indexVal]);//  		    break;//  		case opc_iaload: //  		case opc_laload: //  		case opc_faload: //  		case opc_daload: //  		case opc_aaload://  		    content = Array.get(array.value, indexVal);//  		    break;//  		default://  		    throw new jode.AssertError("Can't happen.");//  		}//  		result = new ConstValue(content);//  		array.addConstantListener(result);//  		index.addConstantListener(result);//  	    } else {	    result = unknownValue[(opcode == opc_laload				   || opcode == opc_daload) ? 1 : 0];//  	    }	    mergeInfo(instr.getNextByAddr(), info.poppush(2, result));	    break;	}        case opc_istore: case opc_fstore: case opc_astore: {	    result = info.getStack(1);	    if (result.value instanceof JSRTargetInfo)		info.constInfo.flags |= RETASTORE;	    mergeInfo(instr.getNextByAddr(), 		      info.pop(1).setLocal(instr.getLocalSlot(), result));	    break;	}	case opc_lstore: case opc_dstore: {	    mergeInfo(instr.getNextByAddr(), 		      info.pop(2).setLocal(instr.getLocalSlot(), info.getStack(2)));	    break;	}        case opc_iastore: case opc_lastore:        case opc_fastore: case opc_dastore: case opc_aastore:        case opc_bastore: case opc_castore: case opc_sastore: {	    int size = (opcode == opc_lastore			|| opcode == opc_dastore) ? 2 : 1;	    mergeInfo(instr.getNextByAddr(), info.pop(2+size));	    break;	}        case opc_pop: 	    mergeInfo(instr.getNextByAddr(), info.pop(1));	    break;	case opc_pop2:	    mergeInfo(instr.getNextByAddr(), info.pop(2));	    break;	case opc_dup: case opc_dup_x1: case opc_dup_x2:        case opc_dup2: case opc_dup2_x1: case opc_dup2_x2:	    mergeInfo(instr.getNextByAddr(),		      info.dup((opcode - (opc_dup - 3)) / 3,			       (opcode - (opc_dup - 3)) % 3));	    break;        case opc_swap:	    mergeInfo(instr.getNextByAddr(), info.swap());	    break;        case opc_iadd: case opc_ladd: case opc_fadd: case opc_dadd:        case opc_isub: case opc_lsub: case opc_fsub: case opc_dsub:        case opc_imul: case opc_lmul: case opc_fmul: case opc_dmul:        case opc_idiv: case opc_ldiv: case opc_fdiv: case opc_ddiv:        case opc_irem: case opc_lrem: case opc_frem: case opc_drem:        case opc_iand: case opc_land:        case opc_ior : case opc_lor :        case opc_ixor: case opc_lxor: {	    int size = 1 + (opcode - opc_iadd & 1);	    ConstValue value1 = info.getStack(2*size);	    ConstValue value2 = info.getStack(1*size);	    boolean known = value1.value != ConstValue.VOLATILE		&& value2.value != ConstValue.VOLATILE;	    if (known) {		if (((opcode == opc_idiv || opcode == opc_irem)		     && ((Integer)value2.value).intValue() == 0)		    || ((opcode == opc_ldiv || opcode == opc_lrem)			&& ((Long)value2.value).longValue() == 0))		    known = false;	    }	    if (known) {		Object newValue;		switch (opcode) {		case opc_iadd: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 + ((Integer)value2.value).intValue());		    break;		case opc_isub: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 - ((Integer)value2.value).intValue());		    break;		case opc_imul: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 * ((Integer)value2.value).intValue());		    break;		case opc_idiv: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 / ((Integer)value2.value).intValue());		    break;		case opc_irem: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 % ((Integer)value2.value).intValue());		    break;		case opc_iand: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 & ((Integer)value2.value).intValue());		    break;		case opc_ior: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 | ((Integer)value2.value).intValue());		    break;		case opc_ixor: 		    newValue = new Integer			(((Integer)value1.value).intValue()			 ^ ((Integer)value2.value).intValue());		    break;		    		case opc_ladd: 		    newValue = new Long			(((Long)value1.value).longValue()			 + ((Long)value2.value).longValue());		    break;		case opc_lsub: 		    newValue = new Long			(((Long)value1.value).longValue()			 - ((Long)value2.value).longValue());		    break;		case opc_lmul: 		    newValue = new Long			(((Long)value1.value).longValue()			 * ((Long)value2.value).longValue());		    break;		case opc_ldiv: 		    newValue = new Long			(((Long)value1.value).longValue()			 / ((Long)value2.value).longValue());		    break;		case opc_lrem: 		    newValue = new Long			(((Long)value1.value).longValue()			 % ((Long)value2.value).longValue());		    break;		case opc_land: 		    newValue = new Long			(((Long)value1.value).longValue()			 & ((Long)value2.value).longValue());		    break;		case opc_lor: 		    newValue = new Long			(((Long)value1.value).longValue()			 | ((Long)value2.value).longValue());		    break;		case opc_lxor: 		    newValue = new Long			(((Long)value1.value).longValue()			 ^ ((Long)value2.value).longValue());		    break;		    		case opc_fadd: 		    newValue = new Float			(((Float)value1.value).floatValue()			 + ((Float)value2.value).floatValue());		    break;		case opc_fsub: 		    newValue = new Float			(((Float)value1.value).floatValue()			 - ((Float)value2.value).floatValue());		    break;		case opc_fmul: 		    newValue = new Float			(((Float)value1.value).floatValue()			 * ((Float)value2.value).floatValue());		    break;		case opc_fdiv: 		    newValue = new Float			(((Float)value1.value).floatValue()			 / ((Float)value2.value).floatValue());		    break;		case opc_frem: 		    newValue = new Float			(((Float)value1.value).floatValue()			 % ((Float)value2.value).floatValue());		    break;		    		case opc_dadd: 		    newValue = new Double			(((Double)value1.value).doubleValue()			 + ((Double)value2.value).doubleValue());		    break;		case opc_dsub: 		    newValue = new Double			(((Double)value1.value).doubleValue()			 - ((Double)value2.value).doubleValue());		    break;		case opc_dmul: 		    newValue = new Double			(((Double)value1.value).doubleValue()			 * ((Double)value2.value).doubleValue());		    break;		case opc_ddiv: 		    newValue = new Double			(((Double)value1.value).doubleValue()			 / ((Double)value2.value).doubleValue());		    break;		case opc_drem: 		    newValue = new Double			(((Double)value1.value).doubleValue()			 % ((Double)value2.value).doubleValue());		    break;		default:		    throw new jode.AssertError("Can't happen.");		}		info.constInfo = new ConstantInfo(CONSTANT, newValue);		result = new ConstValue(newValue);		result.addConstantListener(info.constInfo);		value1.addConstantListener(result);		value2.addConstantListener(result);	    } else 		result = unknownValue[size-1];	    mergeInfo(instr.getNextByAddr(), info.poppush(2*size, result));	    break;	}        case opc_ineg: case opc_lneg: case opc_fneg: case opc_dneg: {	    int size = 1 + (opcode - opc_ineg & 1);	    ConstValue value = info.getStack(size);	    if (value.value != ConstValue.VOLATILE) {		Object newValue;		switch (opcode) {		case opc_ineg: 		    newValue = new Integer			(-((Integer)value.value).intValue());		    break;

⌨️ 快捷键说明

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