1 package alt.jiapi.reflect; 2 3 import java.lang.reflect.Modifier ; 4 import java.util.List ; 5 6 import alt.jiapi.file.ConstantPool; 7 import alt.jiapi.file.ConstantPool.ClassInfo; 8 import alt.jiapi.file.Field; 9 import alt.jiapi.file.Method; 10 11 import alt.jiapi.reflect.instruction.CPInstruction; 12 import alt.jiapi.reflect.instruction.FieldAccess; 13 import alt.jiapi.reflect.instruction.Invocation; 14 import alt.jiapi.reflect.instruction.Opcodes; 15 16 21 public class InstructionFactory { 22 private ConstantPool cp; 23 24 public InstructionFactory() { 25 this.cp = new ConstantPool(); 26 } 27 28 29 31 InstructionFactory(ConstantPool cp) { 32 this.cp = cp; 33 } 34 35 42 List createInstructionList(byte[] byteCode) { 43 InstructionParser ip = new InstructionParser(); 44 return ip.createInstructionList(byteCode, cp); 45 } 46 47 48 public Instruction pushConstant(float constant) { 49 short index = cp.addFloatInfo((int)constant).getEntryIndex(); 50 byte[] bytes = createLDC(index); 51 52 return new CPInstruction(bytes, cp); } 54 55 public Instruction pushConstant(int constant) { 56 switch(constant) { 57 case 0: 58 return new Instruction(new byte[] {Opcodes.ICONST_0}); 59 case 1: 60 return new Instruction(new byte[] {Opcodes.ICONST_1}); 61 case 2: 62 return new Instruction(new byte[] {Opcodes.ICONST_2}); 63 case 3: 64 return new Instruction(new byte[] {Opcodes.ICONST_3}); 65 case 4: 66 return new Instruction(new byte[] {Opcodes.ICONST_4}); 67 case 5: 68 return new Instruction(new byte[] {Opcodes.ICONST_5}); 69 } 70 71 short index = cp.addIntegerInfo(constant).getEntryIndex(); 72 byte[] bytes = createLDC(index); 73 74 return new CPInstruction(bytes, cp); 75 } 76 77 public Instruction pushConstant(String constant) { 78 short index = cp.addStringInfo(constant).getEntryIndex(); 79 byte[] bytes = createLDC(index); 80 81 return new CPInstruction(bytes, cp); } 83 84 public Instruction newClass(String className) { 85 short index = cp.addClassInfo(className).getEntryIndex(); 86 byte[] bytes = new byte[3]; 87 bytes[0] = Opcodes.NEW; 88 bytes[1] = (byte) (index >> 8); 89 bytes[2] = (byte) (index & 255); 90 91 return new CPInstruction(bytes, cp); 93 } 94 95 96 106 public Instruction cast(String type) { 107 ClassInfo ci = cp.addClassInfo(type); 108 short index = ci.getEntryIndex(); 109 110 byte[] bytes = new byte[3]; 111 bytes[0] = Opcodes.CHECKCAST; 112 bytes[1] = (byte) (index >> 8); 113 bytes[2] = (byte) (index & 255); 114 115 return new CPInstruction(bytes, cp); 116 } 117 118 119 public Instruction pushNull() { 120 return new Instruction(new byte[] { Opcodes.ACONST_NULL }); 121 } 122 123 public Instruction pushThis() { 124 return new Instruction(new byte[] { Opcodes.ALOAD_0 }); 125 } 126 127 128 public Instruction returnMethod(JiapiMethod jm) { 129 String retType = jm.getSignature().getReturnType(); 130 Instruction ins = null; 131 132 if ("void".equals(retType)) { 133 ins = new Instruction(new byte[] { Opcodes.RETURN }); 134 } 135 else if ("boolean".equals(retType) || 136 "int".equals(retType) || 137 "short".equals(retType) || 138 "byte".equals(retType)) { 139 ins = new Instruction(new byte[] { Opcodes.IRETURN }); 140 } 141 else if ("long".equals(retType)) { 142 ins = new Instruction(new byte[] { Opcodes.LRETURN }); 143 } 144 else if ("float".equals(retType)) { 145 ins = new Instruction(new byte[] { Opcodes.FRETURN }); 146 } 147 else if ("double".equals(retType)) { 148 ins = new Instruction(new byte[] { Opcodes.DRETURN }); 149 } 150 else { 151 ins = new Instruction(new byte[] { Opcodes.ARETURN }); 152 } 153 154 return ins; 155 } 156 157 158 159 public Instruction invoke(int mods, String className, String methodName, 160 Signature s) { 161 short index = ConstantPoolHelper.addMethodReference(cp, className, 162 methodName, s); 163 164 byte[] bytes; 165 166 if (Modifier.isStatic(mods)) { 167 bytes = new byte[3]; 168 bytes[0] = Opcodes.INVOKESTATIC; 169 bytes[1] = (byte) (index >> 8); 170 bytes[2] = (byte) (index & 255); 171 } 172 else if (Modifier.isInterface(mods)) { 173 bytes = new byte[5]; 174 bytes[0] = Opcodes.INVOKEINTERFACE; 175 bytes[1] = (byte) (index >> 8); 176 bytes[2] = (byte) (index & 255); 177 bytes[3] = (byte) s.getParameters().length; 178 bytes[4] = (byte) 0; 179 } 180 else if ("<init>".equals(methodName)) { 181 bytes = new byte[3]; 182 bytes[0] = Opcodes.INVOKESPECIAL; 183 bytes[1] = (byte) (index >> 8); 184 bytes[2] = (byte) (index & 255); 185 } 186 else { 187 bytes = new byte[3]; 188 bytes[0] = Opcodes.INVOKEVIRTUAL; 189 bytes[1] = (byte) (index >> 8); 190 bytes[2] = (byte) (index & 255); 191 } 192 193 Instruction instruction = new Invocation(bytes, cp); 194 195 return instruction; 196 } 197 198 199 public Instruction invoke(JiapiMethod jm) { 200 String [] params = jm.getParameterTypeNames(); 201 202 short index = ConstantPoolHelper.addReference(cp, jm); 203 204 byte[] bytes; 205 int stackUsage = 1 + params.length; 207 if (Modifier.isStatic(jm.getModifiers())) { 208 bytes = new byte[3]; 209 bytes[0] = Opcodes.INVOKESTATIC; 210 bytes[1] = (byte) (index >> 8); 211 bytes[2] = (byte) (index & 255); 212 } 213 else if (Modifier.isInterface(jm.getModifiers())) { 214 bytes = new byte[5]; 215 bytes[0] = Opcodes.INVOKEINTERFACE; 216 bytes[1] = (byte) (index >> 8); 217 bytes[2] = (byte) (index & 255); 218 bytes[3] = (byte) params.length; 219 bytes[4] = (byte) 0; 220 } 221 else if ("<init>".equals(jm.getName())) { 222 bytes = new byte[3]; 223 bytes[0] = Opcodes.INVOKESPECIAL; 224 bytes[1] = (byte) (index >> 8); 225 bytes[2] = (byte) (index & 255); 226 } 227 else { 228 bytes = new byte[3]; 229 bytes[0] = Opcodes.INVOKEVIRTUAL; 230 bytes[1] = (byte) (index >> 8); 231 bytes[2] = (byte) (index & 255); 232 } 233 234 Instruction instruction = new Invocation(bytes, cp); 236 return instruction; 237 } 238 239 240 private byte[] createLDC(short index) { 241 byte[] bytes; 242 if (index > 255) { 243 bytes = new byte[3]; 244 bytes[0] = Opcodes.LDC_W; 245 bytes[1] = (byte) (index >> 8); 246 bytes[2] = (byte) (index & 255); 247 } 248 else { 249 bytes = new byte[2]; 250 bytes[0] = Opcodes.LDC; 251 bytes[1] = (byte)index; 252 } 253 254 return bytes; 255 } 256 257 private byte[] createLDC_longDouble(short index) { 258 byte[] bytes = new byte[3]; 259 260 bytes[0] = Opcodes.LDC2_W; 261 bytes[1] = (byte) (index >> 8); 262 bytes[2] = (byte) (index & 255); 263 264 return bytes; 265 } 266 267 268 269 public Instruction getField(int modifiers, String className, 270 String fieldName, 271 String fieldType) { 272 ConstantPool.ClassInfo ci = 273 cp.addClassInfo(className); 274 ConstantPool.FieldRefInfo fri = 275 cp.addFieldRefInfo(ci, fieldName, fieldType); 276 277 int index = fri.getEntryIndex(); 278 byte[] bytes = new byte[3]; 279 280 if (Modifier.isStatic(modifiers)) { 281 bytes[0] = Opcodes.GETSTATIC; 282 bytes[1] = (byte) (index >> 8); 283 bytes[2] = (byte) (index & 255); 284 } 285 else { 286 bytes[0] = Opcodes.GETFIELD; 287 bytes[1] = (byte) (index >> 8); 288 bytes[2] = (byte) (index & 255); 289 } 290 291 Instruction instruction = new FieldAccess(bytes, cp); 292 return instruction; 293 } 294 295 public Instruction getField(JiapiField field) { 296 ConstantPool cp = 297 field.getDeclaringClass().getConstantPool(); 298 299 ConstantPool.ClassInfo ci = 300 cp.addClassInfo(field.getDeclaringClass().getName()); 301 ConstantPool.FieldRefInfo fri = 302 cp.addFieldRefInfo(ci, field.getName(), field.getDescriptor()); 303 304 int index = fri.getEntryIndex(); 305 306 int modifiers = field.getModifiers(); 307 byte[] bytes = new byte[3]; 308 309 if (Modifier.isStatic(modifiers)) { 310 bytes[0] = Opcodes.GETSTATIC; 311 bytes[1] = (byte) (index >> 8); 312 bytes[2] = (byte) (index & 255); 313 } 314 else { 315 bytes[0] = Opcodes.GETFIELD; 316 bytes[1] = (byte) (index >> 8); 317 bytes[2] = (byte) (index & 255); 318 } 319 320 Instruction instruction = new FieldAccess(bytes, cp); 321 return instruction; 322 } 323 324 343 public Instruction setField(JiapiField field) { 344 ConstantPool cp = 347 field.getDeclaringClass().getConstantPool(); 348 349 ConstantPool.ClassInfo ci = 350 cp.addClassInfo(field.getDeclaringClass().getName()); 351 ConstantPool.FieldRefInfo fri = 352 cp.addFieldRefInfo(ci, field.getName(), field.getDescriptor()); 353 354 int index = fri.getEntryIndex(); 355 356 357 int modifiers = field.getModifiers(); 358 byte[] bytes = new byte[3]; 359 360 if (Modifier.isStatic(modifiers)) { 361 bytes[0] = Opcodes.PUTSTATIC; 362 bytes[1] = (byte) (index >> 8); 363 bytes[2] = (byte) (index & 255); 364 } 365 else { 366 bytes[0] = Opcodes.PUTFIELD; 367 bytes[1] = (byte) (index >> 8); 368 bytes[2] = (byte) (index & 255); 369 } 370 371 Instruction instruction = new FieldAccess(bytes, cp); 372 return instruction; 373 } 374 375 376 public Instruction aload(int idx) { 377 switch(idx) { 379 case 0: 380 return new Instruction(new byte[] {Opcodes.ALOAD_0}); 381 case 1: 382 return new Instruction(new byte[] {Opcodes.ALOAD_1}); 383 case 2: 384 return new Instruction(new byte[] {Opcodes.ALOAD_2}); 385 case 3: 386 return new Instruction(new byte[] {Opcodes.ALOAD_3}); 387 default: 388 return new Instruction(new byte[] {Opcodes.ALOAD, (byte)idx}); 389 } 390 } 391 392 public Instruction iload(int idx) { 393 switch(idx) { 395 case 0: 396 return new Instruction(new byte[] {Opcodes.ILOAD_0}); 397 case 1: 398 return new Instruction(new byte[] {Opcodes.ILOAD_1}); 399 case 2: 400 return new Instruction(new byte[] {Opcodes.ILOAD_2}); 401 case 3: 402 return new Instruction(new byte[] {Opcodes.ILOAD_3}); 403 default: 404 return new Instruction(new byte[] {Opcodes.ILOAD, (byte)idx}); 405 } 406 } 407 408 public Instruction lload(int idx) { 409 switch(idx) { 411 case 0: 412 return new Instruction(new byte[] {Opcodes.LLOAD_0}); 413 case 1: 414 return new Instruction(new byte[] {Opcodes.LLOAD_1}); 415 case 2: 416 return new Instruction(new byte[] {Opcodes.LLOAD_2}); 417 case 3: 418 return new Instruction(new byte[] {Opcodes.LLOAD_3}); 419 default: 420 return new Instruction(new byte[] {Opcodes.LLOAD, (byte)idx}); 421 } 422 } 423 424 public Instruction dload(int idx) { 425 switch(idx) { 427 case 0: 428 return new Instruction(new byte[] {Opcodes.DLOAD_0}); 429 case 1: 430 return new Instruction(new byte[] {Opcodes.DLOAD_1}); 431 case 2: 432 return new Instruction(new byte[] {Opcodes.DLOAD_2}); 433 case 3: 434 return new Instruction(new byte[] {Opcodes.DLOAD_3}); 435 default: 436 return new Instruction(new byte[] {Opcodes.DLOAD, (byte)idx}); 437 } 438 } 439 440 public Instruction fload(int idx) { 441 switch(idx) { 443 case 0: 444 return new Instruction(new byte[] {Opcodes.FLOAD_0}); 445 case 1: 446 return new Instruction(new byte[] {Opcodes.FLOAD_1}); 447 case 2: 448 return new Instruction(new byte[] {Opcodes.FLOAD_2}); 449 case 3: 450 return new Instruction(new byte[] {Opcodes.FLOAD_3}); 451 default: 452 return new Instruction(new byte[] {Opcodes.FLOAD, (byte)idx}); 453 } 454 } 455 456 public Instruction astore(int idx) { 457 switch(idx) { 459 case 0: 460 return new Instruction(new byte[] {Opcodes.ASTORE_0}); 461 case 1: 462 return new Instruction(new byte[] {Opcodes.ASTORE_1}); 463 case 2: 464 return new Instruction(new byte[] {Opcodes.ASTORE_2}); 465 case 3: 466 return new Instruction(new byte[] {Opcodes.ASTORE_3}); 467 default: 468 return new Instruction(new byte[] {Opcodes.ASTORE, (byte)idx}); 469 } 470 } 471 472 public Instruction istore(int idx) { 473 switch(idx) { 475 case 0: 476 return new Instruction(new byte[] {Opcodes.ISTORE_0}); 477 case 1: 478 return new Instruction(new byte[] {Opcodes.ISTORE_1}); 479 case 2: 480 return new Instruction(new byte[] {Opcodes.ISTORE_2}); 481 case 3: 482 return new Instruction(new byte[] {Opcodes.ISTORE_3}); 483 default: 484 return new Instruction(new byte[] {Opcodes.ISTORE, (byte)idx}); 485 } 486 } 487 488 public Instruction lstore(int idx) { 489 switch(idx) { 491 case 0: 492 return new Instruction(new byte[] {Opcodes.LSTORE_0}); 493 case 1: 494 return new Instruction(new byte[] {Opcodes.LSTORE_1}); 495 case 2: 496 return new Instruction(new byte[] {Opcodes.LSTORE_2}); 497 case 3: 498 return new Instruction(new byte[] {Opcodes.LSTORE_3}); 499 default: 500 return new Instruction(new byte[] {Opcodes.LSTORE, (byte)idx}); 501 } 502 } 503 504 public Instruction fstore(int idx) { 505 switch(idx) { 507 case 0: 508 return new Instruction(new byte[] {Opcodes.FSTORE_0}); 509 case 1: 510 return new Instruction(new byte[] {Opcodes.FSTORE_1}); 511 case 2: 512 return new Instruction(new byte[] {Opcodes.FSTORE_2}); 513 case 3: 514 return new Instruction(new byte[] {Opcodes.FSTORE_3}); 515 default: 516 return new Instruction(new byte[] {Opcodes.FSTORE, (byte)idx}); 517 } 518 } 519 520 public Instruction dstore(int idx) { 521 switch(idx) { 523 case 0: 524 return new Instruction(new byte[] {Opcodes.DSTORE_0}); 525 case 1: 526 return new Instruction(new byte[] {Opcodes.DSTORE_1}); 527 case 2: 528 return new Instruction(new byte[] {Opcodes.DSTORE_2}); 529 case 3: 530 return new Instruction(new byte[] {Opcodes.DSTORE_3}); 531 default: 532 return new Instruction(new byte[] {Opcodes.DSTORE, (byte)idx}); 533 } 534 } 535 536 public Instruction aastore() { 537 return new Instruction(new byte[] {Opcodes.AASTORE}); 538 } 539 540 public Instruction dup() { 541 return new Instruction(new byte[] {Opcodes.DUP}); 542 } 543 public Instruction dup2() { 544 return new Instruction(new byte[] {Opcodes.DUP2}); 545 } 546 547 public InstructionList newArray(String type, int size) { 548 InstructionList il = new InstructionList(cp); 549 il.add(pushConstant(size)); 550 551 if (SignatureUtil.isPrimitive(type)) { 552 throw new RuntimeException ("NOT implemented: new array for primitive types"); 553 } 554 else { 555 ClassInfo ci = cp.addClassInfo("java.lang.Object"); 556 short idx = ci.getEntryIndex(); 557 558 il.add(new CPInstruction(new byte[] {Opcodes.ANEWARRAY, 559 (byte)(idx >> 8), 560 (byte)(idx& 0xff)}, 561 cp)); 562 } 563 564 return il; 565 } 566 567 568 570 572 } 579 | Popular Tags |