1 30 31 package jbet; 32 import java.util.*; 33 34 52 53 public class Node implements Cloneable { 54 55 Node safeclone() { 56 try { 57 return (Node) clone(); 58 } catch (CloneNotSupportedException e) { 59 throw new IllegalStateException (e.getMessage()); 60 } 61 } 62 63 public BasicBlock sb; public int op; public int count; public HashSet destinations; 68 public boolean esneed; public int clocal = -1; public boolean done; public boolean required; 74 public boolean external; 75 public Object otype; 76 77 public String comment; 78 79 public Vector requires = new Vector(); 85 int number = -1; 86 boolean noreplace; 88 boolean hasDirectUsers; 90 HashSet users; 91 boolean hasIndirectUsers; 92 93 public int serial; 94 95 public boolean isFake() { return false;}; 96 97 public static Node.var[] NONE = new Node.var[0]; 98 99 public static Node EXIT = new Node() { 100 public boolean equals(Object o) { return o == this; } 101 public boolean isFake() { return true; } 102 protected String toString1 (int flags) { return "EXIT"; } 103 }; 104 105 106 public static final int OP_VAR = 0; 108 public static final int OP_CINT = 1; 109 public static final int OP_CSTRING = 2; 110 111 public static final int OP_INEG = 101; 113 public static final int OP_ARRAYLENGTH = 102; 114 public static final int OP_L2I = 103; 115 public static final int OP_I2L = 104; 116 117 public static final int OP_FNEG = 105; 118 public static final int OP_L2F = 106; 119 public static final int OP_I2F = 107; 120 public static final int OP_F2I = 108; 121 public static final int OP_F2L = 109; 122 public static final int OP_DNEG = 110; 123 public static final int OP_L2D = 111; 124 public static final int OP_I2D = 112; 125 public static final int OP_F2D = 113; 126 public static final int OP_D2I = 114; 127 public static final int OP_D2L = 115; 128 public static final int OP_D2F = 116; 129 public static final int OP_I2B = 117; 130 public static final int OP_I2C = 118; 131 public static final int OP_I2S = 119; 132 public static final int OP_LNEG = 120; 133 134 public static final int OP_IADD = 201; 136 public static final int OP_ISUB = 202; 137 public static final int OP_IMUL = 203; 138 public static final int OP_IDIV = 204; 139 public static final int OP_IAND = 205; 140 public static final int OP_IOR = 206; 141 public static final int OP_IXOR = 207; 142 143 public static final int OP_LADD = 208; 144 public static final int OP_LSUB = 209; 145 public static final int OP_LMUL = 210; 146 public static final int OP_LDIV = 211; 147 public static final int OP_LAND = 212; 148 public static final int OP_LOR = 213; 149 public static final int OP_LXOR = 214; 150 public static final int OP_LCMP = 215; 151 152 public static final int OP_FADD = 216; 153 public static final int OP_FSUB = 217; 154 public static final int OP_FMUL = 218; 155 public static final int OP_FDIV = 219; 156 157 public static final int OP_FCMPL = 220; 158 public static final int OP_FCMPG = 221; 159 160 public static final int OP_DADD = 222; 161 public static final int OP_DSUB = 223; 162 public static final int OP_DMUL = 224; 163 public static final int OP_DDIV = 225; 164 165 public static final int OP_DCMPL = 226; 166 public static final int OP_DCMPG = 227; 167 168 public static final int OP_IREM = 228; 169 public static final int OP_ISHR = 229; 170 public static final int OP_ISHL = 230; 171 172 public static final int OP_LSHR = 231; 173 public static final int OP_LSHL = 232; 174 public static final int OP_LREM = 233; 175 176 public static final int OP_IUSHR = 234; 177 public static final int OP_LUSHR = 235; 178 179 public static final int OP_FREM = 236; 180 public static final int OP_DREM = 237; 181 182 public static final int OP_INVOKESTATIC = 901; 184 public static final int OP_INVOKEVIRTUAL = 902; 185 public static final int OP_INVOKEINTERFACE = 903; 186 public static final int OP_GETFIELD = 904; 187 public static final int OP_GETSTATIC = 905; 188 public static final int OP_PUTFIELD = 906; 189 public static final int OP_PUTSTATIC = 907; 190 191 public static final int TOSTR_DFL = 1; 193 public static final int TOSTR_EXTRA = 2; 194 public static final int TOSTR_SRC = 4; 195 public static final int TOSTR_FLAGS1 = 7; 196 public static final int TOSTR_COMMENT = 8; 197 198 static final String op1char = "-#IL-FFIL-DDDILFBCS-"; 199 static final String op2char = "+-*/&|^+-*/&|^?+-*/??+-*/??%><><%->>%%"; 200 201 public static final int op1jvm[] = {Instruction.OP_INEG, 203 Instruction.OP_ARRAYLENGTH, 204 Instruction.OP_L2I, 205 Instruction.OP_I2L, 206 Instruction.OP_FNEG, 207 Instruction.OP_L2F, 208 Instruction.OP_I2F, 209 Instruction.OP_F2I, 210 Instruction.OP_F2L, 211 Instruction.OP_DNEG, 212 Instruction.OP_L2D, 213 Instruction.OP_I2D, 214 Instruction.OP_F2D, 215 Instruction.OP_D2I, 216 Instruction.OP_D2L, 217 Instruction.OP_D2F, 218 Instruction.OP_I2B, 219 Instruction.OP_I2C, 220 Instruction.OP_I2S, 221 Instruction.OP_LNEG, 222 }; 223 224 public static final int op2jvm[] = {Instruction.OP_IADD, Instruction.OP_ISUB, 225 Instruction.OP_IMUL, Instruction.OP_IDIV, 226 Instruction.OP_IAND, Instruction.OP_IOR, 227 Instruction.OP_IXOR, 228 229 Instruction.OP_LADD, Instruction.OP_LSUB, 230 Instruction.OP_LMUL, Instruction.OP_LDIV, 231 Instruction.OP_LAND, Instruction.OP_LOR, 232 Instruction.OP_LXOR, Instruction.OP_LCMP, 233 234 Instruction.OP_FADD, Instruction.OP_FSUB, 235 Instruction.OP_FMUL, Instruction.OP_FDIV, 236 Instruction.OP_FCMPL,Instruction.OP_FCMPG, 237 Instruction.OP_DADD, Instruction.OP_DSUB, 238 Instruction.OP_DMUL, Instruction.OP_DDIV, 239 Instruction.OP_DCMPL,Instruction.OP_DCMPG, 240 Instruction.OP_IREM, Instruction.OP_ISHR, 241 Instruction.OP_ISHL, 242 243 Instruction.OP_LSHR, Instruction.OP_LSHL, 244 Instruction.OP_LREM, 245 Instruction.OP_IUSHR, Instruction.OP_LUSHR, 246 Instruction.OP_FREM, Instruction.OP_DREM 247 }; 248 249 static final Type op2ptype[] = { Type.INT, Type.INT, 250 Type.INT, Type.INT, 251 Type.INT, Type.INT, 252 Type.INT, Type.INT, 253 Type.INT, Type.INT, 254 Type.INT, Type.INT, 255 Type.INT, Type.INT, 256 Type.LONG,Type.LONG, 257 Type.LONG,Type.LONG, 258 Type.LONG,Type.LONG, 259 Type.LONG,Type.LONG, 260 Type.LONG,Type.LONG, 261 Type.LONG,Type.LONG, 262 Type.LONG,Type.LONG, 263 Type.LONG,Type.LONG, 264 Type.FLOAT,Type.FLOAT, 265 Type.FLOAT,Type.FLOAT, 266 Type.FLOAT,Type.FLOAT, 267 Type.FLOAT,Type.FLOAT, 268 Type.FLOAT,Type.FLOAT, 269 Type.FLOAT,Type.FLOAT, 270 Type.DOUBLE,Type.DOUBLE, 271 Type.DOUBLE,Type.DOUBLE, 272 Type.DOUBLE,Type.DOUBLE, 273 Type.DOUBLE,Type.DOUBLE, 274 Type.DOUBLE,Type.DOUBLE, 275 Type.DOUBLE,Type.DOUBLE, 276 Type.INT,Type.INT, 277 Type.INT,Type.INT, 278 Type.INT,Type.INT, 279 Type.LONG,Type.INT, 280 Type.LONG,Type.INT, 281 Type.LONG, Type.LONG, 282 Type.INT, Type.INT, 283 Type.LONG, Type.INT, 284 Type.FLOAT,Type.FLOAT, 285 Type.DOUBLE,Type.DOUBLE }; 286 287 static final Type op1ptype[] = { Type.INT, 289 Type.ARRAY, 290 Type.LONG, 291 Type.INT, 292 Type.FLOAT, 293 Type.LONG, 294 Type.INT, 295 Type.FLOAT, 296 Type.FLOAT, 297 Type.DOUBLE, 298 Type.LONG, 299 Type.INT, 300 Type.FLOAT, 301 Type.DOUBLE, 302 Type.DOUBLE, 303 Type.DOUBLE, 304 Type.INT, 305 Type.INT, 306 Type.INT, 307 Type.LONG, 308 } ; 309 310 static final Type op1type[] = { Type.INT, 312 Type.INT, 313 Type.INT, 314 Type.LONG, 315 Type.FLOAT, 316 Type.FLOAT, 317 Type.FLOAT, 318 Type.INT, 319 Type.LONG, 320 Type.DOUBLE, 321 Type.DOUBLE, 322 Type.DOUBLE, 323 Type.DOUBLE, 324 Type.INT, 325 Type.LONG, 326 Type.FLOAT, 327 Type.BYTE, 328 Type.CHAR, 329 Type.SHORT, 330 Type.INT, 331 Type.LONG, 332 } ; 333 334 static final Type op2type[] = { Type.INT, 335 Type.INT, 336 Type.INT, 337 Type.INT, 338 Type.INT, 339 Type.INT, 340 Type.INT, 341 Type.LONG, 342 Type.LONG, 343 Type.LONG, 344 Type.LONG, 345 Type.LONG, 346 Type.LONG, 347 Type.LONG, 348 Type.INT, 349 Type.FLOAT, 350 Type.FLOAT, 351 Type.FLOAT, 352 Type.FLOAT, 353 Type.BOOLEAN, 354 Type.BOOLEAN, 355 Type.DOUBLE, 356 Type.DOUBLE, 357 Type.DOUBLE, 358 Type.DOUBLE, 359 Type.BOOLEAN, 360 Type.BOOLEAN, 361 Type.INT, 362 Type.INT, 363 Type.INT, 364 Type.LONG, 365 Type.LONG, 366 Type.LONG, Type.INT, Type.LONG, 367 Type.FLOAT,Type.DOUBLE }; 368 369 public static final int jvm2node[] = new int [256]; 371 372 static { 373 jvm2node[Instruction.OP_IADD] = Node.OP_IADD; 374 jvm2node[Instruction.OP_ISUB] = Node.OP_ISUB; 375 jvm2node[Instruction.OP_IMUL] = Node.OP_IMUL; 376 jvm2node[Instruction.OP_IDIV] = Node.OP_IDIV; 377 jvm2node[Instruction.OP_IREM] = Node.OP_IREM; 378 jvm2node[Instruction.OP_IAND] = Node.OP_IAND; 379 jvm2node[Instruction.OP_IOR ] = Node.OP_IOR; 380 jvm2node[Instruction.OP_IXOR] = Node.OP_IXOR; 381 jvm2node[Instruction.OP_INEG] = Node.OP_INEG; 382 jvm2node[Instruction.OP_DNEG] = Node.OP_DNEG; 383 jvm2node[Instruction.OP_FNEG] = Node.OP_FNEG; 384 jvm2node[Instruction.OP_LNEG] = Node.OP_LNEG; 385 jvm2node[Instruction.OP_ARRAYLENGTH] = Node.OP_ARRAYLENGTH; 386 jvm2node[Instruction.OP_LADD] = Node.OP_LADD; 387 jvm2node[Instruction.OP_LSUB] = Node.OP_LSUB; 388 jvm2node[Instruction.OP_LMUL] = Node.OP_LMUL; 389 jvm2node[Instruction.OP_LDIV] = Node.OP_LDIV; 390 jvm2node[Instruction.OP_LAND] = Node.OP_LAND; 391 jvm2node[Instruction.OP_LOR ] = Node.OP_LOR; 392 jvm2node[Instruction.OP_LXOR] = Node.OP_LXOR; 393 jvm2node[Instruction.OP_LCMP] = Node.OP_LCMP; 394 jvm2node[Instruction.OP_L2I ] = Node.OP_L2I; 395 jvm2node[Instruction.OP_I2L ] = Node.OP_I2L; 396 jvm2node[Instruction.OP_FADD] = Node.OP_FADD; 397 jvm2node[Instruction.OP_FSUB] = Node.OP_FSUB; 398 jvm2node[Instruction.OP_FMUL] = Node.OP_FMUL; 399 jvm2node[Instruction.OP_FDIV] = Node.OP_FDIV; 400 jvm2node[Instruction.OP_FCMPL] = Node.OP_FCMPL; 401 jvm2node[Instruction.OP_FCMPG] = Node.OP_FCMPG; 402 jvm2node[Instruction.OP_L2F ] = Node.OP_L2F; 403 jvm2node[Instruction.OP_I2F ] = Node.OP_I2F; 404 jvm2node[Instruction.OP_F2I ] = Node.OP_F2I; 405 jvm2node[Instruction.OP_F2L ] = Node.OP_F2L; 406 jvm2node[Instruction.OP_DADD] = Node.OP_DADD; 407 jvm2node[Instruction.OP_DSUB] = Node.OP_DSUB; 408 jvm2node[Instruction.OP_DMUL] = Node.OP_DMUL; 409 jvm2node[Instruction.OP_DDIV] = Node.OP_DDIV; 410 jvm2node[Instruction.OP_DCMPL] = Node.OP_DCMPL; 411 jvm2node[Instruction.OP_DCMPG] = Node.OP_DCMPG; 412 jvm2node[Instruction.OP_L2D ] = Node.OP_L2D; 413 jvm2node[Instruction.OP_I2D ] = Node.OP_I2D; 414 jvm2node[Instruction.OP_F2D ] = Node.OP_F2D; 415 jvm2node[Instruction.OP_D2I ] = Node.OP_D2I; 416 jvm2node[Instruction.OP_D2L ] = Node.OP_D2L; 417 jvm2node[Instruction.OP_D2F ] = Node.OP_D2F; 418 jvm2node[Instruction.OP_I2C ] = Node.OP_I2C; 419 jvm2node[Instruction.OP_I2B ] = Node.OP_I2B; 420 jvm2node[Instruction.OP_I2S ] = Node.OP_I2S; 421 jvm2node[Instruction.OP_LSHR ] = Node.OP_LSHR; 422 jvm2node[Instruction.OP_LSHL ] = Node.OP_LSHL; 423 jvm2node[Instruction.OP_ISHR ] = Node.OP_ISHR; 424 jvm2node[Instruction.OP_ISHL ] = Node.OP_ISHL; 425 jvm2node[Instruction.OP_LREM ] = Node.OP_LREM; 426 jvm2node[Instruction.OP_IUSHR ] = Node.OP_IUSHR; 427 jvm2node[Instruction.OP_LUSHR ] = Node.OP_LUSHR; 428 jvm2node[Instruction.OP_FREM ] = Node.OP_FREM; 429 jvm2node[Instruction.OP_DREM ] = Node.OP_DREM; 430 } 431 432 public boolean isinit() { return false; } 433 434 public Node usesAt(int i) { 435 return (Node) requires.elementAt(i); 436 } 437 438 439 440 public Type paramType (int i) { 441 throw new IllegalStateException (getClass().getName() + ": invalid param number " + i); 442 } 443 444 449 public int numParams() { 450 return 0; 451 } 452 453 final int objectHashCode() { return super.hashCode(); } 454 455 public final String toString() { 456 if (comment != null) 457 return toString1 (TOSTR_EXTRA) + " /* " + comment + " */ "; 458 else 459 if (serial >= 0) 460 return toString1 (TOSTR_EXTRA); 461 else 462 return "(" + toString1 (TOSTR_EXTRA) + ")*" + serial; 463 } 464 465 public final String toString (int flags) { 466 if ((flags & TOSTR_COMMENT) != 0 && comment != null) 467 return toString1 (flags & TOSTR_FLAGS1) + " /* " + comment + " */ "; 468 else if ((flags & TOSTR_SRC) != 0 && clocal != -1 && !idempotent()) 469 return "t" + clocal; 470 else 471 if (serial >= 0) 472 return toString1 (flags & TOSTR_FLAGS1); 473 else 474 return "(" + toString1 (flags & TOSTR_FLAGS1) + ")*" + serial; 475 476 } 477 478 protected String toString1 (int flags) { return "invalid node " + getClass().getName(); } 479 480 481 public final int jvm2node (int jvm_op) { return jvm2node[jvm_op]; } 482 483 484 public final String destinationString() { 485 StringBuffer out = new StringBuffer (); 486 487 if (destinations != null) 488 for (Iterator i = destinations.iterator(); i.hasNext();) { 489 out.append (i.next()); 490 if (i.hasNext() || esneed) 491 out.append (", "); 492 } 493 if (esneed) { 494 out.append ("es"); 495 } else if (destinations == null) { 496 out.append ("none"); 497 } 498 if (required) { 499 out.append (",require"); 500 } 501 502 return out.toString(); 503 } 504 505 public void addDestination(Node n) { 506 if (destinations == null) 507 destinations = new HashSet(); 508 destinations.add(n); 509 } 510 511 512 513 public void addDestination2 (Node.var n) { 514 if (destinations == null) 515 destinations = new HashSet(); 516 destinations.add (n); 517 n.producers.add (this); 518 } 519 520 521 522 public void findinputs (int[] mk) { } 523 524 525 public final void addrefcounts () { 526 Vector s = new Vector(); 527 allnodes (s); 528 for (Iterator i = s.iterator(); i.hasNext(); ) { 529 ((Node)i.next()).count++; 530 } 531 } 532 533 534 public final HashSet allnodes() { HashSet v = new HashSet(); allnodes (v); return v; } 535 536 537 public final void allnodes (Collection v) { allnodes (v, true); } 538 public void allnodes (Collection v, boolean doRequires) { 539 v.add (this); 540 541 if (doRequires) 542 for (Iterator i = requires.iterator(); i.hasNext(); ) 543 ((Node)i.next()).allnodes (v, doRequires); 544 else 545 for (int i = 0; i < numParams(); i++) 546 usesAt (i).allnodes (v, doRequires); 547 } 548 549 551 public boolean idempotent() { return true; } 552 553 public boolean hasSideEffect() { return false; } 554 555 public final int countDests (int extra, boolean leaveonstack) { 556 int nvars = 0; 557 if (extra != -1) nvars++; 558 if (leaveonstack) nvars++; 559 if (destinations != null) 560 for (Iterator i = destinations.iterator(); i.hasNext();) 561 if (i.next() instanceof Node.var) 562 nvars++; 563 return nvars; 564 } 565 566 567 570 public final void storeDests (Snippit out, LocalAccess locals, int extra, boolean leaveonstack) { 571 if ( this.type().equals( Type.VOID ) ) return; 572 if (this instanceof ret) return; 574 int nvars = countDests(extra, leaveonstack); 575 576 out.setDupX (type(), nvars-1 ); 577 578 if (destinations != null) 579 for (Iterator i = destinations.iterator(); i.hasNext();) { 580 Object o = i.next(); 581 if (o instanceof Node.var) { 582 Node.var dest = (var) o; 583 locals.store (out, dest.outlvt, type()); 585 } 586 } 587 588 if (extra != -1) 589 locals.store (out, extra, type()); 590 } 591 592 593 594 595 596 public Type type() { throw new IllegalStateException ("invalid node " + getClass().getName()); } 597 598 599 public final InternSet requires() { 600 InternSet out = new InternSet(); 601 for (int i = numParams(); i < requires.size(); i++) 602 out.add (requires.elementAt (i)); 603 return out; 604 } 605 606 607 public void require (Node n) 608 { 609 if (n == this) 610 throw new IllegalStateException ("node cannot require itself"); 611 if (n instanceof Node.Cast) 612 require (((Node.Cast) n).val); 613 614 if (n.idempotent ()) 615 return; if (idempotent()) 617 return; 619 requires.addElement (n); 620 } 621 622 public final void require (Collection c) 623 { 624 for (Iterator i = c.iterator(); i.hasNext(); ) { 625 Object o = i.next(); 626 require ((Node)o); 627 } 628 } 629 630 public void require2 (Node n) 631 { 632 require (n); 633 for (int i = 0; i < numParams(); i++) 634 usesAt (i).require2 (n); 635 } 637 638 public final void require2 (Collection c) 639 { 640 require (c); 641 for (int i = 0; i < numParams(); i++) 642 usesAt (i).require2 (c); 643 } 645 646 647 public final void urequire (Collection c) 648 { 649 for (Iterator i = c.iterator(); i.hasNext(); ) { 650 Node o = (Node) i.next(); 651 o.require (this); 652 } 653 } 654 655 656 657 675 676 public static class SubMethod 677 { 678 public Node f (Node in) throws Throwable { return in; } 679 } 680 681 public final Node replace (Hashtable subs, SubMethod sm) throws Throwable { 682 return replace (subs, sm, true); 683 } 684 685 public final Node replace (Hashtable subs, SubMethod sm, boolean recursive) throws Throwable { 686 687 if (noreplace) 688 return this; 689 690 if (recursive) 691 replace1 (subs, sm); 692 693 Node mn = sm.f (this); 694 Node hn = (Node) subs.get (this); 695 Node nn; 696 697 if (mn != null && hn != null && mn != hn) 698 throw new IllegalStateException ("subs and sm conflict for " + this + ": " + hn + " / " + mn); 699 else if (hn != null) 700 nn = hn; 701 else 702 nn = mn; 703 704 if (destinations != null && this != nn) { 705 loop: while (true) { 706 for (Iterator i = destinations.iterator(); i.hasNext(); ) { 707 Object o = i.next(); 708 Object so = subs.get (o); 709 710 720 721 Node.var vn = (Node.var) o; 722 if (this != nn) { 723 vn.producers.remove (this); 724 vn.producers.add (nn); 725 } 726 nn.addDestination (vn); 727 } 728 break loop; 729 } 730 731 if (destinations.size() == 0) 732 destinations = null; 733 } 734 735 return nn; 736 } 737 738 protected final void replace1 (Hashtable subs, SubMethod sm) throws Throwable { 739 740 for (int i = 0; i < requires.size(); i++) 741 requires.setElementAt (usesAt (i).replace (subs, sm, false), i); 742 } 743 744 746 747 public void codegen1 (Snippit out) { 748 749 throw new IllegalStateException 750 ("use of abstract codegen1 by class " + getClass().getName()); 751 } 752 753 757 758 759 public static class assign extends Node { 760 public boolean idempotent () { return false; } 761 public boolean hasSideEffect () { return true; } 762 763 public Node val; static { jbet.cmd.property.makeProperty("val"); } 764 public Node get__val() { return (Node) usesAt(0); } 765 public void set__val(Node n) { requires.setElementAt(n, 0); } 766 767 public int numParams() { return 1; } 768 769 public Type paramType (int i) { 770 return val.type(); 771 } 772 773 int lvt; 774 775 public assign (int lo, Node v, BasicBlock b) { 776 requires.setSize(1); lvt = lo; val = v; sb=b; } 777 778 protected String toString1 (int flags) { return "&" + lvt + " = " + val; } 779 public boolean equals (Object io) { return io == this; } 780 public Type type() { return Type.VOID; } 781 } 782 783 784 public static class param extends Node { 785 int v; 786 Type t; 787 public param (int n, Type tt) { 788 v = n; t = tt; 789 esneed = false; 790 } 791 792 protected String toString1 (int flags) { 793 if (flags == TOSTR_SRC) 794 return "p" + v; 795 else 796 return "&" + v; 797 } 798 803 public Type type() { 804 return t; 805 } 806 public boolean equals (Object io) { 807 return io instanceof param && 808 ((param)io).v == v && ((param)io).t.equals(t) && 809 sb==((Node)io).sb; 810 } 811 public int hashCode() { return v * 33; } 812 } 813 814 static class LoadMarker extends Node { 815 Node n; 816 LoadMarker(Node nn) { n = nn; } 817 public String toString1 (int flags) { return "LOADMARKER " + n; }; 818 public boolean isFake() { return true; } 819 } 820 821 static class DupMarker extends Node { 822 DupMarker() {} 823 public String toString1 (int flags) { return "DUPMARKER"; } 824 public boolean isFake() { return true; } 825 } 826 827 828 static class other extends Node { 829 Object o; 830 Type t; 831 832 other (Object io, Type it) { 833 o = io; t = it; 834 } 835 836 public Type type() { 837 if (t == null) 838 throw new IllegalStateException ("no type specified for " + o.toString()); 839 return t; 840 } 841 842 protected String toString1 (int flags) { return o.toString(); } 843 844 public boolean equals (Object io) { 845 if (io instanceof other) { 846 other oo = (other) io; 847 return 848 (t == null && oo.t == null && o.equals (oo.o)) || 849 (t != null && oo.t != null && o.equals (oo.o) && t.equals (oo.t)); 850 } 851 return false; 852 } 853 } 854 855 public static class marker extends Node 856 { 857 String message; 858 859 public marker (String msg) { message = msg; } 860 861 public boolean hasSideEffect () { return true; } 862 public boolean idempotent () { return false; } 863 864 protected String toString1 (int flags) { return message; } 865 public void codegen1 (Snippit out) { } 866 public Type type () { return Type.VOID; } 867 public boolean equals (Object io) { return (io == this); } 868 public boolean isFake() { return true;} 869 } 870 871 872 public static class var extends Node 873 { 874 875 var split(BasicBlock b) { 876 var ret = new var(v, t); 877 ret.name = name; 878 ret.producers = new HashSet(producers); 879 if (destinations != null) 880 ret.destinations = new HashSet(destinations); 881 ret.outlvt = outlvt; 882 if (exobject) throw new IllegalStateException 883 ("exobjects can not safely be split"); 884 for (Iterator i = producers.iterator(); i.hasNext();) { 885 Node p = (Node) i.next(); 886 p.destinations.add(ret); 887 } 888 ret.sb = b; 889 return ret; 890 } 891 892 public String name; 893 public int v; 896 public Type t; 897 public HashSet producers; 899 public int outlvt; 900 public boolean leftover; 901 public boolean exobject; 902 903 public var (int _v, Type _t) { 904 v = _v; t = _t; producers = new HashSet(); 905 outlvt = -1; leftover = exobject = false; 906 } 907 908 protected String toString1 (int flags) { 909 910 if (flags == TOSTR_DFL || flags == TOSTR_EXTRA) { 911 String out = sb != null ? ("&" + sb.swval + ":" + v) : ("&?:" + v); 912 if (producers.size() == 1 && 913 producers.iterator().next() instanceof Node.New) 914 out += "/N" + ((Node.New)producers.iterator().next()).serial; 915 916 if (flags == TOSTR_EXTRA) { 917 if (exobject) 918 out += "/E"; 919 if (outlvt >= 0) 920 out += "!" + outlvt; 921 if (name != null) 922 out += "{" + name + "}"; 923 927 if (producers.size() == 0 && !exobject) 928 out += "_BUG"; 929 } 930 return out; 931 } else { 932 if (name == null) { 933 if (v >= 0) 934 name = "b" + sb.swval + "v" + v; 935 else 936 name = "b" + sb.swval + "s" + (-v); 937 } 938 return name; 939 } 940 } 941 942 public void addname(String s) { 943 if (name == null) { 944 name = s; 945 } else if (! name.equals(s)) 946 throw new IllegalStateException ("2 diffirent names for a var"); 947 } 948 949 950 public boolean equals (Object io) { return (io == this); } 951 952 public void codegen1 (Snippit out) { 953 if (outlvt >= 0) { 954 out.push (new Instruction().setLoad (t, outlvt)); 955 } 956 else { 957 throw new IllegalStateException ("load from unallocated var " + toString()); 958 } 959 } 960 961 public Type type() { return t; } 962 963 public void findinputs (int[] inputs) { 964 if (outlvt >= 0) { 965 inputs[outlvt]++; 966 } 967 } 968 } 970 public static Node Constant (Object val) { 971 if (val instanceof String ) 972 return new Node.cString ((String ) val); 973 else if (val instanceof Integer ) 974 return new Node.cint (((Integer )val).intValue()); 975 else if (val instanceof Long ) 976 return new Node.clong (((Long )val).longValue()); 977 else if (val instanceof Float ) 978 return new Node.cfloat (((Float )val).floatValue()); 979 else if (val instanceof Double ) 980 return new Node.cdouble (((Double )val).doubleValue()); 981 else 982 throw new IllegalStateException ("no constant type for " + val); 983 } 984 985 public abstract static class constant extends Node 986 { 987 abstract public Object value(); 988 } 989 990 991 992 public static class cint extends constant 993 { 994 public int i; 995 996 public cint (int c) { i = c; } 997 998 protected String toString1 (int flags) { return "" + i; } 999 public boolean equals (Object io) { 1000 return io instanceof cint && ((cint)io).i == i && sb==((Node)io).sb && 1001 toString().equals (io.toString()); 1002 } 1003 public int hashCode() { return i; }; 1004 1005 public void codegen1 (Snippit out) { 1006 out.push (new Instruction().setIpush ((int)i)); 1007 } 1008 public Type type() { return Type.INT; } 1009 1010 public static final cint ONE = new cint (1); 1011 public static final cint ZERO = new cint (0); 1012 public static final cint TWO = new cint (2); 1013 1014 public static cint[] NewX (int[] a) 1015 { 1016 cint[] n = new cint[a.length]; 1017 for (int i = 0; i < a.length; i++) 1018 n[i] = new cint (a[i]); 1019 return n; 1020 } 1021 1022 public Object value() { return new Integer (i); } 1023 } 1024 1025 public static class ret extends Node 1026 { 1027 BasicBlock block; 1028 1029 ret (BasicBlock b) { block = b; } 1030 1031 protected String toString1 (int flags) { return "R" ; } 1032 public boolean equals (Object io) { 1033 return io instanceof ret && 1034 ((ret)io).block == block && sb==((Node)io).sb; 1035 } 1036 public int hashCode() { 1037 return 3; 1038 } 1039 public void codegen1 (Snippit out) { 1040 ; } 1042 public Type type() { return Type.RETADDR; } 1043 } 1044 1045 1046 1047 public static class clong extends constant 1048 { 1049 public long i; 1050 1051 public clong (long c) { i = c; } 1052 1053 protected String toString1 (int flags) { return "" + i + "L"; } 1054 public boolean equals (Object io) { 1055 return io instanceof clong && ((clong)io).i == i && sb==((Node)io).sb; 1056 } 1057 public int hashCode() { return (int) i; } 1058 public void codegen1 (Snippit out) { 1059 out.push (new Instruction().setLpush (i)); 1060 } 1061 public Type type() { return Type.LONG; } 1062 1063 public static final clong ONE = new clong (1); 1064 public static final clong ZERO = new clong (0); 1065 1066 public Object value() { return new Long (i); } 1067 } 1068 1069 1070 1071 public static class cfloat extends constant 1072 { 1073 public double f; 1074 1075 public cfloat (double c) { f = c; } 1076 1077 protected String toString1 (int flags) { return "" + f + "f"; } 1078 public boolean equals (Object io) { 1079 if ( !(io instanceof cfloat) ) return false; 1080 cfloat i = (cfloat) io; 1081 if (i.sb != sb) return false; 1082 if (Double.isNaN(f) && Double.isNaN(i.f)) return true; 1083 return i.f == f; 1084 } 1086 public int hashCode() { 1087 return (int)f; 1088 } 1089 public void codegen1 (Snippit out) { 1090 out.push (new Instruction().setFpush (f)); 1091 } 1092 public Type type() { return Type.FLOAT; } 1093 1094 public Object value() { return new Float (f); } 1095 } 1096 1097 1098 1099 public static class cdouble extends constant 1100 { 1101 public double d; 1102 1103 public cdouble (double c) { d = c; } 1104 1105 protected String toString1 (int flags) { return "" + d + "d"; } 1106 public boolean equals (Object io) { 1107 if ( !(io instanceof cdouble) ) return false; 1108 cdouble i = (cdouble) io; 1109 if (i.sb != sb) return false; 1110 if (Double.isNaN(d) && Double.isNaN(i.d)) return true; 1111 if (d==0) return Double.doubleToLongBits(d)== 1112 Double.doubleToLongBits(i.d); 1113 return i.d == d; 1114 } 1115 public int hashCode() { return (int) d; } 1116 public void codegen1 (Snippit out) { 1117 out.push (new Instruction().setDpush (d)); 1118 } 1119 public Type type() { return Type.DOUBLE; } 1120 1121 public Object value() { return new Double (d); } 1122 } 1123 1124 1125 1126 public static class cString extends constant 1127 { 1128 public String s; 1129 1130 public cString (String sin) { s = sin; } 1131 1132 protected String toString1 (int flags) { 1133 1134 1135 if (s.length() > 100) { 1136 return "<" + s.length() + " chars>"; 1137 } else { 1138 return "\"" + s + "\""; 1139 } 1140 } 1141 public boolean equals (Object io) { 1142 return (io instanceof cString) && 1143 ((cString)io).s.equals (s); 1144 } 1145 public int hashCode() { 1146 return s.hashCode(); 1147 } 1148 1149 public void codegen1 (Snippit out) { out.push (new Instruction().setSpush (s)); } 1150 public Type type() { return Type.STRING; } 1151 1152 public Object value() { return s; } 1153 } 1154 1155 1156 1157 public static class cnull extends constant 1158 { 1159 public cnull () {} 1160 protected String toString1 (int flags) { return "null"; } 1161 public boolean equals (Object io) { 1162 return (io instanceof cnull) && ((cnull)io).sb==sb; 1163 } 1164 public int hashCode() { return 33; } 1165 public void codegen1 (Snippit out) { out.push (new Instruction().setAconst_Null()); } 1166 public Type type() { return Type.NULL; } 1167 1168 public Object value() { return null; } 1169 } 1170 1171 1172 1173 public static class New extends Node 1174 { 1175 static int newcount = 0; 1176 1177 public String cname; public Type t; int serial; 1181 public New (String cn) { cname = cn; t = new Type ('l', 0, cname); clocal = -1; count = 1; serial = ++newcount; } 1182 protected String toString1 (int flags) { 1183 if (0 != (flags & TOSTR_SRC)) 1184 return "n" + serial; 1185 else 1186 return "&N" + serial; 1187 } 1188 public boolean equals (Object io) { return io == this; } 1189 public boolean idempotent() { return false; } 1190 1191 public void codegen1 (Snippit out) { 1192 out.push (new Instruction().setNew (cname)); 1193 } 1194 1195 public Type type() { return t; } 1196 } 1197 1198 1199 1200 public static class getfield extends Node 1201 { 1202 public boolean isstatic; 1203 public String cname; 1204 public String field; 1205 public Type t; 1206 public Node obj; public int ver; 1208 1209 public getfield (String c, String f, Type _t, Node o) { 1210 isstatic = (o==null); 1211 requires.setSize(numParams()); 1212 cname = c; field = f; 1213 t = _t; 1214 if (!isstatic) obj = o; 1215 count = 1; clocal = -1; 1216 ver = -1; 1217 } 1218 1219 static { jbet.cmd.property.makeProperty("obj"); } 1220 public Node get__obj() { return isstatic ? null : (Node) usesAt(0); } 1221 public void set__obj(Node n) { requires.setElementAt(n, 0); } 1222 1223 public int numParams() { return isstatic ? 0 : 1; }; 1224 1225 public Type paramType (int i) { 1226 if (isstatic) 1227 throw new IllegalStateException ("getstatic has no params"); 1228 1229 return new Type ('L', 0, cname); 1230 } 1231 1232 protected String toString1 (int flags) { 1233 StringBuffer r = new StringBuffer (); 1234 r.append (obj != null ? obj.toString (flags) : ((flags & TOSTR_SRC) != 0 ? Util.srcClassName (cname) : cname)); 1235 r.append ('.'); 1236 r.append (field); 1237 1238 1248 1249 return r.toString(); 1250 } 1251 1252 public boolean equals (Object io) { 1253 if (this != null) 1254 return io == this; 1255 1256 1258 if (sb != null && io instanceof getfield) { 1259 getfield o = (getfield) io; 1260 1261 if (ver == -1 || o.ver == -1) 1262 return false; 1263 if (sb != o.sb) 1264 return false; 1265 if (obj != null && o.obj == null) 1266 return false; 1267 if (obj == null && o.obj != null) 1268 return false; 1269 1270 if (obj == null) 1271 return o.cname.equals (cname) && o.field.equals (field) && ver == o.ver; 1272 else 1273 return o.cname.equals (cname) && o.field.equals (field) && obj.equals (o.obj) && ver == o.ver; 1274 } 1275 1276 return false; 1277 } 1278 public int hashCode() { 1279 return 3*cname.hashCode() + 2*field.hashCode() + 5*ver; 1280 } 1281 1282 public Type type() { return t; } 1283 1284 public boolean idempotent() { return false; } 1285 public void codegen1 (Snippit out) { 1286 if (obj != null) { 1287 out.push (new Instruction().setGetfield (cname, field, t)); 1288 } else { 1289 out.push (new Instruction().setGetstatic (cname, field, t)); 1290 } 1291 } 1292 1293 public void findinputs (int[] mk) { 1294 if (obj != null) 1295 obj.findinputs (mk); 1296 } 1297 } 1298 1299 1300 1301 public static class setfield extends Node 1302 { 1303 public Node val; public String cname; 1305 public String field; 1306 public Type t; 1307 public Node obj; public int ver; public boolean isstatic; 1310 1311 public boolean hasSideEffect() { return true; } 1312 1313 public setfield (String c, String f, Type _t, Node o, Node v) { 1314 isstatic = (o == null); 1315 requires.setSize(numParams()); 1316 val = v; 1317 if (!isstatic) obj = o; 1318 cname = c; field = f; t = _t; 1319 count = 1; 1320 clocal = -1; 1321 ver = -1; 1322 } 1323 1324 static { jbet.cmd.property.makeProperty("obj"); } 1325 public Node get__obj() { return isstatic ? null : (Node) usesAt(0); } 1326 public void set__obj(Node n) { requires.setElementAt(n, 0); } 1327 static { jbet.cmd.property.makeProperty("val"); } 1328 public Node get__val() { return (Node) usesAt(isstatic ? 0 : 1); } 1329 public void set__val(Node n) { requires.setElementAt(n, isstatic ? 0 : 1); } 1330 1331 public int numParams() { return isstatic ? 1 : 2; }; 1332 1333 public Type paramType (int i) { 1334 if (i == 0) { 1335 if (isstatic) 1336 return t; 1337 else 1338 return new Type ('L', 0, cname); 1339 } 1340 else if (i == 2) { 1341 if (isstatic) 1342 throw new IllegalStateException ("setstatic has only 1 param"); 1343 else 1344 return t; 1345 } 1346 else 1347 throw new IllegalStateException ("setfield has 1 or 2 params"); 1348 } 1349 1350 protected String toString1 (int flags) { 1351 StringBuffer r = new StringBuffer ("("); 1352 r.append (obj != null ? obj.toString (flags) : ((flags & TOSTR_SRC) != 0 ? Util.srcClassName (cname) : cname)); 1353 r.append (")."); 1354 r.append (field); 1355 1356 if (flags == TOSTR_DFL || flags == TOSTR_EXTRA) { 1357 if (ver >= 0) { 1358 r.append ("__"); 1359 r.append (ver); 1360 } 1361 if (clocal >= 0) { 1362 r.append ('!'); 1363 r.append (clocal); 1364 } 1365 } 1366 if (clocal >= 0) { 1367 r.append ('!'); 1368 r.append (clocal); 1369 } 1370 1371 r.append (" = "); 1372 r.append (val.toString(flags)); 1373 1374 return r.toString(); 1375 } 1376 1377 public boolean equals (Object io) { return io == this; } 1378 1379 public Type type() { return Type.VOID; } 1380 1381 public boolean idempotent() { return false; } 1382 1383 public void codegen1 (Snippit out) { 1384 if (obj != null) { 1385 out.push (new Instruction().setPutfield (cname, field, t)); 1386 } else { 1387 out.push (new Instruction().setPutstatic (cname, field, t)); 1388 } 1389 } 1390 1391 public void findinputs (int[] mk) { 1392 val.findinputs (mk); 1393 if (obj != null) 1394 obj.findinputs (mk); 1395 } 1396 1397 } 1398 1399 1400 1401 public static class NewArray extends Node { 1402 1403 public boolean hasSideEffect() { return true; } 1404 1405 public int numParams() { return 1; }; 1406 public Type paramType (int i) { return Type.INT; } 1407 1408 public Node size; public Type t; 1410 1411 static { jbet.cmd.property.makeProperty("size"); } 1412 public Node get__size() { return (Node) usesAt(0); } 1413 public void set__size(Node n) { requires.setElementAt(n, 0); } 1414 1415 1416 public NewArray (Node s, Type arrayType) { requires.setSize (1); size = s; t = arrayType; clocal = -1; count = 1; } 1417 public NewArray (Node s, int nat) { 1418 requires.setSize(1); 1419 size = s; t = Type.newarray (nat); clocal = -1; count = 1; 1420 } 1421 public NewArray (Node s, String cname) { 1422 requires.setSize(1); 1423 size = s; t = new Type ('L', 1, cname); clocal = -1; count = 1; 1424 } 1425 1426 public NewArray (Node s, Object aValue) { 1427 requires.setSize(1); 1428 t = new Type (aValue); 1429 t.arraydepth++; 1430 size = s; 1431 clocal = -1; 1432 count = 1; 1433 } 1434 1435 protected String toString1 (int flags) { 1436 if ((flags & TOSTR_SRC) != 0) 1437 return "new " + t.popbracket().declaration() + " [" + size.toString (flags) + ']'; 1438 else 1439 return "new-" + t.popbracket() + "[" + size.toString (flags) + "]"; 1440 } 1441 1442 public boolean equals (Object io) { return io == this; } 1443 public boolean idempotent() { return false; } 1444 1445 public void codegen1 (Snippit out) { 1446 out.push (new Instruction().setNewArray (t)); 1448 } 1449 1450 public Type type() { return t; } 1451 1452 public void findinputs (int[] mk) { 1453 size.findinputs (mk); 1454 } 1455 1456 } 1457 1458 1459 1460 public static class MultiNewArray extends Node 1461 { 1462 public int n; 1463 public Type t; 1464 1465 public boolean hasSideEffect() { return true; } 1466 public int numParams() { return n; }; 1467 1468 public Type paramType (int i) { return Type.INT; } 1469 1470 public Node arg (int i) { return (Node)requires.elementAt (i); } 1471 public void setArg (int i, Node o) { requires.setElementAt (o, i); } 1472 1473 public MultiNewArray (Node[] s, Type arrayType) { 1474 n = s.length; 1475 requires.setSize (n); 1476 t = arrayType; 1477 clocal = -1; count = 1; 1478 for (int i = 0; i < n; i++) 1479 requires.setElementAt (s[i], i); 1480 } 1481 1482 public MultiNewArray (Node[] s, String arrayType) { 1483 n = s.length; 1484 requires.setSize (n); 1485 t = new Type (arrayType); 1486 clocal = -1; count = 1; 1487 for (int i = 0; i < n; i++) 1488 requires.setElementAt (s[i], i); 1489 } 1490 1491 public MultiNewArray (int nin, Vector args, Type arrayType) { 1492 n = nin; 1493 requires.setSize (n); 1494 t = arrayType; 1495 clocal = -1; count = 1; 1496 for (int i = 0; i < n; i++) 1497 requires.setElementAt (args.elementAt (i), i); 1498 } 1499 1500 protected String toString1 (int flags) { 1501 StringBuffer out; 1502 1503 if ((flags & TOSTR_SRC) != 0) 1504 out = new StringBuffer ("new " + t.popbrackets().declaration() + " "); 1505 else 1506 out = new StringBuffer ("(newx-" + t.popbrackets()); 1507 1508 for (int i = 0; i < n; i++) { 1509 out.append ('['); 1510 out.append (arg (i).toString (flags)); 1511 out.append (']'); 1512 } 1513 if (!((flags & TOSTR_SRC) != 0)) 1514 out.append (')'); 1515 1516 return out.toString(); 1517 } 1518 1519 public boolean equals (Object io) { return io == this; } 1520 public boolean idempotent() { return false; } 1521 1522 public void codegen1 (Snippit out) { 1523 out.push (new Instruction().setMultiaNewArray (t.toClassRef(), n)); 1524 } 1525 1526 public Type type() { return t; } 1527 1528 public void findinputs (int[] mk) { 1529 for (int i = 0; i < n; i++) 1530 arg(i).findinputs (mk); 1531 } 1532 } 1533 1534 1535 1536 public static class aload extends Node 1537 { 1538 public boolean hasSideEffect() { return true; } 1539 1540 public int numParams() { return 2; }; 1541 1542 public Type paramType (int i) { 1543 switch (i) { 1544 case 0: return array.type(); 1545 case 1: return Type.INT; 1546 default: throw new IllegalStateException ("aload has 2 params"); 1547 } 1548 } 1549 1550 public Node array; static{ jbet.cmd.property.makeProperty("array"); } 1551 public Node get__array() { return (Node) usesAt(0); } 1552 public void set__array(Node n) { requires.setElementAt(n, 0); } 1553 public Node index; static{ jbet.cmd.property.makeProperty("index"); } 1554 public Node get__index() { return (Node) usesAt(1); } 1555 public void set__index(Node n) { requires.setElementAt(n, 1); } 1556 1557 public aload (Node a, Node i) { 1558 requires.setSize(2); 1559 array = a; index = i; count = 1; clocal = -1; 1560 } 1561 protected String toString1 (int flags) { 1562 return array.toString(flags) + '[' + index.toString (flags) + ']'; 1563 } 1564 public boolean equals (Object io) { return io == this; } 1565 public Type type() { return array.type().popbracket(); } 1566 public boolean idempotent() { return false; } 1567 1568 public void codegen1 (Snippit out) { 1569 out.push (new Instruction().setArrayLoad (array.type())); 1570 } 1571 1572 public void findinputs (int[] mk) { 1573 array.findinputs (mk); 1574 index.findinputs (mk); 1575 } 1576 1577 } 1578 1579 1580 1581 public static class astore extends Node 1582 { 1583 public boolean hasSideEffect() { return true; } 1584 public int numParams() { return 3; }; 1585 1586 public Type paramType (int i) { 1587 switch (i) { 1588 case 0: return array.type(); 1589 case 1: return Type.INT; 1590 case 2: return array.type().popbracket(); 1591 default: throw new IllegalStateException ("astore has 3 params"); 1592 } 1593 } 1594 1595 public Node array; static{ jbet.cmd.property.makeProperty("array"); } 1596 public Node get__array() { return (Node) usesAt(0); } 1597 public void set__array(Node n) { 1598 requires.setElementAt(n, 0); 1599 if (n.type().arraydepth == 0) throw new IllegalStateException 1600 ("non-array used with astore"); 1601 } 1602 public Node index; static{ jbet.cmd.property.makeProperty("index"); } 1603 public Node get__index() { return (Node) usesAt(1); } 1604 public void set__index(Node n) { requires.setElementAt(n, 1); } 1605 public Node val; static{ jbet.cmd.property.makeProperty("val"); } 1606 public Node get__val() { return (Node) usesAt(2); } 1607 public void set__val(Node n) { requires.setElementAt(n, 2); } 1608 1609 1610 public astore (Node a, Node i, Node v) { 1611 requires.setSize(3); 1612 1613 array = a; index = i; val = v; count = 1; clocal = -1; 1614 } 1615 protected String toString1 (int flags) { 1616 return array.toString(flags) + "[" + index.toString (flags) + "] = " + val.toString (flags); 1617 } 1618 public boolean equals (Object io) { return io == this; } 1619 public Type type() { return Type.VOID; } 1620 public boolean idempotent() { return false; } 1621 1622 public void codegen1 (Snippit out) { 1623 out.push (new Instruction().setArrayStore (array.type())); 1624 } 1625 1626 public void findinputs (int[] mk) { 1627 array.findinputs (mk); 1628 index.findinputs (mk); 1629 val.findinputs (mk); 1630 } 1631 } 1632 1633 1634 1635 public static class N2 extends Node 1636 { 1637 public int numParams() { return 2; } 1638 1639 public Type paramType (int i) { 1640 if (i > 2) 1641 throw new IllegalStateException ("N2 has only 2 params"); 1642 return op2ptype[ (op-201) * 2 + i]; 1643 } 1644 1645 public Node a; static{ jbet.cmd.property.makeProperty("a"); } 1646 public Node get__a() { return (Node) usesAt(0); } 1647 public void set__a(Node n) { requires.setElementAt(n, 0); } 1648 public Node b; static{ jbet.cmd.property.makeProperty("b"); } 1649 public Node get__b() { return (Node) usesAt(1); } 1650 public void set__b(Node n) { requires.setElementAt(n, 1); } 1651 1652 1653 public N2 (int _op, Node _a, Node _b) { 1654 requires.setSize(2); 1655 op = _op; a = _a; b = _b; 1656 } 1657 1658 protected String toString1 (int flags) { 1659 return "(" + a.toString (flags) + " " + 1660 op2char.substring (op-201, op-200) + " " + 1661 b.toString (flags) + ")"; } 1662 1663 public boolean equals (Object o) { 1664 return o == this || 1665 (o instanceof N2 && 1666 op == ((N2)o).op && 1667 a.equals (((N2)o).a) && 1668 b.equals (((N2)o).b) && sb==((Node)o).sb); 1669 } 1670 public int hashCode() { 1671 return op * 11 + 13*a.hashCode() + 17*b.hashCode(); 1672 } 1673 1674 public void findinputs (int[] mk) { a.findinputs (mk); b.findinputs (mk); } 1675 public void codegen1 (Snippit out) { 1676 Instruction ins = new Instruction().setNop(); 1679 ins.setOpCode (op2jvm[op-201]); 1680 out.push (ins); 1681 } 1682 public Type type() { return op2type[op-201]; } 1683 1684 } 1685 1686 1687 1688 public static class N1 extends Node 1689 { 1690 public Node in; static{ jbet.cmd.property.makeProperty("in"); } 1692 public Node get__in() { return (Node) usesAt(0); } 1693 public void set__in(Node n) { requires.setElementAt(n, 0); } 1694 1695 public int numParams() { return 1; } 1696 1697 public Type paramType (int i) { 1698 if (i != 0) 1699 throw new IllegalStateException ("N1 has only 1 param"); 1700 return op1ptype[ op-101]; 1701 } 1702 1703 public N1 (int _op, Node _a) { requires.setSize(1); op = _op; in = _a; } 1704 protected String toString1 (int flags) { return "(" + op1char.substring (op-101, op-100) + " " + in.toString (flags) + ")"; } 1705 1706 public boolean equals (Object o) { 1707 return o == this || 1708 (o instanceof N1 && 1709 op == ((N1)o).op && 1710 in.equals (((N1)o).in) && 1711 sb==((Node)o).sb); 1712 } 1713 public int hashCode() { 1714 return op * 11 + 17*in.hashCode(); 1715 } 1716 1717 public void findinputs (int[] mk) { in.findinputs (mk); } 1718 public void codegen1 (Snippit out) { 1719 Instruction ins = new Instruction().setNop(); 1721 ins.setOpCode (op1jvm[op-101]); 1722 out.push (ins); 1723 } 1724 public Type type() { return op1type[op-101]; } 1725 1726 } 1727 1728 1730 1731 public static class invokev extends Node 1732 { 1733 public boolean hasSideEffect() { return true; } 1734 public MethodSignature method; 1735 public int op; 1736 1737 public int numParams() { return 1 + method.descriptor.args.length; } 1738 1739 public Type paramType (int i) { 1740 if (i == 0) 1741 return new Type ('L', 0, method.classrep().toString ()); 1742 else 1743 return method.descriptor.args[i-1]; 1744 } 1745 1746 public Node This; static{ jbet.cmd.property.makeProperty("This"); } 1747 public Node get__This() { return (Node) usesAt(0); } 1748 public void set__This(Node n) { requires.setElementAt(n, 0); } 1749 1750 public Node arg(int i) { return (Node) requires.elementAt(i+1); } 1751 Node setArg(int i, Node n) { 1752 requires.setElementAt(n, i+1); 1753 return n; 1754 } 1755 public int argslen() { return numParams() - 1; }; 1756 1757 public boolean isinit() { 1758 return op == Instruction.AOP_INVOKEINIT; 1759 } 1760 1761 static int curr_serial = 0; 1762 int serial; 1763 1764 protected invokev () { } 1765 1766 public invokev (MethodSignature mi, Node _this, Vector _args) { 1767 serial = curr_serial++; 1768 method = mi; 1769 requires.setSize( numParams() ); 1770 count = 1; 1771 clocal = -1; 1772 op = Instruction.OP_INVOKEVIRTUAL; 1773 This = _this; 1774 for (int i = 0 ; i < _args.size(); i++) 1775 setArg(i, (Node) _args.elementAt(i)); 1776 } 1777 1778 public invokev (MethodSignature mi, Node _this, Node[] _args) { 1779 method = mi; 1780 requires.setSize( numParams() ); 1781 This = _this; 1782 count = 1; 1783 clocal = -1; 1784 op = Instruction.OP_INVOKEVIRTUAL; 1785 for (int i = 0 ; i < _args.length; i++) 1786 setArg(i, _args[i]); 1787 } 1788 1789 public invokev (MethodSignature mi, Node _this, Node[] _args, int _op) { 1790 method = mi; 1791 requires.setSize( numParams() ); 1792 This = _this; 1793 count = 1; 1794 clocal = -1; 1795 op = _op; 1796 for (int i = 0 ; i < _args.length; i++) 1797 setArg(i, _args[i]); 1798 } 1799 1800 public invokev (MethodSignature mi, Node _this, Vector _args, int _op) { 1801 serial = curr_serial++; 1802 method = mi; 1803 requires.setSize( numParams() ); 1804 This = _this; 1805 count = 1; 1806 clocal = -1; 1807 op = _op; 1808 for (int i = 0 ; i < _args.size(); i++) 1809 setArg(i, (Node) _args.elementAt(i)); 1810 } 1811 1812 public invokev (MethodSignature mi, Node _this, Node _arg0, int _op) { 1813 method = mi; 1814 requires.setSize( numParams() ); 1815 This = _this; 1816 count = 1; 1817 clocal = -1; 1818 op = _op; 1819 setArg (0, _arg0); 1820 } 1821 1822 protected String dot () { return "."; } 1823 1824 protected String toString1(int flags) 1825 { 1826 StringBuffer argstr = new StringBuffer (); 1827 1828 for (int i = 0; i < argslen(); i++) { 1829 argstr.append (arg(i).toString (flags)); 1830 if (i != argslen() - 1) 1831 argstr.append (","); 1832 } 1833 1834 switch (op) { 1835 case Instruction.OP_INVOKESPECIAL: 1836 case Instruction.AOP_INVOKEINIT: 1837 if (method.name.equals ("<init>") && This instanceof Node.New) { 1838 1839 if ((flags & TOSTR_SRC) != 0) 1840 return "new " + Util.srcClassName (method.classrep().toString()) + " (" + argstr + ')'; 1841 else 1842 return This.toString (flags) + " = new " + method.classrep().toString() + "(" + argstr + ")"; 1843 } 1844 { 1849 if ((flags & TOSTR_EXTRA) != 0) 1850 return "(" + This.toString (flags) + ")" + dot() + method.classrep().toString() + "::" + method.name + "(" + argstr + ")__" + serial; 1851 else 1852 return This.toString (flags) + dot() + method.classrep().toString() + "::" + method.name + "(" + argstr + ")"; 1853 } 1854 1855 case Instruction.OP_INVOKEVIRTUAL: 1856 case Instruction.OP_INVOKEINTERFACE: 1857 if ((flags & TOSTR_EXTRA) != 0) 1858 return "(" + This.toString (flags) + ")" + dot() + method.name + "(" + argstr + ")__" + serial; 1859 else 1860 return This.toString (flags) + dot() + method.name + "(" + argstr + ")"; 1861 } 1862 1863 throw new IllegalStateException ("invokev with bad op"); 1864 } 1865 1866 public boolean equals (Object _o) { return _o == this; } 1867 1868 1869 public boolean idempotent() { return false; } 1870 1871 public void findinputs (int[] mk) { 1872 This.findinputs (mk); 1873 1874 for (int i = 0; i < argslen(); i++) 1875 arg(i).findinputs (mk); 1876 } 1877 1878 public void codegen1 (Snippit out) { 1879 out.push (new Instruction().setInvoke 1880 (method.classrep().toString(), method.name, method.descriptor, 1881 isinit () ? Instruction.OP_INVOKESPECIAL : op)); 1882 } 1883 1884 public Type type() { 1885 return isinit() ? This.type().initialize() : method.descriptor.ret; 1886 } 1887 1888 public final MethodInfo method() throws ClassFileException, ElementNotFoundException { 1889 return method.resolve(); 1890 } 1891 } 1893 1894 public static class monitorop extends Node 1895 { 1896 public Node objref; static{ jbet.cmd.property.makeProperty("objref"); } 1897 public Node get__objref() { return (Node) usesAt(0); } 1898 public void set__objref(Node n) { requires.setElementAt(n, 0); } 1899 1900 public int numParams() { return 1; } 1901 1902 public Type paramType (int i) { 1903 return Type.OBJECT; 1904 } 1905 1906 monitorop(int _op, Node _objref) { 1907 requires.setSize(1); 1908 count = 1; 1909 clocal = -1; 1910 op = _op; 1911 objref = _objref; 1912 } 1913 1914 protected String toString1 (int flags) 1915 { 1916 return objref + ".monitorenter()"; 1917 } 1918 1919 public boolean equals (Object _o) { return _o == this; } 1920 1921 public boolean idempotent() { return false; } 1922 1923 public void findinputs (int[] mk) { objref.findinputs (mk); } 1924 1925 public void codegen1 (Snippit out) { 1926 Instruction ins = new Instruction().setNop(); 1928 ins.setOpCode(op); 1929 out.push(ins); 1930 } 1931 1932 public Type type() { return Type.VOID; } 1933 1934 }; 1935 1936 1937 1938 public static class invokes extends Node 1939 { 1940 public MethodSignature method; 1941 1942 public int numParams() { return method.descriptor.args.length; } 1943 1944 public Type paramType (int i) { 1945 return method.descriptor.args[i]; 1946 } 1947 1948 public Node arg(int i) { return (Node) requires.elementAt(i); } 1949 Node setArg(int i, Node n) { 1950 requires.setElementAt(n, i); 1951 return n; 1952 } 1953 public int argslen() { return method.descriptor.args.length; } 1954 1955 public Node[] args() { 1956 Node[] a = new Node[argslen()]; 1957 for (int i = 0; i < a.length; i++) 1958 a[i] = arg(i); 1959 return a; 1960 } 1961 1962 static int curr_serial = 0; 1963 public int serial; 1964 1965 protected invokes () { } 1966 1967 public invokes (MethodSignature mi, Vector _args) { 1968 serial = curr_serial++; 1969 method = mi; 1970 requires.setSize( argslen() ); 1971 for (int i = 0 ; i < _args.size(); i++) 1972 setArg(i, (Node) _args.elementAt(i)); 1973 count = 1; 1974 clocal = -1; 1975 } 1976 1977 public invokes (MethodSignature _mi, Node[] _args) { 1978 serial = curr_serial++; 1979 method = _mi; 1980 requires.setSize( argslen() ); 1981 for (int i = 0 ; i < _args.length; i++) 1982 setArg(i, _args[i]); 1983 count = 1; 1984 clocal = -1; 1985 } 1986 1987 public invokes (MethodSignature _mi, Node _arg0) { 1988 serial = curr_serial++; 1989 method = _mi; 1990 requires.setSize( argslen() ); 1991 setArg(0, _arg0); 1992 count = 1; 1993 clocal = -1; 1994 } 1995 1996 public invokes (MethodSignature _mi, Node _arg0, Node _arg1) { 1997 serial = curr_serial++; 1998 method = _mi; 1999 requires.setSize( argslen() ); 2000 setArg(0, _arg0); 2001 setArg(1, _arg1); 2002 count = 1; 2003 clocal = -1; 2004 } 2005 2006 public invokes (MethodSignature _mi, Node _arg0, Node _arg1, Node _arg2) { 2007 serial = curr_serial++; 2008 method = _mi; 2009 requires.setSize( argslen() ); 2010 setArg(0, _arg0); 2011 setArg(1, _arg1); 2012 setArg(2, _arg2); 2013 count = 1; 2014 clocal = -1; 2015 } 2016 2017 protected String dot () { return "."; } 2018 2019 protected String toString1 (int flags) 2020 { 2021 StringBuffer argstr = new StringBuffer (); 2022 2023 for (int i = 0; i < argslen(); i++) { 2024 argstr.append (arg(i).toString (flags)); 2025 if (i != argslen() - 1) 2026 argstr.append (","); 2027 } 2028 2029 if ((flags & TOSTR_EXTRA) != 0) 2030 return method.classrep().toString() + dot() + method.name + "(" + argstr + ")" + "__" + serial; 2031 else 2032 return method.classrep().toString() + dot() + method.name + "(" + argstr + ")"; 2033 } 2034 2035 public boolean equals (Object _o) { return _o == this; } 2036 2037 public boolean idempotent() { return false; } 2038 2039 public void findinputs (int[] mk) { 2040 for (int i = 0; i < argslen(); i++) 2041 arg(i).findinputs (mk); 2042 } 2043 2044 public void codegen1 (Snippit out) { 2045 2046 out.push (new Instruction().setInvokeStatic 2047 (method.classrep().toString(), method.name, 2048 method.descriptor)); 2049 } 2050 2051 public Type type() { return method.descriptor.ret; } 2052 2053 public final MethodInfo method() throws ClassFileException, ElementNotFoundException { 2054 return method.resolve(); 2055 } 2056 } 2058 2063 2064 public static class invokeinit extends invokes 2065 { 2066 Type thist; 2067 2068 public invokeinit (MethodSignature mi, Node[] _args) { 2069 if (!mi.name.equals ("<init>")) 2070 throw new IllegalStateException ("improper use of Node.invokeinit"); 2071 Type t = new Type ('L', 0, mi.classrep().toString()); 2072 thist = t; 2073 2074 method = mi; 2075 requires.setSize( numParams() ); 2076 count = 1; 2077 clocal = -1; 2078 2079 if (argslen() != _args.length) 2080 throw new IllegalStateException ("incorrect number of arguments"); 2081 2082 for (int i = 0 ; i < _args.length; i++) 2083 setArg(i, _args[i]); 2084 } 2085 2086 public invokeinit (MethodSignature mi, Node _arg0) { 2087 if (!mi.name.equals ("<init>")) 2088 throw new IllegalStateException ("improper use of Node.invokeinit"); 2089 Type t = new Type ('L', 0, mi.classrep().toString()); 2090 thist = t; 2091 2092 method = mi; 2093 requires.setSize( numParams() ); 2094 count = 1; 2095 clocal = -1; 2096 setArg (0, _arg0); 2097 } 2098 2099 public Type type() { return thist; } 2100 2101 public void allnodes (Collection v, boolean doRequires) { 2102 v.add (this); 2103 2104 if (doRequires) 2105 for (Iterator i = requires.iterator(); i.hasNext(); ) 2106 ((Node)i.next()).allnodes (v, doRequires); 2107 else 2108 for (int i = 1; i < numParams(); i++) 2109 usesAt (i).allnodes (v, doRequires); 2110 } 2111 2112 public void codegen1 (Snippit out) { 2113 out.push (new Instruction().setNew (thist.toClassRef())); 2114 out.push (new Instruction().setDup()); 2115 out.moveDown (Type.LONG, method.descriptor.args); 2116 out.push (new Instruction().setInvokeSpecial 2117 (method.classrep().toString(), method.name, method.descriptor)); 2118 } 2119 } 2120 2121 2122 2123 public static class Cast extends Node 2124 { 2125 public Type t; 2126 public boolean checkcast; 2128 public int numParams() { return 1; } 2129 2130 public Type paramType (int i) { 2131 return val.type (); 2132 } 2133 2134 public Node val; static{ jbet.cmd.property.makeProperty("val"); } 2135 public Node get__val() { return (Node) usesAt(0); } 2136 public void set__val(Node n) { requires.setElementAt(n, 0); } 2137 2138 public Cast (String c, Node v, boolean cc) { 2139 requires.setSize(1); 2140 if (c.charAt (0) == '[') 2141 t = new Type (c); 2142 else 2143 t = new Type ('L', 0, c); 2144 val = v; checkcast = cc; 2145 } 2146 2147 public Cast (Type _t, Node v, boolean cc) { 2148 requires.setSize(1); 2149 t = _t; 2150 val = v; checkcast = cc; 2151 } 2152 2153 protected String toString1 (int flags) { 2154 String ts = ((flags & TOSTR_SRC) != 0) ? t.declaration() : t.toClassRef(); 2155 2156 if (checkcast) { 2157 return "((" + ts + ") " + val.toString (flags) + ')'; 2158 } else { 2159 return "(" + val.toString (flags) + " instanceof " + ts + ")"; 2160 } 2161 } 2162 2163 public boolean equals (Object io) { 2164 if (io instanceof Cast) { 2165 Cast o = (Cast) io; 2166 return val.equals (o.val) && t.equals (o.t) && 2167 checkcast == o.checkcast && sb==o.sb; 2168 } 2169 return false; 2170 } 2171 public int hashCode() { 2172 return 3*t.hashCode() + 2*val.hashCode(); 2173 } 2174 2175 public void codegen1 (Snippit out) { 2176 Instruction ins = new Instruction(); 2177 if (checkcast) { 2178 ins.setCheckcast (t); 2179 } else { 2180 ins.setInstanceof (t); 2181 } 2182 2183 out.push (ins); 2184 } 2185 2186 public Type type() { return checkcast ? t : Type.INT; } 2187 2188 public void findinputs (int[] mk) { 2189 val.findinputs (mk); 2190 } 2191 } 2192 2193 public static class Label extends Node 2194 { 2195 public int swval; 2196 public cint swvaln; 2198 public BasicBlock swvalb; 2199 public String name; 2200 public Instruction ip; 2201 2202 static int lastln = 0; 2203 2204 static { jbet.cmd.property.makeProperty("swval"); } 2205 2206 public int get__swval () { 2207 if (swvalb != null) 2208 return swvalb.swval; 2209 else 2210 return -1; 2211 } 2212 public void set__swval (int i) { 2213 throw new IllegalStateException ("attempt to assign to Node$Label.swval"); 2214 } 2215 2216 public int numParams() { return 0; } 2217 2218 public Label () { 2219 this ("L" + lastln); 2220 lastln++; 2221 } 2222 2223 public Label (String c) { 2224 requires.setSize (0); 2225 name = c; 2226 swvaln = new Node.cint(-1) { 2227 public boolean equals (Object io) { return io == this; } 2228 public String toString1 (int flags) { 2229 if (swval >= 0) 2230 return "#B" + swval + ':' + name; 2231 else 2232 return '#' + name; 2233 } 2234 }; 2235 } 2236 2237 public cint addr() { return swvaln; } 2238 2239 protected String toString1 (int flags) { 2240 if ((flags & TOSTR_SRC) != 0) 2241 return name + ':'; 2242 else if (swval >= 0) 2243 return "#B" + swval + " (" + name + "):"; 2244 else 2245 return "#B? (" + name + "):"; 2246 } 2247 2248 public boolean equals (Object io) { 2249 return io == this; 2250 } 2251 2252 public int hashCode() { 2253 return 37 * swval; 2254 } 2255 2256 public void codegen1 (Snippit out) { 2257 } 2258 2259 public Type type() { return Type.VOID; } 2260 2261 public void findinputs (int[] mk) { 2262 } 2263 2264 public boolean idempotent () { return false; } 2265 public boolean hasSideEffect () { return true; } 2266 } 2267 2268 public static class Goto extends Node 2269 { 2270 public int numparams; 2271 public Node dest; 2272 2273 static{ jbet.cmd.property.makeProperty("dest"); } 2274 2275 public Node get__dest() { return (Node) usesAt(0); } 2276 public void set__dest(Node n) { requires.setElementAt(n, 0); } 2277 2278 public int numParams() { return numparams; } 2279 2280 public Type paramType (int i) 2281 { 2282 if (i == 0) 2283 return Type.INT; 2284 else 2285 return ((Node)requires.elementAt (i)).type(); 2286 } 2287 2288 public Goto (Node n) { 2289 numparams = 1; 2290 requires.setSize (1); 2291 dest = n; 2292 } 2293 2294 public Goto (Node n, Node cs) { 2295 numparams = 2; 2296 requires.setSize (2); 2297 dest = n; 2298 requires.setElementAt (cs, 1); 2299 } 2300 2301 public Goto (Goto in) { 2302 numparams = in.numparams; 2303 requires.setSize (numparams); 2304 for (int i = 0; i < numparams; i++) 2305 requires.setElementAt (in.usesAt (i), i); 2306 } 2307 2308 protected String toString1 (int flags) { 2309 if (numparams == 1) 2310 return "goto " + dest.toString (flags); 2311 else { 2312 StringBuffer b = new StringBuffer ("goto "); 2313 2314 b.append (usesAt (0).toString (flags)); 2315 b.append (" ("); 2316 2317 for (int i = 1; i < numparams; i++) { 2318 b.append (usesAt (i).toString (flags)); 2319 if (i != numparams - 1) 2320 b.append (", "); 2321 } 2322 b.append (')'); 2323 return b.toString(); 2324 } 2325 } 2326 2327 public boolean equals (Object io) { 2328 return io == this; 2329 } 2330 2331 public int hashCode() { 2332 return 3 * dest.hashCode(); 2333 } 2334 2335 public void codegenpre (Snippit out, CodeGenerator cg) { 2336 throw new IllegalStateException ("codegen an abstract goto"); 2337 } 2338 2339 public void codegen2 (Snippit out, CodeGenerator cg) { 2340 throw new IllegalStateException ("codegen an abstract goto"); 2341 } 2342 2343 public Type type() { return Type.VOID; } 2344 2345 public void findinputs (int[] mk) { 2346 } 2347 2348 public boolean idempotent () { return false; } 2349 public boolean hasSideEffect () { return true; } 2350 } 2352 public static class invokevnoa extends Node.invokev 2353 { 2354 public invokevnoa (MethodSignature mi, Node _this, Vector _args) { 2355 super (mi, _this, _args); 2356 } 2357 2358 public invokevnoa (MethodSignature mi, Node _this, Node[] _args) { 2359 super (mi, _this, _args); 2360 } 2361 2362 public invokevnoa (MethodSignature mi, Node _this, Node[] _args, int _op) { 2363 super (mi, _this, _args, _op); 2364 } 2365 2366 public invokevnoa (MethodSignature mi, Node _this, Vector _args, int _op) { 2367 super (mi, _this, _args, _op); 2368 } 2369 2370 public invokevnoa (MethodSignature mi, Node _this, Node _arg0, int _op) { 2371 super (mi, _this, _arg0, _op); 2372 } 2373 2374 protected String dot () { return ".*"; } 2375 2376 public void codegen1 (Snippit out) { 2377 invokenoa.codegen (out, op, method); 2378 } 2379 } 2380 2381 public static class invokesnoa extends Node.invokes 2382 { 2383 public invokesnoa (MethodSignature mi, Vector _args) { 2384 super (mi, _args); 2385 } 2386 2387 public invokesnoa (MethodSignature _mi, Node[] _args) { 2388 super (_mi, _args); 2389 } 2390 2391 public invokesnoa (MethodSignature _mi, Node _arg0) { 2392 super (_mi, _arg0); 2393 } 2394 2395 public invokesnoa (MethodSignature _mi, Node _arg0, Node _arg1) { 2396 super (_mi, _arg0, _arg1); 2397 } 2398 2399 public invokesnoa (MethodSignature _mi, Node _arg0, Node _arg1, Node _arg2) { 2400 super (_mi, _arg0, _arg1, _arg2); 2401 } 2402 2403 protected String dot () { return ".*"; } 2404 2405 public void codegen1 (Snippit out) { 2406 invokenoa.codegen (out, Instruction.OP_INVOKESTATIC, method); 2407 } 2408 } 2409 2410 public static class invokenoa 2411 { 2412 public static void codegen (Snippit out, int op, MethodSignature mi) 2413 { 2414 Reflection.arguments2array (out, mi.descriptor); 2415 2416 out.push (new Instruction().setSpush (mi.classrep().toString().replace ('/','.'))); 2417 out.push (new Instruction().setInvokeStatic ("java/lang/Class", "forName", new Descriptor (Type.STRING, Type.CLASS))); 2418 2419 out.push (new Instruction().setSpush (mi.name)); 2420 2421 Reflection.descriptor2classes (out, mi.descriptor); 2422 2423 2424 out.push (new Instruction().setInvokeVirtual ("java/lang/Class", "getDeclaredMethod", 2425 new Descriptor ("(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;"))); 2426 if (op == Instruction.OP_INVOKESTATIC) 2427 out.push (new Instruction().setDup_x1()); 2428 else 2429 out.push (new Instruction().setDup_x2()); 2430 2431 out.push (new Instruction().setIpush (1)); 2432 out.push (new Instruction().setInvokeVirtual ("java/lang/reflect/AccessibleObject", "setAccessible", 2433 new Descriptor (Type.BOOLEAN, Type.VOID))); 2434 2435 if (op == Instruction.OP_INVOKESTATIC) 2436 out.push (new Instruction().setDup()); 2437 2438 Instruction call = new Instruction(); 2439 call.setInvokeVirtual ("java/lang/reflect/Method", "invoke", new Descriptor ("(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")); 2440 out.push (call); 2441 2442 2443 Reflection.getReturn (out, mi.descriptor.ret); 2444 } 2445 } 2446 2447} 2448 | Popular Tags |