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