//===---------- Jnjvm.cpp - Java virtual machine description --------------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#define JNJVM_LOAD 0

#include <float.h>
#include <limits.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "debug.h"

#include "mvm/JIT.h"
#include "mvm/Threads/Thread.h"

#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "JavaConstantPool.h"
#include "JavaJIT.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "JnjvmModuleProvider.h"
#include "LockedMap.h"
#include "Reader.h"
#ifdef SERVICE_VM
#include "ServiceDomain.h"
#endif
#include "Zip.h"

using namespace jnjvm;

const char* Jnjvm::dirSeparator = "/";
const char* Jnjvm::envSeparator = ":";
const unsigned int Jnjvm::Magic = 0xcafebabe;

typedef void (*clinit_t)(Jnjvm* vm, UserConstantPool*);

void UserCommonClass::initialiseClass(Jnjvm* vm) {
  // Primitives are initialized at boot time
  if (isArray()) {
    status = ready;
  } else if (status != ready) {
    acquire();
    if (status == ready) {
      release();
    } else if (status >= resolved && status != clinitParent &&
               status != inClinit) {
      UserClass* cl = (UserClass*)this;
      status = clinitParent;
      release();
      UserCommonClass* super = getSuper();
      if (super) {
        super->initialiseClass(vm);
      }
      
      cl->resolveStaticClass();
      
      status = inClinit;
      JavaMethod* meth = lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
                                               vm->bootstrapLoader->clinitType,
                                               true, false, 0);
      
      PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "; ", 0);
      PRINT_DEBUG(JNJVM_LOAD, 0, LIGHT_GREEN, "clinit ", 0);
      PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "%s\n", printString());
      
      JavaObject* val = 
        (JavaObject*)vm->gcAllocator.allocateManagedObject(cl->getStaticSize(),
                                                           cl->getStaticVT());
      val->initialise(cl);
      JavaField* fields = cl->getStaticFields();
      for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
        fields[i].initField(val, vm);
      }
  
      cl->setStaticInstance(val);

      if (meth) {
        JavaObject* exc = 0;
        try{
          clinit_t pred = (clinit_t)(intptr_t)meth->compiledPtr();
          pred(vm, cl->getConstantPool());
        } catch(...) {
          exc = JavaThread::getJavaException();
          assert(exc && "no exception?");
          JavaThread::clearException();
        }
        if (exc) {
          if (exc->classOf->isAssignableFrom(vm->upcalls->newException)) {
            vm->initializerError(exc);
          } else {
            JavaThread::throwException(exc);
          }
        }
      }
      
      status = ready;
      broadcastClass();
    } else if (status < resolved) {
      release();
      vm->unknownError("try to clinit a not-read class...");
    } else {
      if (!ownerClass()) {
        while (status < ready) waitClass();
        release();
        initialiseClass(vm);
      } 
      release();
    }
  }
}


void Jnjvm::errorWithExcp(UserClass* cl, JavaMethod* init, const JavaObject* excp) {
  JavaObject* obj = cl->doNew(this);
  init->invokeIntSpecial(this, cl, obj, excp);
  JavaThread::throwException(obj);
}

void Jnjvm::error(UserClass* cl, JavaMethod* init, const char* fmt, ...) {
  char* tmp = (char*)alloca(4096);
  va_list ap;
  va_start(ap, fmt);
  vsnprintf(tmp, 4096, fmt, ap);
  va_end(ap);
  
  if (cl && !bootstrapLoader->getModule()->isStaticCompiling()) {
    JavaObject* obj = cl->doNew(this);
    init->invokeIntSpecial(this, cl, obj, asciizToStr(tmp));
    JavaThread::throwException(obj);
  } else {
    throw std::string(tmp);
  }
}

void Jnjvm::arrayStoreException() {
  error(upcalls->ArrayStoreException,
        upcalls->InitArrayStoreException, "");
}

void Jnjvm::indexOutOfBounds(const JavaObject* obj, sint32 entry) {
  error(upcalls->ArrayIndexOutOfBoundsException,
        upcalls->InitArrayIndexOutOfBoundsException, "%d", entry);
}

void Jnjvm::negativeArraySizeException(sint32 size) {
  error(upcalls->NegativeArraySizeException,
        upcalls->InitNegativeArraySizeException, "%d", size);
}

void Jnjvm::nullPointerException(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  char* val = va_arg(ap, char*);
  va_end(ap);
  error(upcalls->NullPointerException,
        upcalls->InitNullPointerException, fmt, val);
}

void Jnjvm::illegalAccessException(const char* msg) {
  error(upcalls->IllegalAccessException,
        upcalls->InitIllegalAccessException, msg);
}

void Jnjvm::illegalMonitorStateException(const JavaObject* obj) {
  error(upcalls->IllegalMonitorStateException,
        upcalls->InitIllegalMonitorStateException, "");
}

void Jnjvm::interruptedException(const JavaObject* obj) {
  error(upcalls->InterruptedException,
        upcalls->InitInterruptedException, "");
}


void Jnjvm::initializerError(const JavaObject* excp) {
  errorWithExcp(upcalls->ExceptionInInitializerError,
                upcalls->ErrorWithExcpExceptionInInitializerError,
                excp);
}

void Jnjvm::invocationTargetException(const JavaObject* excp) {
  errorWithExcp(upcalls->InvocationTargetException,
                upcalls->ErrorWithExcpInvocationTargetException,
                excp);
}

void Jnjvm::outOfMemoryError(sint32 n) {
  error(upcalls->OutOfMemoryError,
        upcalls->InitOutOfMemoryError, "%d", n);
}

void Jnjvm::illegalArgumentExceptionForMethod(JavaMethod* meth, 
                                              UserCommonClass* required,
                                              UserCommonClass* given) {
  error(upcalls->IllegalArgumentException, 
        upcalls->InitIllegalArgumentException, 
        "for method %s", meth->printString());
}

void Jnjvm::illegalArgumentExceptionForField(JavaField* field, 
                                             UserCommonClass* required,
                                             UserCommonClass* given) {
  error(upcalls->IllegalArgumentException, 
        upcalls->InitIllegalArgumentException, 
        "for field %s", field->printString());
}

void Jnjvm::illegalArgumentException(const char* msg) {
  error(upcalls->IllegalArgumentException,
        upcalls->InitIllegalArgumentException,
        msg);
}

void Jnjvm::classCastException(JavaObject* obj, UserCommonClass* cl) {
  error(upcalls->ClassCastException,
        upcalls->InitClassCastException,
        "");
}

void Jnjvm::noSuchFieldError(CommonClass* cl, const UTF8* name) {
  error(upcalls->NoSuchFieldError,
        upcalls->InitNoSuchFieldError, 
        "unable to find %s in %s",
        name->UTF8ToAsciiz(), cl->name->UTF8ToAsciiz());

}

void Jnjvm::noSuchMethodError(CommonClass* cl, const UTF8* name) {
  error(upcalls->NoSuchMethodError,
        upcalls->InitNoSuchMethodError, 
        "unable to find %s in %s",
        name->UTF8ToAsciiz(), cl->name->UTF8ToAsciiz());

}

void Jnjvm::classFormatError(const char* msg, ...) {
  error(upcalls->ClassFormatError,
        upcalls->InitClassFormatError, 
        msg);
}

void Jnjvm::noClassDefFoundError(JavaObject* obj) {
  errorWithExcp(upcalls->NoClassDefFoundError,
        upcalls->ErrorWithExcpNoClassDefFoundError, 
        obj);
}

void Jnjvm::noClassDefFoundError(const UTF8* name) {
  error(upcalls->NoClassDefFoundError,
        upcalls->InitNoClassDefFoundError, 
        "Unable to load %s", name->UTF8ToAsciiz());
}

void Jnjvm::classNotFoundException(JavaString* str) {
  error(upcalls->ClassNotFoundException,
        upcalls->InitClassNotFoundException, 
        "unable to load %s",
        str->strToAsciiz());
}

void Jnjvm::unknownError(const char* fmt, ...) {
  error(upcalls->UnknownError,
        upcalls->InitUnknownError,  
        fmt);
}

JavaString* Jnjvm::internalUTF8ToStr(const UTF8* utf8) {
  JavaString* res = hashStr.lookup(utf8);
  if (!res) {
    uint32 size = utf8->size;
    UTF8* tmp = (UTF8*)upcalls->ArrayOfChar->doNew(size, this);
    uint16* buf = tmp->elements;
  
    for (uint32 i = 0; i < size; i++) {
      buf[i] = utf8->elements[i];
    }
  
    const UTF8* newUTF8 = (const UTF8*)tmp;
    res = hashStr.lookupOrCreate(newUTF8, this, JavaString::stringDup);
  }
  return res;
}

JavaString* Jnjvm::UTF8ToStr(const UTF8* utf8) { 
  JavaString* res = hashStr.lookupOrCreate(utf8, this, JavaString::stringDup);
  return res;
}

JavaString* Jnjvm::asciizToStr(const char* asciiz) {
  const UTF8* var = asciizToUTF8(asciiz);
  return UTF8ToStr(var);
}

void Jnjvm::addProperty(char* key, char* value) {
  postProperties.push_back(std::make_pair(key, value));
}

JavaObject* UserCommonClass::getClassDelegatee(Jnjvm* vm, JavaObject* pd) {
  acquire();
  if (!(delegatee)) {
    UserClass* cl = vm->upcalls->newClass;
    JavaObject* delegatee = cl->doNew(vm);
    if (!pd) {
      vm->upcalls->initClass->invokeIntSpecial(vm, cl, delegatee, this);
    } else {
      vm->upcalls->initClassWithProtectionDomain->invokeIntSpecial(vm, cl,
                                                                   delegatee,
                                                                   this, pd);
    }
    this->delegatee = delegatee;
  }
  release();
  return delegatee;
}

#define PATH_MANIFEST "META-INF/MANIFEST.MF"
#define MAIN_CLASS "Main-Class: "
#define PREMAIN_CLASS "Premain-Class: "
#define BOOT_CLASS_PATH "Boot-Class-Path: "
#define CAN_REDEFINE_CLASS_PATH "Can-Redefine-Classes: "

#define LENGTH_MAIN_CLASS 12
#define LENGTH_PREMAIN_CLASS 15
#define LENGTH_BOOT_CLASS_PATH 17

extern "C" struct JNINativeInterface JNI_JNIEnvTable;
extern "C" const struct JNIInvokeInterface JNI_JavaVMTable;

namespace jnjvm {

class ClArgumentsInfo {
public:
  uint32 appArgumentsPos;
  char* className;
  std::vector< std::pair<char*, char*> > agents;

  void readArgs(int argc, char** argv, Jnjvm *vm);
  void extractClassFromJar(Jnjvm* vm, int argc, char** argv, int i);
  void javaAgent(char* cur);

  void printInformation();
  void nyi();
  void printVersion();
};

}

void ClArgumentsInfo::javaAgent(char* cur) {
  assert(0 && "implement me");
}

extern "C" int sys_strnstr(const char *haystack, const char *needle) {
  char * res = strstr(haystack, needle);
  if (res) return res - haystack;
  else return -1; 
}


static char* findInformation(Jnjvm* vm, ArrayUInt8* manifest, const char* entry,
                             uint32 len) {
  uint8* ptr = manifest->elements;
  sint32 index = sys_strnstr((char*)ptr, entry);
  if (index != -1) {
    index += len;
    sint32 end = sys_strnstr((char*)&(ptr[index]), "\n");
    if (end == -1) end = manifest->size;
    else end += index;

    sint32 length = end - index - 1;
    char* name = (char*)vm->allocator.Allocate(length + 1);
    memcpy(name, &(ptr[index]), length);
    name[length] = 0;
    return name;
  } else {
    return 0;
  }
}

void ClArgumentsInfo::extractClassFromJar(Jnjvm* vm, int argc, char** argv, 
                                          int i) {
  char* jarFile = argv[i];
  uint32 size = 2 + strlen(vm->classpath) + strlen(jarFile);
  char* temp = (char*)vm->allocator.Allocate(size);

  sprintf(temp, "%s:%s", vm->classpath, jarFile);
  vm->setClasspath(temp);
  
  ArrayUInt8* bytes = Reader::openFile(vm->bootstrapLoader, jarFile);

  ZipArchive archive(bytes, vm->allocator);
  if (archive.getOfscd() != -1) {
    ZipFile* file = archive.getFile(PATH_MANIFEST);
    if (file) {
      UserClassArray* array = vm->bootstrapLoader->upcalls->ArrayOfByte;
      ArrayUInt8* res = (ArrayUInt8*)array->doNew(file->ucsize, vm);
      int ok = archive.readFile(res, file);
      if (ok) {
        char* mainClass = findInformation(vm, res, MAIN_CLASS, LENGTH_MAIN_CLASS);
        if (mainClass) {
          className = mainClass;
        } else {
          printf("No Main-Class:  in Manifest of archive %s.\n", jarFile);
        }
      } else {
        printf("Can't extract Manifest file from archive %s\n", jarFile);
      }
    } else {
      printf("Can't find Manifest file in archive %s\n", jarFile);
    }
  } else {
    printf("Can't find archive %s\n", jarFile);
  }
}

void ClArgumentsInfo::nyi() {
  fprintf(stdout, "Not yet implemented\n");
}

void ClArgumentsInfo::printVersion() {
  fprintf(stdout, "JnJVM for Java 1.1 -- 1.5\n");
}

void ClArgumentsInfo::printInformation() {
  fprintf(stdout, 
  "Usage: java [-options] class [args...] (to execute a class)\n"
   "or  java [-options] -jar jarfile [args...]\n"
           "(to execute a jar file) where options include:\n"
    "-client       to select the \"client\" VM\n"
    "-server       to select the \"server\" VM\n"
    "-hotspot      is a synonym for the \"client\" VM  [deprecated]\n"
    "              The default VM is client.\n"
    "\n"
    "-cp <class search path of directories and zip/jar files>\n"
    "-classpath <class search path of directories and zip/jar files>\n"
    "              A : separated list of directories, JAR archives,\n"
    "              and ZIP archives to search for class files.\n"
    "-D<name>=<value>\n"
    "              set a system property\n"
    "-verbose[:class|gc|jni]\n"
    "              enable verbose output\n"
    "-version      print product version and exit\n"
    "-version:<value>\n"
    "              require the specified version to run\n"
    "-showversion  print product version and continue\n"
    "-jre-restrict-search | -jre-no-restrict-search\n"
    "              include/exclude user private JREs in the version search\n"
    "-? -help      print this help message\n"
    "-X            print help on non-standard options\n"
    "-ea[:<packagename>...|:<classname>]\n"
    "-enableassertions[:<packagename>...|:<classname>]\n"
    "              enable assertions\n"
    "-da[:<packagename>...|:<classname>]\n"
    "-disableassertions[:<packagename>...|:<classname>]\n"
    "              disable assertions\n"
    "-esa | -enablesystemassertions\n"
    "              enable system assertions\n"
    "-dsa | -disablesystemassertions\n"
    "              disable system assertions\n"
    "-agentlib:<libname>[=<options>]\n"
    "              load native agent library <libname>, e.g. -agentlib:hprof\n"
    "                see also, -agentlib:jdwp=help and -agentlib:hprof=help\n"
    "-agentpath:<pathname>[=<options>]\n"
    "              load native agent library by full pathname\n"
    "-javaagent:<jarpath>[=<options>]\n"
    "              load Java programming language agent, see java.lang.instrument\n");
}

void ClArgumentsInfo::readArgs(int argc, char** argv, Jnjvm* vm) {
  className = 0;
  appArgumentsPos = 0;
  sint32 i = 1;
  if (i == argc) printInformation();
  while (i < argc) {
    char* cur = argv[i];
    if (!(strcmp(cur, "-client"))) {
      nyi();
    } else if (!(strcmp(cur, "-server"))) {
      nyi();
    } else if (!(strcmp(cur, "-classpath"))) {
      ++i;
      if (i == argc) printInformation();
      else vm->setClasspath(argv[i]);
    } else if (!(strcmp(cur, "-cp"))) {
      ++i;
      if (i == argc) printInformation();
      else vm->setClasspath(argv[i]);
    } else if (!(strcmp(cur, "-debug"))) {
      nyi();
    } else if (!(strncmp(cur, "-D", 2))) {
      uint32 len = strlen(cur);
      if (len == 2) {
        printInformation();
      } else {
        char* key = &cur[2];
        char* value = strchr(key, '=');
        if (!value) {
          printInformation();
          return;
        } else {
          value[0] = 0;
          vm->addProperty(key, &value[1]);
        }
      }
    } else if (!(strncmp(cur, "-Xbootclasspath:", 16))) {
      uint32 len = strlen(cur);
      if (len == 16) {
        printInformation();
      } else {
        char* path = &cur[16];
        vm->bootstrapLoader->analyseClasspathEnv(path);
      }
    } else if (!(strcmp(cur, "-enableassertions"))) {
      nyi();
    } else if (!(strcmp(cur, "-ea"))) {
      nyi();
    } else if (!(strcmp(cur, "-disableassertions"))) {
      nyi();
    } else if (!(strcmp(cur, "-da"))) {
      nyi();
    } else if (!(strcmp(cur, "-enablesystemassertions"))) {
      nyi();
    } else if (!(strcmp(cur, "-esa"))) {
      nyi();
    } else if (!(strcmp(cur, "-disablesystemassertions"))) {
      nyi();
    } else if (!(strcmp(cur, "-dsa"))) {
      nyi();
    } else if (!(strcmp(cur, "-jar"))) {
      ++i;
      if (i == argc) {
        printInformation();
      } else {
        extractClassFromJar(vm, argc, argv, i);
        appArgumentsPos = i;
        return;
      }
    } else if (!(strcmp(cur, "-jre-restrict-research"))) {
      nyi();
    } else if (!(strcmp(cur, "-jre-no-restrict-research"))) {
      nyi();
    } else if (!(strcmp(cur, "-noclassgc"))) {
      nyi();
    } else if (!(strcmp(cur, "-ms"))) {
      nyi();
    } else if (!(strcmp(cur, "-mx"))) {
      nyi();
    } else if (!(strcmp(cur, "-ss"))) {
      nyi();
    } else if (!(strcmp(cur, "-verbose"))) {
      nyi();
    } else if (!(strcmp(cur, "-verbose:class"))) {
      nyi();
    } else if (!(strcmp(cur, "-verbosegc"))) {
      nyi();
    } else if (!(strcmp(cur, "-verbose:gc"))) {
      nyi();
    } else if (!(strcmp(cur, "-verbose:jni"))) {
      nyi();
    } else if (!(strcmp(cur, "-version"))) {
      printVersion();
    } else if (!(strcmp(cur, "-showversion"))) {
      nyi();
    } else if (!(strcmp(cur, "-?"))) {
      printInformation();
    } else if (!(strcmp(cur, "-help"))) {
      printInformation();
    } else if (!(strcmp(cur, "-X"))) {
      nyi();
    } else if (!(strcmp(cur, "-agentlib"))) {
      nyi();
    } else if (!(strcmp(cur, "-agentpath"))) {
      nyi();
    } else if (cur[0] == '-') {
    } else if (!(strcmp(cur, "-javaagent"))) {
      javaAgent(cur);
    } else {
      className = cur;
      appArgumentsPos = i;
      return;
    }
    ++i;
  }
}


void Jnjvm::print(mvm::PrintBuffer* buf) const {
  buf->write("Java isolate");
}

JnjvmClassLoader* Jnjvm::loadAppClassLoader() {
  if (appClassLoader == 0) {
    UserClass* cl = upcalls->newClassLoader;
    JavaObject* loader = 
      upcalls->getSystemClassLoader->invokeJavaObjectStatic(this, cl);
    appClassLoader = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader,
                                                                    this);
  }
  return appClassLoader;
}

void Jnjvm::mapInitialThread() {
  upcalls->mapInitialThread(this);
}

void Jnjvm::loadBootstrap() {
  JnjvmClassLoader* loader = bootstrapLoader;
#define LOAD_CLASS(cl) \
  cl->resolveClass(); \
  cl->initialiseClass(this);
  
  // If a string belongs to the vm hashmap, we must remove it when
  // it's destroyed. So we change the destructor of java.lang.String
  // to perform this action.
  LOAD_CLASS(upcalls->newString);
  uintptr_t* ptr = ((uintptr_t*)upcalls->newString->getVirtualVT());
  ptr[VT_DESTRUCTOR_OFFSET] = (uintptr_t)JavaString::stringDestructor;
  
  // To make classes non GC-allocated, we have to bypass the tracer
  // functions of java.lang.Class, java.lang.reflect.Field,
  // java.lang.reflect.Method and java.lang.reflect.constructor. The new
  // tracer functions trace the classloader instead of the class/field/method.
  LOAD_CLASS(upcalls->newClass);
  ptr = ((uintptr_t*)upcalls->newClass->getVirtualVT());
  ptr[VT_TRACER_OFFSET] = (uintptr_t)JavaObjectClass::staticTracer;

  LOAD_CLASS(upcalls->newConstructor);
  ptr = ((uintptr_t*)upcalls->newConstructor->getVirtualVT());
  ptr[VT_TRACER_OFFSET] = (uintptr_t)JavaObjectConstructor::staticTracer;

  
  LOAD_CLASS(upcalls->newMethod);
  ptr = ((uintptr_t*)upcalls->newMethod->getVirtualVT());
  ptr[VT_TRACER_OFFSET] = (uintptr_t)JavaObjectMethod::staticTracer;
  
  LOAD_CLASS(upcalls->newField);
  ptr = ((uintptr_t*)upcalls->newField->getVirtualVT());
  ptr[VT_TRACER_OFFSET] = (uintptr_t)JavaObjectField::staticTracer;
  
  LOAD_CLASS(upcalls->newStackTraceElement);
  LOAD_CLASS(upcalls->newVMThrowable);
  LOAD_CLASS(upcalls->boolClass);
  LOAD_CLASS(upcalls->byteClass);
  LOAD_CLASS(upcalls->charClass);
  LOAD_CLASS(upcalls->shortClass);
  LOAD_CLASS(upcalls->intClass);
  LOAD_CLASS(upcalls->longClass);
  LOAD_CLASS(upcalls->floatClass);
  LOAD_CLASS(upcalls->doubleClass);
  LOAD_CLASS(upcalls->InvocationTargetException);
  LOAD_CLASS(upcalls->ArrayStoreException);
  LOAD_CLASS(upcalls->ClassCastException);
  LOAD_CLASS(upcalls->IllegalMonitorStateException);
  LOAD_CLASS(upcalls->IllegalArgumentException);
  LOAD_CLASS(upcalls->InterruptedException);
  LOAD_CLASS(upcalls->IndexOutOfBoundsException);
  LOAD_CLASS(upcalls->ArrayIndexOutOfBoundsException);
  LOAD_CLASS(upcalls->NegativeArraySizeException);
  LOAD_CLASS(upcalls->NullPointerException);
  LOAD_CLASS(upcalls->SecurityException);
  LOAD_CLASS(upcalls->ClassFormatError);
  LOAD_CLASS(upcalls->ClassCircularityError);
  LOAD_CLASS(upcalls->NoClassDefFoundError);
  LOAD_CLASS(upcalls->UnsupportedClassVersionError);
  LOAD_CLASS(upcalls->NoSuchFieldError);
  LOAD_CLASS(upcalls->NoSuchMethodError);
  LOAD_CLASS(upcalls->InstantiationError);
  LOAD_CLASS(upcalls->IllegalAccessError);
  LOAD_CLASS(upcalls->IllegalAccessException);
  LOAD_CLASS(upcalls->VerifyError);
  LOAD_CLASS(upcalls->ExceptionInInitializerError);
  LOAD_CLASS(upcalls->LinkageError);
  LOAD_CLASS(upcalls->AbstractMethodError);
  LOAD_CLASS(upcalls->UnsatisfiedLinkError);
  LOAD_CLASS(upcalls->InternalError);
  LOAD_CLASS(upcalls->OutOfMemoryError);
  LOAD_CLASS(upcalls->StackOverflowError);
  LOAD_CLASS(upcalls->UnknownError);
  LOAD_CLASS(upcalls->ClassNotFoundException); 
#undef LOAD_CLASS

  mapInitialThread();
  loadAppClassLoader();
  JavaObject* obj = JavaThread::currentThread();
  JavaObject* javaLoader = appClassLoader->getJavaClassLoader();
  upcalls->setContextClassLoader->invokeIntSpecial(this, upcalls->newThread,
                                                   obj, javaLoader);
  // load and initialise math since it is responsible for dlopen'ing 
  // libjavalang.so and we are optimizing some math operations
  UserCommonClass* math = 
    loader->loadName(loader->asciizConstructUTF8("java/lang/Math"), true, true);
  math->initialiseClass(this);
}

void Jnjvm::executeClass(const char* className, ArrayObject* args) {
  try {
    JavaJIT::invokeOnceVoid(this, appClassLoader, className, "main",
                        "([Ljava/lang/String;)V", ACC_STATIC, args);
  }catch(...) {
  }

  JavaObject* exc = JavaThread::get()->pendingException;
  if (exc) {
    JavaThread::clearException();
    JavaObject* obj = JavaThread::currentThread();
    JavaObject* group = 
      upcalls->group->getObjectField(obj);
    try{
      upcalls->uncaughtException->invokeIntSpecial(this, upcalls->threadGroup,
                                                   group, obj, exc);
    }catch(...) {
      printf("Even uncaught exception throwed an exception!\n");
      assert(0);
    }
  }
}

void Jnjvm::executePremain(const char* className, JavaString* args,
                             JavaObject* instrumenter) {
  JavaJIT::invokeOnceVoid(this, appClassLoader, className, "premain",
          "(Ljava/lang/String;Ljava/lang/instrument/Instrumentation;)V",
          ACC_STATIC, args, instrumenter);
}

void Jnjvm::waitForExit() { 
  threadSystem.nonDaemonLock.lock();
  --(threadSystem.nonDaemonThreads);
  
  while (threadSystem.nonDaemonThreads) {
    threadSystem.nonDaemonVar.wait(&threadSystem.nonDaemonLock);
  }

  threadSystem.nonDaemonLock.unlock();  
  return;
}

void Jnjvm::runApplication(int argc, char** argv) {
  ClArgumentsInfo info;

  info.readArgs(argc, argv, this);
  if (info.className) {
    int pos = info.appArgumentsPos;
    
    argv = argv + pos - 1;
    argc = argc - pos + 1;
    
    mvm::Thread* oldThread = mvm::Thread::get();
    JavaThread thread(0, this, oldThread->baseSP);
    bootstrapThread = &thread;

    loadBootstrap();

#ifdef SERVICE_VM
    ServiceDomain::initialise((ServiceDomain*)this);
#endif
    
    if (info.agents.size()) {
      assert(0 && "implement me");
      JavaObject* instrumenter = 0;//createInstrumenter();
      for (std::vector< std::pair<char*, char*> >::iterator i = 
                                                  info.agents.begin(),
              e = info.agents.end(); i!= e; ++i) {
        JavaString* args = asciizToStr(i->second);
        executePremain(i->first, args, instrumenter);
      }
    }
    
    UserClassArray* array = bootstrapLoader->upcalls->ArrayOfString;
    ArrayObject* args = (ArrayObject*)array->doNew(argc - 2, this);
    for (int i = 2; i < argc; ++i) {
      args->elements[i - 2] = (JavaObject*)asciizToStr(argv[i]);
    }

    executeClass(info.className, args);
    waitForExit();
    mvm::Thread::set(oldThread);
  }
}

Jnjvm::Jnjvm(JnjvmBootstrapLoader* loader) {

  classpath = getenv("CLASSPATH");
  if (!classpath) classpath = ".";
  
  appClassLoader = 0;
  jniEnv = &JNI_JNIEnvTable;
  javavmEnv = &JNI_JavaVMTable;
  

  bootstrapLoader = loader;
  upcalls = bootstrapLoader->upcalls;

  throwable = upcalls->newThrowable;
   
}

const UTF8* Jnjvm::asciizToInternalUTF8(const char* asciiz) {
  uint32 size = strlen(asciiz);
  UTF8* tmp = (UTF8*)upcalls->ArrayOfChar->doNew(size, this);
  uint16* buf = tmp->elements;
  
  for (uint32 i = 0; i < size; i++) {
    if (asciiz[i] == '.') buf[i] = '/';
    else buf[i] = asciiz[i];
  }
  return (const UTF8*)tmp;

}
  
const UTF8* Jnjvm::asciizToUTF8(const char* asciiz) {
  uint32 size = strlen(asciiz);
  UTF8* tmp = (UTF8*)upcalls->ArrayOfChar->doNew(size, this);
  uint16* buf = tmp->elements;
  
  for (uint32 i = 0; i < size; i++) {
    buf[i] = asciiz[i];
  }
  return (const UTF8*)tmp;
}


static void compileClass(Class* cl) {

  for (uint32 i = 0; i < cl->nbVirtualMethods; ++i) {
    JavaMethod& meth = cl->virtualMethods[i];
    if (!isAbstract(meth.access))
      cl->classLoader->TheModuleProvider->parseFunction(&meth);
  }
  
  for (uint32 i = 0; i < cl->nbStaticMethods; ++i) {
    JavaMethod& meth = cl->staticMethods[i];
    if (!isAbstract(meth.access))
      cl->classLoader->TheModuleProvider->parseFunction(&meth);
  }
}


void Jnjvm::compile(const char* name) {
  bootstrapLoader->analyseClasspathEnv(classpath);
    
  mvm::Thread* oldThread = mvm::Thread::get();
  JavaThread thread(0, this, oldThread->baseSP);
  bootstrapThread = &thread;
  
  
  uint32 size = strlen(name);
  if (size > 4 && 
      (!strcmp(&name[size - 4], ".jar") || !strcmp(&name[size - 4], ".zip"))) {
  

    std::vector<Class*> classes;

    ArrayUInt8* bytes = Reader::openFile(bootstrapLoader, name);
    if (!bytes) unknownError("Can't find zip file.");
    ZipArchive archive(bytes, bootstrapLoader->allocator);
    
    char* realName = (char*)alloca(4096);
    for (ZipArchive::table_iterator i = archive.filetable.begin(), 
         e = archive.filetable.end(); i != e; ++i) {
      ZipFile* file = i->second;
      
      size = strlen(file->filename);
      if (size > 6 && !strcmp(&(file->filename[size - 6]), ".class")) {
        UserClassArray* array = bootstrapLoader->upcalls->ArrayOfByte;
        ArrayUInt8* res = (ArrayUInt8*)array->doNew(file->ucsize,
                                                    bootstrapLoader->allocator);
        int ok = archive.readFile(res, file);
        if (!ok) unknownError("Wrong zip file.");
      
        
        memcpy(realName, file->filename, size);
        realName[size - 6] = 0;
        const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(realName);
        Class* cl = bootstrapLoader->constructClass(utf8, res);
        classes.push_back(cl);
      }
    }

    // First resolve everyone so that there can not be unknown references in
    // constant pools.
    for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end(); 
         i != e; ++i) {
      Class* cl = *i;
      cl->resolveClass();
    }
      
    for (std::vector<Class*>::iterator i = classes.begin(), e = classes.end(); 
         i != e; ++i) {
      Class* cl = *i;
      if (!cl->isInterface()) compileClass(cl);
    }

  } else {

    const UTF8* utf8 = bootstrapLoader->asciizConstructUTF8(name);
    UserClass* cl = bootstrapLoader->loadName(utf8, true, true);
    compileClass(cl);
  }
   
  // Set the linkage to External, so that the printer does not complain.
  llvm::Module* M = bootstrapLoader->getModule();
  for (Module::iterator i = M->begin(), e = M->end(); i != e; ++i) {
    i->setLinkage(llvm::GlobalValue::ExternalLinkage);
  }
  
  mvm::Thread::set(oldThread);
}
