⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 codewriter.java

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/***
 * ASM: a very small and fast Java bytecode manipulation framework
 * Copyright (c) 2000,2002,2003 INRIA, France Telecom
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holders nor the names of its
 *    contributors may be used to endorse or promote products derived from
 *    this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.objectweb.asm153;

/**
 * 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.
 * 
 * @author Eric Bruneton
 */

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 index of the constant pool item that contains the name of this method.
   */

  private int name;

  /**
   * The index of the constant pool item that contains the descriptor of this
   * method.
   */

  private int 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;

  /**
   * The non standard attributes of the method.
   */

  private Attribute attrs;

  /**
   * 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;

  /**
   * The non standard attributes of the method's code.
   */

  private Attribute cattrs;

  /**
   * 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,        // -

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -