KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jas > CodeAttr


1 // CHANGES,
2
// Instead of calling soot.tagkits.JasminAttribute.decode,
3
// jas has its own CodeAttributeDecode class which performs
4
// the same functionality. It will remove the dependency to
5
// soot package. However, the decode method should be changed
6
// according to the format of CodeAttribute if the format is
7
// changed in the future.
8

9 // Feng Qian
10
// Jan 25, 2001
11

12 /**
13  * CodeAttr's are used as a bag to hold lists of instructions
14  * until it is time to put them into a Class.
15  * @see ClassEnv#addMethod
16  * @author $Author: olhota $
17  * @version $Revision: 1.2 $
18  */

19
20 package jas;
21
22 import java.io.*;
23 import java.util.*;
24
25 public class CodeAttr
26 {
27   static CP attr = new AsciiCP("Code");
28   short stack_size, num_locals;
29   int code_size;
30   Vector insns;
31     Hashtable insn_pc;
32   Catchtable ctb;
33   LineTableAttr ltab;
34   LocalVarTableAttr lvar;
35   Vector generic;
36
37
38     Vector sootAttrNames = new Vector();
39     Vector sootAttrValues = new Vector();
40     Hashtable labels;
41
42
43   /**
44    * Create a new bag. Add instructions with the addInsn() method,
45    * set the catch table with the setCatchTable() method.
46    * @see Insn
47    * @see Catchtable
48    * @see ClassEnv#addMethod
49    */

50
51   public CodeAttr()
52   {
53     this.stack_size = 1;
54     this.num_locals = 1;
55     this.ctb = null;
56     this.insns = new Vector();
57     generic = new Vector();
58   }
59   /**
60    * Set the catchtable for this code
61    */

62   public void setCatchtable(Catchtable ctb)
63   { this.ctb = ctb; }
64
65   /**
66    * Set the line number table for this method
67    */

68
69   public void setLineTable(LineTableAttr ltab)
70   { this.ltab = ltab; }
71
72   /**
73    * Set the local variable information for this method
74    */

75
76   public void setLocalVarTable(LocalVarTableAttr lvar)
77   { this.lvar = lvar; }
78
79   /**
80    * Add a generic attribute to the method. A generic attribute
81    * contains a stream of uninterpreted bytes which is ignored by
82    * the VM (as long as its name doesn't conflict with other names
83    * for attributes that are understood by the VM)
84    */

85     public void addGenericAttr(GenericAttr g)
86     { generic.addElement(g); }
87
88     
89     public void addSootCodeAttr(String JavaDoc name, String JavaDoc value)
90     {
91     sootAttrNames.addElement(name);
92     sootAttrValues.addElement(value);
93     }
94     
95
96     
97     Label getLabel(String JavaDoc name) {
98
99         Label lab = (Label)labels.get(name);
100         if (lab == null) {
101             lab = new Label(name);
102             labels.put(name, lab);
103         }
104         return lab;
105
106     }
107
108     public void setLabelTable(Hashtable labelTable)
109     {
110     labels = labelTable;
111     }
112
113
114     private int processSootAttributes() {
115     Hashtable labelToPc = new Hashtable();
116     int totalSize = 0;
117
118     
119     Enumeration enumeration = sootAttrValues.elements();
120     Enumeration nameEnum = sootAttrNames.elements();
121     while(enumeration.hasMoreElements()) {
122         String JavaDoc attrValue = (String JavaDoc) enumeration.nextElement();
123         String JavaDoc attrName = (String JavaDoc) nameEnum.nextElement();
124
125         boolean isLabel = false;//xx what if it starts with %
126

127
128         StringTokenizer st = new StringTokenizer(attrValue, "%", true);
129         while(st.hasMoreTokens()) {
130         String JavaDoc token = (String JavaDoc) st.nextElement();
131         if( token.equals( "%" ) ) {
132             isLabel = !isLabel;
133             continue;
134         }
135         if(isLabel) {
136             Integer JavaDoc i = (Integer JavaDoc) labelToPc.get(token);
137             
138             try {
139             if(i == null)
140             labelToPc.put(token, new Integer JavaDoc( getPc(getLabel(token))));
141             } catch(jas.jasError e) {throw new RuntimeException JavaDoc(e.toString());}
142         }
143         }
144         
145         byte[] data = CodeAttributeDecoder.decode(attrValue, labelToPc);
146         GenericAttr ga = new GenericAttr(attrName, data);
147         totalSize += ga.size();
148         addGenericAttr(ga);
149     }
150     sootAttrNames.removeAllElements();
151     sootAttrValues.removeAllElements();
152     return totalSize;
153     }
154
155     
156     
157
158
159
160
161
162
163
164   /**
165    * Append a new Insn to this code. Insn's are sequentially
166    * stored, in the order in which this method is called. You
167    * can't reorder code fragments after you've added it here.
168    */

169   public void addInsn(Insn insn)
170   { insns.addElement(insn); }
171
172   public void setStackSize(short stack_size)
173   { this.stack_size = stack_size; }
174   public void setVarSize(short num_vars)
175   { num_locals = num_vars; }
176
177   void resolve(ClassEnv e)
178   {
179                                 // propagate this resolution to
180
// the insns and catch table, so
181
// that any CP's referenced by them
182
// also get added.
183
e.addCPItem(attr);
184     for (Enumeration en = insns.elements(); en.hasMoreElements();)
185       {
186         Insn i = (Insn)(en.nextElement());
187         i.resolve(e);
188       }
189     if (ctb != null) ctb.resolve(e);
190     if (ltab != null) ltab.resolve(e);
191     if (lvar != null) lvar.resolve(e);
192     for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
193       {
194     GenericAttr gattr = (GenericAttr)gen.nextElement();
195     gattr.resolve(e);
196       }
197   }
198
199  public int getPc(Insn i)
200      throws jasError
201   {
202
203       if (insn_pc == null){
204
205       throw new jasError("Internal error, insn_pc has not been initialized");
206       }
207     Integer JavaDoc tmp;
208     if (i instanceof Label)
209       {
210         tmp = (Integer JavaDoc)(insn_pc.get(((Label)i).id));
211       }
212     else
213       {
214         tmp = (Integer JavaDoc)(insn_pc.get(i));
215       }
216     if (tmp == null)
217       throw new jasError(i + " has not been added to the code");
218     return tmp.intValue();
219   }
220
221   void write(ClassEnv e, DataOutputStream out)
222     throws IOException, jasError
223   {
224                                 // First, resolve all labels and
225
// compute total size
226
int code_size = 0;
227   
228     insn_pc = new Hashtable();
229     for (Enumeration en = insns.elements(); en.hasMoreElements();)
230       {
231         Insn now = (Insn)(en.nextElement());
232         if (now instanceof Label)
233           {
234             insn_pc.put(((Label)now).id, new Integer JavaDoc(code_size));
235           }
236         else
237           { insn_pc.put(now, new Integer JavaDoc(code_size)); }
238         code_size += now.size(e, this);
239       }
240     int total_size = code_size;
241     if (ctb != null) total_size += ctb.size();
242     if (ltab != null) total_size += ltab.size();
243     if (lvar != null) total_size += lvar.size();
244     for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
245       {
246     GenericAttr gattr = (GenericAttr)(gen.nextElement());
247     total_size += gattr.size();
248       }
249     
250     total_size += processSootAttributes();
251
252
253
254
255                                 // extra headers
256
total_size += 12;
257
258
259     out.writeShort(e.getCPIndex(attr));
260     out.writeInt(total_size);
261     out.writeShort(stack_size);
262     out.writeShort(num_locals);
263     out.writeInt(code_size);
264     for (Enumeration en = insns.elements(); en.hasMoreElements();)
265       {
266         Insn now = (Insn)(en.nextElement());
267         now.write(e, this, out);
268       }
269     if (ctb != null)
270       { ctb.write(e, this, out); }
271     else
272       { out.writeShort(0); }
273     short extra = 0;
274     if (ltab != null) extra++;
275     if (lvar != null) extra++;
276     extra += generic.size();
277     out.writeShort(extra);
278     if (ltab != null)
279       { ltab.write(e, this, out); }
280     if (lvar != null)
281       { lvar.write(e, this, out); }
282     for (Enumeration gen = generic.elements(); gen.hasMoreElements();)
283       {
284     GenericAttr gattr = (GenericAttr)gen.nextElement();
285     gattr.write(e, out);
286       }
287   }
288
289   public String JavaDoc toString()
290   { return ("<#code-attr>"); }
291 }
292
Popular Tags