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 
  22 package com.sun.org.apache.bcel.internal.generic;
  23 
  24 /**
  25  * Super class for JSR - Jump to subroutine
  26  *
  27  * @version $Id: JsrInstruction.java 1749603 2016-06-21 20:50:19Z ggregory $
  28  */
  29 public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch,
  30         TypedInstruction, StackProducer {
  31 
  32     JsrInstruction(final short opcode, final InstructionHandle target) {
  33         super(opcode, target);
  34     }
  35 
  36 
  37     /**
  38      * Empty constructor needed for the Class.newInstance() statement in
  39      * Instruction.readInstruction(). Not to be used otherwise.
  40      */
  41     JsrInstruction() {
  42     }
  43 
  44 
  45     /** @return return address type
  46      */
  47     @Override
  48     public Type getType( final ConstantPoolGen cp ) {
  49         return new ReturnaddressType(physicalSuccessor());
  50     }
  51 
  52 
  53     /**
  54      * Returns an InstructionHandle to the physical successor
  55      * of this JsrInstruction. <B>For this method to work,
  56      * this JsrInstruction object must not be shared between
  57      * multiple InstructionHandle objects!</B>
  58      * Formally, there must not be InstructionHandle objects
  59      * i, j where i != j and i.getInstruction() == this ==
  60      * j.getInstruction().
  61      * @return an InstructionHandle to the "next" instruction that
  62      * will be executed when RETurned from a subroutine.
  63      */
  64     public InstructionHandle physicalSuccessor() {
  65         InstructionHandle ih = super.getTarget();
  66         // Rewind!
  67         while (ih.getPrev() != null) {
  68             ih = ih.getPrev();
  69         }
  70         // Find the handle for "this" JsrInstruction object.
  71         while (ih.getInstruction() != this) {
  72             ih = ih.getNext();
  73         }
  74         final InstructionHandle toThis = ih;
  75         while (ih != null) {
  76             ih = ih.getNext();
  77             if ((ih != null) && (ih.getInstruction() == this)) {
  78                 throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction.");
  79             }
  80         }
  81         // Return the physical successor
  82         return toThis.getNext();
  83     }
  84 }