📄 classfilewriter.java
字号:
index = putInt16(lineNumberTableAttrIndex, codeAttribute, index); int tableAttrLength = 2 + (itsLineNumberTableTop * 4); index = putInt32(tableAttrLength, codeAttribute, index); index = putInt16(itsLineNumberTableTop, codeAttribute, index); for (int i = 0; i < itsLineNumberTableTop; i++) { index = putInt32(itsLineNumberTable[i], codeAttribute, index); } } if (itsVarDescriptors != null) { int variableTableAttrIndex = itsConstantPool.addUtf8("LocalVariableTable"); index = putInt16(variableTableAttrIndex, codeAttribute, index); int varCount = itsVarDescriptors.size(); int tableAttrLength = 2 + (varCount * 10); index = putInt32(tableAttrLength, codeAttribute, index); index = putInt16(varCount, codeAttribute, index); for (int i = 0; i < varCount; i++) { int[] chunk = (int[])itsVarDescriptors.get(i); int nameIndex = chunk[0]; int descriptorIndex = chunk[1]; int startPC = chunk[2]; int register = chunk[3]; int length = itsCodeBufferTop - startPC; index = putInt16(startPC, codeAttribute, index); index = putInt16(length, codeAttribute, index); index = putInt16(nameIndex, codeAttribute, index); index = putInt16(descriptorIndex, codeAttribute, index); index = putInt16(register, codeAttribute, index); } } itsCurrentMethod.setCodeAttribute(codeAttribute); itsExceptionTable = null; itsExceptionTableTop = 0; itsLineNumberTableTop = 0; itsCodeBufferTop = 0; itsCurrentMethod = null; itsMaxStack = 0; itsStackTop = 0; itsLabelTableTop = 0; itsFixupTableTop = 0; itsVarDescriptors = null; } /** * Add the single-byte opcode to the current method. * * @param theOpCode the opcode of the bytecode */ public void add(int theOpCode) { if (opcodeCount(theOpCode) != 0) throw new IllegalArgumentException("Unexpected operands"); int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); if (DEBUGCODE) System.out.println("Add " + bytecodeStr(theOpCode)); addToCodeBuffer(theOpCode); itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } /** * Add a single-operand opcode to the current method. * * @param theOpCode the opcode of the bytecode * @param theOperand the operand of the bytecode */ public void add(int theOpCode, int theOperand) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+Integer.toHexString(theOperand)); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); switch (theOpCode) { case ByteCode.GOTO : // fallthru... case ByteCode.IFEQ : case ByteCode.IFNE : case ByteCode.IFLT : case ByteCode.IFGE : case ByteCode.IFGT : case ByteCode.IFLE : case ByteCode.IF_ICMPEQ : case ByteCode.IF_ICMPNE : case ByteCode.IF_ICMPLT : case ByteCode.IF_ICMPGE : case ByteCode.IF_ICMPGT : case ByteCode.IF_ICMPLE : case ByteCode.IF_ACMPEQ : case ByteCode.IF_ACMPNE : case ByteCode.JSR : case ByteCode.IFNULL : case ByteCode.IFNONNULL : { if ((theOperand & 0x80000000) != 0x80000000) { if ((theOperand < 0) || (theOperand > 65535)) throw new IllegalArgumentException( "Bad label for branch"); } int branchPC = itsCodeBufferTop; addToCodeBuffer(theOpCode); if ((theOperand & 0x80000000) != 0x80000000) { // hard displacement addToCodeInt16(theOperand); } else { // a label int targetPC = getLabelPC(theOperand); if (DEBUGLABELS) { int theLabel = theOperand & 0x7FFFFFFF; System.out.println("Fixing branch to " + theLabel + " at " + targetPC + " from " + branchPC); } if (targetPC != -1) { int offset = targetPC - branchPC; addToCodeInt16(offset); } else { addLabelFixup(theOperand, branchPC + 1); addToCodeInt16(0); } } } break; case ByteCode.BIPUSH : if ((byte)theOperand != theOperand) throw new IllegalArgumentException("out of range byte"); addToCodeBuffer(theOpCode); addToCodeBuffer((byte)theOperand); break; case ByteCode.SIPUSH : if ((short)theOperand != theOperand) throw new IllegalArgumentException("out of range short"); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); break; case ByteCode.NEWARRAY : if (!(0 <= theOperand && theOperand < 256)) throw new IllegalArgumentException("out of range index"); addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); break; case ByteCode.GETFIELD : case ByteCode.PUTFIELD : if (!(0 <= theOperand && theOperand < 65536)) throw new IllegalArgumentException("out of range field"); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); break; case ByteCode.LDC : case ByteCode.LDC_W : case ByteCode.LDC2_W : if (!(0 <= theOperand && theOperand < 65536)) throw new IllegalArgumentException("out of range index"); if (theOperand >= 256 || theOpCode == ByteCode.LDC_W || theOpCode == ByteCode.LDC2_W) { if (theOpCode == ByteCode.LDC) { addToCodeBuffer(ByteCode.LDC_W); } else { addToCodeBuffer(theOpCode); } addToCodeInt16(theOperand); } else { addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); } break; case ByteCode.RET : case ByteCode.ILOAD : case ByteCode.LLOAD : case ByteCode.FLOAD : case ByteCode.DLOAD : case ByteCode.ALOAD : case ByteCode.ISTORE : case ByteCode.LSTORE : case ByteCode.FSTORE : case ByteCode.DSTORE : case ByteCode.ASTORE : if (!(0 <= theOperand && theOperand < 65536)) throw new IllegalArgumentException("out of range variable"); if (theOperand >= 256) { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(theOpCode); addToCodeInt16(theOperand); } else { addToCodeBuffer(theOpCode); addToCodeBuffer(theOperand); } break; default : throw new IllegalArgumentException( "Unexpected opcode for 1 operand"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } /** * Generate the load constant bytecode for the given integer. * * @param k the constant */ public void addLoadConstant(int k) { add(ByteCode.LDC, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given long. * * @param k the constant */ public void addLoadConstant(long k) { add(ByteCode.LDC2_W, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given float. * * @param k the constant */ public void addLoadConstant(float k) { add(ByteCode.LDC, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given double. * * @param k the constant */ public void addLoadConstant(double k) { add(ByteCode.LDC2_W, itsConstantPool.addConstant(k)); } /** * Generate the load constant bytecode for the given string. * * @param k the constant */ public void addLoadConstant(String k) { add(ByteCode.LDC, itsConstantPool.addConstant(k)); } /** * Add the given two-operand bytecode to the current method. * * @param theOpCode the opcode of the bytecode * @param theOperand1 the first operand of the bytecode * @param theOperand2 the second operand of the bytecode */ public void add(int theOpCode, int theOperand1, int theOperand2) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+Integer.toHexString(theOperand1) +", "+Integer.toHexString(theOperand2)); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); if (theOpCode == ByteCode.IINC) { if (!(0 <= theOperand1 && theOperand1 < 65536)) throw new IllegalArgumentException("out of range variable"); if (!(0 <= theOperand2 && theOperand2 < 65536)) throw new IllegalArgumentException("out of range increment"); if (theOperand1 > 255 || theOperand2 < -128 || theOperand2 > 127) { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(ByteCode.IINC); addToCodeInt16(theOperand1); addToCodeInt16(theOperand2); } else { addToCodeBuffer(ByteCode.WIDE); addToCodeBuffer(ByteCode.IINC); addToCodeBuffer(theOperand1); addToCodeBuffer(theOperand2); } } else if (theOpCode == ByteCode.MULTIANEWARRAY) { if (!(0 <= theOperand1 && theOperand1 < 65536)) throw new IllegalArgumentException("out of range index"); if (!(0 <= theOperand2 && theOperand2 < 256)) throw new IllegalArgumentException("out of range dimensions"); addToCodeBuffer(ByteCode.MULTIANEWARRAY); addToCodeInt16(theOperand1); addToCodeBuffer(theOperand2); } else { throw new IllegalArgumentException( "Unexpected opcode for 2 operands"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } public void add(int theOpCode, String className) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+className); } int newStack = itsStackTop + stackChange(theOpCode); if (newStack < 0 || Short.MAX_VALUE < newStack) badStack(newStack); switch (theOpCode) { case ByteCode.NEW : case ByteCode.ANEWARRAY : case ByteCode.CHECKCAST : case ByteCode.INSTANCEOF : { short classIndex = itsConstantPool.addClass(className); addToCodeBuffer(theOpCode); addToCodeInt16(classIndex); } break; default : throw new IllegalArgumentException( "bad opcode for class reference"); } itsStackTop = (short)newStack; if (newStack > itsMaxStack) itsMaxStack = (short)newStack; if (DEBUGSTACK) { System.out.println("After "+bytecodeStr(theOpCode) +" stack = "+itsStackTop); } } public void add(int theOpCode, String className, String fieldName, String fieldType) { if (DEBUGCODE) { System.out.println("Add "+bytecodeStr(theOpCode) +", "+className+", "+fieldName+", "+fieldType); } int newStack = itsStackTop + stackChange(theOpCode); char fieldTypeChar = fieldType.charAt(0); int fieldSize = (fieldTypeChar == 'J' || fieldTypeChar == 'D') ? 2 : 1; switch (theOpCode) { case ByteCode.GETFIELD : case ByteCode.GETSTATIC : newStack += fieldSize; break; case ByteCode.PUTSTATIC : case ByteCode.PUTFIELD : newStack -= fieldSize; break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -