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
21package com.sun.org.apache.bcel.internal.classfile;
22
23import java.io.DataInput;
24import java.io.DataOutputStream;
25import java.io.IOException;
26
27import 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 */
37public 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     */
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     */
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     */
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
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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     */
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
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     */
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
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     */
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