📄 codewriter.java
字号:
/*** * ASM: a very small and fast Java bytecode manipulation framework * Copyright (C) 2000 INRIA, France Telecom * Copyright (C) 2002 France Telecom * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact: Eric.Bruneton@rd.francetelecom.com * * Author: Eric Bruneton */package org.objectweb.asm;/** * A {@link CodeVisitor CodeVisitor} that generates Java bytecode instructions. * Each visit method of this class appends the bytecode corresponding to the * visited instruction to a byte vector, in the order these methods are called. */public class CodeWriter implements CodeVisitor { /** * <tt>true</tt> if preconditions must be checked at runtime or not. */ final static boolean CHECK = false; /** * Next code writer (see {@link ClassWriter#firstMethod firstMethod}). */ CodeWriter next; /** * The class writer to which this method must be added. */ private ClassWriter cw; /** * The constant pool item that contains the name of this method. */ private Item name; /** * The constant pool item that contains the descriptor of this method. */ private Item desc; /** * Access flags of this method. */ private int access; /** * Maximum stack size of this method. */ private int maxStack; /** * Maximum number of local variables for this method. */ private int maxLocals; /** * The bytecode of this method. */ private ByteVector code = new ByteVector(); /** * Number of entries in the catch table of this method. */ private int catchCount; /** * The catch table of this method. */ private ByteVector catchTable; /** * Number of exceptions that can be thrown by this method. */ private int exceptionCount; /** * The exceptions that can be thrown by this method. More * precisely, this array contains the indexes of the constant pool items * that contain the internal names of these exception classes. */ private int[] exceptions; /** * Number of entries in the LocalVariableTable attribute. */ private int localVarCount; /** * The LocalVariableTable attribute. */ private ByteVector localVar; /** * Number of entries in the LineNumberTable attribute. */ private int lineNumberCount; /** * The LineNumberTable attribute. */ private ByteVector lineNumber; /** * Indicates if some jump instructions are too small and need to be resized. */ private boolean resize; // -------------------------------------------------------------------------- // Fields for the control flow graph analysis algorithm (used to compute the // maximum stack size). A control flow graph contains one node per "basic // block", and one edge per "jump" from one basic block to another. Each node // (i.e., each basic block) is represented by the Label object that // corresponds to the first instruction of this basic block. Each node also // stores the list of its successors in the graph, as a linked list of Edge // objects. // -------------------------------------------------------------------------- /** * <tt>true</tt> if the maximum stack size and number of local variables must * be automatically computed. */ private final boolean computeMaxs; /** * The (relative) stack size after the last visited instruction. This size is * relative to the beginning of the current basic block, i.e., the true stack * size after the last visited instruction is equal to the {@link * Label#beginStackSize beginStackSize} of the current basic block plus * <tt>stackSize</tt>. */ private int stackSize; /** * The (relative) maximum stack size after the last visited instruction. This * size is relative to the beginning of the current basic block, i.e., the * true maximum stack size after the last visited instruction is equal to the * {@link Label#beginStackSize beginStackSize} of the current basic block plus * <tt>stackSize</tt>. */ private int maxStackSize; /** * The current basic block. This block is the basic block to which the next * instruction to be visited must be added. */ private Label currentBlock; /** * The basic block stack used by the control flow analysis algorithm. This * stack is represented by a linked list of {@link Label Label} objects, * linked to each other by their {@link Label#next} field. This stack must * not be confused with the JVM stack used to execute the JVM instructions! */ private Label blockStack; /** * The stack size variation corresponding to each JVM instruction. This stack * variation is equal to the size of the values produced by an instruction, * minus the size of the values consumed by this instruction. */ private final static int[] SIZE; // -------------------------------------------------------------------------- // Fields to optimize the creation of {@link Edge Edge} objects by using a // pool of reusable objects. The (shared) pool is a linked list of Edge // objects, linked to each other by their {@link Edge#poolNext} field. Each // time a CodeWriter needs to allocate an Edge, it removes the first Edge // of the pool and adds it to a private list of Edge objects. After the end // of the control flow analysis algorithm, the Edge objects in the private // list of the CodeWriter are added back to the pool (by appending this // private list to the pool list; in order to do this in constant time, both // head and tail of the private list are stored in this CodeWriter). // -------------------------------------------------------------------------- /** * The head of the list of {@link Edge Edge} objects used by this {@link * CodeWriter CodeWriter}. These objects, linked to each other by their * {@link Edge#poolNext} field, are added back to the shared pool at the * end of the control flow analysis algorithm. */ private Edge head; /** * The tail of the list of {@link Edge Edge} objects used by this {@link * CodeWriter CodeWriter}. These objects, linked to each other by their * {@link Edge#poolNext} field, are added back to the shared pool at the * end of the control flow analysis algorithm. */ private Edge tail; /** * The shared pool of {@link Edge Edge} objects. This pool is a linked list * of Edge objects, linked to each other by their {@link Edge#poolNext} field. */ private static Edge pool; // -------------------------------------------------------------------------- // Static initializer // -------------------------------------------------------------------------- /** * Computes the stack size variation corresponding to each JVM instruction. */ static { int i; int[] b = new int[202]; String s = "EFFFFFFFFGGFFFGGFFFEEFGFGFEEEEEEEEEEEEEEEEEEEEDEDEDDDDDCDCDEEEEEEEEE" + "EEEEEEEEEEEBABABBBBDCFFFGGGEDCDCDCDCDCDCDCDCDCDCEEEEDDDDDDDCDCDCEFEF" + "DDEEFFDEDEEEBDDBBDDDDDDCCCCCCCCEFEDDDCDCDEEEEEEEEEEFEEEEEEDDEEDDEE"; for (i = 0; i < b.length; ++i) { b[i] = s.charAt(i) - 'E'; } SIZE = b; /* code to generate the above string int NA = 0; // not applicable (unused opcode or variable size opcode) b = new int[] { 0, //NOP, // visitInsn 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, // visitIntInsn 1, //SIPUSH, // - 1, //LDC, // visitLdcInsn NA, //LDC_W, // - NA, //LDC2_W, // - 1, //ILOAD, // visitVarInsn 2, //LLOAD, // - 1, //FLOAD, // - 2, //DLOAD, // - 1, //ALOAD, // - NA, //ILOAD_0, // - NA, //ILOAD_1, // - NA, //ILOAD_2, // - NA, //ILOAD_3, // - NA, //LLOAD_0, // - NA, //LLOAD_1, // - NA, //LLOAD_2, // - NA, //LLOAD_3, // - NA, //FLOAD_0, // - NA, //FLOAD_1, // - NA, //FLOAD_2, // - NA, //FLOAD_3, // - NA, //DLOAD_0, // - NA, //DLOAD_1, // - NA, //DLOAD_2, // - NA, //DLOAD_3, // - NA, //ALOAD_0, // - NA, //ALOAD_1, // - NA, //ALOAD_2, // - NA, //ALOAD_3, // - -1, //IALOAD, // visitInsn 0, //LALOAD, // - -1, //FALOAD, // - 0, //DALOAD, // - -1, //AALOAD, // - -1, //BALOAD, // - -1, //CALOAD, // - -1, //SALOAD, // - -1, //ISTORE, // visitVarInsn -2, //LSTORE, // - -1, //FSTORE, // - -2, //DSTORE, // - -1, //ASTORE, // - NA, //ISTORE_0, // - NA, //ISTORE_1, // - NA, //ISTORE_2, // - NA, //ISTORE_3, // - NA, //LSTORE_0, // - NA, //LSTORE_1, // - NA, //LSTORE_2, // - NA, //LSTORE_3, // - NA, //FSTORE_0, // - NA, //FSTORE_1, // - NA, //FSTORE_2, // - NA, //FSTORE_3, // - NA, //DSTORE_0, // - NA, //DSTORE_1, // - NA, //DSTORE_2, // - NA, //DSTORE_3, // - NA, //ASTORE_0, // - NA, //ASTORE_1, // - NA, //ASTORE_2, // - NA, //ASTORE_3, // - -3, //IASTORE, // visitInsn -4, //LASTORE, // - -3, //FASTORE, // - -4, //DASTORE, // - -3, //AASTORE, // - -3, //BASTORE, // - -3, //CASTORE, // - -3, //SASTORE, // - -1, //POP, // - -2, //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, // - 0, //INEG, // - 0, //LNEG, // - 0, //FNEG, // - 0, //DNEG, // - -1, //ISHL, // - -1, //LSHL, // - -1, //ISHR, // - -1, //LSHR, // - -1, //IUSHR, // - -1, //LUSHR, // - -1, //IAND, // - -2, //LAND, // - -1, //IOR, // - -2, //LOR, // - -1, //IXOR, // - -2, //LXOR, // - 0, //IINC, // visitIincInsn 1, //I2L, // visitInsn 0, //I2F, // - 1, //I2D, // - -1, //L2I, // - -1, //L2F, // - 0, //L2D, // - 0, //F2I, // - 1, //F2L, // - 1, //F2D, // - -1, //D2I, // - 0, //D2L, // - -1, //D2F, // - 0, //I2B, // - 0, //I2C, // - 0, //I2S, // - -3, //LCMP, // - -1, //FCMPL, // - -1, //FCMPG, // - -3, //DCMPL, // - -3, //DCMPG, // - -1, //IFEQ, // visitJumpInsn -1, //IFNE, // - -1, //IFLT, // - -1, //IFGE, // - -1, //IFGT, // - -1, //IFLE, // - -2, //IF_ICMPEQ, // - -2, //IF_ICMPNE, // - -2, //IF_ICMPLT, // - -2, //IF_ICMPGE, // - -2, //IF_ICMPGT, // - -2, //IF_ICMPLE, // - -2, //IF_ACMPEQ, // - -2, //IF_ACMPNE, // - 0, //GOTO, // - 1, //JSR, // - 0, //RET, // visitVarInsn -1, //TABLESWITCH, // visiTableSwitchInsn -1, //LOOKUPSWITCH, // visitLookupSwitch -1, //IRETURN, // visitInsn -2, //LRETURN, // - -1, //FRETURN, // -
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -