View Javadoc

1   // jq_Reference.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   import joeq.Allocator.ObjectLayout;
7   import joeq.Main.jq;
8   import joeq.Memory.HeapAddress;
9   import joeq.Runtime.Reflection;
10  import joeq.UTF.Utf8;
11  import jwutil.util.Assert;
12  
13  /*
14   * @author  John Whaley <jwhaley@alum.mit.edu>
15   * @version $Id: jq_Reference.java 1931 2004-09-22 22:17:47Z joewhaley $
16   */
17  public abstract class jq_Reference extends jq_Type implements jq_ClassFileConstants {
18  
19      public static final jq_Reference getTypeOf(Object o) {
20          if (!jq.RunningNative) return Reflection.getTypeOf(o);
21          return ((HeapAddress)HeapAddress.addressOf(o).offset(ObjectLayout.VTABLE_OFFSET).peek().peek()).asReferenceType();
22      }
23  
24      public final int getState() { return state; }
25      public final boolean isLoaded() { return state >= STATE_LOADED; }
26      public final boolean isVerified() { return state >= STATE_VERIFIED; }
27      public final boolean isPrepared() { return state >= STATE_PREPARED; }
28      public final boolean isSFInitialized() { return state >= STATE_SFINITIALIZED; }
29      public final boolean isCompiled() { return state >= STATE_COMPILED; }
30      public final boolean isClsInitRunning() { return state >= STATE_CLSINITRUNNING; }
31      public final boolean isClsInitialized() { return state >= STATE_CLSINITIALIZED; }
32      
33      public final boolean isPrimitiveType() { return false; }
34      public final boolean isIntLike() { return false; }
35      
36      public final ClassLoader getClassLoader() { return class_loader; }
37      public final int getReferenceSize() { return 4; }
38      public final Object getVTable() { chkState(STATE_PREPARED); return vtable; }
39      
40      public abstract String getJDKName();
41      public abstract jq_Class[] getInterfaces();
42      public abstract jq_Class getInterface(Utf8 desc);
43      public abstract boolean implementsInterface(jq_Class k);
44  
45      public abstract jq_InstanceMethod getVirtualMethod(jq_NameAndDesc nd);
46      
47      public abstract jq_Reference getDirectPrimarySupertype();
48      
49      public boolean isInstance(Object o) {
50          if (o == null) return false;
51          jq_Reference that = jq_Reference.getTypeOf(o);
52          return that.isSubtypeOf(this);
53      }
54      
55      public static final boolean TRACE = false;
56      
57      public final void chkState(byte s) {
58          if (state >= s) return;
59          Assert.UNREACHABLE(this+" actual state: "+state+" expected state: "+s);
60      }
61  
62      protected jq_Reference(Utf8 desc, ClassLoader class_loader) {
63          super(desc, class_loader);
64          Assert._assert(class_loader != null);
65          this.class_loader = class_loader;
66      }
67      protected Object vtable;
68      protected int/*byte*/ state; // use an 'int' so we can do cas4 on it
69      protected final ClassLoader class_loader;
70  
71      public static class jq_NullType extends jq_Reference {
72          private jq_NullType() {
73              super(Utf8.get("L&NULL;"), PrimordialClassLoader.loader);
74              this.state = STATE_CLSINITIALIZED;
75              this.display = new jq_Type[DISPLAY_SIZE+2];
76              this.s_s_array = new jq_Reference[0];
77              this.s_s_array_length = 0;
78          }
79          public boolean isAddressType() { return false; }
80          public String getJDKName() { return desc.toString(); }
81          public String getJDKDesc() { return getJDKName(); }
82          public jq_Class[] getInterfaces() { Assert.UNREACHABLE(); return null; }
83          public jq_Class getInterface(Utf8 desc) { Assert.UNREACHABLE(); return null; }
84          public boolean implementsInterface(jq_Class k) { Assert.UNREACHABLE(); return false; }
85          public jq_InstanceMethod getVirtualMethod(jq_NameAndDesc nd) { Assert.UNREACHABLE(); return null; }
86          public String getName() { Assert.UNREACHABLE(); return null; }
87          public String shortName() { return "NULL_TYPE"; }
88          public boolean isClassType() { Assert.UNREACHABLE(); return false; }
89          public boolean isArrayType() { Assert.UNREACHABLE(); return false; }
90          public boolean isFinal() { Assert.UNREACHABLE(); return false; }
91          public boolean isInstance(Object o) { return o == null; }
92          public int getDepth() { Assert.UNREACHABLE(); return 0; }
93          public jq_Reference getDirectPrimarySupertype() { Assert.UNREACHABLE(); return null; }
94          public void load() { }
95          public void verify() { }
96          public void prepare() { }
97          public void sf_initialize() { }
98          public void compile() { }
99          public void cls_initialize() { }
100         public String toString() { return "NULL_TYPE"; }
101         public static final jq_NullType NULL_TYPE = new jq_NullType();
102     }
103     
104     public static final jq_Class _class;
105     public static final jq_InstanceField _vtable;
106     public static /*final*/ jq_InstanceField _state; // set after PrimordialClassLoader finishes initialization
107     static {
108         _class = (jq_Class)PrimordialClassLoader.loader.getOrCreateBSType("Ljoeq/Class/jq_Reference;");
109         _vtable = _class.getOrCreateInstanceField("vtable", "Ljava/lang/Object;");
110         // primitive types have not yet been created!
111         _state = _class.getOrCreateInstanceField("state", "I");
112     }
113 }