KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > bytecode > CodeAttribute


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  *
23  * Free Software Foundation, Inc.
24  * 59 Temple Place, Suite 330
25  * Boston, MA 02111-1307 USA
26  *
27  * @author Scott Ferguson
28  */

29
30 package com.caucho.bytecode;
31
32 import com.caucho.log.Log;
33 import com.caucho.vfs.TempBuffer;
34 import com.caucho.vfs.TempStream;
35 import com.caucho.vfs.WriteStream;
36
37 import java.io.IOException JavaDoc;
38 import java.util.ArrayList JavaDoc;
39 import java.util.logging.Logger JavaDoc;
40
41 /**
42  * Represents a generic attribute
43  */

44 public class CodeAttribute extends Attribute {
45   static private final Logger JavaDoc log = Log.open(CodeAttribute.class);
46
47   private int _maxStack;
48   private int _maxLocals;
49   private byte []_code;
50   private ArrayList JavaDoc<ExceptionItem> _exceptions =
51     new ArrayList JavaDoc<ExceptionItem>();
52   
53   private ArrayList JavaDoc<Attribute> _attributes = new ArrayList JavaDoc<Attribute>();
54
55   public CodeAttribute()
56   {
57     super("Code");
58   }
59
60   CodeAttribute(String JavaDoc name)
61   {
62     super(name);
63   }
64
65   /**
66    * Returns the max locals.
67    */

68   public int getMaxLocals()
69   {
70     return _maxLocals;
71   }
72
73   /**
74    * Sets the max locals.
75    */

76   public void setMaxLocals(int max)
77   {
78     _maxLocals = max;
79   }
80
81   /**
82    * Returns the max stack.
83    */

84   public int getMaxStack()
85   {
86     return _maxStack;
87   }
88
89   /**
90    * Sets the max stack.
91    */

92   public void setMaxStack(int max)
93   {
94     _maxStack = max;
95   }
96
97   /**
98    * Sets the code value.
99    */

100   public void setCode(byte []code)
101   {
102     _code = code;
103   }
104
105   /**
106    * Gets the code value.
107    */

108   public byte []getCode()
109   {
110     return _code;
111   }
112
113   /**
114    * Adds an attribute.
115    */

116   public void addAttribute(Attribute attr)
117   {
118     _attributes.add(attr);
119   }
120
121   /**
122    * Returns the exceptions.
123    */

124   public ArrayList JavaDoc<Attribute> getAttributes()
125   {
126     return _attributes;
127   }
128
129   /**
130    * Returns the exceptions.
131    */

132   public void setAttributes(ArrayList JavaDoc<Attribute> attributes)
133   {
134     if (_attributes != attributes) {
135       _attributes.clear();
136       _attributes.addAll(attributes);
137     }
138   }
139
140   /**
141    * Removes an attribute.
142    */

143   public Attribute removeAttribute(String JavaDoc name)
144   {
145     for (int i = _attributes.size() - 1; i >= 0; i--) {
146       Attribute attr = _attributes.get(i);
147
148       if (attr.getName().equals(name)) {
149     _attributes.remove(i);
150     return attr;
151       }
152     }
153
154     return null;
155   }
156
157   /**
158    * Returns the exceptions.
159    */

160   public ArrayList JavaDoc<ExceptionItem> getExceptions()
161   {
162     return _exceptions;
163   }
164
165   /**
166    * Returns the exceptions.
167    */

168   public void addException(ClassConstant type, int start, int end, int handler)
169   {
170     _exceptions.add(new ExceptionItem(type.getIndex(), start, end, handler));
171   }
172
173   /**
174    * Writes the field to the output.
175    */

176   public void read(ByteCodeParser in)
177     throws IOException JavaDoc
178   {
179     int length = in.readInt();
180     
181     _maxStack = in.readShort();
182     _maxLocals = in.readShort();
183
184     int codeLength = in.readInt();
185
186     _code = new byte[codeLength];
187     in.read(_code, 0, codeLength);
188
189     int exnCount = in.readShort();
190
191     for (int i = 0; i < exnCount; i++) {
192       ExceptionItem exn = new ExceptionItem();
193
194       exn.setStart(in.readShort() & 0xffff);
195       exn.setEnd(in.readShort() & 0xffff);
196       exn.setHandler(in.readShort() & 0xffff);
197       exn.setType(in.readShort() & 0xffff);
198
199       _exceptions.add(exn);
200     }
201
202     int attrCount = in.readShort();
203
204     for (int i = 0; i < attrCount; i++) {
205       Attribute attr = in.parseAttribute();
206
207       _attributes.add(attr);
208     }
209   }
210
211   /**
212    * Writes the field to the output.
213    */

214   public void write(ByteCodeWriter out)
215     throws IOException JavaDoc
216   {
217     out.writeUTF8Const(getName());
218
219     TempStream ts = new TempStream();
220     ts.openWrite();
221     WriteStream ws = new WriteStream(ts);
222     ByteCodeWriter o2 = new ByteCodeWriter(ws, out.getJavaClass());
223     
224     o2.writeShort(_maxStack);
225     o2.writeShort(_maxLocals);
226     o2.writeInt(_code.length);
227     o2.write(_code, 0, _code.length);
228
229     o2.writeShort(_exceptions.size());
230     for (int i = 0; i < _exceptions.size(); i++) {
231       ExceptionItem exn = _exceptions.get(i);
232
233       o2.writeShort(exn.getStart());
234       o2.writeShort(exn.getEnd());
235       o2.writeShort(exn.getHandler());
236       o2.writeShort(exn.getType());
237     }
238
239     o2.writeShort(_attributes.size());
240     for (int i = 0; i < _attributes.size(); i++) {
241       Attribute attr = _attributes.get(i);
242
243       attr.write(o2);
244     }
245     
246     ws.close();
247     
248     out.writeInt(ts.getLength());
249     TempBuffer ptr = ts.getHead();
250
251     for (; ptr != null; ptr = ptr.getNext())
252       out.write(ptr.getBuffer(), 0, ptr.getLength());
253
254     ts.destroy();
255   }
256
257   /**
258    * Clones the attribute
259    */

260   public Attribute export(JavaClass source, JavaClass target)
261   {
262     ConstantPool cp = target.getConstantPool();
263
264     cp.addUTF8(getName());
265     
266     CodeAttribute attr = new CodeAttribute(getName());
267
268     attr._maxStack = _maxStack;
269     attr._maxLocals = _maxLocals;
270
271     byte []code = new byte[_code.length];
272     System.arraycopy(_code, 0, code, 0, _code.length);
273     attr._code = code;
274
275     for (int i = 0; i < _exceptions.size(); i++) {
276       ExceptionItem exn = _exceptions.get(i);
277
278       int type = exn.getType();
279       
280       if (type != 0)
281     type = cp.addClass(source.getConstantPool().getClass(type).getName()).getIndex();
282
283       ExceptionItem newExn = new ExceptionItem(type,
284                            exn.getStart(),
285                            exn.getEnd(),
286                            exn.getHandler());
287     
288       attr._exceptions.add(newExn);
289     }
290
291     for (int i = 0; i < _attributes.size(); i++) {
292       Attribute codeAttr = _attributes.get(i);
293
294       attr.addAttribute(codeAttr.export(source, target));
295     }
296
297     try {
298       attr.exportCode(source, target);
299     } catch (Exception JavaDoc e) {
300       throw new RuntimeException JavaDoc(e);
301     }
302
303     return attr;
304   }
305
306   /**
307    * Exports code.
308    */

309   public void exportCode(JavaClass source, JavaClass target)
310     throws Exception JavaDoc
311   {
312     ExportAnalyzer analyzer = new ExportAnalyzer(source, target);
313
314     CodeEnhancer visitor = new CodeEnhancer(source, this);
315
316     visitor.analyze(analyzer, false);
317
318     visitor.update();
319   }
320
321   public String JavaDoc toString()
322   {
323     return "CodeAttribute[" + getName() + "]";
324   }
325
326   public static class ExceptionItem {
327     private int _type;
328     
329     private int _start;
330     private int _end;
331     private int _handler;
332
333     public ExceptionItem()
334     {
335     }
336
337     public ExceptionItem(int type, int start, int end, int handler)
338     {
339       _type = type;
340       _start = start;
341       _end = end;
342       _handler = handler;
343     }
344
345     /**
346      * Sets the exception type.
347      */

348     public void setType(int type)
349     {
350       _type = type;
351     }
352
353     /**
354      * Returns the exception type.
355      */

356     public int getType()
357     {
358       return _type;
359     }
360
361     /**
362      * Sets the start PC
363      */

364     public void setStart(int pc)
365     {
366       _start = pc;
367     }
368
369     /**
370      * Gets the start PC
371      */

372     public int getStart()
373     {
374       return _start;
375     }
376
377     /**
378      * Sets the end PC
379      */

380     public void setEnd(int pc)
381     {
382       _end = pc;
383     }
384
385     /**
386      * Gets the end PC
387      */

388     public int getEnd()
389     {
390       return _end;
391     }
392
393     /**
394      * Sets the handler PC
395      */

396     public void setHandler(int pc)
397     {
398       _handler = pc;
399     }
400
401     /**
402      * Gets the handler PC
403      */

404     public int getHandler()
405     {
406       return _handler;
407     }
408   }
409
410   public static class ExportAnalyzer extends Analyzer {
411     private JavaClass _source;
412     private JavaClass _target;
413     
414     public ExportAnalyzer(JavaClass source, JavaClass target)
415     {
416       _source = source;
417       _target = target;
418     }
419
420     public void analyze(CodeVisitor visitor)
421       throws Exception JavaDoc
422     {
423       int op = visitor.getOpcode();
424       int index;
425       ConstantPool sourcePool = _source.getConstantPool();
426       ConstantPool targetPool = _target.getConstantPool();
427       ConstantPoolEntry entry;
428
429       switch (op) {
430       case CodeVisitor.ANEWARRAY:
431       case CodeVisitor.CHECKCAST:
432       case CodeVisitor.GETFIELD:
433       case CodeVisitor.GETSTATIC:
434       case CodeVisitor.INSTANCEOF:
435       case CodeVisitor.INVOKEINTERFACE:
436       case CodeVisitor.INVOKESPECIAL:
437       case CodeVisitor.INVOKESTATIC:
438       case CodeVisitor.INVOKEVIRTUAL:
439       case CodeVisitor.LDC_W:
440       case CodeVisitor.LDC2_W:
441       case CodeVisitor.MULTIANEWARRAY:
442       case CodeVisitor.NEW:
443       case CodeVisitor.PUTFIELD:
444       case CodeVisitor.PUTSTATIC:
445     index = visitor.getShortArg(1);
446     
447     entry = sourcePool.getEntry(index);
448     int targetIndex = entry.export(targetPool);
449
450     visitor.setShortArg(1, targetIndex);
451     break;
452
453       case CodeVisitor.LDC:
454     index = visitor.getByteArg(1);
455     entry = sourcePool.getEntry(index);
456     index = entry.export(targetPool);
457     if (index <= 0xff)
458       visitor.setByteArg(1, index);
459     else {
460       CodeEnhancer enhancer = (CodeEnhancer) visitor;
461       enhancer.setByteArg(0, CodeVisitor.LDC_W);
462       enhancer.addByte(enhancer.getOffset() + 2, 0);
463       enhancer.setShortArg(1, index);
464     }
465     break;
466
467       default:
468     break;
469       }
470     }
471   }
472 }
473
Popular Tags