1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.generic;
18
19 /***
20 * Super class for JSR - Jump to subroutine
21 *
22 * @version $Id: JsrInstruction.java 386056 2006-03-15 11:31:56Z tcurdt $
23 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
24 */
25 public abstract class JsrInstruction extends BranchInstruction implements UnconditionalBranch,
26 TypedInstruction, StackProducer {
27
28 JsrInstruction(short opcode, InstructionHandle target) {
29 super(opcode, target);
30 }
31
32
33 /***
34 * Empty constructor needed for the Class.newInstance() statement in
35 * Instruction.readInstruction(). Not to be used otherwise.
36 */
37 JsrInstruction() {
38 }
39
40
41 /*** @return return address type
42 */
43 public Type getType( ConstantPoolGen cp ) {
44 return new ReturnaddressType(physicalSuccessor());
45 }
46
47
48 /***
49 * Returns an InstructionHandle to the physical successor
50 * of this JsrInstruction. <B>For this method to work,
51 * this JsrInstruction object must not be shared between
52 * multiple InstructionHandle objects!</B>
53 * Formally, there must not be InstructionHandle objects
54 * i, j where i != j and i.getInstruction() == this ==
55 * j.getInstruction().
56 * @return an InstructionHandle to the "next" instruction that
57 * will be executed when RETurned from a subroutine.
58 */
59 public InstructionHandle physicalSuccessor() {
60 InstructionHandle ih = this.target;
61
62 while (ih.getPrev() != null) {
63 ih = ih.getPrev();
64 }
65
66 while (ih.getInstruction() != this) {
67 ih = ih.getNext();
68 }
69 InstructionHandle toThis = ih;
70 while (ih != null) {
71 ih = ih.getNext();
72 if ((ih != null) && (ih.getInstruction() == this)) {
73 throw new RuntimeException("physicalSuccessor() called on a shared JsrInstruction.");
74 }
75 }
76
77 return toThis.getNext();
78 }
79 }