//===---------- OpenJDK.inc - OpenJDK JVM Interface Definition ------------===//
//                            The VMKit project
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "jvm.h"

#include "JavaConstantPool.h"
#include "Reader.h"

#include "ArrayCopy.inc"
#include "ClassContext.inc"
#include "DefineClass.inc"
#include "SetProperties.inc"

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>

#define NYI() \
  do{ assert(0 && "Not yet implemented!"); abort(); } while(0)

// Convenience wrapper for returning a JNI ref to something
#define RETURN_REF_FROM_JNI(a,type) {\
  type __jni_ret_val = (type)th->pushJNIRef(a); \
  RETURN_FROM_JNI(__jni_ret_val); \
  }

JavaObject* internalFillInStackTrace(JavaObject* throwable) {

  ArrayPtr* result = 0;
  llvm_gcroot(throwable, 0);
  llvm_gcroot(result, 0);

  JavaThread* th = JavaThread::get();
  Jnjvm* vm = th->getJVM();
  assert(th);
  assert(vm);

  uint32 length = th->getFrameContextLength();

#ifndef ARCH_64
    ClassArray* cl = vm->upcalls->ArrayOfInt;
    result = (ArrayPtr*) cl->doNew(length, vm);
#else
    ClassArray* cl = vm->upcalls->ArrayOfLong;
    result = (ArrayPtr*) cl->doNew(length, vm);
#endif

  // Don't call th->getFrameContext because it is not GC-safe.
  vmkit::StackWalker Walker(th);
  uint32_t i = 0;

  while (intptr_t ip = *Walker) {
    ArrayPtr::setElement(result, ip, i);
    ++i;
    ++Walker;
  }

  return result;
}

JavaObject* consStackElement(vmkit::FrameInfo* FI, intptr_t ip) {

  JavaString* methodName = 0;
  JavaString* className = 0;
  JavaString* sourceName = 0;
  JavaObject* res = 0;
  llvm_gcroot(methodName, 0);
  llvm_gcroot(className, 0);
  llvm_gcroot(sourceName, 0);
  llvm_gcroot(res, 0);

  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaMethod* meth = (JavaMethod*)FI->Metadata;
  methodName = vm->internalUTF8ToStr(meth->name);
  Class* cl = meth->classDef;
  className = JavaString::internalToJava(cl->name, vm);

  JavaAttribute* sourceAtt = cl->lookupAttribute(JavaAttribute::sourceFileAttribute);

  if (sourceAtt) {
    Reader reader(sourceAtt, cl->bytes);
    uint16 index = reader.readU2();
    sourceName = vm->internalUTF8ToStr(cl->getConstantPool()->UTF8At(index));
  }

  uint16 lineNumber = meth->lookupLineNumber(FI);

  UserClass* newS = vm->upcalls->newStackTraceElement;
  res = newS->doNew(vm);
  vm->upcalls->initStackTraceElement->invokeIntSpecial(vm, newS, res,
                                                       &className,
                                                       &methodName,
                                                       &sourceName,
                                                       lineNumber);
  return res;
}

JNIEXPORT jint JNICALL
JVM_GetInterfaceVersion(void) {
  return JVM_INTERFACE_VERSION;
}

jint JVM_CreateJavaVM(JavaVM **pvm, void **penv, void *args) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_IHashCode(JNIEnv *env, jobject _obj) {
  JavaObject * obj = _obj ? *(JavaObject**)_obj : 0;
  llvm_gcroot(obj, 0);

  jint hash = (obj == NULL) ? 0 : JavaObject::hashCode(obj);
  return hash;
}

