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