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