//===---------- 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 0

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

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

#include "ClasspathReflect.h"
#include "JavaArray.h"
#include "JavaClass.h"
#include "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 "Zip.h"

using namespace j3;

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

#ifdef ISOLATE
Jnjvm* Jnjvm::RunningIsolates[NR_ISOLATES];
mvm::LockNormal Jnjvm::IsolateLock;
#endif


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

void UserClass::initialiseClass(Jnjvm* vm) {
  
  // 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);
    bool vmjced = (getInitializationState() == vmjc);
    setInitializationState(inClinit);
    UserClass* cl = (UserClass*)this;
#if defined(ISOLATE) || defined(ISOLATE_SHARING)
    // Isolate environments allocate the static instance on their own, not when
    // the class is being resolved.
    cl->allocateStaticInstance(vm);
#else
    // 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);
#endif
    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;
      }
    }
 
    JavaObject* exc = 0;
    JavaObject* obj = 0;
    llvm_gcroot(exc, 0);
    llvm_gcroot(obj, 0);
#ifdef SERVICE
    if (classLoader == classLoader->bootstrapLoader || 
        classLoader->getIsolate() == vm) {
#endif

    // 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, "; ", 0);
    PRINT_DEBUG(JNJVM_LOAD, 0, LIGHT_GREEN, "clinit ", 0);
    PRINT_DEBUG(JNJVM_LOAD, 0, COLOR_NORMAL, "%s\n", mvm::PrintString(this).cString());



    if (!vmjced) {
      JavaField* fields = cl->getStaticFields();
      void* val = cl->getStaticInstance();
      for (uint32 i = 0; i < cl->nbStaticFields; ++i) {
        fields[i].initField(val, 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;
    }
#ifdef SERVICE
    }
#endif

    // 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 (exc->getClass()->isAssignableFrom(vm->upcalls->newException)) {
      Classpath* upcalls = classLoader->bootstrapLoader->upcalls;
      UserClass* clExcp = upcalls->ExceptionInInitializerError;
      Jnjvm* vm = self->getJVM();
      obj = clExcp->doNew(vm);
      if (!obj) {
        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 = cl->doNew(this);
  llvm_gcroot(obj, 0);
  init->invokeIntSpecial(this, cl, obj, &excp);
  JavaThread::get()->throwException(obj);
}

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

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

JavaObject* Jnjvm::CreateError(UserClass* cl, JavaMethod* init,
                               JavaString* str) {
  JavaObject* obj = 0;
  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 = (JavaString*)
    upcalls->IntToString->invokeJavaObjectStatic(this, upcalls->intClass,
                                                 entry, 10);
  llvm_gcroot(str, 0);
  error(upcalls->ArrayIndexOutOfBoundsException,
        upcalls->InitArrayIndexOutOfBoundsException, str);
}

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

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

JavaObject* Jnjvm::CreateIndexOutOfBoundsException(sint32 entry) {
  JavaString* str = (JavaString*)
    upcalls->IntToString->invokeJavaObjectStatic(this, upcalls->intClass,
                                                 entry, 10);
  llvm_gcroot(str, 0);
  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 = constructString(meth->toString());
  llvm_gcroot(str, 0);
  return CreateError(upcalls->UnsatisfiedLinkError,
                     upcalls->InitUnsatisfiedLinkError,
                     str);
}

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

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

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

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

JavaObject* Jnjvm::CreateArrayStoreException(JavaVirtualTable* VT) {
  JavaString* str = VT ? JavaString::internalToJava(VT->cl->name, this) : NULL;
  llvm_gcroot(str, 0);
  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 = asciizToStr(msg);
  llvm_gcroot(str, 0);
  return CreateError(upcalls->LinkageError,
                     upcalls->InitLinkageError, str);
}

void Jnjvm::illegalAccessException(const char* msg) {
  JavaString* str = asciizToStr(msg);
  llvm_gcroot(str, 0);
  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 = asciizToStr("Java heap space");
  llvm_gcroot(str, 0);
  error(upcalls->OutOfMemoryError,
        upcalls->InitOutOfMemoryError, str);
}

void Jnjvm::illegalArgumentException(const char* msg) {
  JavaString* str = asciizToStr(msg);
  llvm_gcroot(str, 0);
  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 = internalUTF8ToStr(cl->name);
  llvm_gcroot(str, 0);
  error(upcalls->InstantiationException, upcalls->InitInstantiationException,
        str);
}

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

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

  uint32 i = 0;


  msg->elements[i++] = 'u';
  msg->elements[i++] = 'n';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'b';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'e';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 't';
  msg->elements[i++] = 'o';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 'f';
  msg->elements[i++] = 'i';
  msg->elements[i++] = 'n';
  msg->elements[i++] = 'd';
  msg->elements[i++] = ' ';

  for (sint32 j = 0; j < name->size; ++j)
    msg->elements[i++] = name->elements[j];

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

  str = vm->constructString(msg);

  return str;
}

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

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

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

static JavaString* CreateUnableToLoad(const UTF8* name, Jnjvm* vm) {
  ArrayUInt16* msg = (ArrayUInt16*)
    vm->upcalls->ArrayOfChar->doNew(15 + name->size, vm);
  JavaString* str = 0;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);
  uint32 i = 0;


  msg->elements[i++] = 'u';
  msg->elements[i++] = 'n';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'b';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'e';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 't';
  msg->elements[i++] = 'o';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'o';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'd';
  msg->elements[i++] = ' ';

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

  str = vm->constructString(msg);

  return str;
}

static JavaString* CreateUnableToLoad(JavaString* name, Jnjvm* vm) {
  JavaString* str = 0;
  ArrayUInt16* msg = (ArrayUInt16*)
    vm->upcalls->ArrayOfChar->doNew(15 + name->count, vm);
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);
  uint32 i = 0;


  msg->elements[i++] = 'u';
  msg->elements[i++] = 'n';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'b';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'e';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 't';
  msg->elements[i++] = 'o';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'o';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'd';
  msg->elements[i++] = ' ';

  for (sint32 j = name->offset; j < name->offset + name->count; ++j) {
    if (name->value->elements[j] == '/') msg->elements[i++] = '.';
    else msg->elements[i++] = name->value->elements[j];
  }

  str = vm->constructString(msg);

  return str;
}



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

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

void Jnjvm::noClassDefFoundError(UserClass* cl, const UTF8* name) {
  uint32 size = 35 + name->size + cl->name->size;
  ArrayUInt16* msg = (ArrayUInt16*)upcalls->ArrayOfChar->doNew(size, this);
  JavaString* str = 0;
  llvm_gcroot(msg, 0);
  llvm_gcroot(str, 0);
  uint32 i = 0;


  msg->elements[i++] = 't';
  msg->elements[i++] = 'r';
  msg->elements[i++] = 'y';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 't';
  msg->elements[i++] = 'o';
  msg->elements[i++] = ' ';
  msg->elements[i++] = 'l';
  msg->elements[i++] = 'o';
  msg->elements[i++] = 'a';
  msg->elements[i++] = 'd';
  msg->elements[i++] = ' ';

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

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


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

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

JavaString* Jnjvm::constructString(const ArrayUInt16* array) { 
  llvm_gcroot(array, 0);
  JavaString* res = hashStr.lookupOrCreate(array, this, JavaString::stringDup);
  return res;
}

JavaString* Jnjvm::asciizToStr(const char* asciiz) {
  assert(asciiz && "No asciiz given");
  ArrayUInt16* var = 0;
  llvm_gcroot(var, 0);
  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()) {
    UserClass* cl = vm->upcalls->newClass;
    delegatee = (JavaObjectClass*)cl->doNew(vm);
    delegatee->vmdata = this;
    if (!pd && isArray()) {
      base = (JavaObjectClass*)
        asArrayClass()->baseClass()->getClassDelegatee(vm, pd);
      delegatee->pd = base->pd;
    } else {
      delegatee->pd = 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();
}

//===----------------------------------------------------------------------===//
// The command line parsing tool does not manipulate any GC-allocated objects.
// The ArrayUInt8 is allocated with malloc and free'd after parsing.
//===----------------------------------------------------------------------===//

#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, 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, "class name");
    memcpy(name, &(ptr[index]), length);
    name[length] = 0;
    return name;
  } else {
    return 0;
  }
}

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

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

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

  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->allocator,
                                                  true);
      int ok = archive.readFile(res, file);
      if (ok) {
        char* mainClass = findInformation(vm, res, MAIN_CLASS,
                                          LENGTH_MAIN_CLASS);
        if (!mainClass)
          mainClass = findInformation(vm, res, MAIN_LOWER_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);
      }
      free(res);
    } else {
      printf("Can't find Manifest file in archive %s\n", jarFile);
    }
  } else {
    printf("Can't find archive %s\n", jarFile);
  }
  free(bytes);
}

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 (!(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"))) {
      mvm::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 == 0) {
    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() {
  JnjvmClassLoader* loader = bootstrapLoader;
  
  // First create system threads.
  finalizerThread = new JavaThread(0, 0, this);
  finalizerThread->start((void (*)(mvm::Thread*))finalizerStart);
    
  enqueueThread = new JavaThread(0, 0, this);
  enqueueThread->start((void (*)(mvm::Thread*))enqueueStart);
  
  // Initialise the bootstrap class loader if it's not
  // done already.
  if (!bootstrapLoader->upcalls->newString)
    bootstrapLoader->upcalls->initialiseClasspath(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 define a new VT for strings that will be
  // placed in the hashmap. This VT will have its destructor set so
  // that the string is removed when deallocated.
  upcalls->newString->resolveClass();
  if (!JavaString::internStringVT) {
    JavaVirtualTable* stringVT = upcalls->newString->getVirtualVT();
    uint32 size = upcalls->newString->virtualTableSize * sizeof(uintptr_t);
    
    JavaString::internStringVT = 
      (JavaVirtualTable*)bootstrapLoader->allocator.Allocate(size, "String VT");

    memcpy(JavaString::internStringVT, stringVT, size);
    
    JavaString::internStringVT->destructor = 
      (uintptr_t)JavaString::stringDestructor;

    // Tell the finalizer that this is a native destructor.
    JavaString::internStringVT->operatorDelete = 
      (uintptr_t)JavaString::stringDestructor;
  }
  upcalls->newString->initialiseClass(this);

#ifdef SERVICE
  if (!IsolateID)
#endif
  // 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->newVMThread);
  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); 
  LOAD_CLASS(upcalls->ArithmeticException); 
  LOAD_CLASS(upcalls->InstantiationException);
  LOAD_CLASS(upcalls->SystemClass);
#undef LOAD_CLASS

  loadAppClassLoader();
  JavaObject* obj = JavaThread::get()->currentThread();
  JavaObject* javaLoader = appClassLoader->getJavaClassLoader();

#ifdef SERVICE
  if (!IsolateID)
#endif
  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->asClass()->initialiseClass(this);
}

void Jnjvm::executeClass(const char* className, ArrayObject* args) {
  JavaObject* exc = 0;
  JavaObject* obj = 0;
  JavaObject* group = 0;
  
  llvm_gcroot(args, 0);
  llvm_gcroot(exc, 0);
  llvm_gcroot(obj, 0);
  llvm_gcroot(group, 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) {
      const UTF8* name = appClassLoader->asciizConstructUTF8(className);
      cl = (UserClass*)appClassLoader->loadName(name, true, true);
    }
    
    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");
    }
  } CATCH {
  } END_CATCH;

  exc = JavaThread::get()->pendingException;
  if (exc) {
    JavaThread* th = JavaThread::get();
    th->clearException();
    obj = th->currentThread();
    group = upcalls->group->getObjectField(obj);
    TRY {
      upcalls->uncaughtException->invokeIntSpecial(this, upcalls->threadGroup,
                                                   group, &obj, &exc);
    } CATCH {
      fprintf(stderr, "Exception in thread \"main\": "
                      "Can not print stack trace.\n");
    } END_CATCH;
  }
}

void Jnjvm::executePremain(const char* className, JavaString* args,
                             JavaObject* instrumenter) {
  llvm_gcroot(instrumenter, 0);
  TRY {
    const UTF8* name = appClassLoader->asciizConstructUTF8(className);
    UserClass* cl = (UserClass*)appClassLoader->loadName(name, true, true);
    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::waitForExit() { 
  
  threadSystem.nonDaemonLock.lock();
  
  while (threadSystem.nonDaemonThreads) {
    threadSystem.nonDaemonVar.wait(&threadSystem.nonDaemonLock);
  }
  
  threadSystem.nonDaemonLock.unlock();

  return;
}

void Jnjvm::mainJavaStart(JavaThread* thread) {

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

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

  Jnjvm* vm = thread->getJVM();
  vm->mainThread = thread;

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

  if (exc != NULL) {
    fprintf(stderr, "Exception %s while bootstrapping VM.",
        UTF8Buffer(exc->getClass()->name).cString());
  } else {
#ifdef SERVICE
    thread->ServiceException = vm->upcalls->newThrowable->doNew(vm);
#endif

    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) {
      args->elements[i - 2] = (JavaObject*)vm->asciizToStr(info.argv[i]);
    }

    vm->executeClass(info.className, args);
  }
  vm->threadSystem.nonDaemonLock.lock();
  --(vm->threadSystem.nonDaemonThreads);
  if (vm->threadSystem.nonDaemonThreads == 0)
      vm->threadSystem.nonDaemonVar.signal();
  vm->threadSystem.nonDaemonLock.unlock();  
}

#ifdef SERVICE

#include <signal.h>

extern void terminationHandler(int);

static void serviceCPUMonitor(mvm::Thread* th) {
  while (true) {
    sleep(1);
    for(JavaThread* cur = (Java*)th->next(); cur != th;
        cur = (JavaThread*)cur->next()) {
        JavaThread* th = (JavaThread*)cur;
        if (!(th->StateWaiting)) {
          mvm::VirtualMachine* executingVM = cur->MyVM;
          assert(executingVM && "Thread with no VM!");
          ++executingVM->executionTime;
      }
    }
  }
}
#endif

void Jnjvm::runApplication(int argc, char** argv) {
  argumentsInfo.argc = argc;
  argumentsInfo.argv = argv;
  argumentsInfo.readArgs(this);
  if (argumentsInfo.className) {
    int pos = argumentsInfo.appArgumentsPos;
    
    argumentsInfo.argv = argumentsInfo.argv + pos - 1;
    argumentsInfo.argc = argumentsInfo.argc - pos + 1;
#ifdef SERVICE
    struct sigaction sa;
    sigset_t mask;
    sigfillset(&mask);
    sigaction(SIGUSR1, 0, &sa);
    sa.sa_mask = mask;
    sa.sa_handler = terminationHandler;
    sa.sa_flags |= SA_RESTART;
    sigaction(SIGUSR1, &sa, NULL);

    mvm::Thread* th = new JavaThread(0, 0, this);
    th->start(serviceCPUMonitor);
#endif
   
    mainThread = new JavaThread(0, 0, this);
    mainThread->start((void (*)(mvm::Thread*))mainJavaStart);
  } else {
    threadSystem.nonDaemonThreads = 0;
  }
}

Jnjvm::Jnjvm(mvm::BumpPtrAllocator& Alloc, JnjvmBootstrapLoader* loader) : 
  VirtualMachine(Alloc), lockSystem(this) {

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

  bootstrapLoader = loader;
  upcalls = bootstrapLoader->upcalls;

  throwable = upcalls->newThrowable;

  StringList* end = loader->strings;
  while (end) {
    for (uint32 i = 0; i < end->length; ++i) {
      JavaString* obj = end->strings[i];
      hashStr.insert(obj);
    }
    end = end->prev;
  }

  bootstrapLoader->insertAllMethodsInVM(this);  

#ifdef ISOLATE
  IsolateLock.lock();
  for (uint32 i = 0; i < NR_ISOLATES; ++i) {
    if (RunningIsolates[i] == 0) {
      RunningIsolates[i] = this;
      IsolateID = i;
      break;
    }
  }
  IsolateLock.unlock();
#endif

  scanner = loader->getCompiler()->createStackScanner();
}

Jnjvm::~Jnjvm() {
#ifdef ISOLATE
  RunningIsolates[IsolateID] = 0;
#endif
}

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;

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

void Jnjvm::internalRemoveMethods(JnjvmClassLoader* loader, mvm::FunctionMap& Map) {
  // Loop over all methods in the map to find which ones belong
  // to this class loader.
  Map.FunctionMapLock.acquire();
  std::map<void*, mvm::MethodInfo*>::iterator temp;
  for (std::map<void*, mvm::MethodInfo*>::iterator i = Map.Functions.begin(), 
       e = Map.Functions.end(); i != e;) {
    mvm::MethodInfo* MI = i->second;
    if (MI->MethodType == 1) {
      JavaMethod* meth = (JavaMethod*)i->second->getMetaInfo();
      if (meth->classDef->classLoader == loader) {
        temp = i;
        ++i;
        Map.Functions.erase(temp);
      } else {
        ++i;
      }
    } else {
      ++i;
    }
  }
  Map.FunctionMapLock.release();
}

void Jnjvm::removeMethodsInFunctionMaps(JnjvmClassLoader* loader) {
  internalRemoveMethods(loader, RuntimeFunctions);
  internalRemoveMethods(loader, StaticFunctions);
}


/// JavaStaticCompiler - Compiler for AOT-compiled programs that
/// do not use the JIT.
class JavaStaticCompiler : public JavaCompiler {
public:
#ifdef WITH_LLVM_GCC
  virtual mvm::StackScanner* createStackScanner() {
    return new mvm::PreciseStackScanner();
  }
#endif
};


// Helper function to run Jnjvm without JIT.
extern "C" int StartJnjvmWithoutJIT(int argc, char** argv, char* mainClass) {
  mvm::Collector::initialise();
  
  char** newArgv = new char*[argc + 1];
  memcpy(newArgv + 1, argv, argc * sizeof(char*));
  newArgv[0] = newArgv[1];
  newArgv[1] = mainClass;
 
  JavaCompiler* Comp = new JavaStaticCompiler();
  JnjvmClassLoader* JCL = mvm::VirtualMachine::initialiseJVM(Comp);
  mvm::VirtualMachine* vm = mvm::VirtualMachine::createJVM(JCL);
  vm->runApplication(argc + 1, newArgv);
  vm->waitForExit();

  delete[] newArgv;
  
  return 0; 
}
