KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > Variable


1 // Copyright (c) 1997, 2004 Per M.A. Bothner.
2
// This is free software; for terms and warranty disclaimer see ./COPYING.
3

4 package gnu.bytecode;
5
6 public class Variable extends Location implements java.util.Enumeration JavaDoc
7 {
8   /* Variables in a Scope are linked together in a linked list. */
9   Variable next;
10   public final Variable nextVar () { return next; }
11   public final boolean hasMoreElements () { return next != null; }
12   public Object JavaDoc nextElement ()
13   {
14     if (next == null)
15       throw new java.util.NoSuchElementException JavaDoc("Variable enumeration");
16     return next;
17   }
18
19   public Variable ()
20   {
21   }
22
23   public Variable (String JavaDoc name)
24   {
25     setName(name);
26   }
27
28   public Variable (String JavaDoc name, Type type)
29   {
30     setName(name);
31     setType(type);
32   }
33
34   private int flags = SIMPLE_FLAG;
35   /** The SIMPLE_FLAG records the isSimple (q.v.) state. */
36   private static final int SIMPLE_FLAG = 0x1;
37   /** The PARAMETER_FLAG bit is true for parameters. */
38   private static final int PARAMETER_FLAG = 0x2;
39   private static final int LIVE_FLAG = 0x4;
40
41   static final int UNASSIGNED = -1;
42   /** The local variable slot number used by this variable.
43    * Not used (by the codegen layer) if !isSimple(). */

44   int offset = UNASSIGNED;
45   /** Returns true iff assigned to a local variable slot.
46    * Only relevant if isSimple (). */

47   public final boolean isAssigned () { return offset != UNASSIGNED; }
48
49   Scope scope;
50
51   public final boolean dead () { return (flags & LIVE_FLAG) == 0; }
52
53   private void setFlag (boolean setting, int flag)
54   {
55     if (setting) flags |= flag;
56     else flags &= ~flag;
57   }
58
59   /** Returns true for a "simple" variable.
60    * A "simple" Variable can be stack-allocated using standard local
61    * variable slots. It is allocated by the codegen package.
62    * A non-simple variable may need heap allocation, or more more
63    * complex access; it is basically ignored by the codegen package,
64    * and must be managed by higher layers. */

65   public final boolean isSimple ()
66   {
67     return (flags & SIMPLE_FLAG) != 0;
68   }
69   
70   public final void setSimple (boolean simple)
71   { setFlag(simple, SIMPLE_FLAG); }
72
73   public final boolean isParameter ()
74   {
75     return (flags & PARAMETER_FLAG) != 0;
76   }
77   
78   public final void setParameter (boolean parameter)
79   {
80     setFlag(parameter, PARAMETER_FLAG);
81   }
82
83   /** Assign a local variable to a given local variable slot.
84    * @param varIndex the index of the local variables.
85    * @return true iff we succeeded (i.e. the slot was unused) */

86   public boolean reserveLocal (int varIndex, CodeAttr code)
87   {
88     int size = getType().getSizeInWords();
89     if (code.locals.used == null)
90       code.locals.used = new Variable[20+size];
91     else if (code.getMaxLocals() + size >= code.locals.used.length) {
92       Variable[] new_locals = new Variable [2 * code.locals.used.length + size];
93       System.arraycopy (code.locals.used, 0, new_locals, 0, code.getMaxLocals());
94       code.locals.used = new_locals;
95     }
96     for (int j = 0; j < size; j++)
97       {
98     if (code.locals.used[varIndex+j] != null)
99       return false;
100       }
101     for (int j = 0; j < size; j++)
102       code.locals.used[varIndex + j] = this;
103     if (varIndex + size > code.getMaxLocals())
104       code.setMaxLocals(varIndex + size);
105     offset = varIndex;
106     flags |= LIVE_FLAG;
107     return true;
108   }
109
110   /**
111    * Allocate slots for a local variable (or parameter).
112    */

113   public void allocateLocal (CodeAttr code)
114   {
115     if (offset != UNASSIGNED)
116       return;
117     for (int i = 0; ; i++)
118       {
119     if (reserveLocal (i, code))
120       return;
121       }
122   }
123
124   public void freeLocal (CodeAttr code)
125   {
126     flags &= ~LIVE_FLAG;
127     int size = getType().size > 4 ? 2 : 1;
128     while (--size >= 0)
129       code.locals.used[offset + size] = null;
130   }
131
132   boolean shouldEmit ()
133   {
134     Scope sc = scope; // Cache
135
Label start, end;
136     int pos;
137     return (isSimple () && name != null && sc != null
138         && (start = sc.start) != null
139         && (pos = start.position) >= 0
140         && (end = sc.end) != null
141         && end.position > pos);
142   }
143
144   public String JavaDoc toString()
145   {
146     return "Variable["+getName()+" offset:"+offset+']';
147   }
148 }
149
Popular Tags