📄 methodinfo.java
字号:
case opc_getstatic: case opc_putstatic: constType = CP_FIELD | CP_STATIC; index = shortAt(codeBytes, i+1); break; case opc_getfield: case opc_putfield: case opc_getfield_quick_w: case opc_putfield_quick_w: constType = CP_FIELD; index = shortAt(codeBytes, i+1); break; case opc_getstatic_quick: case opc_putstatic_quick: constType = CP_FIELD | CP_STATIC | CP_SINGLE; index = shortAt(codeBytes, i+1); break; case opc_agetstatic_quick: case opc_aputstatic_quick: case opc_agetstatic_checkinit_quick: case opc_aputstatic_checkinit_quick: constType = CP_FIELD | CP_STATIC | CP_REF; index = shortAt(codeBytes, i+1); break; case opc_getstatic2_quick: case opc_putstatic2_quick: case opc_getstatic2_checkinit_quick: case opc_putstatic2_checkinit_quick: constType = CP_FIELD | CP_STATIC | CP_DOUBLE; index = shortAt(codeBytes, i+1); break; case opc_invokevirtual: case opc_invokespecial: case opc_invokenonvirtual_quick: // actually IS virtual. case opc_invokeinterface: case opc_invokevirtual_quick_w: // TODO: interface checking constType = CP_METHOD; index = shortAt(codeBytes, i+1); break; case opc_invokestatic: case opc_invokestatic_quick: constType = CP_METHOD | CP_STATIC; index = shortAt(codeBytes, i+1); break; case opc_new: case opc_anewarray: case opc_checkcast: case opc_instanceof: case opc_multianewarray: case opc_new_quick: case opc_new_checkinit_quick: case opc_anewarray_quick: case opc_multianewarray_quick: case opc_checkcast_quick: case opc_instanceof_quick: constType = CP_CLASS; index = shortAt(codeBytes, i+1); break; default: break noCPAccess; } validateLoadable(constantPool, index, constType); } i += opcLengths[opcode]; } } } public void relocateConstantReferences( ConstantObject table[] ) throws DataFormatException { if ( code == null ) return; // no code, no relocation if (ldcInstructions == null){ findConstantReferences(); } { 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; } } { 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 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(" INVALID_TYPE"); break; } offset += 2; break; case opc_anewarray_quick: 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_quick: case opc_aldc_quick: case opc_aldc_ind_quick: case opc_ldc: { int index = at(codeBytes, offset+1); output.print(" #" + index + " "); offset += 2; break; } case opc_ldc_w_quick: case opc_aldc_w_quick: case opc_aldc_ind_w_quick: case opc_ldc2_w_quick: case opc_getstatic_quick: case opc_putstatic_quick: case opc_getstatic2_quick: case opc_putstatic2_quick: case opc_agetstatic_quick: case opc_aputstatic_quick: case opc_agetstatic_checkinit_quick: case opc_aputstatic_checkinit_quick: case opc_getstatic_checkinit_quick: // CVM case opc_getstatic2_checkinit_quick: // CVM case opc_putstatic_checkinit_quick: // CVM case opc_putstatic2_checkinit_quick: // CVM case opc_invokenonvirtual_quick: case opc_invokesuper_quick: case opc_invokestatic_quick: case opc_invokestatic_checkinit_quick: // CVM case opc_new_quick: case opc_new_checkinit_quick: // CVM case opc_checkcast_quick: case opc_instanceof_quick: case opc_invokevirtual_quick_w: case opc_getfield_quick_w: case opc_putfield_quick_w: case opc_ldc_w: case opc_ldc2_w: case opc_instanceof: case opc_checkcast: case opc_new: case opc_putstatic: case opc_getstatic: case opc_putfield: case opc_getfield: case opc_invokevirtual: case opc_invokespecial: case opc_invokestatic: { int index = shortAt(codeBytes, offset+1); output.print(" #" + index + " "); offset += 3; break; } case opc_jsr: 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_icmpgt: case opc_if_icmple: case opc_if_icmplt: case opc_if_acmpeq: case opc_if_acmpne: case opc_ifnull: case opc_ifnonnull: { int target = offset + (short) shortAt(codeBytes,offset+1); output.print(" " + target); offset += 3; break; } case opc_getfield_quick: case opc_putfield_quick: case opc_getfield2_quick: case opc_putfield2_quick: case opc_agetfield_quick: // CVM case opc_aputfield_quick: // CVM output.print(" #" + at(codeBytes, offset+1)); offset += 3; break; case opc_invokevirtualobject_quick: case opc_invokevirtual_quick: case opc_ainvokevirtual_quick: case opc_dinvokevirtual_quick: case opc_vinvokevirtual_quick: output.print(" #" + at(codeBytes, offset+1) + " args=" + at(codeBytes, offset+2)); offset += 3; break; case opc_invokeignored_quick: { char null_check = (at(codeBytes, offset+2) != 0) ? 'T' : 'F'; output.print(" #" + at(codeBytes, offset+1) + " " + null_check); offset += 3; break; } default: offset++; break; } } output.close(); return sw.toString(); } public static String opcodeName (int opcode) { return opcNames[opcode]; } public String toString(){ String r = "Method: "+super.toString(); if ( code != null ){ r += " {"+code.length+" bytes of code}"; } return r; } // Case 1: expand code. // Convert ldc to ldc2: a. Insert extra bytes // b. Fix all branch targets/exception ranges // Case 2: smash code // ldc_w_quick has index which is less than 255. Change to use // ldc_w. public void relocateAndPackCode (ConstantPool cp, boolean noCodeCompaction) { if (code == null) return; ConstantObject[] co = cp.getConstants(); int opcode, adjustment = 0; int newOffsets[] = new int[code.length]; int indexByPC[] = new int[code.length]; // First figure out where we'll have to insert extra bytes in // order to fit opc_ldc_w instead of opc_ldc instructions. for (int pc = 0, pcindex = 0; pc < code.length; pc = pc + opcodeLength(pc), pcindex++) { opcode = (int) code[pc]&0xFF; newOffsets[pcindex] = pc + adjustment; indexByPC[pc] = pcindex; switch (opcode) { case opc_ldc: case opc_ldc_quick: case opc_aldc_quick: case opc_aldc_ind_quick: { // a conversion table which maps pcValue to new index. int oldindex = (int)(code[pc+1] & 0xFF); int index = co[oldindex].index; if (index >= 0x100)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -