1 4 package gnu.bytecode; 5 import java.io.*; 6 7 18 19 public class Method implements AttrContainer, Member { 20 private String name; 21 Type[] arg_types; 22 Type return_type; 23 int access_flags; 24 int name_index; 25 int signature_index; 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 103 public final boolean reachableHere () { return code.reachableHere(); } 104 105 public Scope popScope () { return code.popScope(); } 106 107 112 public void allocate_local (Variable local) 113 { 114 local.allocateLocal(code); 115 } 116 117 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 131 public void init_param_slots () 132 { 133 initCode (); 134 code.addParamLocals(); 135 } 136 137 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 150 void prepareCode(int max_size) 151 { 152 if (code == null) 153 code = new CodeAttr(this); 154 code.reserve(max_size); 155 } 156 157 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) code.emitCheckcast(type); 179 } 180 181 186 public void push_var (Variable var) { code.emitLoad (var); } 187 190 public void compile_push_value (Variable var) { code.emitLoad(var); } 191 192 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 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 signature; 216 217 public String getSignature () 218 { 219 if (signature == null) 220 { 221 StringBuffer buf = new StringBuffer (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 signature) 234 { 235 int len = signature.length(); 236 if (len < 3 || signature.charAt(0) != '(') 237 throw new ClassFormatError ("bad method signature"); 238 int pos = 1; 239 240 242 java.util.Stack types = new java.util.Stack (); 243 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 ("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 getName () 294 { 295 return name; 296 } 297 298 public final void setName(String 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 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 toString() 335 { 336 StringBuffer sbuf = new StringBuffer (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 |