1 /*
   2  * reserved comment block
   3  * DO NOT REMOVE OR ALTER!
   4  */
   5 /*
   6  * Licensed to the Apache Software Foundation (ASF) under one or more
   7  * contributor license agreements.  See the NOTICE file distributed with
   8  * this work for additional information regarding copyright ownership.
   9  * The ASF licenses this file to You under the Apache License, Version 2.0
  10  * (the "License"); you may not use this file except in compliance with
  11  * the License.  You may obtain a copy of the License at
  12  *
  13  *      http://www.apache.org/licenses/LICENSE-2.0
  14  *
  15  * Unless required by applicable law or agreed to in writing, software
  16  * distributed under the License is distributed on an "AS IS" BASIS,
  17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  18  * See the License for the specific language governing permissions and
  19  * limitations under the License.
  20  */
  21 package com.sun.org.apache.bcel.internal.generic;
  22 
  23 /**
  24  * BranchHandle is returned by specialized InstructionList.append() whenever a
  25  * BranchInstruction is appended. This is useful when the target of this
  26  * instruction is not known at time of creation and must be set later
  27  * via setTarget().
  28  *
  29  * @see InstructionHandle
  30  * @see Instruction
  31  * @see InstructionList
  32  */
  33 public final class BranchHandle extends InstructionHandle {
  34 
  35     // This is also a cache in case the InstructionHandle#swapInstruction() method is used
  36     // See BCEL-273
  37     private BranchInstruction bi; // An alias in fact, but saves lots of casts
  38 
  39 
  40     private BranchHandle(final BranchInstruction i) {
  41         super(i);
  42         bi = i;
  43     }
  44 
  45     /** Factory method.
  46      */
  47     static BranchHandle getBranchHandle( final BranchInstruction i ) {
  48         return new BranchHandle(i);
  49     }
  50 
  51 
  52     /* Override InstructionHandle methods: delegate to branch instruction.
  53      * Through this overriding all access to the private i_position field should
  54      * be prevented.
  55      */
  56     @Override
  57     public int getPosition() {
  58         return bi.getPosition();
  59     }
  60 
  61 
  62     @Override
  63     void setPosition( final int pos ) {
  64         // Original code: i_position = bi.position = pos;
  65         bi.setPosition(pos);
  66         super.setPosition(pos);
  67     }
  68 
  69 
  70     @Override
  71     protected int updatePosition( final int offset, final int max_offset ) {
  72         final int x = bi.updatePosition(offset, max_offset);
  73         super.setPosition(bi.getPosition());
  74         return x;
  75     }
  76 
  77 
  78     /**
  79      * Pass new target to instruction.
  80      */
  81     public void setTarget( final InstructionHandle ih ) {
  82         bi.setTarget(ih);
  83     }
  84 
  85 
  86     /**
  87      * Update target of instruction.
  88      */
  89     public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
  90         bi.updateTarget(old_ih, new_ih);
  91     }
  92 
  93 
  94     /**
  95      * @return target of instruction.
  96      */
  97     public InstructionHandle getTarget() {
  98         return bi.getTarget();
  99     }
 100 
 101 
 102     /**
 103      * Set new contents. Old instruction is disposed and may not be used anymore.
 104      */
 105     @Override // This is only done in order to apply the additional type check; could be merged with super impl.
 106     public void setInstruction( final Instruction i ) { // TODO could be package-protected?
 107         super.setInstruction(i);
 108         if (!(i instanceof BranchInstruction)) {
 109             throw new ClassGenException("Assigning " + i
 110                     + " to branch handle which is not a branch instruction");
 111         }
 112         bi = (BranchInstruction) i;
 113     }
 114 }