javassist.bytecode.ExceptionTable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of javassist Show documentation
Show all versions of javassist Show documentation
Javassist (JAVA programming ASSISTant) makes Java bytecode manipulation
simple. It is a class library for editing bytecodes in Java.
/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later,
* or the Apache License Version 2.0.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.bytecode;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
class ExceptionTableEntry {
int startPc;
int endPc;
int handlerPc;
int catchType;
ExceptionTableEntry(int start, int end, int handle, int type) {
startPc = start;
endPc = end;
handlerPc = handle;
catchType = type;
}
}
/**
* exception_table[]
of Code_attribute
.
*/
public class ExceptionTable implements Cloneable {
private ConstPool constPool;
private List entries;
/**
* Constructs an exception_table[]
.
*
* @param cp constant pool table.
*/
public ExceptionTable(ConstPool cp) {
constPool = cp;
entries = new ArrayList();
}
ExceptionTable(ConstPool cp, DataInputStream in) throws IOException {
constPool = cp;
int length = in.readUnsignedShort();
List list = new ArrayList(length);
for (int i = 0; i < length; ++i) {
int start = in.readUnsignedShort();
int end = in.readUnsignedShort();
int handle = in.readUnsignedShort();
int type = in.readUnsignedShort();
list.add(new ExceptionTableEntry(start, end, handle, type));
}
entries = list;
}
/**
* Creates and returns a copy of this object.
* The constant pool object is shared between this object
* and the cloned object.
*/
@Override
public Object clone() throws CloneNotSupportedException {
ExceptionTable r = (ExceptionTable)super.clone();
r.entries = new ArrayList(entries);
return r;
}
/**
* Returns exception_table_length
, which is the number
* of entries in the exception_table[]
.
*/
public int size() {
return entries.size();
}
/**
* Returns startPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
*/
public int startPc(int nth) {
return entries.get(nth).startPc;
}
/**
* Sets startPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
* @param value new value.
*/
public void setStartPc(int nth, int value) {
entries.get(nth).startPc = value;
}
/**
* Returns endPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
*/
public int endPc(int nth) {
return entries.get(nth).endPc;
}
/**
* Sets endPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
* @param value new value.
*/
public void setEndPc(int nth, int value) {
entries.get(nth).endPc = value;
}
/**
* Returns handlerPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
*/
public int handlerPc(int nth) {
return entries.get(nth).handlerPc;
}
/**
* Sets handlerPc
of the n-th entry.
*
* @param nth the n-th (>= 0).
* @param value new value.
*/
public void setHandlerPc(int nth, int value) {
entries.get(nth).handlerPc = value;
}
/**
* Returns catchType
of the n-th entry.
*
* @param nth the n-th (>= 0).
* @return an index into the constant_pool
table,
* or zero if this exception handler is for all exceptions.
*/
public int catchType(int nth) {
return entries.get(nth).catchType;
}
/**
* Sets catchType
of the n-th entry.
*
* @param nth the n-th (>= 0).
* @param value new value.
*/
public void setCatchType(int nth, int value) {
entries.get(nth).catchType = value;
}
/**
* Copies the given exception table at the specified position
* in the table.
*
* @param index index (>= 0) at which the entry is to be inserted.
* @param offset the offset added to the code position.
*/
public void add(int index, ExceptionTable table, int offset) {
int len = table.size();
while (--len >= 0) {
ExceptionTableEntry e = table.entries.get(len);
add(index, e.startPc + offset, e.endPc + offset,
e.handlerPc + offset, e.catchType);
}
}
/**
* Adds a new entry at the specified position in the table.
*
* @param index index (>= 0) at which the entry is to be inserted.
* @param start startPc
* @param end endPc
* @param handler handlerPc
* @param type catchType
*/
public void add(int index, int start, int end, int handler, int type) {
if (start < end)
entries.add(index,
new ExceptionTableEntry(start, end, handler, type));
}
/**
* Appends a new entry at the end of the table.
*
* @param start startPc
* @param end endPc
* @param handler handlerPc
* @param type catchType
*/
public void add(int start, int end, int handler, int type) {
if (start < end)
entries.add(new ExceptionTableEntry(start, end, handler, type));
}
/**
* Removes the entry at the specified position in the table.
*
* @param index the index of the removed entry.
*/
public void remove(int index) {
entries.remove(index);
}
/**
* Makes a copy of this exception_table[]
.
* Class names are replaced according to the
* given Map
object.
*
* @param newCp the constant pool table used by the new copy.
* @param classnames pairs of replaced and substituted
* class names.
*/
public ExceptionTable copy(ConstPool newCp, Map classnames) {
ExceptionTable et = new ExceptionTable(newCp);
ConstPool srcCp = constPool;
for (ExceptionTableEntry e:entries) {
int type = srcCp.copy(e.catchType, newCp, classnames);
et.add(e.startPc, e.endPc, e.handlerPc, type);
}
return et;
}
void shiftPc(int where, int gapLength, boolean exclusive) {
for (ExceptionTableEntry e:entries) {
e.startPc = shiftPc(e.startPc, where, gapLength, exclusive);
e.endPc = shiftPc(e.endPc, where, gapLength, exclusive);
e.handlerPc = shiftPc(e.handlerPc, where, gapLength, exclusive);
}
}
private static int shiftPc(int pc, int where, int gapLength,
boolean exclusive) {
if (pc > where || (exclusive && pc == where))
pc += gapLength;
return pc;
}
void write(DataOutputStream out) throws IOException {
out.writeShort(size()); // exception_table_length
for (ExceptionTableEntry e:entries) {
out.writeShort(e.startPc);
out.writeShort(e.endPc);
out.writeShort(e.handlerPc);
out.writeShort(e.catchType);
}
}
}