📄 methodinfo.java
字号:
"instruction: " + code[i+1] ); } break; case opc_ldc: ldc[nldc++] = i; i += opcLengths[opcode]; break; case opc_ldc_w: case opc_ldc2_w: case opc_getstatic: case opc_putstatic: case opc_getfield: case opc_putfield: case opc_invokevirtual: case opc_invokespecial: case opc_invokestatic: case opc_invokeinterface: case opc_new: case opc_anewarray: case opc_checkcast: case opc_instanceof: case opc_multianewarray: case opc_getstatic_fast: case opc_getstaticp_fast: case opc_getstatic2_fast: case opc_putstatic_fast: case opc_putstatic2_fast: case opc_invokevirtual_fast: case opc_invokespecial_fast: case opc_invokestatic_fast: case opc_invokeinterface_fast: case opc_new_fast: case opc_anewarray_fast: case opc_multianewarray_fast: case opc_checkcast_fast: case opc_instanceof_fast: wide[nwide++] = i; i += opcLengths[opcode]; break; default: i += opcLengths[opcode]; break; } } // not knowing any better, we allocated excess capacity. // allocate and fill appropriately-sized arrays. ldcInstructions = new int[ nldc ]; System.arraycopy( ldc, 0, ldcInstructions, 0, nldc ); ldc = null; wideConstantRefInstructions = new int[ nwide ]; System.arraycopy( wide, 0, wideConstantRefInstructions, 0, nwide ); wide = null; } private static int opcodeLength(byte[] code, int pc) { int old_pc; int opcode = (int)code[pc]&0xff; switch (opcode) { case opc_tableswitch: old_pc = pc; pc = (pc + 4) & ~3; int low = getInt(code, pc + 4); int high = getInt(code, pc + 8); pc += (high - low + 1) * 4 + 12; return pc - old_pc; case opc_lookupswitch: old_pc = pc; pc = (pc + 4) & ~3; int pairs = getInt(code, pc + 4); pc += pairs * 8 + 8; return pc - old_pc; case opc_wide: if (((int)code[pc + 1]&0xff) == opc_iinc) return 6; return 4; default: return opcLengths[opcode]; } } public int opcodeLength (int pc) { return opcodeLength(code, pc); } public void countConstantReferences( ConstantObject table[], boolean isRelocatable ){ super.countConstantReferences(); Attribute.countConstantReferences( methodAttributes, isRelocatable ); Attribute.countConstantReferences( codeAttributes, isRelocatable ); if ( code == null ) return; // no code, no relocation if ( ldcInstructions != null ){ int list[] = ldcInstructions; int n = list.length; for (int i = 0; i < n; i++){ int loc = list[i]; if ( loc==-1 ) continue; table[ (int)code[loc+1]&0xff ].incReference(); } } if ( wideConstantRefInstructions != null ){ int list[] = wideConstantRefInstructions; int n = list.length; for (int i = 0; i < n; i++){ int loc = list[i]; if ( loc==-1 ) continue; table[ getUnsignedShort(loc+1) ].incReference(); } } } public void relocateConstantReferences( ConstantObject table[] ) throws DataFormatException { if ( code == null ) return; // no code, no relocation if ( ldcInstructions != null ){ int list[] = ldcInstructions; int n = list.length; for (int i = 0; i < n; i++){ int j = list[i]+1; if ( j <= 0 ) continue; ConstantObject c = table[ (int)code[j]&0xff ]; if ( c.shared ) throw new DataFormatException("code reference to shared constant"); int v = c.index; if ( v < 0 ) throw new DataFormatException("code reference to deleted constant at "+qualifiedName()+"+"+Integer.toHexString(j)); if ( v > 255 ) throw new DataFormatException("ldc subscript out of range at "+qualifiedName()+"+"+Integer.toHexString(j)); code[j] = (byte)v; } } if ( wideConstantRefInstructions != null ){ int list[] = wideConstantRefInstructions; int n = list.length; for (int i = 0; i < n; i++){ int j = list[i]+1; if ( j <= 0 ) continue; ConstantObject c = table[ getUnsignedShort(j) ]; if ( c.shared ) throw new DataFormatException("code reference to shared constant at "+qualifiedName()+"+"+Integer.toHexString(j)); int v = c.index; if ( v < 0 ) throw new DataFormatException("code reference to deleted constant at "+qualifiedName()+"+"+Integer.toHexString(j)); putShort( j, (short)v ); } } } public void replaceCode(int start, int end) { replaceCode(start, end, new byte[0]); } public void replaceCode(int start, int end, int op1) { byte code[] = { (byte)op1 }; replaceCode(start, end, code); } public void replaceCode(int start, int end, int op1, int op2) { byte code[] = { (byte)op1, (byte)op2 }; replaceCode(start, end, code); } public void replaceCode(int start, int end, int op1, int op2, int op3) { byte code[] = { (byte)op1, (byte)op2, (byte)op3 }; replaceCode(start, end, code); } public java.util.BitSet getLabelTargets() { java.util.BitSet result = new java.util.BitSet(); int ncode = code.length; int nextpc; for(int pc = 0; pc < ncode; pc = nextpc) { nextpc = pc + opcodeLength(pc); int opcode = (int)code[pc]&0xff; switch (opcode) { case opc_tableswitch: case opc_lookupswitch: int i = (pc + 4) & ~3; int delta = (opcode == opc_tableswitch) ? 4 : 8; result.set(pc + getInt(i)); // default for (i = i + 12; i < nextpc; i += delta) result.set(pc + getInt(i)); break; case opc_jsr: result.set(pc + 3); case opc_goto: case opc_ifeq: case opc_ifge: case opc_ifgt: case opc_ifle: case opc_iflt: case opc_ifne: case opc_if_icmpeq: case opc_if_icmpne: case opc_if_icmpge: case opc_if_icmplt: case opc_if_icmpgt: case opc_if_icmple: case opc_if_acmpeq: case opc_if_acmpne: case opc_ifnull: case opc_ifnonnull: result.set(pc + getShort(pc + 1)); break; case opc_jsr_w: result.set(pc + 5); case opc_goto_w: result.set(pc + getInt(pc + 1)); break; } } return result; } public void replaceCode(int start, int end, byte[] replaceCode) { if (end - start < replaceCode.length) { // System.out.println(" Cannot yet do expansion!!"); return; } if (exceptionTable != null && exceptionTable.length > 0) { for (int i = 0; i < exceptionTable.length; i++) { int startPC = exceptionTable[i].startPC; int endPC = exceptionTable[i].endPC; if (startPC >= start && startPC < end) return; if (endPC >= start && endPC < end) return; } } int startExtra = start + replaceCode.length; int extra = end - startExtra; System.arraycopy(replaceCode, 0, code, start, replaceCode.length); for (int i = startExtra; i < end; i++) code[i] = (byte)opc_nop; } public void disassemble() { System.out.println(disassemble(code, 0, code.length)); } public String disassemble(int start, int end) { return disassemble(code, start, end); } /** * Return the byte stored at a given index from the offset * within code bytes */ private static final int at(byte codeBytes[], int index) { return codeBytes[index] & 0xFF; } /** * Return the short stored at a given index from the offset * within code bytes */ private static final int shortAt(byte codeBytes[], int index) { return ((codeBytes[index] & 0xFF) << 8) | (codeBytes[index+1] & 0xFF); } public static String disassemble(byte[] codeBytes, int start, int end) { // Output goes into a string StringWriter sw = new StringWriter(); PrintWriter output = new PrintWriter(sw); for (int offset = start; offset < end; ) { int opcode = at(codeBytes, offset); if (offset > start) output.print("; "); output.print(opcodeName(opcode)); switch (opcode) { case opc_aload: case opc_astore: case opc_fload: case opc_fstore: case opc_iload: case opc_istore: case opc_lload: case opc_lstore: case opc_dload: case opc_dstore: case opc_ret: output.print(" " + at(codeBytes, offset+1)); offset += 2; break; case opc_iinc: output.print(" " + at(codeBytes, offset+1) + " " + (byte) at(codeBytes, offset +2)); offset += 3; break; case opc_newarray: switch (at(codeBytes, offset+1)) { case T_INT: output.print(" int"); break; case T_LONG: output.print(" long"); break; case T_FLOAT: output.print(" float"); break; case T_DOUBLE: output.print(" double"); break; case T_CHAR: output.print(" char"); break; case T_SHORT: output.print(" short"); break; case T_BYTE: output.print(" byte"); break; case T_BOOLEAN:output.print(" boolean"); break; default: output.print(" BOGUS"); break; } offset += 2; break; case opc_anewarray_fast: case opc_anewarray: { int index = shortAt(codeBytes, offset+1); output.print(" class #" + index + " "); offset += 3; break; } case opc_sipush: output.print(" " + (short) shortAt(codeBytes, offset+1)); offset += 3; break; case opc_bipush: output.print(" " + (byte) at(codeBytes, offset+1)); offset += 2; break; case opc_ldc: { int index = at(codeBytes, offset+1); output.print(" #" + index + " "); offset += 2; break; } case opc_getstatic_fast: case opc_getstaticp_fast: case opc_getstatic2_fast: case opc_putstatic_fast: case opc_putstatic2_fast: case opc_unused_d5: case opc_invokevirtual_fast: case opc_invokespecial_fast: case opc_invokestatic_fast:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -