View Javadoc

1   // jq_InstanceMethod.java, created Mon Feb  5 23:23:20 2001 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Class;
5   
6   //friend jq_ClassLoader;
7   
8   import joeq.Main.jq;
9   import joeq.UTF.Utf8;
10  import jwutil.util.Assert;
11  
12  /*
13   * @author  John Whaley <jwhaley@alum.mit.edu>
14   * @version $Id: jq_InstanceMethod.java 1931 2004-09-22 22:17:47Z joewhaley $
15   */
16  public class jq_InstanceMethod extends jq_Method {
17  
18      // available after preparation
19      public static final int INVALID_OFFSET = 0x80000000;
20      private int offset;
21      private boolean isOverriding, isOverridden;
22      
23      // inherited: clazz, name, desc, access_flags, attributes
24      //            max_stack, max_locals, bytecode, exception_table, codeattribMap,
25      //            param_types, return_type
26      protected jq_InstanceMethod(jq_Class clazz, jq_NameAndDesc nd) {
27          super(clazz, nd);
28          offset = INVALID_OFFSET;
29      }
30      // ONLY TO BE CALLED BY jq_ClassLoader!!!
31      static jq_InstanceMethod newInstanceMethod(jq_Class clazz, jq_NameAndDesc nd) {
32          return new jq_InstanceMethod(clazz, nd);
33      }
34      protected void parseMethodSignature() {
35          Utf8.MethodDescriptorIterator i = nd.getDesc().getParamDescriptors();
36          // count them up
37          int num = 1, words = 1;
38          while (i.hasNext()) { i.nextUtf8(); ++num; }
39          // get them for real
40          param_types = new jq_Type[num];
41          param_types[0] = clazz;
42          i = nd.getDesc().getParamDescriptors();
43          for (int j=1; j<num; ++j) {
44              Utf8 pd = i.nextUtf8();
45              param_types[j] = PrimordialClassLoader.getOrCreateType(clazz.getClassLoader(), pd);
46              ++words;
47              if ((param_types[j] == jq_Primitive.LONG) ||
48                  (param_types[j] == jq_Primitive.DOUBLE)) ++words;
49          }
50          param_words = words;
51          Utf8 rd = i.getReturnDescriptor();
52          return_type = PrimordialClassLoader.getOrCreateType(clazz.getClassLoader(), rd);
53      }
54      public final void clearOverrideFlags() { this.isOverridden = false; this.isOverriding = false; }
55      public final void overriddenBy(jq_InstanceMethod that) {
56          this.isOverridden = true; that.isOverriding = true;
57      }
58      public final boolean isOverriding() { return isOverriding; }
59      public final boolean isOverridden() { return isOverridden; }
60      
61      public final jq_Member resolve() { return resolve1(); }
62      public jq_InstanceMethod resolve1() {
63          this.clazz.load();
64          if (this.state >= STATE_LOADED) return this;
65          // this reference may be to a superclass or superinterface.
66          jq_InstanceMethod m = this.clazz.getInstanceMethod(nd);
67          if (m != null) return m;
68          throw new NoSuchMethodError(this.toString());
69      }
70      
71      public final void prepare() { prepare(INVALID_OFFSET); }
72      public final void prepare(int offset) {
73          Assert._assert(state == STATE_LOADED); state = STATE_PREPARED; this.offset = offset;
74      }
75      public final int getOffset() { chkState(STATE_PREPARED); Assert._assert(offset != INVALID_OFFSET); return offset; }
76      public final boolean isVirtual() { chkState(STATE_PREPARED); return offset != INVALID_OFFSET; }
77      public final boolean needsDynamicLink(jq_Method method) {
78          if (!jq.RunningNative) return (state < STATE_PREPARED) || getDeclaringClass().needsDynamicLink(method);
79          /*
80          if (method.getDeclaringClass() == this.getDeclaringClass())
81              return false;
82              */
83          return state < STATE_SFINITIALIZED;
84      }
85      public final boolean isStatic() { return false; }
86      public final void unprepare() { chkState(STATE_PREPARED); offset = INVALID_OFFSET; state = STATE_LOADED; }
87      
88      public boolean isInitializer() { return false; }
89  
90      public void accept(jq_MethodVisitor mv) {
91          mv.visitInstanceMethod(this);
92          super.accept(mv);
93      }
94      
95      public static final jq_Class _class = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Class/jq_InstanceMethod;");
96  }