Complete support for loading classes from a DEX file.

Change-Id: I1b9aa105fc78df170e83b259d8d04317c296a1b5
diff --git a/src/object.h b/src/object.h
index b7d3a50..e8d1ee1 100644
--- a/src/object.h
+++ b/src/object.h
@@ -4,6 +4,7 @@
 #define ART_SRC_OBJECT_H_
 
 #include "src/globals.h"
+#include "src/macros.h"
 
 namespace art {
 
@@ -14,29 +15,75 @@
 class InterfaceEntry;
 class Monitor;
 class Method;
+class Object;
 class SField;
 
+union JValue {
+  uint8_t z;
+  int8_t b;
+  uint16_t c;
+  int16_t s;
+  int32_t i;
+  int64_t j;
+  float f;
+  double d;
+  Object* l;
+};
+
+static const uint32_t kAccPublic = 0x0001; // class, field, method, ic
+static const uint32_t kAccPrivate = 0x0002; // field, method, ic
+static const uint32_t kAccProtected = 0x0004; // field, method, ic
+static const uint32_t kAccStatic = 0x0008; // field, method, ic
+static const uint32_t kAccFinal = 0x0010; // class, field, method, ic
+static const uint32_t kAccSynchronized = 0x0020; // method (only allowed on natives)
+static const uint32_t kAccSuper = 0x0020; // class (not used in Dalvik)
+static const uint32_t kAccVolatile = 0x0040; // field
+static const uint32_t kAccBridge = 0x0040; // method (1.5)
+static const uint32_t kAccTransient = 0x0080; // field
+static const uint32_t kAccVarargs = 0x0080; // method (1.5)
+static const uint32_t kAccNative = 0x0100; // method
+static const uint32_t kAccInterface = 0x0200; // class, ic
+static const uint32_t kAccAbstract = 0x0400; // class, method, ic
+static const uint32_t kAccStrict = 0x0800; // method
+static const uint32_t kAccSynthetic = 0x1000; // field, method, ic
+static const uint32_t kAccAnnotation = 0x2000; // class, ic (1.5)
+static const uint32_t kAccEnum = 0x4000; // class, field, ic (1.5)
+
+static const uint32_t kAccConstructor = 0x00010000; // method (Dalvik only)
+static const uint32_t kAccDeclaredSynchronized = 0x00020000; // method (Dalvik only)
+
+
 class Object {
+ public:
   Class* klass_;
   Monitor* lock_;
 };
 
 class Field {
+ public:
+  // The class in which this field is declared.
   Class* klass_;
+
+  const char* name_;
+
+  // e.g. "I", "[C", "Landroid/os/Debug;"
+  const char* signature_;
+
+  uint32_t access_flags_;
 };
 
 // Instance fields.
-class IField : Field {
-  // TODO
+class IField : public Field {
+  uint32_t offset_;
 };
 
 // Static fields.
-class SField : Field {
-  // TODO
+class SField : public Field {
+  JValue value_;
 };
 
 // Class objects.
-class Class : Object {
+class Class : public Object {
  public:
   enum ClassStatus {
     kClassError = -1,
@@ -60,6 +107,15 @@
     return OFFSETOF_MEMBER(Class, sfields_) + sizeof(SField) * num_sfields;
   }
 
+  uint32_t NumDirectMethods() {
+    return num_dmethods_;
+  }
+
+  uint32_t NumVirtualMethods() {
+    return num_vmethods_;
+  }
+
+
  public: // TODO: private
   // leave space for instance data; we could access fields directly if
   // we freeze the definition of java/lang/Class
@@ -76,7 +132,7 @@
   char* descriptor_alloc_;
 
   // access flags; low 16 bits are defined by VM spec
-  uint32_t access_flags_;
+  uint32_t access_flags_;  // TODO: make an instance field?
 
   // VM-unique class serial number, nonzero, set very early
   //uint32_t serial_number_;
@@ -101,7 +157,7 @@
   // For array classes, the class object for base element, for
   // instanceof/checkcast (for String[][][], this will be String).
   // Otherwise, NULL.
-  Class* array_element_class_;
+  Class* array_element_class_;  // TODO: make an instance field
 
   // For array classes, the number of array dimensions, e.g. int[][]
   // is 2.  Otherwise 0.
@@ -112,10 +168,10 @@
 
   // The superclass, or NULL if this is java.lang.Object or a
   // primitive type.
-  Class* super_;
+  Class* super_;  // TODO: make an instance field
 
   // defining class loader, or NULL for the "bootstrap" system loader
-  Object* class_loader_;
+  Object* class_loader_;  // TODO: make an instance field
 
   // initiating class loader list
   // NOTE: for classes with low serialNumber, these are unused, and the
@@ -127,12 +183,12 @@
   Class** interfaces_;
 
   // static, private, and <init> methods
-  int direct_method_count_;
-  Method* direct_methods_;
+  uint32_t num_dmethods_;
+  Method* dmethods_;
 
   // virtual methods defined in this class; invoked through vtable
-  int virtual_method_count_;
-  Method* virtual_methods_;
+  uint32_t num_vmethods_;
+  Method* vmethods_;
 
   // Virtual method table (vtable), for use by "invoke-virtual".  The
   // vtable from the superclass is copied in, and virtual methods from
@@ -172,8 +228,10 @@
   // All instance fields that refer to objects are guaranteed to be at
   // the beginning of the field list.  ifieldRefCount specifies the
   // number of reference fields.
-  int ifield_count_;
-  int ifield_ref_count_; // number of fields that are object refs
+  uint32_t num_ifields_;
+
+  // number of fields that are object refs
+  uint32_t num_reference_ifields_;
   IField* ifields_;
 
   // bitmap of offsets of ifields
@@ -183,7 +241,7 @@
   const char* source_file_;
 
   // Static fields
-  uint16_t num_sfields_;
+  uint32_t num_sfields_;
   SField sfields_[];  // MUST be last item
 };
 
@@ -206,7 +264,90 @@
 
 class Method {
  public:
-  Class* klass;
+  // Returns true if the method is declared public.
+  bool IsPublic() {
+    return (access_flags_ & kAccPublic) != 0;
+  }
+
+  // Returns true if the method is declared private.
+  bool IsPrivate() {
+    return (access_flags_ & kAccPrivate) != 0;
+  }
+
+  // Returns true if the method is declared static.
+  bool IsStatic() {
+    return (access_flags_ & kAccStatic) != 0;
+  }
+
+  // Returns true if the method is declared native and synchronized.
+  bool IsSynchronized() {
+    return (access_flags_ & kAccSynchronized) != 0;
+  }
+
+  // Returns true if the method is not native and declared synchronized.
+  bool IsDeclaredSynchronized() {
+    return (access_flags_ & kAccDeclaredSynchronized) != 0;
+  }
+
+  // Returns true if the method is declared final.
+  bool IsFinal() {
+    return (access_flags_ & kAccFinal) != 0;
+  }
+
+  // Returns true if the method is declared native.
+  bool IsNative() {
+    return (access_flags_ & kAccNative) != 0;
+  }
+
+  // Returns true if the method is declared abstract.
+  bool IsAbstract() {
+    return (access_flags_ & kAccAbstract) != 0;
+  }
+
+  bool IsSynthetic() {
+    return (access_flags_ & kAccSynthetic) != 0;
+  }
+
+  // Number of argument registers required by the prototype.
+  uint32_t NumArgRegisters();
+
+ public:  // TODO: private
+  // the class we are a part of
+  Class* klass_;
+
+  // access flags; low 16 bits are defined by spec (could be uint16_t?)
+  uint32_t access_flags_;
+
+  // For concrete virtual methods, this is the offset of the method
+  // in "vtable".
+  //
+  // For abstract methods in an interface class, this is the offset
+  // of the method in "iftable[n]->methodIndexArray".
+  uint16_t method_index_;
+
+  // Method bounds; not needed for an abstract method.
+  //
+  // For a native method, we compute the size of the argument list, and
+  // set "insSize" and "registerSize" equal to it.
+  uint16_t num_registers_;  // ins + locals
+  uint16_t num_outs_;
+  uint16_t num_ins_;
+
+  // method name, e.g. "<init>" or "eatLunch"
+  const char* name_;
+
+  // A pointer to the DEX file this class was loaded from or NULL for
+  // proxy objects.
+  DexFile* dex_file_;
+
+  // Method prototype descriptor string (return and argument types).
+  uint32_t proto_idx_;
+
+  // The short-form method descriptor string.
+  const char* shorty_;
+
+  // A pointer to the memory-mapped DEX code.
+  const uint16_t* insns_;
 };
 
 }  // namespace art