1 34 package jarg; 35 36 import java.util.*; 37 import org.apache.bcel.classfile.*; 38 import org.apache.bcel.generic.*; 39 import org.apache.bcel.Constants; 40 41 47 class DataflowAnalizer { 48 private static final boolean DEBUG_TYPE = true; 49 private static final boolean DEBUG_INST = true; 50 51 private Jarg app; 52 53 DataflowAnalizer(Jarg app) { 54 this.app = app; 55 } 56 57 HashMap analize(MethodGen mg) { 58 int count = 0; 59 InstructionList il = mg.getInstructionList(); 60 HashMap dataMap = new HashMap(); 62 InstructionDataset dataset0 = new InstructionDataset(null); 63 { 64 int j=0; 65 if (!mg.isStatic()) { 66 dataset0.toLoc(j++, Type.OBJECT); 67 } 68 Type[] ts = mg.getArgumentTypes(); 69 for (int i=0; i<ts.length; i++) { 70 Type t = ts[i]; 71 if (t == Type.LONG) { 72 dataset0.toLoc(j++, LONGUpper.instance); 73 } else if (t == Type.DOUBLE) { 74 dataset0.toLoc(j++, DOUBLEUpper.instance); 75 } 76 dataset0.toLoc(j++, t); 77 } 78 } 79 analizeDataflow(dataset0, il.getStart(), dataMap, new PassCounter(), mg.getConstantPool()); 80 81 return dataMap; 82 } 83 84 private void analizeDataflow(InstructionDataset dataset0, InstructionHandle first, HashMap dataMap, PassCounter pass, ConstantPoolGen cpg) { 85 InstructionDataset dataset1; 86 for (; first != null; first=first.getNext(), dataset0 = dataset1) { 87 if (dataMap.containsKey(first)) { 88 InstructionDataset datasetX = (InstructionDataset)dataMap.get(first); 89 datasetX.merge(dataset0); 90 dataset0 = datasetX; 91 } else { 92 dataMap.put(first, dataset0); 93 } 94 dataset1 = new InstructionDataset(first); 95 dataset1.merge(dataset0); 97 Instruction ins1 = first.getInstruction(); 98 if (ins1 instanceof BranchInstruction) { 99 if (analizeBranchInstruction(first, ins1, dataset1, dataMap, pass, cpg)) { 100 break; 101 } 102 } else if (ins1 instanceof ATHROW) { 103 Type t1 = dataset1.popOpStack(); 104 if (DEBUG_TYPE) { 105 checkTypeReferenceType(t1); 106 } 107 break; 108 } else if (ins1 instanceof RET) { 109 int vn = ((RET)ins1).getIndex(); Type t1 = dataset1.fromLoc(vn); 111 if (DEBUG_TYPE) { 112 checkTypeReturnaddressType(t1); 113 } 114 break; 115 } else if (ins1 instanceof ReturnInstruction) { 116 if (!(ins1 instanceof RETURN)) { 117 Type t1 = dataset1.popOpStack(); 118 if (ins1 instanceof LRETURN || ins1 instanceof DRETURN) { 119 Type t2 = dataset1.popOpStack(); 120 } 121 } 122 break; 123 124 } else if (ins1 instanceof LocalVariableInstruction) { 125 analizeLocalVariableInstruction(ins1, dataset1); 126 } else if (ins1 instanceof ConversionInstruction) { 127 analizeConversionInstruction(ins1, dataset1); 128 } else if (ins1 instanceof CPInstruction) { 129 analizeCPInstruction(ins1, dataset1, cpg); 130 131 } else if (ins1 instanceof ACONST_NULL) { 132 dataset1.pushOpStack(CONSTNull.instance); 134 } else if (ins1 instanceof ICONST || ins1 instanceof BIPUSH || ins1 instanceof SIPUSH) { 135 dataset1.pushOpStack(new ConstantIntType((Integer )((ConstantPushInstruction)ins1).getValue())); 137 } else if (ins1 instanceof FCONST) { 138 dataset1.pushOpStack(Type.FLOAT); 139 } else if (ins1 instanceof LCONST) { 140 dataset1.pushOpStack(LONGUpper.instance); 141 dataset1.pushOpStack(Type.LONG); 142 } else if (ins1 instanceof DCONST) { 143 dataset1.pushOpStack(DOUBLEUpper.instance); 144 dataset1.pushOpStack(Type.DOUBLE); 145 146 } else if (ins1 instanceof DCMPG) { 147 Type t4 = dataset1.popOpStack(); 148 Type t3 = dataset1.popOpStack(); 149 Type t2 = dataset1.popOpStack(); 150 Type t1 = dataset1.popOpStack(); 151 dataset1.pushOpStack(Type.INT); 152 if (DEBUG_TYPE) { 153 checkTypeDOUBLEUpper(t1); 154 checkTypeDOUBLE(t2); 155 checkTypeDOUBLEUpper(t3); 156 checkTypeDOUBLE(t4); 157 } 158 } else if (ins1 instanceof DCMPL) { 159 Type t4 = dataset1.popOpStack(); 160 Type t3 = dataset1.popOpStack(); 161 Type t2 = dataset1.popOpStack(); 162 Type t1 = dataset1.popOpStack(); 163 dataset1.pushOpStack(Type.INT); 164 if (DEBUG_TYPE) { 165 checkTypeDOUBLEUpper(t1); 166 checkTypeDOUBLE(t2); 167 checkTypeDOUBLEUpper(t3); 168 checkTypeDOUBLE(t4); 169 } 170 } else if (ins1 instanceof FCMPG) { 171 Type t1 = dataset1.popOpStack(); 172 Type t2 = dataset1.popOpStack(); 173 dataset1.pushOpStack(Type.INT); 174 if (DEBUG_TYPE) { 175 checkTypeFLOAT(t1); 176 checkTypeFLOAT(t2); 177 } 178 } else if (ins1 instanceof FCMPL) { 179 Type t1 = dataset1.popOpStack(); 180 Type t2 = dataset1.popOpStack(); 181 dataset1.pushOpStack(Type.INT); 182 if (DEBUG_TYPE) { 183 checkTypeFLOAT(t1); 184 checkTypeFLOAT(t2); 185 } 186 } else if (ins1 instanceof LCMP) { 187 Type t4 = dataset1.popOpStack(); 188 Type t3 = dataset1.popOpStack(); 189 Type t2 = dataset1.popOpStack(); 190 Type t1 = dataset1.popOpStack(); 191 dataset1.pushOpStack(Type.INT); 192 if (DEBUG_TYPE) { 193 checkTypeLONGUpper(t1); 194 checkTypeLONG(t2); 195 checkTypeLONGUpper(t3); 196 checkTypeLONG(t4); 197 } 198 199 } else if (ins1 instanceof NEWARRAY) { 200 Type t1 = dataset1.popOpStack(); 201 dataset1.pushOpStack(Type.OBJECT); 202 if (DEBUG_TYPE) { 203 checkTypeINT(t1); 204 } 205 } else if (ins1 instanceof ArrayInstruction) { 206 analizeArrayInstruction(ins1, dataset1); 207 } else if (ins1 instanceof ARRAYLENGTH) { 208 Type t1 = dataset1.popOpStack(); 209 dataset1.pushOpStack(Type.INT); 210 if (DEBUG_TYPE) { 211 checkTypeReferenceType(t1); 212 } 213 214 } else if (ins1 instanceof ArithmeticInstruction) { 215 analizeArithmeticInstruction(ins1, dataset1); 216 } else if (ins1 instanceof StackInstruction) { 217 analizeStackInstruction(ins1, dataset1); 218 219 } else if (ins1 instanceof MONITORENTER) { 220 Type t1 = dataset1.popOpStack(); 221 if (DEBUG_TYPE) { 222 checkTypeReferenceType(t1); 223 } 224 } else if (ins1 instanceof MONITOREXIT) { 225 Type t1 = dataset1.popOpStack(); 226 if (DEBUG_TYPE) { 227 checkTypeReferenceType(t1); 228 } 229 230 } else if (ins1 instanceof NOP) { 231 } else if (ins1 instanceof BREAKPOINT) { 232 } else if (ins1 instanceof IMPDEP1) { 233 } else if (ins1 instanceof IMPDEP2) { 234 } else { 235 if (DEBUG_INST) { 236 notReached(); 237 } 238 } 239 } 240 } 241 242 private boolean analizeBranchInstruction(InstructionHandle first, Instruction ins1, InstructionDataset dataset1, HashMap dataMap, PassCounter pass, ConstantPoolGen cpg) { 243 if (ins1 instanceof IfInstruction) { 244 if (ins1 instanceof IF_ACMPEQ 245 || ins1 instanceof IF_ACMPNE 246 ) { 247 Type t1 = dataset1.popOpStack(); 248 Type t2 = dataset1.popOpStack(); 249 if (DEBUG_TYPE) { 250 checkTypeReferenceType(t1); 251 checkTypeReferenceType(t2); 252 } 253 } else if ( 263 ins1 instanceof IF_ICMPEQ 264 || ins1 instanceof IF_ICMPNE 265 || ins1 instanceof IF_ICMPGE 266 || ins1 instanceof IF_ICMPGT 267 || ins1 instanceof IF_ICMPLE 268 || ins1 instanceof IF_ICMPLT 269 ) { 270 Type t1 = dataset1.popOpStack(); 271 Type t2 = dataset1.popOpStack(); 272 if (DEBUG_TYPE) { 273 checkTypeINT(t1); 274 checkTypeINT(t2); 275 } 276 } else if ( 277 ins1 instanceof IFEQ 278 || ins1 instanceof IFNE 279 || ins1 instanceof IFGE 280 || ins1 instanceof IFGT 281 || ins1 instanceof IFLE 282 || ins1 instanceof IFLT 283 ) { 284 Type t1 = dataset1.popOpStack(); 285 if (DEBUG_TYPE) { 286 checkTypeINT(t1); 287 } 288 } else if ( 289 ins1 instanceof IFNULL 290 || ins1 instanceof IFNONNULL 291 ) { 292 Type t1 = dataset1.popOpStack(); 293 if (DEBUG_TYPE) { 294 checkTypeReferenceType(t1); 295 } 296 } 297 } else if (ins1 instanceof Select) { 298 Type t1 = dataset1.popOpStack(); 299 if (DEBUG_TYPE) { 300 checkTypeINT(t1); 301 } 302 InstructionHandle[] targets = ((Select)ins1).getTargets(); 303 } else if (ins1 instanceof JsrInstruction) { 304 } else if (ins1 instanceof GotoInstruction) { 305 } else { 306 if (DEBUG_INST) { 307 notReached(); 308 } 309 } 310 311 InstructionDataset dataset2 = dataset1.duplicate(); 312 if (ins1 instanceof JsrInstruction) { 313 dataset2.pushOpStack(new ReturnaddressType(first.getNext())); 314 } 315 316 InstructionHandle target = ((BranchInstruction)ins1).getTarget(); 317 if (!pass.isCompleat(target)) { 318 pass.put(target); 319 analizeDataflow(dataset2, target, dataMap, pass, cpg); 320 } 321 322 if (ins1 instanceof GotoInstruction) { 323 return true; 324 } else if (ins1 instanceof Select) { 325 InstructionHandle[] targets = ((Select)ins1).getTargets(); 326 for (int i=0; i<targets.length; i++) { 327 InstructionHandle targetn = targets[i]; 328 if (!pass.isCompleat(targetn)) { 329 pass.put(targetn); 330 analizeDataflow(dataset1.duplicate(), targetn, dataMap, pass, cpg); 331 } 332 } 333 } 334 return false; 335 } 336 337 private void analizeLocalVariableInstruction(Instruction ins1, InstructionDataset dataset1) { 338 int vn = ((LocalVariableInstruction)ins1).getIndex(); 339 if (ins1 instanceof LoadInstruction) { 340 if (ins1 instanceof ALOAD) { 341 Type t1 = dataset1.fromLoc(vn); 342 if (t1 == Type.UNKNOWN) { 343 t1 = Type.OBJECT; 344 } 345 dataset1.pushOpStack(t1); 346 if (DEBUG_TYPE) { 347 checkTypeReferenceType(t1); 348 } 349 } else if (ins1 instanceof ILOAD) { 350 Type t1 = dataset1.fromLoc(vn); 351 if (t1 == Type.UNKNOWN) { 352 t1 = Type.INT; 353 } 354 dataset1.pushOpStack(t1); 355 if (DEBUG_TYPE) { 356 checkTypeINT(t1); 357 } 358 } else if (ins1 instanceof FLOAD) { 359 Type t1 = dataset1.fromLoc(vn); 360 if (t1 == Type.UNKNOWN) { 361 t1 = Type.FLOAT; 362 } 363 dataset1.pushOpStack(t1); 364 if (DEBUG_TYPE) { 365 checkTypeFLOAT(t1); 366 } 367 } else if (ins1 instanceof LLOAD) { 368 Type t1 = dataset1.fromLoc(vn); 369 Type t2 = dataset1.fromLoc(vn+1); 370 if (t1 == Type.UNKNOWN) { 371 t1 = LONGUpper.instance; 372 t2 = Type.LONG; 373 } 374 dataset1.pushOpStack(t1); 375 dataset1.pushOpStack(t2); 376 if (DEBUG_TYPE) { 377 checkTypeLONGUpper(t1); 378 checkTypeLONG(t2); 379 } 380 } else if (ins1 instanceof DLOAD) { 381 Type t1 = dataset1.fromLoc(vn); 382 Type t2 = dataset1.fromLoc(vn+1); 383 if (t1 == Type.UNKNOWN) { 384 t1 = DOUBLEUpper.instance; 385 t2 = Type.DOUBLE; 386 } 387 dataset1.pushOpStack(t1); 388 dataset1.pushOpStack(t2); 389 if (DEBUG_TYPE) { 390 checkTypeDOUBLEUpper(t1); 391 checkTypeDOUBLE(t2); 392 } 393 } else { 394 if (DEBUG_INST) { 395 notReached(); 396 } 397 } 398 } else if (ins1 instanceof StoreInstruction) { 399 if (ins1 instanceof ASTORE) { 400 Type t1 = dataset1.popOpStack(); 401 dataset1.toLoc(vn, t1); 402 if (DEBUG_TYPE) { 403 checkTypeReferenceTypeOrReturnaddressType(t1); 404 } 405 } else if (ins1 instanceof ISTORE) { 406 Type t1 = dataset1.popOpStack(); 407 dataset1.toLoc(vn, t1); 408 if (DEBUG_TYPE) { 409 checkTypeINT(t1); 410 } 411 } else if (ins1 instanceof FSTORE) { 412 Type t1 = dataset1.popOpStack(); 413 dataset1.toLoc(vn, t1); 414 if (DEBUG_TYPE) { 415 checkTypeFLOAT(t1); 416 } 417 } else if (ins1 instanceof LSTORE) { 418 Type t2 = dataset1.popOpStack(); 419 Type t1 = dataset1.popOpStack(); 420 dataset1.toLoc(vn, t1); 421 dataset1.toLoc(vn+1, t2); 422 if (DEBUG_TYPE) { 423 checkTypeLONGUpper(t1); 424 checkTypeLONG(t2); 425 } 426 } else if (ins1 instanceof DSTORE) { 427 Type t2 = dataset1.popOpStack(); 428 Type t1 = dataset1.popOpStack(); 429 dataset1.toLoc(vn, t1); 430 dataset1.toLoc(vn+1, t2); 431 if (DEBUG_TYPE) { 432 checkTypeDOUBLEUpper(t1); 433 checkTypeDOUBLE(t2); 434 } 435 } else { 436 if (DEBUG_INST) { 437 notReached(); 438 } 439 } 440 } else if (ins1 instanceof IINC) { 441 Type t1 = dataset1.fromLoc(vn); 442 if (t1 == Type.UNKNOWN || t1 instanceof ConstantIntType) { 443 t1 = Type.INT; 444 } 445 dataset1.toLoc(vn, t1); 446 if (DEBUG_TYPE) { 447 checkTypeINT(t1); 448 } 449 } else { 450 if (DEBUG_INST) { 451 notReached(); 452 } 453 } 454 } 455 456 private void analizeConversionInstruction(Instruction ins1, InstructionDataset dataset1) { 457 if (ins1 instanceof D2F) { 458 Type t2 = dataset1.popOpStack(); 459 Type t1 = dataset1.popOpStack(); 460 dataset1.pushOpStack(Type.FLOAT); 461 if (DEBUG_TYPE) { 462 checkTypeDOUBLEUpper(t1); 463 checkTypeDOUBLE(t2); 464 } 465 } else if (ins1 instanceof D2I) { 466 Type t2 = dataset1.popOpStack(); 467 Type t1 = dataset1.popOpStack(); 468 dataset1.pushOpStack(Type.INT); 469 if (DEBUG_TYPE) { 470 checkTypeDOUBLEUpper(t1); 471 checkTypeDOUBLE(t2); 472 } 473 } else if (ins1 instanceof D2L) { 474 Type t2 = dataset1.popOpStack(); 475 Type t1 = dataset1.popOpStack(); 476 dataset1.pushOpStack(LONGUpper.instance); 477 dataset1.pushOpStack(Type.LONG); 478 if (DEBUG_TYPE) { 479 checkTypeDOUBLEUpper(t1); 480 checkTypeDOUBLE(t2); 481 } 482 483 } else if (ins1 instanceof F2D) { 484 Type t1 = dataset1.popOpStack(); 485 dataset1.pushOpStack(DOUBLEUpper.instance); 486 dataset1.pushOpStack(Type.DOUBLE); 487 if (DEBUG_TYPE) { 488 checkTypeFLOAT(t1); 489 } 490 } else if (ins1 instanceof F2I) { 491 Type t1 = dataset1.popOpStack(); 492 dataset1.pushOpStack(Type.INT); 493 if (DEBUG_TYPE) { 494 checkTypeFLOAT(t1); 495 } 496 } else if (ins1 instanceof F2L) { 497 Type t1 = dataset1.popOpStack(); 498 dataset1.pushOpStack(LONGUpper.instance); 499 dataset1.pushOpStack(Type.LONG); 500 if (DEBUG_TYPE) { 501 checkTypeFLOAT(t1); 502 } 503 504 } else if (ins1 instanceof I2B) { 505 Type t1 = dataset1.popOpStack(); 506 dataset1.pushOpStack(Type.INT); 507 if (DEBUG_TYPE) { 508 checkTypeINT(t1); 509 } 510 } else if (ins1 instanceof I2C) { 511 Type t1 = dataset1.popOpStack(); 512 dataset1.pushOpStack(Type.INT); 513 if (DEBUG_TYPE) { 514 checkTypeINT(t1); 515 } 516 } else if (ins1 instanceof I2D) { 517 Type t1 = dataset1.popOpStack(); 518 dataset1.pushOpStack(DOUBLEUpper.instance); 519 dataset1.pushOpStack(Type.DOUBLE); 520 if (DEBUG_TYPE) { 521 checkTypeINT(t1); 522 } 523 } else if (ins1 instanceof I2F) { 524 Type t1 = dataset1.popOpStack(); 525 dataset1.pushOpStack(Type.FLOAT); 526 if (DEBUG_TYPE) { 527 checkTypeINT(t1); 528 } 529 } else if (ins1 instanceof I2L) { 530 Type t1 = dataset1.popOpStack(); 531 dataset1.pushOpStack(LONGUpper.instance); 532 dataset1.pushOpStack(Type.LONG); 533 if (DEBUG_TYPE) { 534 checkTypeINT(t1); 535 } 536 } else if (ins1 instanceof I2S) { 537 Type t1 = dataset1.popOpStack(); 538 dataset1.pushOpStack(Type.INT); 539 if (DEBUG_TYPE) { 540 checkTypeINT(t1); 541 } 542 543 } else if (ins1 instanceof L2D) { 544 Type t2 = dataset1.popOpStack(); 545 Type t1 = dataset1.popOpStack(); 546 dataset1.pushOpStack(DOUBLEUpper.instance); 547 dataset1.pushOpStack(Type.DOUBLE); 548 if (DEBUG_TYPE) { 549 checkTypeLONGUpper(t1); 550 checkTypeLONG(t2); 551 } 552 } else if (ins1 instanceof L2F) { 553 Type t2 = dataset1.popOpStack(); 554 Type t1 = dataset1.popOpStack(); 555 dataset1.pushOpStack(Type.FLOAT); 556 if (DEBUG_TYPE) { 557 checkTypeLONGUpper(t1); 558 checkTypeLONG(t2); 559 } 560 } else if (ins1 instanceof L2I) { 561 Type t2 = dataset1.popOpStack(); 562 Type t1 = dataset1.popOpStack(); 563 dataset1.pushOpStack(Type.INT); 564 if (DEBUG_TYPE) { 565 checkTypeLONGUpper(t1); 566 checkTypeLONG(t2); 567 } 568 } else { 569 if (DEBUG_INST) { 570 notReached(); 571 } 572 } 573 } 574 575 private void analizeCPInstruction(Instruction ins1, InstructionDataset dataset1, ConstantPoolGen cpg) { 576 if (ins1 instanceof ANEWARRAY) { 577 Type t1 = dataset1.popOpStack(); 578 dataset1.pushOpStack(Type.OBJECT); 579 if (DEBUG_TYPE) { 580 checkTypeINT(t1); 581 } 582 } else if (ins1 instanceof CHECKCAST) { 583 Type t1 = dataset1.popOpStack(); 584 dataset1.pushOpStack(t1); 585 if (DEBUG_TYPE) { 586 checkTypeReferenceType(t1); 587 } 588 } else if (ins1 instanceof FieldInstruction) { 589 if (ins1 instanceof GETFIELD) { 590 Type t1 = dataset1.popOpStack(); 591 if (DEBUG_TYPE) { 592 checkTypeReferenceType(t1); 593 } 594 Type tt = ((GETFIELD)ins1).getType(cpg); 595 if (!(tt instanceof ReferenceType)) { 596 if (tt == Type.LONG) { 597 dataset1.pushOpStack(LONGUpper.instance); 598 } else if (tt == Type.DOUBLE) { 599 dataset1.pushOpStack(DOUBLEUpper.instance); 600 } 601 } 602 dataset1.pushOpStack(tt); 603 } else if (ins1 instanceof GETSTATIC) { 604 Type tt = ((GETSTATIC)ins1).getType(cpg); 605 if (!(tt instanceof ReferenceType)) { 606 if (tt == Type.LONG) { 607 dataset1.pushOpStack(LONGUpper.instance); 608 } else if (tt == Type.DOUBLE) { 609 dataset1.pushOpStack(DOUBLEUpper.instance); 610 } 611 } 612 dataset1.pushOpStack(tt); 613 } else if (ins1 instanceof PUTFIELD) { 614 Type tt = ((PUTFIELD)ins1).getType(cpg); 615 if (tt == Type.LONG || tt == Type.DOUBLE) { 616 Type t3 = dataset1.popOpStack(); 617 } 618 Type t2 = dataset1.popOpStack(); 619 Type t1 = dataset1.popOpStack(); 620 if (DEBUG_TYPE) { 621 checkTypeReferenceType(t1); 622 } 623 } else if (ins1 instanceof PUTSTATIC) { 624 Type tt = ((PUTSTATIC)ins1).getType(cpg); 625 if (tt == Type.LONG || tt == Type.DOUBLE) { 626 Type t2 = dataset1.popOpStack(); 627 } 628 Type t1 = dataset1.popOpStack(); 629 } 630 } else if (ins1 instanceof InvokeInstruction) { 631 Type[] args = ((InvokeInstruction)ins1).getArgumentTypes(cpg); 632 for (int i=args.length-1; i>=0; i--) { 633 Type t2 = null; 634 if (args[i] == Type.LONG || args[i] == Type.DOUBLE) { 635 t2 = dataset1.popOpStack(); 636 } 637 Type t1 = dataset1.popOpStack(); 638 if (DEBUG_TYPE) { 639 if (args[i] instanceof ReferenceType) { 640 checkTypeReferenceType(t1); 641 } else if (args[i] == Type.INT || args[i] == Type.BYTE || args[i] == Type.SHORT || args[i] == Type.CHAR || args[i] == Type.BOOLEAN) { 642 checkTypeINT(t1); 643 } else if (args[i] == Type.FLOAT) { 644 checkTypeFLOAT(t1); 645 } else if (args[i] == Type.LONG) { 646 checkTypeLONGUpper(t1); 647 checkTypeLONG(t2); 648 } else if (args[i] == Type.DOUBLE) { 649 checkTypeDOUBLEUpper(t1); 650 checkTypeDOUBLE(t2); 651 } else { 652 if (DEBUG_INST) { 653 notReached(); 654 } 655 } 656 } 657 } 658 if (ins1 instanceof INVOKEINTERFACE) { 659 Type t1 = dataset1.popOpStack(); 660 if (DEBUG_TYPE) { 661 checkTypeReferenceType(t1); 662 } 663 } else if (ins1 instanceof INVOKESPECIAL) { 664 Type t1 = dataset1.popOpStack(); 665 if (DEBUG_TYPE) { 666 checkTypeReferenceType(t1); 667 } 668 } else if (ins1 instanceof INVOKESTATIC) { 669 } else if (ins1 instanceof INVOKEVIRTUAL) { 670 Type t1 = dataset1.popOpStack(); 671 if (DEBUG_TYPE) { 672 checkTypeReferenceType(t1); 673 } 674 } else { 675 if (DEBUG_INST) { 676 notReached(); 677 } 678 } 679 Type r = ((InvokeInstruction)ins1).getReturnType(cpg); 680 if (r == Type.LONG) { 681 dataset1.pushOpStack(LONGUpper.instance); 682 } else if (r == Type.DOUBLE) { 683 dataset1.pushOpStack(DOUBLEUpper.instance); 684 } 685 if (r != Type.VOID) { 686 dataset1.pushOpStack(r); 687 } 688 } else if (ins1 instanceof INSTANCEOF) { 689 Type t1 = dataset1.popOpStack(); 690 dataset1.pushOpStack(Type.INT); 691 if (DEBUG_TYPE) { 692 checkTypeReferenceType(t1); 693 } 694 } else if (ins1 instanceof LDC) { 695 Type t = ((LDC)ins1).getType(cpg); 696 if (!(t instanceof ReferenceType)) { 697 if (t == Type.INT) { 698 t = new ConstantIntLType((LDC)ins1); 699 } else if (t == Type.LONG) { 700 dataset1.pushOpStack(LONGUpper.instance); 701 } else if (t == Type.DOUBLE) { 702 dataset1.pushOpStack(DOUBLEUpper.instance); 703 } 704 } 705 dataset1.pushOpStack(t); 706 } else if (ins1 instanceof LDC2_W) { 707 Type t = ((LDC2_W)ins1).getType(cpg); 708 if (!(t instanceof ReferenceType)) { 709 if (t == Type.LONG) { 710 dataset1.pushOpStack(LONGUpper.instance); 711 } else if (t == Type.DOUBLE) { 712 dataset1.pushOpStack(DOUBLEUpper.instance); 713 } 714 } 715 dataset1.pushOpStack(t); 716 } else if (ins1 instanceof MULTIANEWARRAY) { 717 short dims = ((MULTIANEWARRAY)ins1).getDimensions(); 718 for (int i=0; i<dims; i++) { 719 Type t = dataset1.popOpStack(); 720 if (DEBUG_TYPE) { 721 checkTypeINT(t); 722 } 723 } 724 dataset1.pushOpStack(Type.OBJECT); 725 } else if (ins1 instanceof NEW) { 726 dataset1.pushOpStack(Type.OBJECT); 727 } else { 728 if (DEBUG_INST) { 729 notReached(); 730 } 731 } 732 } 733 734 private void analizeArrayInstruction(Instruction ins1, InstructionDataset dataset1) { 735 if (ins1 instanceof AASTORE 736 || ins1 instanceof BASTORE 737 || ins1 instanceof CASTORE 738 || ins1 instanceof SASTORE 739 || ins1 instanceof IASTORE 740 || ins1 instanceof FASTORE 741 ) { 742 Type t3 = dataset1.popOpStack(); 743 Type t2 = dataset1.popOpStack(); 744 Type t1 = dataset1.popOpStack(); 745 if (DEBUG_TYPE) { 746 checkTypeReferenceType(t1); 747 checkTypeINT(t2); 748 if (ins1 instanceof AASTORE) { 749 checkTypeReferenceType(t3); 750 } else if ( 751 ins1 instanceof BASTORE 752 || ins1 instanceof CASTORE 753 || ins1 instanceof SASTORE 754 || ins1 instanceof IASTORE 755 ) { 756 checkTypeINT(t3); 757 } else if (ins1 instanceof FASTORE) { 758 checkTypeFLOAT(t3); 759 } 760 } 761 762 } else if ( 763 ins1 instanceof LASTORE 764 || ins1 instanceof DASTORE 765 ) { 766 Type t4 = dataset1.popOpStack(); 767 Type t3 = dataset1.popOpStack(); 768 Type t2 = dataset1.popOpStack(); 769 Type t1 = dataset1.popOpStack(); 770 if (DEBUG_TYPE) { 771 checkTypeReferenceType(t1); 772 checkTypeINT(t2); 773 if (ins1 instanceof LASTORE) { 774 checkTypeLONGUpper(t3); 775 checkTypeLONG(t4); 776 } else { 777 checkTypeDOUBLEUpper(t3); 778 checkTypeDOUBLE(t4); 779 } 780 } 781 782 } else if (ins1 instanceof AALOAD) { 783 Type t2 = dataset1.popOpStack(); 784 Type t1 = dataset1.popOpStack(); 785 dataset1.pushOpStack(Type.OBJECT); 786 if (DEBUG_TYPE) { 787 checkTypeReferenceType(t1); 788 checkTypeINT(t2); 789 } 790 791 } else if ( 792 ins1 instanceof BALOAD 793 || ins1 instanceof CALOAD 794 || ins1 instanceof SALOAD 795 || ins1 instanceof IALOAD 796 ) { 797 Type t2 = dataset1.popOpStack(); 798 Type t1 = dataset1.popOpStack(); 799 dataset1.pushOpStack(Type.INT); 800 if (DEBUG_TYPE) { 801 checkTypeReferenceType(t1); 802 checkTypeINT(t2); 803 } 804 805 } else if (ins1 instanceof FALOAD) { 806 Type t2 = dataset1.popOpStack(); 807 Type t1 = dataset1.popOpStack(); 808 dataset1.pushOpStack(Type.FLOAT); 809 if (DEBUG_TYPE) { 810 checkTypeReferenceType(t1); 811 checkTypeINT(t2); 812 } 813 814 } else if (ins1 instanceof LALOAD) { 815 Type t2 = dataset1.popOpStack(); 816 Type t1 = dataset1.popOpStack(); 817 dataset1.pushOpStack(LONGUpper.instance); 818 dataset1.pushOpStack(Type.LONG); 819 if (DEBUG_TYPE) { 820 checkTypeReferenceType(t1); 821 checkTypeINT(t2); 822 } 823 824 } else if (ins1 instanceof DALOAD) { 825 Type t2 = dataset1.popOpStack(); 826 Type t1 = dataset1.popOpStack(); 827 dataset1.pushOpStack(DOUBLEUpper.instance); 828 dataset1.pushOpStack(Type.DOUBLE); 829 if (DEBUG_TYPE) { 830 checkTypeReferenceType(t1); 831 checkTypeINT(t2); 832 } 833 } else { 834 if (DEBUG_INST) { 835 notReached(); 836 } 837 } 838 } 839 840 private void analizeArithmeticInstruction(Instruction ins1, InstructionDataset dataset1) { 841 if (ins1 instanceof DADD 842 || ins1 instanceof DDIV 843 || ins1 instanceof DMUL 844 || ins1 instanceof DREM 845 || ins1 instanceof DSUB 846 ) { 847 Type t4 = dataset1.popOpStack(); 848 Type t3 = dataset1.popOpStack(); 849 Type t2 = dataset1.popOpStack(); 850 Type t1 = dataset1.popOpStack(); 851 dataset1.pushOpStack(DOUBLEUpper.instance); 852 dataset1.pushOpStack(Type.DOUBLE); 853 if (DEBUG_TYPE) { 854 checkTypeDOUBLEUpper(t1); 855 checkTypeDOUBLE(t2); 856 checkTypeDOUBLEUpper(t3); 857 checkTypeDOUBLE(t4); 858 } 859 860 } else if (ins1 instanceof DNEG) { 861 Type t2 = dataset1.popOpStack(); 862 Type t1 = dataset1.popOpStack(); 863 dataset1.pushOpStack(DOUBLEUpper.instance); 864 dataset1.pushOpStack(Type.DOUBLE); 865 if (DEBUG_TYPE) { 866 checkTypeDOUBLEUpper(t1); 867 checkTypeDOUBLE(t2); 868 } 869 870 } else if ( 871 ins1 instanceof FADD 872 || ins1 instanceof FDIV 873 || ins1 instanceof FMUL 874 || ins1 instanceof FREM 875 || ins1 instanceof FSUB 876 ) { 877 Type t1 = dataset1.popOpStack(); 878 Type t2 = dataset1.popOpStack(); 879 dataset1.pushOpStack(Type.FLOAT); 880 if (DEBUG_TYPE) { 881 checkTypeFLOAT(t1); 882 checkTypeFLOAT(t2); 883 } 884 885 } else if (ins1 instanceof FNEG) { 886 Type t1 = dataset1.popOpStack(); 887 dataset1.pushOpStack(Type.FLOAT); 888 if (DEBUG_TYPE) { 889 checkTypeFLOAT(t1); 890 } 891 892 } else if ( 893 ins1 instanceof IADD 894 || ins1 instanceof IDIV 895 || ins1 instanceof IMUL 896 || ins1 instanceof IREM 897 || ins1 instanceof ISUB 898 ) { 899 Type t1 = dataset1.popOpStack(); 900 Type t2 = dataset1.popOpStack(); 901 dataset1.pushOpStack(Type.INT); 902 if (DEBUG_TYPE) { 903 checkTypeINT(t1); 904 checkTypeINT(t2); 905 } 906 907 } else if (ins1 instanceof INEG) { 908 Type t1 = dataset1.popOpStack(); 909 dataset1.pushOpStack(Type.INT); 910 if (DEBUG_TYPE) { 911 checkTypeINT(t1); 912 } 913 914 } else if ( 915 ins1 instanceof LADD 916 || ins1 instanceof LDIV 917 || ins1 instanceof LMUL 918 || ins1 instanceof LREM 919 || ins1 instanceof LSUB 920 ) { 921 Type t4 = dataset1.popOpStack(); 922 Type t3 = dataset1.popOpStack(); 923 Type t2 = dataset1.popOpStack(); 924 Type t1 = dataset1.popOpStack(); 925 dataset1.pushOpStack(LONGUpper.instance); 926 dataset1.pushOpStack(Type.LONG); 927 if (DEBUG_TYPE) { 928 checkTypeLONGUpper(t1); 929 checkTypeLONG(t2); 930 checkTypeLONGUpper(t3); 931 checkTypeLONG(t4); 932 } 933 934 } else if (ins1 instanceof LNEG) { 935 Type t2 = dataset1.popOpStack(); 936 Type t1 = dataset1.popOpStack(); 937 dataset1.pushOpStack(LONGUpper.instance); 938 dataset1.pushOpStack(Type.LONG); 939 if (DEBUG_TYPE) { 940 checkTypeLONGUpper(t1); 941 checkTypeLONG(t2); 942 } 943 944 } else if ( 945 ins1 instanceof IAND 946 || ins1 instanceof IOR 947 || ins1 instanceof ISHL 948 || ins1 instanceof ISHR 949 || ins1 instanceof IUSHR 950 || ins1 instanceof IXOR 951 ) { 952 Type t1 = dataset1.popOpStack(); 953 Type t2 = dataset1.popOpStack(); 954 dataset1.pushOpStack(Type.INT); 955 if (DEBUG_TYPE) { 956 checkTypeINT(t1); 957 checkTypeINT(t2); 958 } 959 960 } else if ( 961 ins1 instanceof LAND 962 || ins1 instanceof LOR 963 || ins1 instanceof LXOR 964 ) { 965 Type t4 = dataset1.popOpStack(); 966 Type t3 = dataset1.popOpStack(); 967 Type t2 = dataset1.popOpStack(); 968 Type t1 = dataset1.popOpStack(); 969 dataset1.pushOpStack(LONGUpper.instance); 970 dataset1.pushOpStack(Type.LONG); 971 if (DEBUG_TYPE) { 972 checkTypeLONGUpper(t1); 973 checkTypeLONG(t2); 974 checkTypeLONGUpper(t3); 975 checkTypeLONG(t4); 976 } 977 } else if ( 978 ins1 instanceof LSHL 979 || ins1 instanceof LSHR 980 || ins1 instanceof LUSHR 981 ) { 982 Type t3 = dataset1.popOpStack(); 983 Type t2 = dataset1.popOpStack(); 984 Type t1 = dataset1.popOpStack(); 985 dataset1.pushOpStack(LONGUpper.instance); 986 dataset1.pushOpStack(Type.LONG); 987 if (DEBUG_TYPE) { 988 checkTypeLONGUpper(t1); 989 checkTypeLONG(t2); 990 checkTypeINT(t3); 991 } 992 } else { 993 if (DEBUG_INST) { 994 notReached(); 995 } 996 } 997 } 998 999 private void analizeStackInstruction(Instruction ins1, InstructionDataset dataset1) { 1000 if (ins1 instanceof DUP) { 1001 Type t1 = dataset1.popOpStack(); 1002 dataset1.pushOpStack(t1); 1003 dataset1.pushOpStack(t1); 1004 } else if (ins1 instanceof DUP_X1) { 1005 Type t1 = dataset1.popOpStack(); 1006 Type t2 = dataset1.popOpStack(); 1007 dataset1.pushOpStack(t1); 1008 dataset1.pushOpStack(t2); 1009 dataset1.pushOpStack(t1); 1010 } else if (ins1 instanceof DUP_X2) { 1011 Type t1 = dataset1.popOpStack(); 1012 Type t2 = dataset1.popOpStack(); 1013 Type t3 = dataset1.popOpStack(); 1014 dataset1.pushOpStack(t1); 1015 dataset1.pushOpStack(t3); 1016 dataset1.pushOpStack(t2); 1017 dataset1.pushOpStack(t1); 1018 } else if (ins1 instanceof DUP2) { 1019 Type t1 = dataset1.popOpStack(); 1020 Type t2 = dataset1.popOpStack(); 1021 dataset1.pushOpStack(t2); 1022 dataset1.pushOpStack(t1); 1023 dataset1.pushOpStack(t2); 1024 dataset1.pushOpStack(t1); 1025 } else if (ins1 instanceof DUP2_X1) { 1026 Type t1 = dataset1.popOpStack(); 1027 Type t2 = dataset1.popOpStack(); 1028 Type t3 = dataset1.popOpStack(); 1029 dataset1.pushOpStack(t2); 1030 dataset1.pushOpStack(t1); 1031 dataset1.pushOpStack(t3); 1032 dataset1.pushOpStack(t2); 1033 dataset1.pushOpStack(t1); 1034 } else if (ins1 instanceof DUP2_X2) { 1035 Type t1 = dataset1.popOpStack(); 1036 Type t2 = dataset1.popOpStack(); 1037 Type t3 = dataset1.popOpStack(); 1038 Type t4 = dataset1.popOpStack(); 1039 dataset1.pushOpStack(t2); 1040 dataset1.pushOpStack(t1); 1041 dataset1.pushOpStack(t4); 1042 dataset1.pushOpStack(t3); 1043 dataset1.pushOpStack(t2); 1044 dataset1.pushOpStack(t1); 1045 } else if (ins1 instanceof POP) { 1046 Type t1 = dataset1.popOpStack(); 1047 } else if (ins1 instanceof POP2) { 1048 Type t1 = dataset1.popOpStack(); 1049 Type t2 = dataset1.popOpStack(); 1050 } else if (ins1 instanceof SWAP) { 1051 Type t1 = dataset1.popOpStack(); 1052 Type t2 = dataset1.popOpStack(); 1053 dataset1.pushOpStack(t1); 1054 dataset1.pushOpStack(t2); 1055 } else { 1056 if (DEBUG_INST) { 1057 notReached(); 1058 } 1059 } 1060 } 1061 1062 private static void notReached() { 1064 int x = 0; 1065 throw new java.lang.RuntimeException ("NOT REACHED!!"); 1066 } 1067 1068 private static void checkTypeReturnaddressType(Type t) { 1070 if (!(t instanceof ReturnaddressType)) { 1071 notReached(); 1072 } 1073 } 1074 1075 private static void checkTypeReferenceTypeOrReturnaddressType(Type t) { 1076 if (!(t instanceof ReferenceType) && !(t instanceof ReturnaddressType)) { 1077 notReached(); 1078 } 1079 } 1080 1081 private static void checkTypeReferenceType(Type t) { 1082 if (!(t instanceof ReferenceType)) { 1083 notReached(); 1084 } 1085 } 1086 1087 private static void checkTypeINT(Type t) { 1088 if (t != Type.INT && t != Type.BOOLEAN && t != Type.BYTE && t != Type.CHAR && t != Type.SHORT && !(t instanceof ConstantIntType)) { 1089 notReached(); 1090 } 1091 } 1092 1093 private static void checkTypeFLOAT(Type t) { 1094 if (t != Type.FLOAT) { 1095 notReached(); 1096 } 1097 } 1098 1099 private static void checkTypeLONGUpper(Type t) { 1100 if (t != LONGUpper.instance) { 1101 notReached(); 1102 } 1103 } 1104 private static void checkTypeLONG(Type t) { 1105 if (t != Type.LONG) { 1106 notReached(); 1107 } 1108 } 1109 1110 private static void checkTypeDOUBLEUpper(Type t) { 1111 if (t != DOUBLEUpper.instance) { 1112 notReached(); 1113 } 1114 } 1115 private static void checkTypeDOUBLE(Type t) { 1116 if (t != Type.DOUBLE) { 1117 notReached(); 1118 } 1119 } 1120 1121 private static class PassCounter { 1123 private static Integer int1 = new Integer (1); 1124 private static Integer int2 = new Integer (2); 1125 1126 private HashMap map = new HashMap(); 1127 PassCounter() { 1128 } 1129 1130 void put(InstructionHandle target) { 1131 Integer cnt = (Integer )map.get(target); 1132 if (cnt == null) { 1133 cnt = int1; 1134 } else { 1135 cnt = int2; 1136 } 1137 map.put(target, cnt); 1138 } 1139 1140 boolean isCompleat(InstructionHandle target) { 1141 Integer cnt = (Integer )map.get(target); 1142 if (cnt == int2) { 1143 return true; 1144 } 1145 return false; 1146 } 1147 } 1148 1149 static class InstructionDataset implements Cloneable { 1151 private InstructionHandle ih; 1152 private int opStackTopIndex = -1; 1153 private ArrayList opStack = new ArrayList(); private ArrayList locSlot = new ArrayList(); 1156 InstructionDataset(InstructionHandle ih) { 1157 this.ih = ih; 1158 } 1159 1160 InstructionDataset duplicate() { 1161 return (InstructionDataset)this.clone(); 1162 } 1163 1164 public Object clone() { 1165 try { 1166 InstructionDataset r = (InstructionDataset)super.clone(); 1167 r.opStack = (ArrayList)r.opStack.clone(); 1168 r.locSlot = (ArrayList)r.locSlot.clone(); 1169 return r; 1170 } catch (CloneNotSupportedException ex) { 1171 throw new InternalError (ex.getMessage()); 1173 } 1174 } 1175 1176 Type getLocalType(int vn) { 1178 return fromLoc(vn); 1179 } 1180 1181 void merge(InstructionDataset pre) { 1183 int preTop = pre.opStackTopIndex; 1185 if (preTop >= 0) { 1186 if (preTop >= opStack.size()) { 1187 int sz = opStack.size(); 1188 for (int i=0; i<=preTop+1-sz; i++) { 1189 opStack.add(null); 1190 } 1191 } 1192 for (int i=0; i<=preTop; i++) { 1193 Type t0 = (Type)pre.opStack.get(i); 1194 Type t1 = (Type)this.opStack.get(i); 1195 1196 if (t0 == t1) { 1197 } else if (t1 == null || t1 == Type.UNKNOWN) { 1199 this.opStack.set(i, t0); 1200 1201 } else if (t0 instanceof ReferenceType && t1 instanceof ReferenceType) { 1202 this.opStack.set(i, t0); 1203 } else if (t0 instanceof ReturnaddressType && t1 instanceof ReturnaddressType) { 1204 this.opStack.set(i, t0); 1205 1206 } else if ( 1207 (t0 == Type.INT || t0 == Type.BOOLEAN || t0 == Type.BYTE || t0 == Type.SHORT || t0 == Type.CHAR) 1208 && (t1 == Type.INT || t1 == Type.BOOLEAN || t1 == Type.BYTE || t1 == Type.SHORT || t1 == Type.CHAR) 1209 ) { 1210 this.opStack.set(i, t0); 1211 1212 } else if (t0 instanceof DirectConstant && t1 instanceof DirectConstant) { 1213 this.opStack.set(i, t0); 1214 } else if (t0 instanceof DirectConstant && !(t1 instanceof DirectConstant)) { 1215 } else if (!(t0 instanceof DirectConstant) && t1 instanceof DirectConstant) { 1217 this.opStack.set(i, t0); 1218 1219 } else if (t1 == LONGUpper.instance) { 1220 this.opStack.set(i, t0); 1221 } else if (t1 == DOUBLEUpper.instance) { 1222 this.opStack.set(i, t0); 1223 1224 } else { 1225 this.opStack.set(i, t0); 1226 } 1227 } 1228 if (this.opStackTopIndex < preTop) { 1229 this.opStackTopIndex = preTop; 1230 } 1231 } 1232 1233 int preSz = pre.locSlot.size(); 1235 locSlotRangeCheck(preSz-1); 1236 for (int i=0; i<preSz; i++) { 1237 Type t0 = (Type)pre.locSlot.get(i); 1238 Type t1 = (Type)this.locSlot.get(i); 1239 1240 if (t0 == t1) { 1241 } else if (t0 == Type.UNKNOWN) { 1243 } else if (t1 == Type.UNKNOWN) { 1245 this.locSlot.set(i, t0); 1246 1247 } else if (t0 instanceof ReferenceType && t1 instanceof ReferenceType) { 1248 this.locSlot.set(i, t0); 1249 } else if (t0 instanceof ReturnaddressType && t1 instanceof ReturnaddressType) { 1250 this.locSlot.set(i, t0); 1251 1252 } else if ( 1253 (t0 == Type.INT || t0 == Type.BOOLEAN || t0 == Type.BYTE || t0 == Type.SHORT || t0 == Type.CHAR) 1254 && (t1 == Type.INT || t1 == Type.BOOLEAN || t1 == Type.BYTE || t1 == Type.SHORT || t1 == Type.CHAR) 1255 ) { 1256 this.locSlot.set(i, t0); 1257 1258 } else if (t0 instanceof DirectConstant && t1 instanceof DirectConstant) { 1259 this.locSlot.set(i, t0); 1260 } else if (t0 instanceof DirectConstant && !(t1 instanceof DirectConstant)) { 1261 } else if (!(t0 instanceof DirectConstant) && t1 instanceof DirectConstant) { 1263 this.locSlot.set(i, t0); 1264 1265 } else if (t1 == LONGUpper.instance) { 1266 this.locSlot.set(i, t0); 1267 this.locSlot.set(i+1, Type.UNKNOWN); 1268 } else if (t1 == DOUBLEUpper.instance) { 1269 this.locSlot.set(i, t0); 1270 this.locSlot.set(i+1, Type.UNKNOWN); 1271 1272 } else { 1273 this.locSlot.set(i, Type.UNKNOWN); 1274 } 1275 } 1276 } 1277 1278 private void pushOpStack(Type t) { 1280 opStackTopIndex ++; 1281 if (opStackTopIndex >= opStack.size()) { 1282 opStack.add(null); 1283 } 1284 opStack.set(opStackTopIndex, t); 1285 if (DEBUG_TYPE) { 1286 if (t == Type.LONG) { 1287 Type t1 = (Type)opStack.get(opStackTopIndex-1); 1288 checkTypeLONGUpper(t1); 1289 } else if (t == Type.DOUBLE) { 1290 Type t1 = (Type)opStack.get(opStackTopIndex-1); 1291 checkTypeDOUBLEUpper(t1); 1292 } 1293 } 1294 } 1295 1296 private Type popOpStack() { 1297 if (opStackTopIndex < 0) { 1298 int x = 0; 1299 } 1300 Type r = (Type)opStack.get(opStackTopIndex); 1301 opStack.set(opStackTopIndex, null); 1302 opStackTopIndex --; 1303 return r; 1304 } 1305 1306 private void locSlotRangeCheck(int vn) { 1307 int sz = locSlot.size(); 1308 for (int i=0; i<vn+1-sz; i++) { 1309 locSlot.add(Type.UNKNOWN); 1310 } 1311 } 1312 1313 private void toLoc(int vn, Type t) { 1314 locSlotRangeCheck(vn); 1315 locSlot.set(vn, t); 1316 } 1317 1318 private Type fromLoc(int vn) { 1319 locSlotRangeCheck(vn); 1320 return (Type)locSlot.get(vn); 1321 } 1322 } 1323} 1324 1325class LONGUpper extends Type { 1327 static LONGUpper instance = new LONGUpper(); 1328 private LONGUpper() { 1329 super((byte)0, "long upper"); 1330 } 1331} 1332 1333class DOUBLEUpper extends Type { 1334 static DOUBLEUpper instance = new DOUBLEUpper(); 1335 private DOUBLEUpper() { 1336 super((byte)0, "double upper"); 1337 } 1338} 1339 1340interface DirectConstant { 1342} 1343 1344class CONSTNull extends ReferenceType implements DirectConstant { 1345 static CONSTNull instance = new CONSTNull(); 1346 private CONSTNull() { 1347 super(Constants.T_OBJECT, "<constant null object>"); 1348 } 1349 1350 Instruction createInstruction() { 1351 return new ACONST_NULL(); 1352 } 1353} 1354 1355class ConstantType extends Type implements DirectConstant { 1356 ConstantType(byte type) { 1357 super(type, Constants.SHORT_TYPE_NAMES[type]); 1358 if ((type < Constants.T_BOOLEAN) || (type > Constants.T_VOID)) { 1359 throw new ClassGenException("Invalid type: " + type); 1360 } 1361 } 1362} 1363 1364class ConstantIntType extends ConstantType { 1365 private LDC inst; 1366 private int val; 1367 1368 ConstantIntType(int val) { 1369 super(Constants.T_INT); 1370 this.val = val; 1371 } 1372 1373 ConstantIntType(Integer value) { 1374 this(value.intValue()); 1375 } 1376 1377 int getValue() { 1378 return val; 1379 } 1380 1381 Instruction createInstruction() { 1382 if (val >= -1 && val <= 5) { 1383 return new ICONST(val); 1384 } else if (val >= Byte.MIN_VALUE && val <= Byte.MAX_VALUE) { 1385 return new BIPUSH((byte)val); 1386 } else if (val >= Short.MIN_VALUE && val <= Short.MAX_VALUE) { 1387 return new SIPUSH((short)val); 1388 } 1389 return null; 1390 } 1391} 1392 1393class ConstantIntLType extends ConstantIntType { 1394 private LDC inst; 1395 1396 ConstantIntLType(LDC inst) { 1397 super(0); 1398 this.inst = inst; 1399 } 1400 1401 int getValue() { 1402 return 0; 1403 } 1404 1405 Instruction createInstruction() { 1406 return inst; 1407 } 1408} 1409 | Popular Tags |