001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.commons.compress.harmony.unpack200.bytecode; 020 021import java.io.DataOutputStream; 022import java.io.IOException; 023import java.util.List; 024 025/** 026 * An entry in an exception table. 027 */ 028public class ExceptionTableEntry { 029 030 private final int startPC; 031 private final int endPC; 032 private final int handlerPC; 033 private final CPClass catchType; 034 035 private int startPcRenumbered; 036 private int endPcRenumbered; 037 private int handlerPcRenumbered; 038 private int catchTypeIndex; 039 040 /** 041 * Constructs a new ExceptionTableEntry. Exception tables are of two kinds: either a normal one (with a Throwable as the catchType) or a finally clause 042 * (which has no catchType). In the class file, the finally clause is represented as catchType == 0. 043 * 044 * To create a finally clause with this method, pass in null for the catchType. 045 * 046 * @param startPC int 047 * @param endPC int 048 * @param handlerPC int 049 * @param catchType CPClass (if it's a normal catch) or null (if it's a finally clause). 050 */ 051 public ExceptionTableEntry(final int startPC, final int endPC, final int handlerPC, final CPClass catchType) { 052 this.startPC = startPC; 053 this.endPC = endPC; 054 this.handlerPC = handlerPC; 055 this.catchType = catchType; 056 } 057 058 public CPClass getCatchType() { 059 return catchType; 060 } 061 062 public void renumber(final List<Integer> byteCodeOffsets) { 063 startPcRenumbered = byteCodeOffsets.get(startPC).intValue(); 064 final int endPcIndex = startPC + endPC; 065 endPcRenumbered = byteCodeOffsets.get(endPcIndex).intValue(); 066 final int handlerPcIndex = endPcIndex + handlerPC; 067 handlerPcRenumbered = byteCodeOffsets.get(handlerPcIndex).intValue(); 068 } 069 070 public void resolve(final ClassConstantPool pool) { 071 if (catchType == null) { 072 // If the catch type is a finally clause 073 // the index is always 0. 074 catchTypeIndex = 0; 075 return; 076 } 077 catchType.resolve(pool); 078 catchTypeIndex = pool.indexOf(catchType); 079 } 080 081 public void write(final DataOutputStream dos) throws IOException { 082 dos.writeShort(startPcRenumbered); 083 dos.writeShort(endPcRenumbered); 084 dos.writeShort(handlerPcRenumbered); 085 dos.writeShort(catchTypeIndex); 086 } 087}