JNIEXPORT void JNICALL
JVM_MonitorWait(JNIEnv *env, jobject obj, jlong ms) {
  BEGIN_JNI_EXCEPTION

  JavaObject::wait(*(JavaObject**)obj, ms, 0);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT void JNICALL
JVM_MonitorNotify(JNIEnv *env, jobject obj) {
  BEGIN_JNI_EXCEPTION

  JavaObject::notify(*(JavaObject**)obj);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT void JNICALL
JVM_MonitorNotifyAll(JNIEnv *env, jobject obj) {
  BEGIN_JNI_EXCEPTION

  JavaObject::notifyAll(*(JavaObject**)obj);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT jobject JNICALL
JVM_Clone(JNIEnv *env, jobject obj) {
  JavaObject* src = 0;
  JavaObject * clone = 0;
  llvm_gcroot(clone, 0);
  llvm_gcroot(src, 0);

  BEGIN_JNI_EXCEPTION

  clone = JavaObject::clone(src = *(JavaObject**)obj);
  RETURN_REF_FROM_JNI(clone, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.lang.String
 */
JNIEXPORT jstring JNICALL
JVM_InternString(JNIEnv *env, jstring _str) {
  JavaString * str = *(JavaString**)_str;
  const ArrayUInt16* array = 0;
  JavaString * res = 0;
  llvm_gcroot(str, 0);
  llvm_gcroot(array, 0);
  llvm_gcroot(res, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = JavaThread::get()->getJVM();
  //vmkit::Collector::collect();
  array = JavaString::strToArray(str, vm);
  res = vm->constructString(array);

  RETURN_REF_FROM_JNI(res, jstring);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.lang.System
 */

uint64 CurrentTimeMillis() {
  struct timeval tv;
  gettimeofday(&tv, NULL);
  return (tv.tv_sec * 1000LL) + (tv.tv_usec / 1000LL);
}

JNIEXPORT jlong JNICALL
JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored) {
  return CurrentTimeMillis();
}

JNIEXPORT jlong JNICALL
JVM_NanoTime(JNIEnv *env, jclass ignored) {
  // TODO: Impl with more accurate clock?
  struct timeval tv;

  gettimeofday(&tv, NULL);

  jlong time = tv.tv_sec * 1000000000LL + tv.tv_usec * 1000LL;

  return time;
}

JNIEXPORT void JNICALL
JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject jsrc, jint sstart,
              jobject jdst, jint dstart, jint len) {
  JavaObject *src = 0;
  JavaObject *dst = 0;
  JavaObject* cur = 0;
  llvm_gcroot(src, 0);
  llvm_gcroot(dst, 0);
  llvm_gcroot(cur, 0);

  BEGIN_JNI_EXCEPTION

  src = jsrc ? *(JavaObject**)jsrc : 0;
  dst = jdst ? *(JavaObject**)jdst : 0;

  ArrayCopy(src, sstart, dst, dstart, len);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT jobject JNICALL
JVM_InitProperties(JNIEnv *env, jobject p) {
  BEGIN_JNI_EXCEPTION
  JavaObject * prop = *(JavaObject**)p;
  llvm_gcroot(prop, 0);
  setProperties(prop);
  setCommandLineProperties(prop);

  Jnjvm* vm = JavaThread::get()->getJVM();
  const char * tmp = getenv("JAVA_COMPILER");
  if (tmp)
    setProperty(vm, prop, "java.compiler", tmp);

  // Override properties to indicate java version 1.6
  setProperty(vm, prop, "java.specification.version", "1.6");
  setProperty(vm, prop, "java.version", "1.6");
  setProperty(vm, prop, "java.runtime.version", "1.6");

  // Set additional path properties
  // For now, ignore JAVA_HOME.  We don't want to be using a location
  // other than the one we precompiled against anyway.
  setProperty(vm, prop, "java.home", OpenJDKJRE);
  setProperty(vm, prop, "java.ext.dirs", OpenJDKExtDirs);

  RETURN_FROM_JNI(p);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.io.File
 */
JNIEXPORT void JNICALL
JVM_OnExit(void (*func)(void)) {
  NYI();
}

/*
 * java.lang.Runtime
 */
JNIEXPORT void JNICALL
JVM_Exit(jint code) {
  vmkit::System::Exit(code);
}

JNIEXPORT void JNICALL
JVM_Halt(jint code) {
  vmkit::System::Exit(code);
}

JNIEXPORT void JNICALL
JVM_GC(void) {
  BEGIN_JNI_EXCEPTION
  vmkit::Collector::collect();
  END_JNI_EXCEPTION
  RETURN_VOID_FROM_JNI;
}

/* Returns the number of real-time milliseconds that have elapsed since the
 * least-recently-inspected heap object was last inspected by the garbage
 * collector.
 *
 * For simple stop-the-world collectors this value is just the time
 * since the most recent collection.  For generational collectors it is the
 * time since the oldest generation was most recently collected.  Other
 * collectors are free to return a pessimistic estimate of the elapsed time, or
 * simply the time since the last full collection was performed.
 *
 * Note that in the presence of reference objects, a given object that is no
 * longer strongly reachable may have to be inspected multiple times before it
 * can be reclaimed.
 */
JNIEXPORT jlong JNICALL
JVM_MaxObjectInspectionAge(void) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_TraceInstructions(jboolean on) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_TraceMethodCalls(jboolean on) {
  NYI();
}

JNIEXPORT jlong JNICALL
JVM_TotalMemory(void) {
  return (jlong)vmkit::Collector::getTotalMemory();
}

JNIEXPORT jlong JNICALL
JVM_FreeMemory(void) {
  return (jlong)vmkit::Collector::getFreeMemory();
}

JNIEXPORT jlong JNICALL
JVM_MaxMemory(void) {
  return (jlong)vmkit::Collector::getMaxMemory();
}

JNIEXPORT jint JNICALL
JVM_ActiveProcessorCount(void) {
  return vmkit::System::GetNumberOfProcessors();
}

JNIEXPORT void * JNICALL
JVM_LoadLibrary(const char *name) {
  BEGIN_JNI_EXCEPTION
  Jnjvm* vm = JavaThread::get()->getJVM();
  void * res = (void*)vm->bootstrapLoader->loadLib(name);
  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_UnloadLibrary(void * handle) {
  NYI();
}

JNIEXPORT void * JNICALL
JVM_FindLibraryEntry(void *handle, const char *name) {
  BEGIN_JNI_EXCEPTION
  Jnjvm* vm = JavaThread::get()->getJVM();
  void* res = (void *)vm->bootstrapLoader->loadInLib(name, handle);
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jboolean JNICALL
JVM_IsSupportedJNIVersion(jint version) {
  return version == JNI_VERSION_1_1 ||
         version == JNI_VERSION_1_2 ||
         version == JNI_VERSION_1_4 ||
         version == JNI_VERSION_1_6;
}

/*
 * java.lang.Float and java.lang.Double
 */
JNIEXPORT jboolean JNICALL
JVM_IsNaN(jdouble d) {
  NYI();
}

/*
 * java.lang.Throwable
 */
JNIEXPORT void JNICALL
JVM_FillInStackTrace(JNIEnv *env, jobject throwable) {
  JavaObjectThrowable * T = 0;
  llvm_gcroot(T, 0);

  BEGIN_JNI_EXCEPTION

  T = *(JavaObjectThrowable**)throwable;
  JavaObjectThrowable::fillInStackTrace(T);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI;
}

JNIEXPORT void JNICALL
JVM_PrintStackTrace(JNIEnv *env, jobject throwable, jobject printable) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable) {
  JavaObjectThrowable * T = 0;
  llvm_gcroot(T, 0);

  jint res = -1;

  BEGIN_JNI_EXCEPTION

  T = *(JavaObjectThrowable**)throwable;
  res = JavaObjectThrowable::getStackTraceDepth(T);

  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobject JNICALL
JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index) {
  JavaObjectThrowable * T = 0;
  JavaObject * result = 0;
  JavaObject * stack = 0;
  llvm_gcroot(T, 0);
  llvm_gcroot(result, 0);
  llvm_gcroot(stack, 0);

  BEGIN_JNI_EXCEPTION

  T = *(JavaObjectThrowable**)throwable;
  Jnjvm* vm = JavaThread::get()->getJVM();
  stack = vm->upcalls->backtrace->getInstanceObjectField(T);
  verifyNull(stack);

  sint32 base = JavaObjectThrowable::getStackTraceBase(T);

  sint32 cur = 0;
  for (sint32 i = base; i < JavaArray::getSize(stack); ++i) {
    intptr_t ip = ArrayPtr::getElement((ArrayPtr*)stack, i);
    vmkit::FrameInfo* FI = vm->IPToFrameInfo(ip);
    if (FI->Metadata != NULL) {
      if (cur == index) {
        result = consStackElement(FI, ip);
        break;
      }
      cur++;
    }
  }

  assert(result && "No stack element found");
  RETURN_REF_FROM_JNI(result, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.lang.Compiler
 */
JNIEXPORT void JNICALL
JVM_InitializeCompiler (JNIEnv *env, jclass compCls) {
  NYI();
}

JNIEXPORT jboolean JNICALL
JVM_IsSilentCompiler(JNIEnv *env, jclass compCls) {
  NYI();
}

JNIEXPORT jboolean JNICALL
JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls) {
  // Unsupported.
  return false;
}

JNIEXPORT jboolean JNICALL
JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname) {
  // Unsupported.
  return false;
}

JNIEXPORT jobject JNICALL
JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_EnableCompiler(JNIEnv *env, jclass compCls) {
  // Ignore.
}

JNIEXPORT void JNICALL
JVM_DisableCompiler(JNIEnv *env, jclass compCls) {
  // Ignore.
}

void start(JavaThread* thread) {

  JavaObject* javaThread = NULL;
  JavaObject* handler = NULL;
  JavaObject* exc = NULL;
  llvm_gcroot(javaThread, 0);
  llvm_gcroot(exc, 0);
  llvm_gcroot(handler, 0);

  Jnjvm* vm = thread->getJVM();

  // Wait some time to let the creator initialise the fields
  while (thread->javaThread == NULL || thread->sleepObject == NULL) {
    vmkit::Thread::yield();
  }

  javaThread = thread->javaThread;
  assert(javaThread && "Didn't fix the javaThread of a j3 thread");

  assert(javaThread->getVirtualTable());

  // Get the class for this Thread
  UserClass* thClass = JavaObject::getClass(javaThread)->asClass();
  assert(thClass);
  assert(thClass->isResolved());

  // Lookup the correct run() method to call...
  const UTF8 * runName = thClass->classLoader->hashUTF8->lookupAsciiz("run");
  const UTF8 * runType = thClass->classLoader->hashUTF8->lookupAsciiz("()V");
  JavaMethod * meth = thClass->lookupMethodDontThrow(runName, runType, false, true, 0);
  assert(meth);

  // Sanity check
  assert(JavaThread::get() == thread);

  // Run the thread...
  TRY {
    meth->invokeIntSpecial(vm, thClass, javaThread);
  } CATCH {
    exc = thread->pendingException;
  } END_CATCH;

  // Sanity check
  assert(JavaThread::get() == thread);

  if (exc != NULL) {
    thread->clearException();
    TRY {
      handler = vm->upcalls->getUncaughtExceptionHandler->invokeJavaObjectVirtual(vm, thClass, javaThread);
      verifyNull(handler);
      vm->upcalls->uncaughtException->invokeIntVirtual(vm, thClass, handler, &javaThread, &exc);
    } CATCH {
      fprintf(stderr, "Exception in thread \"(unknown)\": "
                      "Can not print stack trace.\n");
    } END_CATCH;
  }

  // Call Thread.exit()
  vm->upcalls->threadExit->invokeIntVirtual(vm, thClass, javaThread);

  JavaObject::acquire(javaThread);
  // Indicate that the thread is done by clearing the eetop field.
  vm->upcalls->eetop->setInstanceLongField(javaThread, 0);
  // Notify all waiting threads
  JavaObject::notifyAll(javaThread);
  JavaObject::release(javaThread);

  // Remove the thread from the list.
  bool isDaemon = vm->upcalls->daemon->getInstanceInt8Field(javaThread);
  if (!isDaemon) {
    vm->threadSystem.leave();
  }

}
/*
 * java.lang.Thread
 */
JNIEXPORT void JNICALL
JVM_StartThread(JNIEnv *env, jobject _thread) {
  JavaObject * sleepObject = 0;
  JavaObject * thread = 0;
  llvm_gcroot(thread, 0);
  llvm_gcroot(sleepObject, 0);
  BEGIN_JNI_EXCEPTION

  thread = *(JavaObject**)_thread;
  assert(thread);
  assert(thread->getVirtualTable());
  Jnjvm* vm = JavaThread::get()->getJVM();

  // Create a placeholder 'sleepObject' that
  // we track in same field as Classpath's VMThread,
  // used solely for sleeping.
  sleepObject = vm->upcalls->OfObject->doNew(vm);

  JavaThread * newTh = new JavaThread(vm);
  if (!newTh) vm->outOfMemoryError();

  // Set the eetop field
  vm->upcalls->eetop->setInstanceLongField(thread, (long)newTh);

  // If the thread is not a daemon, it is added to the list of threads to
  // wait until exit.
  //bool isDaemon = vm->upcalls->daemon->getInstanceInt8Field(thread);
  bool isDaemon = vm->upcalls->daemon->getInstanceInt8Field(thread);

  if (!isDaemon) {
    vm->threadSystem.enter();
  }

  newTh->start((void (*)(vmkit::Thread*))start);

  newTh->initialise(thread, sleepObject);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT void JNICALL
JVM_StopThread(JNIEnv *env, jobject thread, jobject exception) {
  NYI();
}

JNIEXPORT jboolean JNICALL
JVM_IsThreadAlive(JNIEnv *env, jobject _thread) {
  BEGIN_JNI_EXCEPTION
  JavaObject * thread = *(JavaObject**)_thread;
  llvm_gcroot(thread, 0);
  assert(thread);

  Jnjvm* vm = JavaThread::get()->getJVM();
  jlong InternalThread =vm->upcalls->eetop->getInstanceLongField(thread);

  RETURN_FROM_JNI(InternalThread != 0);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_SuspendThread(JNIEnv *env, jobject thread) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_ResumeThread(JNIEnv *env, jobject thread) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_SetThreadPriority(JNIEnv *env, jobject thread, jint prio) {
  JavaObject * T;
  llvm_gcroot(T, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm * vm = th->getJVM();
  T = *(JavaObject**)thread;

  vm->upcalls->priority->setInstanceInt32Field(T, prio);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT void JNICALL
JVM_Yield(JNIEnv *env, jclass threadClass) {
  vmkit::Thread::yield();
}

static struct timeval getTimeVal(long long ms) {
  struct timeval ret;
  long long seconds = ms / 1000LL;
  ret.tv_usec = 1000LL * (ms % 1000LL);
  ret.tv_sec = seconds > LONG_MAX ? LONG_MAX : seconds;
  return ret;
}


JNIEXPORT void JNICALL
JVM_Sleep(JNIEnv *env, jclass threadClass, jlong _millis) {

  BEGIN_JNI_EXCEPTION

  Jnjvm * vm = th->getJVM();

  // Check for invalid sleep time
  if (_millis < 0)
    th->getJVM()->illegalArgumentException("Negative sleep value");

  uint64 millis = _millis;

  // If Thread is interrupted, throw exception
  if (th->lockingThread.interruptFlag != 0) {
    th->lockingThread.interruptFlag = 0;
    vm->interruptedException(NULL);
    UNREACHABLE();
  }

  // Treat sleep(0) as yield.
  if (millis == 0) {
    vmkit::Thread::yield();
    RETURN_VOID_FROM_JNI
  }

  // See the Classpath sleep() implementation for inspiration here.
  // We use a dummy per-thread 'sleepObject' to wait on instead of using
  // a VMThread, but otherwise same implementation.
  assert(th->sleepObject && "Missing sleep object!");

  uint64 now = CurrentTimeMillis();

  JavaObject::acquire(th->sleepObject);
  while(true) {
    struct timeval tv = getTimeVal(millis);
    JavaObject::timedWait(th->sleepObject, tv);

    uint64 then = now;
    now = CurrentTimeMillis();
    uint64 timePassed = now - then;

    if (timePassed >= millis) break;

    millis -= timePassed;
  }
  JavaObject::release(th->sleepObject);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT jobject JNICALL
JVM_CurrentThread(JNIEnv *env, jclass threadClass) {
  BEGIN_JNI_EXCEPTION
  JavaThread* th = JavaThread::get();
  RETURN_REF_FROM_JNI(th->currentThread(), jobject);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jint JNICALL
JVM_CountStackFrames(JNIEnv *env, jobject thread) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_Interrupt(JNIEnv *env, jobject _thread) {
  gc* obj = NULL;
  JavaObject * thread = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(thread, 0);
  BEGIN_JNI_EXCEPTION

  thread = *(JavaObject**)_thread;
  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaField * field = vm->upcalls->eetop;

  // It's possible that the thread to be interrupted has not finished
  // its initialization. Wait until the initialization is done.
  while (field->getInstanceLongField(thread) == 0)
    vmkit::Thread::yield();

  JavaThread* jth = (JavaThread*)field->getInstanceLongField(thread);
  jth->lockingThread.interruptFlag = 1;
  //jth->parkLock.unpark();
  jth->parkLock.interrupt();
  vmkit::FatLock* lock = jth->lockingThread.waitsOn;
  

  // If the thread is blocked on a wait. We also verify nextWaiting in case
  // the thread has been notified.
  if (lock && jth->lockingThread.nextWaiting) {
    jth->lockingThread.state = vmkit::LockingThread::StateInterrupted;

    // Make sure the thread is waiting.
    uint32 locked = 0;
    while (true) {
      locked = (lock->tryAcquire() == 0);
      if (locked || (lock->getOwner() != jth && lock->getOwner() != 0))
        break;
      else vmkit::Thread::yield();
    }

    // Interrupt the thread.
    jth->lockingThread.varcond.signal();

    // Release the lock if we acquired it.
    if (locked) lock->release(obj = lock->getAssociatedObject(), vm->lockSystem);
  }

  // Here we could also raise a signal for interrupting I/O

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT jboolean JNICALL
JVM_IsInterrupted(JNIEnv *env, jobject _thread, jboolean clearInterrupted) {
  JavaObject * thread = 0;
  llvm_gcroot(thread, 0);

  bool interrupt = false;

  BEGIN_JNI_EXCEPTION

  thread = *(JavaObject**)_thread;
  Jnjvm* vm = JavaThread::get()->getJVM();
  JavaField * field = vm->upcalls->eetop;

  JavaThread* jth = (JavaThread*)field->getInstanceLongField(thread);
  interrupt = (jboolean)jth->lockingThread.interruptFlag;

  if (clearInterrupted)
    jth->lockingThread.interruptFlag = 0;

  RETURN_FROM_JNI(interrupt);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(JNI_FALSE);
}

JNIEXPORT jboolean JNICALL
JVM_HoldsLock(JNIEnv *env, jclass threadClass, jobject obj) {
  BEGIN_JNI_EXCEPTION
  jboolean res = JavaObject::owner(*(JavaObject**)obj);
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(JNI_FALSE);
}

JNIEXPORT void JNICALL
JVM_DumpAllStacks(JNIEnv *env, jclass unused) {
  NYI();
}

JNIEXPORT jobjectArray JNICALL
JVM_GetAllThreads(JNIEnv *env, jclass dummy) {
  NYI();
}

/* getStackTrace() and getAllStackTraces() method */
JNIEXPORT jobjectArray JNICALL
JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads) {
  NYI();
}

/*
 * java.lang.SecurityManager
 */
JNIEXPORT jclass JNICALL
JVM_CurrentLoadedClass(JNIEnv *env) {
  NYI();
}

JNIEXPORT jobject JNICALL
JVM_CurrentClassLoader(JNIEnv *env) {
  NYI();
}

JNIEXPORT jobjectArray JNICALL
JVM_GetClassContext(JNIEnv *env) {
  ArrayObject * res = 0;
  llvm_gcroot(res, 0);
  BEGIN_JNI_EXCEPTION

  res = GetClassContext(1);

  RETURN_REF_FROM_JNI(res, jobjectArray);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jint JNICALL
JVM_ClassDepth(JNIEnv *env, jstring name) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_ClassLoaderDepth(JNIEnv *env) {
  NYI();
}

/*
 * java.lang.Package
 */
JNIEXPORT jstring JNICALL
JVM_GetSystemPackage(JNIEnv *env, jstring name) {
  // TODO: Actually implement this
  // Not doing so doesn't seem to hurt anything, yet.
  return name;
}

JNIEXPORT jobjectArray JNICALL
JVM_GetSystemPackages(JNIEnv *env) {
  ArrayObject * res = 0;
  llvm_gcroot(res, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = JavaThread::get()->getJVM();
  res = vm->bootstrapLoader->getBootPackages(vm);

  RETURN_REF_FROM_JNI(res, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.io.ObjectInputStream
 */
JNIEXPORT jobject JNICALL
JVM_AllocateNewObject(JNIEnv *env, jobject obj, jclass currClass,
                      jclass initClass) {
  NYI();
}

JNIEXPORT jobject JNICALL
JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass,
                     jint length) {
  NYI();
}

JNIEXPORT jobject JNICALL
JVM_LatestUserDefinedLoader(JNIEnv *env) {
  JavaObject* res = 0;
  llvm_gcroot(res, 0);

  BEGIN_JNI_EXCEPTION

  JavaThread* th = JavaThread::get();
  res = th->getNonNullClassLoader();

  RETURN_REF_FROM_JNI(res, jobject);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * This function has been deprecated and should not be considered
 * part of the specified JVM interface.
 */
JNIEXPORT jclass JNICALL
JVM_LoadClass0(JNIEnv *env, jobject obj, jclass currClass,
               jstring currClassName) {
  NYI();
}

/*
 * java.lang.reflect.Array
 */
JNIEXPORT jint JNICALL
JVM_GetArrayLength(JNIEnv *env, jobject arr) {
  ArrayObject* array = 0;
  llvm_gcroot(array, 0);

  BEGIN_JNI_EXCEPTION
  array = *(ArrayObject**)arr;
  jint size = ArrayObject::getSize(array);
  RETURN_FROM_JNI(size);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobject JNICALL
JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index) {
  ArrayObject* array = 0;
  JavaObject* element = 0;
  llvm_gcroot(array, 0);
  llvm_gcroot(element, 0);

  BEGIN_JNI_EXCEPTION
  array = *(ArrayObject**)arr;
  element = ArrayObject::getElement(array, index);

  RETURN_REF_FROM_JNI(element, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jvalue JNICALL
JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val) {
  ArrayObject* array = 0;
  JavaObject* element = 0;
  llvm_gcroot(array, 0);
  llvm_gcroot(element, 0);

  BEGIN_JNI_EXCEPTION
  verifyNull(arr);
  array = *(ArrayObject**)arr;
  element = val ? *(JavaObject**)val : NULL;

  Jnjvm* vm = th->getJVM();

  // Verify this is, in fact, an array
  UserCommonClass * cl = JavaObject::getClass(array);
  if (!cl || !cl->isArray())
    vm->illegalArgumentException("Invalid object, expected array");

  // Bounds check
  if (index < 0 || index >= ArrayObject::getSize(array))
    vm->indexOutOfBounds(array, index);

  // Check the object is of the correct type
  UserCommonClass * base = cl->asArrayClass()->baseClass();
  if (element && !JavaObject::instanceOf(element, base))
    vm->illegalArgumentException("Wrong object for array type");

  ArrayObject::setElement(array, element, index);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

JNIEXPORT void JNICALL
JVM_SetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jvalue v,
                             unsigned char vCode) {
  NYI();
}

JNIEXPORT jobject JNICALL
JVM_NewArray(JNIEnv *env, jclass eltClass, jint length) {
  JavaObject* res = 0;
  JavaObject* eltClassObj = 0;
  llvm_gcroot(res, 0);
  llvm_gcroot(eltClassObj, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = th->getJVM();
  if (length < 0) vm->negativeArraySizeException(length);

  eltClassObj = *(JavaObject**)eltClass;
  UserCommonClass* base =
    UserCommonClass::resolvedImplClass(vm, eltClassObj, true);
  JnjvmClassLoader* loader = base->classLoader;
  const UTF8* name = base->getName();
  const UTF8* arrayName = loader->constructArrayName(1, name);
  if (base->isPrimitive()) {
    UserClassArray *array = 0;
    if (base == vm->upcalls->OfBool) {
      array = vm->upcalls->ArrayOfBool;
    } else if (base == vm->upcalls->OfByte) {
      array = vm->upcalls->ArrayOfByte;
    } else if (base == vm->upcalls->OfShort) {
      array = vm->upcalls->ArrayOfShort;
    } else if (base == vm->upcalls->OfChar) {
      array = vm->upcalls->ArrayOfChar;
    } else if (base == vm->upcalls->OfInt) {
      array = vm->upcalls->ArrayOfInt;
    } else if (base == vm->upcalls->OfFloat) {
      array = vm->upcalls->ArrayOfFloat;
    } else if (base == vm->upcalls->OfLong) {
      array = vm->upcalls->ArrayOfLong;
    } else if (base == vm->upcalls->OfDouble) {
      array = vm->upcalls->ArrayOfDouble;
    } else {
      vm->illegalArgumentException("Invalid array primitive type!");
      abort();
    }
    res = (JavaObject*)array->doNew(length, vm);
  } else {
    UserClassArray* array = loader->constructArray(arrayName, base);
    res = (JavaObject*)array->doNew(length, vm);
  }

  RETURN_REF_FROM_JNI(res, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

extern JavaObject* multiCallNewIntern(UserClassArray* cl, uint32 len,
                               sint32* dims, Jnjvm* vm);
JNIEXPORT jobject JNICALL
JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray _dim) {
  ArraySInt32* dim = 0;
  JavaObjectClass * eltClassObj = 0;
  JavaObject* array = 0;

  llvm_gcroot(dim, 0);
  llvm_gcroot(eltClassObj, 0);
  llvm_gcroot(array, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = th->getJVM();

  verifyNull(eltClass);
  verifyNull(_dim);

  eltClassObj = *(JavaObjectClass**)eltClass;
  dim = *(ArraySInt32**)_dim;

  int dim_len = ArraySInt32::getSize(dim);
  if(dim_len <= 0 || dim_len > 255) {
    vm->illegalArgumentException("Too many dimensions for array");
    UNREACHABLE();
  }

  UserCommonClass* base = JavaObjectClass::getClass(eltClassObj);
  JnjvmClassLoader* loader = base->classLoader;

  // Build array name
  vmkit::ThreadAllocator allocator;
  const UTF8* arrayName;
  if (base->isPrimitive()) {
    char baseChar;
    if (base == vm->upcalls->OfBool) {
      baseChar = I_BOOL;
    } else if (base == vm->upcalls->OfByte) {
      baseChar = I_BYTE;
    } else if (base == vm->upcalls->OfShort) {
      baseChar = I_SHORT;
    } else if (base == vm->upcalls->OfChar) {
      baseChar = I_CHAR;
    } else if (base == vm->upcalls->OfInt) {
      baseChar = I_INT;
    } else if (base == vm->upcalls->OfFloat) {
      baseChar = I_FLOAT;
    } else if (base == vm->upcalls->OfLong) {
      baseChar = I_LONG;
    } else if (base == vm->upcalls->OfDouble) {
      baseChar = I_DOUBLE;
    } else {
      vm->illegalArgumentException("Invalid array primitive type!");
      UNREACHABLE();
    }
    char* buf = (char*)allocator.Allocate(dim_len+2);
    for(int i = 0; i < dim_len; ++i) buf[i] = I_TAB;
    buf[dim_len] = baseChar;
    buf[dim_len+1] = '\0';
    arrayName = loader->asciizConstructUTF8(buf);
  }
  else {
    const UTF8* baseName = base->getName();
    arrayName = loader->constructArrayName(dim_len, baseName);
  }

  // Get class corresponding to array name
  UserClassArray* arrayCl =
    (UserClassArray*)loader->loadClassFromUserUTF8(arrayName, true, false, NULL);

  // Convert dimensions array to internal representation
  sint32* dims = (sint32*)allocator.Allocate(sizeof(sint32) * dim_len);
  for (sint32 i = 0; i < dim_len; ++i){
    dims[i] = ArraySInt32::getElement(dim, i);
  }

  // Invoke recursive helper to create this array
  array = multiCallNewIntern(arrayCl, dim_len, dims, vm);

  RETURN_REF_FROM_JNI(array, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.lang.Class and java.lang.ClassLoader
 */
/*
 * Returns the class in which the code invoking the native method
 * belongs.
 *
 * Note that in JDK 1.1, native methods did not create a frame.
 * In 1.2, they do. Therefore native methods like Class.forName
 * can no longer look at the current frame for the caller class.
 */
JNIEXPORT jclass JNICALL
JVM_GetCallerClass(JNIEnv *env, int n) {
  BEGIN_JNI_EXCEPTION

  JavaThread* th = JavaThread::get();

  Jnjvm* vm = th->getJVM();

  // Find the requested frame
  JavaMethod * meth = th->getCallingMethodLevel(n);

  // Grab the next frame up if the frame requested is Method.invoke()
  // TODO: Better integrate this throughout the reflection API?
  // Note that this isn't necessary in the Classpath port only because
  // it doesn't enforce any language access control for reflection
  if (meth == vm->upcalls->ReflectInvokeMethod)
    meth = th->getCallingMethodLevel(n+1);

  UserClass *cl = meth->classDef;
  assert(cl);
  JavaObject * const * res = cl->getClassDelegateePtr(vm);
  RETURN_FROM_JNI((jclass)res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Find primitive classes
 * utf: class name
 */


const struct {
  const char * name;
  char id;
} static PrimMap[] = {
  { "boolean", 'Z' },
  { "byte"   , 'B' },
  { "char"   , 'C' },
  { "short"  , 'S' },
  { "int"    , 'I' },
  { "long"   , 'J' },
  { "float"  , 'F' },
  { "double" , 'D' },
  { "void"   , 'V' }
};
const static unsigned PrimMapSize = sizeof(PrimMap)/sizeof(PrimMap[0]);

JNIEXPORT jclass JNICALL
JVM_FindPrimitiveClass(JNIEnv *env, const char *utf) {
  JavaObject* res = 0;
  llvm_gcroot(res, 0);

  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = JavaThread::get()->getJVM();

  UserClassPrimitive * prim =  0;
  for(unsigned i = 0; i < PrimMapSize; ++i) {
    if(!strcmp(PrimMap[i].name, utf)) {
      prim = UserClassPrimitive::byteIdToPrimitive(PrimMap[i].id, vm->upcalls);
      break;
    }
  }
  if (!prim) {
    fprintf(stderr, "Unsupported primitive \"%s\"!  Missing table entry?\n", utf);
  }
  assert(prim && "Invalid Primitive in JVM_FindPrimitiveClass");

  res = (JavaObject*)prim->getClassDelegateePtr(vm);
  RETURN_FROM_JNI((jclass)res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Link the class
 */
JNIEXPORT void JNICALL
JVM_ResolveClass(JNIEnv *env, jclass cls) {
  JavaObjectClass * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObjectClass**)cls;

  UserCommonClass * C = JavaObjectClass::getClass(Cl);
  assert(C && C->isClass());

  C->asClass()->resolveClass();

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI
}

/*
 * Find a class from a given class loader. Throw ClassNotFoundException
 * or NoClassDefFoundError depending on the value of the last
 * argument.
 */
JNIEXPORT jclass JNICALL
JVM_FindClassFromClassLoader(JNIEnv *env, const char *name, jboolean init,
                             jobject _loader, jboolean throwError) {
  BEGIN_JNI_EXCEPTION

  JavaObject * loader = _loader ? *(JavaObject**)_loader : 0;
  llvm_gcroot(loader, 0);

  jclass res;

  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader* JCL =
    JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);

  CommonClass * Cl = JCL->loadClassFromAsciiz(name, true, throwError);
  if (Cl) {
    if (init && Cl->asClass())
      Cl->asClass()->initialiseClass(vm);
    res = (jclass)Cl->getClassDelegateePtr(vm);
  }
  else {
    vm->classNotFoundException(vm->asciizToStr(name));
    res = NULL;
  }

  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jclass JNICALL
JVM_FindClassFromBootLoader(JNIEnv *env, const char *name) {
  BEGIN_JNI_EXCEPTION

  jclass res = 0;

  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader* JCL = vm->bootstrapLoader;

  CommonClass * Cl = JCL->loadClassFromAsciiz(name, true, false);
  if (Cl) {
    res = (jclass)Cl->getClassDelegateePtr(vm);
  }
  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Find a class from a given class.
 */
JNIEXPORT jclass JNICALL
JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init,
                             jclass from) {
  NYI();
}

/* Find a loaded class cached by the VM */
JNIEXPORT jclass JNICALL
JVM_FindLoadedClass(JNIEnv *env, jobject _loader, jstring name) {
  JavaObject * loader = 0;
  JavaString * str = 0;
  llvm_gcroot(loader, 0);
  llvm_gcroot(str, 0);
  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader* JCL = NULL;

  loader = *(JavaObject**)_loader;
  str = *(JavaString**)name;

  CommonClass * Cl = 0;

  JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
  assert(JCL && "JnVMClassloader is null");
  Cl = JCL->lookupClassFromJavaString(str);
  jclass res = Cl ? (jclass)Cl->getClassDelegateePtr(vm) : 0;
  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* Define a class */
JNIEXPORT jclass JNICALL
JVM_DefineClass(JNIEnv *env, const char *name, jobject _loader, const jbyte *buf,
                jsize len, jobject pd) {
  JavaObject * loader = 0;
  llvm_gcroot(loader, 0);
  BEGIN_JNI_EXCEPTION

  loader = _loader ? *(JavaObject**)_loader : 0;

  jclass res = 0;

  Jnjvm* vm = JavaThread::get()->getJVM();
  JnjvmClassLoader* JCL = NULL;
  JCL = JnjvmClassLoader::getJnjvmLoaderFromJavaObject(loader, vm);
  const UTF8* utfName = JCL->asciizConstructUTF8(name);

  UserClass* cl = defineClass(JCL, utfName, (const char*)buf, len);

  res = (jclass)cl->getClassDelegateePtr(vm, pd ? *(JavaObject**)pd : 0);

  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* Define a class with a source (added in JDK1.5) */
JNIEXPORT jclass JNICALL
JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader,
                          const jbyte *buf, jsize len, jobject pd,
                          const char *source) {
  // Discard source for now
  return JVM_DefineClass(env, name, loader, buf, len, pd);
}

/* Define a class with a source with conditional verification (added HSX 14)
 * -Xverify:all will verify anyway, -Xverify:none will not verify,
 * -Xverify:remote (default) will obey this conditional
 * i.e. true = should_verify_class
 */
JNIEXPORT jclass JNICALL
JVM_DefineClassWithSourceCond(JNIEnv *env, const char *name, jobject loader,
                              const jbyte *buf, jsize len, jobject pd,
                              const char *source, jboolean verify) {
  // Discard source and verification
  return JVM_DefineClass(env, name, loader, buf, len, pd);
}

/*
 * Reflection support functions
 */

JNIEXPORT jstring JNICALL
JVM_GetClassName(JNIEnv *env, jclass cls) {
  JavaObject * result = 0;
  JavaObject * Cl = 0;
  llvm_gcroot(result, 0);
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  const UTF8* iname = cl->getName();
  result = JavaString::internalToJava(iname, vm);

  RETURN_REF_FROM_JNI(result, jstring);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobjectArray JNICALL
JVM_GetClassInterfaces(JNIEnv *env, jclass cls) {
  JavaObjectClass* cl = 0;
  ArrayObject* ret = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(cl, 0);

  BEGIN_JNI_EXCEPTION

  cl = *(JavaObjectClass**)cls;
  ret = JavaObjectClass::getInterfaces(cl);

  RETURN_REF_FROM_JNI(ret, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobject JNICALL
JVM_GetClassLoader(JNIEnv *env, jclass cls) {
  JavaObject * Cl = *(JavaObject**)cls;
  JavaObject * res = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(res, 0);
  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  res = cl->classLoader->getJavaClassLoader();
  RETURN_REF_FROM_JNI(res, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jboolean JNICALL
JVM_IsInterface(JNIEnv *env, jclass cls) {
  jboolean res = JNI_FALSE;

  JavaObject * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  res = cl->isInterface();

  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(JNI_FALSE);
}

JNIEXPORT jobjectArray JNICALL
JVM_GetClassSigners(JNIEnv *env, jclass cls) {
  NYI();
}

JNIEXPORT void JNICALL
JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers) {
  // Let them 'set' signers, since we don't implement this yet and
  // don't allow them to 'get' the value back (above).
  //NYI();
}

JNIEXPORT jobject JNICALL
JVM_GetProtectionDomain(JNIEnv *env, jclass cls) {
  JavaObjectClass * JOC = 0;
  JavaObject * pd = 0;
  llvm_gcroot(JOC, 0);
  llvm_gcroot(pd, 0);
  BEGIN_JNI_EXCEPTION

  JOC = *(JavaObjectClass**)cls;
  pd = JavaObjectClass::getProtectionDomain(JOC);

  RETURN_REF_FROM_JNI(pd, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain) {
  NYI();
}

JNIEXPORT jboolean JNICALL
JVM_IsArrayClass(JNIEnv *env, jclass cls) {
  JavaObject * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  jboolean ret = cl->isArray();
  RETURN_FROM_JNI(ret);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(JNI_FALSE);
}

JNIEXPORT jboolean JNICALL
JVM_IsPrimitiveClass(JNIEnv *env, jclass cls) {
  JavaObject * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  jboolean ret = cl->isPrimitive();
  RETURN_FROM_JNI(ret);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(JNI_FALSE);
}

JNIEXPORT jclass JNICALL
JVM_GetComponentType(JNIEnv *env, jclass cls) {
  JavaObject * Cl = 0;
  JavaObject* res = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(res, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;
  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);

  if (cl->isArray()) {
    UserCommonClass* bc = cl->asArrayClass()->baseClass();
    res = (JavaObject*)bc->getClassDelegateePtr(vm);
  } else {
    res = 0;
  }

  RETURN_FROM_JNI((jclass)res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jint JNICALL
JVM_GetClassModifiers(JNIEnv *env, jclass cls) {
  JavaObjectClass * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObjectClass**)cls;

  jint res = JavaObjectClass::getModifiers(Cl);
  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobjectArray JNICALL
JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass) {
  JavaObjectClass* cl = 0;
  ArrayObject* ret = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(cl, 0);

  BEGIN_JNI_EXCEPTION

  // TODO: Verify boolean parameter here, assuming should default to true.
  cl = *(JavaObjectClass**)ofClass;
  ret = JavaObjectClass::getDeclaredClasses(cl, false);

  RETURN_REF_FROM_JNI(ret, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jclass JNICALL
JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass) {
  JavaObject* ret = 0;
  llvm_gcroot(ret, 0);

  BEGIN_JNI_EXCEPTION

  ret = JavaObjectClass::getDeclaringClass(*(JavaObjectClass**)ofClass);

  RETURN_REF_FROM_JNI(ret, jclass);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* Generics support (JDK 1.5) */
JNIEXPORT jstring JNICALL
JVM_GetClassSignature(JNIEnv *env, jclass cls) {
  JavaObjectClass * Cl = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_JNI_EXCEPTION

  Cl = cls ? *(JavaObjectClass**)cls : 0;
  verifyNull(Cl);

  Class* cl = JavaObjectClass::getClass(Cl)->asClass();
  if (!cl) return 0;

  JavaString** sig = JavaObjectClass::getSignature(cl);
  RETURN_FROM_JNI((jstring)sig);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* Annotations support (JDK 1.5) */
JNIEXPORT jbyteArray JNICALL
JVM_GetClassAnnotations(JNIEnv *env, jclass cls) {
  ArraySInt8 * ret = 0;
  JavaObjectClass* Cl = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(Cl, 0);

  BEGIN_JNI_EXCEPTION

  Cl = cls ? *(JavaObjectClass**)cls : 0;
  verifyNull(Cl);
  Class * cl = JavaObjectClass::getClass(Cl)->asClass();

  if (cl)
    ret = JavaObjectClass::getAnnotations(cl);

  RETURN_REF_FROM_JNI(ret, jbyteArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * New (JDK 1.4) reflection implementation
 */

JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly) {
  JavaObjectClass* cl = 0;
  ArrayObject* ret = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(cl, 0);

  BEGIN_JNI_EXCEPTION

  cl = *(JavaObjectClass**)ofClass;
  ret = JavaObjectClass::getDeclaredMethods(cl, publicOnly);

  RETURN_REF_FROM_JNI(ret, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly) {
  JavaObjectClass* cl = 0;
  ArrayObject* ret = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(cl, 0);

  BEGIN_JNI_EXCEPTION

  cl = *(JavaObjectClass**)ofClass;
  ret = JavaObjectClass::getDeclaredFields(cl, publicOnly);

  RETURN_REF_FROM_JNI(ret, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobjectArray JNICALL
JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly) {
  JavaObjectClass* cl = 0;
  ArrayObject* ret = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(cl, 0);

  BEGIN_JNI_EXCEPTION

  cl = *(JavaObjectClass**)ofClass;
  ret = JavaObjectClass::getDeclaredConstructors(cl, publicOnly);

  RETURN_REF_FROM_JNI(ret, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* Differs from JVM_GetClassModifiers in treatment of inner classes.
   This returns the access flags for the class as specified in the
   class file rather than searching the InnerClasses attribute (if
   present) to find the source-level access flags. Only the values of
   the low 13 bits (i.e., a mask of 0x1FFF) are guaranteed to be
   valid. */
JNIEXPORT jint JNICALL
JVM_GetClassAccessFlags(JNIEnv *env, jclass cls) {
  JavaObject * Cl = 0;
  llvm_gcroot(Cl, 0);
  BEGIN_JNI_EXCEPTION

  Cl = *(JavaObject**)cls;

  Jnjvm* vm = JavaThread::get()->getJVM();
  UserCommonClass* cl = UserCommonClass::resolvedImplClass(vm, Cl, false);
  assert(cl->isClass());

  // TODO: Verify this is doing what this function is supposed to do
  // (In particular regarding the comment block above)
  jint res = cl->asClass()->access;
  RETURN_FROM_JNI(res);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/* The following two reflection routines are still needed due to startup time issues */
/*
 * java.lang.reflect.Method
 */
JNIEXPORT jobject JNICALL
JVM_InvokeMethod(JNIEnv *env, jobject _m, jobject _obj, jobjectArray args0) {
  JavaObject * ret = 0;
  JavaObjectMethod * m = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(m, 0);

  BEGIN_JNI_EXCEPTION

  m = *(JavaObjectMethod**)_m;

  ret = proceedMethod(
    m,
    _obj ? *(JavaObject**)_obj : 0,
    args0? *(ArrayObject**)args0 : 0,
    JavaObjectMethod::getClass(m)->getDelegatee(),
    0 /* unused */ );

  RETURN_REF_FROM_JNI(ret, jobject);
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.lang.reflect.Constructor
 */
JNIEXPORT jobject JNICALL
JVM_NewInstanceFromConstructor(JNIEnv *env, jobject _c, jobjectArray args0) {
  JavaObject * ret = 0;
  JavaObjectConstructor * c = 0;
  llvm_gcroot(ret, 0);
  llvm_gcroot(c, 0);

  BEGIN_JNI_EXCEPTION

  c = *(JavaObjectConstructor**)_c;

  ret = proceedConstructor(
    c,
    args0? *(ArrayObject**)args0 : 0,
    JavaObjectConstructor::getClass(c)->getDelegatee(),
    0 /* unused */ );

  RETURN_REF_FROM_JNI(ret, jobject);
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Constant pool access; currently used to implement reflective access to annotations (JDK 1.5
 */

JNIEXPORT jobject JNICALL
JVM_GetClassConstantPool(JNIEnv *env, jclass cls) {
  JavaObjectClass * Cl = 0;
  JavaObject* CP = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(CP, 0);
  BEGIN_JNI_EXCEPTION

  Cl = cls ? *(JavaObjectClass**)cls : 0;
  verifyNull(Cl);

  Jnjvm* vm = th->getJVM();

  CP = vm->upcalls->constantPoolClass->doNew(vm);

  // Set the constantPoolOop field to point to the Class this
  // ConstantPool object is supposed to represent the constant pool for.
  vm->upcalls->constantPoolOop->setInstanceObjectField(CP, Cl);

  RETURN_REF_FROM_JNI(CP, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jint JNICALL JVM_ConstantPoolGetSize
(JNIEnv *env, jobject unused, jobject jcpool) {
  NYI();
}

JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jclass JNICALL JVM_ConstantPoolGetClassAtIfLoaded
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jobject JNICALL JVM_ConstantPoolGetMethodAtIfLoaded
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jobject JNICALL JVM_ConstantPoolGetFieldAtIfLoaded
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jobjectArray JNICALL JVM_ConstantPoolGetMemberRefInfoAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jint JNICALL JVM_ConstantPoolGetIntAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  JavaObjectClass* Cl = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_JNI_EXCEPTION

  Cl = jcpool ? *(JavaObjectClass**)jcpool : 0;
  verifyNull(Cl);

  Class* cl = JavaObjectClass::getClass(Cl)->asClass();
  assert(cl);

  sint32 ret = cl->getConstantPool()->IntegerAt(index);
  RETURN_FROM_JNI(ret);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jlong JNICALL JVM_ConstantPoolGetLongAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jfloat JNICALL JVM_ConstantPoolGetFloatAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jdouble JNICALL JVM_ConstantPoolGetDoubleAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jstring JNICALL JVM_ConstantPoolGetStringAt
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  NYI();
}

JNIEXPORT jstring JNICALL JVM_ConstantPoolGetUTF8At
(JNIEnv *env, jobject unused, jobject jcpool, jint index) {
  JavaObjectClass* Cl = 0;
  llvm_gcroot(Cl, 0);

  BEGIN_JNI_EXCEPTION

  Cl = jcpool ? *(JavaObjectClass**)jcpool : 0;
  verifyNull(Cl);

  Class* cl = JavaObjectClass::getClass(Cl)->asClass();
  assert(cl);

  const UTF8* utf = cl->getConstantPool()->UTF8At(index);
  assert(utf);

  jstring str = (jstring)cl->classLoader->UTF8ToStr(utf);

  RETURN_FROM_JNI(str);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.security.*
 */

JNIEXPORT jobject JNICALL
JVM_DoPrivileged(JNIEnv *env, jclass cls,
                 jobject action, jobject context, jboolean wrapException) {
  JavaObject * obj = 0;
  JavaObject * res = 0;
  llvm_gcroot(obj, 0);
  llvm_gcroot(res, 0);
  BEGIN_JNI_EXCEPTION

  verifyNull(action);

  obj = *(JavaObject**)action;

  Jnjvm* vm = th->getJVM();

  // For now, we don't do anything special,
  // just call the requested 'run()' method...
  UserClass * cl = JavaObject::getClass(obj)->asClass();
  const UTF8 * runName = cl->classLoader->hashUTF8->lookupAsciiz("run");
  const UTF8 * runType = cl->classLoader->hashUTF8->lookupAsciiz("()Ljava/lang/Object;");
  assert(cl); assert(runName); assert(runType);

  JavaMethod * meth = cl->lookupMethodDontThrow(runName, runType, false, true, 0);
  assert(meth);

  res = meth->invokeJavaObjectVirtual(vm, cl, obj);

  RETURN_REF_FROM_JNI(res, jobject);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT jobject JNICALL
JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls) {
  // No AccessControlContext supported yet
  return NULL;
}


JNIEXPORT jobject JNICALL
JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls) {
  // No AccessControlContext supported yet
  return NULL;
}

/*
 * Signal support, used to implement the shutdown sequence.  Every VM must
 * support JVM_SIGINT and JVM_SIGTERM, raising the former for user interrupts
 * (^C) and the latter for external termination (kill, system shutdown, etc.).
 * Other platform-dependent signal values may also be supported.
 */

JNIEXPORT void * JNICALL
JVM_RegisterSignal(jint sig, void *handler) {
  // Don't let signals be registered, yet.
  return (void*)-1;
}

JNIEXPORT jboolean JNICALL
JVM_RaiseSignal(jint sig) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_FindSignal(const char *name) {
  // Map Signal name to integer...
  static struct {
    const char * name;
    int num;
  } SignalMap[] =
  {
    { "TERM", SIGTERM },
    { "HUP", SIGHUP },
    { "INT", SIGINT }
  };
  static uint32 signal_count = sizeof(SignalMap)/sizeof(SignalMap[0]);

  BEGIN_JNI_EXCEPTION

  for(uint32 i = 0; i < signal_count; ++i) {
    if (!strcmp(name, SignalMap[i].name))
      RETURN_FROM_JNI(SignalMap[i].num);
  }

  fprintf(stderr, "Unknown Signal \"%s\", missing entry in table?\n", name);
  UNIMPLEMENTED();

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Retrieve the assertion directives for the specified class.
 */
JNIEXPORT jboolean JNICALL
JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls) {
  // TODO: Actually implement?
  return JNI_FALSE;
}

/*
 * Retrieve the assertion directives from the VM.
 */
JNIEXPORT jobject JNICALL
JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused) {
  JavaObject* asdObj = 0;
  JavaObject* emptyStringArr = 0;
  llvm_gcroot(asdObj, 0);
  llvm_gcroot(emptyStringArr, 0);
  BEGIN_JNI_EXCEPTION

  Jnjvm* vm = th->getJVM();
  UserClass * asdCl = vm->upcalls->assertionStatusDirectivesClass;
  asdObj = asdCl->doNew(vm);

  emptyStringArr = vm->upcalls->ArrayOfString->doNew(0, vm);

  const UTF8 * classesName = asdCl->classLoader->hashUTF8->lookupAsciiz("classes");
  const UTF8 * packagesName = asdCl->classLoader->hashUTF8->lookupAsciiz("packages");
  const UTF8 * stringArrType = asdCl->classLoader->hashUTF8->lookupAsciiz("[Ljava/lang/String;");
  JavaField* classes = asdCl->lookupFieldDontThrow(classesName, stringArrType, false, true, 0);
  JavaField* packages = asdCl->lookupFieldDontThrow(packagesName, stringArrType, false, true, 0);
  assert(classes);
  assert(packages);

  classes->setInstanceObjectField(asdObj, emptyStringArr);
  packages->setInstanceObjectField(asdObj, emptyStringArr);

  RETURN_REF_FROM_JNI(asdObj, jobject);
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * java.util.concurrent.AtomicLong
 */
JNIEXPORT jboolean JNICALL
JVM_SupportsCX8(void) {
  return JNI_FALSE;
}

/*************************************************************************
 PART 2: Support for the Verifier and Class File Format Checker
 ************************************************************************/
/*
 * Return the class name in UTF format. The result is valid
 * until JVM_ReleaseUTf is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetClassNameUTF(JNIEnv *env, jclass cb) {
  NYI();
}

/*
 * Returns the constant pool types in the buffer provided by "types."
 */
JNIEXPORT void JNICALL
JVM_GetClassCPTypes(JNIEnv *env, jclass cb, unsigned char *types) {
  NYI();
}

/*
 * Returns the number of Constant Pool entries.
 */
JNIEXPORT jint JNICALL
JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cb) {
  NYI();
}

/*
 * Returns the number of *declared* fields or methods.
 */
JNIEXPORT jint JNICALL
JVM_GetClassFieldsCount(JNIEnv *env, jclass cb) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_GetClassMethodsCount(JNIEnv *env, jclass cb) {
  NYI();
}

/*
 * Returns the CP indexes of exceptions raised by a given method.
 * Places the result in the given buffer.
 *
 * The method is identified by method_index.
 */
JNIEXPORT void JNICALL
JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cb, jint method_index,
                                unsigned short *exceptions) {
  NYI();
}

/*
 * Returns the number of exceptions raised by a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cb, jint method_index) {
  NYI();
}

/*
 * Returns the byte code sequence of a given method.
 * Places the result in the given buffer.
 *
 * The method is identified by method_index.
 */
JNIEXPORT void JNICALL
JVM_GetMethodIxByteCode(JNIEnv *env, jclass cb, jint method_index,
                        unsigned char *code) {
  NYI();
}

/*
 * Returns the length of the byte code sequence of a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cb, jint method_index) {
  NYI();
}

/*
 * Returns the exception table entry at entry_index of a given method.
 * Places the result in the given buffer.
 *
 * The method is identified by method_index.
 */
JNIEXPORT void JNICALL
JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cb, jint method_index,
                                   jint entry_index,
                                   JVM_ExceptionTableEntryType *entry) {
  NYI();
}

/*
 * Returns the length of the exception table of a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the modifiers of a given field.
 * The field is identified by field_index.
 */
JNIEXPORT jint JNICALL
JVM_GetFieldIxModifiers(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the modifiers of a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxModifiers(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the number of local variables of a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the number of arguments (including this pointer) of a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the maximum amount of stack (in words) used by a given method.
 * The method is identified by method_index.
 */
JNIEXPORT jint JNICALL
JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Is a given method a constructor.
 * The method is identified by method_index.
 */
JNIEXPORT jboolean JNICALL
JVM_IsConstructorIx(JNIEnv *env, jclass cb, int index) {
  NYI();
}

/*
 * Returns the name of a given method in UTF format.
 * The result remains valid until JVM_ReleaseUTF is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the signature of a given method in UTF format.
 * The result remains valid until JVM_ReleaseUTF is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the name of the field refered to at a given constant pool
 * index.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the name of the method refered to at a given constant pool
 * index.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the signature of the method refered to at a given constant pool
 * index.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the signature of the field refered to at a given constant pool
 * index.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the class name refered to at a given constant pool index.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPClassNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the class name refered to at a given constant pool index.
 *
 * The constant pool entry must refer to a CONSTANT_Fieldref.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the class name refered to at a given constant pool index.
 *
 * The constant pool entry must refer to CONSTANT_Methodref or
 * CONSTANT_InterfaceMethodref.
 *
 * The result is in UTF format and remains valid until JVM_ReleaseUTF
 * is called.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 */
JNIEXPORT const char * JNICALL
JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cb, jint index) {
  NYI();
}

/*
 * Returns the modifiers of a field in calledClass. The field is
 * referred to in class cb at constant pool entry index.
 *
 * The caller must treat the string as a constant and not modify it
 * in any way.
 *
 * Returns -1 if the field does not exist in calledClass.
 */
JNIEXPORT jint JNICALL
JVM_GetCPFieldModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass) {
  NYI();
}

/*
 * Returns the modifiers of a method in calledClass. The method is
 * referred to in class cb at constant pool entry index.
 *
 * Returns -1 if the method does not exist in calledClass.
 */
JNIEXPORT jint JNICALL
JVM_GetCPMethodModifiers(JNIEnv *env, jclass cb, int index, jclass calledClass) {
  NYI();
}

/*
 * Releases the UTF string obtained from the VM.
 */
JNIEXPORT void JNICALL
JVM_ReleaseUTF(const char *utf) {
  NYI();
}

/*
 * Compare if two classes are in the same package.
 */
JNIEXPORT jboolean JNICALL
JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2) {
  NYI();
}

/* Write a string into the given buffer, in the platform's local encoding,
 * that describes the most recent system-level error to occur in this thread.
 * Return the length of the string or zero if no error occurred.
 */
JNIEXPORT jint JNICALL
JVM_GetLastErrorString(char *buf, int len) {
  BEGIN_JNI_EXCEPTION
  char * err = strerror_r(errno, buf, len);
  if (err != buf)
    strncpy(buf, err, len);

  jint len = strlen(buf);
  RETURN_FROM_JNI(len);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Convert a pathname into native format.  This function does syntactic
 * cleanup, such as removing redundant separator characters.  It modifies
 * the given pathname string in place.
 */
JNIEXPORT char * JNICALL
JVM_NativePath(char * path) {
  // TODO: Implement me?
  return path;
}

/*
 * Open a file descriptor. This function returns a negative error code
 * on error, and a non-negative integer that is the file descriptor on
 * success.
 */
JNIEXPORT jint JNICALL
JVM_Open(const char *fname, jint flags, jint mode) {
  // Special flag the JVM uses
  // means to delete the file after opening.
  static const int O_DELETE = 0x10000;

  BEGIN_JNI_EXCEPTION

  int result = open(fname, flags & ~O_DELETE, mode);

  // Map EEXIST to special JVM_EEXIST, otherwise all errors are -1
  if (result < 0) {
    if (errno == EEXIST) {
      RETURN_FROM_JNI(JVM_EEXIST);
    } else {
      RETURN_FROM_JNI(-1);
    }
  }

  // Handle O_DELETE flag, if specified
  if (flags & O_DELETE)
    unlink(fname);

  RETURN_FROM_JNI(result);
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(-1);
}

/*
 * Close a file descriptor. This function returns -1 on error, and 0
 * on success.
 *
 * fd        the file descriptor to close.
 */
JNIEXPORT jint JNICALL
JVM_Close(jint fd) {
  BEGIN_JNI_EXCEPTION
  jint res = close(fd);
  RETURN_FROM_JNI(res);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(-1);
}

/*
 * Read data from a file decriptor into a char array.
 *
 * fd        the file descriptor to read from.
 * buf       the buffer where to put the read data.
 * nbytes    the number of bytes to read.
 *
 * This function returns -1 on error, and 0 on success.
 * (WDTZ: If I return '0' on success, things die. Returning
 *  number of bytes read instead for now)
 */
JNIEXPORT jint JNICALL
JVM_Read(jint fd, char *buf, jint nbytes) {
  BEGIN_JNI_EXCEPTION
  vmkit::Thread* th = vmkit::Thread::get();
  jint res = 0;
  //if (fd)
  //	res = read(fd, buf, nbytes);
  //else {
  	th->enterUncooperativeCode();
  	res = read(fd, buf, nbytes);
  	th->leaveUncooperativeCode();
  //}
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(-1);
}

/*
 * Write data from a char array to a file decriptor.
 *
 * fd        the file descriptor to read from.
 * buf       the buffer from which to fetch the data.
 * nbytes    the number of bytes to write.
 *
 * This function returns -1 on error, and 0 on success.
 */
JNIEXPORT jint JNICALL
JVM_Write(jint fd, char *buf, jint nbytes) {
  BEGIN_JNI_EXCEPTION
  jint res = write(fd, buf, nbytes);
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(-1);
}

/*
 * Returns the number of bytes available for reading from a given file
 * descriptor
 */
JNIEXPORT jint JNICALL
JVM_Available(jint fd, jlong *pbytes) {
  // From JamVM's JVM_Available implementation, GPLv2
  BEGIN_JNI_EXCEPTION
  struct stat sb;

  if(fstat(fd, &sb) == -1)
    RETURN_FROM_JNI(0);

  switch(sb.st_mode & S_IFMT) {
    case S_IFCHR:
    case S_IFIFO:
    case S_IFSOCK: {
      int n;

      if(ioctl(fd, TIOCINQ, &n) == -1)
        RETURN_FROM_JNI(0);

      *pbytes = n;
      RETURN_FROM_JNI(1);
    }

    default: {
      off64_t cur, end;

      if((cur = lseek64(fd, 0, SEEK_CUR)) == -1)
        RETURN_FROM_JNI(0);

      if((end = lseek64(fd, 0, SEEK_END)) == -1)
        RETURN_FROM_JNI(0);

      if(lseek64(fd, cur, SEEK_SET) == -1)
        RETURN_FROM_JNI(0);

      *pbytes = end - cur;
      RETURN_FROM_JNI(1);
    }
  }
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(0);
}

/*
 * Move the file descriptor pointer from whence by offset.
 *
 * fd        the file descriptor to move.
 * offset    the number of bytes to move it by.
 * whence    the start from where to move it.
 *
 * This function returns the resulting pointer location.
 */
JNIEXPORT jlong JNICALL
JVM_Lseek(jint fd, jlong offset, jint whence) {
  BEGIN_JNI_EXCEPTION
  jlong res = lseek64(fd, offset, whence);
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(0);
}

/*
 * Set the length of the file associated with the given descriptor to the given
 * length.  If the new length is longer than the current length then the file
 * is extended; the contents of the extended portion are not defined.  The
 * value of the file pointer is undefined after this procedure returns.
 */
JNIEXPORT jint JNICALL
JVM_SetLength(jint fd, jlong length) {
  int res = ftruncate64(fd, length);
  return res != -1;
}

/*
 * Synchronize the file descriptor's in memory state with that of the
 * physical device.  Return of -1 is an error, 0 is OK.
 */
JNIEXPORT jint JNICALL
JVM_Sync(jint fd) {
  return fsync(fd);
}

/*
 * Networking library support
 */

JNIEXPORT jint JNICALL
JVM_InitializeSocketLibrary(void) {
  // Nothing to do here.
  return 0;
}

JNIEXPORT jint JNICALL
JVM_Socket(jint domain, jint type, jint protocol) {
  return socket(domain, type, protocol);
}

JNIEXPORT jint JNICALL
JVM_SocketClose(jint fd) {
  return close(fd);
}

JNIEXPORT jint JNICALL
JVM_SocketShutdown(jint fd, jint howto) {
  // Nothing to do here.
  return true;
}

JNIEXPORT jint JNICALL
JVM_Recv(jint fd, char *buf, jint nBytes, jint flags) {
  return recv(fd, buf, nBytes, flags);
}

JNIEXPORT jint JNICALL
JVM_Send(jint fd, char *buf, jint nBytes, jint flags) {
  return send(fd, buf, nBytes, flags);
}

JNIEXPORT jint JNICALL
JVM_Timeout(int fd, long timeout) {
  NYI();
}

JNIEXPORT jint JNICALL
JVM_Listen(jint fd, jint count) {
  return listen(fd, count);
}

JNIEXPORT jint JNICALL
JVM_Connect(jint fd, struct sockaddr *him, jint len) {
  return connect(fd, him, len);
}

JNIEXPORT jint JNICALL
JVM_Bind(jint fd, struct sockaddr *him, jint len) {
  return bind(fd, him, len);
}

JNIEXPORT jint JNICALL
JVM_Accept(jint fd, struct sockaddr *him, jint *len) {
	BEGIN_JNI_EXCEPTION
	vmkit::Thread* th = vmkit::Thread::get();
  	th->enterUncooperativeCode();
  	jint res = accept(fd, him, (socklen_t*)len);
  	th->leaveUncooperativeCode();
	RETURN_FROM_JNI(res);
	END_JNI_EXCEPTION
	RETURN_FROM_JNI(-1);
}

JNIEXPORT jint JNICALL
JVM_RecvFrom(jint fd, char *buf, int nBytes,
                  int flags, struct sockaddr *from, int *fromlen) {
    BEGIN_JNI_EXCEPTION
	vmkit::Thread* th = vmkit::Thread::get();
  	th->enterUncooperativeCode();
  	jint res = recvfrom(fd, buf, nBytes, flags, from, (socklen_t*)fromlen);
  	th->leaveUncooperativeCode();
	RETURN_FROM_JNI(res);
	END_JNI_EXCEPTION
	RETURN_FROM_JNI(-1);
}

JNIEXPORT jint JNICALL
JVM_SendTo(jint fd, char *buf, int len,
                int flags, struct sockaddr *to, int tolen) {
  return sendto(fd, buf, len, flags, to, (socklen_t)tolen);
}

JNIEXPORT jint JNICALL
JVM_SocketAvailable(jint fd, jint *result) {

  BEGIN_JNI_EXCEPTION

  if(ioctl(fd, TIOCINQ, result) == -1)
    RETURN_FROM_JNI(JNI_FALSE);

  RETURN_FROM_JNI(JNI_TRUE);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(JNI_FALSE);
}


JNIEXPORT jint JNICALL
JVM_GetSockName(jint fd, struct sockaddr *him, int *len) {
  return getsockname(fd, him, (socklen_t*)len);
}

JNIEXPORT jint JNICALL
JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen) {
  return getsockopt(fd, level, optname, optval, (socklen_t*)optlen);
}

JNIEXPORT jint JNICALL
JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen) {
  return setsockopt(fd, level, optname, optval, optlen);
}

/*
 * These routines are only reentrant on Windows
 */

JNIEXPORT int JNICALL
JVM_GetHostName(char* name, int namelen) {
  return gethostname(name, namelen);
}

/*
 * The standard printing functions supported by the Java VM. (Should they
 * be renamed to JVM_* in the future?
 */

/*
 * BE CAREFUL! The following functions do not implement the
 * full feature set of standard C printf formats.
 */
int
jio_vsnprintf(char *str, size_t count, const char *fmt, va_list args) {
  return vsnprintf(str, count, fmt, args);
}

int
jio_snprintf(char *str, size_t count, const char *fmt, ...) {
  va_list args;
  int res;

  va_start(args, fmt);
  res = vsnprintf(str, count, fmt, args);
  va_end(args);

  return res;
}

int
jio_fprintf(FILE *, const char *fmt, ...) {
  NYI();
}

int
jio_vfprintf(FILE *, const char *fmt, va_list args) {
  NYI();
}

JNIEXPORT void * JNICALL
JVM_RawMonitorCreate(void) {
  BEGIN_JNI_EXCEPTION
  pthread_mutex_t* L = (pthread_mutex_t*)malloc(sizeof(pthread_mutex_t));
  pthread_mutex_init(L, NULL);

  RETURN_FROM_JNI(L);
  
  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_RawMonitorDestroy(void *mon) {
  BEGIN_JNI_EXCEPTION
  pthread_mutex_t* L = (pthread_mutex_t*)mon;
  pthread_mutex_destroy(L);
  free(L);

  END_JNI_EXCEPTION

  RETURN_VOID_FROM_JNI;
}

JNIEXPORT jint JNICALL
JVM_RawMonitorEnter(void *mon) {
  BEGIN_JNI_EXCEPTION
  pthread_mutex_t* L = (pthread_mutex_t*)mon;
  jint res = pthread_mutex_lock(L);
  RETURN_FROM_JNI(res);
  END_JNI_EXCEPTION
  RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_RawMonitorExit(void *mon) {
  BEGIN_JNI_EXCEPTION
  pthread_mutex_t* L = (pthread_mutex_t*)mon;
  pthread_mutex_unlock(L);
  END_JNI_EXCEPTION
  RETURN_VOID_FROM_JNI;
}

/*
 * java.lang.management support
 */
JNIEXPORT void* JNICALL
JVM_GetManagement(jint version) {
  NYI();
}

/*
 * com.sun.tools.attach.VirtualMachine support
 *
 * Initialize the agent properties with the properties maintained in the VM.
 */
JNIEXPORT jobject JNICALL
JVM_InitAgentProperties(JNIEnv *env, jobject agent_props) {
  NYI();
}

/* Generics reflection support.
 *
 * Returns information about the given class's EnclosingMethod
 * attribute, if present, or null if the class had no enclosing
 * method.
 *
 * If non-null, the returned array contains three elements. Element 0
 * is the java.lang.Class of which the enclosing method is a member,
 * and elements 1 and 2 are the java.lang.Strings for the enclosing
 * method's name and descriptor, respectively.
 */
JNIEXPORT jobjectArray JNICALL
JVM_GetEnclosingMethodInfo(JNIEnv* env, jclass ofClass) {
  JavaObjectClass * Cl = 0;
  ArrayObject * arr = 0;
  llvm_gcroot(Cl, 0);
  llvm_gcroot(arr, 0);

  BEGIN_JNI_EXCEPTION
  Jnjvm * vm = th->getJVM();

  Cl = ofClass ? *(JavaObjectClass**)ofClass : 0;
  verifyNull(Cl);

  CommonClass* CC =
    UserCommonClass::resolvedImplClass(vm, Cl, false);
  Class* cl = CC->asClass();

  // Primitives arrays, interfaces...
  if (!cl) RETURN_FROM_JNI(0);

  JavaAttribute* emAtt = cl->lookupAttribute(JavaAttribute::enclosingMethodAttribute);

  if (emAtt) {
    Reader reader(emAtt, cl->bytes);
    uint16 class_index = reader.readU2();
    uint16 method_index = reader.readU2();

    JavaConstantPool * cpl = cl->getConstantPool();
    CommonClass * enclosingClass = cpl->loadClass(class_index, true);
    assert(enclosingClass);

    arr = (ArrayObject*)vm->upcalls->ArrayOfObject->doNew(3,vm);
    ArrayObject::setElement(arr, enclosingClass->getClassDelegatee(vm), 0);

    if (method_index) {
      Signdef * sign = cl->getConstantPool()->resolveNameAndSign(method_index);
      assert(sign);

      const UTF8* methodName = cpl->UTF8At((cpl->ctpDef[method_index] >> 16) & 0xFFFF);
      assert(methodName);

      ArrayObject::setElement(arr, *cl->classLoader->UTF8ToStr(methodName), 1);
      ArrayObject::setElement(arr, *cl->classLoader->UTF8ToStr(sign->keyName), 2);
    }
  }

  RETURN_REF_FROM_JNI(arr, jobjectArray);

  END_JNI_EXCEPTION

  RETURN_FROM_JNI(0);
}

/*
 * Returns an array of the threadStatus values representing the
 * given Java thread state.  Returns NULL if the VM version is
 * incompatible with the JDK or doesn't support the given
 * Java thread state.
 */
JNIEXPORT jintArray JNICALL
JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState) {
	ArraySInt32* res = 0;
	jintArray result = 0;
	llvm_gcroot(res, 0);
	llvm_gcroot(result, 0);
	
	BEGIN_JNI_EXCEPTION
  	/* If new thread states are added in future JDK and VM versions,
	   this should check if the JDK version is compatible with thread
	   states supported by the VM.  Return NULL if not compatible.
	
	   This function must map the VM java_lang_Thread::ThreadStatus
	   to the Java thread state that the JDK supports. */
	Jnjvm* vm = JavaThread::get()->getJVM();
	Classpath* upcalls = vm->upcalls;
	UserClassArray* array = upcalls->ArrayOfInt;

	switch (javaThreadState) {
    case vmkit::LockingThread::StateNew:
    case vmkit::LockingThread::StateRunning:
    case vmkit::LockingThread::StateBlocked:
    case vmkit::LockingThread::StateTerminated:
	{
		res = (ArraySInt32*)array->doNew(1, vm);
		ArraySInt32::setElement(res, javaThreadState , 0);
		break;
	}

    case vmkit::LockingThread::StateWaiting:
	{
		res = (ArraySInt32*)array->doNew(2, vm);
		ArraySInt32::setElement(res, vmkit::LockingThread::StateWaiting , 0);
		ArraySInt32::setElement(res, vmkit::LockingThread::StateParked , 1);
		break;
	}

    case vmkit::LockingThread::StateTimeWaiting:
	{
		res = (ArraySInt32*)array->doNew(2, vm);
		ArraySInt32::setElement(res, vmkit::LockingThread::StateTimeWaiting , 0);
		ArraySInt32::setElement(res, vmkit::LockingThread::StateTimeParked , 1);
		break;
	}

    default:
		/* Unknown state - probably incompatible JDK version */
		break;
	}
	RETURN_REF_FROM_JNI(res, jintArray);
	END_JNI_EXCEPTION
	RETURN_FROM_JNI(0);
}

/*
 * Returns an array of the substate names representing the
 * given Java thread state.  Returns NULL if the VM version is
 * incompatible with the JDK or the VM doesn't support
 * the given Java thread state.
 * values must be the jintArray returned from JVM_GetThreadStateValues
 * and javaThreadState.
 */
JNIEXPORT jobjectArray JNICALL
JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values) {
	BEGIN_JNI_EXCEPTION
  
  ArrayObject* res = 0;
jobjectArray result = 0;
JavaObject* str = 0;
llvm_gcroot(res, 0);
llvm_gcroot(result, 0);
llvm_gcroot(str, 0);
llvm_gcroot(values, 0);

Jnjvm* vm = JavaThread::get()->getJVM();
Classpath* upcalls = vm->upcalls;
UserClassArray* array = upcalls->ArrayOfString;

JnjvmClassLoader* loader;

  switch (javaThreadState) {
    case vmkit::LockingThread::StateNew:
		{
			//assert(ia.get_length() == 1 && ia.get_element(0) == THREAD_STATE_NEW);

			res = (ArrayObject*)array->doNew(1, vm);
			str = (vm->asciizToStr("NEW"));
			ArrayObject::setElement(res, str, 0);
			break;
		}

    case vmkit::LockingThread::StateRunning:
		{
			res = (ArrayObject*)array->doNew(1, vm);
			str = (vm->asciizToStr("RUNNABLE"));
			ArrayObject::setElement(res, str, 0);
			break;
		}

    case vmkit::LockingThread::StateBlocked:
		{
			res = (ArrayObject*)array->doNew(1, vm);
			str = (vm->asciizToStr("BLOCKED"));
			ArrayObject::setElement(res, str, 0);
			break;
		}

    case vmkit::LockingThread::StateWaiting:
		{
			res = (ArrayObject*)array->doNew(2, vm);
			str = (vm->asciizToStr("WAITING.OBJECT_WAIT"));
			ArrayObject::setElement(res, str, 0);
			str = (vm->asciizToStr("WAITING.PARKED"));
			ArrayObject::setElement(res, str, 1);
			break;
		}

    case vmkit::LockingThread::StateTimeWaiting:
		{	
			res = (ArrayObject*)array->doNew(2, vm);
			str = (vm->asciizToStr("TIMED_WAITING.OBJECT_WAIT"));
			ArrayObject::setElement(res, str, 0);
			str = (vm->asciizToStr("TIMED_WAITING.PARKED"));
			ArrayObject::setElement(res, str, 1);
			break;
		}

    case vmkit::LockingThread::StateTerminated:
		{
			res = (ArrayObject*)array->doNew(1, vm);
			str = (vm->asciizToStr("TERMINATED"));
			ArrayObject::setElement(res, str, 0);
			break;
		}

	default:
		/* Unknown state - probably incompatible JDK version */
		break;
	}
	//th->leaveUncooperativeCode();
	RETURN_REF_FROM_JNI(res, jobjectArray);
	END_JNI_EXCEPTION
	RETURN_FROM_JNI(0);
}

JNIEXPORT void JNICALL
JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size) {
  NYI();
}
// vim: set ft=cpp:
