perlport information about portably embedding string data.
[p5sagit/p5-mst-13.2.git] / jpl / JNI / JNI.xs
index ee854c1..f482695 100644 (file)
@@ -8,24 +8,63 @@
 #include "perl.h"
 #include "XSUB.h"
 
-#include <perl.h>
+#include <stdio.h>
 #include <jni.h>
-#include <dlfcn.h>
 
+#ifndef PERL_VERSION
+#  include <patchlevel.h>
+#  define PERL_REVISION                5
+#  define PERL_VERSION         PATCHLEVEL
+#  define PERL_SUBVERSION      SUBVERSION
+#endif
+
+#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75))
+#  define PL_na                na
+#  define PL_sv_no     sv_no
+#  define PL_sv_undef  sv_undef
+#  define PL_dowarn    dowarn
+#endif
+
+#ifndef newSVpvn
+#  define newSVpvn(a,b)        newSVpv(a,b)
+#endif
+
+#ifndef pTHX
+#  define pTHX         void
+#  define pTHX_
+#  define aTHX
+#  define aTHX_
+#  define dTHX         extern int JNI___notused
+#endif
+
+#ifndef WIN32
+#  include <dlfcn.h>
+#endif
+
+#ifdef EMBEDDEDPERL
 extern JNIEnv* jplcurenv;
 extern int jpldebug;
+#else
+JNIEnv* jplcurenv;
+int jpldebug = 1;
+#endif
 
 #define SysRet jint
 
-static void
-call_my_exit(jint status)
+#ifdef WIN32
+static void JNICALL call_my_exit(jint status)
+{
+    my_exit(status);
+}
+#else
+static void call_my_exit(jint status)
 {
-    dTHX;
     my_exit(status);
 }
+#endif
 
 jvalue*
-makeargs(pTHX_ char *sig, SV** svp, int items)
+makeargs(char *sig, SV** svp, int items)
 {
     jvalue* jv = (jvalue*)safemalloc(sizeof(jvalue) * items);
     int ix = 0;
@@ -330,7 +369,7 @@ makeargs(pTHX_ char *sig, SV** svp, int items)
                            int i;
                            SV** esv;
                            static jclass jcl = 0;
-                           jarray ja;
+                           jobjectArray ja;
 
                            if (!jcl)
                                jcl = (*env)->FindClass(env, "java/lang/String");
@@ -359,19 +398,17 @@ makeargs(pTHX_ char *sig, SV** svp, int items)
                        int i;
                        SV** esv;
                       static jclass jcl = 0;
-                       jarray ja;
+                       jobjectArray ja;
 
                        if (!jcl)
                            jcl = (*env)->FindClass(env, "java/lang/Object");
                        ja = (*env)->NewObjectArray(env, len, jcl, 0);
                        for (esv = AvARRAY((AV*)rv), i = 0; i < len; esv++, i++) {
                            if (SvROK(*esv) && (rv = SvRV(*esv)) && SvOBJECT(rv)) {
-                               (*env)->SetObjectArrayElement(env, ja, i,
-                                   (jobject)(void*)SvIV(rv));
+                               (*env)->SetObjectArrayElement(env, ja, i, (jobject)(void*)SvIV(rv));
                            }
                            else {
-                               jobject str = (jobject)(*env)->NewStringUTF(env,
-                                   SvPV(*esv,n_a));
+                               jobject str = (jobject)(*env)->NewStringUTF(env, SvPV(*esv,n_a));
                                (*env)->SetObjectArrayElement(env, ja, i, str);
                            }
                        }
@@ -388,8 +425,7 @@ makeargs(pTHX_ char *sig, SV** svp, int items)
        case 'L':
            if (!SvROK(sv) || strnEQ(s, "java/lang/String;", 17)) {
                s += 17;
-               jv[ix++].l = (jobject)(*env)->NewStringUTF(env,
-                               (char*) SvPV(sv,n_a));
+               jv[ix++].l = (jobject)(*env)->NewStringUTF(env, (char*) SvPV(sv,n_a));
                break;
            }
            while (*s != ';') s++;
@@ -400,16 +436,16 @@ makeargs(pTHX_ char *sig, SV** svp, int items)
            }
            break;
        case ')':
-           Perl_croak(aTHX_ "too many arguments, signature: %s", sig);
+           croak("too many arguments, signature: %s", sig);
            goto cleanup;
        default:
-           Perl_croak(aTHX_ "panic: malformed signature: %s", s-1);
+           croak("panic: malformed signature: %s", s-1);
            goto cleanup;
        }
 
     }
     if (*s != ')') {
-       Perl_croak(aTHX_ "not enough arguments, signature: %s", sig);
+       croak("not enough arguments, signature: %s", sig);
        goto cleanup;
     }
     return jv;
@@ -420,9 +456,9 @@ cleanup:
 }
 
 static int
-not_here(pTHX_ char *s)
+not_here(char *s)
 {
-    Perl_croak(aTHX_ "%s not implemented on this architecture", s);
+    croak("%s not implemented on this architecture", s);
     return -1;
 }
 
@@ -476,7 +512,11 @@ constant(char *name, int arg)
 #endif
        if (strEQ(name, "JNI_H"))
 #ifdef JNI_H
+#ifdef WIN32
+           return 1;
+#else
            return JNI_H;
+#endif
 #else
            goto not_there;
 #endif
@@ -567,7 +607,11 @@ DefineClass(name, loader, buf)
        const jbyte *           buf
     CODE:
        {
-           RETVAL = (*env)->DefineClass(env,  name, loader, buf, (jsize)buf_len_);
+#ifdef KAFFE
+           RETVAL = (*env)->DefineClass(env,  loader, buf, (jsize)buf_len_);
+#else
+           RETVAL = (*env)->DefineClass(env,  name, loader, buf, (jsize)buf_len_); 
+#endif
            RESTOREENV;
        }
     OUTPUT:
