KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > gnu > bytecode > Method


1 // Copyright (c) 1997 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 /**
8   * Represents a method in a <code>ClassType</code>.
9   * <p>
10   * A <code>Method</code> contain a <code>CodeAttr</code> object;
11   * the interface for generating bytecode instructions is primarily
12   * in <code>CodeAttr</code>.
13   * <p>
14   * All the methods whose name start with <code>compile_</code> are
15   * deprecated, and should not be used; use the methods
16   * in <code>CodeAttr</code>instead.
17   */

18
19 public class Method implements AttrContainer, Member {
20   private String JavaDoc name;
21   Type[] arg_types;
22   Type return_type;
23   int access_flags;
24   int name_index; /* Index in constant table, or 0 if un-assigned */
25   int signature_index; /* Index in constant table, or 0 if un-assigned */
26   Method next;
27   ClassType classfile;
28
29   Attribute attributes;
30   public final Attribute getAttributes () { return attributes; }
31   public final void setAttributes (Attribute attributes)
32   { this.attributes = attributes; }
33
34   ExceptionsAttr exceptions;
35   public final ExceptionsAttr getExceptionAttr () { return exceptions; }
36
37   public void setExceptions (short[] exn_indices)
38   {
39     if (exceptions == null)
40       exceptions = new ExceptionsAttr (this);
41     exceptions.setExceptions (exn_indices, classfile);
42   }
43
44   public void setExceptions (ClassType[] exn_types)
45   {
46     if (exceptions == null)
47       exceptions = new ExceptionsAttr(this);
48     exceptions.setExceptions(exn_types);
49   }
50
51   CodeAttr code;
52   public final CodeAttr getCode () { return code; }
53
54   Method (ClassType clfile, int flags)
55   {
56     if (clfile.last_method == null)
57        clfile.methods = this;
58     else
59       clfile.last_method.next = this;
60     clfile.last_method = this;
61     clfile.methods_count++;
62     access_flags = flags;
63     classfile = clfile;
64   }
65
66   public final void setStaticFlag (boolean is_static) {
67     if (is_static)
68       access_flags |= Access.STATIC;
69     else
70       access_flags ^= ~Access.STATIC;
71   }
72
73   public final boolean getStaticFlag () {
74     return (access_flags & Access.STATIC) != 0;
75   }
76
77   public final boolean isAbstract()
78   {
79     return (access_flags & Access.ABSTRACT) != 0;
80   }
81
82   public int getModifiers ()
83   {
84     return access_flags;
85   }
86
87   public void setModifiers (int modifiers)
88   {
89     access_flags = modifiers;
90   }
91
92   public final ConstantPool getConstants ()
93   {
94     return classfile.constants;
95   }
96     
97   public Scope pushScope () {
98     prepareCode(0);
99     return code.pushScope();
100   }
101
102   /** True if control could reach here. */
103   public final boolean reachableHere () { return code.reachableHere(); }
104
105   public Scope popScope () { return code.popScope(); }
106
107   /**
108    * Allocate slots for a local variable (or parameter).
109    * @param local the variable we need to allocate
110    * @deprecated
111    */

112   public void allocate_local (Variable local)
113   {
114     local.allocateLocal(code);
115   }
116
117   /** Allocate a Code attribute, and prepare to generate code.
118    * Most code generators should use the startCode convenience method. */

119   public void initCode ()
120   {
121     if (classfile.constants == null)
122       classfile.constants = new ConstantPool();
123     prepareCode(0);
124     code.sourceDbgExt = classfile.sourceDbgExt;
125     code.pushScope();
126   }
127
128   /**
129    * @deprecated Use startCode instead
130    */

131   public void init_param_slots ()
132   {
133     initCode ();
134     code.addParamLocals();
135   }
136
137   /** Recommended method to create a new CodeAttr for this Method. */
138   public CodeAttr startCode ()
139   {
140     initCode();
141     code.addParamLocals();
142     return code;
143   }
144
145   void kill_local (Variable var) { var.freeLocal(code); }
146
147   /** Method that must be called before we generate any instructions.
148     * Set so there is room for at least max_size bytes of code.
149     */

150   void prepareCode(int max_size)
151   {
152     if (code == null)
153       code = new CodeAttr(this);
154     code.reserve(max_size);
155   }
156
157   // This method should be called before we generate code for
158
// an instruction (or sequence).
159
// An upper bound of the intruction length is max_size.
160
// deprecated!
161
void instruction_start_hook (int max_size)
162   {
163     prepareCode(max_size);
164   }
165
166   final Type pop_stack_type () { return code.popType(); }
167   final void push_stack_type (Type type) { code.pushType(type); }
168
169   public void compile_checkcast (Type type)
170   {
171     code.emitCheckcast (type);
172   }
173
174   public void maybe_compile_checkcast (Type type)
175   {
176     Type stack_type = code.topType();
177     if (type != stack_type) // FIXME rather simple-minded, but safe.
178
code.emitCheckcast(type);
179   }
180
181   /**
182    * Comple code to push the contents of a local variable onto the statck.
183    * @param var The variable whose contents we want to push.
184    * @deprecated
185    */

186   public void push_var (Variable var) { code.emitLoad (var); }
187   /**
188    * @deprecated
189    */

190   public void compile_push_value (Variable var) { code.emitLoad(var); }
191
192   /**
193     * @deprecated
194    */

195   public void compile_store_value (Variable var)
196   {
197     code.emitStore(var);
198   }
199
200   public void compile_push_this ()
201   {
202     code.emitPushThis();
203   }
204
205   void write (DataOutputStream dstr, ClassType classfile)
206        throws java.io.IOException JavaDoc
207   {
208     dstr.writeShort (access_flags);
209     dstr.writeShort (name_index);
210     dstr.writeShort (signature_index);
211
212     Attribute.writeAll(this, dstr);
213   }
214
215   String JavaDoc signature;
216
217   public String JavaDoc getSignature ()
218   {
219     if (signature == null)
220       {
221     StringBuffer JavaDoc buf = new StringBuffer JavaDoc(100);
222     int args_count = arg_types.length;
223     buf.append('(');
224     for (int i = 0; i < args_count; i++)
225       buf.append (arg_types[i].getSignature());
226     buf.append(')');
227     buf.append(return_type.getSignature());
228     signature = buf.toString();
229       }
230     return signature;
231   }
232
233   public void setSignature (String JavaDoc signature)
234   {
235     int len = signature.length();
236     if (len < 3 || signature.charAt(0) != '(')
237       throw new ClassFormatError JavaDoc("bad method signature");
238     int pos = 1;
239     /* #ifdef JAVA5 */
240     // java.util.Stack<Type> types = new java.util.Stack<Type>();
241
/* #else */
242     java.util.Stack JavaDoc types = new java.util.Stack JavaDoc();
243     /* #endif */
244     for (;;)
245       {
246     int arg_sig_len = Type.signatureLength(signature, pos);
247     if (arg_sig_len < 0)
248       {
249         if (pos < len && signature.charAt(pos) == ')')
250           break;
251         throw new ClassFormatError JavaDoc("bad method signature");
252       }
253     Type arg_type = Type.signatureToType(signature, pos, arg_sig_len);
254     types.push(arg_type);
255     pos += arg_sig_len;
256       }
257     arg_types = new Type[types.size()];
258     for (int i = types.size(); --i >= 0; )
259       arg_types[i] = (Type) types.pop();
260     return_type = Type.signatureToType(signature, pos+1, len-pos-1);
261   }
262
263   public void setSignature (int signature_index)
264   {
265     CpoolUtf8 sigConstant = (CpoolUtf8)
266       getConstants().getForced(signature_index, ConstantPool.UTF8);
267     this.signature_index = signature_index;
268     setSignature(sigConstant.string);
269   }
270
271   void assignConstants ()
272   {
273     ConstantPool constants = getConstants();
274     if (name_index == 0 && name != null)
275       name_index = constants.addUtf8(name).index;
276     if (signature_index == 0)
277       signature_index = constants.addUtf8(getSignature()).index;
278     Attribute.assignConstants(this, classfile);
279   }
280
281   public ClassType getDeclaringClass() { return classfile; }
282
283   public final Type getReturnType() { return return_type; }
284
285   public final Type[] getParameterTypes() { return arg_types; }
286
287   public final ClassType[] getExceptions()
288   {
289     if (exceptions == null) return null;
290     return exceptions.getExceptions();
291   }
292
293   public final String JavaDoc getName ()
294   {
295     return name;
296   }
297
298   public final void setName(String JavaDoc name)
299   {
300     this.name = name;
301   }
302
303   public final void setName(int name_index)
304   {
305     if (name_index <= 0)
306       name = null;
307     else
308       {
309     CpoolUtf8 nameConstant = (CpoolUtf8)
310       getConstants().getForced(name_index, ConstantPool.UTF8);
311     name = nameConstant.string;
312       }
313     this.name_index = name_index;
314   }
315
316   public final Method getNext()
317   {
318     return next;
319   }
320
321   public void listParameters (StringBuffer JavaDoc sbuf)
322   {
323     int args_count = arg_types.length;
324     sbuf.append('(');
325     for (int i = 0; i < args_count; i++)
326       {
327         if (i > 0)
328           sbuf.append(',');
329         sbuf.append (arg_types[i].getName());
330       }
331     sbuf.append(')');
332   }
333
334   public String JavaDoc toString()
335   {
336     StringBuffer JavaDoc sbuf = new StringBuffer JavaDoc(100);
337     sbuf.append(getDeclaringClass().getName());
338     sbuf.append('.');
339     sbuf.append(name);
340     if (arg_types != null)
341       {
342         listParameters(sbuf);
343     sbuf.append(return_type.getName());
344       }
345     return sbuf.toString();
346   }
347
348   public void cleanupAfterCompilation ()
349   {
350     attributes = null;
351     exceptions = null;
352     code = null;
353   }
354 };
355
Popular Tags