EMMA Coverage Report (generated Thu Dec 06 15:52:10 GMT 2007)
[all classes][com.sun.tools.javac.jvm]

COVERAGE SUMMARY FOR SOURCE FILE [Items.java]

nameclass, %method, %block, %line, %
Items.java67%  (8/12)28%  (27/97)21%  (337/1604)25%  (68.4/271)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class Items$CondItem0%   (0/1)0%   (0/14)0%   (0/265)0%   (0/42)
<static initializer> 0%   (0/1)0%   (0/8)0%   (0/1)
Items$CondItem (Items, int, Code$Chain, Code$Chain): void 0%   (0/1)0%   (0/17)0%   (0/6)
drop (): void 0%   (0/1)0%   (0/4)0%   (0/2)
duplicate (): void 0%   (0/1)0%   (0/4)0%   (0/2)
isFalse (): boolean 0%   (0/1)0%   (0/11)0%   (0/1)
isTrue (): boolean 0%   (0/1)0%   (0/11)0%   (0/1)
jumpFalse (): Code$Chain 0%   (0/1)0%   (0/61)0%   (0/5)
jumpTrue (): Code$Chain 0%   (0/1)0%   (0/51)0%   (0/5)
load (): Items$Item 0%   (0/1)0%   (0/49)0%   (0/11)
mkCond (): Items$CondItem 0%   (0/1)0%   (0/2)0%   (0/1)
negate (): Items$CondItem 0%   (0/1)0%   (0/23)0%   (0/3)
stash (int): void 0%   (0/1)0%   (0/7)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/13)0%   (0/1)
width (): int 0%   (0/1)0%   (0/4)0%   (0/1)
     
class Items$ImmediateItem0%   (0/1)0%   (0/9)0%   (0/387)0%   (0/59)
<static initializer> 0%   (0/1)0%   (0/8)0%   (0/1)
Items$ImmediateItem (Items, Type, Object): void 0%   (0/1)0%   (0/12)0%   (0/4)
coerce (int): Items$Item 0%   (0/1)0%   (0/126)0%   (0/13)
isPosZero (double): boolean 0%   (0/1)0%   (0/14)0%   (0/1)
isPosZero (float): boolean 0%   (0/1)0%   (0/14)0%   (0/1)
ldc (): void 0%   (0/1)0%   (0/39)0%   (0/7)
load (): Items$Item 0%   (0/1)0%   (0/148)0%   (0/29)
mkCond (): Items$CondItem 0%   (0/1)0%   (0/14)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
     
class Items$IndexedItem0%   (0/1)0%   (0/8)0%   (0/74)0%   (0/15)
Items$IndexedItem (Items, Type): void 0%   (0/1)0%   (0/9)0%   (0/3)
drop (): void 0%   (0/1)0%   (0/6)0%   (0/2)
duplicate (): void 0%   (0/1)0%   (0/6)0%   (0/2)
load (): Items$Item 0%   (0/1)0%   (0/15)0%   (0/2)
stash (int): void 0%   (0/1)0%   (0/13)0%   (0/2)
store (): void 0%   (0/1)0%   (0/9)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/14)0%   (0/1)
width (): int 0%   (0/1)0%   (0/2)0%   (0/1)
     
class Items$StaticItem0%   (0/1)0%   (0/5)0%   (0/95)0%   (0/15)
Items$StaticItem (Items, Symbol): void 0%   (0/1)0%   (0/15)0%   (0/4)
invoke (): Items$Item 0%   (0/1)0%   (0/38)0%   (0/6)
load (): Items$Item 0%   (0/1)0%   (0/18)0%   (0/2)
store (): void 0%   (0/1)0%   (0/12)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
     
class Items$StackItem100% (1/1)29%  (2/7)14%  (10/71)33%  (4/12)
drop (): void 0%   (0/1)0%   (0/12)0%   (0/2)
duplicate (): void 0%   (0/1)0%   (0/12)0%   (0/2)
stash (int): void 0%   (0/1)0%   (0/19)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/14)0%   (0/1)
width (): int 0%   (0/1)0%   (0/4)0%   (0/1)
Items$StackItem (Items, int): void 100% (1/1)100% (8/8)100% (3/3)
load (): Items$Item 100% (1/1)100% (2/2)100% (1/1)
     
