1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.jdo.impl.enhancer.classfile;
19
20
21 import java.io.PrintStream;
22 import java.util.Stack;
23
24 /***
25 * An instruction which requires a single branch offset
26 * as an immediate operand .
27 */
28 public class InsnTargetOp extends Insn {
29
30 InsnTarget targetOp;
31
32
33
34 public int nStackArgs() {
35 return VMOp.ops[opcode()].nStackArgs();
36 }
37
38 public int nStackResults() {
39 return VMOp.ops[opcode()].nStackResults();
40 }
41
42 public String argTypes() {
43 return VMOp.ops[opcode()].argTypes();
44 }
45
46 public String resultTypes() {
47 return VMOp.ops[opcode()].resultTypes();
48 }
49
50 public boolean branches() {
51 return true;
52 }
53
54 /***
55 * Mark possible branch targets
56 */
57 public void markTargets() {
58 targetOp.setBranchTarget();
59 }
60
61 /***
62 * Return the branch target which is the immediate operand
63 */
64 public InsnTarget target() {
65 return targetOp;
66 }
67
68 /***
69 * Compares this instance with another for structural equality.
70 */
71
72 public boolean isEqual(Stack msg, Object obj) {
73 if (!(obj instanceof InsnTargetOp)) {
74 msg.push("obj/obj.getClass() = "
75 + (obj == null ? null : obj.getClass()));
76 msg.push("this.getClass() = "
77 + this.getClass());
78 return false;
79 }
80 InsnTargetOp other = (InsnTargetOp)obj;
81
82 if (!super.isEqual(msg, other)) {
83 return false;
84 }
85
86 if (!this.targetOp.isEqual(msg, other.targetOp)) {
87 msg.push(String.valueOf("targetOp = "
88 + other.targetOp));
89 msg.push(String.valueOf("targetOp = "
90 + this.targetOp));
91 return false;
92 }
93 return true;
94 }
95
96 /* package local methods *//package-summary/html">class="comment"> package local methods *//package-summary.html">
97
98 void print (PrintStream out, int indent) {
99 ClassPrint.spaces(out, indent);
100
101 out.println(offset() + " " + opName(opcode()) + " " +
102 targetOp.offset());
103 }
104
105 int store(byte[] buf, int index) {
106 buf[index++] = (byte) opcode();
107 int off = targetOp.offset() - offset();
108 if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
109 return storeInt(buf, index, off);
110 else
111 return storeShort(buf, index, (short)off);
112 }
113
114 int size() {
115 if (opcode() == opc_goto_w || opcode() == opc_jsr_w)
116 return 5;
117 return 3;
118 }
119
120 InsnTargetOp (int theOpcode, InsnTarget theOperand, int pc) {
121 super(theOpcode, pc);
122 targetOp = theOperand;
123 }
124
125 InsnTargetOp (int theOpcode, InsnTarget theOperand) {
126 super(theOpcode, NO_OFFSET);
127
128 targetOp = theOperand;
129
130 switch(theOpcode) {
131 case opc_ifeq:
132 case opc_ifne:
133 case opc_iflt:
134 case opc_ifge:
135 case opc_ifgt:
136 case opc_ifle:
137 case opc_if_icmpeq:
138 case opc_if_icmpne:
139 case opc_if_icmplt:
140 case opc_if_icmpge:
141 case opc_if_icmpgt:
142 case opc_if_icmple:
143 case opc_if_acmpeq:
144 case opc_if_acmpne:
145 case opc_goto:
146 case opc_jsr:
147 case opc_ifnull:
148 case opc_ifnonnull:
149 case opc_goto_w:
150 case opc_jsr_w:
151
152 if (theOperand == null)
153 throw new InsnError ("attempt to create an " + opName(theOpcode) +
154 " with a null Target operand");
155 break;
156
157 default:
158 throw new InsnError ("attempt to create an " + opName(theOpcode) +
159 " with an InsnTarget operand");
160 }
161 }
162 }