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 + -
显示快捷键?