class Items$Item100% (1/1)36%  (4/11)19%  (21/111)28%  (7/25)
duplicate (): void 0%   (0/1)0%   (0/1)0%   (0/1)
invoke (): Items$Item 0%   (0/1)0%   (0/5)0%   (0/1)
load (): Items$Item 0%   (0/1)0%   (0/4)0%   (0/1)
mkCond (): Items$CondItem 0%   (0/1)0%   (0/8)0%   (0/2)
stash (int): void 0%   (0/1)0%   (0/7)0%   (0/2)
store (): void 0%   (0/1)0%   (0/12)0%   (0/1)
width (): int 0%   (0/1)0%   (0/2)0%   (0/1)
coerce (int): Items$Item 100% (1/1)11%  (6/57)18%  (2/11)
Items$Item (Items, int): void 100% (1/1)100% (9/9)100% (3/3)
coerce (Type): Items$Item 100% (1/1)100% (5/5)100% (1/1)
drop (): void 100% (1/1)100% (1/1)100% (1/1)
     
class Items$LocalItem100% (1/1)50%  (3/6)26%  (50/193)34%  (9.5/28)
incr (int): void 0%   (0/1)0%   (0/71)0%   (0/11)
store (): void 0%   (0/1)0%   (0/37)0%   (0/5)
toString (): String 0%   (0/1)0%   (0/17)0%   (0/1)
load (): Items$Item 100% (1/1)70%  (26/37)75%  (3/4)
Items$LocalItem (Items, Type, int): void 100% (1/1)74%  (17/23)94%  (5.6/6)
<static initializer> 100% (1/1)88%  (7/8)87%  (0.9/1)
     
class Items$AssignItem100% (1/1)38%  (3/8)33%  (23/70)43%  (6.9/16)
duplicate (): void 0%   (0/1)0%   (0/4)0%   (0/2)
load (): Items$Item 0%   (0/1)0%   (0/15)0%   (0/3)
stash (int): void 0%   (0/1)0%   (0/7)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/12)0%   (0/1)
width (): int 0%   (0/1)0%   (0/8)0%   (0/1)
<static initializer> 100% (1/1)88%  (7/8)87%  (0.9/1)
Items$AssignItem (Items, Items$Item): void 100% (1/1)100% (12/12)100% (4/4)
drop (): void 100% (1/1)100% (4/4)100% (2/2)
     
class Items$MemberItem100% (1/1)44%  (4/9)66%  (101/154)64%  (16/25)
drop (): void 0%   (0/1)0%   (0/7)0%   (0/2)
duplicate (): void 0%   (0/1)0%   (0/7)0%   (0/2)
stash (int): void 0%   (0/1)0%   (0/8)0%   (0/2)
toString (): String 0%   (0/1)0%   (0/17)0%   (0/1)
width (): int 0%   (0/1)0%   (0/2)0%   (0/1)
invoke (): Items$Item 100% (1/1)82%  (53/65)88%  (7/8)
Items$MemberItem (Items, Symbol, boolean): void 100% (1/1)100% (18/18)100% (5/5)
load (): Items$Item 100% (1/1)100% (18/18)100% (2/2)
store (): void 100% (1/1)100% (12/12)100% (2/2)
     
class Items100% (1/1)53%  (8/15)70%  (101/144)73%  (19/26)
makeCondItem (int): Items$CondItem 0%   (0/1)0%   (0/6)0%   (0/1)
makeCondItem (int, Code$Chain, Code$Chain): Items$CondItem 0%   (0/1)0%   (0/8)0%   (0/1)
makeImmediateItem (Type, Object): Items$Item 0%   (0/1)0%   (0/7)0%   (0/1)
makeIndexedItem (Type): Items$Item 0%   (0/1)0%   (0/6)0%   (0/1)
makeLocalItem (Type, int): Items$LocalItem 0%   (0/1)0%   (0/7)0%   (0/1)
makeStaticItem (Symbol): Items$Item 0%   (0/1)0%   (0/6)0%   (0/1)
makeVoidItem (): Items$Item 0%   (0/1)0%   (0/3)0%   (0/1)
Items (Pool, Code, Symtab, Types): void 100% (1/1)100% (62/62)100% (12/12)
access$000 (Items): Items$Item [] 100% (1/1)100% (3/3)100% (1/1)
makeAssignItem (Items$Item): Items$Item 100% (1/1)100% (6/6)100% (1/1)
makeLocalItem (Symbol$VarSymbol): Items$LocalItem 100% (1/1)100% (11/11)100% (1/1)
makeMemberItem (Symbol, boolean): Items$Item 100% (1/1)100% (7/7)100% (1/1)
makeStackItem (Type): Items$Item 100% (1/1)100% (6/6)100% (1/1)
makeSuperItem (): Items$Item 100% (1/1)100% (3/3)100% (1/1)
makeThisItem (): Items$Item 100% (1/1)100% (3/3)100% (1/1)
     
