//===-------- JavaClass.h - Java class representation -------------------===//
//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#ifndef JNJVM_JAVA_CLASS_H
#define JNJVM_JAVA_CLASS_H


#include "types.h"

#include "mvm/Allocator.h"
#include "mvm/MethodInfo.h"
#include "mvm/Object.h"
#include "mvm/Threads/Cond.h"
#include "mvm/Threads/Locks.h"

#include "JavaAccess.h"
#include "JavaObject.h"
#include "JnjvmClassLoader.h"
#include "JnjvmConfig.h"

#include <cassert>
#include <set>

namespace j3 {

class ArrayObject;
class ArrayUInt8;
class ArrayUInt16;
class Class;
class ClassArray;
class JavaArray;
class JavaConstantPool;
class JavaField;
class JavaMethod;
class JavaObject;
class JavaVirtualTable;
class Reader;
class Signdef;
class Typedef;


/// JavaState - List of states a Java class can have. A class is ready to be
/// used (i.e allocating instances of the class, calling methods of the class
/// and accessing static fields of the class) when it is in the ready state.
///
#define loaded 0       /// The .class file has been found.
#define classRead 1    /// The .class file has been read.
#define resolved 2     /// The class has been resolved.
#define vmjc 3         /// The class is defined in a shared library.
#define inClinit 4     /// The class is cliniting.
#define ready 5        /// The class is ready to be used.
#define erroneous 6    /// The class is in an erroneous state.


class AnnotationReader {
public:
  Reader& reader;
  Class* cl;
  uint16 AnnotationNameIndex;

  AnnotationReader(Reader& R, Class* C) : reader(R), cl(C),
    AnnotationNameIndex(0) {}
  void readAnnotation();
  void readElementValue();
};

/// Attribut - This class represents JVM attributes to Java class, methods and
/// fields located in the .class file.
///
class Attribut : public mvm::PermanentObject {
public:
  
  /// name - The name of the attribut. These are specified in the JVM book.
  /// Experimental attributes exist, but the JnJVM does nor parse them.
  ///
  const UTF8* name;

  /// start - The offset in the class of this attribut.
  ///
  uint32 start;

  /// nbb - The size of the attribut.
  ///
  uint32 nbb;

  /// Attribut - Create an attribut at the given length and offset.
  ///
  Attribut(const UTF8* name, uint32 length, uint32 offset);
  Attribut() {}

  /// codeAttribut - The "Code" JVM attribut. This is a method attribut for
  /// finding the bytecode of a method in the .class file.
  //
  static const UTF8* codeAttribut;
  
  /// annotationsAttribut - The "RuntimeVisibleAnnotations" JVM attribut.
  /// This is a method attribut for getting the runtime annotations.
  //
  static const UTF8* annotationsAttribut;

  /// exceptionsAttribut - The "Exceptions" attribut. This is a method
  /// attribut for finding the exception table of a method in the .class
  /// file.
  ///
  static const UTF8* exceptionsAttribut;

  /// constantAttribut - The "ConstantValue" attribut. This is a field attribut
  /// when the field has a static constant value.
  ///
  static const UTF8* constantAttribut;

  /// lineNumberTableAttribut - The "LineNumberTable" attribut. This is used
  /// for corresponding JVM bytecode to source line in the .java file.
  ///
  static const UTF8* lineNumberTableAttribut;

  /// innerClassAttribut - The "InnerClasses" attribut. This is a class attribut
  /// for knowing the inner/outer informations of a Java class.
  ///
  static const UTF8* innerClassesAttribut;

  /// sourceFileAttribut - The "SourceFile" attribut. This is a class attribut
  /// and gives the correspondance between a class and the name of its Java
  /// file.
  ///
  static const UTF8* sourceFileAttribut;
  
};

/// TaskClassMirror - The isolate specific class information: the initialization
/// state and the static instance. In a non-isolate environment, there is only
/// one instance of a TaskClassMirror per Class.
class TaskClassMirror {
public:
  
  /// status - The state.
  ///
  uint8 status;

  /// initialized - Is the class initialized?
  bool initialized;

  /// staticInstance - Memory that holds the static variables of the class.
  ///
  void* staticInstance;
};

/// CommonClass - This class is the root class of all Java classes. It is
/// GC-allocated because CommonClasses have to be traceable. A java/lang/Class
/// object that stays in memory has a reference to the class. Same for
/// super or interfaces.
///
class CommonClass : public mvm::PermanentObject {
#ifdef ISOLATE_SHARING
friend class UserCommonClass;
#endif

public:
  
//===----------------------------------------------------------------------===//
//
// If you want to add new fields or modify the types of fields, you must also
// change their LLVM representation in LLVMRuntime/runtime-*.ll, and their
// offsets in JnjvmModule.cpp.
//
//===----------------------------------------------------------------------===//
 
  /// delegatees - The java/lang/Class delegatee.
  ///
  JavaObject* delegatee[NR_ISOLATES];

  /// access - {public, private, protected}.
  ///
  uint16 access;
  
  /// interfaces - The interfaces this class implements.
  ///
  Class** interfaces; 
  uint16 nbInterfaces;
  
  /// name - The name of the class.
  ///
  const UTF8* name;
   
  /// super - The parent of this class.
  ///
  Class * super;
   
  /// classLoader - The Jnjvm class loader that loaded the class.
  ///
  JnjvmClassLoader* classLoader;
  
  /// virtualVT - The virtual table of instances of this class.
  ///
  JavaVirtualTable* virtualVT;
  

//===----------------------------------------------------------------------===//
//
// End field declaration.
//
//===----------------------------------------------------------------------===//

  bool isSecondaryClass() {
    return virtualVT->offset == JavaVirtualTable::getCacheIndex();
  }

  // Assessor methods.
  uint32 getAccess() const      { return access; }
  Class** getInterfaces() const { return interfaces; }
  const UTF8* getName() const   { return name; }
  Class* getSuper() const       { return super; }
  
  /// isArray - Is the class an array class?
  ///
  bool isArray() const {
    return j3::isArray(access);
  }
  
  /// isPrimitive - Is the class a primitive class?
  ///
  bool isPrimitive() const {
    return j3::isPrimitive(access);
  }
  
  /// isInterface - Is the class an interface?
  ///
  bool isInterface() const {
    return j3::isInterface(access);
  }
  
  /// isClass - Is the class a real, instantiable class?
  ///
  bool isClass() const {
    return j3::isClass(access);
  }

  /// asClass - Returns the class as a user-defined class
  /// if it is not a primitive or an array.
  ///
  UserClass* asClass() {
    if (isClass()) return (UserClass*)this;
    return 0;
  }
  
  /// asClass - Returns the class as a user-defined class
  /// if it is not a primitive or an array.
  ///
  const UserClass* asClass() const {
    if (isClass()) return (const UserClass*)this;
    return 0;
  }
  
  /// asPrimitiveClass - Returns the class if it's a primitive class.
  ///
  UserClassPrimitive* asPrimitiveClass() {
    if (isPrimitive()) return (UserClassPrimitive*)this;
    return 0;
  }
  
  const UserClassPrimitive* asPrimitiveClass() const {
    if (isPrimitive()) return (const UserClassPrimitive*)this;
    return 0;
  }
  
  /// asArrayClass - Returns the class if it's an array class.
  ///
  UserClassArray* asArrayClass() {
    if (isArray()) return (UserClassArray*)this;
    return 0;
  }
  
  const UserClassArray* asArrayClass() const {
    if (isArray()) return (const UserClassArray*)this;
    return 0;
  }

  /// tracer - The tracer of this GC-allocated class.
  ///
  void tracer();
  
  /// inheritName - Does this class in its class hierarchy inherits
  /// the given name? Equality is on the name. This function does not take
  /// into account array classes.
  ///
  bool inheritName(const uint16* buf, uint32 len);

  /// isOfTypeName - Does this class inherits the given name? Equality is on
  /// the name. This function takes into account array classes.
  ///
  bool isOfTypeName(const UTF8* Tname);

  /// isAssignableFrom - Is this class assignable from the given class? The
  /// classes may be of any type.
  ///
  bool isAssignableFrom(CommonClass* cl);

  /// getClassDelegatee - Return the java/lang/Class representation of this
  /// class.
  ///
  JavaObject* getClassDelegatee(Jnjvm* vm, JavaObject* pd = 0);
  
  /// getClassDelegateePtr - Return a pointer on the java/lang/Class
  /// representation of this class. Used for JNI.
  ///
  JavaObject* const* getClassDelegateePtr(Jnjvm* vm, JavaObject* pd = 0);
  
  /// CommonClass - Create a class with th given name.
  ///
  CommonClass(JnjvmClassLoader* loader, const UTF8* name);
  
  /// ~CommonClass - Free memory used by this class, and remove it from
  /// metadata.
  ///
  ~CommonClass();

  /// setInterfaces - Set the interfaces of the class.
  ///
  void setInterfaces(Class** I) {
    interfaces = I;
  }
 
  /// toPrimitive - Returns the primitive class which represents
  /// this class, ie void for java/lang/Void.
  ///
  UserClassPrimitive* toPrimitive(Jnjvm* vm) const;
 
  /// getInternal - Return the class.
  ///
  CommonClass* getInternal() {
    return this;
  }
 
  /// setDelegatee - Set the java/lang/Class object of this class.
  ///
  JavaObject* setDelegatee(JavaObject* val);

#if !defined(ISOLATE) && !defined(ISOLATE_SHARING)
  /// getDelegatee - Get the java/lang/Class object representing this class.
  ///
  JavaObject* getDelegatee() const {
    return delegatee[0];
  }
  
  /// getDelegatee - Get a pointer on the java/lang/Class object
  /// representing this class.
  ///
  JavaObject* const* getDelegateePtr() const {
    return delegatee;
  }

#else
#if defined(ISOLATE)
  JavaObject* getDelegatee();
  JavaObject** getDelegateePtr();
#endif
#endif
  
  /// resolvedImplClass - Return the internal representation of the
  /// java.lang.Class object. The class must be resolved.
  //
  static UserCommonClass* resolvedImplClass(Jnjvm* vm, JavaObject* delegatee,
                                            bool doClinit);
#ifdef USE_GC_BOEHM
  void* operator new(size_t sz, mvm::BumpPtrAllocator& allocator) {
    return GC_MALLOC(sz);
  }
#endif

};

/// ClassPrimitive - This class represents internal classes for primitive
/// types, e.g. java/lang/Integer.TYPE.
///
class ClassPrimitive : public CommonClass {
public:
  
  /// logSize - The log size of this class, eg 2 for int.
  ///
  uint32 logSize;
  
  
  /// ClassPrimitive - Constructs a primitive class. Only called at boot
  /// time.
  ///
  ClassPrimitive(JnjvmClassLoader* loader, const UTF8* name, uint32 nb);

  /// byteIdToPrimitive - Get the primitive class from its byte representation,
  /// ie int for I.
  ///
  static UserClassPrimitive* byteIdToPrimitive(char id, Classpath* upcalls);
  
};


/// Class - This class is the representation of Java regular classes (i.e not
/// array or primitive). Theses classes have a constant pool.
///
class Class : public CommonClass {

private:
 
  /// FatLock - This class is the inflated lock of Class instances. It should
  /// be very rare that such locks are allocated.
  class FatLock : public mvm::PermanentObject {
  public:
    /// lockVar - When multiple threads want to load/resolve/initialize a class,
    /// they must be synchronized so that these steps are only performed once
    /// for a given class.
    mvm::LockRecursive lockVar;

    /// condVar - Used to wake threads waiting on the load/resolve/initialize
    /// process of this class, done by another thread.
    mvm::Cond condVar;
  
    bool owner() {
      return lockVar.selfOwner();
    }

    mvm::Thread* getOwner() {
      return lockVar.getOwner();
    }

    static FatLock* allocate(UserCommonClass* cl) {
      return new(cl->classLoader->allocator, "Class fat lock") FatLock();
    }
   
    uintptr_t getID() {
      return (((uintptr_t)this) >> 1) | mvm::FatMask;
    }

    static FatLock* getFromID(uintptr_t id) {
      return (FatLock*)(id << 1);
    }
    
    void deallocate() {
      // Too bad, I can't deallocate it because it is in permanent memory.
    }

    bool acquire(CommonClass* cl) {
      lockVar.lock();
      return true;
    }

    void acquireAll(uint32 nb) {
      lockVar.lockAll(nb);
    }

    void release(CommonClass* cl) {
      lockVar.unlock();
    }

    void broadcast() {
      condVar.broadcast();
    }

    void wait() {
      condVar.wait(&lockVar);
    }
  };

public:
  
  /// virtualSize - The size of instances of this class.
  /// 
  uint32 virtualSize;

  /// aligment - Alignment of instances of this class.
  ///
  uint32 alignment;

  /// IsolateInfo - Per isolate informations for static instances and
  /// initialization state.
  ///
  TaskClassMirror IsolateInfo[NR_ISOLATES];
   
  /// lock - The lock of this class. It should be very rare that this lock
  /// inflates.
  ///
  mvm::ThinLock<FatLock, CommonClass, mvm::FatLockNoGC> lock;
  
  /// virtualFields - List of all the virtual fields defined in this class.
  /// This does not contain non-redefined super fields.
  JavaField* virtualFields;
  
  /// nbVirtualFields - The number of virtual fields.
  ///
  uint16 nbVirtualFields;

  /// staticFields - List of all the static fields defined in this class.
  ///
  JavaField* staticFields;

  /// nbStaticFields - The number of static fields.
  ///
  uint16 nbStaticFields;
  
  /// virtualMethods - List of all the virtual methods defined by this class.
  /// This does not contain non-redefined super methods.
  JavaMethod* virtualMethods;

  /// nbVirtualMethods - The number of virtual methods.
  ///
  uint16 nbVirtualMethods;
  
  /// staticMethods - List of all the static methods defined by this class.
  ///
  JavaMethod* staticMethods;

  /// nbStaticMethods - The number of static methods.
  ///
  uint16 nbStaticMethods;
  
  /// ownerClass - Who is initializing this class.
  ///
  mvm::Thread* ownerClass;
  
  /// bytes - The .class file of this class.
  ///
  ArrayUInt8* bytes;

  /// ctpInfo - The constant pool info of this class.
  ///
  JavaConstantPool* ctpInfo;

  /// attributs - JVM attributes of this class.
  ///
  Attribut* attributs;

  /// nbAttributs - The number of attributes.
  ///
  uint16 nbAttributs;
  
  /// innerClasses - The inner classes of this class.
  ///
  Class** innerClasses;
  
  /// nbInnerClasses - The number of inner classes.
  ///
  uint16 nbInnerClasses;

  /// outerClass - The outer class, if this class is an inner class.
  ///
  Class* outerClass;
  
  /// innerAccess - The access of this class, if this class is an inner class.
  ///
  uint16 innerAccess;

  /// innerOuterResolved - Is the inner/outer resolution done?
  ///
  bool innerOuterResolved;
  
  /// isAnonymous - Is the class an anonymous class?
  ///
  bool isAnonymous;

  /// virtualTableSize - The size of the virtual table of this class.
  ///
  uint32 virtualTableSize;
  
  /// staticSize - The size of the static instance of this class.
  ///
  uint32 staticSize;
  
  /// getVirtualSize - Get the virtual size of instances of this class.
  ///
  uint32 getVirtualSize() const { return virtualSize; }
  
  /// getVirtualVT - Get the virtual VT of instances of this class.
  ///
  JavaVirtualTable* getVirtualVT() const { return virtualVT; }

  /// getOwnerClass - Get the thread that is currently initializing the class.
  ///
  mvm::Thread* getOwnerClass() const {
    return ownerClass;
  }

  /// setOwnerClass - Set the thread that is currently initializing the class.
  ///
  void setOwnerClass(mvm::Thread* th) {
    ownerClass = th;
  }
 
  /// getOuterClass - Get the class that contains the definition of this class.
  ///
  Class* getOuterClass() const {
    return outerClass;
  }

  /// getInnterClasses - Get the classes that this class defines.
  ///
  Class** getInnerClasses() const {
    return innerClasses;
  }

  /// lookupMethodDontThrow - Lookup a method in the method map of this class.
  /// Do not throw if the method is not found.
  ///
  JavaMethod* lookupMethodDontThrow(const UTF8* name, const UTF8* type,
                                    bool isStatic, bool recurse, Class** cl);
  
  /// lookupInterfaceMethodDontThrow - Lookup a method in the interfaces of
  /// this class.
  /// Do not throw if the method is not found.
  ///
  JavaMethod* lookupInterfaceMethodDontThrow(const UTF8* name,
                                             const UTF8* type);
  
  /// lookupSpecialMethodDontThrow - Lookup a method following the
  /// invokespecial specification.
  /// Do not throw if the method is not found.
  ///
  JavaMethod* lookupSpecialMethodDontThrow(const UTF8* name,
                                           const UTF8* type,
                                           Class* current);
  
  /// lookupMethod - Lookup a method and throw an exception if not found.
  ///
  JavaMethod* lookupMethod(const UTF8* name, const UTF8* type, bool isStatic,
                           bool recurse, Class** cl);
  
  /// lookupInterfaceMethodDontThrow - Lookup a method in the interfaces of
  /// this class.
  /// Throws a MethodNotFoundError if the method can not ne found.
  ///
  JavaMethod* lookupInterfaceMethod(const UTF8* name, const UTF8* type);

  /// lookupFieldDontThrow - Lookup a field in the field map of this class. Do
  /// not throw if the field is not found.
  ///
  JavaField* lookupFieldDontThrow(const UTF8* name, const UTF8* type,
                                  bool isStatic, bool recurse,
                                  Class** definingClass);
  
  /// lookupField - Lookup a field and throw an exception if not found.
  ///
  JavaField* lookupField(const UTF8* name, const UTF8* type, bool isStatic,
                         bool recurse, Class** definingClass);
   
  /// Assessor methods.
  JavaField* getStaticFields() const    { return staticFields; }
  JavaField* getVirtualFields() const   { return virtualFields; }
  JavaMethod* getStaticMethods() const  { return staticMethods; }
  JavaMethod* getVirtualMethods() const { return virtualMethods; }

  
  /// setInnerAccess - Set the access flags of this inner class.
  ///
  void setInnerAccess(uint16 access) {
    innerAccess = access;
  }
   
  /// getStaticSize - Get the size of the static instance.
  ///
  uint32 getStaticSize() const {
    return staticSize;
  }
  
#ifndef ISOLATE_SHARING
  /// doNew - Allocates a Java object whose class is this class.
  ///
  JavaObject* doNew(Jnjvm* vm);
#endif
  
  /// tracer - Tracer function of instances of Class.
  ///
  void tracer();
  
  ~Class();
  Class();
  
  /// lookupAttribut - Look up a JVM attribut of this class.
  ///
  Attribut* lookupAttribut(const UTF8* key);
  
  /// allocateStaticInstance - Allocate the static instance of this class.
  ///
  void* allocateStaticInstance(Jnjvm* vm);
  
  /// Class - Create a class in the given virtual machine and with the given
  /// name.
  Class(JnjvmClassLoader* loader, const UTF8* name, ArrayUInt8* bytes);
  
  /// readParents - Reads the parents, i.e. super and interfaces, of the class.
  ///
  void readParents(Reader& reader);

  /// loadParents - Loads and resolves the parents, i.e. super and interfarces,
  /// of the class.
  ///
  void loadParents();
  
  /// loadExceptions - Loads and resolves the exception classes used in catch 
  /// clauses of methods defined in this class.
  ///
  void loadExceptions();

  /// readAttributs - Reads the attributs of the class.
  ///
  Attribut* readAttributs(Reader& reader, uint16& size);

  /// readFields - Reads the fields of the class.
  ///
  void readFields(Reader& reader);

  /// readMethods - Reads the methods of the class.
  ///
  void readMethods(Reader& reader);
  
  /// readClass - Reads the class.
  ///
  void readClass();
 
  /// getConstantPool - Get the constant pool of the class.
  ///
  JavaConstantPool* getConstantPool() const {
    return ctpInfo;
  }

  /// getBytes - Get the bytes of the class file.
  ///
  ArrayUInt8* getBytes() const {
    return bytes;
  }
  
  ArrayUInt8** getBytesPtr() {
    return &bytes;
  }
  
  /// resolveInnerOuterClasses - Resolve the inner/outer information.
  ///
  void resolveInnerOuterClasses();

  /// resolveClass - If the class has not been resolved yet, resolve it.
  ///
  void resolveClass();

  /// initialiseClass - If the class has not been initialized yet,
  /// initialize it.
  ///
  void initialiseClass(Jnjvm* vm);
  
  /// acquire - Acquire this class lock.
  ///
  void acquire() {
    lock.acquire(this);
  }
  
  /// release - Release this class lock.
  ///
  void release() {
    lock.release(this);
  }

  /// waitClass - Wait for the class to be loaded/initialized/resolved.
  ///
  void waitClass() {
    FatLock* FL = lock.changeToFatlock(this);
    FL->wait();
  }
  
  /// broadcastClass - Unblock threads that were waiting on the class being
  /// loaded/initialized/resolved.
  ///
  void broadcastClass() {
    lock.broadcast();  
  }
  
#ifndef ISOLATE
  
  /// getCurrentTaskClassMirror - Get the class task mirror of the executing
  /// isolate.
  ///
  TaskClassMirror& getCurrentTaskClassMirror() {
    return IsolateInfo[0];
  }
  
  /// isReadyForCompilation - Can this class be inlined when JITing?
  ///
  bool isReadyForCompilation() {
    return isReady();
  }
  
  /// setResolved - Set the status of the class as resolved.
  ///
  void setResolved() {
    getCurrentTaskClassMirror().status = resolved;
  }
  
  /// setErroneous - Set the class as erroneous.
  ///
  void setErroneous() {
    getCurrentTaskClassMirror().status = erroneous;
  }
  
  /// setIsRead - The class file has been read.
  ///
  void setIsRead() {
    getCurrentTaskClassMirror().status = classRead;
  }
  

#else
  
  TaskClassMirror& getCurrentTaskClassMirror();
  
  bool isReadyForCompilation() {
    return false;
  }
  
  void setResolved() {
    for (uint32 i = 0; i < NR_ISOLATES; ++i) {
      IsolateInfo[i].status = resolved;
    }
  }
  
  void setIsRead() {
    for (uint32 i = 0; i < NR_ISOLATES; ++i) {
      IsolateInfo[i].status = classRead;
    }
  }
  
  void setErroneous() {
    for (uint32 i = 0; i < NR_ISOLATES; ++i) {
      IsolateInfo[i].status = erroneous;
    }
  }

#endif
  
  /// getStaticInstance - Get the memory that holds static variables.
  ///
  void* getStaticInstance() {
    return getCurrentTaskClassMirror().staticInstance;
  }
  
  /// setStaticInstance - Set the memory that holds static variables.
  ///
  void setStaticInstance(void* val) {
    getCurrentTaskClassMirror().staticInstance = val;
  }
  
  /// getInitializationState - Get the state of the class.
  ///
  uint8 getInitializationState() {
    return getCurrentTaskClassMirror().status;
  }

  /// setInitializationState - Set the state of the class.
  ///
  void setInitializationState(uint8 st) {
    TaskClassMirror& TCM = getCurrentTaskClassMirror();
    TCM.status = st;
    if (st == ready) TCM.initialized = true;
  }
  
  /// isReady - Has this class been initialized?
  ///
  bool isReady() {
    return getCurrentTaskClassMirror().status == ready;
  }
  
  /// isInitializing - Is the class currently being initialized?
  ///
  bool isInitializing() {
    return getCurrentTaskClassMirror().status >= inClinit;
  }
  
  /// isResolved - Has this class been resolved?
  ///
  bool isResolved() {
    uint8 stat = getCurrentTaskClassMirror().status;
    return (stat >= resolved && stat != erroneous);
  }
  
  /// isErroneous - Is the class in an erroneous state.
  ///
  bool isErroneous() {
    return getCurrentTaskClassMirror().status == erroneous;
  }

  /// isResolving - Is the class currently being resolved?
  ///
  bool isResolving() {
    return getCurrentTaskClassMirror().status == classRead;
  }

  /// isClassRead - Has the .class file been read?
  ///
  bool isClassRead() {
    return getCurrentTaskClassMirror().status >= classRead;
  }
 
  /// isNativeOverloaded - Is the method overloaded with a native function?
  ///
  bool isNativeOverloaded(JavaMethod* meth);

  /// needsInitialisationCheck - Does the method need an initialisation check?
  ///
  bool needsInitialisationCheck();

  /// fillIMT - Fill the vector with vectors of methods with the same IMT
  /// index.
  ///
  void fillIMT(std::set<JavaMethod*>* meths);

private:

  /// makeVT - Create the virtual table of this class.
  ///
  void makeVT();

};

/// ClassArray - This class represents Java array classes.
///
class ClassArray : public CommonClass {

public:
  
  /// doNew - Allocate a new array with the given allocator.
  ///
  JavaArray* doNew(sint32 n, mvm::BumpPtrAllocator& allocator,
                   bool temp = false);
  JavaArray* doNew(sint32 n);

  /// _baseClass - The base class of the array.
  ///
  CommonClass*  _baseClass;

  /// baseClass - Get the base class of this array class.
  ///
  CommonClass* baseClass() const {
    return _baseClass;
  }

  /// doNew - Allocate a new array in the given vm.
  ///
  JavaArray* doNew(sint32 n, Jnjvm* vm);

  /// ClassArray - Construct a Java array class with the given name.
  ///
  ClassArray(JnjvmClassLoader* loader, const UTF8* name,
             UserCommonClass* baseClass);
  
  /// SuperArray - The super of class arrays. Namely java/lang/Object.
  ///
  static Class* SuperArray;

  /// InterfacesArray - The list of interfaces for array classes.
  ///
  static Class** InterfacesArray;

  /// initialiseVT - Initialise the primitive and reference array VT.
  /// super is the java/lang/Object class.
  ///
  static void initialiseVT(Class* javaLangObject);
  
};

class JavaStaticMethodInfo : public mvm::CamlMethodInfo {
protected:
  JavaMethod* meth;
public:
  virtual void print(void* ip, void* addr);
  
  JavaStaticMethodInfo(mvm::CamlFrame* CF, void* ip, JavaMethod* M) :
    mvm::CamlMethodInfo(CF, ip) {
    meth = M;
    MethodType = 1;
  }

  virtual void* getMetaInfo() {
    return meth;
  }
};

class CodeLineInfo : public mvm::PermanentObject {
public:
  uintptr_t address;
  uint16 lineNumber;
  uint16 ctpIndex;
  uint16 bytecodeIndex;
  uint16 bytecode;
  // TODO: Use these fields when inlining.
  JavaMethod* executingMethod;
  // The code where the inlined method starts.
  CodeLineInfo* inlineLocation;
};

/// JavaMethod - This class represents Java methods.
///
class JavaMethod : public mvm::PermanentObject {
private:

  /// _signature - The signature of this method. Null if not resolved.
  ///
  Signdef* _signature;

public:
  
  enum Type {
    Static,
    Special,
    Interface,
    Virtual
  };

  /// constructMethod - Create a new method.
  ///
  void initialise(Class* cl, const UTF8* name, const UTF8* type, uint16 access);
   
  /// compiledPtr - Return a pointer to the compiled code of this Java method,
  /// compiling it if necessary.
  ///
  void* compiledPtr();

  /// setCompiledPtr - Set the pointer function to the method.
  ///
  void setCompiledPtr(void*, const char*);
  
  /// JavaMethod - Delete the method as well as the cache enveloppes and
  /// attributes of the method.
  ///
  ~JavaMethod();

  /// access - Java access type of this method (e.g. private, public...).
  ///
  uint16 access;

  /// attributs - List of Java attributs of this method.
  ///
  Attribut* attributs;
  
  /// nbAttributs - The number of attributes.
  ///
  uint16 nbAttributs;

  /// classDef - The Java class where the method is defined.
  ///
  Class* classDef;

  /// name - The name of the method.
  ///
  const UTF8* name;

  /// type - The UTF8 signature of the method.
  ///
  const UTF8* type;

  /// canBeInlined - Can the method be inlined?
  ///
  bool canBeInlined;

  /// code - Pointer to the compiled code of this method.
  ///
  void* code;
 
  /// codeInfo - Array of CodeLineInfo objects.
  ///
  CodeLineInfo* codeInfo;

  /// codeInfoLength - Number of entries in the codeInfo field.
  ///
  uint16 codeInfoLength;

  /// offset - The index of the method in the virtual table.
  ///
  uint32 offset;

  /// lookupAttribut - Look up an attribut in the method's attributs. Returns
  /// null if the attribut is not found.
  ///
  Attribut* lookupAttribut(const UTF8* key);

  /// lookupLineNumber - Find the line number based on the given instruction
  /// pointer.
  ///
  uint16 lookupLineNumber(uintptr_t ip);
  
  /// lookupCtpIndex - Lookup the constant pool index pointed by the opcode
  /// related to the given instruction pointer.
  ///
  uint16 lookupCtpIndex(uintptr_t ip);
  
  /// lookupCodeLineInfo - Lookup the code line info related to the given
  /// instruction pointer.
  ///
  CodeLineInfo* lookupCodeLineInfo(uintptr_t ip);

  /// getSignature - Get the signature of thes method, resolving it if
  /// necessary.
  ///
  Signdef* getSignature() {
    if(!_signature)
      _signature = classDef->classLoader->constructSign(type);
    return _signature;
  }
  
  /// toString - Return an array of chars, suitable for creating a string.
  ///
  ArrayUInt16* toString() const;
  
  /// jniConsFromMeth - Construct the JNI name of this method as if
  /// there is no other function in the class with the same name.
  ///
  void jniConsFromMeth(char* buf) const {
    jniConsFromMeth(buf, classDef->name, name, type, isSynthetic(access));
  }

  /// jniConsFromMethOverloaded - Construct the JNI name of this method
  /// as if its name is overloaded in the class.
  ///
  void jniConsFromMethOverloaded(char* buf) const {
    jniConsFromMethOverloaded(buf, classDef->name, name, type,
                              isSynthetic(access));
  }
  
  /// jniConsFromMeth - Construct the non-overloaded JNI name with
  /// the given name and type.
  ///
  static void jniConsFromMeth(char* buf, const UTF8* clName, const UTF8* name,
                              const UTF8* sign, bool synthetic);

  /// jniConsFromMethOverloaded - Construct the overloaded JNI name with
  /// the given name and type.
  ///
  static void jniConsFromMethOverloaded(char* buf, const UTF8* clName,
                                        const UTF8* name, const UTF8* sign,
                                        bool synthetic);
  
  /// getParameterTypes - Get the java.lang.Class of the parameters of
  /// the method, with the given class loader.
  ///
  ArrayObject* getParameterTypes(JnjvmClassLoader* loader);

  /// getExceptionTypes - Get the java.lang.Class of the exceptions of the
  /// method, with the given class loader.
  ///
  ArrayObject* getExceptionTypes(JnjvmClassLoader* loader);

  /// getReturnType - Get the java.lang.Class of the result of the method,
  /// with the given class loader.
  ///
  JavaObject* getReturnType(JnjvmClassLoader* loader);
  

//===----------------------------------------------------------------------===//
//
// Upcalls from JnJVM code to Java code. 
//
//===----------------------------------------------------------------------===//
  
  /// This class of methods takes a variable argument list.
  uint32 invokeIntSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  float invokeFloatSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  double invokeDoubleSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj,
                               va_list ap) __attribute__ ((noinline));
  sint64 invokeLongSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectSpecialAP(Jnjvm* vm, UserClass*, JavaObject* obj,
                                        va_list ap) __attribute__ ((noinline));
  
  uint32 invokeIntVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  float invokeFloatVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  double invokeDoubleVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj,
                               va_list ap) __attribute__ ((noinline));
  sint64 invokeLongVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj, va_list ap)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectVirtualAP(Jnjvm* vm, UserClass*, JavaObject* obj,
                                        va_list ap) __attribute__ ((noinline));
  
  uint32 invokeIntStaticAP(Jnjvm* vm, UserClass*, va_list ap)
    __attribute__ ((noinline));
  float invokeFloatStaticAP(Jnjvm* vm, UserClass*, va_list ap)
    __attribute__ ((noinline));
  double invokeDoubleStaticAP(Jnjvm* vm, UserClass*, va_list ap)
    __attribute__ ((noinline));
  sint64 invokeLongStaticAP(Jnjvm* vm, UserClass*, va_list ap)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectStaticAP(Jnjvm* vm, UserClass*, va_list ap)
    __attribute__ ((noinline));

  /// This class of methods takes a buffer which contain the arguments of the
  /// call.
  uint32 invokeIntSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  float invokeFloatSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  double invokeDoubleSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj,
                                void* buf) __attribute__ ((noinline));
  sint64 invokeLongSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectSpecialBuf(Jnjvm* vm, UserClass*, JavaObject* obj,
                                         void* buf) __attribute__ ((noinline));
  
  uint32 invokeIntVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  float invokeFloatVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  double invokeDoubleVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj,
                                void* buf) __attribute__ ((noinline));
  sint64 invokeLongVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj, void* buf)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectVirtualBuf(Jnjvm* vm, UserClass*, JavaObject* obj,
                                         void* buf) __attribute__ ((noinline));
  
  uint32 invokeIntStaticBuf(Jnjvm* vm, UserClass*, void* buf)
    __attribute__ ((noinline));
  float invokeFloatStaticBuf(Jnjvm* vm, UserClass*, void* buf)
    __attribute__ ((noinline));
  double invokeDoubleStaticBuf(Jnjvm* vm, UserClass*, void* buf)
    __attribute__ ((noinline));
  sint64 invokeLongStaticBuf(Jnjvm* vm, UserClass*, void* buf)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectStaticBuf(Jnjvm* vm, UserClass*, void* buf)
    __attribute__ ((noinline));

  /// This class of methods is variadic.
  uint32 invokeIntSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  float invokeFloatSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  double invokeDoubleSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  sint64 invokeLongSpecial(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectSpecial(Jnjvm* vm, UserClass*, JavaObject* obj,
                                      ...) __attribute__ ((noinline));
  
  uint32 invokeIntVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  float invokeFloatVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  double invokeDoubleVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  sint64 invokeLongVirtual(Jnjvm* vm, UserClass*, JavaObject* obj, ...)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectVirtual(Jnjvm* vm, UserClass*, JavaObject* obj,
                                      ...) __attribute__ ((noinline));
  
  uint32 invokeIntStatic(Jnjvm* vm, UserClass*, ...)
    __attribute__ ((noinline));
  float invokeFloatStatic(Jnjvm* vm, UserClass*, ...)
    __attribute__ ((noinline));
  double invokeDoubleStatic(Jnjvm* vm, UserClass*, ...)
    __attribute__ ((noinline));
  sint64 invokeLongStatic(Jnjvm* vm, UserClass*, ...)
    __attribute__ ((noinline));
  JavaObject* invokeJavaObjectStatic(Jnjvm* vm, UserClass*, ...)
    __attribute__ ((noinline));
  
  #define JNI_NAME_PRE "Java_"
  #define JNI_NAME_PRE_LEN 5
  
};

/// JavaField - This class represents a Java field.
///
class JavaField  : public mvm::PermanentObject {
private:
  /// _signature - The signature of the field. Null if not resolved.
  ///
  Typedef* _signature;
  
  /// InitField - Set an initial value to the field of an object.
  ///
  void InitField(void* obj, uint64 val = 0);
  void InitField(void* obj, JavaObject* val);
  void InitField(void* obj, double val);
  void InitField(void* obj, float val);

public:
  
  /// constructField - Create a new field.
  ///
  void initialise(Class* cl, const UTF8* name, const UTF8* type, uint16 access);

  /// ~JavaField - Destroy the field as well as its attributs.
  ///
  ~JavaField();

  /// access - The Java access type of this field (e.g. public, private).
  ///
  uint16 access;

  /// name - The name of the field.
  ///
  const UTF8* name;

  /// type - The UTF8 type name of the field.
  ///
  const UTF8* type;

  /// attributs - List of Java attributs for this field.
  ///
  Attribut* attributs;
  
  /// nbAttributs - The number of attributes.
  ///
  uint16 nbAttributs;

  /// classDef - The class where the field is defined.
  ///
  Class* classDef;

  /// ptrOffset - The offset of the field when the object containing
  /// the field is casted to an array of bytes.
  ///
  uint32 ptrOffset;
  
  /// num - The index of the field in the field list.
  ///
  uint16 num;
  
  /// getSignature - Get the signature of this field, resolving it if
  /// necessary.
  ///
  Typedef* getSignature() {
    if(!_signature)
      _signature = classDef->classLoader->constructType(type);
    return _signature;
  }

  /// initField - Init the value of the field in the given object. This is
  /// used for static fields which have a default value.
  ///
  void initField(void* obj, Jnjvm* vm);

  /// lookupAttribut - Look up the attribut in the field's list of attributs.
  ///
  Attribut* lookupAttribut(const UTF8* key);

  JavaObject** getObjectFieldPtr(void* obj) {
    assert(classDef->isResolved());
    void* ptr = (void*)((uint64)obj + ptrOffset);
    return (JavaObject**)ptr;
  }

  /// getVritual*Field - Get a virtual field of an object.
  ///
  #define GETFIELD(TYPE, TYPE_NAME) \
  TYPE get##TYPE_NAME##Field(void* obj) { \
    assert(classDef->isResolved()); \
    void* ptr = (void*)((uint64)obj + ptrOffset); \
    return ((TYPE*)ptr)[0]; \
  }

  /// set*Field - Set a field of an object.
  ///
  #define SETFIELD(TYPE, TYPE_NAME) \
  void set##TYPE_NAME##Field(void* obj, TYPE val) { \
    assert(classDef->isResolved()); \
    void* ptr = (void*)((uint64)obj + ptrOffset); \
    ((TYPE*)ptr)[0] = val; \
  }

  #define MK_ASSESSORS(TYPE, TYPE_NAME) \
    GETFIELD(TYPE, TYPE_NAME) \
    SETFIELD(TYPE, TYPE_NAME) \

  MK_ASSESSORS(float, Float);
  MK_ASSESSORS(double, Double);
  MK_ASSESSORS(JavaObject*, Object);
  MK_ASSESSORS(uint8, Int8);
  MK_ASSESSORS(uint16, Int16);
  MK_ASSESSORS(uint32, Int32);
  MK_ASSESSORS(sint64, Long);
  
  bool isReference() {
    uint16 val = type->elements[0];
    return (val == '[' || val == 'L');
  }

};


} // end namespace j3


#ifdef ISOLATE_SHARING
#include "IsolateCommonClass.h"
#endif

#endif
