codevisitor.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 805 行 · 第 1/2 页

JAVA
805
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.bytecode;import com.caucho.log.Log;import com.caucho.util.IntArray;import com.caucho.util.L10N;import java.util.ArrayList;import java.util.logging.Logger;/** * Visitor for travelling the code. */public class CodeVisitor {  static private final Logger log = Log.open(CodeVisitor.class);  static private final L10N L = new L10N(CodeVisitor.class);  private JavaClass _javaClass;  protected CodeAttribute _codeAttr;  private byte []_code;  protected int _offset;  public CodeVisitor()  {  }  public CodeVisitor(JavaClass javaClass, CodeAttribute codeAttr)  {    init(javaClass, codeAttr);  }  public void init(JavaClass javaClass, CodeAttribute codeAttr)  {    _javaClass = javaClass;    _codeAttr = codeAttr;    _code = codeAttr.getCode();    _offset = 0;  }  /**   * Returns the java class.   */  public JavaClass getJavaClass()  {    return _javaClass;  }    /**   * Returns the code attribute.   */  public CodeAttribute getCodeAttribute()  {    return _codeAttr;  }  /**   * Returns the offset.   */  public int getOffset()  {    return _offset;  }  /**   * Sets the offset.   */  public void setOffset(int offset)  {    _offset = offset;  }  /**   * Returns the code buffer.   */  public byte []getCode()  {    return _code;  }  /**   * Returns the exceptions.   */  public ArrayList<CodeAttribute.ExceptionItem> getExceptions()  {    return _codeAttr.getExceptions();  }  /**   * Returns the opcode at the cursor.   */  public int getOpcode()  {    int op = getCode()[_offset] & 0xff;    if (op == WIDE)      return getCode()[_offset + 1] & 0xff;    else      return op;   }  /**   * Goes to the next opcode.   */  public boolean next()  {    _offset = nextOffset();    return _offset >= 0;  }  /**   * Goes to the next opcode.   */  protected int nextOffset()  {    int opcode = getCode()[_offset] & 0xff;        int length = OP_LEN[opcode];    switch (opcode) {    case GOTO:    case GOTO_W:    case RET:    case IRETURN:    case LRETURN:    case FRETURN:    case DRETURN:    case ARETURN:    case RETURN:    case ATHROW:      return -1;    case TABLESWITCH:      {	int arg = _offset + 1;	arg += (4 - arg % 4) % 4;	int low = getInt(arg + 4);	int high = getInt(arg + 8);	return arg + 12 + (high - low + 1) * 4;      }    case LOOKUPSWITCH:      {	return -1;		/*	int arg = _offset + 1;	arg += (4 - arg % 4) % 4;	int n = getInt(arg + 4);	int next = arg + 12 + n * 8;	return next;	*/      }    case WIDE:      {	int op2 = getCode()[_offset + 1] & 0xff;	if (op2 == IINC)	  length = 5;	else	  length = 3;	break;      }    }        if (length < 0 || length > 0x10)      throw new UnsupportedOperationException(L.l("{0}: can't handle opcode {1}",						  "" + _offset,						  "" + getOpcode()));    return _offset + length + 1;  }  /**   * Returns true for a simple branch, i.e. a branch with a simple target.   */  public boolean isBranch()  {    switch (getOpcode()) {    case IFNULL:    case IFNONNULL:    case IFNE:    case IFEQ:    case IFLT:    case IFGE:    case IFGT:    case IFLE:    case IF_ICMPEQ:    case IF_ICMPNE:    case IF_ICMPLT:    case IF_ICMPGE:    case IF_ICMPGT:    case IF_ICMPLE:    case IF_ACMPEQ:    case IF_ACMPNE:    case JSR:    case JSR_W:    case GOTO:    case GOTO_W:      return true;    }    return false;  }  /**   * Returns the branch target.   */  public int getBranchTarget()  {    switch (getOpcode()) {    case IFNULL:    case IFNONNULL:    case IFNE:    case IFEQ:    case IFLT:    case IFGE:    case IFGT:    case IFLE:    case IF_ICMPEQ:    case IF_ICMPNE:    case IF_ICMPLT:    case IF_ICMPLE:    case IF_ICMPGE:    case IF_ICMPGT:    case IF_ACMPEQ:    case IF_ACMPNE:    case GOTO:    case JSR:      return _offset + getShortArg();          case GOTO_W:    case JSR_W:      return _offset + getIntArg();    default:      throw new UnsupportedOperationException();    }  }  /**   * Returns true for a switch.   */  public boolean isSwitch()  {    switch (getOpcode()) {    case TABLESWITCH:    case LOOKUPSWITCH:      return true;    default:      return false;    }  }  /**   * Returns the branch target.   */  public int []getSwitchTargets()  {    switch (getOpcode()) {    case TABLESWITCH:      {	int arg = _offset + 1;	arg += (4 - arg % 4) % 4;		int low = getInt(arg + 4);	int high = getInt(arg + 8);	int []targets = new int[high - low + 2];	targets[0] = getInt(arg) + _offset;		for (int i = 0; i <= high - low; i++) {	  targets[i + 1] = getInt(arg + 12 + i * 4) + _offset;	}	return targets;      }          case LOOKUPSWITCH:      {	int arg = _offset + 1;	arg += (4 - arg % 4) % 4;	int n = getInt(arg + 4);	int []targets = new int[n + 1];	targets[0] = getInt(arg) + _offset;		for (int i = 0; i < n; i++) {	  int off = arg + 8 + i * 8 + 4;	  	  targets[i + 1] = getInt(off) + _offset;	}	return targets;      }    default:      throw new UnsupportedOperationException("getSwitchTargets");    }  }  /**   * Returns a constant pool item.   */  public ConstantPoolEntry getConstantArg()  {    switch (getOpcode()) {    case LDC:      return _javaClass.getConstantPool().getEntry(getByteArg());          case LDC_W:      return _javaClass.getConstantPool().getEntry(getShortArg());    default:      throw new UnsupportedOperationException();    }  }  /**   * Reads a byte argument.   */  public int getByteArg()  {    return getCode()[_offset + 1];  }  /**   * Gets a byte arg   */  public int getByteArg(int offset)  {    return getByte(_offset + offset);  }  /**   * Sets a byte value.   */  public void setByteArg(int offset, int value)  {    getCode()[_offset + offset + 0] = (byte) value;  }  /**   * Reads a short argument.   */  public int getShortArg()  {    return getShort(_offset + 1);  }  /**   * Sets a short value.   */  public int getShortArg(int offset)  {    return getShort(_offset + offset);  }  /**   * Sets a short value.   */  public void setShortArg(int offset, int value)  {    setShort(_offset + offset, value);  }  /**   * Sets a short value.

⌨️ 快捷键说明

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