* src/native/vm/sun/jvm.c (JVM_EEXIST): Defined.
[cacao.git] / src / native / vm / sun / jvm.c
index d036f0566d2094f90141f60bb68751465d23d737..80de64b27a66a1f1f11da6dcc030d30b20a4d769 100644 (file)
@@ -1,6 +1,6 @@
 /* src/native/vm/sun/jvm.c - HotSpot JVM interface functions
 
-   Copyright (C) 2007 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 2007, 2008 R. Grafl, A. Krall, C. Kruegel,
    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
    J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   $Id: jvm.c 8341 2007-08-17 21:32:01Z michi $
-
 */
 
 
-#define PRINTJVM 0
-
 #include "config.h"
 
 #include <assert.h>
 #include <errno.h>
-#include <fcntl.h>
 #include <ltdl.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <string.h>
 #include <unistd.h>
@@ -46,6 +42,7 @@
 
 #include <sys/socket.h>
 #include <sys/stat.h>
+#include <sys/types.h>
 
 #include "vm/types.h"
 
 #include "native/include/java_lang_StackTraceElement.h"
 #include "native/include/java_lang_Throwable.h"
 #include "native/include/java_security_ProtectionDomain.h"
-#include "native/include/java_lang_Integer.h"
-#include "native/include/java_lang_Long.h"
-#include "native/include/java_lang_Short.h"
-#include "native/include/java_lang_Byte.h"
-#include "native/include/java_lang_Character.h"
-#include "native/include/java_lang_Boolean.h"
-#include "native/include/java_lang_Float.h"
-#include "native/include/java_lang_Double.h"
 
 #if defined(ENABLE_ANNOTATIONS)
 #include "native/include/sun_reflect_ConstantPool.h"
 
 #include "native/vm/java_lang_Class.h"
 #include "native/vm/java_lang_ClassLoader.h"
-#include "native/vm/java_lang_Object.h"
 #include "native/vm/java_lang_Runtime.h"
-#include "native/vm/java_lang_String.h"
 #include "native/vm/java_lang_Thread.h"
 #include "native/vm/java_lang_reflect_Constructor.h"
 #include "native/vm/java_lang_reflect_Method.h"
-#include "native/vm/java_util_concurrent_atomic_AtomicLong.h"
 #include "native/vm/reflect.h"
 
 #include "threads/lock-common.h"
+#include "threads/threads-common.h"
 
 #include "toolbox/logging.h"
+#include "toolbox/list.h"
 
 #include "vm/array.h"
+
+#if defined(ENABLE_ASSERTION)
+#include "vm/assertion.h"
+#endif
+
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/global.h"
 #include "vm/initialize.h"
+#include "vm/package.h"
 #include "vm/primitive.h"
 #include "vm/properties.h"
 #include "vm/resolve.h"
+#include "vm/signallocal.h"
 #include "vm/stringlocal.h"
 #include "vm/vm.h"
 
 
 #include "vmcore/classcache.h"
 #include "vmcore/options.h"
+#include "vmcore/system.h"
 
 
-/* debugging macro ************************************************************/
+/* debugging macro***********************************************************/
 
 #if !defined(NDEBUG)
-# define TRACEJVMCALLS(...) \
-    do { \
-        if (opt_TraceJVMCalls) { \
-            log_println(__VA_ARGS__); \
-        } \
+
+# define TRACEJVMCALLS(...)                                            \
+    do {                                                                               \
+        if (opt_TraceJVMCalls || opt_TraceJVMCallsVerbose) {                           \
+            log_println(__VA_ARGS__);                  \
+        }                                                                              \
+    } while (0)
+
+# define TRACEJVMCALLSVERBOSE(x)                               \
+    do {                                                                               \
+        if (opt_TraceJVMCallsVerbose) {                        \
+            log_println x;                                             \
+        }                                                                              \
     } while (0)
+
+# define PRINTJVMWARNINGS(...)
+/*     do { \ */
+/*         if (opt_PrintJVMWarnings) { \ */
+/*             log_println(__VA_ARGS__); \ */
+/*         } \ */
+/*     } while (0) */
+
 #else
+
 # define TRACEJVMCALLS(...)
+# define TRACEJVMCALLSVERBOSE(x)
+# define PRINTJVMWARNINGS(...)
+
 #endif
 
 
@@ -180,18 +196,24 @@ int jio_snprintf(char *str, size_t count, const char *fmt, ...)
 int jio_fprintf(FILE* f, const char *fmt, ...)
 {
        log_println("jio_fprintf: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
 int jio_vfprintf(FILE* f, const char *fmt, va_list args)
 {
        log_println("jio_vfprintf: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
 int jio_printf(const char *fmt, ...)
 {
        log_println("jio_printf: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -211,9 +233,8 @@ jint JVM_GetInterfaceVersion()
 
 jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
 {
-#if PRINTJVM
-       log_println("JVM_CurrentTimeMillis");
-#endif
+       TRACEJVMCALLS("JVM_CurrentTimeMillis(env=%p, ignored=%p)", env, ignored);
+
        return (jlong) builtin_currenttimemillis();
 }
 
@@ -222,9 +243,8 @@ jlong JVM_CurrentTimeMillis(JNIEnv *env, jclass ignored)
 
 jlong JVM_NanoTime(JNIEnv *env, jclass ignored)
 {
-#if PRINTJVM
-       log_println("JVM_NanoTime");
-#endif
+       TRACEJVMCALLS("JVM_NanoTime(env=%p, ignored=%p)", env, ignored);
+
        return (jlong) builtin_nanotime();
 }
 
@@ -239,11 +259,9 @@ void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobje
        s = (java_handle_t *) src;
        d = (java_handle_t *) dst;
 
-#if PRINTJVM
-       log_println("JVM_ArrayCopy: src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d", src, src_pos, dst, dst_pos, length);
-#endif
+       TRACEJVMCALLSVERBOSE(("JVM_ArrayCopy(env=%p, ignored=%p, src=%p, src_pos=%d, dst=%p, dst_pos=%d, length=%d)", env, ignored, src, src_pos, dst, dst_pos, length));
 
-       (void) builtin_arraycopy(s, src_pos, d, dst_pos, length);
+       builtin_arraycopy(s, src_pos, d, dst_pos, length);
 }
 
 
@@ -251,10 +269,15 @@ void JVM_ArrayCopy(JNIEnv *env, jclass ignored, jobject src, jint src_pos, jobje
 
 jobject JVM_InitProperties(JNIEnv *env, jobject properties)
 {
-#if PRINTJVM
-       log_println("JVM_InitProperties: properties=%d", properties);
-#endif
-       properties_system_add_all((java_handle_t *) properties);
+       java_handle_t *h;
+
+       TRACEJVMCALLS("JVM_InitProperties(env=%p, properties=%p)", env, properties);
+
+       h = (java_handle_t *) properties;
+
+       properties_system_add_all(h);
+
+       return properties;
 }
 
 
@@ -270,9 +293,8 @@ void JVM_Exit(jint code)
 
 void JVM_Halt(jint code)
 {
-#if PRINTJVM
-       log_println("JVM_Halt: code=%d", code);
-#endif
+       TRACEJVMCALLS("JVM_Halt(code=%d)", code);
+
 /*     vm_exit(code); */
        vm_shutdown(code);
 }
@@ -301,6 +323,8 @@ void JVM_GC(void)
 jlong JVM_MaxObjectInspectionAge(void)
 {
        log_println("JVM_MaxObjectInspectionAge: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -344,7 +368,9 @@ jlong JVM_FreeMemory(void)
 
 jlong JVM_MaxMemory(void)
 {
-       log_println("JVM_MaxMemory: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_MaxMemory()");
+
+       return gc_get_max_heap_size();
 }
 
 
@@ -352,7 +378,9 @@ jlong JVM_MaxMemory(void)
 
 jint JVM_ActiveProcessorCount(void)
 {
-       log_println("JVM_ActiveProcessorCount: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_ActiveProcessorCount()");
+
+       return system_processors_online();
 }
 
 
@@ -360,21 +388,19 @@ jint JVM_ActiveProcessorCount(void)
 
 void JVM_FillInStackTrace(JNIEnv *env, jobject receiver)
 {
-       java_lang_Throwable *o;
-       stacktracecontainer *stc;
+       java_lang_Throwable     *o;
+       java_handle_bytearray_t *ba;
 
-#if PRINTJVM
-       log_println("JVM_FillInStackTrace: receiver=%p", receiver);
-#endif
+       TRACEJVMCALLS("JVM_FillInStackTrace(env=%p, receiver=%p)", env, receiver);
 
        o = (java_lang_Throwable *) receiver;
 
-       stc = stacktrace_fillInStackTrace();
+       ba = stacktrace_get();
 
-       if (stc == NULL)
+       if (ba == NULL)
                return;
 
-    o->backtrace = (java_lang_Object *) stc;
+       LLNI_field_set_ref(o, backtrace, (java_lang_Object *) ba);
 }
 
 
@@ -390,19 +416,37 @@ void JVM_PrintStackTrace(JNIEnv *env, jobject receiver, jobject printable)
 
 jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 {
-       java_lang_Throwable *o;
-       stacktracecontainer *stc;
-       stacktracebuffer    *stb;
+       java_lang_Throwable     *t;
+       java_handle_bytearray_t *ba;
+       stacktrace_t            *st;
+       int32_t                  depth;
 
-#if PRINTJVM
-       log_println("JVM_GetStackTraceDepth: throwable=%p", throwable);
-#endif
+       TRACEJVMCALLS("JVM_GetStackTraceDepth(env=%p, throwable=%p)", env, throwable);
+
+       if (throwable == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
+       }
+
+       t = (java_lang_Throwable *) throwable;
+
+       LLNI_field_get_ref(t, backtrace, ba);
+
+       if (ba == NULL)
+               return 0;
+
+       /* We need a critical section here as the stacktrace structure is
+          mapped onto a Java byte-array. */
+
+       LLNI_CRITICAL_START;
+
+       st = (stacktrace_t *) LLNI_array_data(ba);
+
+       depth = st->length;
 
-       o   = (java_lang_Throwable *) throwable;
-       stc = (stacktracecontainer *) o->backtrace;
-       stb = &(stc->stb);
+       LLNI_CRITICAL_END;
 
-       return stb->used;
+       return depth;
 }
 
 
@@ -410,24 +454,29 @@ jint JVM_GetStackTraceDepth(JNIEnv *env, jobject throwable)
 
 jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 {
-       java_lang_Throwable *t;
-       stacktracecontainer *stc;
-       stacktracebuffer    *stb;
-       stacktrace_entry    *ste;
+       java_lang_Throwable         *t;
+       java_handle_bytearray_t     *ba;
+       stacktrace_t                *st;
+       stacktrace_entry_t          *ste;
+       codeinfo                    *code;
+       methodinfo                  *m;
+       classinfo                   *c;
        java_lang_StackTraceElement *o;
        java_lang_String            *declaringclass;
        java_lang_String            *filename;
-       s4                           linenumber;
+       int32_t                      linenumber;
 
-#if PRINTJVM
-       log_println("JVM_GetStackTraceElement: throwable=%p, index=%d", throwable, index);
-#endif
+       TRACEJVMCALLS("JVM_GetStackTraceElement(env=%p, throwable=%p, index=%d)", env, throwable, index);
+
+       t = (java_lang_Throwable *) throwable;
+
+       LLNI_field_get_ref(t, backtrace, ba);
+
+       /* FIXME critical section */
 
-       t   = (java_lang_Throwable *) throwable;
-       stc = (stacktracecontainer *) t->backtrace;
-       stb = &(stc->stb);
+       st = (stacktrace_t *) LLNI_array_data(ba);
 
-       if ((index < 0) || (index >= stb->used)) {
+       if ((index < 0) || (index >= st->length)) {
                /* XXX This should be an IndexOutOfBoundsException (check this
                   again). */
 
@@ -435,7 +484,15 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
                return NULL;
        }
 
-       ste = &(stb->entries[index]);
+       /* Get the stacktrace entry. */
+
+       ste = &(st->entries[index]);
+
+       /* Get the codeinfo, methodinfo and classinfo. */
+
+       code = ste->code;
+       m    = code->m;
+       c    = m->class;
 
        /* allocate a new StackTraceElement */
 
@@ -447,9 +504,9 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
        /* get filename */
 
-       if (!(ste->method->flags & ACC_NATIVE)) {
-               if (ste->method->class->sourcefile)
-                       filename = (java_lang_String *) javastring_new(ste->method->class->sourcefile);
+       if (!(m->flags & ACC_NATIVE)) {
+               if (c->sourcefile != NULL)
+                       filename = (java_lang_String *) javastring_new(c->sourcefile);
                else
                        filename = NULL;
        }
@@ -458,20 +515,27 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
        /* get line number */
 
-       if (ste->method->flags & ACC_NATIVE)
+       if (m->flags & ACC_NATIVE) {
                linenumber = -2;
-       else
-               linenumber = (ste->linenumber == 0) ? -1 : ste->linenumber;
+       }
+       else {
+               /* FIXME The linenumbertable_linenumber_for_pc could change
+                  the methodinfo pointer when hitting an inlined method. */
+
+               linenumber = linenumbertable_linenumber_for_pc(&m, code, ste->pc);
+               linenumber = (linenumber == 0) ? -1 : linenumber;
+       }
 
        /* get declaring class name */
 
-       declaringclass =
-               _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(ste->method->class));
+       declaringclass = _Jv_java_lang_Class_getName(LLNI_classinfo_wrap(c));
 
        /* fill the java.lang.StackTraceElement element */
 
+       /* FIXME critical section */
+
        o->declaringClass = declaringclass;
-       o->methodName     = (java_lang_String *) javastring_new(ste->method->name);
+       o->methodName     = (java_lang_String *) javastring_new(m->name);
        o->fileName       = filename;
        o->lineNumber     = linenumber;
 
@@ -483,9 +547,8 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
 
 jint JVM_IHashCode(JNIEnv* env, jobject handle)
 {
-#if PRINTJVM
-       log_println("JVM_IHashCode: jobject=%p", handle);
-#endif
+       TRACEJVMCALLS("JVM_IHashCode(env=%p, jobject=%p)", env, handle);
+
        return (jint) ((ptrint) handle);
 }
 
@@ -494,10 +557,22 @@ jint JVM_IHashCode(JNIEnv* env, jobject handle)
 
 void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
 {
-#if PRINTJVM
-       log_println("JVM_MonitorWait: handle=%p, ms=%ld", handle, ms);
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS("JVM_MonitorWait(env=%p, handle=%p, ms=%ld)", env, handle, ms);
+    if (ms < 0) {
+/*             exceptions_throw_illegalargumentexception("argument out of range"); */
+               exceptions_throw_illegalargumentexception();
+               return;
+       }
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_wait_for_object(o, ms, 0);
 #endif
-       _Jv_java_lang_Object_wait((java_lang_Object *) handle, ms, 0);
 }
 
 
@@ -505,10 +580,17 @@ void JVM_MonitorWait(JNIEnv* env, jobject handle, jlong ms)
 
 void JVM_MonitorNotify(JNIEnv* env, jobject handle)
 {
-#if PRINTJVM
-       log_println("JVM_MonitorNotify: IMPLEMENT ME!");
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS("JVM_MonitorNotify(env=%p, handle=%p)", env, handle);
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_notify_object(o);
 #endif
-       _Jv_java_lang_Object_notify((java_lang_Object *) handle);
 }
 
 
@@ -516,10 +598,17 @@ void JVM_MonitorNotify(JNIEnv* env, jobject handle)
 
 void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
 {
-#if PRINTJVM
-       log_println("JVM_MonitorNotifyAll: handle=%p", handle);
+#if defined(ENABLE_THREADS)
+       java_handle_t *o;
+#endif
+
+       TRACEJVMCALLS("JVM_MonitorNotifyAll(env=%p, handle=%p)", env, handle);
+
+#if defined(ENABLE_THREADS)
+       o = (java_handle_t *) handle;
+
+       lock_notify_all_object(o);
 #endif
-       _Jv_java_lang_Object_notifyAll((java_lang_Object *) handle);
 }
 
 
@@ -527,9 +616,8 @@ void JVM_MonitorNotifyAll(JNIEnv* env, jobject handle)
 
 jobject JVM_Clone(JNIEnv* env, jobject handle)
 {
-#if PRINTJVM
-       log_println("JVM_Clone: handle=%p", handle);
-#endif
+       TRACEJVMCALLS("JVM_Clone(env=%p, handle=%p)", env, handle);
+
        return (jobject) builtin_clone(env, (java_handle_t *) handle);
 }
 
@@ -547,6 +635,8 @@ void JVM_InitializeCompiler (JNIEnv *env, jclass compCls)
 jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
 {
        log_println("JVM_IsSilentCompiler: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -555,6 +645,8 @@ jboolean JVM_IsSilentCompiler(JNIEnv *env, jclass compCls)
 jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
 {
        log_println("JVM_CompileClass: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -563,6 +655,8 @@ jboolean JVM_CompileClass(JNIEnv *env, jclass compCls, jclass cls)
 jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
 {
        log_println("JVM_CompileClasses: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -571,6 +665,8 @@ jboolean JVM_CompileClasses(JNIEnv *env, jclass cls, jstring jname)
 jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
 {
        log_println("JVM_CompilerCommand: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -578,7 +674,8 @@ jobject JVM_CompilerCommand(JNIEnv *env, jclass compCls, jobject arg)
 
 void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
 {
-       log_println("JVM_EnableCompiler: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_EnableCompiler(env=%p, compCls=%p)", env, compCls);
+       PRINTJVMWARNINGS("JVM_EnableCompiler not supported");
 }
 
 
@@ -586,7 +683,8 @@ void JVM_EnableCompiler(JNIEnv *env, jclass compCls)
 
 void JVM_DisableCompiler(JNIEnv *env, jclass compCls)
 {
-       log_println("JVM_DisableCompiler: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_DisableCompiler(env=%p, compCls=%p)", env, compCls);
+       PRINTJVMWARNINGS("JVM_DisableCompiler not supported");
 }
 
 
@@ -618,11 +716,10 @@ jint JVM_GetLastErrorString(char *buf, int len)
 
 /* JVM_NativePath */
 
-char* JVM_NativePath(char* path)
+char *JVM_NativePath(char *path)
 {
-#if PRINTJVM
-       log_println("JVM_NativePath: path=%s", path);
-#endif
+       TRACEJVMCALLS("JVM_NativePath(path=%s)", path);
+
        /* XXX is this correct? */
 
        return path;
@@ -635,9 +732,7 @@ jclass JVM_GetCallerClass(JNIEnv* env, int depth)
 {
        java_handle_objectarray_t *oa;
 
-#if PRINTJVM
-       log_println("JVM_GetCallerClass: depth=%d", depth);
-#endif
+       TRACEJVMCALLS("JVM_GetCallerClass(env=%p, depth=%d)", env, depth);
 
        oa = stacktrace_getClassContext();
 
@@ -664,7 +759,7 @@ jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
        u = utf_new_char(s);
        c = primitive_class_get_by_name(u);
 
-       return LLNI_classinfo_wrap(c);
+       return (jclass) LLNI_classinfo_wrap(c);
 }
 
 
@@ -672,7 +767,8 @@ jclass JVM_FindPrimitiveClass(JNIEnv* env, const char* s)
 
 void JVM_ResolveClass(JNIEnv* env, jclass cls)
 {
-       log_println("JVM_ResolveClass: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_ResolveClass(env=%p, cls=%p)", env, cls);
+       PRINTJVMWARNINGS("JVM_ResolveClass not implemented");
 }
 
 
@@ -680,13 +776,16 @@ void JVM_ResolveClass(JNIEnv* env, jclass cls)
 
 jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init, jobject loader, jboolean throwError)
 {
-       classinfo *c;
+       classinfo   *c;
+       utf         *u;
+       classloader *cl;
 
-#if PRINTJVM
-       log_println("JVM_FindClassFromClassLoader: name=%s, init=%d, loader=%p, throwError=%d", name, init, loader, throwError);
-#endif
+       TRACEJVMCALLS("JVM_FindClassFromClassLoader(name=%s, init=%d, loader=%p, throwError=%d)", name, init, loader, throwError);
+
+       u  = utf_new_char(name);
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
-       c = load_class_from_classloader(utf_new_char(name), (classloader *) loader);
+       c = load_class_from_classloader(u, cl);
 
        if (c == NULL)
                return NULL;
@@ -696,7 +795,7 @@ jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init
                        if (!initialize_class(c))
                                return NULL;
 
-       return LLNI_classinfo_wrap(c);
+       return (jclass) LLNI_classinfo_wrap(c);
 }
 
 
@@ -705,6 +804,8 @@ jclass JVM_FindClassFromClassLoader(JNIEnv* env, const char* name, jboolean init
 jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jclass from)
 {
        log_println("JVM_FindClassFromClass: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -713,6 +814,8 @@ jclass JVM_FindClassFromClass(JNIEnv *env, const char *name, jboolean init, jcla
 jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd)
 {
        log_println("JVM_DefineClass: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -720,13 +823,24 @@ jclass JVM_DefineClass(JNIEnv *env, const char *name, jobject loader, const jbyt
 
 jclass JVM_DefineClassWithSource(JNIEnv *env, const char *name, jobject loader, const jbyte *buf, jsize len, jobject pd, const char *source)
 {
-#if PRINTJVM
-       log_println("JVM_DefineClassWithSource: name=%s, loader=%p, buf=%p, len=%d, pd=%p, source=%s", name, loader, buf, len, pd, source);
-#endif
-       /* XXX do something with pd and source */
+       classinfo   *c;
+       utf         *u;
+       classloader *cl;
+
+       TRACEJVMCALLS("JVM_DefineClassWithSource(env=%p, name=%s, loader=%p, buf=%p, len=%d, pd=%p, source=%s)", env, name, loader, buf, len, pd, source);
+
+       if (name != NULL)
+               u = utf_new_char(name);
+       else
+               u = NULL;
+
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
-       return LLNI_classinfo_wrap( class_define(utf_new_char(name), (classloader *) loader, len, (u1 *) buf) );
+       /* XXX do something with source */
 
+       c = class_define(u, cl, len, (const uint8_t *) buf, (java_handle_t *) pd);
+
+       return (jclass) LLNI_classinfo_wrap(c);
 }
 
 
@@ -738,16 +852,14 @@ jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
        utf         *u;
        classinfo   *c;
 
-       cl = (classloader *) loader;
+       TRACEJVMCALLS("JVM_FindLoadedClass(env=%p, loader=%p, name=%p)", env, loader, name);
 
-#if PRINTJVM
-       log_println("JVM_FindLoadedClass(loader=%p, name=%p)", loader, name);
-#endif
+       cl = loader_hashtable_classloader_add((java_handle_t *) loader);
 
        u = javastring_toutf((java_handle_t *) name, true);
        c = classcache_lookup(cl, u);
 
-       return LLNI_classinfo_wrap(c);
+       return (jclass) LLNI_classinfo_wrap(c);
 }
 
 
@@ -755,9 +867,8 @@ jclass JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name)
 
 jstring JVM_GetClassName(JNIEnv *env, jclass cls)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassName: cls=%p", cls);
-#endif
+       TRACEJVMCALLS("JVM_GetClassName(env=%p, cls=%p)", env, cls);
+
        return (jstring) _Jv_java_lang_Class_getName((java_lang_Class *) cls);
 }
 
@@ -783,10 +894,15 @@ jobjectArray JVM_GetClassInterfaces(JNIEnv *env, jclass cls)
 
 jobject JVM_GetClassLoader(JNIEnv *env, jclass cls)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassLoader: cls=%p", cls);
-#endif
-       return (jobject) _Jv_java_lang_Class_getClassLoader((java_lang_Class *) cls);
+       classinfo   *c;
+       classloader *cl;
+
+       TRACEJVMCALLS("JVM_GetClassLoader(env=%p, cls=%p)", env, cls);
+
+       c  = LLNI_classinfo_unwrap(cls);
+       cl = class_get_classloader(c);
+
+       return (jobject) cl;
 }
 
 
@@ -796,9 +912,7 @@ jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-#if PRINTJVM
-       log_println("JVM_IsInterface: cls=%p", cls);
-#endif
+       TRACEJVMCALLS("JVM_IsInterface(env=%p, cls=%p)", env, cls);
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -811,6 +925,8 @@ jboolean JVM_IsInterface(JNIEnv *env, jclass cls)
 jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassSigners: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -818,7 +934,24 @@ jobjectArray JVM_GetClassSigners(JNIEnv *env, jclass cls)
 
 void JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers)
 {
-       log_println("JVM_SetClassSigners: IMPLEMENT ME!");
+       classinfo                 *c;
+       java_handle_objectarray_t *hoa;
+
+       TRACEJVMCALLS("JVM_SetClassSigners(env=%p, cls=%p, signers=%p)", env, cls, signers);
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       hoa = (java_handle_objectarray_t *) signers;
+
+    /* This call is ignored for primitive types and arrays.  Signers
+          are only set once, ClassLoader.java, and thus shouldn't be
+          called with an array.  Only the bootstrap loader creates
+          arrays. */
+
+       if (class_is_primitive(c) || class_is_array(c))
+               return;
+
+       LLNI_classinfo_field_set(c, signers, hoa);
 }
 
 
@@ -828,9 +961,7 @@ jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-#if PRINTJVM || 1
-       log_println("JVM_GetProtectionDomain: cls=%p");
-#endif
+       TRACEJVMCALLS("JVM_GetProtectionDomain(env=%p, cls=%p)", env, cls);
 
        c = LLNI_classinfo_unwrap(cls);
 
@@ -844,7 +975,7 @@ jobject JVM_GetProtectionDomain(JNIEnv *env, jclass cls)
        if (class_is_primitive(c))
                return NULL;
 
-       return NULL;
+       return (jobject) c->protectiondomain;
 }
 
 
@@ -866,9 +997,7 @@ jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject contex
        java_handle_t *result;
        java_handle_t *e;
 
-#if PRINTJVM
-       log_println("JVM_DoPrivileged: action=%p, context=%p, wrapException=%d", action, context, wrapException);
-#endif
+       TRACEJVMCALLS("JVM_DoPrivileged(env=%p, cls=%p, action=%p, context=%p, wrapException=%d)", env, cls, action, context, wrapException);
 
        o = (java_handle_t *) action;
        c = o->vftbl->class;
@@ -909,6 +1038,8 @@ jobject JVM_DoPrivileged(JNIEnv *env, jclass cls, jobject action, jobject contex
 jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetInheritedAccessControlContext: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -916,7 +1047,13 @@ jobject JVM_GetInheritedAccessControlContext(JNIEnv *env, jclass cls)
 
 jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
 {
-       log_println("JVM_GetStackAccessControlContext: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_GetStackAccessControlContext(env=%p, cls=%p): IMPLEMENT ME!", env, cls);
+
+       /* XXX All stuff I tested so far works without that function.  At
+          some point we have to implement it, but I disable the output
+          for now to make IcedTea happy. */
+
+       return NULL;
 }
 
 
@@ -924,10 +1061,13 @@ jobject JVM_GetStackAccessControlContext(JNIEnv *env, jclass cls)
 
 jboolean JVM_IsArrayClass(JNIEnv *env, jclass cls)
 {
-#if PRINTJVM
-       log_println("JVM_IsArrayClass: cls=%p", cls);
-#endif
-       return class_is_array(LLNI_classinfo_unwrap(cls));
+       classinfo *c;
+
+       TRACEJVMCALLS("JVM_IsArrayClass(env=%p, cls=%p)", env, cls);
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       return class_is_array(c);
 }
 
 
@@ -937,11 +1077,9 @@ jboolean JVM_IsPrimitiveClass(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-       c = LLNI_classinfo_unwrap(cls);
+       TRACEJVMCALLS("JVM_IsPrimitiveClass(env=%p, cls=%p)", env, cls);
 
-#if PRINTJVM
-       log_println("JVM_IsPrimitiveClass(cls=%p)", cls);
-#endif
+       c = LLNI_classinfo_unwrap(cls);
 
        return class_is_primitive(c);
 }
@@ -960,7 +1098,7 @@ jclass JVM_GetComponentType(JNIEnv *env, jclass cls)
        
        component = class_get_componenttype(c);
 
-       return LLNI_classinfo_wrap(component);
+       return (jclass) LLNI_classinfo_wrap(component);
 }
 
 
@@ -969,16 +1107,15 @@ jclass JVM_GetComponentType(JNIEnv *env, jclass cls)
 jint JVM_GetClassModifiers(JNIEnv *env, jclass cls)
 {
        classinfo *c;
+       int32_t    flags;
 
-#if PRINTJVM
-       log_println("JVM_GetClassModifiers: cls=%p", cls);
-#endif
+       TRACEJVMCALLS("JVM_GetClassModifiers(env=%p, cls=%p)", env, cls);
 
        c = LLNI_classinfo_unwrap(cls);
 
-       /* XXX is this correct? */
+       flags = class_get_modifiers(c, false);
 
-       return c->flags & ACC_CLASS_REFLECT_MASK;
+       return flags;
 }
 
 
@@ -1003,16 +1140,16 @@ jobjectArray JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass)
 
 jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)
 {
-       classinfo *c = LLNI_classinfo_unwrap(ofClass);
+       classinfo *c;
+       classinfo *dc;
 
-       TRACEJVMCALLS("JVM_GetDeclaringClass: ofClass=%p", ofClass);
+       TRACEJVMCALLS("JVM_GetDeclaringClass(env=%p, ofClass=%p)", env, ofClass);
 
-       if(c == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       dc = class_get_declaringclass(c);
 
-       return LLNI_classinfo_wrap(class_get_declaringclass(c));
+       return (jclass) LLNI_classinfo_wrap(dc);
 }
 
 
@@ -1020,7 +1157,26 @@ jclass JVM_GetDeclaringClass(JNIEnv *env, jclass ofClass)
 
 jstring JVM_GetClassSignature(JNIEnv *env, jclass cls)
 {
-       log_println("JVM_GetClassSignature: IMPLEMENT ME!");
+       classinfo     *c;
+       utf           *u;
+       java_handle_t *s;
+
+       TRACEJVMCALLS("JVM_GetClassSignature(env=%p, cls=%p)", env, cls);
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       /* Get the signature of the class. */
+
+       u = class_get_signature(c);
+
+       if (u == NULL)
+               return NULL;
+
+       /* Convert UTF-string to a Java-string. */
+
+       s = javastring_new(u);
+
+       return (jstring) s;
 }
 
 
@@ -1028,9 +1184,8 @@ jstring JVM_GetClassSignature(JNIEnv *env, jclass cls)
 
 jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls)
 {
-#if defined(ENABLE_ANNOTATIONS)
-       classinfo *c = LLNI_classinfo_unwrap(cls);
-       java_handle_bytearray_t *annotations = NULL;
+       classinfo               *c           = NULL; /* classinfo for 'cls'  */
+       java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
 
        TRACEJVMCALLS("JVM_GetClassAnnotations: cls=%p", cls);
 
@@ -1038,29 +1193,13 @@ jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls)
                exceptions_throw_nullpointerexception();
                return NULL;
        }
+       
+       c = LLNI_classinfo_unwrap(cls);
 
-       /* Return null for arrays and primitives: */
-       if(class_is_primitive(c) || class_is_array(c))
-       {
-               return NULL;
-       }
-
-       if(c->annotations != NULL)
-       {
-               uint32_t size = c->annotations->size;
-               annotations = builtin_newarray_byte(size);
-
-               if(annotations != NULL)
-               {
-                       MCOPY(annotations->data, c->annotations->data, uint8_t, size);
-               }
-       }
+       /* get annotations: */
+       annotations = class_get_annotations(c);
 
        return (jbyteArray)annotations;
-#else
-       log_println("JVM_GetClassAnnotations: cls=%p, not implemented in this configuration!", cls);
-       return NULL;
-#endif
 }
 
 
@@ -1068,8 +1207,8 @@ jbyteArray JVM_GetClassAnnotations(JNIEnv *env, jclass cls)
 
 jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field)
 {
-       java_lang_reflect_Field *rf = (java_lang_reflect_Field*)field;
-       java_handle_bytearray_t *ba = NULL;
+       java_lang_reflect_Field *rf = NULL; /* java.lang.reflect.Field for 'field' */
+       java_handle_bytearray_t *ba = NULL; /* unparsed annotations */
 
        TRACEJVMCALLS("JVM_GetFieldAnnotations: field=%p", field);
 
@@ -1078,6 +1217,8 @@ jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field)
                return NULL;
        }
 
+       rf = (java_lang_reflect_Field*)field;
+
        LLNI_field_get_ref(rf, annotations, ba);
 
        return (jbyteArray)ba;
@@ -1088,8 +1229,8 @@ jbyteArray JVM_GetFieldAnnotations(JNIEnv *env, jobject field)
 
 jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method)
 {
-       java_lang_reflect_Method *rm = (java_lang_reflect_Method*)method;
-       java_handle_bytearray_t  *ba = NULL;
+       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
+       java_handle_bytearray_t  *ba = NULL; /* unparsed annotations */
 
        TRACEJVMCALLS("JVM_GetMethodAnnotations: method=%p", method);
 
@@ -1098,6 +1239,8 @@ jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method)
                return NULL;
        }
 
+       rm = (java_lang_reflect_Method*)method;
+
        LLNI_field_get_ref(rm, annotations, ba);
 
        return (jbyteArray)ba;
@@ -1108,8 +1251,8 @@ jbyteArray JVM_GetMethodAnnotations(JNIEnv *env, jobject method)
 
 jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)
 {
-       java_lang_reflect_Method *rm = (java_lang_reflect_Method*)method;
-       java_handle_bytearray_t  *ba = NULL;
+       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
+       java_handle_bytearray_t  *ba = NULL; /* unparsed annotation default value */
 
        TRACEJVMCALLS("JVM_GetMethodDefaultAnnotationValue: method=%p", method);
 
@@ -1118,6 +1261,8 @@ jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)
                return NULL;
        }
 
+       rm = (java_lang_reflect_Method*)method;
+
        LLNI_field_get_ref(rm, annotationDefault, ba);
 
        return (jbyteArray)ba;
@@ -1128,8 +1273,8 @@ jbyteArray JVM_GetMethodDefaultAnnotationValue(JNIEnv *env, jobject method)
 
 jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
 {
-       java_lang_reflect_Method *rm = (java_lang_reflect_Method*)method;
-       java_handle_bytearray_t  *ba = NULL;
+       java_lang_reflect_Method *rm = NULL; /* java.lang.reflect.Method for 'method' */
+       java_handle_bytearray_t  *ba = NULL; /* unparsed parameter annotations */
 
        TRACEJVMCALLS("JVM_GetMethodParameterAnnotations: method=%p", method);
 
@@ -1138,6 +1283,8 @@ jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
                return NULL;
        }
 
+       rm = (java_lang_reflect_Method*)method;
+
        LLNI_field_get_ref(rm, parameterAnnotations, ba);
 
        return (jbyteArray)ba;
@@ -1148,9 +1295,8 @@ jbyteArray JVM_GetMethodParameterAnnotations(JNIEnv *env, jobject method)
 
 jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredFields: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
+       TRACEJVMCALLS("JVM_GetClassDeclaredFields(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly);
+
        return (jobjectArray) _Jv_java_lang_Class_getDeclaredFields((java_lang_Class *) ofClass, publicOnly);
 }
 
@@ -1159,9 +1305,8 @@ jobjectArray JVM_GetClassDeclaredFields(JNIEnv *env, jclass ofClass, jboolean pu
 
 jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredMethods: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
+       TRACEJVMCALLS("JVM_GetClassDeclaredMethods(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly);
+
        return (jobjectArray) _Jv_java_lang_Class_getDeclaredMethods((java_lang_Class *) ofClass, publicOnly);
 }
 
@@ -1170,9 +1315,8 @@ jobjectArray JVM_GetClassDeclaredMethods(JNIEnv *env, jclass ofClass, jboolean p
 
 jobjectArray JVM_GetClassDeclaredConstructors(JNIEnv *env, jclass ofClass, jboolean publicOnly)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassDeclaredConstructors: ofClass=%p, publicOnly=%d", ofClass, publicOnly);
-#endif
+       TRACEJVMCALLS("JVM_GetClassDeclaredConstructors(env=%p, ofClass=%p, publicOnly=%d)", env, ofClass, publicOnly);
+
        return (jobjectArray) _Jv_java_lang_Class_getDeclaredConstructors((java_lang_Class *) ofClass, publicOnly);
 }
 
@@ -1183,12 +1327,12 @@ jint JVM_GetClassAccessFlags(JNIEnv *env, jclass cls)
 {
        classinfo *c;
 
-#if PRINTJVM
-       log_println("JVM_GetClassAccessFlags: cls=%p", cls);
-#endif
+       TRACEJVMCALLS("JVM_GetClassAccessFlags(env=%p, cls=%p)", env, cls);
 
        c = LLNI_classinfo_unwrap(cls);
 
+       /* Primitive type classes have the correct access flags. */
+
        return c->flags & ACC_CLASS_REFLECT_MASK;
 }
 
@@ -1199,11 +1343,11 @@ jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls)
 {
 #if defined(ENABLE_ANNOTATIONS)
        sun_reflect_ConstantPool *constantPool    = NULL;
+                     /* constant pool object for the class refered by 'cls' */
        java_lang_Object         *constantPoolOop = (java_lang_Object*)cls;
-       
-       TRACEJVMCALLS("JVM_GetClassConstantPool: cls=%p", cls);
+                     /* constantPoolOop field of the constant pool object   */
 
-       assert(cls != NULL);
+       TRACEJVMCALLS("JVM_GetClassConstantPool(env=%p, cls=%p)", env, cls);
 
        constantPool = 
                (sun_reflect_ConstantPool*)native_new_and_init(
@@ -1218,7 +1362,7 @@ jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls)
 
        return (jobject)constantPool;
 #else
-       log_println("JVM_GetClassConstantPool: cls=%p, not implemented in this configuration!", cls);
+       log_println("JVM_GetClassConstantPool(env=%p, cls=%p): not implemented in this configuration!", env, cls);
        return NULL;
 #endif
 }
@@ -1228,9 +1372,13 @@ jobject JVM_GetClassConstantPool(JNIEnv *env, jclass cls)
 
 jint JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool)
 {
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-       TRACEJVMCALLS("JVM_ConstantPoolGetSize: jcpool=%p", jcpool);
-       return cls->cpcount;
+       classinfo *c; /* classinfo of the class for which 'this' is the constant pool */
+
+       TRACEJVMCALLS("JVM_ConstantPoolGetSize(env=%p, unused=%p, jcpool=%p)", env, unused, jcpool);
+
+       c = LLNI_classinfo_unwrap(jcpool);
+
+       return c->cpcount;
 }
 
 
@@ -1238,18 +1386,24 @@ jint JVM_ConstantPoolGetSize(JNIEnv *env, jobject unused, jobject jcpool)
 
 jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_classref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
-       
-       TRACEJVMCALLS("JVM_ConstantPoolGetClassAt: jcpool=%p, index=%d", jcpool, index);
+       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
+       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
+       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
+
+       TRACEJVMCALLS("JVM_ConstantPoolGetClassAt(env=%p, jcpool=%p, index=%d)", env, jcpool, index);
 
-       ref = (constant_classref*)class_getconstant(cls, index, CONSTANT_Class);
+       c = LLNI_classinfo_unwrap(jcpool);
+
+       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
-       return LLNI_classinfo_wrap(resolve_classref_eager(ref));
+       result = resolve_classref_eager(ref);
+
+       return (jclass) LLNI_classinfo_wrap(result);
 }
 
 
@@ -1257,27 +1411,30 @@ jclass JVM_ConstantPoolGetClassAt(JNIEnv *env, jobject unused, jobject jcpool, j
 
 jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_classref *ref;
-       classinfo *c = NULL;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_classref *ref;    /* classref to the class at constant pool index 'index' */
+       classinfo         *c;      /* classinfo of the class for which 'this' is the constant pool */
+       classinfo         *result; /* classinfo of the class at constant pool index 'index' */
+
+       TRACEJVMCALLS("JVM_ConstantPoolGetClassAtIfLoaded(env=%p, unused=%p, jcpool=%p, index=%d)", env, unused, jcpool, index);
 
-       TRACEJVMCALLS("JVM_ConstantPoolGetClassAtIfLoaded: jcpool=%p, index=%d", jcpool, index);
+       c = LLNI_classinfo_unwrap(jcpool);
 
-       ref = (constant_classref*)class_getconstant(cls, index, CONSTANT_Class);
+       ref = (constant_classref *) class_getconstant(c, index, CONSTANT_Class);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
        
-       if (!resolve_classref(NULL, ref, resolveLazy, true, true, &c)) {
+       if (!resolve_classref(NULL, ref, resolveLazy, true, true, &result)) {
                return NULL;
        }
 
-       if (c == NULL || !(c->state & CLASS_LOADED)) {
+       if ((result == NULL) || !(result->state & CLASS_LOADED)) {
                return NULL;
        }
        
-       return LLNI_classinfo_wrap(c);
+       return (jclass) LLNI_classinfo_wrap(result);
 }
 
 
@@ -1285,14 +1442,16 @@ jclass JVM_ConstantPoolGetClassAtIfLoaded(JNIEnv *env, jobject unused, jobject j
 
 jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_FMIref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
        
        TRACEJVMCALLS("JVM_ConstantPoolGetMethodAt: jcpool=%p, index=%d", jcpool, index);
-
+       
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
        
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1305,15 +1464,17 @@ jobject JVM_ConstantPoolGetMethodAt(JNIEnv *env, jobject unused, jobject jcpool,
 
 jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_FMIref *ref;
-       classinfo *c = NULL;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_FMIref *ref; /* reference to the method in constant pool at index 'index' */
+       classinfo *c = NULL;  /* resolved declaring class of the method */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetMethodAtIfLoaded: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Methodref);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1333,14 +1494,16 @@ jobject JVM_ConstantPoolGetMethodAtIfLoaded(JNIEnv *env, jobject unused, jobject
 
 jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_FMIref *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
        
        TRACEJVMCALLS("JVM_ConstantPoolGetFieldAt: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1352,15 +1515,17 @@ jobject JVM_ConstantPoolGetFieldAt(JNIEnv *env, jobject unused, jobject jcpool,
 
 jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_FMIref *ref;
-       classinfo *c;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_FMIref *ref; /* reference to the field in constant pool at index 'index' */
+       classinfo *c;         /* resolved declaring class for the field */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetFieldAtIfLoaded: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_FMIref*)class_getconstant(cls, index, CONSTANT_Fieldref);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1381,6 +1546,9 @@ jobject JVM_ConstantPoolGetFieldAtIfLoaded(JNIEnv *env, jobject unused, jobject
 jobjectArray JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
        log_println("JVM_ConstantPoolGetMemberRefInfoAt: jcpool=%p, index=%d, IMPLEMENT ME!", jcpool, index);
+
+       /* TODO: implement. (this is yet unused be OpenJDK but, so very low priority) */
+
        return NULL;
 }
 
@@ -1389,14 +1557,16 @@ jobjectArray JVM_ConstantPoolGetMemberRefInfoAt(JNIEnv *env, jobject unused, job
 
 jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_integer *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_integer *ref; /* reference to the int value in constant pool at index 'index' */
+       classinfo *cls;        /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetIntAt: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_integer*)class_getconstant(cls, index, CONSTANT_Integer);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return 0;
        }
 
@@ -1408,14 +1578,16 @@ jint JVM_ConstantPoolGetIntAt(JNIEnv *env, jobject unused, jobject jcpool, jint
 
 jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_long *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_long *ref; /* reference to the long value in constant pool at index 'index' */
+       classinfo *cls;     /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetLongAt: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_long*)class_getconstant(cls, index, CONSTANT_Long);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return 0;
        }
 
@@ -1427,14 +1599,16 @@ jlong JVM_ConstantPoolGetLongAt(JNIEnv *env, jobject unused, jobject jcpool, jin
 
 jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_float *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_float *ref; /* reference to the float value in constant pool at index 'index' */
+       classinfo *cls;      /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetFloatAt: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_float*)class_getconstant(cls, index, CONSTANT_Float);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return 0;
        }
 
@@ -1446,14 +1620,16 @@ jfloat JVM_ConstantPoolGetFloatAt(JNIEnv *env, jobject unused, jobject jcpool, j
 
 jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       constant_double *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       constant_double *ref; /* reference to the double value in constant pool at index 'index' */
+       classinfo *cls;       /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetDoubleAt: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (constant_double*)class_getconstant(cls, index, CONSTANT_Double);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return 0;
        }
 
@@ -1465,14 +1641,16 @@ jdouble JVM_ConstantPoolGetDoubleAt(JNIEnv *env, jobject unused, jobject jcpool,
 
 jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       utf *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       utf *ref;       /* utf object for the string in constant pool at index 'index' */
+       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetStringAt: jcpool=%p, index=%d", jcpool, index);
        
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (utf*)class_getconstant(cls, index, CONSTANT_String);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1485,14 +1663,16 @@ jstring JVM_ConstantPoolGetStringAt(JNIEnv *env, jobject unused, jobject jcpool,
 
 jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, jint index)
 {
-       utf *ref;
-       classinfo *cls = LLNI_classinfo_unwrap(jcpool);
+       utf *ref; /* utf object for the utf8 data in constant pool at index 'index' */
+       classinfo *cls; /* classinfo of the class for which 'this' is the constant pool */
 
        TRACEJVMCALLS("JVM_ConstantPoolGetUTF8At: jcpool=%p, index=%d", jcpool, index);
 
+       cls = LLNI_classinfo_unwrap(jcpool);
        ref = (utf*)class_getconstant(cls, index, CONSTANT_Utf8);
 
        if (ref == NULL) {
+               exceptions_throw_illegalargumentexception();
                return NULL;
        }
 
@@ -1505,9 +1685,42 @@ jstring JVM_ConstantPoolGetUTF8At(JNIEnv *env, jobject unused, jobject jcpool, j
 
 jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
 {
-       log_println("JVM_DesiredAssertionStatus: cls=%p, IMPLEMENT ME!", cls);
+#if defined(ENABLE_ASSERTION)
+       assertion_name_t  *item;
+       classinfo         *c;
+       jboolean           status;
+       utf               *name;
 
-       return false;
+       TRACEJVMCALLS("JVM_DesiredAssertionStatus(env=%p, unused=%p, cls=%p)", env, unused, cls);
+
+       c = LLNI_classinfo_unwrap(cls);
+
+       if (c->classloader == NULL) {
+               status = (jboolean)assertion_system_enabled;
+       }
+       else {
+               status = (jboolean)assertion_user_enabled;
+       }
+
+       if (list_assertion_names != NULL) {
+               item = (assertion_name_t *)list_first(list_assertion_names);
+               while (item != NULL) {
+                       name = utf_new_char(item->name);
+                       if (name == c->packagename) {
+                               status = (jboolean)item->enabled;
+                       }
+                       else if (name == c->name) {
+                               status = (jboolean)item->enabled;
+                       }
+
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+               }
+       }
+
+       return status;
+#else
+       return (jboolean)false;
+#endif
 }
 
 
@@ -1515,15 +1728,19 @@ jboolean JVM_DesiredAssertionStatus(JNIEnv *env, jclass unused, jclass cls)
 
 jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
 {
-       classinfo                           *c;
-       java_lang_AssertionStatusDirectives *o;
-       java_handle_objectarray_t           *classes;
-       java_handle_objectarray_t           *packages;
-
-#if PRINTJVM || 1
-       log_println("JVM_AssertionStatusDirectives");
+       classinfo                             *c;
+       java_lang_AssertionStatusDirectives   *o;
+       java_handle_objectarray_t             *classes;
+       java_handle_objectarray_t             *packages;
+       java_booleanarray_t                   *classEnabled;
+       java_booleanarray_t                   *packageEnabled;
+#if defined(ENABLE_ASSERTION)
+       assertion_name_t                      *item;
+       java_handle_t                         *js;
+       s4                                     i, j;
 #endif
-       /* XXX this is not completely implemented */
+
+       TRACEJVMCALLS("JVM_AssertionStatusDirectives(env=%p, unused=%p)", env, unused);
 
        c = load_class_bootstrap(utf_new_char("java/lang/AssertionStatusDirectives"));
 
@@ -1535,30 +1752,86 @@ jobject JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused)
        if (o == NULL)
                return NULL;
 
+#if defined(ENABLE_ASSERTION)
+       classes = builtin_anewarray(assertion_class_count, class_java_lang_Object);
+#else
        classes = builtin_anewarray(0, class_java_lang_Object);
-
+#endif
        if (classes == NULL)
                return NULL;
 
+#if defined(ENABLE_ASSERTION)
+       packages = builtin_anewarray(assertion_package_count, class_java_lang_Object);
+#else
        packages = builtin_anewarray(0, class_java_lang_Object);
-
+#endif
        if (packages == NULL)
                return NULL;
+       
+#if defined(ENABLE_ASSERTION)
+       classEnabled = builtin_newarray_boolean(assertion_class_count);
+#else
+       classEnabled = builtin_newarray_boolean(0);
+#endif
+       if (classEnabled == NULL)
+               return NULL;
 
-       /* set instance fields */
-
-       o->classes  = classes;
-       o->packages = packages;
+#if defined(ENABLE_ASSERTION)
+       packageEnabled = builtin_newarray_boolean(assertion_package_count);
+#else
+       packageEnabled = builtin_newarray_boolean(0);
+#endif
+       if (packageEnabled == NULL)
+               return NULL;
 
-       return (jobject) o;
+#if defined(ENABLE_ASSERTION)
+       /* initialize arrays */
+
+       if (list_assertion_names != NULL) {
+               i = 0;
+               j = 0;
+               
+               item = (assertion_name_t *)list_first(list_assertion_names);
+               while (item != NULL) {
+                       js = javastring_new_from_ascii(item->name);
+                       if (js == NULL) {
+                               return NULL;
+                       }
+
+                       if (item->package == false) {
+                               classes->data[i] = js;
+                               classEnabled->data[i] = (jboolean) item->enabled;
+                               i += 1;
+                       }
+                       else {
+                               packages->data[j] = js;
+                               packageEnabled->data[j] = (jboolean) item->enabled;
+                               j += 1;
+                       }
+
+                       item = (assertion_name_t *)list_next(list_assertion_names, item);
+               }
+       }
+#endif
+
+       /* set instance fields */
+
+       o->classes  = classes;
+       o->packages = packages;
+       o->classEnabled = classEnabled;
+       o->packageEnabled = packageEnabled;
+
+       return (jobject) o;
 }
 
 
 /* JVM_GetClassNameUTF */
 
-const charJVM_GetClassNameUTF(JNIEnv *env, jclass cls)
+const char *JVM_GetClassNameUTF(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -1575,6 +1848,8 @@ void JVM_GetClassCPTypes(JNIEnv *env, jclass cls, unsigned char *types)
 jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassCPEntriesCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1583,6 +1858,8 @@ jint JVM_GetClassCPEntriesCount(JNIEnv *env, jclass cls)
 jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassFieldsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1591,6 +1868,8 @@ jint JVM_GetClassFieldsCount(JNIEnv *env, jclass cls)
 jint JVM_GetClassMethodsCount(JNIEnv *env, jclass cls)
 {
        log_println("JVM_GetClassMethodsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1607,6 +1886,8 @@ void JVM_GetMethodIxExceptionIndexes(JNIEnv *env, jclass cls, jint method_index,
 jint JVM_GetMethodIxExceptionsCount(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxExceptionsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1623,6 +1904,8 @@ void JVM_GetMethodIxByteCode(JNIEnv *env, jclass cls, jint method_index, unsigne
 jint JVM_GetMethodIxByteCodeLength(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxByteCodeLength: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1639,6 +1922,8 @@ void JVM_GetMethodIxExceptionTableEntry(JNIEnv *env, jclass cls, jint method_ind
 jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxExceptionTableLength: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1647,6 +1932,8 @@ jint JVM_GetMethodIxExceptionTableLength(JNIEnv *env, jclass cls, int method_ind
 jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1655,6 +1942,8 @@ jint JVM_GetMethodIxModifiers(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
 {
        log_println("JVM_GetFieldIxModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1663,6 +1952,8 @@ jint JVM_GetFieldIxModifiers(JNIEnv *env, jclass cls, int field_index)
 jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxLocalsCount: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1671,6 +1962,8 @@ jint JVM_GetMethodIxLocalsCount(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxArgsSize: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1679,6 +1972,8 @@ jint JVM_GetMethodIxArgsSize(JNIEnv *env, jclass cls, int method_index)
 jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_GetMethodIxMaxStack: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1687,78 +1982,98 @@ jint JVM_GetMethodIxMaxStack(JNIEnv *env, jclass cls, int method_index)
 jboolean JVM_IsConstructorIx(JNIEnv *env, jclass cls, int method_index)
 {
        log_println("JVM_IsConstructorIx: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
 /* JVM_GetMethodIxNameUTF */
 
-const charJVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
+const char *JVM_GetMethodIxNameUTF(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetMethodIxSignatureUTF */
 
-const charJVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
+const char *JVM_GetMethodIxSignatureUTF(JNIEnv *env, jclass cls, jint method_index)
 {
        log_println("JVM_GetMethodIxSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldNameUTF */
 
-const charJVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodNameUTF */
 
-const charJVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodSignatureUTF */
 
-const charJVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldSignatureUTF */
 
-const charJVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldSignatureUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldSignatureUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPClassNameUTF */
 
-const charJVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPFieldClassNameUTF */
 
-const charJVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPFieldClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPFieldClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetCPMethodClassNameUTF */
 
-const charJVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
+const char *JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 {
        log_println("JVM_GetCPMethodClassNameUTF: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -1767,6 +2082,8 @@ const char* JVM_GetCPMethodClassNameUTF(JNIEnv *env, jclass cls, jint cp_index)
 jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
 {
        log_println("JVM_GetCPFieldModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1775,6 +2092,8 @@ jint JVM_GetCPFieldModifiers(JNIEnv *env, jclass cls, int cp_index, jclass calle
 jint JVM_GetCPMethodModifiers(JNIEnv *env, jclass cls, int cp_index, jclass called_cls)
 {
        log_println("JVM_GetCPMethodModifiers: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -1791,30 +2110,35 @@ void JVM_ReleaseUTF(const char *utf)
 jboolean JVM_IsSameClassPackage(JNIEnv *env, jclass class1, jclass class2)
 {
        log_println("JVM_IsSameClassPackage: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
 /* JVM_Open */
 
+/* Taken from: hotspot/src/share/vm/prims/jvm.h */
+
+/*
+ * JVM I/O error codes
+ */
+#define JVM_EEXIST       -100
+
 jint JVM_Open(const char *fname, jint flags, jint mode)
 {
        int result;
 
-#if PRINTJVM
-       log_println("JVM_Open: fname=%s, flags=%d, mode=%d", fname, flags, mode);
-#endif
+       TRACEJVMCALLS("JVM_Open(fname=%s, flags=%d, mode=%d)", fname, flags, mode);
 
-       result = open(fname, flags, mode);
+       result = system_open(fname, flags, mode);
 
        if (result >= 0) {
                return result;
        }
        else {
-               switch(errno) {
+               switch (errno) {
                case EEXIST:
-                       /* XXX don't know what to do here */
-/*                     return JVM_EEXIST; */
-                       return -1;
+                       return JVM_EEXIST;
                default:
                        return -1;
                }
@@ -1826,10 +2150,9 @@ jint JVM_Open(const char *fname, jint flags, jint mode)
 
 jint JVM_Close(jint fd)
 {
-#if PRINTJVM
-       log_println("JVM_Close: fd=%d", fd);
-#endif
-       return close(fd);
+       TRACEJVMCALLS("JVM_Close(fd=%d)", fd);
+
+       return system_close(fd);
 }
 
 
@@ -1837,10 +2160,9 @@ jint JVM_Close(jint fd)
 
 jint JVM_Read(jint fd, char *buf, jint nbytes)
 {
-#if PRINTJVM
-       log_println("JVM_Read: fd=%d, buf=%p, nbytes=%d", fd, buf, nbytes);
-#endif
-       return read(fd, buf, nbytes);
+       TRACEJVMCALLS("JVM_Read(fd=%d, buf=%p, nbytes=%d)", fd, buf, nbytes);
+
+       return system_read(fd, buf, nbytes);
 }
 
 
@@ -1848,10 +2170,9 @@ jint JVM_Read(jint fd, char *buf, jint nbytes)
 
 jint JVM_Write(jint fd, char *buf, jint nbytes)
 {
-#if PRINTJVM
-       log_println("JVM_Write: fd=%d, buf=%s, nbytes=%d", fd, buf, nbytes);
-#endif
-       return write(fd, buf, nbytes);
+       TRACEJVMCALLS("JVM_Write(fd=%d, buf=%s, nbytes=%d)", fd, buf, nbytes);
+
+       return system_write(fd, buf, nbytes);
 }
 
 
@@ -1859,69 +2180,24 @@ jint JVM_Write(jint fd, char *buf, jint nbytes)
 
 jint JVM_Available(jint fd, jlong *pbytes)
 {
-       TRACEJVMCALLS("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes);
-
 #if defined(FIONREAD)
        int bytes;
-
-       if (ioctl(fd, FIONREAD, &bytes) < 0)
-               return 0;
-
-       *pbytes = bytes;
-
-       return 1;
-#elif defined(HAVE_FSTAT)
-       struct stat statBuffer;
-       off_t n;
        int result;
 
+       TRACEJVMCALLS("JVM_Available(fd=%d, pbytes=%p)", fd, pbytes);
+
        *pbytes = 0;
 
-       if ((fstat(fd, &statBuffer) == 0) && S_ISREG (statBuffer.st_mode)) {
-               n = lseek (fd, 0, SEEK_CUR);
+       result = ioctl(fd, FIONREAD, &bytes);
 
-               if (n != -1) {
-                       *pbytes = statBuffer.st_size - n; 
-                       result = 1;
-               }
-               else {
-                       result = 0;
-               }
-       }
-       else {
-               result = 0;
-       }
-  
-       return result;
-#elif defined(HAVE_SELECT)
-       fd_set filedescriptset;
-       struct timeval tv;
-       int result;
+       if (result < 0)
+               return 0;
 
-       *pbytes = 0;
-  
-       FD_ZERO(&filedescriptset);
-       FD_SET(fd, &filedescriptset);
-       memset(&tv, 0, sizeof(tv));
-
-       switch (select(fd+1, &filedescriptset, NULL, NULL, &tv))
-               {
-               case -1: 
-                       result = errno; 
-                       break;
-               case  0:
-                       *pbytes = 0;
-                       result = CPNATIVE_OK;
-                       break;      
-               default: 
-                       *pbytes = 1;
-                       result = CPNATIVE_OK;
-                       break;
-               }
-       return result;
+       *pbytes = bytes;
+
+       return 1;
 #else
-       *pbytes = 0;
-       return 0;
+# error FIONREAD not defined
 #endif
 }
 
@@ -1930,10 +2206,9 @@ jint JVM_Available(jint fd, jlong *pbytes)
 
 jlong JVM_Lseek(jint fd, jlong offset, jint whence)
 {
-#if PRINTJVM
-       log_println("JVM_Lseek: fd=%d, offset=%ld, whence=%d", fd, offset, whence);
-#endif
-       return (jlong) lseek(fd, (off_t) offset, whence);
+       TRACEJVMCALLS("JVM_Lseek(fd=%d, offset=%ld, whence=%d)", fd, offset, whence);
+
+       return (jlong) system_lseek(fd, (off_t) offset, whence);
 }
 
 
@@ -1941,7 +2216,9 @@ jlong JVM_Lseek(jint fd, jlong offset, jint whence)
 
 jint JVM_SetLength(jint fd, jlong length)
 {
-       log_println("JVM_SetLength: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_SetLength(fd=%d, length=%ld)", length);
+
+       return system_ftruncate(fd, length);
 }
 
 
@@ -1949,7 +2226,9 @@ jint JVM_SetLength(jint fd, jlong length)
 
 jint JVM_Sync(jint fd)
 {
-       log_println("JVM_Sync: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_Sync(fd=%d)", fd);
+
+       return system_fsync(fd);
 }
 
 
@@ -1957,9 +2236,8 @@ jint JVM_Sync(jint fd)
 
 void JVM_StartThread(JNIEnv* env, jobject jthread)
 {
-#if PRINTJVM
-       log_println("JVM_StartThread: jthread=%p", jthread);
-#endif
+       TRACEJVMCALLS("JVM_StartThread(env=%p, jthread=%p)", env, jthread);
+
        _Jv_java_lang_Thread_start((java_lang_Thread *) jthread, 0);
 }
 
@@ -1976,10 +2254,30 @@ void JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable)
 
 jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
 {
-#if PRINTJVM
-       log_println("JVM_IsThreadAlive: jthread=%p", jthread);
-#endif
-       return _Jv_java_lang_Thread_isAlive((java_lang_Thread *) jthread);
+       threadobject *t;
+       bool          equal;
+       bool          result;
+
+       TRACEJVMCALLS("JVM_IsThreadAlive(env=%p, jthread=%p)", env, jthread);
+
+       /* XXX this is just a quick hack */
+
+       for (t = threads_list_first(); t != NULL; t = threads_list_next(t)) {
+               LLNI_equals(t->object, jthread, equal);
+
+               if (equal == true)
+                       break;
+       }
+
+       /* The threadobject is null when a thread is created in Java. The
+          priority is set later during startup. */
+
+       if (t == NULL)
+               return 0;
+
+       result = threads_thread_is_alive(t);
+
+       return result;
 }
 
 
@@ -2003,9 +2301,8 @@ void JVM_ResumeThread(JNIEnv* env, jobject jthread)
 
 void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
 {
-#if PRINTJVM
-       log_println("JVM_SetThreadPriority: jthread=%p, prio=%d", jthread, prio);
-#endif
+       TRACEJVMCALLS("JVM_SetThreadPriority(env=%p, jthread=%p, prio=%d)", env, jthread, prio);
+
        _Jv_java_lang_Thread_setPriority((java_lang_Thread *) jthread, prio);
 }
 
@@ -2014,7 +2311,9 @@ void JVM_SetThreadPriority(JNIEnv* env, jobject jthread, jint prio)
 
 void JVM_Yield(JNIEnv *env, jclass threadClass)
 {
-       log_println("JVM_Yield: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_Yield(env=%p, threadClass=%p)", env, threadClass);
+
+       threads_yield();
 }
 
 
@@ -2022,9 +2321,8 @@ void JVM_Yield(JNIEnv *env, jclass threadClass)
 
 void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
 {
-#if PRINTJVM
-       log_println("JVM_Sleep: threadClass=%p, millis=%ld", threadClass, millis);
-#endif
+       TRACEJVMCALLS("JVM_Sleep(env=%p, threadClass=%p, millis=%ld)", env, threadClass, millis);
+
        _Jv_java_lang_Thread_sleep(millis);
 }
 
@@ -2033,9 +2331,8 @@ void JVM_Sleep(JNIEnv* env, jclass threadClass, jlong millis)
 
 jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
 {
-#if PRINTJVM
-       log_println("JVM_CurrentThread: threadClass=%p", threadClass);
-#endif
+       TRACEJVMCALLSVERBOSE(("JVM_CurrentThread(env=%p, threadClass=%p)", env, threadClass));
+
        return (jobject) _Jv_java_lang_Thread_currentThread();
 }
 
@@ -2045,6 +2342,8 @@ jobject JVM_CurrentThread(JNIEnv* env, jclass threadClass)
 jint JVM_CountStackFrames(JNIEnv* env, jobject jthread)
 {
        log_println("JVM_CountStackFrames: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2060,10 +2359,10 @@ void JVM_Interrupt(JNIEnv* env, jobject jthread)
 
 jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted)
 {
-#if PRINTJVM
-       log_println("JVM_IsInterrupted: jthread=%p, clear_interrupted=%d", jthread, clear_interrupted);
-#endif
+       TRACEJVMCALLS("JVM_IsInterrupted(env=%p, jthread=%p, clear_interrupted=%d)", env, jthread, clear_interrupted);
+
        /* XXX do something with clear_interrupted */
+
        return _Jv_java_lang_Thread_isInterrupted((java_lang_Thread *) jthread);
 }
 
@@ -2072,7 +2371,21 @@ jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrup
 
 jboolean JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj)
 {
-       log_println("JVM_HoldsLock: IMPLEMENT ME!");
+       java_handle_t *h;
+       bool           result;
+
+       TRACEJVMCALLS("JVM_HoldsLock(env=%p, threadClass=%p, obj=%p)", env, threadClass, obj);
+
+       h = (java_handle_t *) obj;
+
+       if (h == NULL) {
+               exceptions_throw_nullpointerexception();
+               return JNI_FALSE;
+       }
+
+       result = lock_is_held_by_current_thread(h);
+
+       return result;
 }
 
 
@@ -2089,6 +2402,8 @@ void JVM_DumpAllStacks(JNIEnv* env, jclass unused)
 jclass JVM_CurrentLoadedClass(JNIEnv *env)
 {
        log_println("JVM_CurrentLoadedClass: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2096,7 +2411,12 @@ jclass JVM_CurrentLoadedClass(JNIEnv *env)
 
 jobject JVM_CurrentClassLoader(JNIEnv *env)
 {
+    /* XXX if a method in a class in a trusted loader is in a
+          doPrivileged, return NULL */
+
        log_println("JVM_CurrentClassLoader: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2104,9 +2424,8 @@ jobject JVM_CurrentClassLoader(JNIEnv *env)
 
 jobjectArray JVM_GetClassContext(JNIEnv *env)
 {
-#if PRINTJVM
-       log_println("JVM_GetClassContext");
-#endif
+       TRACEJVMCALLS("JVM_GetClassContext(env=%p)", env);
+
        return (jobjectArray) stacktrace_getClassContext();
 }
 
@@ -2116,6 +2435,8 @@ jobjectArray JVM_GetClassContext(JNIEnv *env)
 jint JVM_ClassDepth(JNIEnv *env, jstring name)
 {
        log_println("JVM_ClassDepth: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2124,6 +2445,8 @@ jint JVM_ClassDepth(JNIEnv *env, jstring name)
 jint JVM_ClassLoaderDepth(JNIEnv *env)
 {
        log_println("JVM_ClassLoaderDepth: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2131,7 +2454,23 @@ jint JVM_ClassLoaderDepth(JNIEnv *env)
 
 jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
 {
-       log_println("JVM_GetSystemPackage: IMPLEMENT ME!");
+       java_handle_t *s;
+       utf *u;
+       utf *result;
+
+       TRACEJVMCALLS("JVM_GetSystemPackage(env=%p, name=%p)", env, name);
+
+/*     s = package_find(name); */
+       u = javastring_toutf((java_handle_t *) name, false);
+
+       result = package_find(u);
+
+       if (result != NULL)
+               s = javastring_new(result);
+       else
+               s = NULL;
+
+       return (jstring) s;
 }
 
 
@@ -2140,6 +2479,8 @@ jstring JVM_GetSystemPackage(JNIEnv *env, jstring name)
 jobjectArray JVM_GetSystemPackages(JNIEnv *env)
 {
        log_println("JVM_GetSystemPackages: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2148,6 +2489,8 @@ jobjectArray JVM_GetSystemPackages(JNIEnv *env)
 jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, jclass initClass)
 {
        log_println("JVM_AllocateNewObject: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2156,6 +2499,8 @@ jobject JVM_AllocateNewObject(JNIEnv *env, jobject receiver, jclass currClass, j
 jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint length)
 {
        log_println("JVM_AllocateNewArray: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2163,7 +2508,13 @@ jobject JVM_AllocateNewArray(JNIEnv *env, jobject obj, jclass currClass, jint le
 
 jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 {
-       log_println("JVM_LatestUserDefinedLoader: IMPLEMENT ME!");
+       classloader *cl;
+
+       TRACEJVMCALLS("JVM_LatestUserDefinedLoader(env=%p)", env);
+
+       cl = stacktrace_first_nonnull_classloader();
+
+       return (jobject) cl;
 }
 
 
@@ -2172,6 +2523,8 @@ jobject JVM_LatestUserDefinedLoader(JNIEnv *env)
 jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring currClassName)
 {
        log_println("JVM_LoadClass0: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2179,24 +2532,13 @@ jclass JVM_LoadClass0(JNIEnv *env, jobject receiver, jclass currClass, jstring c
 
 jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 {
-       java_array_t *a;
+       java_handle_t *a;
 
        TRACEJVMCALLS("JVM_GetArrayLength(arr=%p)", arr);
 
-       a = (java_array_t *) arr;
-
-       if (a == NULL) {
-               exceptions_throw_nullpointerexception();
-               return 0;
-       }
-
-       if (!class_is_array(a->objheader.vftbl->class)) {
-/*             exceptions_throw_illegalargumentexception("Argument is not an array"); */
-               exceptions_throw_illegalargumentexception();
-               return 0;
-       }
+       a = (java_handle_t *) arr;
 
-       return a->size;
+       return array_length_get(a);
 }
 
 
@@ -2204,54 +2546,21 @@ jint JVM_GetArrayLength(JNIEnv *env, jobject arr)
 
 jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
 {
-       java_array_t *a;
-       int           elementtype;
+       java_handle_t *a;
+       java_handle_t *o;
 
        TRACEJVMCALLS("JVM_GetArrayElement(env=%p, arr=%p, index=%d)", env, arr, index);
 
-       a = (java_array_t *) arr;
+       a = (java_handle_t *) arr;
 
-       if (a == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
+/*     if (!class_is_array(a->objheader.vftbl->class)) { */
+/*             exceptions_throw_illegalargumentexception(); */
+/*             return NULL; */
+/*     } */
 
-       if (!class_is_array(a->objheader.vftbl->class)) {
-               exceptions_throw_illegalargumentexception();
-               return NULL;
-       }
-       
-       if (index < 0 || index > a->size) {
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-       
-       elementtype = a->objheader.vftbl->arraydesc->elementtype;
-
-       switch (elementtype) {
-       case ARRAYTYPE_INT:
-               return (jobject)primitive_box_int(((java_handle_intarray_t*)a)->data[index]);
-       case ARRAYTYPE_LONG:
-               return (jobject)primitive_box_long(((java_handle_longarray_t*)a)->data[index]);
-       case ARRAYTYPE_FLOAT:
-               return (jobject)primitive_box_float(((java_handle_floatarray_t*)a)->data[index]);
-       case ARRAYTYPE_DOUBLE:
-               return (jobject)primitive_box_double(((java_handle_doublearray_t*)a)->data[index]);
-       case ARRAYTYPE_BYTE:
-               return (jobject)primitive_box_byte(((java_handle_bytearray_t*)a)->data[index]);
-       case ARRAYTYPE_CHAR:
-               return (jobject)primitive_box_char(((java_handle_chararray_t*)a)->data[index]);
-       case ARRAYTYPE_SHORT:
-               return (jobject)primitive_box_short(((java_handle_shortarray_t*)a)->data[index]);
-       case ARRAYTYPE_BOOLEAN:
-               return (jobject)primitive_box_boolean(((java_handle_booleanarray_t*)a)->data[index]);
-       case ARRAYTYPE_OBJECT:
-               return (jobject)((java_handle_objectarray_t*)a)->data[index];
-       default:
-               /* invalid element type */
-               exceptions_throw_internalerror("invalid element type code in array descriptor: %d", elementtype);
-               return (jobject)NULL;
-       }
+       o = array_element_get(a, index);
+
+       return (jobject) o;
 }
 
 
@@ -2259,7 +2568,13 @@ jobject JVM_GetArrayElement(JNIEnv *env, jobject arr, jint index)
 
 jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint wCode)
 {
+       jvalue jv;
+
        log_println("JVM_GetPrimitiveArrayElement: IMPLEMENT ME!");
+
+       jv.l = NULL;
+
+       return jv;
 }
 
 
@@ -2267,7 +2582,15 @@ jvalue JVM_GetPrimitiveArrayElement(JNIEnv *env, jobject arr, jint index, jint w
 
 void JVM_SetArrayElement(JNIEnv *env, jobject arr, jint index, jobject val)
 {
-       log_println("JVM_SetArrayElement: IMPLEMENT ME!");
+       java_handle_t *a;
+       java_handle_t *value;
+
+       TRACEJVMCALLS("JVM_SetArrayElement(env=%p, arr=%p, index=%d, val=%p)", env, arr, index, val);
+
+       a     = (java_handle_t *) arr;
+       value = (java_handle_t *) val;
+
+       array_element_set(a, index, value);
 }
 
 
@@ -2290,6 +2613,13 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 
        TRACEJVMCALLS("JVM_NewArray(env=%p, eltClass=%p, length=%d)", env, eltClass, length);
 
+       if (eltClass == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* NegativeArraySizeException is checked in builtin_newarray. */
+
        c = LLNI_classinfo_unwrap(eltClass);
 
        /* create primitive or object array */
@@ -2312,7 +2642,52 @@ jobject JVM_NewArray(JNIEnv *env, jclass eltClass, jint length)
 
 jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 {
-       log_println("JVM_NewMultiArray: IMPLEMENT ME!");
+       classinfo                 *c;
+       java_handle_intarray_t    *ia;
+       int32_t                    length;
+       long                      *dims;
+       int32_t                    value;
+       int32_t                    i;
+       classinfo                 *ac;
+       java_handle_objectarray_t *a;
+
+       TRACEJVMCALLS("JVM_NewMultiArray(env=%p, eltClass=%p, dim=%p)", env, eltClass, dim);
+
+       if (eltClass == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       /* NegativeArraySizeException is checked in builtin_newarray. */
+
+       c = LLNI_classinfo_unwrap(eltClass);
+
+       /* XXX This is just a quick hack to get it working. */
+
+       ia = (java_handle_intarray_t *) dim;
+
+       length = array_length_get((java_handle_t *) ia);
+
+       dims = MNEW(long, length);
+
+       for (i = 0; i < length; i++) {
+               value = LLNI_array_direct(ia, i);
+               dims[i] = (long) value;
+       }
+
+       /* Create an array-class if necessary. */
+
+       if (class_is_primitive(c))
+               ac = primitive_arrayclass_get_by_name(c->name);
+       else
+               ac = class_array_of(c, true);
+
+       if (ac == NULL)
+               return NULL;
+
+       a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
+
+       return (jobject) a;
 }
 
 
@@ -2321,6 +2696,8 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 jint JVM_InitializeSocketLibrary()
 {
        log_println("JVM_InitializeSocketLibrary: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2328,10 +2705,9 @@ jint JVM_InitializeSocketLibrary()
 
 jint JVM_Socket(jint domain, jint type, jint protocol)
 {
-#if PRINTJVM || 1
-       log_println("JVM_Socket: domain=%d, type=%d, protocol=%d", domain, type, protocol);
-#endif
-       return socket(domain, type, protocol);
+       TRACEJVMCALLS("JVM_Socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol);
+
+       return system_socket(domain, type, protocol);
 }
 
 
@@ -2339,10 +2715,9 @@ jint JVM_Socket(jint domain, jint type, jint protocol)
 
 jint JVM_SocketClose(jint fd)
 {
-#if PRINTJVM || 1
-       log_println("JVM_SocketClose: fd=%d", fd);
-#endif
-       return close(fd);
+       TRACEJVMCALLS("JVM_SocketClose(fd=%d)", fd);
+
+       return system_close(fd);
 }
 
 
@@ -2350,10 +2725,9 @@ jint JVM_SocketClose(jint fd)
 
 jint JVM_SocketShutdown(jint fd, jint howto)
 {
-#if PRINTJVM || 1
-       log_println("JVM_SocketShutdown: fd=%d, howto=%d", fd, howto);
-#endif
-       return shutdown(fd, howto);
+       TRACEJVMCALLS("JVM_SocketShutdown(fd=%d, howto=%d)", fd, howto);
+
+       return system_shutdown(fd, howto);
 }
 
 
@@ -2362,6 +2736,8 @@ jint JVM_SocketShutdown(jint fd, jint howto)
 jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 {
        log_println("JVM_Recv: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2370,6 +2746,8 @@ jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 {
        log_println("JVM_Send: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2378,6 +2756,8 @@ jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 jint JVM_Timeout(int fd, long timeout)
 {
        log_println("JVM_Timeout: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2385,10 +2765,9 @@ jint JVM_Timeout(int fd, long timeout)
 
 jint JVM_Listen(jint fd, jint count)
 {
-#if PRINTJVM || 1
-       log_println("JVM_Listen: fd=%d, count=%d", fd, count);
-#endif
-       return listen(fd, count);
+       TRACEJVMCALLS("JVM_Listen(fd=%d, count=%d)", fd, count);
+
+       return system_listen(fd, count);
 }
 
 
@@ -2396,10 +2775,9 @@ jint JVM_Listen(jint fd, jint count)
 
 jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
 {
-#if PRINTJVM || 1
-       log_println("JVM_Connect: fd=%d, him=%p, len=%d", fd, him, len);
-#endif
-       return connect(fd, him, len);
+       TRACEJVMCALLS("JVM_Connect(fd=%d, him=%p, len=%d)", fd, him, len);
+
+       return system_connect(fd, him, len);
 }
 
 
@@ -2408,6 +2786,8 @@ jint JVM_Connect(jint fd, struct sockaddr *him, jint len)
 jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
 {
        log_println("JVM_Bind: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2415,10 +2795,9 @@ jint JVM_Bind(jint fd, struct sockaddr *him, jint len)
 
 jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
 {
-#if PRINTJVM || 1
-       log_println("JVM_Accept: fd=%d, him=%p, len=%p", fd, him, len);
-#endif
-       return accept(fd, him, (socklen_t *) len);
+       TRACEJVMCALLS("JVM_Accept(fd=%d, him=%p, len=%p)", fd, him, len);
+
+       return system_accept(fd, him, (socklen_t *) len);
 }
 
 
@@ -2427,6 +2806,8 @@ jint JVM_Accept(jint fd, struct sockaddr *him, jint *len)
 jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *from, int *fromlen)
 {
        log_println("JVM_RecvFrom: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2434,10 +2815,9 @@ jint JVM_RecvFrom(jint fd, char *buf, int nBytes, int flags, struct sockaddr *fr
 
 jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
 {
-#if PRINTJVM || 1
-       log_println("JVM_GetSockName: fd=%d, him=%p, len=%p", fd, him, len);
-#endif
-       return getsockname(fd, him, (socklen_t *) len);
+       TRACEJVMCALLS("JVM_GetSockName(fd=%d, him=%p, len=%p)", fd, him, len);
+
+       return system_getsockname(fd, him, (socklen_t *) len);
 }
 
 
@@ -2446,6 +2826,8 @@ jint JVM_GetSockName(jint fd, struct sockaddr *him, int *len)
 jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int tolen)
 {
        log_println("JVM_SendTo: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2453,7 +2835,25 @@ jint JVM_SendTo(jint fd, char *buf, int len, int flags, struct sockaddr *to, int
 
 jint JVM_SocketAvailable(jint fd, jint *pbytes)
 {
-       log_println("JVM_SocketAvailable: IMPLEMENT ME!");
+#if defined(FIONREAD)
+       int bytes;
+       int result;
+
+       TRACEJVMCALLS("JVM_SocketAvailable(fd=%d, pbytes=%p)", fd, pbytes);
+
+       *pbytes = 0;
+
+       result = ioctl(fd, FIONREAD, &bytes);
+
+       if (result < 0)
+               return 0;
+
+       *pbytes = bytes;
+
+       return 1;
+#else
+# error FIONREAD not defined
+#endif
 }
 
 
@@ -2461,7 +2861,9 @@ jint JVM_SocketAvailable(jint fd, jint *pbytes)
 
 jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
 {
-       log_println("JVM_GetSockOpt: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_GetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%p)", fd, level, optname, optval, optlen);
+
+       return system_getsockopt(fd, level, optname, optval, (socklen_t *) optlen);
 }
 
 
@@ -2469,56 +2871,63 @@ jint JVM_GetSockOpt(jint fd, int level, int optname, char *optval, int *optlen)
 
 jint JVM_SetSockOpt(jint fd, int level, int optname, const char *optval, int optlen)
 {
-#if PRINTJVM || 1
-       log_println("JVM_SetSockOpt: fd=%d, level=%d, optname=%d, optval=%s, optlen=%d", fd, level, optname, optval, optlen);
-#endif
-       return setsockopt(fd, level, optname, optval, optlen);
+       TRACEJVMCALLS("JVM_SetSockOpt(fd=%d, level=%d, optname=%d, optval=%s, optlen=%d)", fd, level, optname, optval, optlen);
+
+       return system_setsockopt(fd, level, optname, optval, optlen);
 }
 
 
 /* JVM_GetHostName */
 
-int JVM_GetHostName(charname, int namelen)
+int JVM_GetHostName(char *name, int namelen)
 {
-#if PRINTJVM || 1
-       log_println("JVM_GetHostName: name=%s, namelen=%d", name, namelen);
-#endif
-       return gethostname(name, namelen);
+       TRACEJVMCALLS("JVM_GetHostName(name=%s, namelen=%d)", name, namelen);
+
+       return system_gethostname(name, namelen);
 }
 
 
 /* JVM_GetHostByAddr */
 
-struct hostentJVM_GetHostByAddr(const char* name, int len, int type)
+struct hostent *JVM_GetHostByAddr(const char* name, int len, int type)
 {
        log_println("JVM_GetHostByAddr: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetHostByName */
 
-struct hostentJVM_GetHostByName(char* name)
+struct hostent *JVM_GetHostByName(char* name)
 {
        log_println("JVM_GetHostByName: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetProtoByName */
 
-struct protoentJVM_GetProtoByName(char* name)
+struct protoent *JVM_GetProtoByName(char* name)
 {
        log_println("JVM_GetProtoByName: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_LoadLibrary */
 
-void* JVM_LoadLibrary(const char* name)
+void *JVM_LoadLibrary(const char *name)
 {
-#if PRINTJVM
-       log_println("JVM_LoadLibrary: name=%s", name);
-#endif
-    return native_library_open(utf_new_char(name));
+       utf *u;
+
+       TRACEJVMCALLS("JVM_LoadLibrary(name=%s)", name);
+
+       u = utf_new_char(name);
+
+       return native_library_open(u);
 }
 
 
@@ -2526,19 +2935,19 @@ void* JVM_LoadLibrary(const char* name)
 
 void JVM_UnloadLibrary(void* handle)
 {
-       log_println("JVM_UnloadLibrary: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_UnloadLibrary(handle=%p)", handle);
+
+       native_library_close(handle);
 }
 
 
 /* JVM_FindLibraryEntry */
 
-void* JVM_FindLibraryEntry(void* handle, const char* name)
+void *JVM_FindLibraryEntry(void *handle, const char *name)
 {
        lt_ptr symbol;
 
-#if PRINTJVM
-       log_println("JVM_FindLibraryEntry: handle=%p, name=%s", handle, name);
-#endif
+       TRACEJVMCALLS("JVM_FindLibraryEntry(handle=%p, name=%s)", handle, name);
 
        symbol = lt_dlsym(handle, name);
 
@@ -2551,6 +2960,8 @@ void* JVM_FindLibraryEntry(void* handle, const char* name)
 jboolean JVM_IsNaN(jdouble a)
 {
        log_println("JVM_IsNaN: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2558,17 +2969,9 @@ jboolean JVM_IsNaN(jdouble a)
 
 jboolean JVM_IsSupportedJNIVersion(jint version)
 {
-#if PRINTJVM
-       log_println("JVM_IsSupportedJNIVersion: version=%d", version);
-#endif
-       switch (version) {
-       case JNI_VERSION_1_1:
-       case JNI_VERSION_1_2:
-       case JNI_VERSION_1_4:
-               return true;
-       default:
-               return false;
-       }
+       TRACEJVMCALLS("JVM_IsSupportedJNIVersion(version=%d)", version);
+
+       return jni_version_check(version);
 }
 
 
@@ -2576,10 +2979,9 @@ jboolean JVM_IsSupportedJNIVersion(jint version)
 
 jstring JVM_InternString(JNIEnv *env, jstring str)
 {
-#if PRINTJVM
-       log_println("JVM_InternString: str=%p", str);
-#endif
-       return (jstring) _Jv_java_lang_String_intern((java_lang_String *) str);
+       TRACEJVMCALLS("JVM_InternString(env=%p, str=%p)", env, str);
+
+       return (jstring) javastring_intern((java_handle_t *) str);
 }
 
 
@@ -2589,9 +2991,7 @@ JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
 {
        java_object_t *o;
 
-#if PRINTJVM
-       log_println("JVM_RawMonitorCreate");
-#endif
+       TRACEJVMCALLS("JVM_RawMonitorCreate()");
 
        o = NEW(java_object_t);
 
@@ -2605,9 +3005,8 @@ JNIEXPORT void* JNICALL JVM_RawMonitorCreate(void)
 
 JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorDestroy: mon=%p", mon);
-#endif
+       TRACEJVMCALLS("JVM_RawMonitorDestroy(mon=%p)", mon);
+
        FREE(mon, java_object_t);
 }
 
@@ -2616,9 +3015,8 @@ JNIEXPORT void JNICALL JVM_RawMonitorDestroy(void *mon)
 
 JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorEnter: mon=%p", mon);
-#endif
+       TRACEJVMCALLS("JVM_RawMonitorEnter(mon=%p)", mon);
+
        (void) lock_monitor_enter((java_object_t *) mon);
 
        return 0;
@@ -2629,9 +3027,8 @@ JNIEXPORT jint JNICALL JVM_RawMonitorEnter(void *mon)
 
 JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon)
 {
-#if PRINTJVM
-       log_println("JVM_RawMonitorExit: mon=%p", mon);
-#endif
+       TRACEJVMCALLS("JVM_RawMonitorExit(mon=%p)", mon);
+
        (void) lock_monitor_exit((java_object_t *) mon);
 }
 
@@ -2657,6 +3054,8 @@ void JVM_GetPrimitiveFieldValues(JNIEnv *env, jclass cb, jobject obj, jlongArray
 jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_get)
 {
        log_println("JVM_AccessVMBooleanFlag: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2665,6 +3064,8 @@ jboolean JVM_AccessVMBooleanFlag(const char* name, jboolean* value, jboolean is_
 jboolean JVM_AccessVMIntFlag(const char* name, jint* value, jboolean is_get)
 {
        log_println("JVM_AccessVMIntFlag: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2681,6 +3082,8 @@ void JVM_VMBreakPoint(JNIEnv *env, jobject obj)
 jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassFields: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2689,6 +3092,8 @@ jobjectArray JVM_GetClassFields(JNIEnv *env, jclass cls, jint which)
 jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassMethods: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2697,6 +3102,8 @@ jobjectArray JVM_GetClassMethods(JNIEnv *env, jclass cls, jint which)
 jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
 {
        log_println("JVM_GetClassConstructors: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2705,6 +3112,8 @@ jobjectArray JVM_GetClassConstructors(JNIEnv *env, jclass cls, jint which)
 jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
 {
        log_println("JVM_GetClassField: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2713,6 +3122,8 @@ jobject JVM_GetClassField(JNIEnv *env, jclass cls, jstring name, jint which)
 jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray types, jint which)
 {
        log_println("JVM_GetClassMethod: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2721,6 +3132,8 @@ jobject JVM_GetClassMethod(JNIEnv *env, jclass cls, jstring name, jobjectArray t
 jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jint which)
 {
        log_println("JVM_GetClassConstructor: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2729,6 +3142,8 @@ jobject JVM_GetClassConstructor(JNIEnv *env, jclass cls, jobjectArray types, jin
 jobject JVM_NewInstance(JNIEnv *env, jclass cls)
 {
        log_println("JVM_NewInstance: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2737,6 +3152,8 @@ jobject JVM_NewInstance(JNIEnv *env, jclass cls)
 jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
 {
        log_println("JVM_GetField: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2744,7 +3161,13 @@ jobject JVM_GetField(JNIEnv *env, jobject field, jobject obj)
 
 jvalue JVM_GetPrimitiveField(JNIEnv *env, jobject field, jobject obj, unsigned char wCode)
 {
+       jvalue jv;
+
        log_println("JVM_GetPrimitiveField: IMPLEMENT ME!");
+
+       jv.l = NULL;
+
+       return jv;
 }
 
 
@@ -2768,9 +3191,8 @@ void JVM_SetPrimitiveField(JNIEnv *env, jobject field, jobject obj, jvalue v, un
 
 jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray args0)
 {
-#if PRINTJVM
-       log_println("JVM_InvokeMethod: method=%p, obj=%p, args0=%p", method, obj, args0);
-#endif
+       TRACEJVMCALLS("JVM_InvokeMethod(env=%p, method=%p, obj=%p, args0=%p)", env, method, obj, args0);
+
        return (jobject) _Jv_java_lang_reflect_Method_invoke((java_lang_reflect_Method *) method, (java_lang_Object *) obj, (java_handle_objectarray_t *) args0);
 }
 
@@ -2779,9 +3201,8 @@ jobject JVM_InvokeMethod(JNIEnv *env, jobject method, jobject obj, jobjectArray
 
 jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args0)
 {
-#if PRINTJVM
-       log_println("JVM_NewInstanceFromConstructor: c=%p, args0=%p", c, args0);
-#endif
+       TRACEJVMCALLS("JVM_NewInstanceFromConstructor(env=%p, c=%p, args0=%p)", env, c, args0);
+
        return (jobject) _Jv_java_lang_reflect_Constructor_newInstance(env, (java_lang_reflect_Constructor *) c, (java_handle_objectarray_t *) args0);
 }
 
@@ -2790,10 +3211,11 @@ jobject JVM_NewInstanceFromConstructor(JNIEnv *env, jobject c, jobjectArray args
 
 jboolean JVM_SupportsCX8()
 {
-#if PRINTJVM
-       log_println("JVM_SupportsCX8");
-#endif
-       return _Jv_java_util_concurrent_atomic_AtomicLong_VMSupportsCS8(NULL, NULL);
+       TRACEJVMCALLS("JVM_SupportsCX8()");
+
+       /* IMPLEMENT ME */
+
+       return 0;
 }
 
 
@@ -2802,6 +3224,8 @@ jboolean JVM_SupportsCX8()
 jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlong newVal)
 {
        log_println("JVM_CX8Field: IMPLEMENT ME!");
+
+       return 0;
 }
 
 
@@ -2810,6 +3234,8 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
        log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2818,14 +3244,20 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
        log_println("JVM_DumpThreads: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
 /* JVM_GetManagement */
 
-voidJVM_GetManagement(jint version)
+void *JVM_GetManagement(jint version)
 {
-       log_println("JVM_GetManagement: IMPLEMENT ME!");
+       TRACEJVMCALLS("JVM_GetManagement(version=%d)", version);
+
+       /* TODO We current don't support the management interface. */
+
+       return NULL;
 }
 
 
@@ -2834,6 +3266,8 @@ void* JVM_GetManagement(jint version)
 jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 {
        log_println("JVM_InitAgentProperties: IMPLEMENT ME!");
+
+       return NULL;
 }
 
 
@@ -2841,7 +3275,32 @@ jobject JVM_InitAgentProperties(JNIEnv *env, jobject properties)
 
 jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 {
-       log_println("JVM_GetEnclosingMethodInfo: IMPLEMENT ME!");
+       classinfo                 *c;
+       methodinfo                *m;
+       java_handle_objectarray_t *oa;
+
+       TRACEJVMCALLS("JVM_GetEnclosingMethodInfo(env=%p, ofClass=%p)", env, ofClass);
+
+       c = LLNI_classinfo_unwrap(ofClass);
+
+       if ((c == NULL) || class_is_primitive(c))
+               return NULL;
+
+       m = class_get_enclosingmethod(c);
+
+       if (m == NULL)
+               return NULL;
+
+       oa = builtin_anewarray(3, class_java_lang_Object);
+
+       if (oa == NULL)
+               return NULL;
+
+       array_objectarray_element_set(oa, 0, (java_handle_t *) LLNI_classinfo_wrap(m->class));
+       array_objectarray_element_set(oa, 1, javastring_new(m->name));
+       array_objectarray_element_set(oa, 2, javastring_new(m->descriptor));
+
+       return (jobjectArray) oa;
 }
 
 
@@ -2849,15 +3308,212 @@ jobjectArray JVM_GetEnclosingMethodInfo(JNIEnv *env, jclass ofClass)
 
 jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
 {
-       log_println("JVM_GetThreadStateValues: IMPLEMENT ME!");
+       java_handle_intarray_t *ia;
+
+       TRACEJVMCALLS("JVM_GetThreadStateValues(env=%p, javaThreadState=%d)",
+                                 env, javaThreadState);
+
+       /* 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. */
+
+       switch (javaThreadState) {
+    case THREAD_STATE_NEW:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_NEW);
+               break; 
+
+    case THREAD_STATE_RUNNABLE:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_RUNNABLE);
+               break; 
+
+    case THREAD_STATE_BLOCKED:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_BLOCKED);
+               break; 
+
+    case THREAD_STATE_WAITING:
+               ia = builtin_newarray_int(2);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
+               /* XXX Implement parked stuff. */
+/*             array_intarray_element_set(ia, 1, PARKED); */
+               break; 
+
+    case THREAD_STATE_TIMED_WAITING:
+               ia = builtin_newarray_int(3);
+
+               if (ia == NULL)
+                       return NULL;
+
+               /* XXX Not sure about that one. */
+/*             array_intarray_element_set(ia, 0, SLEEPING); */
+               array_intarray_element_set(ia, 0, THREAD_STATE_TIMED_WAITING);
+               /* XXX Implement parked stuff. */
+/*             array_intarray_element_set(ia, 2, PARKED); */
+               break; 
+
+    case THREAD_STATE_TERMINATED:
+               ia = builtin_newarray_int(1);
+
+               if (ia == NULL)
+                       return NULL;
+
+               array_intarray_element_set(ia, 0, THREAD_STATE_TERMINATED);
+               break; 
+
+    default:
+               /* Unknown state - probably incompatible JDK version */
+               return NULL;
+       }
+
+       return (jintArray) ia;
 }
 
 
-/* JVM_GetThreadStateValues */
+/* JVM_GetThreadStateNames */
 
 jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArray values)
 {
-       log_println("JVM_GetThreadStateValues: IMPLEMENT ME!");
+       java_handle_intarray_t    *ia;
+       java_handle_objectarray_t *oa;
+       java_object_t             *s;
+
+       TRACEJVMCALLS("JVM_GetThreadStateNames(env=%p, javaThreadState=%d, values=%p)",
+                                 env, javaThreadState, values);
+
+       ia = (java_handle_intarray_t *) values;
+
+       /* 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. */
+
+       if (values == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       switch (javaThreadState) {
+    case THREAD_STATE_NEW:
+               assert(ia->header.size == 1 && ia->data[0] == THREAD_STATE_NEW);
+
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("NEW"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_RUNNABLE:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("RUNNABLE"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_BLOCKED:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("BLOCKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+    case THREAD_STATE_WAITING:
+               oa = builtin_anewarray(2, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
+/*             s = javastring_new(utf_new_char("WAITING.PARKED")); */
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+/*             array_objectarray_element_set(oa, 1, s); */
+               break; 
+
+    case THREAD_STATE_TIMED_WAITING:
+               oa = builtin_anewarray(3, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+/*             s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
+               s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
+/*             s = javastring_new(utf_new_char("TIMED_WAITING.PARKED")); */
+
+               if (s == NULL)
+                       return NULL;
+
+/*             array_objectarray_element_set(oa, 0, s); */
+               array_objectarray_element_set(oa, 0, s);
+/*             array_objectarray_element_set(oa, 2, s); */
+               break; 
+
+    case THREAD_STATE_TERMINATED:
+               oa = builtin_anewarray(1, class_java_lang_String);
+
+               if (oa == NULL)
+                       return NULL;
+
+               s = javastring_new(utf_new_char("TERMINATED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 0, s);
+               break; 
+
+       default:
+               /* Unknown state - probably incompatible JDK version */
+               return NULL;
+       }
+
+       return (jobjectArray) oa;
 }
 
 
@@ -2871,10 +3527,44 @@ void JVM_GetVersionInfo(JNIEnv* env, jvm_version_info* info, size_t info_size)
 
 /* OS: JVM_RegisterSignal */
 
-void* JVM_RegisterSignal(jint sig, void* handler)
+void *JVM_RegisterSignal(jint sig, void *handler)
 {
-       log_println("JVM_RegisterSignal: sig=%d, handler=%p, IMPLEMENT ME!", sig, handler);
-       return NULL;
+       functionptr newHandler;
+
+       TRACEJVMCALLS("JVM_RegisterSignal(sig=%d, handler=%p)", sig, handler);
+
+       if (handler == (void *) 2)
+               newHandler = (functionptr) signal_thread_handler;
+       else
+               newHandler = (functionptr) (uintptr_t) handler;
+
+       switch (sig) {
+    case SIGILL:
+    case SIGFPE:
+    case SIGUSR1:
+    case SIGSEGV:
+               /* These signals are already used by the VM. */
+               return (void *) -1;
+
+    case SIGQUIT:
+               /* This signal is used by the VM to dump thread stacks unless
+                  ReduceSignalUsage is set, in which case the user is allowed
+                  to set his own _native_ handler for this signal; thus, in
+                  either case, we do not allow JVM_RegisterSignal to change
+                  the handler. */
+               return (void *) -1;
+
+       case SIGHUP:
+       case SIGINT:
+       case SIGTERM:
+               break;
+       }
+
+       signal_register_signal(sig, newHandler, 0);
+
+       /* XXX Should return old handler. */
+
+       return (void *) 2;
 }
 
 
@@ -2882,7 +3572,8 @@ void* JVM_RegisterSignal(jint sig, void* handler)
 
 jboolean JVM_RaiseSignal(jint sig)
 {
-       log_println("JVM_RaiseSignal: sig=%s", sig);
+       log_println("JVM_RaiseSignal: IMPLEMENT ME! sig=%s", sig);
+
        return false;
 }
 
@@ -2891,8 +3582,22 @@ jboolean JVM_RaiseSignal(jint sig)
 
 jint JVM_FindSignal(const char *name)
 {
-       log_println("JVM_FindSignal: name=%s", name);
-       return 0;
+       TRACEJVMCALLS("JVM_FindSignal(name=%s)", name);
+
+#if defined(__LINUX__)
+       if (strcmp(name, "HUP") == 0)
+               return SIGHUP;
+
+       if (strcmp(name, "INT") == 0)
+               return SIGINT;
+
+       if (strcmp(name, "TERM") == 0)
+               return SIGTERM;
+#else
+# error not implemented for this OS
+#endif
+
+       return -1;
 }