class Items$SelfItem100% (1/1)67%  (2/3)77%  (23/30)86%  (6/7)
toString (): String 0%   (0/1)0%   (0/7)0%   (0/1)
Items$SelfItem (Items, boolean): void 100% (1/1)100% (11/11)100% (4/4)
load (): Items$Item 100% (1/1)100% (12/12)100% (2/2)
     
class Items$1100% (1/1)50%  (1/2)80%  (8/10)50%  (1/2)
toString (): String 0%   (0/1)0%   (0/2)0%   (0/1)
Items$1 (Items, int): void 100% (1/1)100% (8/8)100% (1/1)

1/*
2 * Copyright 1999-2007 Sun Microsystems, Inc.  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.  Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25 
26package com.sun.tools.javac.jvm;
27 
28import com.sun.tools.javac.util.*;
29import com.sun.tools.javac.code.*;
30 
31import com.sun.tools.javac.code.Symbol.*;
32import com.sun.tools.javac.code.Type.*;
33import com.sun.tools.javac.jvm.Code.*;
34import com.sun.tools.javac.tree.JCTree;
35 
36import static com.sun.tools.javac.code.TypeTags.*;
37import 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 API supported by Sun Microsystems.  If
49 *  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 */
53public 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;
100    }
101 
102    /** Make an item representing `super'.
103     */
104    Item makeSuperItem() {
105        return superItem;
106    }
107 
108    /** Make an item representing a value on stack.
109     *  @param type    The value's type.
110     */
111    Item makeStackItem(Type type) {
112        return stackItem[Code.typecode(type)];
113    }
114 
115    /** Make an item representing an indexed expression.
116     *  @param type    The expression's type.
117     */
118    Item makeIndexedItem(Type type) {
119        return new IndexedItem(type);
120    }
121 
122    /** Make an item representing a local variable.
123     *  @param v    The represented variable.
124     */
125    LocalItem makeLocalItem(VarSymbol v) {
126        return new LocalItem(v.erasure(types), v.adr);
127    }
128 
129    /** Make an item representing a local anonymous variable.
130     *  @param type  The represented variable's type.
131     *  @param reg   The represented variable's register.
132     */
133    private LocalItem makeLocalItem(Type type, int reg) {
134        return new LocalItem(type, reg);
135    }
136 
137    /** Make an item representing a static variable or method.
138     *  @param member   The represented symbol.
139     */
140    Item makeStaticItem(Symbol member) {
141        return new StaticItem(member);
142    }
143 
144    /** Make an item representing an instance variable or method.
145     *  @param member       The represented symbol.
146     *  @param nonvirtual   Is the reference not virtual? (true for constructors
147     *                      and private members).
148     */
149    Item makeMemberItem(Symbol member, boolean nonvirtual) {
150        return new MemberItem(member, nonvirtual);
151    }
152 
153    /** Make an item representing a literal.
154     *  @param type     The literal's type.
155     *  @param value    The literal's value.
156     */
157    Item makeImmediateItem(Type type, Object value) {
158        return new ImmediateItem(type, value);
159    }
160 
161    /** Make an item representing an assignment expression.
162     *  @param lhs      The item representing the assignment's left hand side.
163     */
164    Item makeAssignItem(Item lhs) {
165        return new AssignItem(lhs);
166    }
167 
168    /** Make an item representing a conditional or unconditional jump.
169     *  @param opcode      The jump's opcode.
170     *  @param trueJumps   A chain encomassing all jumps that can be taken
171     *                     if the condition evaluates to true.
172     *  @param falseJumps  A chain encomassing all jumps that can be taken
173     *                     if the condition evaluates to false.
174     */
175    CondItem makeCondItem(int opcode, Chain trueJumps, Chain falseJumps) {
176        return new CondItem(opcode, trueJumps, falseJumps);
177    }
178 
179    /** Make an item representing a conditional or unconditional jump.
180     *  @param opcode      The jump's opcode.
181     */
182    CondItem makeCondItem(int opcode) {
183        return makeCondItem(opcode, null, null);
184    }
185 
186    /** The base class of all items, which implements default behavior.
187     */
188    abstract class Item {
189 
190        /** The type code of values represented by this item.
191         */
192        int typecode;
193 
194        Item(int typecode) {
195            this.typecode = typecode;
196        }
197 
198        /** Generate code to load this item onto stack.
199         */
200        Item load() {
201            throw new AssertionError();
202        }
203 
204        /** Generate code to store top of stack into this item.
205         */
206        void store() {
207            throw new AssertionError("store unsupported: " + this);
208        }
209 
210        /** Generate code to invoke method represented by this item.
211         */
212        Item invoke() {
213            throw new AssertionError(this);
214        }
215 
216        /** Generate code to use this item twice.
217         */
218        void duplicate() {}
219 
220        /** Generate code to avoid having to use this item.
221         */
222        void drop() {}
223 
224        /** Generate code to stash a copy of top of stack - of typecode toscode -
225         *  under this item.
226         */
227        void stash(int toscode) {
228            stackItem[toscode].duplicate();
229        }
230 
231        /** Generate code to turn item into a testable condition.
232         */
233        CondItem mkCond() {
234            load();
235            return makeCondItem(ifne);
236        }
237 
238        /** Generate code to coerce item to given type code.
239         *  @param targetcode    The type code to coerce to.
240         */
241        Item coerce(int targetcode) {
242            if (typecode == targetcode)
243                return this;
244            else {
245                load();
246                int typecode1 = Code.truncate(typecode);
247                int targetcode1 = Code.truncate(targetcode);
248                if (typecode1 != targetcode1) {
249                    int offset = targetcode1 > typecode1 ? targetcode1 - 1
250                        : targetcode1;
251                    code.emitop0(i2l + typecode1 * 3 + offset);
252                }
253                if (targetcode != targetcode1) {
254                    code.emitop0(int2byte + targetcode - BYTEcode);
255                }
256                return stackItem[targetcode];
257            }
258        }
259 
260        /** Generate code to coerce item to given type.
261         *  @param targettype    The type to coerce to.
262         */
263        Item coerce(Type targettype) {
264            return coerce(Code.typecode(targettype));
265        }
266 
267        /** Return the width of this item on stack as a number of words.
268         */
269        int width() {
270            return 0;
271        }
272 
273        public abstract String toString();
274    }
275 
276    /** An item representing a value on stack.
277     */
278    class StackItem extends Item {
279 
280        StackItem(int typecode) {
281            super(typecode);
282        }
283 
284        Item load() {
285            return this;
286        }
287 
288        void duplicate() {
289            code.emitop0(width() == 2 ? dup2 : dup);
290        }
291 
292        void drop() {
293            code.emitop0(width() == 2 ? pop2 : pop);
294        }
295 
296        void stash(int toscode) {
297            code.emitop0(
298                (width() == 2 ? dup_x2 : dup_x1) + 3 * (Code.width(toscode) - 1));
299        }
300 
301        int width() {
302            return Code.width(typecode);
303        }
304 
305        public String toString() {
306            return "stack(" + typecodeNames[typecode] + ")";
307        }
308    }
309 
310    /** An item representing an indexed expression.
311     */
312    class IndexedItem extends Item {
313 
314        IndexedItem(Type type) {
315            super(Code.typecode(type));
316        }
317 
318        Item load() {
319            code.emitop0(iaload + typecode);
320            return stackItem[typecode];
321        }
322 
323        void store() {
324            code.emitop0(iastore + typecode);
325        }
326 
327        void duplicate() {
328            code.emitop0(dup2);
329        }
330 
331        void drop() {
332            code.emitop0(pop2);
333        }
334 
335        void stash(int toscode) {
336            code.emitop0(dup_x2 + 3 * (Code.width(toscode) - 1));
337        }
338 
339        int width() {
340            return 2;
341        }
342 
343        public String toString() {
344            return "indexed(" + ByteCodes.typecodeNames[typecode] + ")";
345        }
346    }
347 
348    /** An item representing `this' or `super'.
349     */
350    class SelfItem extends Item {
351 
352        /** Flag which determines whether this item represents `this' or `super'.
353         */
354        boolean isSuper;
355 
356        SelfItem(boolean isSuper) {
357            super(OBJECTcode);
358            this.isSuper = isSuper;
359        }
360 
361        Item load() {
362            code.emitop0(aload_0);
363            return stackItem[typecode];
364        }
365 
366        public String toString() {
367            return isSuper ? "super" : "this";
368        }
369    }
370 
371    /** An item representing a local variable.
372     */
373    class LocalItem extends Item {
374 
375        /** The variable's register.
376         */
377        int reg;
378 
379        /** The variable's type.
380         */
381        Type type;
382 
383        LocalItem(Type type, int reg) {
384            super(Code.typecode(type));
385            assert reg >= 0;
386            this.type = type;
387            this.reg = reg;
388        }
389 
390        Item load() {
391            if (reg <= 3)
392                code.emitop0(iload_0 + Code.truncate(typecode) * 4 + reg);
393            else
394                code.emitop1w(iload + Code.truncate(typecode), reg);
395            return stackItem[typecode];
396        }
397 
398        void store() {
399            if (reg <= 3)
400                code.emitop0(istore_0 + Code.truncate(typecode) * 4 + reg);
401            else
402                code.emitop1w(istore + Code.truncate(typecode), reg);
403            code.setDefined(reg);
404        }
405 
406        void incr(int x) {
407            if (typecode == INTcode && x >= -32768 && x <= 32767) {
408                code.emitop1w(iinc, reg, x);
409            } else {
410                load();
411                if (x >= 0) {
412                    makeImmediateItem(syms.intType, x).load();
413                    code.emitop0(iadd);
414                } else {
415                    makeImmediateItem(syms.intType, -x).load();
416                    code.emitop0(isub);
417                }
418                makeStackItem(syms.intType).coerce(typecode);
419                store();
420            }
421        }
422 
423        public String toString() {
424            return "localItem(type=" + type + "; reg=" + reg + ")";
425        }
426    }
427 
428    /** An item representing a static variable or method.
429     */
430    class StaticItem extends Item {
431 
432        /** The represented symbol.
433         */
434        Symbol member;
435 
436        StaticItem(Symbol member) {
437            super(Code.typecode(member.erasure(types)));
438            this.member = member;
439        }
440 
441        Item load() {
442            code.emitop2(getstatic, pool.put(member));
443            return stackItem[typecode];
444        }
445 
446        void store() {
447            code.emitop2(putstatic, pool.put(member));
448        }
449 
450        Item invoke() {
451            MethodType mtype = (MethodType)member.erasure(types);
452            int argsize = Code.width(mtype.argtypes);
453            int rescode = Code.typecode(mtype.restype);
454            int sdiff = Code.width(rescode) - argsize;
455            code.emitInvokestatic(pool.put(member), mtype);
456            return stackItem[rescode];
457        }
458 
459        public String toString() {
460            return "static(" + member + ")";
461        }
462    }
463 
464    /** An item representing an instance variable or method.
465     */
466    class MemberItem extends Item {
467 
468        /** The represented symbol.
469         */
470        Symbol member;
471 
472        /** Flag that determines whether or not access is virtual.
473         */
474        boolean nonvirtual;
475 
476        MemberItem(Symbol member, boolean nonvirtual) {
477            super(Code.typecode(member.erasure(types)));
478            this.member = member;
479            this.nonvirtual = nonvirtual;
480        }
481 
482        Item load() {
483            code.emitop2(getfield, pool.put(member));
484            return stackItem[typecode];
485        }
486 
487        void store() {
488            code.emitop2(putfield, pool.put(member));
489        }
490 
491        Item invoke() {
492            MethodType mtype = (MethodType)member.externalType(types);
493            int rescode = Code.typecode(mtype.restype);
494            if ((member.owner.flags() & Flags.INTERFACE) != 0) {
495                code.emitInvokeinterface(pool.put(member), mtype);
496            } else if (nonvirtual) {
497                code.emitInvokespecial(pool.put(member), mtype);
498            } else {
499                code.emitInvokevirtual(pool.put(member), mtype);
500            }
501            return stackItem[rescode];
502        }
503 
504        void duplicate() {
505            stackItem[OBJECTcode].duplicate();
506        }
507 
508        void drop() {
509            stackItem[OBJECTcode].drop();
510        }
511 
512        void stash(int toscode) {
513            stackItem[OBJECTcode].stash(toscode);
514        }
515 
516        int width() {
517            return 1;
518        }
519 
520        public String toString() {
521            return "member(" + member + (nonvirtual ? " nonvirtual)" : ")");
522        }
523    }
524 
525    /** An item representing a literal.
526     */
527    class ImmediateItem extends Item {
528 
529        /** The literal's value.
530         */
531        Object value;
532 
533        ImmediateItem(Type type, Object value) {
534            super(Code.typecode(type));
535            this.value = value;
536        }
537 
538        private void ldc() {
539            int idx = pool.put(value);
540            if (typecode == LONGcode || typecode == DOUBLEcode) {
541                code.emitop2(ldc2w, idx);
542            } else if (idx <= 255) {
543                code.emitop1(ldc1, idx);
544            } else {
545                code.emitop2(ldc2, idx);
546            }
547        }
548 
549        Item load() {
550            switch (typecode) {
551            case INTcode: case BYTEcode: case SHORTcode: case CHARcode:
552                int ival = ((Number)value).intValue();
553                if (-1 <= ival && ival <= 5)
554                    code.emitop0(iconst_0 + ival);
555                else if (Byte.MIN_VALUE <= ival && ival <= Byte.MAX_VALUE)
556                    code.emitop1(bipush, ival);
557                else if (Short.MIN_VALUE <= ival && ival <= Short.MAX_VALUE)
558                    code.emitop2(sipush, ival);
559                else
560                    ldc();
561                break;
562            case LONGcode:
563                long lval = ((Number)value).longValue();
564                if (lval == 0 || lval == 1)
565                    code.emitop0(lconst_0 + (int)lval);
566                else
567                    ldc();
568                break;
569            case FLOATcode:
570                float fval = ((Number)value).floatValue();
571                if (isPosZero(fval) || fval == 1.0 || fval == 2.0)
572                    code.emitop0(fconst_0 + (int)fval);
573                else {
574                    ldc();
575                }
576                break;
577            case DOUBLEcode:
578                double dval = ((Number)value).doubleValue();
579                if (isPosZero(dval) || dval == 1.0)
580                    code.emitop0(dconst_0 + (int)dval);
581                else
582                    ldc();
583                break;
584            case OBJECTcode:
585                ldc();
586                break;
587            default:
588                assert false;
589            }
590            return stackItem[typecode];
591        }
592        //where
593            /** Return true iff float number is positive 0.
594             */
595            private boolean isPosZero(float x) {
596                return x == 0.0f && 1.0f / x > 0.0f;
597            }
598            /** Return true iff double number is positive 0.
599             */
600            private boolean isPosZero(double x) {
601                return x == 0.0d && 1.0d / x > 0.0d;
602            }
603 
604        CondItem mkCond() {
605            int ival = ((Number)value).intValue();
606            return makeCondItem(ival != 0 ? goto_ : dontgoto);
607        }
608 
609        Item coerce(int targetcode) {
610            if (typecode == targetcode) {
611                return this;
612            } else {
613                switch (targetcode) {
614                case INTcode:
615                    if (Code.truncate(typecode) == INTcode)
616                        return this;
617                    else
618                        return new ImmediateItem(
619                            syms.intType,
620                            ((Number)value).intValue());
621                case LONGcode:
622                    return new ImmediateItem(
623                        syms.longType,
624                        ((Number)value).longValue());
625                case FLOATcode:
626                    return new ImmediateItem(
627                        syms.floatType,
628                        ((Number)value).floatValue());
629                case DOUBLEcode:
630                    return new ImmediateItem(
631                        syms.doubleType,
632                        ((Number)value).doubleValue());
633                case BYTEcode:
634                    return new ImmediateItem(
635                        syms.byteType,
636                        (int)(byte)((Number)value).intValue());
637                case CHARcode:
638                    return new ImmediateItem(
639                        syms.charType,
640                        (int)(char)((Number)value).intValue());
641                case SHORTcode:
642                    return new ImmediateItem(
643                        syms.shortType,
644                        (int)(short)((Number)value).intValue());
645                default:
646                    return super.coerce(targetcode);
647                }
648            }
649        }
650 
651        public String toString() {
652            return "immediate(" + value + ")";
653        }
654    }
655 
656    /** An item representing an assignment expressions.
657     */
658    class AssignItem extends Item {
659 
660        /** The item representing the assignment's left hand side.
661         */
662        Item lhs;
663 
664        AssignItem(Item lhs) {
665            super(lhs.typecode);
666            this.lhs = lhs;
667        }
668 
669        Item load() {
670            lhs.stash(typecode);
671            lhs.store();
672            return stackItem[typecode];
673        }
674 
675        void duplicate() {
676            load().duplicate();
677        }
678 
679        void drop() {
680            lhs.store();
681        }
682 
683        void stash(int toscode) {
684            assert false;
685        }
686 
687        int width() {
688            return lhs.width() + Code.width(typecode);
689        }
690 
691        public String toString() {
692            return "assign(lhs = " + lhs + ")";
693        }
694    }
695 
696    /** An item representing a conditional or unconditional jump.
697     */
698    class CondItem extends Item {
699 
700        /** A chain encomassing all jumps that can be taken
701         *  if the condition evaluates to true.
702         */
703        Chain trueJumps;
704 
705        /** A chain encomassing all jumps that can be taken
706         *  if the condition evaluates to false.
707         */
708        Chain falseJumps;
709 
710        /** The jump's opcode.
711         */
712        int opcode;
713 
714        /*
715         *  An abstract syntax tree of this item. It is needed
716         *  for branch entries in 'CharacterRangeTable' attribute.
717         */
718        JCTree tree;
719 
720        CondItem(int opcode, Chain truejumps, Chain falsejumps) {
721            super(BYTEcode);
722            this.opcode = opcode;
723            this.trueJumps = truejumps;
724            this.falseJumps = falsejumps;
725        }
726 
727        Item load() {
728            Chain trueChain = null;
729            Chain falseChain = jumpFalse();
730            if (!isFalse()) {
731                code.resolve(trueJumps);
732                code.emitop0(iconst_1);
733                trueChain = code.branch(goto_);
734            }
735            if (falseChain != null) {
736                code.resolve(falseChain);
737                code.emitop0(iconst_0);
738            }
739            code.resolve(trueChain);
740            return stackItem[typecode];
741        }
742 
743        void duplicate() {
744            load().duplicate();
745        }
746 
747        void drop() {
748            load().drop();
749        }
750 
751        void stash(int toscode) {
752            assert false;
753        }
754 
755        CondItem mkCond() {
756            return this;
757        }
758 
759        Chain jumpTrue() {
760            if (tree == null) return code.mergeChains(trueJumps, code.branch(opcode));
761            // we should proceed further in -Xjcov mode only
762            int startpc = code.curPc();
763            Chain c = code.mergeChains(trueJumps, code.branch(opcode));
764            code.crt.put(tree, CRTable.CRT_BRANCH_TRUE, startpc, code.curPc());
765            return c;
766        }
767 
768        Chain jumpFalse() {
769            if (tree == null) return code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
770            // we should proceed further in -Xjcov mode only
771            int startpc = code.curPc();
772            Chain c = code.mergeChains(falseJumps, code.branch(code.negate(opcode)));
773            code.crt.put(tree, CRTable.CRT_BRANCH_FALSE, startpc, code.curPc());
774            return c;
775        }
776 
777        CondItem negate() {
778            CondItem c = new CondItem(code.negate(opcode), falseJumps, trueJumps);
779            c.tree = tree;
780            return c;
781        }
782 
783        int width() {
784            // a CondItem doesn't have a size on the stack per se.
785            throw new AssertionError();
786        }
787 
788        boolean isTrue() {
789            return falseJumps == null && opcode == goto_;
790        }
791 
792        boolean isFalse() {
793            return trueJumps == null && opcode == dontgoto;
794        }
795 
796        public String toString() {
797            return "cond(" + Code.mnem(opcode) + ")";
798        }
799    }
800}

[all classes][com.sun.tools.javac.jvm]
EMMA 2.0.5312 (C) Vladimir Roubtsov