View Javadoc

    1   /*
    2    * Copyright  2000-2004 The Apache Software Foundation
    3    *
    4    *  Licensed under the Apache License, Version 2.0 (the "License");
    5    *  you may not use this file except in compliance with the License.
    6    *  You may obtain a copy of the License at
    7    *
    8    *      http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   *  Unless required by applicable law or agreed to in writing, software
    11   *  distributed under the License is distributed on an "AS IS" BASIS,
    12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   *  See the License for the specific language governing permissions and
    14   *  limitations under the License.
    15   *
    16   */
    17  package org.apache.bcel.generic;
    18
    19  import org.apache.bcel.classfile.CodeException;
    20
    21  /***
    22   * This class represents an exception handler, i.e., specifies the  region where
    23   * a handler is active and an instruction where the actual handling is done.
    24   * pool as parameters. Opposed to the JVM specification the end of the handled
    25   * region is set to be inclusive, i.e. all instructions between start and end
    26   * are protected including the start and end instructions (handles) themselves.
    27   * The end of the region is automatically mapped to be exclusive when calling
    28   * getCodeException(), i.e., there is no difference semantically.
    29   *
    30   * @version $Id: CodeExceptionGen.java 386056 2006-03-15 11:31:56Z tcurdt $
    31   * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
    32   * @see     MethodGen
    33   * @see     CodeException
    34   * @see     InstructionHandle
    35   */
    36  public final class CodeExceptionGen implements InstructionTargeter, Cloneable, java.io.Serializable {
    37
    38      private InstructionHandle start_pc;
    39      private InstructionHandle end_pc;
    40      private InstructionHandle handler_pc;
    41      private ObjectType catch_type;
    42
    43
    44      /***
    45       * Add an exception handler, i.e., specify region where a handler is active and an
    46       * instruction where the actual handling is done.
    47       *
    48       * @param start_pc Start of handled region (inclusive)
    49       * @param end_pc End of handled region (inclusive)
    50       * @param handler_pc Where handling is done
    51       * @param catch_type which exception is handled, null for ANY
    52       */
    53      public CodeExceptionGen(InstructionHandle start_pc, InstructionHandle end_pc,
    54              InstructionHandle handler_pc, ObjectType catch_type) {
    55          setStartPC(start_pc);
    56          setEndPC(end_pc);
    57          setHandlerPC(handler_pc);
    58          this.catch_type = catch_type;
    59      }
    60
    61
    62      /***
    63       * Get CodeException object.<BR>
    64       *
    65       * This relies on that the instruction list has already been dumped
    66       * to byte code or or that the `setPositions' methods has been
    67       * called for the instruction list.
    68       *
    69       * @param cp constant pool
    70       */
    71      public CodeException getCodeException( ConstantPoolGen cp ) {
    72          return new CodeException(start_pc.getPosition(), end_pc.getPosition()
    73                  + end_pc.getInstruction().getLength(), handler_pc.getPosition(),
    74                  (catch_type == null) ? 0 : cp.addClass(catch_type));
    75      }
    76
    77
    78      /* Set start of handler
    79       * @param start_pc Start of handled region (inclusive)
    80       */
    81      public void setStartPC( InstructionHandle start_pc ) {
    82          BranchInstruction.notifyTarget(this.start_pc, start_pc, this);
    83          this.start_pc = start_pc;
    84      }
    85
    86
    87      /* Set end of handler
    88       * @param end_pc End of handled region (inclusive)
    89       */
    90      public void setEndPC( InstructionHandle end_pc ) {
    91          BranchInstruction.notifyTarget(this.end_pc, end_pc, this);
    92          this.end_pc = end_pc;
    93      }
    94
    95
    96      /* Set handler code
    97       * @param handler_pc Start of handler
    98       */
    99      public void setHandlerPC( InstructionHandle handler_pc ) {
    100         BranchInstruction.notifyTarget(this.handler_pc, handler_pc, this);
    101         this.handler_pc = handler_pc;
    102     }
    103
    104
    105     /***
    106      * @param old_ih old target, either start or end
    107      * @param new_ih new target
    108      */
    109     public void updateTarget( InstructionHandle old_ih, InstructionHandle new_ih ) {
    110         boolean targeted = false;
    111         if (start_pc == old_ih) {
    112             targeted = true;
    113             setStartPC(new_ih);
    114         }
    115         if (end_pc == old_ih) {
    116             targeted = true;
    117             setEndPC(new_ih);
    118         }
    119         if (handler_pc == old_ih) {
    120             targeted = true;
    121             setHandlerPC(new_ih);
    122         }
    123         if (!targeted) {
    124             throw new ClassGenException("Not targeting " + old_ih + ", but {" + start_pc + ", "
    125                     + end_pc + ", " + handler_pc + "}");
    126         }
    127     }
    128
    129
    130     /***
    131      * @return true, if ih is target of this handler
    132      */
    133     public boolean containsTarget( InstructionHandle ih ) {
    134         return (start_pc == ih) || (end_pc == ih) || (handler_pc == ih);
    135     }
    136
    137
    138     /*** Sets the type of the Exception to catch. Set 'null' for ANY. */
    139     public void setCatchType( ObjectType catch_type ) {
    140         this.catch_type = catch_type;
    141     }
    142
    143
    144     /*** Gets the type of the Exception to catch, 'null' for ANY. */
    145     public ObjectType getCatchType() {
    146         return catch_type;
    147     }
    148
    149
    150     /*** @return start of handled region (inclusive)
    151      */
    152     public InstructionHandle getStartPC() {
    153         return start_pc;
    154     }
    155
    156
    157     /*** @return end of handled region (inclusive)
    158      */
    159     public InstructionHandle getEndPC() {
    160         return end_pc;
    161     }
    162
    163
    164     /*** @return start of handler
    165      */
    166     public InstructionHandle getHandlerPC() {
    167         return handler_pc;
    168     }
    169
    170
    171     public String toString() {
    172         return "CodeExceptionGen(" + start_pc + ", " + end_pc + ", " + handler_pc + ")";
    173     }
    174
    175
    176     public Object clone() {
    177         try {
    178             return super.clone();
    179         } catch (CloneNotSupportedException e) {
    180             System.err.println(e);
    181             return null;
    182         }
    183     }
    184 }