001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 * 017 */ 018package org.apache.bcel.classfile; 019 020import java.io.DataInput; 021import java.io.DataOutputStream; 022import java.io.IOException; 023 024import org.apache.bcel.Const; 025import org.apache.bcel.Constants; 026 027/** 028 * This class represents an entry in the exception table of the <em>Code</em> 029 * attribute and is used only there. It contains a range in which a 030 * particular exception handler is active. 031 * 032 * @version $Id: CodeException.java 1749603 2016-06-21 20:50:19Z ggregory $ 033 * @see Code 034 */ 035public final class CodeException implements Cloneable, Node, Constants { 036 037 private int start_pc; // Range in the code the exception handler is 038 private int end_pc; // active. start_pc is inclusive, end_pc exclusive 039 private int handler_pc; /* Starting address of exception handler, i.e., 040 * an offset from start of code. 041 */ 042 private int catch_type; /* If this is zero the handler catches any 043 * exception, otherwise it points to the 044 * exception class which is to be caught. 045 */ 046 047 048 /** 049 * Initialize from another object. 050 */ 051 public CodeException(final CodeException c) { 052 this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); 053 } 054 055 056 /** 057 * Construct object from file stream. 058 * @param file Input stream 059 * @throws IOException 060 */ 061 CodeException(final DataInput file) throws IOException { 062 this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file 063 .readUnsignedShort()); 064 } 065 066 067 /** 068 * @param start_pc Range in the code the exception handler is active, 069 * start_pc is inclusive while 070 * @param end_pc is exclusive 071 * @param handler_pc Starting address of exception handler, i.e., 072 * an offset from start of code. 073 * @param catch_type If zero the handler catches any 074 * exception, otherwise it points to the exception class which is 075 * to be caught. 076 */ 077 public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) { 078 this.start_pc = start_pc; 079 this.end_pc = end_pc; 080 this.handler_pc = handler_pc; 081 this.catch_type = catch_type; 082 } 083 084 085 /** 086 * Called by objects that are traversing the nodes of the tree implicitely 087 * defined by the contents of a Java class. I.e., the hierarchy of methods, 088 * fields, attributes, etc. spawns a tree of objects. 089 * 090 * @param v Visitor object 091 */ 092 @Override 093 public void accept( final Visitor v ) { 094 v.visitCodeException(this); 095 } 096 097 098 /** 099 * Dump code exception to file stream in binary format. 100 * 101 * @param file Output file stream 102 * @throws IOException 103 */ 104 public final void dump( final DataOutputStream file ) throws IOException { 105 file.writeShort(start_pc); 106 file.writeShort(end_pc); 107 file.writeShort(handler_pc); 108 file.writeShort(catch_type); 109 } 110 111 112 /** 113 * @return 0, if the handler catches any exception, otherwise it points to 114 * the exception class which is to be caught. 115 */ 116 public final int getCatchType() { 117 return catch_type; 118 } 119 120 121 /** 122 * @return Exclusive end index of the region where the handler is active. 123 */ 124 public final int getEndPC() { 125 return end_pc; 126 } 127 128 129 /** 130 * @return Starting address of exception handler, relative to the code. 131 */ 132 public final int getHandlerPC() { 133 return handler_pc; 134 } 135 136 137 /** 138 * @return Inclusive start index of the region where the handler is active. 139 */ 140 public final int getStartPC() { 141 return start_pc; 142 } 143 144 145 /** 146 * @param catch_type the type of exception that is caught 147 */ 148 public final void setCatchType( final int catch_type ) { 149 this.catch_type = catch_type; 150 } 151 152 153 /** 154 * @param end_pc end of handled block 155 */ 156 public final void setEndPC( final int end_pc ) { 157 this.end_pc = end_pc; 158 } 159 160 161 /** 162 * @param handler_pc where the actual code is 163 */ 164 public final void setHandlerPC( final int handler_pc ) { // TODO unused 165 this.handler_pc = handler_pc; 166 } 167 168 169 /** 170 * @param start_pc start of handled block 171 */ 172 public final void setStartPC( final int start_pc ) { // TODO unused 173 this.start_pc = start_pc; 174 } 175 176 177 /** 178 * @return String representation. 179 */ 180 @Override 181 public final String toString() { 182 return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = " 183 + handler_pc + ", catch_type = " + catch_type + ")"; 184 } 185 186 187 /** 188 * @return String representation. 189 */ 190 public final String toString( final ConstantPool cp, final boolean verbose ) { 191 String str; 192 if (catch_type == 0) { 193 str = "<Any exception>(0)"; 194 } else { 195 str = Utility.compactClassName(cp.getConstantString(catch_type, Const.CONSTANT_Class), false) 196 + (verbose ? "(" + catch_type + ")" : ""); 197 } 198 return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str; 199 } 200 201 202 public final String toString( final ConstantPool cp ) { 203 return toString(cp, true); 204 } 205 206 207 /** 208 * @return deep copy of this object 209 */ 210 public CodeException copy() { 211 try { 212 return (CodeException) clone(); 213 } catch (final CloneNotSupportedException e) { 214 // TODO should this throw? 215 } 216 return null; 217 } 218}