< prev index next >

src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java

Print this page


   1 /*
   2  * Copyright (c) 1999, 2019, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;

  29 import com.sun.tools.javac.code.Symbol.*;
  30 import com.sun.tools.javac.code.Type.*;
  31 import com.sun.tools.javac.jvm.Code.*;
  32 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant;
  33 import com.sun.tools.javac.jvm.PoolConstant.LoadableConstant.BasicConstant;
  34 import com.sun.tools.javac.tree.JCTree;
  35 import com.sun.tools.javac.util.Assert;
  36 
  37 import static com.sun.tools.javac.jvm.ByteCodes.*;
  38 
  39 /** A helper class for code generation. Items are objects
  40  *  that stand for addressable entities in the bytecode. Each item
  41  *  supports a fixed protocol for loading the item on the stack, storing
  42  *  into it, converting it into a jump condition, and several others.
  43  *  There are many individual forms of items, such as local, static,
  44  *  indexed, or instance variables, values on the top of stack, the
  45  *  special values this or super, etc. Individual items are represented as
  46  *  inner classes in class Items.
  47  *
  48  *  <p><b>This is NOT part of any supported API.
  49  *  If you write code that depends on this, you do so at your own risk.
  50  *  This code and its internal interfaces are subject to change or
  51  *  deletion without notice.</b>
  52  */
  53 public class Items {
  54 
  55     /** The current constant pool writer.
  56      */
  57     PoolWriter poolWriter;
  58 
  59     /** The current code buffer.
  60      */
  61     Code code;
  62 
  63     /** The current symbol table.
  64      */
  65     Symtab syms;
  66 
  67     /** Type utilities. */
  68     Types types;
  69 
  70     /** Items that exist only once (flyweight pattern).
  71      */
  72     private final Item voidItem;
  73     private final Item thisItem;
  74     private final Item superItem;
  75     private final Item[] stackItem = new Item[TypeCodeCount];
  76 
  77     public Items(PoolWriter poolWriter, Code code, Symtab syms, Types types) {
  78         this.code = code;
  79         this.poolWriter = poolWriter;
  80         this.types = types;
  81         voidItem = new Item(VOIDcode) {
  82                 public String toString() { return "void"; }
  83             };
  84         thisItem = new SelfItem(false);
  85         superItem = new SelfItem(true);
  86         for (int i = 0; i < VOIDcode; i++) stackItem[i] = new StackItem(i);
  87         stackItem[VOIDcode] = voidItem;
  88         this.syms = syms;
  89     }
  90 
  91     /** Make a void item
  92      */
  93     Item makeVoidItem() {
  94         return voidItem;
  95     }
  96     /** Make an item representing `this'.
  97      */
  98     Item makeThisItem() {
  99         return thisItem;


 148         return new StaticItem(member);
 149     }
 150 
 151     /** Make an item representing an instance variable or method.
 152      *  @param member       The represented symbol.
 153      *  @param nonvirtual   Is the reference not virtual? (true for constructors
 154      *                      and private members).
 155      */
 156     Item makeMemberItem(Symbol member, boolean nonvirtual) {
 157         return new MemberItem(member, nonvirtual);
 158     }
 159 
 160     /** Make an item representing a literal.
 161      *  @param type     The literal's type.
 162      *  @param value    The literal's value.
 163      */
 164     Item makeImmediateItem(Type type, Object value) {
 165         return new ImmediateItem(type, value);
 166     }
 167 







 168     /** Make an item representing an assignment expression.
 169      *  @param lhs      The item representing the assignment's left hand side.
 170      */
 171     Item makeAssignItem(Item lhs) {
 172         return new AssignItem(lhs);
 173     }
 174 
 175     /** Make an item representing a conditional or unconditional jump.
 176      *  @param opcode      The jump's opcode.
 177      *  @param trueJumps   A chain encomassing all jumps that can be taken
 178      *                     if the condition evaluates to true.
 179      *  @param falseJumps  A chain encomassing all jumps that can be taken
 180      *                     if the condition evaluates to false.
 181      */
 182     CondItem makeCondItem(int opcode, Chain trueJumps, Chain falseJumps) {
 183         return new CondItem(opcode, trueJumps, falseJumps);
 184     }
 185 
 186     /** Make an item representing a conditional or unconditional jump.
 187      *  @param opcode      The jump's opcode.


 429 
 430         public String toString() {
 431             return "localItem(type=" + type + "; reg=" + reg + ")";
 432         }
 433     }
 434 
 435     /** An item representing a static variable or method.
 436      */
 437     class StaticItem extends Item {
 438 
 439         /** The represented symbol.
 440          */
 441         Symbol member;
 442 
 443         StaticItem(Symbol member) {
 444             super(Code.typecode(member.erasure(types)));
 445             this.member = member;
 446         }
 447 
 448         Item load() {
 449             code.emitop2(getstatic, member, PoolWriter::putMember);
 450             return stackItem[typecode];
 451         }
 452 
 453         void store() {
 454             code.emitop2(putstatic, member, PoolWriter::putMember);
 455         }
 456 
 457         Item invoke() {
 458             MethodType mtype = (MethodType)member.erasure(types);
 459             int rescode = Code.typecode(mtype.restype);
 460             code.emitInvokestatic(member, mtype);
 461             return stackItem[rescode];
 462         }
 463 
 464         public String toString() {
 465             return "static(" + member + ")";
 466         }
 467     }
 468 



























 469     /** An item representing a dynamic call site.
 470      */
 471     class DynamicItem extends StaticItem {
 472         DynamicItem(Symbol member) {
 473             super(member);
 474         }
 475 
 476         Item load() {
 477             Assert.check(member.kind == Kinds.Kind.VAR);
 478             Type type = member.erasure(types);
 479             int rescode = Code.typecode(type);
 480             code.emitLdc((DynamicVarSymbol)member);
 481             return stackItem[rescode];
 482         }
 483 
 484         void store() { Assert.error("this method shouldn't be invoked"); }


 485 
 486         Item invoke() {
 487             Assert.check(member.kind == Kinds.Kind.MTH);
 488             MethodType mtype = (MethodType)member.erasure(types);
 489             int rescode = Code.typecode(mtype.restype);
 490             code.emitInvokedynamic((DynamicMethodSymbol)member, mtype);
 491             return stackItem[rescode];
 492         }
 493 
 494         public String toString() {
 495             return "dynamic(" + member + ")";
 496         }
 497     }
 498 
 499     /** An item representing an instance variable or method.
 500      */
 501     class MemberItem extends Item {
 502 
 503         /** The represented symbol.
 504          */
 505         Symbol member;
 506 
 507         /** Flag that determines whether or not access is virtual.
 508          */
 509         boolean nonvirtual;
 510 
 511         MemberItem(Symbol member, boolean nonvirtual) {
 512             super(Code.typecode(member.erasure(types)));
 513             this.member = member;
 514             this.nonvirtual = nonvirtual;
 515         }
 516 
 517         Item load() {
 518             code.emitop2(getfield, member, PoolWriter::putMember);
 519             return stackItem[typecode];
 520         }
 521 
 522         void store() {
 523             code.emitop2(putfield, member, PoolWriter::putMember);
 524         }
 525 
 526         Item invoke() {
 527             MethodType mtype = (MethodType)member.externalType(types);
 528             int rescode = Code.typecode(mtype.restype);
 529             if ((member.owner.flags() & Flags.INTERFACE) != 0 && !nonvirtual) {
 530                 code.emitInvokeinterface(member, mtype);
 531             } else if (nonvirtual) {
 532                 code.emitInvokespecial(member, mtype);
 533             } else {
 534                 code.emitInvokevirtual(member, mtype);
 535             }
 536             return stackItem[rescode];
 537         }
 538 
 539         void duplicate() {
 540             stackItem[OBJECTcode].duplicate();
 541         }
 542 
 543         void drop() {
 544             stackItem[OBJECTcode].drop();
 545         }
 546 
 547         void stash(int toscode) {
 548             stackItem[OBJECTcode].stash(toscode);
 549         }
 550 
 551         int width() {
 552             return 1;
 553         }
 554 
 555         public String toString() {
 556             return "member(" + member + (nonvirtual ? " nonvirtual)" : ")");
 557         }
 558     }
 559 
 560     /** An item representing a literal.
 561      */
 562     class ImmediateItem extends Item {
 563 
 564         /** The literal's value.
 565          */
 566         final LoadableConstant value;
 567 
 568         ImmediateItem(Type type, Object value) {
 569             super(Code.typecode(type));
 570             switch (typecode) {
 571                 case BYTEcode:
 572                 case SHORTcode:
 573                 case CHARcode:
 574                 case INTcode:
 575                     this.value = LoadableConstant.Int((int)value);
 576                     break;
 577                 case LONGcode:
 578                     this.value = LoadableConstant.Long((long)value);
 579                     break;
 580                 case FLOATcode:
 581                     this.value = LoadableConstant.Float((float)value);
 582                     break;
 583                 case DOUBLEcode:
 584                     this.value = LoadableConstant.Double((double)value);
 585                     break;
 586                 case OBJECTcode:
 587                     this.value = LoadableConstant.String((String)value);
 588                     break;
 589                 default:
 590                     throw new UnsupportedOperationException("unsupported tag: " + typecode);
 591             }
 592         }
 593 
 594         private void ldc() {

 595             if (typecode == LONGcode || typecode == DOUBLEcode) {
 596                 code.emitop2(ldc2w, value, PoolWriter::putConstant);
 597             } else {
 598                 code.emitLdc(value);
 599             }
 600         }
 601 
 602         private Number numericValue() {
 603             return (Number)((BasicConstant)value).data;
 604         }
 605 
 606         Item load() {
 607             switch (typecode) {
 608             case INTcode: case BYTEcode: case SHORTcode: case CHARcode:
 609                 int ival = numericValue().intValue();
 610                 if (-1 <= ival && ival <= 5)
 611                     code.emitop0(iconst_0 + ival);
 612                 else if (Byte.MIN_VALUE <= ival && ival <= Byte.MAX_VALUE)
 613                     code.emitop1(bipush, ival);
 614                 else if (Short.MIN_VALUE <= ival && ival <= Short.MAX_VALUE)
 615                     code.emitop2(sipush, ival);
 616                 else
 617                     ldc();
 618                 break;
 619             case LONGcode:
 620                 long lval = numericValue().longValue();
 621                 if (lval == 0 || lval == 1)
 622                     code.emitop0(lconst_0 + (int)lval);
 623                 else
 624                     ldc();
 625                 break;
 626             case FLOATcode:
 627                 float fval = numericValue().floatValue();
 628                 if (isPosZero(fval) || fval == 1.0 || fval == 2.0)
 629                     code.emitop0(fconst_0 + (int)fval);
 630                 else {
 631                     ldc();
 632                 }
 633                 break;
 634             case DOUBLEcode:
 635                 double dval = numericValue().doubleValue();
 636                 if (isPosZero(dval) || dval == 1.0)
 637                     code.emitop0(dconst_0 + (int)dval);
 638                 else
 639                     ldc();
 640                 break;
 641             case OBJECTcode:
 642                 ldc();
 643                 break;
 644             default:
 645                 Assert.error();
 646             }
 647             return stackItem[typecode];
 648         }
 649         //where
 650             /** Return true iff float number is positive 0.
 651              */
 652             private boolean isPosZero(float x) {
 653                 return x == 0.0f && 1.0f / x > 0.0f;
 654             }
 655             /** Return true iff double number is positive 0.
 656              */
 657             private boolean isPosZero(double x) {
 658                 return x == 0.0d && 1.0d / x > 0.0d;
 659             }
 660 
 661         CondItem mkCond() {
 662             int ival = numericValue().intValue();
 663             return makeCondItem(ival != 0 ? goto_ : dontgoto);
 664         }
 665 
 666         Item coerce(int targetcode) {
 667             if (typecode == targetcode) {
 668                 return this;
 669             } else {
 670                 switch (targetcode) {
 671                 case INTcode:
 672                     if (Code.truncate(typecode) == INTcode)
 673                         return this;
 674                     else
 675                         return new ImmediateItem(
 676                             syms.intType,
 677                             numericValue().intValue());
 678                 case LONGcode:
 679                     return new ImmediateItem(
 680                         syms.longType,
 681                             numericValue().longValue());
 682                 case FLOATcode:
 683                     return new ImmediateItem(
 684                         syms.floatType,
 685                         numericValue().floatValue());
 686                 case DOUBLEcode:
 687                     return new ImmediateItem(
 688                         syms.doubleType,
 689                         numericValue().doubleValue());
 690                 case BYTEcode:
 691                     return new ImmediateItem(
 692                         syms.byteType,
 693                         (int)(byte)numericValue().intValue());
 694                 case CHARcode:
 695                     return new ImmediateItem(
 696                         syms.charType,
 697                         (int)(char)numericValue().intValue());
 698                 case SHORTcode:
 699                     return new ImmediateItem(
 700                         syms.shortType,
 701                         (int)(short)numericValue().intValue());
 702                 default:
 703                     return super.coerce(targetcode);
 704                 }
 705             }
 706         }
 707 
 708         public String toString() {
 709             return "immediate(" + value + ")";
 710         }
 711     }
 712 
 713     /** An item representing an assignment expressions.
 714      */
 715     class AssignItem extends Item {
 716 
 717         /** The item representing the assignment's left hand side.
 718          */
 719         Item lhs;
 720 
 721         AssignItem(Item lhs) {


   1 /*
   2  * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.tools.javac.jvm;
  27 
  28 import com.sun.tools.javac.code.*;
  29 import com.sun.tools.javac.code.Kinds.Kind;
  30 import com.sun.tools.javac.code.Symbol.*;
  31 import com.sun.tools.javac.code.Type.*;
  32 import com.sun.tools.javac.jvm.Code.*;
  33 import com.sun.tools.javac.jvm.Pool.DynamicVariable;

  34 import com.sun.tools.javac.tree.JCTree;
  35 import com.sun.tools.javac.util.Assert;
  36 
  37 import static com.sun.tools.javac.jvm.ByteCodes.*;
  38 
  39 /** A helper class for code generation. Items are objects
  40  *  that stand for addressable entities in the bytecode. Each item
  41  *  supports a fixed protocol for loading the item on the stack, storing
  42  *  into it, converting it into a jump condition, and several others.
  43  *  There are many individual forms of items, such as local, static,
  44  *  indexed, or instance variables, values on the top of stack, the
  45  *  special values this or super, etc. Individual items are represented as
  46  *  inner classes in class Items.
  47  *
  48  *  <p><b>This is NOT part of any supported API.
  49  *  If you write code that depends on this, you do so at your own risk.
  50  *  This code and its internal interfaces are subject to change or
  51  *  deletion without notice.</b>
  52  */
  53 public class Items {
  54 
  55     /** The current constant pool.
  56      */
  57     Pool pool;
  58 
  59     /** The current code buffer.
  60      */
  61     Code code;
  62 
  63     /** The current symbol table.
  64      */
  65     Symtab syms;
  66 
  67     /** Type utilities. */
  68     Types types;
  69 
  70     /** Items that exist only once (flyweight pattern).
  71      */
  72     private final Item voidItem;
  73     private final Item thisItem;
  74     private final Item superItem;
  75     private final Item[] stackItem = new Item[TypeCodeCount];
  76 
  77     public Items(Pool pool, Code code, Symtab syms, Types types) {
  78         this.code = code;
  79         this.pool = pool;
  80         this.types = types;
  81         voidItem = new Item(VOIDcode) {
  82                 public String toString() { return "void"; }
  83             };
  84         thisItem = new SelfItem(false);
  85         superItem = new SelfItem(true);
  86         for (int i = 0; i < VOIDcode; i++) stackItem[i] = new StackItem(i);
  87         stackItem[VOIDcode] = voidItem;
  88         this.syms = syms;
  89     }
  90 
  91     /** Make a void item
  92      */
  93     Item makeVoidItem() {
  94         return voidItem;
  95     }
  96     /** Make an item representing `this'.
  97      */
  98     Item makeThisItem() {
  99         return thisItem;


 148         return new StaticItem(member);
 149     }
 150 
 151     /** Make an item representing an instance variable or method.
 152      *  @param member       The represented symbol.
 153      *  @param nonvirtual   Is the reference not virtual? (true for constructors
 154      *                      and private members).
 155      */
 156     Item makeMemberItem(Symbol member, boolean nonvirtual) {
 157         return new MemberItem(member, nonvirtual);
 158     }
 159 
 160     /** Make an item representing a literal.
 161      *  @param type     The literal's type.
 162      *  @param value    The literal's value.
 163      */
 164     Item makeImmediateItem(Type type, Object value) {
 165         return new ImmediateItem(type, value);
 166     }
 167 
 168     /** Make an item representing a condy.
 169      *  @param value    The condy value.
 170      */
 171     Item makeCondyItem(DynamicVariable value) {
 172         return new CondyItem(value);
 173     }
 174 
 175     /** Make an item representing an assignment expression.
 176      *  @param lhs      The item representing the assignment's left hand side.
 177      */
 178     Item makeAssignItem(Item lhs) {
 179         return new AssignItem(lhs);
 180     }
 181 
 182     /** Make an item representing a conditional or unconditional jump.
 183      *  @param opcode      The jump's opcode.
 184      *  @param trueJumps   A chain encomassing all jumps that can be taken
 185      *                     if the condition evaluates to true.
 186      *  @param falseJumps  A chain encomassing all jumps that can be taken
 187      *                     if the condition evaluates to false.
 188      */
 189     CondItem makeCondItem(int opcode, Chain trueJumps, Chain falseJumps) {
 190         return new CondItem(opcode, trueJumps, falseJumps);
 191     }
 192 
 193     /** Make an item representing a conditional or unconditional jump.
 194      *  @param opcode      The jump's opcode.


 436 
 437         public String toString() {
 438             return "localItem(type=" + type + "; reg=" + reg + ")";
 439         }
 440     }
 441 
 442     /** An item representing a static variable or method.
 443      */
 444     class StaticItem extends Item {
 445 
 446         /** The represented symbol.
 447          */
 448         Symbol member;
 449 
 450         StaticItem(Symbol member) {
 451             super(Code.typecode(member.erasure(types)));
 452             this.member = member;
 453         }
 454 
 455         Item load() {
 456             code.emitop2(getstatic, pool.put(member));
 457             return stackItem[typecode];
 458         }
 459 
 460         void store() {
 461             code.emitop2(putstatic, pool.put(member));
 462         }
 463 
 464         Item invoke() {
 465             MethodType mtype = (MethodType)member.erasure(types);
 466             int rescode = Code.typecode(mtype.restype);
 467             code.emitInvokestatic(pool.put(member), mtype);
 468             return stackItem[rescode];
 469         }
 470 
 471         public String toString() {
 472             return "static(" + member + ")";
 473         }
 474     }
 475 
 476     /** An item representing a condy
 477      */
 478     class CondyItem extends Item {
 479         DynamicVariable value;
 480 
 481         CondyItem(DynamicVariable value) {
 482             super(Code.typecode(value.type));
 483             this.value = value;
 484         }
 485 
 486         @Override
 487         public String toString() {
 488             return "condy(" + value + ")";
 489         }
 490 
 491         @Override
 492         Item load() {
 493             int idx = pool.put(value);
 494             if (typecode == LONGcode || typecode == DOUBLEcode) {
 495                 code.emitop2(ldc2w, idx);
 496             } else {
 497                 code.emitLdc(idx);
 498             }
 499             return stackItem[typecode];
 500         }
 501     }
 502 
 503     /** An item representing a dynamic call site.
 504      */
 505     class DynamicItem extends StaticItem {
 506         DynamicItem(Symbol member) {
 507             super(member);
 508         }
 509 
 510         Item load() {
 511             Assert.check(member.kind == Kind.VAR);
 512             Type type = member.erasure(types);
 513             int rescode = Code.typecode(type);
 514             code.emitLdc(pool.put(member));
 515             return stackItem[rescode];
 516         }
 517 
 518         void store() {
 519             assert false;
 520         }
 521 
 522         Item invoke() {
 523             Assert.check(member.kind == Kind.MTH);
 524             MethodType mtype = (MethodType)member.erasure(types);
 525             int rescode = Code.typecode(mtype.restype);
 526             code.emitInvokedynamic(pool.put(member), mtype);
 527             return stackItem[rescode];
 528         }
 529 
 530         public String toString() {
 531             return "dynamic(" + member + ")";
 532         }
 533     }
 534 
 535     /** An item representing an instance variable or method.
 536      */
 537     class MemberItem extends Item {
 538 
 539         /** The represented symbol.
 540          */
 541         Symbol member;
 542 
 543         /** Flag that determines whether or not access is virtual.
 544          */
 545         boolean nonvirtual;
 546 
 547         MemberItem(Symbol member, boolean nonvirtual) {
 548             super(Code.typecode(member.erasure(types)));
 549             this.member = member;
 550             this.nonvirtual = nonvirtual;
 551         }
 552 
 553         Item load() {
 554             code.emitop2(getfield, pool.put(member));
 555             return stackItem[typecode];
 556         }
 557 
 558         void store() {
 559             code.emitop2(putfield, pool.put(member));
 560         }
 561 
 562         Item invoke() {
 563             MethodType mtype = (MethodType)member.externalType(types);
 564             int rescode = Code.typecode(mtype.restype);
 565             if ((member.owner.flags() & Flags.INTERFACE) != 0 && !nonvirtual) {
 566                 code.emitInvokeinterface(pool.put(member), mtype);
 567             } else if (nonvirtual) {
 568                 code.emitInvokespecial(pool.put(member), mtype);
 569             } else {
 570                 code.emitInvokevirtual(pool.put(member), mtype);
 571             }
 572             return stackItem[rescode];
 573         }
 574 
 575         void duplicate() {
 576             stackItem[OBJECTcode].duplicate();
 577         }
 578 
 579         void drop() {
 580             stackItem[OBJECTcode].drop();
 581         }
 582 
 583         void stash(int toscode) {
 584             stackItem[OBJECTcode].stash(toscode);
 585         }
 586 
 587         int width() {
 588             return 1;
 589         }
 590 
 591         public String toString() {
 592             return "member(" + member + (nonvirtual ? " nonvirtual)" : ")");
 593         }
 594     }
 595 
 596     /** An item representing a literal.
 597      */
 598     class ImmediateItem extends Item {
 599 
 600         /** The literal's value.
 601          */
 602         Object value;
 603 
 604         ImmediateItem(Type type, Object value) {
 605             super(Code.typecode(type));
 606             this.value = value;





















 607         }
 608 
 609         private void ldc() {
 610             int idx = pool.put(value);
 611             if (typecode == LONGcode || typecode == DOUBLEcode) {
 612                 code.emitop2(ldc2w, idx);
 613             } else {
 614                 code.emitLdc(idx);
 615             }
 616         }
 617 




 618         Item load() {
 619             switch (typecode) {
 620             case INTcode: case BYTEcode: case SHORTcode: case CHARcode:
 621                 int ival = ((Number)value).intValue();
 622                 if (-1 <= ival && ival <= 5)
 623                     code.emitop0(iconst_0 + ival);
 624                 else if (Byte.MIN_VALUE <= ival && ival <= Byte.MAX_VALUE)
 625                     code.emitop1(bipush, ival);
 626                 else if (Short.MIN_VALUE <= ival && ival <= Short.MAX_VALUE)
 627                     code.emitop2(sipush, ival);
 628                 else
 629                     ldc();
 630                 break;
 631             case LONGcode:
 632                 long lval = ((Number)value).longValue();
 633                 if (lval == 0 || lval == 1)
 634                     code.emitop0(lconst_0 + (int)lval);
 635                 else
 636                     ldc();
 637                 break;
 638             case FLOATcode:
 639                 float fval = ((Number)value).floatValue();
 640                 if (isPosZero(fval) || fval == 1.0 || fval == 2.0)
 641                     code.emitop0(fconst_0 + (int)fval);
 642                 else {
 643                     ldc();
 644                 }
 645                 break;
 646             case DOUBLEcode:
 647                 double dval = ((Number)value).doubleValue();
 648                 if (isPosZero(dval) || dval == 1.0)
 649                     code.emitop0(dconst_0 + (int)dval);
 650                 else
 651                     ldc();
 652                 break;
 653             case OBJECTcode:
 654                 ldc();
 655                 break;
 656             default:
 657                 Assert.error();
 658             }
 659             return stackItem[typecode];
 660         }
 661         //where
 662             /** Return true iff float number is positive 0.
 663              */
 664             private boolean isPosZero(float x) {
 665                 return x == 0.0f && 1.0f / x > 0.0f;
 666             }
 667             /** Return true iff double number is positive 0.
 668              */
 669             private boolean isPosZero(double x) {
 670                 return x == 0.0d && 1.0d / x > 0.0d;
 671             }
 672 
 673         CondItem mkCond() {
 674             int ival = ((Number)value).intValue();
 675             return makeCondItem(ival != 0 ? goto_ : dontgoto);
 676         }
 677 
 678         Item coerce(int targetcode) {
 679             if (typecode == targetcode) {
 680                 return this;
 681             } else {
 682                 switch (targetcode) {
 683                 case INTcode:
 684                     if (Code.truncate(typecode) == INTcode)
 685                         return this;
 686                     else
 687                         return new ImmediateItem(
 688                             syms.intType,
 689                             ((Number)value).intValue());
 690                 case LONGcode:
 691                     return new ImmediateItem(
 692                         syms.longType,
 693                         ((Number)value).longValue());
 694                 case FLOATcode:
 695                     return new ImmediateItem(
 696                         syms.floatType,
 697                         ((Number)value).floatValue());
 698                 case DOUBLEcode:
 699                     return new ImmediateItem(
 700                         syms.doubleType,
 701                         ((Number)value).doubleValue());
 702                 case BYTEcode:
 703                     return new ImmediateItem(
 704                         syms.byteType,
 705                         (int)(byte)((Number)value).intValue());
 706                 case CHARcode:
 707                     return new ImmediateItem(
 708                         syms.charType,
 709                         (int)(char)((Number)value).intValue());
 710                 case SHORTcode:
 711                     return new ImmediateItem(
 712                         syms.shortType,
 713                         (int)(short)((Number)value).intValue());
 714                 default:
 715                     return super.coerce(targetcode);
 716                 }
 717             }
 718         }
 719 
 720         public String toString() {
 721             return "immediate(" + value + ")";
 722         }
 723     }
 724 
 725     /** An item representing an assignment expressions.
 726      */
 727     class AssignItem extends Item {
 728 
 729         /** The item representing the assignment's left hand side.
 730          */
 731         Item lhs;
 732 
 733         AssignItem(Item lhs) {


< prev index next >