📄 instruction.java
字号:
1, // arraylength 1, // athrow 1, // checkcast 1, // instanceof 1, // monitorenter 1, // monitorexit 0, // wide 0, // multianewarray 1, // ifnull 1, // ifnonnull 0, // goto_w 0, // jsr_w }; // An array containing the fixed number of entries pushed onto the stack, // for all instructions. private static final int[] STACK_PUSH_COUNTS = new int[] { 0, // nop 1, // aconst_null 1, // iconst_m1 1, // iconst_0 1, // iconst_1 1, // iconst_2 1, // iconst_3 1, // iconst_4 1, // iconst_5 2, // lconst_0 2, // lconst_1 1, // fconst_0 1, // fconst_1 1, // fconst_2 2, // dconst_0 2, // dconst_1 1, // bipush 1, // sipush 1, // ldc 1, // ldc_w 2, // ldc2_w 1, // iload 2, // lload 1, // fload 2, // dload 1, // aload 1, // iload_0 1, // iload_1 1, // iload_2 1, // iload_3 2, // lload_0 2, // lload_1 2, // lload_2 2, // lload_3 1, // fload_0 1, // fload_1 1, // fload_2 1, // fload_3 2, // dload_0 2, // dload_1 2, // dload_2 2, // dload_3 1, // aload_0 1, // aload_1 1, // aload_2 1, // aload_3 1, // iaload 2, // laload 1, // faload 2, // daload 1, // aaload 1, // baload 1, // caload 1, // saload 0, // istore 0, // lstore 0, // fstore 0, // dstore 0, // astore 0, // istore_0 0, // istore_1 0, // istore_2 0, // istore_3 0, // lstore_0 0, // lstore_1 0, // lstore_2 0, // lstore_3 0, // fstore_0 0, // fstore_1 0, // fstore_2 0, // fstore_3 0, // dstore_0 0, // dstore_1 0, // dstore_2 0, // dstore_3 0, // astore_0 0, // astore_1 0, // astore_2 0, // astore_3 0, // iastore 0, // lastore 0, // fastore 0, // dastore 0, // aastore 0, // bastore 0, // castore 0, // sastore 0, // pop 0, // pop2 1, // dup 1, // dup_x1 1, // dup_x2 2, // dup2 2, // dup2_x1 2, // dup2_x2 0, // swap 1, // iadd 2, // ladd 1, // fadd 2, // dadd 1, // isub 2, // lsub 1, // fsub 2, // dsub 1, // imul 2, // lmul 1, // fmul 2, // dmul 1, // idiv 2, // ldiv 1, // fdiv 2, // ddiv 1, // irem 2, // lrem 1, // frem 2, // drem 1, // ineg 2, // lneg 1, // fneg 2, // dneg 1, // ishl 2, // lshl 1, // ishr 2, // lshr 1, // iushr 2, // lushr 1, // iand 2, // land 1, // ior 2, // lor 1, // ixor 2, // lxor 0, // iinc 2, // i2l 1, // i2f 2, // i2d 1, // l2i 1, // l2f 2, // l2d 1, // f2i 2, // f2l 2, // f2d 1, // d2i 2, // d2l 1, // d2f 1, // i2b 1, // i2c 1, // i2s 1, // lcmp 1, // fcmpl 1, // fcmpg 1, // dcmpl 1, // dcmpg 0, // ifeq 0, // ifne 0, // iflt 0, // ifge 0, // ifgt 0, // ifle 0, // ificmpeq 0, // ificmpne 0, // ificmplt 0, // ificmpge 0, // ificmpgt 0, // ificmple 0, // ifacmpeq 0, // ifacmpne 0, // goto 1, // jsr 0, // ret 0, // tableswitch 0, // lookupswitch 0, // ireturn 0, // lreturn 0, // freturn 0, // dreturn 0, // areturn 0, // return 0, // getstatic 0, // putstatic 0, // getfield 0, // putfield 0, // invokevirtual 0, // invokespecial 0, // invokestatic 0, // invokeinterface 0, // unused 1, // new 1, // newarray 1, // anewarray 1, // arraylength 0, // athrow 1, // checkcast 1, // instanceof 0, // monitorenter 0, // monitorexit 0, // wide 1, // multianewarray 0, // ifnull 0, // ifnonnull 0, // goto_w 1, // jsr_w }; public byte opcode; /** * Shrinks this instruction to its shortest possible form. * @return this instruction. */ public abstract Instruction shrink(); /** * Writes the Instruction back to the data in the byte array. */ public final void write(CodeAttrInfo codeAttrInfo, int offset) { byte[] code = codeAttrInfo.code; // Write the wide opcode, if necessary. if (isWide()) { code[offset++] = InstructionConstants.OP_WIDE; } // Write the opcode. code[offset++] = opcode; // Write any additional arguments. writeInfo(code, offset); } /** * Returns whether the instruction is wide, i.e. preceded by a wide opcode. * With the current specifications, only variable instructions can be wide. */ protected boolean isWide() { return false; } /** * Reads the data following the instruction opcode. */ protected abstract void readInfo(byte[] code, int offset); /** * Writes data following the instruction opcode. */ protected abstract void writeInfo(byte[] code, int offset); /** * Returns the length in bytes of the instruction. */ public abstract int length(int offset); /** * Accepts the given visitor. */ public abstract void accept(ClassFile classFile, MethodInfo methodInfo, CodeAttrInfo codeAttrInfo, int offset, InstructionVisitor instructionVisitor); /** * Returns a description of the instruction, at the given offset. */ public abstract String toString(int offset); /** * Returns the name of the instruction. */ public String getName() { return InstructionConstants.NAMES[opcode & 0xff]; } /** * Returns whether the instruction is a Category 2 instruction. This means * that it operates on long or double arguments. */ public boolean isCategory2() { return IS_CATEGORY2[opcode & 0xff]; } /** * Returns the number of entries popped from the stack during the execution * of the instruction. */ public int stackPopCount(ClassFile classFile) { return STACK_POP_COUNTS[opcode & 0xff]; } /** * Returns the number of entries pushed onto the stack during the execution * of the instruction. */ public int stackPushCount(ClassFile classFile) { return STACK_PUSH_COUNTS[opcode & 0xff]; } // Small utility methods. protected static int readByte(byte[] code, int offset) { return code[offset] & 0xff; } protected static int readShort(byte[] code, int offset) { return ((code[offset++] & 0xff) << 8) | ( code[offset ] & 0xff ); } protected static int readInt(byte[] code, int offset) { return ( code[offset++] << 24) | ((code[offset++] & 0xff) << 16) | ((code[offset++] & 0xff) << 8) | ( code[offset ] & 0xff ); } protected static int readValue(byte[] code, int offset, int valueSize) { switch (valueSize) { case 0: return 0; case 1: return readByte( code, offset); case 2: return readShort(code, offset); case 4: return readInt( code, offset); default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } protected static int readSignedByte(byte[] code, int offset) { return code[offset]; } protected static int readSignedShort(byte[] code, int offset) { return (code[offset++] << 8) | (code[offset ] & 0xff); } protected static int readSignedValue(byte[] code, int offset, int valueSize) { switch (valueSize) { case 0: return 0; case 1: return readSignedByte( code, offset); case 2: return readSignedShort(code, offset); case 4: return readInt( code, offset); default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } } protected static void writeByte(byte[] code, int offset, int value) { if (value > 0xff) { throw new IllegalArgumentException("Byte value larger than 0xff ["+value+"]"); } code[offset] = (byte)value; } protected static void writeShort(byte[] code, int offset, int value) { if (value > 0xffff) { throw new IllegalArgumentException("Short value larger than 0xffff ["+value+"]"); } code[offset++] = (byte)(value >> 8); code[offset ] = (byte)(value ); } protected static void writeInt(byte[] code, int offset, int value) { code[offset++] = (byte)(value >> 24); code[offset++] = (byte)(value >> 16); code[offset++] = (byte)(value >> 8); code[offset ] = (byte)(value ); } protected static void writeValue(byte[] code, int offset, int value, int valueSize) { switch (valueSize) { case 0: break; case 1: writeByte( code, offset, value); break; case 2: writeShort(code, offset, value); break; case 4: writeInt( code, offset, value); break; default: throw new IllegalArgumentException("Unsupported value size ["+valueSize+"]"); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -