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


#ifndef JNJVM_CLASSLOADER_H
#define JNJVM_CLASSLOADER_H

#include <map>
#include <vector>

#include "types.h"


#include "mvm/Allocator.h"
#include "mvm/Object.h"

#include "JavaObject.h"
#include "JnjvmConfig.h"
#include "UTF8.h"

namespace j3 {

class ArrayUInt8;
class UserClass;
class UserClassArray;
class ClassMap;
class Classpath;
class UserCommonClass;
class JavaCompiler;
class JavaMethod;
class JavaObject;
class JavaString;
class Jnjvm;
class JnjvmBootstrapLoader;
class JnjvmClassLoader;
class Signdef;
class SignMap;
class StringList;
class Typedef;
class TypeMap;
class ZipArchive;


/// JnjvmClassLoader - Runtime representation of a class loader. It contains
/// its own tables (signatures, UTF8, types) which are mapped to a single
/// table for non-isolate environments.
///
class JnjvmClassLoader : public mvm::PermanentObject {
private:

  /// isolate - Which isolate defined me? Null for the bootstrap class loader.
  ///
  Jnjvm* isolate;

  /// javaLoder - The Java representation of the class loader. Null for the
  /// bootstrap class loader.
  ///
  JavaObject* javaLoader;

  /// internalLoad - Load the class with the given name.
  ///
  virtual UserClass* internalLoad(const UTF8* utf8, bool doResolve,
                                  JavaString* strName = 0);
  
  /// internalConstructType - Hashes a Typedef, an internal representation of
  /// a class still not loaded.
  ///
  Typedef* internalConstructType(const UTF8 * name);
  
  /// JnjvmClassLoader - Allocate a user-defined class loader. Called on
  /// first use of a Java class loader.
  ///
  JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc, JnjvmClassLoader& JCL,
                   JavaObject* loader, Jnjvm* isolate);

  /// lookupComponentName - Try to find the component name of the given array
  /// name. If the component name is not in the table of UTF8s and holder
  /// is null, the function returns 0.
  ///
  const UTF8* lookupComponentName(const UTF8* name, UTF8* holder, bool& prim);

protected:
  
  JnjvmClassLoader(mvm::BumpPtrAllocator& Alloc) : allocator(Alloc) {}
  
  /// TheCompiler - The Java compiler for this class loader.
  ///
  JavaCompiler* TheCompiler;

  /// classes - The classes this class loader has loaded.
  ///
  ClassMap* classes;
  
  /// javaTypes - Tables of Typedef defined by this class loader.
  ///
  TypeMap* javaTypes;

  /// javaSignatures - Tables of Signdef defined by this class loader.
  ///
  SignMap* javaSignatures;

public:
  
  /// allocator - Reference to the memory allocator, which will allocate UTF8s,
  /// signatures and types.
  ///
  mvm::BumpPtrAllocator& allocator;
 
  /// getIsolate - Returns the isolate that created this class loader.
  ///
  Jnjvm* getIsolate() const { return isolate; }

  /// getClasses - Returns the classes this class loader has loaded.
  ///
  ClassMap* getClasses() const { return classes; }
  
  /// hashUTF8 - Tables of UTF8s defined by this class loader.
  ///
  UTF8Map* hashUTF8;
  
  /// getCompiler - Get the Java compiler of this class loader.
  ///
  JavaCompiler* getCompiler() const { return TheCompiler; }

  /// setCompiler - Set the compiler of classes loaded by this class loader.
  ///
  void setCompiler(JavaCompiler* Comp);

  /// tracer - Traces a JnjvmClassLoader for GC.
  ///
  virtual void tracer();
  
  /// getJnjvmLoaderFromJavaObject - Return the Jnjvm runtime representation
  /// of the given class loader.
  ///
  static JnjvmClassLoader* getJnjvmLoaderFromJavaObject(JavaObject*, Jnjvm *vm);
  
  /// getJavaClassLoader - Return the Java representation of this class loader.
  ///
  JavaObject* getJavaClassLoader() const {
    return javaLoader;
  }
  
  /// getJavaClassLoaderPtr - Return a pointer to the Java representation of
  /// this class loader.
  ///
  JavaObject** getJavaClassLoaderPtr() {
    return &javaLoader;
  }
  
  /// loadName - Loads the class of the given name.
  ///
  UserClass* loadName(const UTF8* name, bool doResolve, bool doThrow,
                      JavaString* strName = 0);
  
  /// loadClassFromUTF8 - Lookup a class from an UTF8 name and load it.
  ///
  UserCommonClass* loadClassFromUserUTF8(const UTF8* utf8,
                                         bool doResolve, bool doThrow,
                                         JavaString* strName = 0);
  
  /// loadClassFromAsciiz - Lookup a class from an asciiz name and load it.
  ///
  UserCommonClass* loadClassFromAsciiz(const char* name,
                                       bool doResolve, bool doThrow);
  
  /// loadClassFromJavaString - Lookup a class from a Java String and load it.
  ///
  UserCommonClass* loadClassFromJavaString(JavaString* str,
                                           bool doResolve, bool doThrow);
  
  /// lookupClassFromJavaString - Finds the class of the given string name in
  /// the class loader's table. Do not inline this function, because it
  /// does an alloca and is called by Classpath functions.
  ///
  UserCommonClass* lookupClassFromJavaString(JavaString* str) 
    __attribute__ ((noinline));
   
  /// lookupClass - Finds the class of the given name in the class loader's
  /// table.
  ///
  UserCommonClass* lookupClass(const UTF8* utf8);
  
  /// lookupClassOrArray - Finds the class of the given name in the class
  /// loader's table. If the class has not been loaded, and if it's an
  /// array whose base class is loaded, then this function loads the array class
  /// and returns it.
  ///
  UserCommonClass* lookupClassOrArray(const UTF8* utf8);

  /// constructArray - Hashes a runtime representation of a class with
  /// the given name.
  ///
  UserClassArray* constructArray(const UTF8* name);
  UserClassArray* constructArray(const UTF8* name, UserCommonClass* base);
  
  UserCommonClass* loadBaseClass(const UTF8* name, uint32 start, uint32 len);

  /// constructClass - Hashes a runtime representation of a class with
  /// the given name.
  ///
  UserClass* constructClass(const UTF8* name, ArrayUInt8* bytes);
  
  /// constructType - Hashes a Typedef, an internal representation of a class
  /// still not loaded.
  ///
  Typedef* constructType(const UTF8 * name);

  /// constructSign - Hashes a Signdef, a method signature.
  ///
  Signdef* constructSign(const UTF8 * name);
  
  /// asciizConstructUTF8 - Hashes an UTF8 created from the given asciiz.
  ///
  const UTF8* asciizConstructUTF8(const char* asciiz);

  /// readerConstructUTF8 - Hashes an UTF8 created from the given Unicode
  /// buffer.
  ///
  const UTF8* readerConstructUTF8(const uint16* buf, uint32 size);
  
  /// bootstrapLoader - The bootstrap loader of the JVM. Loads the base
  /// classes.
  ///
  JnjvmBootstrapLoader* bootstrapLoader;
  
  /// ~JnjvmClassLoader - Destroy the loader: destroy the tables, JIT module and
  /// module provider.
  ///
  virtual ~JnjvmClassLoader();
  
  /// loadClass - The user class that defines the loadClass method.
  ///
  UserClass* loadClass;

  /// loadClassMethod - The loadClass defined by this class loader.
  ///
  JavaMethod* loadClassMethod;
 
  /// constructArrayName - Construct an array name based on a class name
  /// and the number of dimensions.
  const UTF8* constructArrayName(uint32 steps, const UTF8* className);
  
  /// UTF8ToStr - Constructs a Java string out of the UTF8.
  ///
  virtual JavaString** UTF8ToStr(const UTF8* utf8);

  /// Strings hashed by this classloader.
  ///
  StringList* strings;
  
  /// nativeLibs - Native libraries (e.g. '.so') loaded by this class loader.
  ///
  std::vector<void*> nativeLibs;

  /// loadInLib - Loads a native function out of the native libraries loaded
  /// by this class loader. The last argument tells if the returned method
  /// is defined in j3.
  ///
  intptr_t loadInLib(const char* buf, bool& j3);

  /// loadInLib - Loads a native function out of the given native library.
  ///
  intptr_t loadInLib(const char* buf, void* handle);

  /// loadLib - Loads the library with the given name.
  ///
  void* loadLib(const char* buf);

  /// nativeLookup - Lookup in the class loader a function pointer for the
  /// method. Also set in the j3 parameter is the function is defined in
  /// JnJVM.
  ///
  intptr_t nativeLookup(JavaMethod* meth, bool& j3, char* buf);

  /// insertAllMethodsInVM - Insert all methods defined by this class loader
  /// in the VM.
  ///
  void insertAllMethodsInVM(Jnjvm* vm);

  /// loadLibFromJar - Try to load the shared library compiled by vmjc with
  /// this jar file.
  ///
  void loadLibFromJar(Jnjvm* vm, const char* name, const char* file);

  /// loadLibFromFile - Try to load the shared library compiled by vmjc with
  /// this class file.
  ///
  void loadLibFromFile(Jnjvm* vm, const char* name);
  
  /// loadClassFromSelf - Load the main class if we are an executable.
  ///
  Class* loadClassFromSelf(Jnjvm* vm, const char* name);

};

/// JnjvmBootstrapLoader - This class is for the bootstrap class loader, which
/// loads base classes, ie glibj.zip or rt.jar and -Xbootclasspath.
///
class JnjvmBootstrapLoader : public JnjvmClassLoader {
private:
  /// internalLoad - Load the class with the given name.
  ///
  virtual UserClass* internalLoad(const UTF8* utf8, bool doResolve,
                                  JavaString* strName = 0);
     
  /// bootClasspath - List of paths for the base classes.
  ///
  std::vector<const char*> bootClasspath;

  /// bootArchives - List of .zip or .jar files that contain base classes.
  ///
  std::vector<ZipArchive*> bootArchives;
  
  /// openName - Opens a file of the given name and returns it as an array
  /// of byte.
  ///
  ArrayUInt8* openName(const UTF8* utf8);
  
public:
  
  /// tracer - Traces instances of this class.
  ///
  virtual void tracer();

  /// libClasspathEnv - The paths for dynamic libraries of Classpath, separated
  /// by ':'.
  ///
  const char* libClasspathEnv;

  /// bootClasspathEnv - The path for base classes, seperated by '.'.
  ///
  const char* bootClasspathEnv;

  /// analyseClasspathEnv - Analyse the paths for base classes.
  ///
  void analyseClasspathEnv(const char*);
  
  /// createBootstrapLoader - Creates the bootstrap loader, first thing
  /// to do before any execution of a JVM. Also try to load libvmjc.so
  /// if dlLoad is not false.
  ///
  JnjvmBootstrapLoader(mvm::BumpPtrAllocator& Alloc, JavaCompiler* Comp,
                       bool dlLoad = true);
  
  virtual JavaString** UTF8ToStr(const UTF8* utf8);

  /// nativeHandle - Non-null handle if boot classes were static compiled in
  /// a dynamic library
  ///
  void* nativeHandle;

  /// upcalls - Upcall classes, fields and methods so that C++ code can call
  /// Java code.
  ///
  Classpath* upcalls;
  
  /// InterfacesArray - The interfaces that array classes implement.
  ///
  UserClass** InterfacesArray;

  /// SuperArray - The super of array classes.
  UserClass* SuperArray;

  /// Lists of UTF8s used internaly in VMKit.
  const UTF8* NoClassDefFoundError;
  const UTF8* initName;
  const UTF8* clinitName;
  const UTF8* clinitType; 
  const UTF8* initExceptionSig;
  const UTF8* runName; 
  const UTF8* prelib; 
  const UTF8* postlib; 
  const UTF8* mathName;
  const UTF8* stackWalkerName;
  const UTF8* abs;
  const UTF8* sqrt;
  const UTF8* sin;
  const UTF8* cos;
  const UTF8* tan;
  const UTF8* asin;
  const UTF8* acos;
  const UTF8* atan;
  const UTF8* atan2;
  const UTF8* exp;
  const UTF8* log;
  const UTF8* pow;
  const UTF8* ceil;
  const UTF8* floor;
  const UTF8* rint;
  const UTF8* cbrt;
  const UTF8* cosh;
  const UTF8* expm1;
  const UTF8* hypot;
  const UTF8* log10;
  const UTF8* log1p;
  const UTF8* sinh;
  const UTF8* tanh;
  const UTF8* finalize;

  /// primitiveMap - Map of primitive classes, hashed by id.
  std::map<const char, UserClassPrimitive*> primitiveMap;

  UserClassPrimitive* getPrimitiveClass(char id) {
    return primitiveMap[id];
  }

  /// arrayTable - Table of array classes.
  UserClassArray* arrayTable[8];

  UserClassArray* getArrayClass(unsigned id) {
    return arrayTable[id - 4];
  }

  virtual ~JnjvmBootstrapLoader();
};

/// VMClassLoader - The vmdata object that will be placed in and will only
/// be referenced by the java.lang.Classloader Java object. Having a
/// separate class between VMClassLoader and JnjvmClassLoader allows to
/// have a JnjvmClassLoader non-GC object. Also the finalizer of this class
/// will delete the internal class loader and we do not have to implement
/// hacks in the java.lang.Classloader finalizer.
class VMClassLoader : public JavaObject {
private:
  
  /// JCL - The internal class loader.
  ///
  JnjvmClassLoader* JCL;

public:

  static VMClassLoader* allocate(JnjvmClassLoader* J) {
    VMClassLoader* res = 0;
    llvm_gcroot(res, 0);
    res = (VMClassLoader*)gc::operator new(sizeof(VMClassLoader), &VT);
    res->JCL = J;
    return res;
  }

  /// VT - The VirtualTable for this GC-class.
  ///
  static VirtualTable VT;

  /// Is the object a VMClassLoader object?
  ///
  static bool isVMClassLoader(JavaObject* obj) {
    return obj->getVirtualTable() == &VT;
  }

  /// staticTracer - Trace the internal class loader.
  ///
  static void staticTracer(VMClassLoader* obj) {
    if (obj->JCL) obj->JCL->tracer();
  }

  /// ~VMClassLoader - Delete the internal class loader.
  ///
  static void staticDestructor(VMClassLoader* obj) {
    if (obj->JCL) {
      obj->JCL->~JnjvmClassLoader();
      delete &(obj->JCL->allocator);
    }
  }

  /// VMClassLoader - Default constructors.
  ///
  VMClassLoader(JnjvmClassLoader* J) : JCL(J) {}

  /// getClassLoader - Get the internal class loader.
  ///
  JnjvmClassLoader* getClassLoader() {
    return JCL;
  }

};

#define MAXIMUM_STRINGS 100

class StringList : public mvm::PermanentObject {
  friend class JnjvmClassLoader;
  friend class Jnjvm;

private:
  StringList* prev;
  uint32_t length;
  JavaString* strings[MAXIMUM_STRINGS];

public:
  StringList() {
    prev = 0;
    length = 0;
  }

  JavaString** addString(JnjvmClassLoader* JCL, JavaString* obj) {
    llvm_gcroot(obj, 0);
    if (length == MAXIMUM_STRINGS) {
      StringList* next = new(JCL->allocator, "StringList") StringList();
      next->prev = this;
      JCL->strings = next;
      return next->addString(JCL, obj);
    } else {
      strings[length] = obj;
      return &strings[length++];
    }
  }
};

} // end namespace j3

#endif // JNJVM_CLASSLOADER_H
