📄 methodinfo.java
字号:
adjustment++; break; } case opc_ldc_w: case opc_ldc_w_quick: case opc_aldc_w_quick: case opc_aldc_ind_w_quick: { // a conversion table which maps pcValue to new index. int oldindex = (int)(((code[pc+1]&0xFF) << 8) | (code[pc+2]&0xFF)); int index = co[oldindex].index; if (index < 0x100) adjustment--; break; } case opc_goto: { // Calculate the displacement, sign extend high byte int displ = (code[pc+1] << 8) | (code[pc+2] & 0xFF); if (!noCodeCompaction && displ == 3) { adjustment -= 3; // remove no-use goto's. } break; } case opc_nop: { if (!noCodeCompaction) { adjustment--; // remove } break; } case opc_tableswitch: case opc_lookupswitch: { int oldExtraPC = (( pc + 4 ) & ~3); int newExtraPC = (( pc + adjustment + 4) & ~3); adjustment = newExtraPC - oldExtraPC; break; } } } // Now copy the code to the new location. At the same // time, we adjust all branch targets. byte newCode[] = new byte[code.length + adjustment]; for (int pc = 0, pcindex = 0; pc < code.length; pc = pc + opcodeLength(pc), pcindex++) { int outPos = newOffsets[pcindex]; int inPos = pc; opcode = (int) code[pc]&0xFF; switch (opcode) { case opc_ldc: case opc_ldc_quick: case opc_aldc_quick: case opc_aldc_ind_quick: { int oldindex = (int)(code[pc+1] & 0xFF); int index = co[oldindex].index; if (index >= 0x100) { if (opcode == opc_aldc_quick) { newCode[outPos] = (byte) opc_aldc_w_quick; } else if (opcode == opc_aldc_ind_quick) { newCode[outPos] = (byte) opc_aldc_ind_w_quick; } else if (opcode == opc_ldc) { newCode[outPos] = (byte) opc_ldc_w; } else { newCode[outPos] = (byte) opc_ldc_w_quick; } newCode[outPos +1] = (byte) ((index >> 8) & 0xFF); newCode[outPos +2] = (byte) (index & 0xFF); } else { newCode[outPos] = (byte) opcode; newCode[outPos +1] = (byte) index ; } break; } case opc_ldc_w: case opc_ldc_w_quick: case opc_aldc_w_quick: case opc_aldc_ind_w_quick: { int oldindex = (int)(((code[pc+1]&0xFF) << 8) | (code[pc+2]&0xFF)); int index = co[oldindex].index; if (index < 0x100) { if (opcode == opc_aldc_w_quick) { newCode[outPos] = (byte) opc_aldc_quick; } else if (opcode == opc_aldc_ind_w_quick) { newCode[outPos] = (byte) opc_aldc_ind_quick; } else if (opcode == opc_ldc_w) { newCode[outPos] = (byte) opc_ldc; } else { newCode[outPos] = (byte) opc_ldc_quick; } newCode[outPos+1] = (byte) index; } else { newCode[outPos] = (byte) opcode; newCode[outPos+1] = (byte) ((index >> 8) & 0xFF); newCode[outPos+2] = (byte) (index & 0xFF); } break; } // Remapping branches case opc_ifeq: case opc_ifne: case opc_iflt: case opc_ifge: case opc_ifgt: case opc_ifle: 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_ifnull: case opc_ifnonnull: case opc_goto: case opc_jsr: { // Calculate the displacement, sign extend high byte int displ = (code[pc+1] << 8) | (code[pc+2] & 0xFF); if (!noCodeCompaction && displ == 3 && opcode == opc_goto) { break; } newCode[outPos] = code[pc]; int branchDest = pc + displ; int newDest = newOffsets[indexByPC[branchDest]] - outPos; newCode[outPos+1] = (byte) ((newDest >> 8) & 0xFF); newCode[outPos+2] = (byte) (newDest & 0xFF); break; } case opc_goto_w: case opc_jsr_w: { // Calculate the displacement, sign extend high byte int displ = getInt(pc+1); if (!noCodeCompaction && displ == 3 && opcode == opc_goto_w) { break; } newCode[outPos] = code[pc]; int branchDest = pc + displ; int newDest = newOffsets[indexByPC[branchDest]] - outPos; putInt(newCode, outPos+1, newDest); break; } case opc_tableswitch: { newCode[outPos] = code[pc]; outPos = (outPos + 4) & ~3; inPos = (inPos + 4) & ~3; // Update the default destination int oldDest = getInt(inPos) + pc; int newDest = newOffsets[indexByPC[oldDest]] - newOffsets[pcindex]; putInt(newCode, outPos, newDest); // Update each of the destinations in the table int low = getInt(inPos+4); int high = getInt(inPos+8); putInt(newCode, outPos+4, low); putInt(newCode, outPos+8, high); for (int j = 0; j <= high-low; j++) { int offset = j * 4 + 12; oldDest = getInt(inPos + offset) + pc; newDest = newOffsets[indexByPC[oldDest]] - newOffsets[pcindex]; putInt(newCode, outPos + offset, newDest); } break; } case opc_lookupswitch: { newCode[outPos] = code[pc]; // 0-3 byte pads outPos = (outPos + 4) & ~3; inPos = (inPos + 4) & ~3; // Update the default destination int oldDest = getInt(inPos) + pc; int newDest = newOffsets[indexByPC[oldDest]] - newOffsets[pcindex]; putInt(newCode, outPos, newDest); // Update each of the pairs of destinations in the list int pairs = getInt(inPos+4); putInt(newCode, outPos+4, pairs); for (int j = 0; j < pairs; j++) { int offset = (j + 1) * 8; // First copy the value putInt(newCode, outPos + offset, getInt(inPos + offset)); offset += 4; // Now adjust the destination oldDest = getInt(inPos + offset) + pc; newDest = newOffsets[indexByPC[oldDest]] - newOffsets[pcindex]; putInt(newCode, outPos + offset, newDest); } break; } // Byte-codes with constant pool access. Remap to new indices case opc_getfield: case opc_checkcast: case opc_getstatic: case opc_instanceof: case opc_ldc2_w: case opc_new: case opc_putfield: case opc_putstatic: case opc_invokevirtual: case opc_invokestatic: case opc_invokespecial: case opc_anewarray: case opc_anewarray_quick: case opc_checkcast_quick: case opc_agetstatic_quick: case opc_getstatic_quick: case opc_getstatic2_quick: case opc_aputstatic_quick: case opc_putstatic_quick: case opc_putstatic2_quick: case opc_agetstatic_checkinit_quick: // CVM case opc_getstatic_checkinit_quick: // CVM case opc_getstatic2_checkinit_quick: // CVM case opc_aputstatic_checkinit_quick: // CVM case opc_putstatic_checkinit_quick: // CVM case opc_putstatic2_checkinit_quick: // CVM case opc_instanceof_quick: case opc_invokestatic_quick: case opc_invokestatic_checkinit_quick: // CVM case opc_new_quick: case opc_new_checkinit_quick: // CVM case opc_invokenonvirtual_quick: case opc_invokesuper_quick: case opc_ldc2_w_quick: case opc_invokevirtual_quick_w: case opc_putfield_quick_w: case opc_getfield_quick_w: { int oldindex = (int)(((code[pc+1]&0xFF) << 8) | (code[pc+2]&0xFF)); int index = co[oldindex].index; newCode[outPos] = (byte) opcode; newCode[outPos+1] = (byte) ((index >> 8) & 0xFF); newCode[outPos+2] = (byte) (index & 0xFF); break; } case opc_multianewarray: case opc_multianewarray_quick: { int oldindex = (int)(((code[pc+1]&0xFF) << 8) | (code[pc+2]&0xFF)); int index = co[oldindex].index; newCode[outPos] = (byte) opcode; newCode[outPos+1] = (byte) ((index >> 8) & 0xFF); newCode[outPos+2] = (byte) (index & 0xFF); newCode[outPos+3] = (byte) code[pc+3]; break; } case opc_invokeinterface: case opc_invokeinterface_quick: { int oldindex = (int)(((code[pc+1]&0xFF) << 8) | (code[pc+2]&0xFF)); int index = co[oldindex].index; newCode[outPos] = (byte) opcode; newCode[outPos+1] = (byte) ((index >> 8) & 0xFF); newCode[outPos+2] = (byte) (index & 0xFF); newCode[outPos+3] = (byte) code[pc+3]; newCode[outPos+4] = (byte) code[pc+4]; break; } case opc_nop: { if (!noCodeCompaction) { break; // remove } } default: { // other bytecode for (int i = 0; i < opcodeLength(pc); i++) { newCode[outPos + i] = code[pc + i]; } break; } } } // Update the exception table for (int i = 0; i < exceptionTable.length; i++) { ExceptionEntry e = exceptionTable[i]; e.startPC = newOffsets[indexByPC[e.startPC]]; e.endPC = newOffsets[indexByPC[e.endPC]]; e.handlerPC = newOffsets[indexByPC[e.handlerPC]]; } // Update the line number table LineNumberTableEntry[] lntab = getLineNumberTable(); if (lntab != null) { for (int i = 0; i < lntab.length; i++) { LineNumberTableEntry e = lntab[i]; e.startPC = newOffsets[indexByPC[e.startPC]]; } } // Update the line number table LocalVariableTableEntry[] locvartab = getLocalVariableTable(); if (locvartab != null) { for (int i = 0; i < locvartab.length; i++) { LocalVariableTableEntry e = locvartab[i]; e.pc0 = newOffsets[indexByPC[e.pc0]]; } } // make the changes permanent code = newCode; } public String getMethodName() { return super.name.string+super.type.string; } public int[] getLdcInstructions() { if (ldcInstructions == null){ findConstantReferences(); } return ldcInstructions; } public int[] getWideConstantRefInstructions() { if (wideConstantRefInstructions == null){ findConstantReferences(); } return wideConstantRefInstructions; } /* * Iterate through code and create the array class for anewarray opcode * and friends. */ public void collectArrayForAnewarray(ConstantObject constantPool[], String clname) { if ( code == null ) return; // no code. int ncode = code.length; int opcode; int index; for( int i = 0; i < ncode; /*nothing*/){ switch (opcode = (int)code[i]&0xff) { case opc_tableswitch: i = (i + 4) & ~3; int low = getInt( i+4); int high = getInt( i+8); i += (high - low + 1) * 4 + 12; break; case opc_lookupswitch: i = (i + 4) & ~3; int pairs = getInt(i+4); i += pairs * 8 + 8; break; case opc_wide: switch ((int)code[i+1]&0xff) { case opc_aload: case opc_iload: case opc_fload: case opc_lload: case opc_dload: case opc_istore: case opc_astore: case opc_fstore: case opc_lstore: case opc_dstore: case opc_ret: i += 4; break; case opc_iinc: i += 6; break; default: throw new DataFormatException( parent.className + "." + name.string + ": unknown wide " + "instruction: " + code[i+1] ); } break; case opc_anewarray: case opc_multianewarray: case opc_anewarray_quick: case opc_multianewarray_quick: index = shortAt(code, i+1); ConstantObject co = constantPool[index]; if (co instanceof ClassConstant) { ClassConstant cc = (ClassConstant)co; String cname = cc.name.string; /* Construct the name of the array. For multianewarray, the * resolved constant should already be the array class with * correct dimensions. */ if (opcode == opc_anewarray || opcode == opc_anewarray_quick) { if (cname.startsWith("[")) { cname = "[" + cname; } else { cname = "[L"+ cname +";"; } } vm.ArrayClassInfo.collectArrayClass(cname, false); } default: i += opcLengths[opcode]; break; } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -