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

#define JNJVM_LOAD 1

#include <cfloat>
#include <climits>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include "debug.h"

#include "vmkit/Thread.h"
#include "VmkitGC.h"

#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "j3/JavaCompiler.h"
#include "JavaConstantPool.h"
#include "JavaString.h"
#include "JavaThread.h"
#include "JavaTypes.h"
#include "JavaUpcalls.h"
#include "Jnjvm.h"
#include "LinkJavaRuntime.h"
#include "LockedMap.h"
#include "Reader.h"
#include "JavaReferenceQueue.h"
#include "VMStaticInstance.h"
#include "Zip.h"

using namespace j3;

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

/**
 * In JVM specification, the virtual machine should execute some code when
 *  the application finish.
 * See Runtime.addShutdownHook
 * In GNUClasspath the default behavior when the program call System.exit
 * is to execute such a code.
 * Hence, the only mission of this thread is to call System.exit when
 * the user press Ctrl_C
 */
void threadToDetectCtrl_C(vmkit::Thread* th) {
	while (!vmkit::finishForCtrl_C) {
		vmkit::lockForCtrl_C.lock();
		vmkit::condForCtrl_C.wait(&vmkit::lockForCtrl_C);
		vmkit::lockForCtrl_C.unlock(th);
	}
	JavaThread* kk = (JavaThread*)th;
	UserClass* cl = kk->getJVM()->upcalls->SystemClass;
	kk->getJVM() -> upcalls->SystemExit->invokeIntStatic(kk->getJVM(), cl, 0);
}


/// initialiseClass - Java class initialization. Java specification §2.17.5.

void UserClass::initialiseClass(Jnjvm* vm) {
  JavaObject* exc = NULL;
  JavaObject* obj = NULL;
  llvm_gcroot(exc, 0);
  llvm_gcroot(obj, 0);
  
  // Primitives are initialized at boot time, arrays are initialized directly.
  
  // Assumes that the Class object has already been verified and prepared and
  // that the Class object contains state that can indicate one of four
  // situations:
  //
  //  * This Class object is verified and prepared but not initialized.
  //  * This Class object is being initialized by some particular thread T.
  //  * This Class object is fully initialized and ready for use.
  //  * This Class object is in an erroneous state, perhaps because the
  //    verification step failed or because initialization was attempted and
  //    failed.

  assert((isResolved() || getOwnerClass() || isReady() ||
         isErroneous()) && "Class in wrong state");
  
  if (getInitializationState() != ready) {
    
    // 1. Synchronize on the Class object that represents the class or 
    //    interface to be initialized. This involves waiting until the
    //    current thread can obtain the lock for that object
    //    (Java specification §8.13).
    acquire();
    JavaThread* self = JavaThread::get();

    if (getInitializationState() == inClinit) {
      // 2. If initialization by some other thread is in progress for the
      //    class or interface, then wait on this Class object (which 
      //    temporarily releases the lock). When the current thread awakens
      //    from the wait, repeat this step.
      if (getOwnerClass() != self) {
        while (getOwnerClass()) {
          waitClass();
        }
      } else {
        // 3. If initialization is in progress for the class or interface by
        //    the current thread, then this must be a recursive request for 
        //    initialization. Release the lock on the Class object and complete
        //    normally.
        release();
        return;
      }
    } 
    
    // 4. If the class or interface has already been initialized, then no 
    //    further action is required. Release the lock on the Class object
    //    and complete normally.
    if (getInitializationState() == ready) {
      release();
      return;
    }
    
    // 5. If the Class object is in an erroneous state, then initialization is
    //    not possible. Release the lock on the Class object and throw a
    //    NoClassDefFoundError.
    if (isErroneous()) {
      release();
      vm->noClassDefFoundError(name);
    }

    // 6. Otherwise, record the fact that initialization of the Class object is
    //    now in progress by the current thread and release the lock on the
    //    Class object.
    setOwnerClass(self);
    setInitializationState(inClinit);
    UserClass* cl = (UserClass*)this;
    
    // Single environment allocates the static instance during resolution, so
    // that compiled code can access it directly (with an initialization
    // check just before the access)
    if (!cl->getStaticInstance()) cl->allocateStaticInstance(vm);

    release();
  

    // 7. Next, if the Class object represents a class rather than an interface, 
    //    and the direct superclass of this class has not yet been initialized,
    //    then recursively perform this entire procedure for the uninitialized 
    //    superclass. If the initialization of the direct superclass completes 
    //    abruptly because of a thrown exception, then lock this Class object, 
    //    label it erroneous, notify all waiting threads, release the lock, 
    //    and complete abruptly, throwing the same exception that resulted from 
    //    the initializing the superclass.
    UserClass* super = getSuper();
    if (super) {
      TRY {
        super->initialiseClass(vm);
      } CATCH {
        acquire();
        setErroneous();
        setOwnerClass(0);
        broadcastClass();
        release();
      } END_CATCH;
      if (self->pendingException != NULL) {
        self->throwPendingException();
        return;
      }
    }
 
    // 8. Next, execute either the class variable initializers and static
    //    initializers of the class or the field initializers of the interface,
    //    in textual order, as though they were a single block, except that
    //    final static variables and fields of interfaces whose values are 
    //    compile-time constants are initialized first.
    
    //PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "; ");
    PRINT_DEBUG(JNJVM_LOAD, 0, LIGHT_GREEN, "clinit ");
    PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "%s\n", UTF8Buffer(this->name).cString());

    JavaField* fields = cl->getStaticFields();
    for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
      fields[i].InitStaticField(vm);
    }
  
    JavaMethod* meth = lookupMethodDontThrow(vm->bootstrapLoader->clinitName,
                                             vm->bootstrapLoader->clinitType,
                                             true, false, 0);

    if (meth) {
      TRY {
        meth->invokeIntStatic(vm, cl);
      } CATCH {
        exc = self->getJavaException();
        assert(exc && "no exception?");
        self->clearException();
      } END_CATCH;
    }

    // 9. If the execution of the initializers completes normally, then lock
    //    this Class object, label it fully initialized, notify all waiting 
    //    threads, release the lock, and complete this procedure normally.
    if (!exc) {
      acquire();
      setInitializationState(ready);
      setOwnerClass(0);
      broadcastClass();
      release();
      return;
    }
    
    // 10. Otherwise, the initializers must have completed abruptly by
    //     throwing some exception E. If the class of E is not Error or one
    //     of its subclasses, then create a new instance of the class 
    //     ExceptionInInitializerError, with E as the argument, and use this
    //     object in place of E in the following step. But if a new instance of
    //     ExceptionInInitializerError cannot be created because an
    //     OutOfMemoryError occurs, then instead use an OutOfMemoryError object
    //     in place of E in the following step.
    if (JavaObject::getClass(exc)->isSubclassOf(vm->upcalls->newException)) {
      Classpath* upcalls = classLoader->bootstrapLoader->upcalls;
      UserClass* clExcp = upcalls->ExceptionInInitializerError;
      Jnjvm* vm = self->getJVM();
      obj = clExcp->doNew(vm);
      if (obj == NULL) {
        fprintf(stderr, "implement me");
        abort();
      }
      JavaMethod* init = upcalls->ErrorWithExcpExceptionInInitializerError;
      init->invokeIntSpecial(vm, clExcp, obj, &exc);
      exc = obj;
    } 

    // 11. Lock the Class object, label it erroneous, notify all waiting
    //     threads, release the lock, and complete this procedure abruptly
    //     with reason E or its replacement as determined in the previous step.
    acquire();
    setErroneous();
    setOwnerClass(0);
    broadcastClass();
    release();
    self->throwException(exc);
    return;
  }
}
      
void Jnjvm::errorWithExcp(UserClass* cl, JavaMethod* init,
                          const JavaObject* excp) {
  JavaObject* obj = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(excp, 0);

  obj = cl->doNew(this);
  init->invokeIntSpecial(this, cl, obj, &excp);
  JavaThread::get()->throwException(obj);
}

JavaObject* Jnjvm::CreateError(UserClass* cl, JavaMethod* init,
                               const char* asciiz) {
  JavaObject* obj = NULL;
  JavaString* str = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(str, 0);
  obj = cl->doNew(this);

  if (asciiz) str = asciizToStr(asciiz);

  init->invokeIntSpecial(this, cl, obj, &str);
  return obj;
}

JavaObject* Jnjvm::CreateError(UserClass* cl, JavaMethod* init,
                               JavaString* str) {
  JavaObject* obj = NULL;
  llvm_gcroot(str, 0);
  llvm_gcroot(obj, 0);
  obj = cl->doNew(this);
  init->invokeIntSpecial(this, cl, obj, &str);
  return obj;
}

void Jnjvm::error(UserClass* cl, JavaMethod* init, JavaString* str) {
  JavaObject* obj = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(str, 0);
  obj = CreateError(cl, init, str);
  JavaThread::get()->throwException(obj);
}

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

void Jnjvm::indexOutOfBounds(const JavaObject* obj, sint32 entry) {
  JavaString* str = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(str, 0);
  str = (JavaString*)upcalls->IntToString->invokeJavaObjectStatic(
      this, upcalls->intClass, entry, 10);
  error(upcalls->ArrayIndexOutOfBoundsException,
        upcalls->InitArrayIndexOutOfBoundsException, str);
}

void Jnjvm::negativeArraySizeException(sint32 size) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = (JavaString*)
    upcalls->IntToString->invokeJavaObjectStatic(this, upcalls->intClass,
                                                 size, 10);
  error(upcalls->NegativeArraySizeException,
        upcalls->InitNegativeArraySizeException, str);
}

void Jnjvm::nullPointerException() {
  error(upcalls->NullPointerException,
        upcalls->InitNullPointerException, (JavaString*)0);
}

void Jnjvm::cloneNotSupportedException() {
  error(upcalls->CloneNotSupportedException,
        upcalls->InitCloneNotSupportedException, (JavaString*)0);
}

JavaObject* Jnjvm::CreateIndexOutOfBoundsException(sint32 entry) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = (JavaString*)
    upcalls->IntToString->invokeJavaObjectStatic(this, upcalls->intClass,
                                                 entry, 10);
  return CreateError(upcalls->ArrayIndexOutOfBoundsException,
                     upcalls->InitArrayIndexOutOfBoundsException, str);
}

