1 4 package gnu.bytecode; 5 6 public class Variable extends Location implements java.util.Enumeration 7 { 8 9 Variable next; 10 public final Variable nextVar () { return next; } 11 public final boolean hasMoreElements () { return next != null; } 12 public Object nextElement () 13 { 14 if (next == null) 15 throw new java.util.NoSuchElementException ("Variable enumeration"); 16 return next; 17 } 18 19 public Variable () 20 { 21 } 22 23 public Variable (String name) 24 { 25 setName(name); 26 } 27 28 public Variable (String name, Type type) 29 { 30 setName(name); 31 setType(type); 32 } 33 34 private int flags = SIMPLE_FLAG; 35 36 private static final int SIMPLE_FLAG = 0x1; 37 38 private static final int PARAMETER_FLAG = 0x2; 39 private static final int LIVE_FLAG = 0x4; 40 41 static final int UNASSIGNED = -1; 42 44 int offset = UNASSIGNED; 45 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 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 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 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; 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 toString() 145 { 146 return "Variable["+getName()+" offset:"+offset+']'; 147 } 148 } 149 | Popular Tags |