1 package jas; 6 7 import java.io.*; 8 9 abstract class InsnOperand 10 { 11 abstract void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 12 throws IOException, jasError; 13 abstract int size(ClassEnv e, CodeAttr code) throws jasError; 14 abstract void resolve(ClassEnv e); 15 void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out) 16 throws IOException, jasError 17 { return; } 18 } 19 20 class LabelOperand extends InsnOperand 22 { 23 Label target; 24 Insn source; 25 boolean wide; 26 27 LabelOperand(Label l, Insn source) 28 { target = l; this.source = source; this.wide = false; } 29 LabelOperand(Label l, Insn source, boolean wide) 30 { target = l; this.source = source; this.wide = wide; } 31 int size(ClassEnv ce, CodeAttr code) { if (wide) return 4; else return 2; } 32 void resolve(ClassEnv e) { return; } 33 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 34 throws IOException, jasError 35 { 36 if (wide) { target.writeWideOffset(ce, source, out); } 37 else { target.writeOffset(ce, source, out); } } 38 } 39 40 class UnsignedByteOperand extends InsnOperand 41 { 42 int val; 43 44 UnsignedByteOperand(int n) { val = n; } 45 int size(ClassEnv ce, CodeAttr code) { return 1; } 46 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 47 throws IOException, jasError 48 { 49 if (val >= 256) 50 throw 51 new jasError("Operand is too large (" +val+ ") for this instruction"); 52 out.writeByte((byte)(0xff & val)); 53 } 54 void resolve(ClassEnv e) { return; } 55 } 56 57 class UnsignedByteWideOperand extends InsnOperand 61 implements RuntimeConstants 62 { 63 int val; 64 65 UnsignedByteWideOperand(int n) { val = n; } 66 int size(ClassEnv ce, CodeAttr code) 67 { 68 if (val >= 256) return 3; 69 return 1; 70 } 71 void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out) 72 throws IOException 73 { 74 if (val > 255) 75 out.writeByte((byte)(opc_wide)); 76 } 77 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 78 throws IOException 79 { 80 if (val > 255) 81 out.writeShort((short)(0xffff & val)); 82 else 83 out.writeByte((byte)(val & 0xff)); 84 } 85 void resolve(ClassEnv e) { return; } 86 } 87 88 class ByteOperand extends InsnOperand 89 { 90 int val; 91 92 ByteOperand(int n) { val = n; } 93 int size(ClassEnv ce, CodeAttr code) { return 1; } 94 void resolve(ClassEnv e) { return; } 95 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 96 throws IOException 97 { out.writeByte((byte)val); } 98 } 99 100 class IntegerOperand extends InsnOperand 101 { 102 int val; 103 104 IntegerOperand(int n) { val = n; } 105 int size(ClassEnv ce, CodeAttr code) { return 4; } 106 void resolve(ClassEnv e) { return; } 107 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 108 throws IOException 109 { out.writeInt(val); } 110 } 111 112 class ShortOperand extends InsnOperand 113 { 114 int offset; 115 ShortOperand(int n) { offset = n; } 116 void resolve(ClassEnv e) { return; } 117 int size(ClassEnv ce, CodeAttr code) { return 2; } 118 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 119 throws IOException 120 { out.writeShort((short)offset); } 121 } 122 123 class CPOperand extends InsnOperand 124 { 125 CP cpe; 126 boolean wide; 127 int size(ClassEnv ce, CodeAttr code) { if (wide) return 2; else return 1; } 128 CPOperand(CP cpe) { this.cpe = cpe; wide = true; } 129 CPOperand(CP cpe, boolean wide) 130 { this.cpe = cpe; this.wide = wide; } 131 void resolve(ClassEnv e) 132 { e.addCPItem(cpe); } 133 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 134 throws IOException, jasError 135 { 136 int idx = e.getCPIndex(cpe); 137 if (wide) 138 { out.writeShort((short) idx); } 139 else 140 { 141 if (idx > 255) 142 { throw new jasError("exceeded size for small cpidx" + cpe); } 143 out.writeByte((byte) (0xff & (idx))); 144 } 145 } 146 } 147 148 class LdcOperand extends InsnOperand implements RuntimeConstants 152 { 153 CP cpe; 154 Insn source; 155 boolean wide; 156 157 int size(ClassEnv ce, CodeAttr code) throws jasError 158 { 159 if (wide) 160 { return 2; } 161 else 162 { 163 int idx = ce.getCPIndex(cpe); 165 if (idx > 255) 168 { 169 wide = true; 170 source.opc = opc_ldc_w; 171 return 2; 172 } 173 return 1; 174 } 175 } 176 LdcOperand(Insn s, CP cpe) { source = s; this.cpe = cpe; wide = true; } 177 LdcOperand(Insn s, CP cpe, boolean wide) 178 { source = s; this.cpe = cpe; this.wide = wide; } 179 180 void resolve(ClassEnv e) 181 { e.addCPItem(cpe); 182 if (cpe instanceof ClassCP){ 183 e.setHighVersion(true); 184 } 185 } 186 187 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 188 throws IOException, jasError 189 { 190 int idx = e.getCPIndex(cpe); 191 if (wide) 195 { out.writeShort((short) idx); } 196 else 197 { 198 if (idx > 255) 199 { throw new jasError("exceeded size for small cpidx" + cpe); } 200 out.writeByte((byte) (0xff & (idx))); 201 } 202 } 203 } 204 205 206 class InvokeinterfaceOperand extends InsnOperand 207 { 208 CP cpe; 209 int nargs; 210 211 InvokeinterfaceOperand(CP cpe, int nargs) 212 { this.cpe = cpe; this.nargs = nargs; } 213 214 int size(ClassEnv ce, CodeAttr code) { return 4; } 215 216 void resolve(ClassEnv e) 217 { e.addCPItem(cpe); } 218 219 void write (ClassEnv e, CodeAttr ce, DataOutputStream out) 220 throws IOException, jasError 221 { 222 out.writeShort(e.getCPIndex(cpe)); 223 out.writeByte((byte) (0xff & nargs)); 224 out.writeByte(0); 225 } 226 } 227 228 class IincOperand extends InsnOperand 229 implements RuntimeConstants 230 { 231 int vindex, constt; 232 233 IincOperand(int vindex, int constt) 234 { this.vindex = vindex; this.constt = constt; } 235 236 int size(ClassEnv ce, CodeAttr code) 237 { 238 if ((vindex > 255) || 239 (constt > 127) || 240 (constt < -128)) 241 return 5; 242 else 243 return 2; 244 } 245 void resolve(ClassEnv e) { return; } 246 void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out) 247 throws IOException 248 { 249 if ((vindex > 255) || 250 (constt > 127) || 251 (constt < -128)) 252 out.writeByte((byte)opc_wide); 253 } 254 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 255 throws IOException 256 { 257 if ((vindex > 255) || 258 (constt > 127) || 259 (constt < -128)) 260 { 261 out.writeShort((short)(0xffff & vindex)); 262 out.writeShort((short)(0xffff & constt)); 263 } 264 else 265 { 266 out.writeByte((byte) (0xff & vindex)); 267 out.writeByte((byte) (0xff & constt)); 268 } 269 } 270 } 271 272 class MultiarrayOperand extends InsnOperand 273 { 274 CP cpe; 275 int sz; 276 277 MultiarrayOperand(CP cpe, int sz) 278 { this.cpe = cpe; this.sz = sz; } 279 void resolve(ClassEnv e) { e.addCPItem(cpe); } 280 int size(ClassEnv ce, CodeAttr code) { return 3; } 281 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 282 throws IOException, jasError 283 { 284 out.writeShort(e.getCPIndex(cpe)); 285 out.writeByte((byte)(0xff & sz)); 286 } 287 } 288 289 class LookupswitchOperand extends InsnOperand 290 { 291 Label dflt; 292 Insn source; 293 int match[]; 294 Label jmp[]; 295 296 LookupswitchOperand(Insn s, Label def, int m[], Label j[]) 297 { dflt = def; jmp = j; match = m; source = s; } 298 299 void resolve (ClassEnv e) { return; } 300 int size(ClassEnv ce, CodeAttr code) throws jasError 301 { 302 int sz = 8; int source_pc = code.getPc(source); 304 if (((source_pc+1) % 4) != 0) 305 { 306 sz += (4 - ((source_pc+1) % 4)); 308 } 309 310 if (jmp != null) 311 { sz += 8*(jmp.length); } 312 return sz; 313 } 314 315 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 316 throws IOException, jasError 317 { 318 int pad; 319 int source_pc = ce.getPc(source); 320 321 if (((source_pc+1) % 4) != 0) 322 { pad = (4 - ((source_pc+1) % 4)); 324 for (int x=0; x<pad; x++) out.writeByte(0); 325 } 326 327 dflt.writeWideOffset(ce, source, out); 330 if (jmp == null) 331 { out.writeInt(0); } 332 else 333 { 334 out.writeInt(jmp.length); 335 for (int x=0; x<jmp.length; x++) 336 { 337 out.writeInt(match[x]); 338 jmp[x].writeWideOffset(ce, source, out); 339 } 340 } 341 } 342 } 343 344 345 class TableswitchOperand extends InsnOperand 346 { 347 int min, max; 348 Label dflt; 349 Label jmp[]; 350 Insn source; 351 352 TableswitchOperand(Insn s,int min, int max, Label def, Label j[]) 353 { 354 this.min = min; this.max = max; 355 dflt = def; jmp = j; source = s; 356 } 357 358 void resolve(ClassEnv e) { return; } 359 360 int size(ClassEnv ce, CodeAttr code) 361 throws jasError 362 { 365 int sz = 12; int source_pc = code.getPc(source); 367 if (((source_pc+1) % 4) != 0) 368 { sz += (4 - ((source_pc+1) % 4)); 370 } 371 if (jmp != null) 372 { sz += 4*(jmp.length); } 373 return sz; 374 } 375 376 void write(ClassEnv e, CodeAttr ce, DataOutputStream out) 377 throws IOException, jasError 378 { 379 int pad; 380 int source_pc = ce.getPc(source); 381 382 if (((source_pc+1) % 4) != 0) 383 { pad = (4 - ((source_pc+1) % 4)); 385 for (int x=0; x<pad; x++) out.writeByte(0); 386 } 387 dflt.writeWideOffset(ce, source, out); 388 out.writeInt(min); 389 out.writeInt(max); 390 int cnt = jmp.length; 391 for (int x=0; x<cnt; x++) 392 { jmp[x].writeWideOffset(ce, source, out); } 393 } 394 } 395 396 | Popular Tags |