JavaObject* Jnjvm::CreateNegativeArraySizeException() {
  return CreateError(upcalls->NegativeArraySizeException,
                     upcalls->InitNegativeArraySizeException,
                     (JavaString*)0);
}

JavaObject* Jnjvm::CreateUnsatisfiedLinkError(JavaMethod* meth) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = constructString(meth->toString());
  return CreateError(upcalls->UnsatisfiedLinkError,
                     upcalls->InitUnsatisfiedLinkError,
                     str);
}

JavaObject* Jnjvm::CreateArithmeticException() {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr("/ by zero");
  return CreateError(upcalls->ArithmeticException,
                     upcalls->InitArithmeticException, str);
}

JavaObject* Jnjvm::CreateNullPointerException() {
  return CreateError(upcalls->NullPointerException,
                     upcalls->InitNullPointerException,
                     (JavaString*)0);
}

JavaObject* Jnjvm::CreateOutOfMemoryError() {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr("Java heap space");
  return CreateError(upcalls->OutOfMemoryError,
                     upcalls->InitOutOfMemoryError, str);
}

JavaObject* Jnjvm::CreateStackOverflowError() {
  // Don't call init, or else we'll get a new stack overflow error.
  JavaObjectThrowable* obj = NULL;
  llvm_gcroot(obj, 0);
  obj = (JavaObjectThrowable*)upcalls->StackOverflowError->doNew(this);
  JavaObjectThrowable::fillInStackTrace(obj);
  return obj;
}

void Jnjvm::stackOverflowError() {
  JavaThread::get()->throwException(CreateStackOverflowError());
  UNREACHABLE();
}

JavaObject* Jnjvm::CreateArrayStoreException(JavaVirtualTable* VT) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  if (VT != NULL) str = JavaString::internalToJava(VT->cl->name, this);
  return CreateError(upcalls->ArrayStoreException,
                     upcalls->InitArrayStoreException, str);
}

JavaObject* Jnjvm::CreateClassCastException(JavaObject* obj,
                                            UserCommonClass* cl) {
  llvm_gcroot(obj, 0);
  return CreateError(upcalls->ClassCastException,
                     upcalls->InitClassCastException,
                     (JavaString*)0);
}

JavaObject* Jnjvm::CreateLinkageError(const char* msg) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr(msg);
  return CreateError(upcalls->LinkageError,
                     upcalls->InitLinkageError, str);
}

void Jnjvm::illegalAccessException(const char* msg) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr(msg);
  error(upcalls->IllegalAccessException,
        upcalls->InitIllegalAccessException, str);
}

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

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


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

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

void Jnjvm::outOfMemoryError() {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr("Java heap space");
  error(upcalls->OutOfMemoryError,
        upcalls->InitOutOfMemoryError, str);
}

void Jnjvm::illegalArgumentException(const char* msg) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr(msg);
  error(upcalls->IllegalArgumentException,
        upcalls->InitIllegalArgumentException, str);
}

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

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

void Jnjvm::instantiationException(UserCommonClass* cl) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = internalUTF8ToStr(cl->name);
  error(upcalls->InstantiationException, upcalls->InitInstantiationException,
        str);
}

void Jnjvm::instantiationError(UserCommonClass* cl) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = internalUTF8ToStr(cl->name);
  error(upcalls->InstantiationError, upcalls->InitInstantiationError, str);
}
  

JavaString* CreateNoSuchMsg(CommonClass* cl, const UTF8* name,
                            Jnjvm* vm) {
  ArrayUInt16* msg = NULL;
  JavaString* str = NULL;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);
  msg = (ArrayUInt16*)
    vm->upcalls->ArrayOfChar->doNew(19 + cl->name->size + name->size, vm);

  uint32 i = 0;


  ArrayUInt16::setElement(msg, 'u', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'b', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'e', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 't', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'f', i); i++;
  ArrayUInt16::setElement(msg, 'i', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;

  for (sint32 j = 0; j < name->size; ++j) {
    ArrayUInt16::setElement(msg, name->elements[j], i);
    i++;
  }

  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'i', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  
  for (sint32 j = 0; j < cl->name->size; ++j) {
    if (cl->name->elements[j] == '/') {
      ArrayUInt16::setElement(msg, '.', i);
      i++;
    } else {
      ArrayUInt16::setElement(msg, cl->name->elements[j], i);
      i++;
    }
  }

  str = vm->constructString(msg);

  return str;
}

void Jnjvm::noSuchFieldError(CommonClass* cl, const UTF8* name) { 
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = CreateNoSuchMsg(cl, name, this);
  error(upcalls->NoSuchFieldError,
        upcalls->InitNoSuchFieldError, str);
}

void Jnjvm::noSuchMethodError(CommonClass* cl, const UTF8* name) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = CreateNoSuchMsg(cl, name, this);
  error(upcalls->NoSuchMethodError,
        upcalls->InitNoSuchMethodError, str);
}

void Jnjvm::abstractMethodError(CommonClass* cl, const UTF8* name) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = CreateNoSuchMsg(cl, name, this);
  error(upcalls->AbstractMethodError,
        upcalls->InitAbstractMethodError, str);
}

JavaString* CreateUnableToLoad(const UTF8* name, Jnjvm* vm) {
  ArrayUInt16* msg = NULL;
  JavaString* str = NULL;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);

  msg = (ArrayUInt16*)vm->upcalls->ArrayOfChar->doNew(15 + name->size, vm);
  uint32 i = 0;


  ArrayUInt16::setElement(msg, 'u', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'b', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'e', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 't', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;

  for (sint32 j = 0; j < name->size; ++j) {
    if (name->elements[j] == '/') {
      ArrayUInt16::setElement(msg, '.', i); i++;
    } else {
      ArrayUInt16::setElement(msg, name->elements[j], i); i++;
    }
  }

  str = vm->constructString(msg);

  return str;
}

JavaString* CreateUnableToLoad(JavaString* name, Jnjvm* vm) {
  JavaString* str = NULL;
  ArrayUInt16* msg = NULL;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);

  msg = (ArrayUInt16*)vm->upcalls->ArrayOfChar->doNew(15 + name->count, vm);
  uint32 i = 0;

  ArrayUInt16::setElement(msg, 'u', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'b', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'e', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 't', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;

  for (sint32 j = name->offset; j < name->offset + name->count; ++j) {
    if (ArrayUInt16::getElement(JavaString::getValue(name), j) == '/') {
      ArrayUInt16::setElement(msg, '.', i); i++;
    } else {
      ArrayUInt16::setElement(msg, ArrayUInt16::getElement(JavaString::getValue(name), j), i); i++;
    }
  }

  str = vm->constructString(msg);

  return str;
}



void Jnjvm::noClassDefFoundError(const UTF8* name) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = CreateUnableToLoad(name, this);
  error(upcalls->NoClassDefFoundError,
        upcalls->InitNoClassDefFoundError, str);
}

void Jnjvm::classNotFoundException(JavaString* name) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = CreateUnableToLoad(name, this);
  error(upcalls->ClassNotFoundException,
        upcalls->InitClassNotFoundException, str);
}

void Jnjvm::noClassDefFoundError(UserClass* cl, const UTF8* name) {
  ArrayUInt16* msg = NULL;
  JavaString* str = NULL;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);

  uint32 size = 35 + name->size + cl->name->size;
  msg = (ArrayUInt16*)upcalls->ArrayOfChar->doNew(size, this);
  uint32 i = 0;


  ArrayUInt16::setElement(msg, 't', i); i++;
  ArrayUInt16::setElement(msg, 'r', i); i++;
  ArrayUInt16::setElement(msg, 'y', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 't', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;

  for (sint32 j = 0; j < cl->name->size; ++j) {
    if (cl->name->elements[j] == '/') {
      ArrayUInt16::setElement(msg, '.', i); i++;
    } else {
      ArrayUInt16::setElement(msg, cl->name->elements[j], i); i++;
    }
  }
  
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'f', i); i++;
  ArrayUInt16::setElement(msg, 'o', i); i++;
  ArrayUInt16::setElement(msg, 'u', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'c', i); i++;
  ArrayUInt16::setElement(msg, 'l', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 's', i); i++;
  ArrayUInt16::setElement(msg, 's', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  ArrayUInt16::setElement(msg, 'n', i); i++;
  ArrayUInt16::setElement(msg, 'a', i); i++;
  ArrayUInt16::setElement(msg, 'm', i); i++;
  ArrayUInt16::setElement(msg, 'e', i); i++;
  ArrayUInt16::setElement(msg, 'd', i); i++;
  ArrayUInt16::setElement(msg, ' ', i); i++;
  
  for (sint32 j = 0; j < name->size; ++j) {
    if (name->elements[j] == '/') {
      ArrayUInt16::setElement(msg, '.', i); i++;
    } else {
      ArrayUInt16::setElement(msg, name->elements[j], i); i++;
    }
  }
 
  assert(i == size && "Array overflow");

  str = constructString(msg);
  error(upcalls->NoClassDefFoundError, upcalls->InitNoClassDefFoundError, str);
}


void Jnjvm::classFormatError(const char* msg) {
  JavaString* str = NULL;
  llvm_gcroot(str, 0);
  str = asciizToStr(msg);
  error(upcalls->ClassFormatError, upcalls->InitClassFormatError, str);
}

JavaString* Jnjvm::internalUTF8ToStr(const UTF8* utf8) {
  ArrayUInt16* tmp = NULL;
  llvm_gcroot(tmp, 0);
  uint32 size = utf8->size;
  tmp = (ArrayUInt16*)upcalls->ArrayOfChar->doNew(size, this);
  
  for (uint32 i = 0; i < size; i++) {
    ArrayUInt16::setElement(tmp, utf8->elements[i], i);
  }

  return constructString(tmp);
}

JavaString* Jnjvm::constructString(const ArrayUInt16* array) { 
  JavaString* key = NULL;
  llvm_gcroot(array, 0);
  llvm_gcroot(key, 0);
  key = JavaString::create(array, this);
  if (upcalls->internString) {
    return (JavaString*)upcalls->internString->invokeJavaObjectStatic(
        this, upcalls->internString->classDef, &key);
  } else {
    return key;
  }
}

JavaString* Jnjvm::asciizToStr(const char* asciiz) {
  ArrayUInt16* var = NULL;
  llvm_gcroot(var, 0);
  assert(asciiz && "No asciiz given");
  var = asciizToArray(asciiz);
  return constructString(var);
}

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

// Mimic what's happening in Classpath when creating a java.lang.Class object.
JavaObject* UserCommonClass::getClassDelegatee(Jnjvm* vm, JavaObject* pd) {
  JavaObjectClass* delegatee = 0;
  JavaObjectClass* base = 0;
  llvm_gcroot(pd, 0);
  llvm_gcroot(delegatee, 0);
  llvm_gcroot(base, 0);

  if (getDelegatee() == NULL) {
    UserClass* cl = vm->upcalls->newClass;
    delegatee = (JavaObjectClass*)cl->doNew(vm);
    JavaObjectClass::setClass(delegatee, this);
    if (pd == NULL && isArray()) {
      base = (JavaObjectClass*)
        asArrayClass()->baseClass()->getClassDelegatee(vm, pd);
      JavaObjectClass::setProtectionDomain(
        delegatee, JavaObjectClass::getProtectionDomain(base));
    } else {
      JavaObjectClass::setProtectionDomain(delegatee, pd);
    }
    setDelegatee(delegatee);
  }
  return getDelegatee();
}

JavaObject* const* UserCommonClass::getClassDelegateePtr(Jnjvm* vm, JavaObject* pd) {
  llvm_gcroot(pd, 0);
  // Make sure it's created.
  getClassDelegatee(vm, pd);
  return getDelegateePtr();
}

#define PATH_MANIFEST "META-INF/MANIFEST.MF"
#define MAIN_CLASS "Main-Class: "
#define MAIN_LOWER_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;

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

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


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

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

void ClArgumentsInfo::extractClassFromJar(Jnjvm* vm, int argc, char** argv, 
                                          int i) {
  ClassBytes* bytes = NULL;
  ClassBytes* res = NULL;
  jarFile = argv[i];

  vm->setClasspath(jarFile);
  
  bytes = Reader::openFile(vm->bootstrapLoader, jarFile);

  if (bytes == NULL) {
    printf("Unable to access jarfile %s\n", jarFile);
    return;
  }

  vmkit::BumpPtrAllocator allocator;
  ZipArchive* archive = new(allocator, "TempZipArchive")
      ZipArchive(bytes, allocator);
  if (archive->getOfscd() != -1) {
    ZipFile* file = archive->getFile(PATH_MANIFEST);
    if (file != NULL) {
      res = new (allocator, file->ucsize) ClassBytes(file->ucsize);
      int ok = archive->readFile(res, file);
      if (ok) {
        char* mainClass = findInformation(vm, res, MAIN_CLASS,
                                          LENGTH_MAIN_CLASS);
        if (mainClass == NULL) {
          mainClass = findInformation(vm, res, MAIN_LOWER_CLASS,
                                      LENGTH_MAIN_CLASS);
        }
        if (mainClass != NULL) {
          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, "J3 for Java 1.1 -- 1.5\n");
}

void ClArgumentsInfo::printInformation() {
  fprintf(stdout, 
  "Usage: j3 [-options] class [args...] (to execute a class)\n"
   "or  j3 [-options] -jar jarfile [args...]\n"
           "(to execute a jar file) where options include:\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(Jnjvm* vm) {
  className = 0;
  appArgumentsPos = 0;
  sint32 i = 1;
  if (i == argc) printInformation();
  while (i < argc) {
    char* cur = argv[i];
    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 (!(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 (!(strncmp(cur, "-Xbootclasspath/a:", 18))) {
	  uint32 len = strlen(cur);
	  if (len == 18) {
		printInformation();
	  } else {
		char* path = &cur[18];
		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"))) {
      vmkit::Collector::verbose = 1;
    } 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;
  }
}


JnjvmClassLoader* Jnjvm::loadAppClassLoader() {
  JavaObject* loader = 0;
  llvm_gcroot(loader, 0);
  
  if (appClassLoader == NULL) {
    UserClass* cl = upcalls->newClassLoader;
    loader = upcalls->getSystemClassLoader->invokeJavaObjectStatic(this, cl);
    appClassLoader = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader,
                                                                    this);
    if (argumentsInfo.jarFile) {
      appClassLoader->loadLibFromJar(this, argumentsInfo.jarFile,
                                     argumentsInfo.className);
    } else if (argumentsInfo.className) {
      appClassLoader->loadLibFromFile(this, argumentsInfo.className);
    }
  }
  return appClassLoader;
}

void Jnjvm::loadBootstrap() {
  JavaObject* obj = NULL;
  JavaObject* javaLoader = NULL;
  llvm_gcroot(obj, 0);
  llvm_gcroot(javaLoader, 0);
  JnjvmBootstrapLoader* loader = bootstrapLoader;
  
  // First create system threads.
  finalizerThread = new JavaFinalizerThread(this);
  finalizerThread->start(
      (void (*)(vmkit::Thread*))JavaFinalizerThread::finalizerStart);
    
  referenceThread = new JavaReferenceThread(this);
  referenceThread->start(
      (void (*)(vmkit::Thread*))JavaReferenceThread::enqueueStart);
  
  // Initialize the bootstrap class loader if it's not
  // done already.
  if (bootstrapLoader->upcalls->newString == NULL) {
    bootstrapLoader->upcalls->initialiseClasspath(bootstrapLoader);
  }
  
#define LOAD_CLASS(cl) \
  cl->resolveClass(); \
  cl->initialiseClass(this);
  
  LOAD_CLASS(upcalls->newString);

  // The initialization code of the classes initialized below may require
  // to get the Java thread, so we create the Java thread object first.
  upcalls->InitializeThreading(this);
  
  LOAD_CLASS(upcalls->newClass);
  LOAD_CLASS(upcalls->newConstructor);
  LOAD_CLASS(upcalls->newField);
  LOAD_CLASS(upcalls->newMethod);
  LOAD_CLASS(upcalls->newStackTraceElement);
  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); 
  LOAD_CLASS(upcalls->ArithmeticException); 
  LOAD_CLASS(upcalls->InstantiationException);
  LOAD_CLASS(upcalls->SystemClass);
  LOAD_CLASS(upcalls->cloneableClass);
  LOAD_CLASS(upcalls->CloneNotSupportedException);
#undef LOAD_CLASS

  // Implementation-specific end-of-bootstrap initialization
  upcalls->InitializeSystem(this);

  loadAppClassLoader();
  obj = JavaThread::get()->currentThread();
  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->mathName, true, true, NULL);
  math->asClass()->initialiseClass(this);
}

void Jnjvm::executeClass(const char* className, ArrayObject* args) {
  JavaObject* exc = NULL;
  JavaObject* obj = NULL;
  JavaObject* handler = NULL;
  
  llvm_gcroot(args, 0);
  llvm_gcroot(exc, 0);
  llvm_gcroot(obj, 0);
  llvm_gcroot(handler, 0);

  TRY {
    // First try to see if we are a self-contained executable.
    UserClass* cl = appClassLoader->loadClassFromSelf(this, className);
    
    // If not, load the class.
    if (cl == NULL) {
      const UTF8* name = appClassLoader->asciizConstructUTF8(className);
      cl = (UserClass*)appClassLoader->loadName(name, true, true, NULL);
    }
    
    cl->initialiseClass(this);
  
    const UTF8* funcSign = 
      appClassLoader->asciizConstructUTF8("([Ljava/lang/String;)V");
    const UTF8* funcName = appClassLoader->asciizConstructUTF8("main");
    JavaMethod* method = cl->lookupMethod(funcName, funcSign, true, true, 0);
    if (isPublic(method->access)) { 
      method->invokeIntStatic(this, method->classDef, &args);
    } else {
      fprintf(stderr, "Main method not public.\n");
      vmkit::System::Exit(1);
    }
  } CATCH {
  } END_CATCH;

  exc = JavaThread::get()->pendingException;
  if (exc != NULL) {
    JavaThread* th = JavaThread::get();
    th->clearException();
    obj = th->currentThread();
    TRY {
      handler = upcalls->getUncaughtExceptionHandler->invokeJavaObjectVirtual(this, upcalls->newThread, obj);
      verifyNull(handler);
      upcalls->uncaughtException->invokeIntVirtual(this, upcalls->uncaughtException->classDef, handler, &obj, &exc);
    } CATCH {
      fprintf(stderr, "Exception in thread \"main\": "
                      "Can not print stack trace.\n");
    } END_CATCH;
    // Program failed. Exit with return code not 0.
    vmkit::System::Exit(1);
  }
}

void Jnjvm::executePremain(const char* className, JavaString* args,
                             JavaObject* instrumenter) {
  llvm_gcroot(args, 0);
  llvm_gcroot(instrumenter, 0);
  TRY {
    const UTF8* name = appClassLoader->asciizConstructUTF8(className);
    UserClass* cl = (UserClass*)
        appClassLoader->loadName(name, true, true, NULL);
    cl->initialiseClass(this);
  
    const UTF8* funcSign = appClassLoader->asciizConstructUTF8(
      "(Ljava/lang/String;Ljava/lang/instrument/Instrumentation;)V");
    const UTF8* funcName = appClassLoader->asciizConstructUTF8("premain");
    JavaMethod* method = cl->lookupMethod(funcName, funcSign, true, true, 0);
  
    method->invokeIntStatic(this, method->classDef, &args, &instrumenter);
  } IGNORE;
}

void Jnjvm::mainJavaStart(JavaThread* thread) {

  JavaString* str = NULL;
  JavaObject* instrumenter = NULL;
  ArrayObject* args = NULL;
  JavaObject* exc = NULL;

  llvm_gcroot(str, 0);
  llvm_gcroot(instrumenter, 0);
  llvm_gcroot(args, 0);
  llvm_gcroot(exc, 0);

  Jnjvm* vm = thread->getJVM();
  vm->argumentsInfo.readArgs(vm);
  if (vm->argumentsInfo.className == NULL) {
    vm->threadSystem.leave();
    return;
  }

  int pos = vm->argumentsInfo.appArgumentsPos;  
  vm->argumentsInfo.argv = vm->argumentsInfo.argv + pos - 1;
  vm->argumentsInfo.argc = vm->argumentsInfo.argc - pos + 1;

  vm->mainThread = thread;

  TRY {
    vm->loadBootstrap();
  } CATCH {
    exc = JavaThread::get()->pendingException;
  } END_CATCH;

  if (exc != NULL) {
    fprintf(stderr, "Exception %s while bootstrapping VM.\n",
        UTF8Buffer(JavaObject::getClass(exc)->name).cString());
  } else {
    ClArgumentsInfo& info = vm->argumentsInfo;
  
    if (info.agents.size()) {
      assert(0 && "implement me");
      instrumenter = 0;//createInstrumenter();
      for (std::vector< std::pair<char*, char*> >::iterator i = 
           info.agents.begin(), e = info.agents.end(); i!= e; ++i) {
        str = vm->asciizToStr(i->second);
        vm->executePremain(i->first, str, instrumenter);
      }
    }
    
    UserClassArray* array = vm->bootstrapLoader->upcalls->ArrayOfString;
    args = (ArrayObject*)array->doNew(info.argc - 2, vm);
    for (int i = 2; i < info.argc; ++i) {
      str = vm->asciizToStr(info.argv[i]);
      ArrayObject::setElement(args, str, i - 2);
    }

    vm->executeClass(info.className, args);
  }
  vm->threadSystem.leave();
}

void ThreadSystem::leave() {
  nonDaemonLock.lock();
  --nonDaemonThreads;
  if (nonDaemonThreads == 0) vmkit::Thread::get()->MyVM->exit();
  nonDaemonLock.unlock();  
}

void ThreadSystem::enter() {
  nonDaemonLock.lock();
  ++nonDaemonThreads;
  nonDaemonLock.unlock();  
}

void Jnjvm::runApplication(int argc, char** argv) {
  argumentsInfo.argc = argc;
  argumentsInfo.argv = argv;
  mainThread = new JavaThread(this);
  mainThread->start((void (*)(vmkit::Thread*))mainJavaStart);

  JavaThread* th = new JavaThread(this);
  th->start((void (*)(vmkit::Thread*))threadToDetectCtrl_C);
}

Jnjvm::Jnjvm(vmkit::BumpPtrAllocator& Alloc,
             vmkit::CompiledFrames** frames,
             JnjvmBootstrapLoader* loader) : 
  VirtualMachine(Alloc, frames), lockSystem(Alloc)
{
  classpath = getenv("CLASSPATH");
  if (classpath == NULL) classpath = ".";
  
  appClassLoader = NULL;
  jniEnv = &JNI_JNIEnvTable;
  javavmEnv = &JNI_JavaVMTable;
  
  bootstrapLoader = loader;
  upcalls = bootstrapLoader->upcalls;
  throwable = upcalls->newThrowable;
}

Jnjvm::~Jnjvm() {
}

ArrayUInt16* Jnjvm::asciizToArray(const char* asciiz) {
  ArrayUInt16* tmp = NULL;
  llvm_gcroot(tmp, 0);

  uint32 size = strlen(asciiz);
  tmp = (ArrayUInt16*)upcalls->ArrayOfChar->doNew(size, this);
  
  for (uint32 i = 0; i < size; i++) {
    ArrayUInt16::setElement(tmp, asciiz[i], i);
  }
  return tmp;
}

void Jnjvm::startCollection() {
  finalizerThread->FinalizationQueueLock.acquire();
  referenceThread->ToEnqueueLock.acquire();
  referenceThread->SoftReferencesQueue.acquire();
  referenceThread->WeakReferencesQueue.acquire();
  referenceThread->PhantomReferencesQueue.acquire();
}

void Jnjvm::endCollection() {
  finalizerThread->FinalizationQueueLock.release();
  referenceThread->ToEnqueueLock.release();
  referenceThread->SoftReferencesQueue.release();
  referenceThread->WeakReferencesQueue.release();
  referenceThread->PhantomReferencesQueue.release();
  finalizerThread->FinalizationCond.broadcast();
  referenceThread->EnqueueCond.broadcast();
}
  
void Jnjvm::scanWeakReferencesQueue(word_t closure) {
  referenceThread->WeakReferencesQueue.scan(referenceThread, closure);
}
  
void Jnjvm::scanSoftReferencesQueue(word_t closure) {
  referenceThread->SoftReferencesQueue.scan(referenceThread, closure);
}
  
void Jnjvm::scanPhantomReferencesQueue(word_t closure) {
  referenceThread->PhantomReferencesQueue.scan(referenceThread, closure);
}

void Jnjvm::scanFinalizationQueue(word_t closure) {
  finalizerThread->scanFinalizationQueue(closure);
}

void Jnjvm::addFinalizationCandidate(gc* object) {
	llvm_gcroot(object, 0);
	finalizerThread->addFinalizationCandidate(object);
}

void Jnjvm::setType(gc* header, void* type) {
	JavaObject* src = 0;
	llvm_gcroot(src, 0);
	llvm_gcroot(header, 0);
	src = (JavaObject*)header;
	src->setVirtualTable((JavaVirtualTable*)type);
}

//void Jnjvm::setType(void* header, void* type)
//{
//	((JavaObject*)header)->setVirtualTable((JavaVirtualTable*)type);
//}

void* Jnjvm::getType(gc* header) {
	JavaObject* src = 0;
	llvm_gcroot(src, 0);
	llvm_gcroot(header, 0);
	src = (JavaObject*)header;
	return src->getVirtualTable();
}

// This method is called during GC so no llvm_gcroot needed.
void Jnjvm::traceObject(gc* _obj, word_t closure) {
  JavaObject* obj = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(_obj, 0);
  obj = (JavaObject*)_obj;
  assert(obj && "No object to trace");
  assert(obj->getVirtualTable() && "No virtual table");
  assert(obj->getVirtualTable()->tracer && "No tracer in VT");
  obj->tracer(closure);
}

// This method is called during GC so no llvm_gcroot needed.
bool Jnjvm::isCorruptedType(gc* obj) {
	JavaObject* _obj = 0;
	llvm_gcroot(_obj, 0);
	llvm_gcroot(obj, 0);
	_obj = (JavaObject*)obj;
	return _obj->getVirtualTable();
}

size_t Jnjvm::getObjectSize(gc* object) {
  // TODO: because this is called during GC, there is no need to do
  // llvm_gcroot. For clarity, it may be useful to have a special type
  // in this case.
  size_t size = 0;
  JavaObject* src = 0;
  llvm_gcroot(object, 0);
  llvm_gcroot(src, 0);
  src = (JavaObject*)object;
  if (VMClassLoader::isVMClassLoader(src)) {
    size = sizeof(VMClassLoader);
  } else if (VMStaticInstance::isVMStaticInstance(src)) {
    size = sizeof(VMStaticInstance);
  } else {
    CommonClass* cl = JavaObject::getClass(src);
    if (cl->isArray()) {
      UserClassArray* array = cl->asArrayClass();
      UserCommonClass* base = array->baseClass();
      uint32 logSize = base->isPrimitive() ? 
        base->asPrimitiveClass()->logSize : (sizeof(JavaObject*) == 8 ? 3 : 2); 

      size = sizeof(JavaObject) + sizeof(ssize_t) + 
                    (JavaArray::getSize(src) << logSize);
    } else {
      assert(cl->isClass() && "Not a class!");
      size = cl->asClass()->getVirtualSize();
    }
  }
  return size;
}

const char* Jnjvm::getObjectTypeName(gc* object) {
  JavaObject* src = 0;
  llvm_gcroot(object, 0);
  llvm_gcroot(src, 0);
  src = (JavaObject*)object;
  if (VMClassLoader::isVMClassLoader(src)) {
    return "VMClassLoader";
  } else if (VMStaticInstance::isVMStaticInstance(src)) {
    return "VMStaticInstance";
  } else {
    CommonClass* cl = JavaObject::getClass(src);
    // This code is only used for debugging on a fatal error. It is fine to
    // allocate in the C++ heap.
    return (new UTF8Buffer(cl->name))->cString();
  }
}

// Helper function to run J3 without JIT.
extern "C" int StartJnjvmWithoutJIT(int argc, char** argv, char* mainClass) {
  vmkit::Collector::initialise(argc, argv);
 
  vmkit::ThreadAllocator allocator; 
  char** newArgv = (char**)allocator.Allocate((argc + 1) * sizeof(char*));
  memcpy(newArgv + 1, argv, argc * sizeof(char*));
  newArgv[0] = newArgv[1];
  newArgv[1] = mainClass;
 
  vmkit::BumpPtrAllocator Allocator;
  JavaCompiler* Comp = new JavaCompiler();
  JnjvmBootstrapLoader* loader = new(Allocator, "Bootstrap loader")
    JnjvmBootstrapLoader(Allocator, Comp, true);
  Jnjvm* vm = new(Allocator, "VM") Jnjvm(Allocator, NULL, loader);

  vm->runApplication(argc + 1, newArgv);
  vm->waitForExit();
  
  return 0; 
}

void Jnjvm::printMethod(vmkit::FrameInfo* FI, word_t ip, word_t addr) {
  if (FI->Metadata == NULL) {
    vmkit::MethodInfoHelper::print(ip, addr);
    return;
  }
  JavaMethod* meth = (JavaMethod*)FI->Metadata;

  fprintf(stderr, "; %p (%p) in %s.%s (line %d, bytecode %d, code start %p)",
          (void*)ip,
          (void*)addr,
          UTF8Buffer(meth->classDef->name).cString(),
          UTF8Buffer(meth->name).cString(),
          meth->lookupLineNumber(FI),
          FI->SourceIndex, meth->code);

  fprintf(stderr, "\n");
}

void Jnjvm::printBacktrace()
{
	std::cerr << "Back trace:" << std::endl;
	JavaThread::get()->printJavaBacktrace();
}
