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 import java.io.PrintStream;
22 import java.util.Stack;
23
24 /***
25 * An instruction which requires a integral constant as an immediate operand
26 */
27
28 public class InsnIntOp extends Insn {
29
30 private int operandValue;
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 opcode() == opc_ret;
52 }
53
54 public int value() {
55 return operandValue;
56 }
57
58 /***
59 * Compares this instance with another for structural equality.
60 */
61
62 public boolean isEqual(Stack msg, Object obj) {
63 if (!(obj instanceof InsnIntOp)) {
64 msg.push("obj/obj.getClass() = "
65 + (obj == null ? null : obj.getClass()));
66 msg.push("this.getClass() = "
67 + this.getClass());
68 return false;
69 }
70 InsnIntOp other = (InsnIntOp)obj;
71
72 if (!super.isEqual(msg, other)) {
73 return false;
74 }
75
76 if (this.operandValue != other.operandValue) {
77 msg.push(String.valueOf("operandValue = "
78 + other.operandValue));
79 msg.push(String.valueOf("operandValue = "
80 + this.operandValue));
81 return false;
82 }
83 return true;
84 }
85
86 /* package local methods *//package-summary/html">class="comment"> package local methods *//package-summary.html">
87
88 static String primType(int primIndex) {
89 switch (primIndex) {
90 case T_BOOLEAN:
91 return "boolean";
92 case T_CHAR:
93 return "char";
94 case T_FLOAT:
95 return "float";
96 case T_DOUBLE:
97 return "double";
98 case T_BYTE:
99 return "byte";
100 case T_SHORT:
101 return "short";
102 case T_INT:
103 return "int";
104 case T_LONG:
105 return "long";
106 default:
107 throw new InsnError ("Invalid primitive type(" + primIndex + ")");
108 }
109 }
110
111 void print (PrintStream out, int indent) {
112 ClassPrint.spaces(out, indent);
113 if (opcode() == opc_newarray)
114 out.println(offset() + " opc_newarray " + primType(operandValue));
115 else
116 out.println(offset() + " " + opName(opcode()) + " " + operandValue);
117 }
118
119 int store(byte[] buf, int index) {
120 if (size() == 4) {
121
122 buf[index++] = (byte) opc_wide;
123 }
124
125 buf[index++] = (byte) opcode();
126 if (size() > 2)
127 buf[index++] = (byte)(operandValue >> 8);
128 buf[index++] = (byte)(operandValue & 0xff);
129 return index;
130 }
131
132
133
134
135 int size() {
136 switch(opcode()) {
137 case opc_bipush:
138 case opc_newarray:
139
140 return 2;
141
142 case opc_sipush:
143
144 return 3;
145
146 case opc_iload:
147 case opc_lload:
148 case opc_fload:
149 case opc_dload:
150 case opc_aload:
151 case opc_istore:
152 case opc_lstore:
153 case opc_fstore:
154 case opc_dstore:
155 case opc_astore:
156 case opc_ret:
157
158
159
160 if (operandValue < 256)
161 return 2;
162 else
163 return 4;
164
165 default:
166 throw new InsnError ("invalid instruction " + opName(opcode()) +
167 " with an integer operand");
168 }
169 }
170
171
172 InsnIntOp (int theOpcode, int theOperand, int pc) {
173 super(theOpcode, pc);
174
175 operandValue = theOperand;
176 }
177
178
179 InsnIntOp (int theOpcode, int theOperand) {
180 super(theOpcode, NO_OFFSET);
181
182 operandValue = theOperand;
183 switch(theOpcode) {
184 case opc_bipush:
185 case opc_newarray:
186
187
188 case opc_sipush:
189
190
191 case opc_dload:
192 case opc_lload:
193 case opc_iload:
194 case opc_fload:
195 case opc_aload:
196 case opc_istore:
197 case opc_lstore:
198 case opc_fstore:
199 case opc_dstore:
200 case opc_astore:
201 case opc_ret:
202
203 break;
204
205 default:
206 throw new InsnError ("attempt to create an " + opName(theOpcode) +
207 " with an integer operand");
208 }
209 }
210 }