/*
 * 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.
/** * <code>exception_table[]</code> of <code>Code_attribute</code>. */
public class ExceptionTable implements Cloneable { private ConstPool constPool; private List<ExceptionTableEntry> entries;
Constructs an exception_table[].
Params:
  • cp – constant pool table.
/** * Constructs an <code>exception_table[]</code>. * * @param cp constant pool table. */
public ExceptionTable(ConstPool cp) { constPool = cp; entries = new ArrayList<ExceptionTableEntry>(); } ExceptionTable(ConstPool cp, DataInputStream in) throws IOException { constPool = cp; int length = in.readUnsignedShort(); List<ExceptionTableEntry> list = new ArrayList<ExceptionTableEntry>(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.
/** * 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<ExceptionTableEntry>(entries); return r; }
Returns exception_table_length, which is the number of entries in the exception_table[].
/** * Returns <code>exception_table_length</code>, which is the number * of entries in the <code>exception_table[]</code>. */
public int size() { return entries.size(); }
Returns startPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
/** * Returns <code>startPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). */
public int startPc(int nth) { return entries.get(nth).startPc; }
Sets startPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
  • value – new value.
/** * Sets <code>startPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). * @param value new value. */
public void setStartPc(int nth, int value) { entries.get(nth).startPc = value; }
Returns endPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
/** * Returns <code>endPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). */
public int endPc(int nth) { return entries.get(nth).endPc; }
Sets endPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
  • value – new value.
/** * Sets <code>endPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). * @param value new value. */
public void setEndPc(int nth, int value) { entries.get(nth).endPc = value; }
Returns handlerPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
/** * Returns <code>handlerPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). */
public int handlerPc(int nth) { return entries.get(nth).handlerPc; }
Sets handlerPc of the n-th entry.
Params:
  • nth – the n-th (>= 0).
  • value – new value.
/** * Sets <code>handlerPc</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). * @param value new value. */
public void setHandlerPc(int nth, int value) { entries.get(nth).handlerPc = value; }
Returns catchType of the n-th entry.
Params:
  • nth – the n-th (>= 0).
Returns:an index into the constant_pool table, or zero if this exception handler is for all exceptions.
/** * Returns <code>catchType</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 0). * @return an index into the <code>constant_pool</code> 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.
Params:
  • nth – the n-th (>= 0).
  • value – new value.
/** * Sets <code>catchType</code> of the <i>n</i>-th entry. * * @param nth the <i>n</i>-th (&gt;= 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.
Params:
  • index – index (>= 0) at which the entry is to be inserted.
  • offset – the offset added to the code position.
/** * Copies the given exception table at the specified position * in the table. * * @param index index (&gt;= 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.
Params:
  • index – index (>= 0) at which the entry is to be inserted.
  • start – startPc
  • end – endPc
  • handler – handlerPc
  • type – catchType
/** * Adds a new entry at the specified position in the table. * * @param index index (&gt;= 0) at which the entry is to be inserted. * @param start <code>startPc</code> * @param end <code>endPc</code> * @param handler <code>handlerPc</code> * @param type <code>catchType</code> */
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.
Params:
  • start – startPc
  • end – endPc
  • handler – handlerPc
  • type – catchType
/** * Appends a new entry at the end of the table. * * @param start <code>startPc</code> * @param end <code>endPc</code> * @param handler <code>handlerPc</code> * @param type <code>catchType</code> */
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.
Params:
  • index – the index of the removed entry.
/** * 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.
Params:
  • newCp – the constant pool table used by the new copy.
  • classnames – pairs of replaced and substituted class names.
/** * Makes a copy of this <code>exception_table[]</code>. * Class names are replaced according to the * given <code>Map</code> 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<String,String> 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); } } }