@@ -740,7 +784,7 @@ NewObject(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->NewObjectA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -810,7 +854,7 @@ CallObjectMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallObjectMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -841,7 +885,7 @@ CallBooleanMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallBooleanMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -872,7 +916,7 @@ CallByteMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallByteMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -903,7 +947,7 @@ CallCharMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallCharMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -934,7 +978,7 @@ CallShortMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallShortMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -965,7 +1009,7 @@ CallIntMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallIntMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -996,7 +1040,7 @@ CallLongMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallLongMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -1027,7 +1071,7 @@ CallFloatMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallFloatMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -1058,7 +1102,7 @@ CallDoubleMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallDoubleMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -1089,7 +1133,7 @@ CallVoidMethod(obj,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            (*env)->CallVoidMethodA(env, obj,methodID,args);
            RESTOREENV;
        }
@@ -1117,7 +1161,7 @@ CallNonvirtualObjectMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualObjectMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1150,7 +1194,7 @@ CallNonvirtualBooleanMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualBooleanMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1183,7 +1227,7 @@ CallNonvirtualByteMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualByteMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1216,7 +1260,7 @@ CallNonvirtualCharMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualCharMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1249,7 +1293,7 @@ CallNonvirtualShortMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualShortMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1282,7 +1326,7 @@ CallNonvirtualIntMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualIntMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1315,7 +1359,7 @@ CallNonvirtualLongMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualLongMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1348,7 +1392,7 @@ CallNonvirtualFloatMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualFloatMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1381,7 +1425,7 @@ CallNonvirtualDoubleMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallNonvirtualDoubleMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1414,7 +1458,7 @@ CallNonvirtualVoidMethod(obj,clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            (*env)->CallNonvirtualVoidMethodA(env, obj,clazz,methodID,args);
            RESTOREENV;
        }
@@ -1713,7 +1757,7 @@ CallStaticObjectMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticObjectMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1744,7 +1788,7 @@ CallStaticBooleanMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticBooleanMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1775,7 +1819,7 @@ CallStaticByteMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticByteMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1806,7 +1850,7 @@ CallStaticCharMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticCharMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1837,7 +1881,7 @@ CallStaticShortMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticShortMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1868,7 +1912,7 @@ CallStaticIntMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticIntMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1899,7 +1943,7 @@ CallStaticLongMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticLongMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1930,7 +1974,7 @@ CallStaticFloatMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticFloatMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1961,7 +2005,7 @@ CallStaticDoubleMethod(clazz,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            RETVAL = (*env)->CallStaticDoubleMethodA(env, clazz,methodID,args);
            RESTOREENV;
        }
@@ -1992,7 +2036,7 @@ CallStaticVoidMethod(cls,methodID,...)
        int                     argoff = $min_args;
     CODE:
        {
-           jvalue * args = makeargs(aTHX_ sig, &ST(argoff), items - argoff);
+           jvalue * args = makeargs(sig, &ST(argoff), items - argoff);
            (*env)->CallStaticVoidMethodA(env, cls,methodID,args);
            RESTOREENV;
        }
@@ -2885,9 +2929,9 @@ SetBooleanArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetBooleanArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2904,9 +2948,9 @@ SetByteArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetByteArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2923,9 +2967,9 @@ SetCharArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetCharArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2942,9 +2986,9 @@ SetShortArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetShortArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2961,9 +3005,9 @@ SetIntArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetIntArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2980,9 +3024,9 @@ SetLongArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetLongArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -2999,9 +3043,9 @@ SetFloatArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetFloatArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -3018,9 +3062,9 @@ SetDoubleArrayRegion(array,start,len,buf)
     CODE:
        {
            if (buf_len_ < len)
-               Perl_croak(aTHX_ "string is too short");
-           else if (buf_len_ > len && ckWARN(WARN_UNSAFE))
-               Perl_warner(aTHX_ WARN_UNSAFE, "string is too long");
+               croak("string is too short");
+           else if (buf_len_ > len && PL_dowarn)
+               warn("string is too long");
            (*env)->SetDoubleArrayRegion(env, array,start,len,buf);
            RESTOREENV;
        }
@@ -3076,61 +3120,134 @@ GetJavaVM(...)
        JNIEnv *                env = FETCHENV;
     CODE:
        {
+#ifdef JPL_DEBUG
+           jpldebug = 1;
+#else
+           jpldebug = 0;
+#endif
            if (env) {  /* We're embedded. */
                if ((*env)->GetJavaVM(env, &RETVAL) < 0)
                    RETVAL = 0;
            }
            else {      /* We're embedding. */
-               JDK1_1InitArgs vm_args;
+#ifdef KAFFE
+                JavaVMInitArgs vm_args;
+#else
+                JDK1_1InitArgs vm_args;
+#endif
                char *lib;
+               if (jpldebug) {
+                   fprintf(stderr, "We're embedding Java in Perl.\n");
+               }
 
                if (items--) {
-                   ++mark;
+                   ++mark;
                    lib = SvPV(*mark, PL_na);
                }
                else
                    lib = 0;
-
+               if (jpldebug) {
+                   fprintf(stderr, "lib is %s.\n", lib);
+               }
+#ifdef WIN32
+        if (LoadLibrary("jvm.dll")) {
+            if (!LoadLibrary("javai.dll")) {
+                warn("Can't load javai.dll");
+            }
+        } else {
+            if (lib && !LoadLibrary(lib))
+                croak("Can't load javai.dll"); 
+        }
+#else
+               if (jpldebug) {
+                   fprintf(stderr, "Opening Java shared library.\n");
+                }
+#ifdef KAFFE
+               if (!dlopen("libkaffevm.so", RTLD_LAZY|RTLD_GLOBAL)) {
+#else
                if (!dlopen("libjava.so", RTLD_LAZY|RTLD_GLOBAL)) {
+#endif
                    if (lib && !dlopen(lib, RTLD_LAZY|RTLD_GLOBAL))
-                       Perl_croak(aTHX_ "Can't load libjava.so");
+                       croak("Can't load Java shared library.");
                }
-
+#endif
+               /* Kaffe seems to get very upset if vm_args.version isn't set */
+#ifdef KAFFE
+               vm_args.version = JNI_VERSION_1_1;
+#endif
                JNI_GetDefaultJavaVMInitArgs(&vm_args);
                vm_args.exit = &call_my_exit;
+               if (jpldebug) {
+            fprintf(stderr, "items = %d\n", items);
+            fprintf(stderr, "mark = %s\n", SvPV(*mark, PL_na));
+        }
                while (items > 1) {
-                   char *s = SvPV(*++mark,PL_na);
+                 char *s;
+                   ++mark;
+                   s = SvPV(*mark,PL_na);
+                   ++mark;
+                   if (jpldebug) {
+                fprintf(stderr, "*s = %s\n", s);
+                fprintf(stderr, "val = %s\n", SvPV(*mark, PL_na));
+            }
                    items -= 2;
                    if (strEQ(s, "checkSource"))
-                       vm_args.checkSource = (jint)SvIV(*++mark);
+                       vm_args.checkSource = (jint)SvIV(*mark);
                    else if (strEQ(s, "nativeStackSize"))
-                       vm_args.nativeStackSize = (jint)SvIV(*++mark);
+                       vm_args.nativeStackSize = (jint)SvIV(*mark);
                    else if (strEQ(s, "javaStackSize"))
-                       vm_args.javaStackSize = (jint)SvIV(*++mark);
+                       vm_args.javaStackSize = (jint)SvIV(*mark);
                    else if (strEQ(s, "minHeapSize"))
-                       vm_args.minHeapSize = (jint)SvIV(*++mark);
+                       vm_args.minHeapSize = (jint)SvIV(*mark);
                    else if (strEQ(s, "maxHeapSize"))
-                       vm_args.maxHeapSize = (jint)SvIV(*++mark);
+                       vm_args.maxHeapSize = (jint)SvIV(*mark);
                    else if (strEQ(s, "verifyMode"))
-                       vm_args.verifyMode = (jint)SvIV(*++mark);
+                       vm_args.verifyMode = (jint)SvIV(*mark);
                    else if (strEQ(s, "classpath"))
-                       vm_args.classpath = savepv(SvPV(*++mark,PL_na));
+                       vm_args.classpath = savepv(SvPV(*mark,PL_na));
                    else if (strEQ(s, "enableClassGC"))
-                       vm_args.enableClassGC = (jint)SvIV(*++mark);
+                       vm_args.enableClassGC = (jint)SvIV(*mark);
                    else if (strEQ(s, "enableVerboseGC"))
-                       vm_args.enableVerboseGC = (jint)SvIV(*++mark);
+                       vm_args.enableVerboseGC = (jint)SvIV(*mark);
                    else if (strEQ(s, "disableAsyncGC"))
-                       vm_args.disableAsyncGC = (jint)SvIV(*++mark);
+                       vm_args.disableAsyncGC = (jint)SvIV(*mark);
+#ifdef KAFFE
+                   else if (strEQ(s, "libraryhome"))
+                       vm_args.libraryhome = savepv(SvPV(*mark,PL_na));
+                   else if (strEQ(s, "classhome"))
+                       vm_args.classhome = savepv(SvPV(*mark,PL_na));
+                   else if (strEQ(s, "enableVerboseJIT"))
+                       vm_args.enableVerboseJIT = (jint)SvIV(*mark); 
+                   else if (strEQ(s, "enableVerboseClassloading"))
+                       vm_args.enableVerboseClassloading = (jint)SvIV(*mark); 
+                   else if (strEQ(s, "enableVerboseCall"))
+                       vm_args.enableVerboseCall = (jint)SvIV(*mark); 
+                   else if (strEQ(s, "allocHeapSize"))
+                       vm_args.allocHeapSize = (jint)SvIV(*mark); 
+#else
                    else if (strEQ(s, "verbose"))
-                       vm_args.verbose = (jint)SvIV(*++mark);
+                       vm_args.verbose = (jint)SvIV(*mark); 
                    else if (strEQ(s, "debugging"))
-                       vm_args.debugging = (jboolean)SvIV(*++mark);
+                       vm_args.debugging = (jboolean)SvIV(*mark);
                    else if (strEQ(s, "debugPort"))
-                       vm_args.debugPort = (jint)SvIV(*++mark);
+                       vm_args.debugPort = (jint)SvIV(*mark); 
+#endif
                    else
-                       Perl_croak(aTHX_ "unrecognized option: %s", s);
+                       croak("unrecognized option: %s", s);
+               }
+
+               if (jpldebug) {
+                   fprintf(stderr, "Creating Java VM...\n");
+                   fprintf(stderr, "Working CLASSPATH: %s\n", 
+                       vm_args.classpath);
                }
-               JNI_CreateJavaVM(&RETVAL, &jplcurenv, &vm_args);
+               if (JNI_CreateJavaVM(&RETVAL, &jplcurenv, &vm_args) < 0) {
+                  croak("Unable to create instance of JVM");
+                }
+               if (jpldebug) {
+                   fprintf(stderr, "Created Java VM.\n");
+               }
+
            }
        }