KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > LocalVarsAttr


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 import java.io.*;
6
7 /* Represents the contents of a standard "LocalVariableTable" attribute.
8  * @author Per Bothner
9  */

10
11 public class LocalVarsAttr extends Attribute
12 {
13   private Method method;
14
15   /* Map local slot index to the local variable that is there. */
16   Variable[] used;
17   public Scope current_scope;
18   Scope parameter_scope;
19
20   /** Add a new LocalVarsAttr to a CodeAttr. */
21   public LocalVarsAttr(CodeAttr code)
22   {
23     super("LocalVariableTable");
24     addToFrontOf(code);
25     method = (Method) code.getContainer();
26     code.locals = this;
27   }
28
29   /** Create, but don't link into method.code's attributes list (yet). */
30   public LocalVarsAttr(Method method)
31   {
32     super("LocalVariableTable");
33     CodeAttr code = method.code;
34     this.method = method;
35     code.locals = this;
36   }
37
38   public final Method getMethod() { return method; }
39
40   public VarEnumerator allVars ()
41   {
42     return new VarEnumerator (parameter_scope);
43   }
44
45   public void enterScope (Scope scope) {
46     scope.linkChild (current_scope);
47     current_scope = scope;
48     CodeAttr code = method.getCode();
49     for (Variable var = scope.firstVar (); var != null; var = var.nextVar ())
50       {
51     if (var.isSimple ())
52       {
53         if (! var.isAssigned ())
54           var.allocateLocal(code);
55         else if (used[var.offset] == null)
56           used[var.offset] = var;
57         else if (used[var.offset] != var)
58           throw new Error JavaDoc ("inconsistent local variable assignments for "
59 +var+" != "+used[var.offset]);
60       }
61       }
62   }
63
64   /** Mark scopes upto specified scope as 'preserved'.
65    * This means that the local variable slots are not available for reuse
66    * when the scope exits. The effected scopes are all ancestor scopes from
67    * the current scope (inclusive) upto the specified scope (exclusive). */

68   public void preserveVariablesUpto(Scope scope)
69   {
70     for (Scope cur = current_scope; cur != scope; cur = cur.parent)
71       cur.preserved = true;
72   }
73
74   public final boolean isEmpty ()
75   {
76     VarEnumerator vars = allVars();
77     Variable var;
78     while ((var = vars.nextVar ()) != null)
79       {
80     if (var.isSimple () && var.name != null)
81           return false;
82       }
83     return true;
84   }
85
86   public final int getCount ()
87   {
88     int local_variable_count = 0;
89     VarEnumerator vars = allVars();
90     Variable var;
91     while ((var = vars.nextVar ()) != null)
92       {
93     if (var.shouldEmit())
94       local_variable_count++;
95       }
96     return local_variable_count;
97   }
98
99   public final int getLength()
100   {
101     return 2 + 10 * getCount();
102   }
103
104   public void assignConstants (ClassType cl)
105   {
106     super.assignConstants(cl);
107
108     VarEnumerator vars = allVars ();
109     Variable var;
110     while ((var = vars.nextVar ()) != null)
111       {
112     if (var.isSimple () && var.name != null)
113       {
114         if (var.name_index == 0)
115           var.name_index = cl.getConstants().addUtf8(var.getName()).index;
116         if (var.signature_index == 0)
117           var.signature_index
118         = cl.getConstants().addUtf8(var.getType().signature).index;
119       }
120       }
121   }
122
123   public void write (DataOutputStream dstr) throws java.io.IOException JavaDoc
124   {
125     VarEnumerator vars = allVars ();
126     Variable var;
127     dstr.writeShort (getCount());
128         
129     for (vars.reset (); (var = vars.nextVar ()) != null; )
130       {
131     if (var.shouldEmit())
132       {
133         Scope scope = var.scope;
134         int start_pc = scope.start.position;
135         int end_pc = scope.end.position;
136         dstr.writeShort(start_pc);
137         dstr.writeShort(end_pc - start_pc);
138         dstr.writeShort(var.name_index);
139         dstr.writeShort(var.signature_index);
140         dstr.writeShort(var.offset);
141       }
142       }
143   }
144
145   public void print (ClassTypeWriter dst)
146   {
147     VarEnumerator vars = allVars ();
148     dst.print("Attribute \"");
149     dst.print(getName());
150     dst.print("\", length:");
151     dst.print(getLength());
152     dst.print(", count: ");
153     dst.println(getCount());
154         
155     Variable var;
156     for (vars.reset (); (var = vars.nextVar ()) != null; )
157       {
158     if (var.isSimple () && var.name != null)
159       {
160         dst.print(" slot#");
161         dst.print(var.offset);
162         dst.print(": name: ");
163         dst.printOptionalIndex(var.name_index);
164         dst.print(var.getName());
165         dst.print(", type: ");
166         dst.printOptionalIndex(var.signature_index);
167         dst.printSignature(var.getType());
168         dst.print(" (pc: ");
169         Scope scope = var.scope;
170         int start_pc, end_pc;
171         if (scope == null || scope.start == null || scope.end == null
172         || (start_pc = scope.start.position) < 0
173         || (end_pc = scope.end.position) < 0)
174           dst.print("unknown");
175         else
176           {
177         dst.print(start_pc);
178         dst.print(" length: ");
179         dst.print(end_pc - start_pc);
180           }
181         dst.println(')');
182       }
183       }
184   }
185 }
186
Popular Tags