1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 */ 18 package org.apache.bcel.classfile; 19 20 import java.io.DataInput; 21 import java.io.DataOutputStream; 22 import java.io.IOException; 23 24 import org.apache.bcel.Const; 25 import org.apache.bcel.Constants; 26 27 /** 28 * This class represents an entry in the exception table of the <em>Code</em> 29 * attribute and is used only there. It contains a range in which a 30 * particular exception handler is active. 31 * 32 * @version $Id$ 33 * @see Code 34 */ 35 public final class CodeException implements Cloneable, Node, Constants { 36 37 private int start_pc; // Range in the code the exception handler is 38 private int end_pc; // active. start_pc is inclusive, end_pc exclusive 39 private int handler_pc; /* Starting address of exception handler, i.e., 40 * an offset from start of code. 41 */ 42 private int catch_type; /* If this is zero the handler catches any 43 * exception, otherwise it points to the 44 * exception class which is to be caught. 45 */ 46 47 48 /** 49 * Initialize from another object. 50 */ 51 public CodeException(final CodeException c) { 52 this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType()); 53 } 54 55 56 /** 57 * Construct object from file stream. 58 * @param file Input stream 59 * @throws IOException 60 */ 61 CodeException(final DataInput file) throws IOException { 62 this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file 63 .readUnsignedShort()); 64 } 65 66 67 /** 68 * @param start_pc Range in the code the exception handler is active, 69 * start_pc is inclusive while 70 * @param end_pc is exclusive 71 * @param handler_pc Starting address of exception handler, i.e., 72 * an offset from start of code. 73 * @param catch_type If zero the handler catches any 74 * exception, otherwise it points to the exception class which is 75 * to be caught. 76 */ 77 public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) { 78 this.start_pc = start_pc; 79 this.end_pc = end_pc; 80 this.handler_pc = handler_pc; 81 this.catch_type = catch_type; 82 } 83 84 85 /** 86 * Called by objects that are traversing the nodes of the tree implicitely 87 * defined by the contents of a Java class. I.e., the hierarchy of methods, 88 * fields, attributes, etc. spawns a tree of objects. 89 * 90 * @param v Visitor object 91 */ 92 @Override 93 public void accept( final Visitor v ) { 94 v.visitCodeException(this); 95 } 96 97 98 /** 99 * 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 } 219