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
22package com.sun.org.apache.bcel.internal.generic;
23
24
25/**
26 * Super class for JSR - Jump to subroutine
27 *
28 * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
29 */
30public abstract class JsrInstruction extends BranchInstruction
31  implements UnconditionalBranch, TypedInstruction, StackProducer
32{
33  JsrInstruction(short opcode, InstructionHandle target) {
34    super(opcode, target);
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  /** @return return address type
44   */
45  public Type getType(ConstantPoolGen cp) {
46    return new ReturnaddressType(physicalSuccessor());
47  }
48
49  /**
50   * Returns an InstructionHandle to the physical successor
51   * of this JsrInstruction. <B>For this method to work,
52   * this JsrInstruction object must not be shared between
53   * multiple InstructionHandle objects!</B>
54   * Formally, there must not be InstructionHandle objects
55   * i, j where i != j and i.getInstruction() == this ==
56   * j.getInstruction().
57   * @return an InstructionHandle to the "next" instruction that
58   * will be executed when RETurned from a subroutine.
59   */
60  public InstructionHandle physicalSuccessor(){
61    InstructionHandle ih = this.target;
62
63    // Rewind!
64    while(ih.getPrev() != null)
65      ih = ih.getPrev();
66
67    // Find the handle for "this" JsrInstruction object.
68    while(ih.getInstruction() != this)
69      ih = ih.getNext();
70
71    InstructionHandle toThis = ih;
72
73    while(ih != null){
74        ih = ih.getNext();
75        if ((ih != null) && (ih.getInstruction() == this))
76        throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction.");
77    }
78
79    // Return the physical successor
80    return toThis.getNext();
81  }
82}
83