1 /*
2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3  */
4 /*
5  * Licensed to the Apache Software Foundation (ASF) under one or more
6  * contributor license agreements.  See the NOTICE file distributed with
7  * this work for additional information regarding copyright ownership.
8  * The ASF licenses this file to You under the Apache License, Version 2.0
9  * (the "License"); you may not use this file except in compliance with
10  * the License.  You may obtain a copy of the License at
11  *
12  *      http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 package com.sun.org.apache.bcel.internal.classfile;
22 
23 import java.io.DataInput;
24 import java.io.DataOutputStream;
25 import java.io.IOException;
26 
27 import com.sun.org.apache.bcel.internal.Const;
28 
29 /**
30  * This class represents an entry in the exception table of the <em>Code</em>
31  * attribute and is used only there. It contains a range in which a
32  * particular exception handler is active.
33  *
34  * @version $Id: CodeException.java 1749603 2016-06-21 20:50:19Z ggregory $
35  * @see     Code
36  */
37 public final class CodeException implements Cloneable, Node {
38 
39     private int start_pc; // Range in the code the exception handler is
40     private int end_pc; // active. start_pc is inclusive, end_pc exclusive
41     private int handler_pc; /* Starting address of exception handler, i.e.,
42      * an offset from start of code.
43      */
44     private int catch_type; /* If this is zero the handler catches any
45      * exception, otherwise it points to the
46      * exception class which is to be caught.
47      */
48 
49 
50     /**
51      * Initialize from another object.
52      */
CodeException(final CodeException c)53     public CodeException(final CodeException c) {
54         this(c.getStartPC(), c.getEndPC(), c.getHandlerPC(), c.getCatchType());
55     }
56 
57 
58     /**
59      * Construct object from file stream.
60      * @param file Input stream
61      * @throws IOException
62      */
CodeException(final DataInput file)63     CodeException(final DataInput file) throws IOException {
64         this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), file
65                 .readUnsignedShort());
66     }
67 
68 
69     /**
70      * @param start_pc Range in the code the exception handler is active,
71      * start_pc is inclusive while
72      * @param end_pc is exclusive
73      * @param handler_pc Starting address of exception handler, i.e.,
74      * an offset from start of code.
75      * @param catch_type If zero the handler catches any
76      * exception, otherwise it points to the exception class which is
77      * to be caught.
78      */
CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type)79     public CodeException(final int start_pc, final int end_pc, final int handler_pc, final int catch_type) {
80         this.start_pc = start_pc;
81         this.end_pc = end_pc;
82         this.handler_pc = handler_pc;
83         this.catch_type = catch_type;
84     }
85 
86 
87     /**
88      * Called by objects that are traversing the nodes of the tree implicitely
89      * defined by the contents of a Java class. I.e., the hierarchy of methods,
90      * fields, attributes, etc. spawns a tree of objects.
91      *
92      * @param v Visitor object
93      */
94     @Override
accept( final Visitor v )95     public void accept( final Visitor v ) {
96         v.visitCodeException(this);
97     }
98 
99 
100     /**
101      * Dump code exception to file stream in binary format.
102      *
103      * @param file Output file stream
104      * @throws IOException
105      */
dump( final DataOutputStream file )106     public final void dump( final DataOutputStream file ) throws IOException {
107         file.writeShort(start_pc);
108         file.writeShort(end_pc);
109         file.writeShort(handler_pc);
110         file.writeShort(catch_type);
111     }
112 
113 
114     /**
115      * @return 0, if the handler catches any exception, otherwise it points to
116      * the exception class which is to be caught.
117      */
getCatchType()118     public final int getCatchType() {
119         return catch_type;
120     }
121 
122 
123     /**
124      * @return Exclusive end index of the region where the handler is active.
125      */
getEndPC()126     public final int getEndPC() {
127         return end_pc;
128     }
129 
130 
131     /**
132      * @return Starting address of exception handler, relative to the code.
133      */
getHandlerPC()134     public final int getHandlerPC() {
135         return handler_pc;
136     }
137 
138 
139     /**
140      * @return Inclusive start index of the region where the handler is active.
141      */
getStartPC()142     public final int getStartPC() {
143         return start_pc;
144     }
145 
146 
147     /**
148      * @param catch_type the type of exception that is caught
149      */
setCatchType( final int catch_type )150     public final void setCatchType( final int catch_type ) {
151         this.catch_type = catch_type;
152     }
153 
154 
155     /**
156      * @param end_pc end of handled block
157      */
setEndPC( final int end_pc )158     public final void setEndPC( final int end_pc ) {
159         this.end_pc = end_pc;
160     }
161 
162 
163     /**
164      * @param handler_pc where the actual code is
165      */
setHandlerPC( final int handler_pc )166     public final void setHandlerPC( final int handler_pc ) { // TODO unused
167         this.handler_pc = handler_pc;
168     }
169 
170 
171     /**
172      * @param start_pc start of handled block
173      */
setStartPC( final int start_pc )174     public final void setStartPC( final int start_pc ) { // TODO unused
175         this.start_pc = start_pc;
176     }
177 
178 
179     /**
180      * @return String representation.
181      */
182     @Override
toString()183     public final String toString() {
184         return "CodeException(start_pc = " + start_pc + ", end_pc = " + end_pc + ", handler_pc = "
185                 + handler_pc + ", catch_type = " + catch_type + ")";
186     }
187 
188 
189     /**
190      * @return String representation.
191      */
toString( final ConstantPool cp, final boolean verbose )192     public final String toString( final ConstantPool cp, final boolean verbose ) {
193         String str;
194         if (catch_type == 0) {
195             str = "<Any exception>(0)";
196         } else {
197             str = Utility.compactClassName(cp.getConstantString(catch_type, Const.CONSTANT_Class), false)
198                     + (verbose ? "(" + catch_type + ")" : "");
199         }
200         return start_pc + "\t" + end_pc + "\t" + handler_pc + "\t" + str;
201     }
202 
203 
toString( final ConstantPool cp )204     public final String toString( final ConstantPool cp ) {
205         return toString(cp, true);
206     }
207 
208 
209     /**
210      * @return deep copy of this object
211      */
copy()212     public CodeException copy() {
213         try {
214             return (CodeException) clone();
215         } catch (final CloneNotSupportedException e) {
216             // TODO should this throw?
217         }
218         return null;
219     }
220 }
221