merge from gnuclasspath branch. I hope I didn't miss or revert any modifications...
authorjowenn <none@none>
Fri, 21 Nov 2003 18:24:01 +0000 (18:24 +0000)
committerjowenn <none@none>
Fri, 21 Nov 2003 18:24:01 +0000 (18:24 +0000)
35 files changed:
Makefile.am
acconfig.h
asmpart.h
builtin.c
builtin.h
configure.in
global.h
headers.c
jni.c
jni.h
loader.c
loader.h
main.c
native.c
native.h
src/cacao/cacao.c
src/cacaoh/headers.c
src/native/jni.c
src/native/jni.h
src/native/native.c
src/native/native.h
src/vm/builtin.c
src/vm/builtin.h
src/vm/global.h
src/vm/jit/asmpart.h
src/vm/loader.c
src/vm/loader.h
src/vm/tables.c
src/vm/tables.h
src/vm/unzip.c [new file with mode: 0644]
src/vm/unzip.h [new file with mode: 0644]
tables.c
tables.h
unzip.c [new file with mode: 0644]
unzip.h [new file with mode: 0644]

index 4bbbed2be838dbece76c3b68b34957d1014797f2..aa988691a79595fac0ecc8b15315d0d3a536df5b 100644 (file)
@@ -1,12 +1,12 @@
 ## Process this file with automake to produce Makefile.in
 
-# $Id: Makefile.am 618 2003-11-13 09:39:28Z stefan $
+# $Id: Makefile.am 664 2003-11-21 18:24:01Z jowenn $
 
 @SET_MAKE@
 
 MAINTAINERCLEANFILES = Makefile.in configure
 ALLSUBDIRS = mm toolbox threads jit nat tst doc jvmtst
-SUBDIRS = $(ALLSUBDIRS)
+SUBDIRS = classpathbin $(ALLSUBDIRS)
 DIST_SUBDIRS = $(ALLSUBDIRS)
 
 EXTRA_DIST = \
@@ -43,7 +43,8 @@ cacao_SOURCES = \
        native.h \
        jni.h \
        tables.c \
-       tables.h
+       tables.h \
+       unzip.c
 
 cacao_LDADD = \
        jit/libjit.a \
@@ -51,7 +52,14 @@ cacao_LDADD = \
        jit/@ARCH_DIR@/libarch.a \
        toolbox/libtoolbox.a \
        $(BOEHM_LIBS) \
-       @THREAD_OBJ@
+       @THREAD_OBJ@ \
+       classpathbin/@ARCH_DIR@/native/jni/java-io/.libs/libjavaio.a \
+       classpathbin/@ARCH_DIR@/native/jni/java-nio/.libs/libjavanio.a \
+       classpathbin/@ARCH_DIR@/native/jni/java-net/.libs/libjavanet.a \
+       classpathbin/@ARCH_DIR@/native/jni/java-util/.libs/libjavautil.a \
+       classpathbin/@ARCH_DIR@/native/jni/java-lang/.libs/libjavalang.a \
+       classpathbin/@ARCH_DIR@/native/jni/java-lang/.libs/libjavalangreflect.a @AWT_OBJS@ @ZIP_LIBS@
+
 
 cacao_DEPENDENCIES = \
        jit/libjit.a \
@@ -65,79 +73,112 @@ cacaoh_SOURCES = \
        headers.c \
        tables.c \
        loader.c \
-       builtin.c
+       builtin.c \
+       unzip.c
 
 cacaoh_LDADD = \
        toolbox/libtoolbox.a \
        $(BOEHM_LIBS) \
-       @THREAD_OBJ@
+       @THREAD_OBJ@  @ZIP_LIBS@
 
 cacaoh_DEPENDENCIES = \
        toolbox/libtoolbox.a \
        $(BOEHM_LIBS) \
        @THREAD_OBJ@
 
-native.c: nativetypes.hh jit/@ARCH_DIR@/offsets.h nativetable.hh
 
-nativetypes.hh jit/@ARCH_DIR@/offsets.h nativetable.hh: cacaoh
-       ./cacaoh \
-               java.lang.Object \
-               java.lang.String \
-               java.lang.ClassLoader \
-               java.lang.Class \
-               java.lang.Compiler \
-               java.lang.Integer \
-               java.lang.Double \
-               java.lang.Float \
-               java.lang.Math \
-               java.lang.Package \
-               java.lang.Runtime \
-               java.lang.SecurityManager \
-               java.lang.Exception \
-               java.io.PrintStream \
-               java.io.InputStream \
-               java.lang.System \
-               java.lang.Thread \
-               java.lang.ThreadGroup \
-               java.lang.Throwable \
-               java.lang.reflect.Array \
-               java.lang.reflect.Constructor \
-               java.lang.reflect.Field \
-               java.lang.reflect.Method \
-               java.lang.reflect.Modifier \
-               java.io.FileDescriptor \
-               java.io.FileInputStream \
-               java.io.FileOutputStream \
-               java.io.FileSystem \
-               java.io.ObjectInputStream \
-               java.io.ObjectStreamClass \
-               java.io.RandomAccessFile \
-               java.util.ResourceBundle \
-               java.util.jar.JarFile \
-               java.util.zip.Adler32 \
-               java.util.zip.CRC32 \
-               java.util.zip.Deflater \
-               java.util.zip.Inflater \
-               java.util.zip.ZipEntry \
-               java.util.zip.ZipFile \
-               java.util.Properties \
-               java.util.Date \
-               java.math.BigInteger \
-               java.net.InetAddress \
-               java.net.InetAddressImpl \
-               java.net.DatagramPacket \
-               java.net.PlainDatagramSocketImpl \
-               java.net.SocketImpl \
-               java.net.PlainSocketImpl \
-               java.net.SocketInputStream \
-               java.net.SocketOutputStream \
-               java.security.PrivilegedActionException \
-               java.security.PrivilegedAction \
-               java.security.PrivilegedExceptionAction \
-               java.security.AccessController \
-               java.io.File \
-               java.io.UnixFileSystem \
-               java.lang.ClassLoader_NativeLibrary
+nativetypes.hh jit/@ARCH_DIR@/offsets.h nativetable.hh: cacaoh Makefile.am Makefile
+       CLASSPATH=./classpathbin/@ARCH_DIR@/lib ./cacaoh \
+       java.lang.Class \
+       java.io.FileDescriptor \
+       gnu.java.nio.SelectorImpl \
+       gnu.java.nio.FileLockImpl \
+       gnu.java.lang.reflect.TypeSignature \
+       gnu.java.math.MPN \
+       gnu.classpath.RawData \
+       gnu.classpath.Configuration \
+       java.io.OutputStream \
+       java.io.PrintWriter \
+       java.io.FileInputStream \
+       java.io.File \
+       java.lang.SecurityManager \
+       java.lang.VMSecurityManager \
+       java.io.VMObjectStreamClass \
+       java.io.ObjectInputStream \
+       java.io.RandomAccessFile \
+       java.io.Writer \
+       java.io.DataInput \
+       java.io.DataInputStream \
+       java.io.OutputStreamWriter \
+       java.io.FileWriter \
+       java.net.NetworkInterface \
+       java.net.SocketImpl \
+       java.net.PlainSocketImpl \
+       java.net.DatagramSocketImpl \
+       java.net.InetAddress \
+       java.net.DatagramPacket \
+       java.net.PlainDatagramSocketImpl \
+       java.nio.CharBufferImpl \
+       java.nio.channels.FileChannelImpl \
+       java.nio.DoubleBufferImpl \
+       java.nio.LongBufferImpl \
+       java.nio.ByteOrder \
+       java.nio.ShortBufferImpl \
+       java.nio.IntBufferImpl \
+       java.nio.DirectByteBufferImpl \
+       java.nio.FloatBufferImpl \
+       java.sql.Connection \
+       java.lang.Math \
+       java.lang.StringBuffer \
+       java.lang.reflect.Array \
+       java.lang.reflect.Modifier \
+       java.lang.reflect.Proxy \
+       java.lang.Double \
+       java.lang.Compiler \
+       java.lang.Integer \
+       java.lang.StackTraceElement \
+       java.lang.Float \
+       java.lang.Object \
+       java.lang.RuntimePermission \
+       java.lang.System \
+       java.lang.StrictMath \
+       java.lang.ClassLoader \
+       java.lang.Process \
+       java.lang.UnsatisfiedLinkError \
+       java.text.Collator \
+       java.util.zip.Deflater \
+       java.util.zip.Inflater \
+       java.util.TimeZone \
+       java.util.Locale \
+       java.util.Hashtable \
+       java.beans.PropertyEditor \
+       java.security.cert.Certificate \
+       java.security.cert.X509Certificate \
+       java.security.AccessController \
+       javax.swing.Popup \
+       javax.swing.UIManager \
+       java.lang.VMClass \
+       java.lang.reflect.Field \
+       java.lang.reflect.Constructor \
+       java.lang.reflect.Method \
+       java.lang.ThreadGroup \
+       java.lang.Thread \
+       java.lang.VMDouble \
+       java.lang.VMFloat \
+       java.lang.Cloneable \
+       java.lang.VMObject \
+       java.lang.VMClassLoader \
+       java.io.PrintStream \
+       java.lang.VMSystem \
+       java.util.Properties \
+       java.lang.Runtime \
+       java.lang.Throwable \
+       java.lang.String \
+       gnu.java.security.x509.X509Certificate  \
+       java.lang.JOWENNTest1 \
+       @AWTPEERS@
+
+native.c: nativetypes.hh jit/@ARCH_DIR@/offsets.h nativetable.hh
 
 checkjvm:
        $(MAKE) -C jvmtst $@
index 710c7065a37135696b03842b86384e9b7c0f722a..308e0bfdeecfa8325799163e4078710c502fd0bb 100644 (file)
@@ -27,7 +27,7 @@
 
    Authors:
 
-   $Id: acconfig.h 557 2003-11-02 22:51:59Z twisti $
+   $Id: acconfig.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
 
 #undef USE_CODEMMAP
 
+#undef USE_GTK
+
+#undef USE_ZLIB
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 7237ba31107778f9ecd339046c82fab1466c26b2..3a98ba64761c0561b6a10a59e3536860256c6cfe 100644 (file)
--- a/asmpart.h
+++ b/asmpart.h
@@ -29,7 +29,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: asmpart.h 596 2003-11-09 20:05:07Z twisti $
+   $Id: asmpart.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -38,6 +38,7 @@
 #define _ASMPART_H
 
 #include "global.h"
+#include "jni.h"
 
 /* 
    determines if the byte support instruction set (21164a and higher)
@@ -72,6 +73,11 @@ java_objectheader *asm_calljavamethod(methodinfo *m, void *arg1, void *arg2,
 */
 java_objectheader *asm_calljavafunction(methodinfo *m, void *arg1, void *arg2,
                                         void *arg3, void *arg4);
+java_objectheader *asm_calljavafunction2(methodinfo *m, u4 count, u4 size , void *callblock);
+jdouble asm_calljavafunction2double(methodinfo *m, u4 count, u4 size , void *callblock);
+jlong asm_calljavafunction2long(methodinfo *m, u4 count, u4 size , void *callblock);
+
+
 
 void asm_handle_exception();
 void asm_handle_nat_exception();
index da8bb491fedc4fc1cb696fc6b035e8d29b7a235e..288a6cec8e5c26b9c1bdb0838c1cfd565e6f904d 100644 (file)
--- a/builtin.c
+++ b/builtin.c
@@ -34,7 +34,7 @@
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 624 2003-11-13 14:06:52Z twisti $
+   $Id: builtin.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -55,6 +55,7 @@
 
 #include "native-math.h"
 
+#undef DEBUG /*define DEBUG 1*/
 
 builtin_descriptor builtin_desc[] = {
        {(functionptr) builtin_instanceof,                 "instanceof"},
@@ -68,12 +69,13 @@ builtin_descriptor builtin_desc[] = {
        {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
        {(functionptr) asm_builtin_aastore,                "aastore"},
        {(functionptr) builtin_new,                                "new"},
+       {(functionptr) builtin_newarray,       "newarray"},
        {(functionptr) builtin_anewarray,          "anewarray"},
-       {(functionptr) builtin_newarray_array,     "newarray_array"},
 #if defined(__I386__)
-       /* have 2 parameters (needs stack manipulation) */
-       {(functionptr) asm_builtin_anewarray,      "anewarray"},
-       {(functionptr) asm_builtin_newarray_array, "newarray_array"},
+       /*
+        * have 2 parameters (needs stack manipulation)
+        */
+       {(functionptr) asm_builtin_newarray,       "newarray"},
 #endif
        {(functionptr) builtin_newarray_boolean,   "newarray_boolean"},
        {(functionptr) builtin_newarray_char,      "newarray_char"},
@@ -167,6 +169,7 @@ builtin_descriptor builtin_desc[] = {
 
 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
 { 
+       classinfo *tmp;
        if (super->flags & ACC_INTERFACE)
                return (sub->vftbl->interfacetablelength > super->index) &&
                        (sub->vftbl->interfacetable[-super->index] != NULL);
@@ -181,10 +184,41 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
          return 0;
        */
 
+/*
+       for (tmp=sub;tmp!=0;tmp=tmp->super) {
+               printf("->");
+               utf_display(tmp->name);
+       }
+               printf("\n\n");
+       
+       for (tmp=super;tmp!=0;tmp=tmp->super) {
+               printf("->");
+               utf_display(tmp->name);
+       }
+               printf("\n");
+       
+
+       printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
+                       sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
+                       super->vftbl->diffval); */
+
        return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
                (unsigned) (super->vftbl->diffval);
 }
 
+/* XXX inline this? */
+s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
+{
+       int base;
+       
+       if ((base = super->baseval) <= 0)
+               /* super is an interface */
+               return (sub->interfacetablelength > -base) &&
+                       (sub->interfacetable[base] != NULL);
+       return (unsigned) (sub->baseval - base)
+               <= (unsigned) (super->diffval);
+}
+
 
 /****************** function: builtin_instanceof *****************************
 
@@ -196,12 +230,22 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
                         
 *****************************************************************************/
 
+/* XXX should use vftbl */
 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
 {
 #ifdef DEBUG
        log_text ("builtin_instanceof called");
-#endif
-       
+
+       /* XXX remove log */
+       /*
+       sprintf(logtext,"instanceof(");
+       utf_sprint(logtext+strlen(logtext),obj->vftbl->class->name);
+       sprintf(logtext+strlen(logtext),",");
+       utf_sprint(logtext+strlen(logtext),class);
+       sprintf(logtext+strlen(logtext),")");
+       dolog();
+       */
+#endif 
        if (!obj) return 0;
        return builtin_isanysubclass (obj->vftbl->class, class);
 }
@@ -215,12 +259,23 @@ s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
                          
 ****************************************************************************/
 
+/* XXX should use vftbl */
 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
 {
 #ifdef DEBUG
        log_text("builtin_checkcast called");
 #endif
 
+       /* XXX remove log */
+       /*
+       sprintf(logtext,"checkcast(");
+       utf_sprint(logtext+strlen(logtext),obj->vftbl->class->name);
+       sprintf(logtext+strlen(logtext),",");
+       utf_sprint(logtext+strlen(logtext),class);
+       sprintf(logtext+strlen(logtext),")");
+       dolog();
+       */
+       
        if (obj == NULL)
                return 1;
        if (builtin_isanysubclass(obj->vftbl->class, class))
@@ -246,6 +301,8 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
                        
 ******************************************************************************/
 
+/* XXX delete */
+#if 0
 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
 {
        if (desc == target) return 1;
@@ -260,8 +317,23 @@ static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant
        default: return 1;
        }
 }
+#endif
 
+/* XXX inline this? */
+static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
+{
+       if (desc==target) return 1;
+       if (desc->arraytype != target->arraytype) return 0;
+       if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
+       
+       /* {both arrays are arrays of references} */
+       if (desc->dimension == target->dimension)
+               return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
+       if (desc->dimension < target->dimension) return 0;
 
+       /* {desc has higher dimension than target} */
+       return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
+}
 
 /******************** function: builtin_checkarraycast ***********************
 
@@ -280,6 +352,8 @@ static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant
                        
 *****************************************************************************/
 
+/* XXX delete */
+#if 0
 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
 {
        java_arrayheader *a = (java_arrayheader*) o;
@@ -325,14 +399,32 @@ s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
                return 1;
        }
 }
+#endif
+
+s4 builtin_checkarraycast(java_objectheader *o,arraydescriptor *target)
+{
+       arraydescriptor *desc;
+       
+       if (!o) return 1;
+       if ((desc = o->vftbl->arraydesc) == NULL) return 0;
 
+       return builtin_descriptorscompatible(desc,target);
+}
 
+/* XXX delete */
+#if 0
 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
 {
        if (!obj) return 1;
        return builtin_checkarraycast (obj, desc);
 }
+#endif
 
+s4 builtin_arrayinstanceof(java_objectheader *obj,arraydescriptor *desc)
+{
+       if (!obj) return 1;
+       return builtin_checkarraycast (obj, desc);
+}
 
 /************************** exception functions *******************************
 
@@ -342,7 +434,21 @@ java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr
 {
        if (verbose) {
                sprintf(logtext, "Builtin exception thrown: ");
-               utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
+               if (local_exceptionptr)
+                       utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
+               else {
+                       sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
+                       if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
+                       if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
+                       if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
+                       if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
+                       if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
+                       if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
+                       if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
+                       if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
+                       }
                dolog();
        }
        exceptionptr = local_exceptionptr;
@@ -358,7 +464,8 @@ java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr
 
 ******************************************************************************/
 
-
+/* XXX delete */
+#if 0
 s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
 {
        if (!o) return 1;
@@ -384,13 +491,133 @@ s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
                return 0;
        }
 }
+#endif
 
+s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
+{
+       arraydescriptor *desc;
+       arraydescriptor *valuedesc;
+       vftbl *componentvftbl;
+       vftbl *valuevftbl;
+    int dim_m1;
+       int base;
+       
+       if (!o) return 1;
 
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->componentvftbl != NULL
+        *     *) o->vftbl is not an interface vftbl
+        */
+       
+       desc = a->header.objheader.vftbl->arraydesc;
+    componentvftbl = desc->componentvftbl;
+       valuevftbl = o->vftbl;
 
-/*****************************************************************************
-                                                 ARRAY OPERATIONS
-*****************************************************************************/
+       /* XXX remove log */
+       /*
+       log_text("builtin_canstore");
+       print_arraydescriptor(stdout,desc);
+       utf_sprint(logtext,valuevftbl->class->name);
+       dolog();
+       */
+
+    if ((dim_m1 = desc->dimension - 1) == 0) {
+               /* {a is a one-dimensional array} */
+               /* {a is an array of references} */
+               
+               if (valuevftbl == componentvftbl)
+                       return 1;
+
+               /* XXX remove log */
+               /* log_text("not same vftbl"); */
+
+               if ((base = componentvftbl->baseval) <= 0)
+                       /* an array of interface references */
+                       return (valuevftbl->interfacetablelength > -base &&
+                                       valuevftbl->interfacetable[base] != NULL);
+               
+               return (unsigned)(valuevftbl->baseval - base)
+                       <= (unsigned)(componentvftbl->diffval);
+    }
+    /* {a has dimension > 1} */
+       /* {componentvftbl->arraydesc != NULL} */
+
+       /* check if o is an array */
+       if ((valuedesc = valuevftbl->arraydesc) == NULL)
+               return 0;
+       /* {o is an array} */
+
+       return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
+}
+
+/* This is an optimized version where a is guaranteed to be one-dimensional */
+s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
+{
+       arraydescriptor *desc;
+       vftbl *elementvftbl;
+       vftbl *valuevftbl;
+       int base;
+       
+       if (!o) return 1;
+
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl != NULL
+        *     *) a->...vftbl->arraydesc->dimension == 1
+        *     *) o->vftbl is not an interface vftbl
+        */
 
+       desc = a->header.objheader.vftbl->arraydesc;
+    elementvftbl = desc->elementvftbl;
+       valuevftbl = o->vftbl;
+
+       /* {a is a one-dimensional array} */
+       
+       if (valuevftbl == elementvftbl)
+               return 1;
+
+       if ((base = elementvftbl->baseval) <= 0)
+               /* an array of interface references */
+               return (valuevftbl->interfacetablelength > -base &&
+                               valuevftbl->interfacetable[base] != NULL);
+       
+       return (unsigned)(valuevftbl->baseval - base)
+               <= (unsigned)(elementvftbl->diffval);
+}
+
+/* This is an optimized version where a is guaranteed to be a
+ * one-dimensional array of a class type */
+/* XXX this could be inlined by the code generator */
+s4 builtin_canstore_onedim_class (java_objectarray *a, java_objectheader *o)
+{
+       vftbl *elementvftbl;
+       vftbl *valuevftbl;
+       
+       if (!o) return 1;
+
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
+        *     *) a->...vftbl->arraydesc->dimension == 1
+        *     *) o->vftbl is not an interface vftbl
+        */
+
+    elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
+       valuevftbl = o->vftbl;
+
+       /* {a is a one-dimensional array} */
+       
+       if (valuevftbl == elementvftbl)
+               return 1;
+
+       return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
+               <= (unsigned)(elementvftbl->diffval);
+}
 
 
 /******************** Function: builtin_new **********************************
@@ -427,128 +654,51 @@ java_objectheader *builtin_new(classinfo *c)
 
 
 
-/******************** function: builtin_anewarray ****************************
 
-       Creates an array of pointers to objects on the heap.
-       Parameters:
-               size ......... number of elements
-       elementtype .. pointer to the classinfo structure for the element type
-       
-       Return value:  pointer to the array or NULL if no memory is available
-
-*****************************************************************************/
-
-static
-void* __builtin_newarray(s4 base_size,
-                                                s4 size, 
-                                                bool references,
-                                                int elementsize,
-                                                int arraytype,
-                                                classinfo *el)
+java_arrayheader *builtin_newarray(s4 size,vftbl *arrayvftbl)
 {
-       java_arrayheader *a;
-
-#ifdef SIZE_FROM_CLASSINFO
-       s4 alignedsize = align_size(base_size + (size-1) * elementsize);
-       a = heap_allocate(alignedsize, references, NULL);
-#else  
-       a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize, 
-                                         references, 
-                                         NULL);
-#endif
-       if (!a) return NULL;
+        /* XXX remove log */
+        /*
+        sprintf(logtext,"newarray size=%d class=",size);
+        utf_sprint(logtext+strlen(logtext),arrayvftbl->class->name);
+        dolog();
+        */
+
+        java_arrayheader *a;
+        arraydescriptor *desc = arrayvftbl->arraydesc;
+        s4 dataoffset = desc->dataoffset;
+        s4 componentsize = desc->componentsize;
 
 #ifdef SIZE_FROM_CLASSINFO
-       memset(a, 0, alignedsize);
+        s4 actualsize = align_size(dataoffset + size * componentsize);
 #else
-       memset(a, 0, base_size + (size-1) * elementsize);
-#endif 
-
-#if 0
-       {
-               classinfo *c;
-
-               switch (arraytype) {
-               case ARRAYTYPE_INT:
-                       c = create_array_class(utf_new_char("[I"));
-                       use_class_as_object(c, "int");
-                       break;
-
-               case ARRAYTYPE_LONG:
-                       c = create_array_class(utf_new_char("[J"));
-                       use_class_as_object(c, "long");
-                       break;
-
-               case ARRAYTYPE_FLOAT:
-                       c = create_array_class(utf_new_char("[F"));
-                       use_class_as_object(c, "float");
-                       break;
-
-               case ARRAYTYPE_DOUBLE:
-                       c = create_array_class(utf_new_char("[D"));
-                       use_class_as_object(c, "double");
-                       break;
-
-               case ARRAYTYPE_BYTE:
-                       c = create_array_class(utf_new_char("[B"));
-                       use_class_as_object(c, "byte");
-                       break;
-
-               case ARRAYTYPE_CHAR:
-                       c = create_array_class(utf_new_char("[C"));
-                       use_class_as_object(c, "char");
-                       break;
-
-               case ARRAYTYPE_SHORT:
-                       c = create_array_class(utf_new_char("[S"));
-                       use_class_as_object(c, "short");
-                       break;
-
-               case ARRAYTYPE_BOOLEAN:
-                       c = create_array_class(utf_new_char("[Z"));
-                       use_class_as_object(c, "boolean");
-                       break;
-
-               case ARRAYTYPE_OBJECT:
-                       {
-                               char *cname, *buf;
-                               cname = heap_allocate(utf_strlen(el->name), false, NULL);
-                               utf_sprint(cname, el->name);
-                               buf = heap_allocate(strlen(cname) + 3, false, NULL);
-                               /*  printf("\n\n[L%s;\n\n", cname); */
-                               sprintf(buf, "[L%s;", cname);
-                               c = create_array_class(utf_new_char(buf));
-                               /*              MFREE(buf, char, strlen(cname) + 3); */
-                               /*              MFREE(cname, char, utf_strlen(el->name)); */
-                               use_class_as_object(c, cname);
-                       }
-                       break;
-
-               case ARRAYTYPE_ARRAY:
-                       c = create_array_class(utf_new_char("[["));
-                       use_class_as_object(c, "java/lang/Boolean");
-                       break;
+        s4 actualsize = dataoffset + size * componentsize;
+#endif
+        a = (java_arrayheader *)
+                heap_allocate(actualsize,
+                                          (desc->arraytype == ARRAYTYPE_OBJECT),
+                                          NULL);
 
-               default:
-                       panic("unknown array type");
-               }
+        if (!a) return NULL;
+        memset(a,0,actualsize);
 
-               a->objheader.vftbl = c->vftbl;
-       }
-#else
-       a->objheader.vftbl = class_array->vftbl;
-#endif
-       a->size = size;
+        a->objheader.vftbl = arrayvftbl;
+        a->size = size;
 #ifdef SIZE_FROM_CLASSINFO
-       a->alignedsize = alignedsize;
+        a->alignedsize = actualsize;
 #endif
-       a->arraytype = arraytype;
-
-       return a;
+        return a;
 }
 
+java_objectarray *
+builtin_anewarray(s4 size,classinfo *component)
+{
+       return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
+}
 
-java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
+/* XXX delete */
+#if 0
+java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
 {
        java_objectarray *a;    
        a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
@@ -562,8 +712,7 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
        a->elementtype = elementtype;
        return a;
 }
-
-
+#endif
 
 /******************** function: builtin_newarray_array ***********************
 
@@ -577,8 +726,10 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
 
 *****************************************************************************/
 
-java_arrayarray *builtin_newarray_array(s4 size, 
-                                                                               constant_arraydescriptor *elementdesc)
+/* XXX delete */
+#if 0
+java_arrayarray *builtin_newarray_array 
+               (s4 size, constant_arraydescriptor *elementdesc)
 {
        java_arrayarray *a; 
        a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
@@ -592,6 +743,7 @@ java_arrayarray *builtin_newarray_array(s4 size,
        a->elementdescriptor = elementdesc;
        return a;
 }
+#endif
 
 
 /******************** function: builtin_newarray_boolean ************************
@@ -603,7 +755,9 @@ java_arrayarray *builtin_newarray_array(s4 size,
 
 *****************************************************************************/
 
-java_booleanarray *builtin_newarray_boolean(s4 size)
+/* XXX delete */
+#if 0
+java_booleanarray *builtin_newarray_boolean (s4 size)
 {
        java_booleanarray *a;   
        a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
@@ -614,6 +768,47 @@ java_booleanarray *builtin_newarray_boolean(s4 size)
                                                                                           NULL);
        return a;
 }
+#endif
+
+java_intarray *builtin_newarray_int (s4 size)
+{
+       return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
+}
+
+java_longarray *builtin_newarray_long (s4 size)
+{
+       return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
+}
+
+java_floatarray *builtin_newarray_float (s4 size)
+{
+       return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
+}
+
+java_doublearray *builtin_newarray_double (s4 size)
+{
+       return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
+}
+
+java_bytearray *builtin_newarray_byte (s4 size)
+{
+       return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
+}
+
+java_chararray *builtin_newarray_char (s4 size)
+{
+       return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
+}
+
+java_shortarray *builtin_newarray_short (s4 size)
+{
+       return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
+}
+
+java_booleanarray *builtin_newarray_boolean (s4 size)
+{
+       return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
+}
 
 /******************** function: builtin_newarray_char ************************
 
@@ -623,7 +818,9 @@ java_booleanarray *builtin_newarray_boolean(s4 size)
 
 *****************************************************************************/
 
-java_chararray *builtin_newarray_char(s4 size)
+/* XXX delete */
+#if 0
+java_chararray *builtin_newarray_char (s4 size)
 {
        java_chararray *a;      
        a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
@@ -644,7 +841,8 @@ java_chararray *builtin_newarray_char(s4 size)
 
 *****************************************************************************/
 
-java_floatarray *builtin_newarray_float(s4 size)
+/* XXX delete */
+java_floatarray *builtin_newarray_float (s4 size)
 {
        java_floatarray *a; 
        a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
@@ -665,7 +863,7 @@ java_floatarray *builtin_newarray_float(s4 size)
 
 *****************************************************************************/
 
-java_doublearray *builtin_newarray_double(s4 size)
+java_doublearray *builtin_newarray_double (s4 size)
 {
        java_doublearray *a;    
        a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
@@ -688,7 +886,8 @@ java_doublearray *builtin_newarray_double(s4 size)
 
 *****************************************************************************/
 
-java_bytearray *builtin_newarray_byte(s4 size)
+/* XXX delete */
+java_bytearray *builtin_newarray_byte (s4 size)
 {
        java_bytearray *a;      
        a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
@@ -709,6 +908,7 @@ java_bytearray *builtin_newarray_byte(s4 size)
 
 *****************************************************************************/
 
+/* XXX delete */
 java_shortarray *builtin_newarray_short(s4 size)
 {
        java_shortarray *a; 
@@ -730,6 +930,8 @@ java_shortarray *builtin_newarray_short(s4 size)
 
 *****************************************************************************/
 
+<<<<<<< builtin.c
+/* XXX delete */
 java_intarray *builtin_newarray_int(s4 size)
 {
        java_intarray *a;       
@@ -758,6 +960,8 @@ java_intarray *builtin_newarray_int(s4 size)
 
 *****************************************************************************/
 
+<<<<<<< builtin.c
+/* XXX delete */
 java_longarray *builtin_newarray_long(s4 size)
 {
        java_longarray *a;      
@@ -771,7 +975,7 @@ java_longarray *builtin_newarray_long(s4 size)
 }
 
 
-
+/* XXX delete */
 /***************** function: builtin_multianewarray ***************************
 
        Creates a multi-dimensional array on the heap. The dimensions are passed in
@@ -784,6 +988,7 @@ java_longarray *builtin_newarray_long(s4 size)
 
        /* Helper functions */
 
+/* XXX delete */
 static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
                                                                                         constant_arraydescriptor *desc)
 {
@@ -841,7 +1046,7 @@ static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
        return (java_arrayheader*) a;
 }
 
-
+/* XXX delete */
 java_arrayheader *builtin_multianewarray(java_intarray *dims,
                                                                                 constant_arraydescriptor *desc)
 {
@@ -906,15 +1111,62 @@ static java_arrayheader *nmultianewarray_part(int n, long *dims, int thisdim,
                
        return (java_arrayheader*) a;
 }
+#endif
+
+/**************** function: builtin_nmultianewarray ***************************
+
+       Creates a multi-dimensional array on the heap. The dimensions are passed in
+       an array of longs.
+
+    Arguments:
+        n............number of dimensions to create
+        arrayvftbl...vftbl of the array class
+        dims.........array containing the size of each dimension to create
 
+       Return value:  pointer to the array or NULL if no memory is available
+
+******************************************************************************/
+
+java_arrayheader *builtin_nmultianewarray (int n,
+                                                                                  vftbl *arrayvftbl, long *dims)
+{
+       int size, i;
+       java_arrayheader *a;
+       vftbl *componentvftbl;
+
+       /* create this dimension */
+       size = (int) dims[0];
+       a = builtin_newarray(size,arrayvftbl);
+       if (!a) return NULL;
+
+       /* if this is the last dimension return */
+       if (!--n) return a;
+
+       /* get the vftbl of the components to create */
+       componentvftbl = arrayvftbl->arraydesc->componentvftbl;
+       if (!componentvftbl) /* XXX the verifier could check this */
+               panic ("multianewarray with too many dimensions");
 
+       /* create the component arrays */
+       for (i = 0; i < size; i++) {
+               java_arrayheader *ea = 
+                       builtin_nmultianewarray(n,componentvftbl,dims+1);
+               if (!ea) return NULL;
+               ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
+       }
+
+       return a;
+}
+
+/* XXX delete */
+#if 0
 java_arrayheader *builtin_nmultianewarray (int size,
                                                                                   constant_arraydescriptor *desc, long *dims)
 {
        (void) builtin_newarray_int(size); /* for compatibility with -old */
        return nmultianewarray_part (size, dims, 0, desc);
 }
-
+#endif
 
 
 
@@ -929,6 +1181,8 @@ java_arrayheader *builtin_nmultianewarray (int size,
 
 *****************************************************************************/
 
+/* XXX delete */
+#if 0
 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
 {
        if (builtin_canstore(a,o)) {
@@ -937,7 +1191,7 @@ s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
        }
        return 0;
 }
-
+#endif
 
 
 
@@ -963,7 +1217,23 @@ java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
                methodindent--;
        if (verbose || runverbose) {
                printf("Exception ");
-               utf_display (exceptionptr->vftbl->class->name);
+               if (exceptionptr) {
+                       utf_display (exceptionptr->vftbl->class->name);
+               }
+               else {
+                       printf("Error: <Nullpointer instead of exception>");
+                       if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
+                       if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
+                       if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
+                       if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
+                       if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
+                       if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
+                       if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
+                       if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
+
+               }
                printf(" thrown in ");
                if (method) {
                        utf_display (method->class->name);
@@ -990,6 +1260,7 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
 #endif
                                                methodinfo *method)
 {
+
        int i;
        for (i = 0; i < methodindent; i++)
                logtext[i] = '\t';
@@ -1104,9 +1375,9 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
 #endif
 #endif
        }
-       sprintf(logtext + strlen(logtext), ")");
+       sprintf (logtext+strlen(logtext), ")");
+       dolog ();
 
-       dolog();
        methodindent++;
 }
 #endif
@@ -1281,7 +1552,7 @@ void builtin_monitorenter(java_objectheader *o)
        ++blockInts;
 
        hashValue = MUTEX_HASH_VALUE(o);
-       if (mutexHashTable[hashValue].object == o
+       if (mutexHashTable[hashValue].object == o 
                && mutexHashTable[hashValue].mutex.holder == currentThread)
                ++mutexHashTable[hashValue].mutex.count;
        else
@@ -1862,6 +2133,11 @@ float builtin_d2f(double a)
 }
 
 
+java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
+        return Java_java_lang_VMObject_clone ( 0 ,  0, o);
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 0afdbf45137a27d7474916e94de1d0d5838cf21c..98bb11cd92e5b50eeecb17656a6f91a9ba0ce782 100644 (file)
--- a/builtin.h
+++ b/builtin.h
@@ -26,14 +26,16 @@ extern java_objectheader* exceptionptr;
 
 s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
 s4 builtin_isanysubclass (classinfo *sub, classinfo *super);
+s4 builtin_isanysubclass_vftbl (vftbl *sub, vftbl *super);
 s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
 s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc);
-#if defined(__I386__)
-s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class);
+
+s4 builtin_arrayinstanceof(java_objectheader *obj, arraydescriptor *desc);
+#ifdef __I386__
+s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class); /* XXX ? */
 #endif
-s4 builtin_checkarraycast(java_objectheader *obj, constant_arraydescriptor *desc);
-s4 asm_builtin_checkarraycast(java_objectheader *obj, constant_arraydescriptor *desc);
+s4 builtin_checkarraycast(java_objectheader *obj, arraydescriptor *desc);
+s4 asm_builtin_checkarraycast(java_objectheader *obj, arraydescriptor *desc);
 
 java_objectheader *builtin_throw_exception (java_objectheader *exception);
 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
@@ -42,12 +44,11 @@ java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
 java_objectheader *builtin_new (classinfo *c);
 
 
-java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype);
+java_arrayheader *builtin_newarray (s4 size, vftbl *arrayvftbl);
+java_objectarray *builtin_anewarray (s4 size, classinfo *component);
 #ifdef __I386__
-void asm_builtin_anewarray (s4 size, classinfo *elementtype);
-void asm_builtin_newarray_array (s4 size, constant_arraydescriptor *elementdesc);
+void asm_builtin_newarray (s4 size, vftbl *arrayvftbl);
 #endif
-java_arrayarray *builtin_newarray_array (s4 size, constant_arraydescriptor *elementdesc);
 java_booleanarray *builtin_newarray_boolean (s4 size);
 java_chararray *builtin_newarray_char (s4 size);
 java_floatarray *builtin_newarray_float (s4 size);
@@ -56,13 +57,10 @@ java_bytearray *builtin_newarray_byte (s4 size);
 java_shortarray *builtin_newarray_short (s4 size);
 java_intarray *builtin_newarray_int (s4 size);
 java_longarray *builtin_newarray_long (s4 size);
-java_arrayheader *builtin_multianewarray (java_intarray *dims,
-                       constant_arraydescriptor *desc);
-java_arrayheader *builtin_nmultianewarray (int size,
-                      constant_arraydescriptor *desc, long *dims);
+java_arrayheader *builtin_nmultianewarray (int n,
+                                           vftbl *arrayvftbl, long *dims);
 
 s4 builtin_canstore (java_objectarray *a, java_objectheader *o);
-s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
 void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
 
 #ifdef TRACE_ARGS_NUM
@@ -142,6 +140,8 @@ s8       asm_builtin_d2l (double a);
 
 float    builtin_d2f (double a);
 
+java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o);
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
index ba484df7237eafc8f07f908c0c98376d19751fb8..f679dd19ef39f7e1705e64041febf48b6f1e0891 100644 (file)
@@ -122,7 +122,7 @@ fi
 dnl Features
 
 dnl check arguments
-AC_ARG_ENABLE(threads, [  --enable-threads        enable threads support])
+AC_ARG_ENABLE(threads, [  --enable-threads        enable threads support [default yes]])
 
 dnl threads
 AC_MSG_CHECKING(whether to include threads support)
@@ -144,6 +144,106 @@ fi
 dnl now configure boehm gc
 AC_CONFIG_SUBDIRS(mm/boehm-gc)
 
+
+AC_ARG_WITH(classcompiler, [  --with-classcompiler[=ARG]         compiler for creating classpath  [jikes,javac13,complang] [default=javac13]])
+
+dnl java compiler
+AC_MSG_CHECKING(which java compiler to use to use)
+case "$with_classcompiler" in
+jikes )
+        AC_MSG_RESULT(jikes (good luck, doesn't seem to really work))
+        CCOMP="jikes"
+        ;;
+complang )
+        AC_MSG_RESULT(complang, make sure that CLASSPATH is set correctly)
+       CCOMP="complang"
+        ;;
+* | "")
+       AC_MSG_RESULT(javac13 (with -target 1.1))
+       CCOMP="javac13complang"
+       ;;
+esac
+
+
+dnl check if zlib should be used
+AC_ARG_ENABLE(zlib, [ --enable-zlib            enable zip archive class storage (experimental), needs zlib [default no]])
+
+AC_MSG_CHECKING(whether zip archives should be supported)
+if test x"$enable_zlib" = "xyes"; then
+       ZIP_LIBS=-lz
+       ZIP_C=unzip.c
+       AC_DEFINE(USE_ZLIB)
+       AC_MSG_RESULT(yes)
+
+else
+       ZIP_LIBS=""
+       ZIP_C=""
+       AC_MSG_RESULT(no)
+
+fi
+AC_SUBST(ZIP_LIBS)
+AC_SUBST(ZIP_C)
+
+dnl check arguments
+AC_ARG_ENABLE(gtkpeer, [  --enable-gtkpeer        enable threads support [default no]])
+
+dnl threads
+AC_MSG_CHECKING(whether to use gtk awt peers)
+if test x"$enable_gtkpeer" = "xyes"; then
+       AC_MSG_RESULT(yes)
+       AWTPEERS="java.awt.peer.ComponentPeer \
+               java.awt.peer.MenuPeer \
+               java.awt.peer.MenuItemPeer \
+               gnu.java.awt.peer.gtk.GdkPixbufDecoder \
+               gnu.java.awt.peer.gtk.GtkMenuBarPeer \
+               gnu.java.awt.peer.gtk.GtkScrollPanePeer \
+               gnu.java.awt.peer.gtk.GtkMenuPeer \
+               gnu.java.awt.peer.gtk.GtkTextComponentPeer \
+               gnu.java.awt.peer.gtk.GtkComponentPeer \
+               gnu.java.awt.peer.gtk.GtkPopupMenuPeer \
+               gnu.java.awt.peer.gtk.GtkCheckboxGroupPeer \
+               gnu.java.awt.peer.gtk.GtkMenuItemPeer \
+               gnu.java.awt.peer.gtk.GdkGraphics \
+               gnu.java.awt.peer.gtk.GtkToolkit \
+               gnu.java.awt.peer.gtk.GtkCanvasPeer \
+               gnu.java.awt.peer.gtk.GtkFramePeer \
+               gnu.java.awt.peer.gtk.GdkFontMetrics \
+               gnu.java.awt.peer.gtk.GtkScrollbarPeer \
+               gnu.java.awt.peer.gtk.GtkGenericPeer \
+               gnu.java.awt.peer.gtk.GtkListPeer \
+               gnu.java.awt.peer.gtk.GtkLabelPeer \
+               gnu.java.awt.peer.gtk.GtkTextAreaPeer \
+               gnu.java.awt.peer.gtk.GtkCheckboxPeer \
+               gnu.java.awt.peer.gtk.GtkFileDialogPeer \
+               gnu.java.awt.peer.gtk.GtkImagePainter \
+               gnu.java.awt.peer.gtk.GtkChoicePeer \
+               gnu.java.awt.peer.gtk.GtkPanelPeer \
+               gnu.java.awt.peer.gtk.GtkMainThread \
+               gnu.java.awt.peer.gtk.GtkButtonPeer \
+               gnu.java.awt.peer.gtk.GtkTextFieldPeer \
+               gnu.java.awt.peer.gtk.GtkCheckboxMenuItemPeer \
+               gnu.java.awt.peer.gtk.GtkClipboard \
+               gnu.java.awt.peer.gtk.GtkWindowPeer"
+               AWT_OBJS="classpathbin/$ARCH_DIR/native/jni/gtk-peer/.libs/libgtkpeer.a \
+                       -lgtk-x11-2.0 -lgdk-x11-2.0 -latk-1.0 -lgdk_pixbuf-2.0 -lm -lpangoxft-1.0 \
+                       -lpangox-1.0 -lpango-1.0 -lgobject-2.0 -lgmodule-2.0 -ldl -lglib-2.0 \
+                       -lgthread-2.0 -lart_lgpl_2"
+               USEGTK=yes
+               AC_SUBST(USEGTK)
+               AC_SUBST(AWTPEERS)
+               AC_SUBST(AWT_OBJS)
+               AC_DEFINE(USE_GTK)
+
+else
+       AWT_OBJS=
+       AWTPEERS=
+       USEGTK=no
+       AC_SUBST(USEGTK)
+       AC_SUBST(AWTPEERS)
+       AC_SUBST(AWT_OBJS)
+       AC_MSG_RESULT(no)
+fi
+
 AC_OUTPUT(Makefile \
           mm/Makefile \
          toolbox/Makefile \
@@ -159,4 +259,19 @@ AC_OUTPUT(Makefile \
           doc/Makefile \
          tst/Makefile \
          tst/kaffe/Makefile \
-         jvmtst/Makefile )
+         jvmtst/Makefile \
+          classpathbin/Makefile)
+
+
+cd classpathbin/$ARCH_DIR
+echo "========================================================================"
+echo "calling: ../../gnuclasspath/configure --prefix=$prefix/classpath --with-$CCOMP=yes --enable-jni=yes --enable-gtk-peer=$USEGTK --enable-shared=no --enable-static=yes --with-zip=no --enable-portable-native-sync"
+echo "========================================================================"
+
+../../gnuclasspath/configure --prefix=$prefix/classpath --with-$CCOMP=yes \
+        --enable-jni=yes --enable-gtk-peer=$USEGTK --enable-shared=no --enable-static=yes --with-zip=no \
+       --enable-portable-native-sync
+cd ../..
+
+
+
index 8f444cd832da8bb3536fa2af3a9578ad66d30822..6b8cee2828a3e2b403002b5ae656bb8064eaf5a8 100644 (file)
--- a/global.h
+++ b/global.h
@@ -30,7 +30,7 @@
    Changes: Mark Probst
             Philipp Tomsich
 
-   $Id: global.h 655 2003-11-20 14:52:00Z carolyn $
+   $Id: global.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
  */
 #define SIZE_FROM_CLASSINFO
 
+/* standard includes **********************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "toolbox/memory.h"
+#include "toolbox/chain.h"
+#include "toolbox/list.h"
+#include "toolbox/loging.h"
+
+/* system dependent types *****************************************************/
+
+#include "types.h"
+
 
 /* additional data types ******************************************************/
 
@@ -65,6 +81,19 @@ typedef int   bool;             /* boolean data type */
 
 #define PRIMITIVETYPE_COUNT  9  /* number of primitive types */
 
+/* CAUTION: Don't change the numerical values! These constants are
+ * used as indices into the primitive type table.
+ */
+#define PRIMITIVETYPE_INT     0
+#define PRIMITIVETYPE_LONG    1
+#define PRIMITIVETYPE_FLOAT   2
+#define PRIMITIVETYPE_DOUBLE  3
+#define PRIMITIVETYPE_BYTE    4
+#define PRIMITIVETYPE_CHAR    5
+#define PRIMITIVETYPE_SHORT   6
+#define PRIMITIVETYPE_BOOLEAN 7
+#define PRIMITIVETYPE_VOID    8
+
 typedef void (*functionptr) (); /* generic function pointer */
 
 
@@ -104,7 +133,6 @@ void cacao_shutdown(s4 status);
 #define CONSTANT_NameAndType          12
 #define CONSTANT_Utf8                  1
 
-#define CONSTANT_Arraydescriptor      13
 #define CONSTANT_UNUSED                0
 
 #define ACC_PUBLIC                0x0001
@@ -118,7 +146,7 @@ void cacao_shutdown(s4 status);
 #define ACC_NATIVE                0x0100
 #define ACC_INTERFACE             0x0200
 #define ACC_ABSTRACT              0x0400
-
+#define ACC_STRICT               0x0800
 
 /* resolve typedef cycles *****************************************************/
 
@@ -130,6 +158,7 @@ typedef struct vftbl vftbl;
 typedef u1* methodptr;
 typedef struct fieldinfo  fieldinfo; 
 typedef struct methodinfo methodinfo; 
+typedef struct arraydescriptor arraydescriptor;
 
 
 /* constant pool entries *******************************************************
@@ -151,7 +180,6 @@ typedef struct methodinfo methodinfo;
     CONSTANT_Double              constant_double                    yes
     CONSTANT_NameAndType         constant_nameandtype               yes
     CONSTANT_Utf8                unicode                             no
-    CONSTANT_Arraydescriptor     constant_arraydescriptor           yes
     CONSTANT_UNUSED              -
 
 *******************************************************************************/
@@ -224,6 +252,16 @@ struct literalstring {
 };
 
 
+/* data structure for calls from c code to java methods */
+
+struct jni_callblock {
+       u1 itemtype;
+       u8 item;
+};
+
+typedef struct jni_callblock jni_callblock;
+
+
 /* data structure for accessing hashtables ************************************/
 
 typedef struct {            
@@ -276,11 +314,14 @@ typedef struct {            /* NameAndType (Field or Method)                  */
    types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY).
 */
 
+/* XXX delete */
+#if 0
 typedef struct constant_arraydescriptor {
        int arraytype;
        classinfo *objectclass;
        struct constant_arraydescriptor *elementdescriptor;
 } constant_arraydescriptor;
+#endif
 
 
 /* data structures of the runtime system **************************************/
@@ -300,21 +341,24 @@ struct java_objectheader {              /* header for all objects             */
 /* arrays **********************************************************************
 
        All arrays are objects (they need the object header with a pointer to a
-       vvftbl (array class table). There is only one class for all arrays. The
+       vvftbl (array class table). There is only one class for all arrays. The    XXX change
        type of an array is stored directly in the array object. Following types
        are defined:
 */
 
-#define ARRAYTYPE_INT      0
-#define ARRAYTYPE_LONG     1
-#define ARRAYTYPE_FLOAT    2
-#define ARRAYTYPE_DOUBLE   3
-#define ARRAYTYPE_BYTE     4
-#define ARRAYTYPE_CHAR     5
-#define ARRAYTYPE_SHORT    6
-#define ARRAYTYPE_BOOLEAN  7
-#define ARRAYTYPE_OBJECT   8
-#define ARRAYTYPE_ARRAY    9
+/* CAUTION: Don't change the numerical values! These constants (with
+ * the exception of ARRAYTYPE_OBJECT) are used as indices in the
+ * primitive type table.
+ */
+#define ARRAYTYPE_INT      PRIMITIVETYPE_INT
+#define ARRAYTYPE_LONG     PRIMITIVETYPE_LONG
+#define ARRAYTYPE_FLOAT    PRIMITIVETYPE_FLOAT
+#define ARRAYTYPE_DOUBLE   PRIMITIVETYPE_DOUBLE
+#define ARRAYTYPE_BYTE     PRIMITIVETYPE_BYTE
+#define ARRAYTYPE_CHAR     PRIMITIVETYPE_CHAR
+#define ARRAYTYPE_SHORT    PRIMITIVETYPE_SHORT
+#define ARRAYTYPE_BOOLEAN  PRIMITIVETYPE_BOOLEAN
+#define ARRAYTYPE_OBJECT   PRIMITIVETYPE_VOID     /* don't use as index! */
 
 typedef struct java_arrayheader {       /* header for all arrays              */
        java_objectheader objheader;        /* object header                      */
@@ -322,7 +366,6 @@ typedef struct java_arrayheader {       /* header for all arrays              */
 #ifdef SIZE_FROM_CLASSINFO
        s4 alignedsize; /* phil */
 #endif
-       s4 arraytype;                       /* array type from previous list      */
 } java_arrayheader;
 
 
@@ -377,16 +420,17 @@ typedef struct java_longarray {
 
 typedef struct java_objectarray {
        java_arrayheader header;
-       classinfo *elementtype;
        java_objectheader *data[1];
 } java_objectarray;
 
+/* XXX delete */
+#if 0
 typedef struct java_arrayarray {
        java_arrayheader header;
        constant_arraydescriptor *elementdescriptor;
        java_arrayheader *data[1];
 } java_arrayarray;
-
+#endif
 
 /* structure for primitive classes ********************************************/
 
@@ -396,6 +440,9 @@ typedef struct primitivetypeinfo {
        char *wrapname;                      /* name of class for wrapping        */
        char typesig;                        /* one character type signature      */
        char *name;                          /* name of primitive class           */
+       char *arrayname;                     /* name of primitive array class     */
+       classinfo *arrayclass;               /* primitive array class             */
+       vftbl *arrayvftbl;                   /* vftbl of primitive array class    */
 } primitivetypeinfo;
 
 
@@ -530,6 +577,15 @@ typedef struct innerclassinfo {
 
 struct classinfo {                /* class structure                          */
        java_objectheader header;     /* classes are also objects                 */
+       java_objectarray* signers;
+       struct java_security_ProtectionDomain* pd;
+       struct java_lang_VMClass* vmClass;
+       struct java_lang_reflect_Constructor* constructor;
+
+
+        s4 initializing_thread; /* gnu classpath*/
+        s4 erroneous_state; /* gnu classpath*/
+        struct gnu_classpath_RawData* vmData; /* gnu classpath*/
 
        s4          flags;            /* ACC flags                                */
        utf        *name;             /* class name                               */ 
@@ -578,6 +634,9 @@ struct classinfo {                /* class structure                          */
        classSetNode *impldBy;          /* implemented by class set */
 };
 
+/* check if class is an array class. Only use for linked classes! */
+#define CLASS_IS_ARRAY(clsinfo)  (clsinfo->vftbl->arraydesc != NULL)
+
 
 /* virtual function table ******************************************************
 
@@ -640,10 +699,13 @@ struct vftbl {
 
        classinfo   *class;                /* class, the vtbl belongs to          */
 
+       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
+
        s4           vftbllength;          /* virtual function table length       */
        s4           interfacetablelength; /* interface table length              */
 
        s4           baseval;              /* base for runtime type check         */
+                                          /* (-index for interfaces)             */
        s4           diffval;              /* high - base for runtime type check  */
 
        s4          *interfacevftbllength; /* length of interface vftbls          */
@@ -654,10 +716,31 @@ struct vftbl {
 #define VFTBLINTERFACETABLE(v,i)       (v)->interfacetable[-i]
 
 
+/* arraydescriptor ************************************************************
+
+    For every array class an arraydescriptor is allocated which
+    describes the array class.
+       The arraydescriptor is referenced from the vftbl of the array
+       class.
+
+*******************************************************************************/
+
+struct arraydescriptor {
+       vftbl *componentvftbl;   /* vftbl of the component type, NULL for primit. */
+       vftbl *elementvftbl;     /* vftbl of the element type, NULL for primitive */
+       short  arraytype;        /* ARRAYTYPE_* constant                          */
+       short  dimension;        /* dimension of the array (always >= 1)          */
+    s4     dataoffset;       /* offset of the array data from object pointer  */
+       s4     componentsize;    /* size of a component in bytes                  */
+};
+
 /* references to some system classes ******************************************/
 
 extern classinfo *class_java_lang_Object;
 extern classinfo *class_java_lang_String;
+extern classinfo *class_java_lang_Throwable;
+extern classinfo *class_java_lang_Cloneable;
+extern classinfo *class_java_io_Serializable;
 extern classinfo *class_java_lang_ClassCastException;
 extern classinfo *class_java_lang_NullPointerException;
 extern classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
@@ -666,7 +749,9 @@ extern classinfo *class_java_lang_OutOfMemoryError;
 extern classinfo *class_java_lang_ArithmeticException;
 extern classinfo *class_java_lang_ArrayStoreException;
 extern classinfo *class_java_lang_ThreadDeath;
-extern classinfo *class_array;
+extern classinfo *pseudo_class_Arraystub;
+extern classinfo *pseudo_class_Null;
+extern vftbl *pseudo_class_Arraystub_vftbl;
 
 /* instances of some system classes *******************************************/
 
@@ -712,10 +797,47 @@ extern int count_utf_new_found;
 
 /* table of primitive types ***************************************************/
 
+/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_
+ * constants (except ARRAYTYPE_OBJECT).
+ */
 extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
 
-#endif /* _GLOBAL_H */
 
+/* macros for descriptor parsing **********************************************/
+
+/* utf_ptr must point to the 'L' or the '[' of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * CAUTION: This macro does not check for an unexpected end of the
+ * descriptor.
+ */
+#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                           \
+            { while (*(utf_ptr)=='[') (utf_ptr)++;                      \
+              if (*(utf_ptr)++=='L')                                            \
+                  while(*(utf_ptr)++ != ';') /* skip */; }
+/* Input:
+ *     utf_ptr....points to first char of descriptor
+ *     end_ptr....points to first char after the end of the string
+ *     errorflag..must be initialized (to false) by the caller!
+ * Output:
+ *     utf_ptr....points to first char after the descriptor
+ *     errorflag..set to true if the string ended unexpectedly
+ */
+#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                                                    \
+            { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;                    \
+              if ((utf_ptr) == (end_ptr))                                                        \
+                  (errorflag) = true;                                                            \
+              else                                                                                   \
+                      if (*(utf_ptr)++=='L') {                                                        \
+                      while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';') /* skip */;  \
+                      if ((utf_ptr)[-1] != ';')                                          \
+                          (errorflag) = true; }}
+
+
+extern classinfo *class_array;
+
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 6c3bfb2b2eeb6121e9b30e6e7c63c70e48a30fe6..c78c767aec7a24afb786dfaef0c8eec690710e2a 100644 (file)
--- a/headers.c
+++ b/headers.c
@@ -29,7 +29,7 @@
    Changes: Mark Probst
             Philipp Tomsich
 
-   $Id: headers.c 583 2003-11-09 19:14:31Z twisti $
+   $Id: headers.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -55,7 +55,14 @@ java_objectheader *javastring_new (utf *text)         /* schani */
 
 void throw_classnotfoundexception() 
 { 
-       panic("class not found"); 
+       panic("class not found----------"); 
+}
+/*  */
+void throw_classnotfoundexception2(utf* classname) 
+{ 
+       sprintf (logtext, "Loading class: ");
+        utf_sprint (logtext+strlen(logtext), classname);
+       panic("******class not found"); 
 }
 
 java_objectheader *literalstring_new (utf *u)
@@ -82,13 +89,14 @@ s8 asm_builtin_d2l(double a) { return 0; }
 void asm_builtin_monitorenter(java_objectheader *o) {}
 void asm_builtin_monitorexit(java_objectheader *o) {}
 
-s4 asm_builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *d) {return 0;}
+s4 asm_builtin_checkarraycast(java_objectheader *o,arraydescriptor *d) {return 0;}
 
 #if defined(__I386__)
 s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class) { return 0; }
-void asm_builtin_anewarray(s4 size, classinfo *elementtype) {}
-void asm_builtin_newarray_array(s4 size, constant_arraydescriptor *elementdesc) {}
+
+void asm_builtin_newarray (s4 size, vftbl *arrayvftbl) {}
 #endif
+
 void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o) {}
 
 u1 *createcompilerstub(methodinfo *m) {return NULL;}
@@ -310,7 +318,11 @@ static void printmethod (methodinfo *m)
                printID (m->class->name);
                fprintf (file, "* this ");
 
-       };
+           } 
+       else
+           {
+               fprintf (file, ", jclass clazz ");
+           }
 
        if ((*utf_ptr)!=')') fprintf (file, ", "); 
                        
@@ -326,24 +338,17 @@ static void printmethod (methodinfo *m)
 
 /****************** remove package-name in fully-qualified classname *********************/
 
-static void simple_classname(char *buffer, utf *u)
+static void gen_header_filename(char *buffer, utf *u)
 {
-       int i, simplename_start;
-
-       for (i=utf_strlen(u)-1; i>=0; i--) { 
-
-               if (u->text[i] == '$') u->text[i] = '_'; else /* convert '$' to '_' */
-                       if (u->text[i] == '/') {
-                               /* beginning of simple name */
-                               simplename_start = i+1;
-                               break;
-                       }
-       }
-
-       for (i=simplename_start; i < utf_strlen(u); i++) 
-               buffer[i-simplename_start] = u->text[i];
-
-       buffer[i-simplename_start] = '\0';                
+  int i, simplename_start;
+  int slash_cnt=0;
+
+  
+  for (i=0;i<utf_strlen(u);i++) {
+       if ((u->text[i] == '/') || (u->text[i] == '$')) buffer[i] = '_';  /* convert '$' and '/' to '_' */
+       else buffer[i]=u->text[i];
+  }
+  buffer[utf_strlen(u)]='\0';
 }
 
 /*********** create headerfile for classes and store native methods in chain ************/
@@ -359,7 +364,7 @@ static void headerfile_generate (classinfo *c)
        chain_addlast (nativeclass_chain, c);                                                           
                                
        /* open headerfile for class */
-       simple_classname(classname,c->name);                                                                                                                                            
+       gen_header_filename(classname,c->name);                                                                                                                                         
 
        /* create chain for renaming fields */
        ident_chain = chain_new ();
@@ -468,7 +473,7 @@ static void headers_finish ()
        while (c) {
        
                dopadding=false;
-               simple_classname(classname,c->name);                                                                                                                                                                                    
+               gen_header_filename(classname,c->name);                                                                                                                                                                                 
                fprintf(file,"#include \"nat/%s.h\"\n",classname);              
                c = chain_next (nativeclass_chain);             
        }
@@ -561,15 +566,19 @@ int main(int argc, char **argv)
        
        fprintf(file, "/* This file is machine generated, don't edit it !*/\n\n"); 
 
-       fprintf(file, "#define offobjvftbl    %3d\n", (int) OFFSET(java_objectheader, vftbl));
-       fprintf(file, "#define offarraysize   %3d\n", (int) OFFSET(java_arrayheader, size));
-       fprintf(file, "#define offobjarrdata  %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
-       fprintf(file, "#define offbaseval     %3d\n", (int) OFFSET(vftbl, baseval));
-       fprintf(file, "#define offdiffval     %3d\n", (int) OFFSET(vftbl, diffval));
+       fprintf (file, "#define offobjvftbl    %3d\n", (int) OFFSET(java_objectheader, vftbl));
+       fprintf (file, "#define offarraysize   %3d\n", (int) OFFSET(java_arrayheader, size));
+       fprintf (file, "#define offobjarrdata  %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
+       fprintf (file, "#define offbaseval     %3d\n", (int) OFFSET(vftbl, baseval));
+       fprintf (file, "#define offdiffval     %3d\n\n", (int) OFFSET(vftbl, diffval));
 
-       fclose(file);
+       fprintf (file, "#define offjniitemtype %3d\n", (int) OFFSET(jni_callblock, itemtype));
+       fprintf (file, "#define offjniitem     %3d\n", (int) OFFSET(jni_callblock, item));
+       fprintf (file, "#define sizejniblock   %3d\n\n", (int) sizeof(jni_callblock));
 
-       suck_init(classpath);
+       fclose (file);
+
+       suck_init (classpath);
    
        tables_init();
        heap_init(heapsize, heapsize, &dummy);
@@ -616,6 +625,13 @@ int main(int argc, char **argv)
 }
 
 
+void setVMClassField(classinfo *c)
+{
+}
+
+
+void* Java_java_lang_VMObject_clone ( void *env ,  void  *clazz, void * this){return 0;}
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
diff --git a/jni.c b/jni.c
index d504479b89f425c304ec0b481ab62735cb66e068..7730cd67b5667f9dd8cb73a08778a9651c26da5a 100644 (file)
--- a/jni.c
+++ b/jni.c
@@ -26,7 +26,7 @@
 
    Authors: ?
 
-   $Id: jni.c 557 2003-11-02 22:51:59Z twisti $
+   $Id: jni.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -37,6 +37,7 @@
 
 #define JNI_VERSION       0x00010002
 
+#include <jit/jit.h>
 
 /********************* accessing instance-fields **********************************/
 
 #define getField(obj,typ,var)     *((typ*) ((long int) obj + (long int) var->offset))
 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val); 
 
+
+
+u4 get_parametercount(methodinfo *m)
+{
+    utf  *descr    =  m->descriptor;    /* method-descriptor */
+    char *utf_ptr  =  descr->text;      /* current position in utf-text */
+    char *desc_end =  utf_end(descr);   /* points behind utf string     */
+    java_objectarray* result;
+    int parametercount = 0;
+   int i;
+
+    /* skip '(' */
+    utf_nextu2(&utf_ptr);
+
+    /* determine number of parameters */
+    while ( *utf_ptr != ')' ) {
+        get_type(&utf_ptr,desc_end,true);
+        parametercount++;
+    }
+
+    return parametercount;
+}
+
+
+
+void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char ret) {
+    char *utf__ptr  =  descr->text;      /* current position in utf-text */
+    char **utf_ptr  =  &utf__ptr;
+    char *desc_end =  utf_end(descr);   /* points behind utf string     */
+
+    int cnt;
+
+    jdouble d;
+    jlong l;
+    u4 dummy;
+    char c;
+       /*
+    log_text("fill_callblock");
+    utf_display(descr);
+    log_text("====");
+       */
+    /* skip '(' */
+    utf_nextu2(utf_ptr);
+
+    /* determine number of parameters */
+   if (obj) {
+          blk[0].itemtype=TYPE_ADR;
+          blk[0].item=(u8)(u4)obj;
+          cnt=1;
+   } else cnt=0;
+   while ( **utf_ptr != ')' ) {
+       if (*utf_ptr>=desc_end)
+               panic("illegal method descriptor");
+
+       switch (utf_nextu2(utf_ptr)) {
+       /* primitive types */
+             case 'B' :
+             case 'C' :
+             case 'S' : 
+             case 'Z' :
+                        blk[cnt].itemtype=TYPE_INT;
+                        blk[cnt].item=(u8) va_arg(data,int);
+                        break;
+             case 'I' :
+                        blk[cnt].itemtype=TYPE_INT;
+                        dummy=va_arg(data,u4);
+                        /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
+                        blk[cnt].item=(u8)dummy;
+
+                        break;
+
+             case 'J' : 
+                        blk[cnt].itemtype=TYPE_LNG;
+                        blk[cnt].item=(u8)va_arg(data,jlong);
+                                break;
+             case 'F' : 
+                        blk[cnt].itemtype=TYPE_FLT;
+                        *((jfloat*)(&blk[cnt].item))=((jfloat)va_arg(data,jdouble));
+                        break;
+
+             case 'D' : 
+                        blk[cnt].itemtype=TYPE_DBL;
+                        *((jdouble*)(&blk[cnt].item))=(jdouble)va_arg(data,jdouble);
+                        break;
+             case 'V' : panic ("V not allowed as function parameter");
+                        break;
+             case 'L' : {
+                           char *start = *utf_ptr;
+                           while (utf_nextu2(utf_ptr)!=';')
+
+                           blk[cnt].itemtype=TYPE_ADR;
+                           blk[cnt].item=(u8)(u4)va_arg(data,void*);
+                           break;                      
+                        }
+             case '[' : {
+                         /* XXX */
+                           /* arrayclass */
+                                   char *start = *utf_ptr;
+                           char ch;
+                           while ((ch = utf_nextu2(utf_ptr))=='[')
+                           if (ch == 'L') {
+                               while (utf_nextu2(utf_ptr)!=';') {}
+                                   }
+       
+                            ch=utf_nextu2(utf_ptr);
+                           blk[cnt].itemtype=TYPE_ADR;
+                           blk[cnt].item=(u8)(u4)va_arg(data,void*);
+                           break;                      
+                        }
+       }
+       cnt++;
+   }
+
+   /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
+   c=utf_nextu2(utf_ptr);
+   c=utf_nextu2(utf_ptr);
+   /*printf("%c  %c\n",ret,c);*/
+   if (ret=='O') {
+       if (!((c=='L') || (c=='['))) log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+   } else if (ret != c) log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+
+}
+
+
+
+jmethodID get_virtual(jobject obj,jmethodID methodID) {
+       if (obj->vftbl->class==methodID->class) return methodID;
+       return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
+}
+
+jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
+       if (clazz==methodID->class) return methodID;
+       return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
+}
+
+jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
+{      
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jobject ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+       
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,'O');
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+}
+
+
+/*core function for integer class methods (bool,byte,short,integer
+  This is basically needed for i386*/
+jint callIntegerMethod (jobject obj, jmethodID methodID, char retType, va_list args) {
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jint ret;
+
+/*     printf("%p,     %c\n",retType,methodID,retType);*/
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        
+       argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,retType);
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=(jint)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
+/*core function for long class functions*/
+jlong callLongMethod (jobject obj, jmethodID methodID, va_list args) {
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jlong ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,'L');
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2long(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
+/*core function for float class methods (float,double)*/
+jdouble callFloatMethod (jobject obj, jmethodID methodID, va_list args,char retType) {
+        int argcount=get_parametercount(methodID);
+        int i;
+        jni_callblock *blk;
+        jdouble ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,retType);
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2double(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
 /*************************** function: jclass_findfield ****************************
        
        searches for field with specified name and type in a 'classinfo'-structur
 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
-       for (i = 0; i < c->fieldscount; i++) {
+/*     printf(" FieldCount: %d\n",c->fieldscount);
+       utf_display(c->name); */
+               for (i = 0; i < c->fieldscount; i++) {
+/*             utf_display(c->fields[i].name);
+               printf("\n");
+               utf_display(c->fields[i].descriptor);
+               printf("\n");*/
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
                        return &(c->fields[i]);
                }
@@ -93,7 +428,11 @@ jclass FindClass (JNIEnv* env, const char *name)
 {
        classinfo *c;  
   
-       c = loader_load(utf_new_char ((char *) name));
+       if (strcmp(name,"[B")==0) {
+               c = loader_load(utf_new_char("The_Array_Class"));
+       }
+       else
+               c = loader_load(utf_new_char_classname ((char *) name));
 
        if (!c) exceptionptr = native_new_and_init(class_java_lang_ClassFormatError);
 
@@ -110,7 +449,7 @@ jclass FindClass (JNIEnv* env, const char *name)
   
 jmethodID FromReflectedMethod (JNIEnv* env, jobject method)
 {
-       log_text("JNI-Call: FromReflectedMethod");
+       /* log_text("JNI-Call: FromReflectedMethod"); */
 }
 
 
@@ -140,7 +479,7 @@ jboolean IsAssignableForm (JNIEnv* env, jclass sub, jclass sup)
 
 jobject ToReflectedField (JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
 {
-       log_text("JNI-Call: ToReflectedField");
+       /* log_text("JNI-Call: ToReflectedField"); */
 }
 
 
@@ -291,7 +630,34 @@ jobject AllocObject (JNIEnv* env, jclass clazz)
 
 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: NewObject");
+        java_objectheader *o;
+       void* args[3];
+       int argcount=get_parametercount(methodID);
+       int i;
+       va_list vaargs;
+
+       /* log_text("JNI-Call: NewObject"); */
+
+       if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+               log_text("Too many arguments. NewObject does not support that");
+               return 0;
+       }
+
+       
+       o = builtin_new (clazz);         /*          create object */
+       
+        if (!o) return NULL;
+
+       va_start(vaargs,methodID);
+       for (i=0;i<argcount;i++) {
+               args[i]=va_arg(vaargs,void*);
+       }
+       va_end(vaargs);
+       exceptionptr=asm_calljavamethod(methodID,o,args[0],args[1],args[2]);
+
+        return o;
+
 }
 
 /*********************************************************************************** 
@@ -303,7 +669,7 @@ jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 
 jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: NewObjectV");
+       /* log_text("JNI-Call: NewObjectV"); */
 }
 
 /*********************************************************************************** 
@@ -316,7 +682,7 @@ jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 
 jobject NewObjectA (JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 {
-       log_text("JNI-Call: NewObjectA");
+       /* log_text("JNI-Call: NewObjectA"); */
 }
 
 
@@ -374,43 +740,56 @@ jmethodID GetMethodID (JNIEnv* env, jclass clazz, const char *name, const char *
 }
 
 /******************** JNI-functions for calling instance methods ******************/
-
 jobject CallObjectMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallObjectMethod");
+       jobject ret;
+       va_list vaargs;
 
-       return NULL;
+/*     log_text("JNI-Call: CallObjectMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callObjectMethod(obj,methodID,vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jobject CallObjectMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallObjectMethodV");
-
-       return NULL;
+       return callObjectMethod(obj,methodID,args);
 }
 
 
 jobject CallObjectMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
 {
+
+
        log_text("JNI-Call: CallObjectMethodA");
 
        return NULL;
 }
 
 
+
+
 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallBooleanMethod");
+       jboolean ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallBooleanMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallBooleanMethodV");
+       return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
 
-       return 0;
 }
 
 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
@@ -422,39 +801,49 @@ jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalu
 
 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallByteMethod");
+       jbyte ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallVyteMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallByteMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallByteMethodV");*/
+       return callIntegerMethod(obj,methodID,'B',args);
 }
 
 
 jbyte CallByteMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallByteMethodA");
-
-       return 0;
 }
 
 
 jchar CallCharMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallCharMethod");
+       jchar ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallCharMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'C',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jchar CallCharMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallCharMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallCharMethodV");*/
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
 }
 
 
@@ -468,17 +857,22 @@ jchar CallCharMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *arg
 
 jshort CallShortMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallShortMethod");
+       jshort ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallShortMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'S',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jshort CallShortMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallShortMethodV");
-
-       return 0;
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'S',args);
 }
 
 
@@ -493,17 +887,19 @@ jshort CallShortMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *a
 
 jint CallIntMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallIntMethod");
+        jint ret;
+        va_list vaargs;
 
-       return 0;
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(obj,get_virtual(obj,methodID),'I',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jint CallIntMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallIntMethodV");
-
-       return 0;
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'I',args);
 }
 
 
@@ -543,17 +939,22 @@ jlong CallLongMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *arg
 
 jfloat CallFloatMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallFloatMethod");
+       jfloat ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallFloatMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_virtual(obj,methodID),vaargs,'F');
+       va_end(vaargs);
+       return ret;
 }
 
 
 jfloat CallFloatMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallFloatMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_virtual(obj,methodID),args,'F');
 }
 
 
@@ -568,24 +969,28 @@ jfloat CallFloatMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *a
 
 jdouble CallDoubleMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallDoubleMethod");
+       jdouble ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallDoubleMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_virtual(obj,methodID),vaargs,'D');
+       va_end(vaargs);
+       return ret;
 }
 
 
 jdouble CallDoubleMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallDoubleMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_virtual(obj,methodID),args,'D');
 }
 
 
 jdouble CallDoubleMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallDoubleMethodA");
-
        return 0;
 }
 
@@ -593,7 +998,14 @@ jdouble CallDoubleMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue
 
 void CallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',vaargs);
+        va_end(vaargs);
+
 
 }
 
@@ -601,6 +1013,7 @@ void CallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallVoidMethodV");
+       (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
 
 }
 
@@ -640,17 +1053,23 @@ jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jme
 
 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualBooleanMethod");
+       jboolean ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualBooleanMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
+       return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
 }
 
 
@@ -665,17 +1084,23 @@ jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, j
 
 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualByteMethod");
+       jbyte ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallNonvirutalByteMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualByteMethodV");
+       /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
 
-       return 0;
 }
 
 
@@ -690,17 +1115,22 @@ jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualCharMethod");
+       jchar ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallNonVirtualCharMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualCharMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
 }
 
 
@@ -715,17 +1145,22 @@ jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualShortMethod");
+       jshort ret;
+       va_list vaargs;
 
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualShortMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
 }
 
 
@@ -740,17 +1175,23 @@ jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmeth
 
 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualIntMethod");
 
-       return 0;
+        jint ret;
+        va_list vaargs;
+
+       /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualIntMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
+        return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
 }
 
 
@@ -790,17 +1231,24 @@ jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualFloatMethod");
+       jfloat ret;
+       va_list vaargs;
+
+       /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
+
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallNonvirtualFloatMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
 }
 
 
@@ -815,17 +1263,22 @@ jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmeth
 
 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
+       jdouble ret;
+       va_list vaargs;
        log_text("JNI-Call: CallNonvirtualDoubleMethod");
 
-       return 0;
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
+       va_end(vaargs);
+       return ret;
+
 }
 
 
 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualDoubleMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
 }
 
 
@@ -840,13 +1293,23 @@ jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jme
 
 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
+        va_end(vaargs);
+
 }
 
 
 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualVoidMethodV");
+/*     log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
+
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
+
 }
 
 
@@ -875,7 +1338,7 @@ jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *si
 
 jfieldID getFieldID_critical(JNIEnv *env,jclass clazz,const char *name,const char *sig)
 {
-    jfieldID id = env->GetFieldID(env,clazz,name,sig);     
+    jfieldID id = GetFieldID(env,clazz,name,sig);     
     if (!id) panic("setfield_critical failed"); 
     return id;
 }
@@ -1028,20 +1491,24 @@ jobject CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID,
 
 jboolean CallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticBooleanMethod");
+        jboolean ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticBooleanMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jboolean)callIntegerMethod(0,methodID,'Z',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jboolean CallStaticBooleanMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticBooleanMethodV");
-
-       return 0;
+       return (jboolean)callIntegerMethod(0,methodID,'Z',args);
 }
 
-
 jboolean CallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticBooleanMethodA");
@@ -1052,17 +1519,22 @@ jboolean CallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID
 
 jbyte CallStaticByteMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticByteMethod");
+        jobject ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jbyte)callIntegerMethod(0,methodID,'B',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jbyte CallStaticByteMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticByteMethodV");
-
-       return 0;
+       return (jbyte)callIntegerMethod(0,methodID,'B',args);
 }
 
 
@@ -1075,17 +1547,22 @@ jbyte CallStaticByteMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jchar CallStaticCharMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticCharMethod");
+        jchar ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jchar)callIntegerMethod(0,methodID,'C',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jchar CallStaticCharMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticCharMethodV");
-
-       return 0;
+        return (jchar)callIntegerMethod(0,methodID,'C',args);
 }
 
 
@@ -1100,17 +1577,22 @@ jchar CallStaticCharMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jshort CallStaticShortMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticShortMethod");
+        jshort ret;
+        va_list vaargs;
 
-       return 0;
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jshort)callIntegerMethod(0,methodID,'S',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jshort CallStaticShortMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticShortMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallStaticShortMethodV");*/
+       return (jshort)callIntegerMethod(0,methodID,'S',args);
 }
 
 
@@ -1125,9 +1607,16 @@ jshort CallStaticShortMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jv
 
 jint CallStaticIntMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticIntMethod");
+        jobject ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticIntMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(0,methodID,'I',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
@@ -1135,7 +1624,7 @@ jint CallStaticIntMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_lis
 {
        log_text("JNI-Call: CallStaticIntMethodV");
 
-       return 0;
+       return callIntegerMethod(0,methodID,'I',args);
 }
 
 
@@ -1150,17 +1639,23 @@ jint CallStaticIntMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue
 
 jlong CallStaticLongMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticLongMethod");
+        jobject ret;
+        va_list vaargs;
 
-       return 0;
-}
+/*      log_text("JNI-Call: CallStaticLongMethod");*/
 
+        va_start(vaargs,methodID);
+        ret = callLongMethod(0,methodID,vaargs);
+        va_end(vaargs);
+        return ret;
+
+}
 
 jlong CallStaticLongMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallStaticLongMethodV");
-
-       return 0;
+       
+       return callLongMethod(0,methodID,args);
 }
 
 
@@ -1175,17 +1670,24 @@ jlong CallStaticLongMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jfloat CallStaticFloatMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticFloatMethod");
+        jfloat ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticLongMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callFloatMethod(0,methodID,vaargs,'F');
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jfloat CallStaticFloatMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticFloatMethodV");
 
-       return 0;
+       return callFloatMethod(0,methodID,args,'F');
+
 }
 
 
@@ -1193,16 +1695,23 @@ jfloat CallStaticFloatMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jv
 {
        log_text("JNI-Call: CallStaticFloatMethodA");
 
-       return 0;
 }
 
 
 
 jdouble CallStaticDoubleMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticDoubleMethod");
 
-       return 0;
+        jdouble ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticDoubleMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callFloatMethod(0,methodID,vaargs,'D');
+        va_end(vaargs);
+        return ret;
+
 }
 
 
@@ -1210,7 +1719,7 @@ jdouble CallStaticDoubleMethodV (JNIEnv *env, jclass clazz, jmethodID methodID,
 {
        log_text("JNI-Call: CallStaticDoubleMethodV");
 
-       return 0;
+       return callFloatMethod(0,methodID,args,'D');
 }
 
 
@@ -1225,7 +1734,13 @@ jdouble CallStaticDoubleMethodA (JNIEnv *env, jclass clazz, jmethodID methodID,
 
 void CallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(0,methodID,'V',vaargs);
+        va_end(vaargs);
 
 }
 
@@ -1233,6 +1748,7 @@ void CallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...)
 void CallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallStaticVoidMethodV");
+        (void)callIntegerMethod(0,methodID,'V',args);
 
 }
 
@@ -1462,7 +1978,8 @@ void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
 
 jstring NewStringUTF (JNIEnv *env, const char *utf)
 {
-    log_text("NewStringUTF called");
+/*    log_text("NewStringUTF called");*/
+    return javastring_new(utf_new_char(utf));
 }
 
 /****************** returns the utf8 length in bytes of a string *******************/
@@ -1478,14 +1995,20 @@ jsize GetStringUTFLength (JNIEnv *env, jstring string)
 
 const char* GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
 {
+    if (verbose) log_text("GetStringUTFChars:");
+
     return javastring_toutf((java_lang_String*) string,false)->text;
+       
 }
 
 /***************** native code no longer needs access to utf ***********************/
 
 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
 {
+       /*
     log_text("JNI-Call: ReleaseStringUTFChars");
+    utf_display(utf_new_char(chars));
+       */
 }
 
 /************************** array operations ***************************************/
@@ -1522,10 +2045,10 @@ void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobjec
 
        /* check if the class of value is a subclass of the element class of the array */
 
-       if (!builtin_instanceof(val, array->elementtype))
-           exceptionptr = proto_java_lang_ArrayStoreException;
-       else
-           array->data[index] = val;
+               if (!builtin_canstore((java_objectarray*)array,(java_objectheader*)val))
+                       exceptionptr = proto_java_lang_ArrayStoreException;
+               else
+                       array->data[index] = val;
     }
 }
 
@@ -1873,12 +2396,16 @@ jint MonitorExit (JNIEnv* env, jobject obj)
 
 
 /************************************* JavaVM interface ****************************/
-
+#ifdef __cplusplus
+#error CPP mode not supported yet
+#else
 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
 {
     log_text("JNI-Call: GetJavaVM");
+    *vm=&javaVM;
     return 0;
 }
+#endif /*__cplusplus*/
 
 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
 {
@@ -1896,22 +2423,12 @@ void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char
 
 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
 {
-       java_arrayheader *s = (java_arrayheader*) array;
-
-       switch (s->arraytype) {
-               case ARRAYTYPE_BYTE:    return (((java_bytearray*)    array)->data);
-               case ARRAYTYPE_BOOLEAN: return (((java_booleanarray*) array)->data);
-               case ARRAYTYPE_CHAR:    return (((java_chararray*)    array)->data);
-               case ARRAYTYPE_SHORT:   return (((java_shortarray*)   array)->data);
-               case ARRAYTYPE_INT:     return (((java_intarray*)     array)->data);
-               case ARRAYTYPE_LONG:    return (((java_longarray*)    array)->data);
-               case ARRAYTYPE_FLOAT:   return (((java_floatarray*)   array)->data);
-               case ARRAYTYPE_DOUBLE:  return (((java_doublearray*)  array)->data);
-               case ARRAYTYPE_OBJECT:  return (((java_objectarray*)  array)->data); 
-               case ARRAYTYPE_ARRAY:   return (((java_arrayarray*)   array)->data);
-       }
+       java_objectheader *s = (java_objectheader*) array;
+       arraydescriptor *desc = s->vftbl->arraydesc;
 
-       return NULL;
+       if (!desc) return NULL;
+
+       return ((u1*)s) + desc->dataoffset;
 }
 
 
@@ -1966,10 +2483,63 @@ jboolean ExceptionCheck (JNIEnv* env)
 
        return exceptionptr ? JNI_TRUE : JNI_FALSE;
 }
-       
+
+
+
+
+
+
+jint DestroyJavaVM (JavaVM *vm) {
+       log_text("DestroyJavaVM called");
+}
+
+jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2) {
+       log_text("AttachCurrentThread called");
+}
+
+jint DetachCurrentThread (JavaVM *vm) {
+       log_text("DetachCurrentThread called");
+}
+   
+jint GetEnv (JavaVM *vm, void **environment, jint jniversion) {
+       *environment=&env;
+       return 0;
+}
+   
+jint AttachCurrentThreadAsDaemon (JavaVM *vm, void **par1, void *par2) {
+       log_text("AttachCurrentThreadAsDaemon called");
+}
+
+
+
+
+
+
+
+
+
+
+
+/********************************* JNI invocation table ******************************/
+
+struct _JavaVM javaVMTable={
+   NULL,
+   NULL,
+   NULL,
+   &DestroyJavaVM,
+   &AttachCurrentThread,
+   &DetachCurrentThread,
+   &GetEnv,
+   &AttachCurrentThreadAsDaemon
+
+};
+
+JavaVM javaVM=&javaVMTable;
+
 /********************************* JNI function table ******************************/
 
-JNIEnv env = {   
+struct JNI_Table envTable =     
+   {   
     NULL,
     NULL,
     NULL,
@@ -2199,7 +2769,10 @@ JNIEnv env = {
     &NewWeakGlobalRef,
     &DeleteWeakGlobalRef,
     &ExceptionCheck
-};
+    };
+
+
+JNIEnv env=&envTable;
 
 
 /*
diff --git a/jni.h b/jni.h
index 140c1737c90034bbe5d81b1fc63b146a0fa5235b..ef49f19375e8ddc46aaaf3d48dc557e4e6c7478f 100644 (file)
--- a/jni.h
+++ b/jni.h
@@ -26,7 +26,7 @@
 
    Authors: ?
 
-   $Id: jni.h 557 2003-11-02 22:51:59Z twisti $
+   $Id: jni.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
 #define jfieldID               fieldinfo*
 #define jmethodID             methodinfo*      
 
-struct _JavaVM;                                     /* opaque structure */
 typedef struct _JavaVM* JavaVM;
 
+struct _JavaVM{
+   void *(*reserved0) ();
+   void *(*reserved1) ();
+   void *(*reserved2) ();
+   jint (*DestroyJavaVM) (JavaVM *);
+   jint (*AttachCurrentThread) (JavaVM *, void **, void *);
+   jint (*DetachCurrentThread) (JavaVM *);
+   jint (*GetEnv) (JavaVM *, void **, jint);
+   jint (*AttachCurrentThreadAsDaemon) (JavaVM *, void **, void *);
+
+};
+
+
 typedef union jvalue {
     jboolean z;
     jbyte    b;
@@ -116,7 +128,7 @@ typedef struct {
        Java VM Interface 
 */
 
-typedef struct JNI_Table JNIEnv;
+typedef struct JNI_Table *JNIEnv;
 
 struct JNI_Table {
     
@@ -427,7 +439,6 @@ struct JNI_Table {
     jint (*MonitorExit) (JNIEnv*, jobject obj);
 
     /* JavaVM interface */
-
     jint (*GetJavaVM) (JNIEnv*, JavaVM **vm);
 
     void (*GetStringRegion) (JNIEnv*, jstring str, jsize start, jsize len, jchar *buf);
@@ -450,8 +461,9 @@ struct JNI_Table {
 
 extern JNIEnv env;
 
-#endif /* _JNI_H */
+extern JavaVM javaVM;
 
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index efba3cea6694850cad155fa91210fd7bd1584a95..cc6a5c5db89c5a5c00681ad375f312d66c00fc23 100644 (file)
--- a/loader.c
+++ b/loader.c
    Contact: cacao@complang.tuwien.ac.at
 
    Authors: Reinhard Grafl
-
    Changes: Andreas Krall
             Roman Obermaiser
             Mark Probst
 
-   $Id: loader.c 593 2003-11-09 19:50:55Z twisti $
+   $Id: loader.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
 #include "toolbox/memory.h"
 #include "toolbox/loging.h"
 #include "threads/thread.h"
+#include <sys/stat.h>
+
+#ifdef USE_ZLIB
+#include "unzip.h"
+#endif
 
+#undef JOWENN_DEBUG
+#undef JOWENN_DEBUG1
+#undef JOWENN_DEBUG2
 
 /* global variables ***********************************************************/
 
@@ -87,17 +94,34 @@ static utf *utf_innerclasses;               /* InnerClasses                    */
 static utf *utf_constantvalue;                 /* ConstantValue                   */
 static utf *utf_code;                      /* Code                            */
 static utf *utf_finalize;                  /* finalize                            */
-static utf *utf_fidesc;                    /* ()V                                     */
+static utf *utf_fidesc;                    /* ()V changed                                   */
 static utf *utf_clinit;                    /* <clinit>                            */
-static utf *utf_initsystemclass;       /* initializeSystemClass   */
+static utf *utf_initsystemclass;       /* initializeSystemClass */
 static utf *utf_systemclass;           /* java/lang/System        */
+static utf *utf_vmclassloader; /*java/lang/VMClassLoader*/
+static utf *utf_vmclass; /*java/lang/VMClassLoader*/
+static utf *utf_initialize;
+static utf *utf_initializedesc;
 
-
+utf* clinit_desc(){
+       return utf_fidesc;
+}
+utf* clinit_name(){
+       return utf_clinit;
+}
 /* important system classes ***************************************************/
 
 classinfo *class_java_lang_Object;
 classinfo *class_java_lang_String;
-classinfo *class_array = NULL;
+
+classinfo *class_java_lang_Throwable;
+classinfo *class_java_lang_Cloneable;
+classinfo *class_java_io_Serializable;
+
+/* Pseudo classes for the typechecker */
+classinfo *pseudo_class_Arraystub = NULL;
+classinfo *pseudo_class_Null = NULL;
+vftbl *pseudo_class_Arraystub_vftbl = NULL;
 
 /* stefan */
 /* These are made static so they cannot be used for throwing in native */
@@ -111,6 +135,9 @@ static classinfo *class_java_lang_ArithmeticException;
 static classinfo *class_java_lang_ArrayStoreException;
 static classinfo *class_java_lang_ThreadDeath;
 
+static methodinfo method_clone_array;
+
+static int loader_inited = 0;
 
 /******************************************************************************
 
@@ -119,19 +146,20 @@ static classinfo *class_java_lang_ThreadDeath;
    the one character type signature and the name of the primitive class
  
  ******************************************************************************/
-primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
-       { NULL, NULL, "java/lang/Integer",   'I', "int"     },
-       { NULL, NULL, "java/lang/Long",      'J', "long"    },
-       { NULL, NULL, "java/lang/Float",     'F', "float"   },
-       { NULL, NULL, "java/lang/Double",    'D', "double"  },
-       { NULL, NULL, "java/lang/Byte",      'B', "byte"    },
-       { NULL, NULL, "java/lang/Character", 'C', "char"    },
-       { NULL, NULL, "java/lang/Short",     'S', "short"   },
-       { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" },
-       { NULL, NULL, "java/lang/Void",      'V', "void"    }
-};
 
+/* CAUTION: Don't change the order of the types. This table is indexed
+ * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
+ */
+primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
+               { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
+               { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
+               { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
+               { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
+               { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
+               { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
+               { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
+               { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
+               { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }};
 
 /* instances of important system classes **************************************/
 
@@ -144,6 +172,50 @@ java_objectheader *proto_java_lang_ArithmeticException;
 java_objectheader *proto_java_lang_ArrayStoreException;
 java_objectheader *proto_java_lang_ThreadDeath;
 
+/* XXX delete */
+#if 0
+void override_array_class(classinfo *c) {
+       int i;
+       classinfo *sup;
+       utf *u=utf_new_char("clone");
+       sup=c->super;
+       class_showmethods(c);
+
+       for (i=0;i<sup->methodscount;i++) {
+               if (sup->methods[i].name==u) {
+                       method_clone_array.class = c;
+                       method_clone_array. flags = ACC_PUBLIC;
+                       method_clone_array.name =  utf_new_char("clone");
+                       method_clone_array.descriptor = utf_new_char("()Ljava/lang/Object;");
+
+                       method_clone_array.jcode = NULL;
+                       method_clone_array.exceptiontable = NULL;
+                       method_clone_array.entrypoint = NULL;
+                       method_clone_array.mcode = NULL;
+                       method_clone_array.stubroutine = NULL;
+                       method_clone_array.methodUsed = NOTUSED;
+                       method_clone_array.monoPoly = MONO;
+                       method_clone_array.subRedefs = 0;
+                       method_clone_array.subRedefsUsed = 0;
+                       method_clone_array.flags=0;
+                       method_clone_array.xta = NULL;
+                        method_clone_array.stubroutine = createnativestub (&builtin_clone_array, &method_clone_array);
+                       c->vftbl->table[sup->methods[i].vftblindex]=method_clone_array.stubroutine;
+                       log_text("Found !!!! :)))))))))))))))))))))))))))))))))))))))))))))))))");
+               }
+       
+
+       }
+}
+#endif
+
+
+
+
+
+
+
+
 
 /************* functions for reading classdata *********************************
 
@@ -275,7 +347,8 @@ bool suck_start (utf *classname) {
        FILE *classfile;
        int  filenamelen, err;
        struct stat buffer;
-       
+       int isZip;
+
        if (classbuffer)                /* classbuffer is already valid */
                return true;
 
@@ -296,41 +369,100 @@ bool suck_start (utf *classname) {
                        filename[filenamelen++] = *(pathpos++);
                        }
 
-               filename[filenamelen++] = '/';  
+               isZip=0;
+               if (filenamelen>4) {
+                       if ( ((filename[filenamelen-1]=='p') || (filename[filenamelen-1]=='P')) &
+                            ((filename[filenamelen-2]=='i') || (filename[filenamelen-1]=='I')) &
+                             ((filename[filenamelen-3]=='z') || (filename[filenamelen-1]=='Z')) ) {
+                               isZip=1;
+                       }
+               }
+
+               if (isZip) {
+#ifdef USE_ZLIB
+
+                       unzFile uf;
+
+                       filename[filenamelen++]='\0';
+                       uf=unzOpen(filename);
+                       if (uf!=0) {
+                               utf_ptr = classname->text;
+                               filenamelen=0;
+                               while (utf_ptr < utf_end(classname)) {
+                                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                                       c = *utf_ptr++;
+                                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                               c = '?'; 
+                                       filename[filenamelen++] = c;    
+                               }
+                               strcpy (filename+filenamelen, ".class");
+                               /*log_text(filename);*/
+                               if (unzLocateFile(uf,filename,1 /*case sensitive*/)==UNZ_OK) {
+                                       unz_file_info file_info;
+                                       log_text("Class found in zip file");
+                                       if (unzGetCurrentFileInfo(uf,&file_info,filename,
+                                               sizeof(filename),NULL,0,NULL,0) ==UNZ_OK) {
+                                               if (unzOpenCurrentFile(uf)==UNZ_OK) {
+                                                       classbuffer_size = file_info.uncompressed_size;                         
+                                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                                       classbuf_pos     = classbuffer-1;
+                                                       /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
+                                                       if (unzReadCurrentFile(uf,classbuffer,classbuffer_size)==classbuffer_size) {
+                                                               unzCloseCurrentFile(uf);
+                                                               return true;
+                                                       } else {
+                                                               MFREE(classbuffer,u1,classbuffer_size);
+                                                               log_text("Error while unzipping");
+                                                       }
+                                               } else log_text("Error while opening file in archive");
+                                       } else log_text("Error while retrieving fileinfo");
+                               }; 
+                               unzCloseCurrentFile(uf);
+
+                       }
+#endif                 
+               } else {
+                       filename[filenamelen++] = '/';  
    
-               /* add classname to filename */
-
-               utf_ptr = classname->text;
-               while (utf_ptr < utf_end(classname)) {
-                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
-                       c = *utf_ptr++;
-                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
-                               c = '?'; 
-                       filename[filenamelen++] = c;    
+                       /* add classname to filename */
+
+                       utf_ptr = classname->text;
+                       while (utf_ptr < utf_end(classname)) {
+                               PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                               c = *utf_ptr++;
+                               if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                       c = '?'; 
+                               filename[filenamelen++] = c;    
                        }
-      
-               /* add suffix */
+       
+                       /* add suffix */
+
+                       strcpy (filename+filenamelen, ".class");
 
-               strcpy (filename+filenamelen, ".class");
+                       classfile = fopen(filename, "r");
+                       if (classfile) {                                       /* file exists */
 
-               classfile = fopen(filename, "r");
-               if (classfile) {                                       /* file exists */
+                               /* XXX remove */
+                               /*
+                                 sprintf(logtext,"Opening file: %s",filename);
+                                 dolog();
+                               */
                        
-                       /* determine size of classfile */
+                               /* determine size of classfile */
 
-                       err = stat (filename, &buffer);
+                               err = stat (filename, &buffer);
 
-                       if (!err) {                                /* read classfile data */                            
-                               classbuffer_size = buffer.st_size;                              
-                               classbuffer      = MNEW(u1, classbuffer_size);
-                               classbuf_pos     = classbuffer-1;
-                               fread(classbuffer, 1, classbuffer_size, classfile);
-                               fclose(classfile);
-                               return true;
+                               if (!err) {                                /* read classfile data */                            
+                                       classbuffer_size = buffer.st_size;                              
+                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                       classbuf_pos     = classbuffer-1;
+                                       fread(classbuffer, 1, classbuffer_size, classfile);
+                                       fclose(classfile);
+                                       return true;
+                               }
                        }
                }
        }
-
        if (verbose) {
                sprintf (logtext, "Warning: Can not open class file '%s'", filename);
                dolog();
@@ -460,7 +592,7 @@ voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype)
 
        /* check type of constantpool entry */
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -524,73 +656,31 @@ static void checkfielddescriptor (char *utf_ptr, char *end_pos)
 {
        char *tstart;  /* pointer to start of classname */
        char ch;
-       
-       switch (*utf_ptr++) {
-       case 'B':
-       case 'C':
-       case 'I':
-       case 'S':
-       case 'Z':  
-       case 'J':  
-       case 'F':  
-       case 'D':
-               /* primitive type */  
-               break;
-
-       case 'L':
-               /* save start of classname */
-               tstart = utf_ptr;  
-               
-               /* determine length of classname */
-               while ( *utf_ptr++ != ';' )
-                       if (utf_ptr>=end_pos) 
-                               panic ("Missing ';' in objecttype-descriptor");
+       char *start = utf_ptr; /* XXX remove */
 
-               /* cause loading of referenced class */                 
-               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-               break;
-
-       case '[' : 
-               /* array type */
-               while ((ch = *utf_ptr++)=='[') 
-                       /* skip */ ;
-
-               /* component type of array */
-               switch (ch) {
-               case 'B':
-               case 'C':
-               case 'I':
-               case 'S':
-               case 'Z':  
-               case 'J':  
-               case 'F':  
-               case 'D':
-                       /* primitive type */  
-                       break;
-                       
-               case 'L':
-                       /* save start of classname */
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
-
-                       /* cause loading of referenced class */                 
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-
-               default:   
-                       panic ("Ill formed methodtype-descriptor");
-               }
-               break;
-                       
-       default:   
-               panic ("Ill formed methodtype-descriptor");
+       switch (*utf_ptr++) {
+         case 'B':
+         case 'C':
+         case 'I':
+         case 'S':
+         case 'Z':  
+         case 'J':  
+         case 'F':  
+         case 'D':
+                 /* primitive type */  
+                 break;
+                 
+         case '[':
+         case 'L':
+                 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                         panic ("Ill formed descriptor");
+                 break;
+                 
+         default:   
+                 panic ("Ill formed descriptor");
        }                       
-
-        /* exceeding characters */             
+       
+       /* exceeding characters */              
        if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
 }
 
@@ -608,12 +698,17 @@ static void checkmethoddescriptor (utf *d)
        char *end_pos = utf_end(d);  /* points behind utf string       */
        char *tstart;                /* pointer to start of classname  */
        char c,ch;
+       char *start; /* XXX remove */
 
        /* method descriptor must start with parenthesis */
+       /* XXX check length */
        if (*utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
 
+       /* XXX check length */
        /* check arguments */
        while ((c = *utf_ptr++) != ')') {
+               start = utf_ptr-1; /* XXX remove */
+               
                switch (c) {
                case 'B':
                case 'C':
@@ -626,58 +721,15 @@ static void checkmethoddescriptor (utf *d)
                        /* primitive type */  
                        break;
 
+               case '[':
                case 'L':
-                       /* save start of classname */ 
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
-                       
-                       /* cause loading of referenced class */
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-          
-               case '[' :
-                       /* array type */ 
-                       while ((ch = *utf_ptr++)=='[') 
-                               /* skip */ ;
-
-                       /* component type of array */
-                       switch (ch) {
-                       case 'B':
-                       case 'C':
-                       case 'I':
-                       case 'S':
-                       case 'Z':  
-                       case 'J':  
-                       case 'F':  
-                       case 'D':
-                               /* primitive type */  
-                               break;
-
-                       case 'L':
-                               /* save start of classname */
-                               tstart = utf_ptr;
-                       
-                               /* determine length of classname */     
-                               while ( *utf_ptr++ != ';' )
-                                       if (utf_ptr>=end_pos) 
-                                               panic ("Missing ';' in objecttype-descriptor");
-
-                               /* cause loading of referenced class */
-                               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                               break;
-
-                       default:   
-                               panic ("Ill formed methodtype-descriptor");
-                       } 
+                       if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                               panic ("Ill formed method descriptor");
                        break;
                        
                default:   
                        panic ("Ill formed methodtype-descriptor");
-               }                       
+               }
        }
 
        /* check returntype */
@@ -698,9 +750,13 @@ static void checkmethoddescriptor (utf *d)
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
 {
        constant_arraydescriptor *d;
+
+       /* class_new( utf_new(utf_ptr,namelen) ); */ /* XXX remove */
        
        if (*utf_ptr++ != '[') panic ("Attempt to build arraydescriptor for non-array");
 
@@ -737,6 +793,7 @@ constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
        }
        return d;
 }
+#endif
 
 
 /******************* Function: freearraydescriptor *****************************
@@ -745,6 +802,8 @@ constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 static void freearraydescriptor (constant_arraydescriptor *d)
 {
        while (d) {
@@ -753,9 +812,12 @@ static void freearraydescriptor (constant_arraydescriptor *d)
                d = n;
                }
 }
+#endif
 
 /*********************** Function: displayarraydescriptor *********************/
 
+/* XXX delete */
+#if 0
 static void displayarraydescriptor (constant_arraydescriptor *d)
 {
        switch (d->arraytype) {
@@ -771,8 +833,44 @@ static void displayarraydescriptor (constant_arraydescriptor *d)
        case ARRAYTYPE_OBJECT: utf_display(d->objectclass->name); printf("[]"); break;
        }
 }
+#endif
 
+/***************** Function: print_arraydescriptor ****************************
 
+       Debugging helper for displaying an arraydescriptor
+       
+*******************************************************************************/
+
+void
+print_arraydescriptor(FILE *file,arraydescriptor *desc)
+{
+       if (!desc) {
+               fprintf(file,"<NULL>");
+               return;
+       }
+
+       fprintf(file,"{");
+       if (desc->componentvftbl) {
+               if (desc->componentvftbl->class)
+                       utf_fprint(file,desc->componentvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+               
+       fprintf(file,",");
+       if (desc->elementvftbl) {
+               if (desc->elementvftbl->class)
+                       utf_fprint(file,desc->elementvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+       fprintf(file,",%d,%d,%d,%d}",desc->arraytype,desc->dimension,
+                       desc->dataoffset,desc->componentsize);
+}
 
 /******************************************************************************/
 /**************************  Functions for fields  ****************************/
@@ -1077,8 +1175,10 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
                panic ("Attempt to access constant outside range");
 
        /* check type of constantpool entry */
+
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               class_showconstantpool(c);
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (class_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -1334,21 +1434,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_classes) {
                utf *name =
                  class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
-               
-               if ( (name->blength>0) && (name->text[0]=='[') ) {
-                       /* check validity of descriptor */
-                       checkfielddescriptor (name->text, utf_end(name)); 
 
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
-                       cpinfos [forward_classes -> thisindex] = 
-                          buildarraydescriptor(name->text, name->blength);
+               cptags  [forward_classes -> thisindex] = CONSTANT_Class;
+               /* retrieve class from class-table */
+               cpinfos [forward_classes -> thisindex] = class_new (name);
 
-                       }
-               else {                                  
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Class;
-                       /* retrieve class from class-table */
-                       cpinfos [forward_classes -> thisindex] = class_new (name);
-                       }
                forward_classes = forward_classes -> next;
                
                }
@@ -1356,7 +1446,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_strings) {
                utf *text = 
                  class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
-       
+/*
+               log_text("forward_string:");
+               printf( "classpoolid: %d\n",forward_strings -> thisindex);
+               utf_display(text);
+               log_text("\n------------------"); */
                /* resolve utf-string */                
                cptags   [forward_strings -> thisindex] = CONSTANT_String;
                cpinfos  [forward_strings -> thisindex] = text;
@@ -1395,6 +1489,21 @@ static void class_loadcpool (classinfo *c)
                nat = class_getconstant
                        (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
 
+#ifdef JOWENN_DEBUG
+               log_text("trying to resolve:");
+               log_text(nat->name->text);
+               switch(forward_fieldmethints ->tag) {
+               case CONSTANT_Fieldref: 
+                               log_text("CONSTANT_Fieldref");
+                               break;
+               case CONSTANT_InterfaceMethodref: 
+                               log_text("CONSTANT_InterfaceMethodref");
+                               break;
+               case CONSTANT_Methodref: 
+                               log_text("CONSTANT_Methodref");
+                               break;
+               }
+#endif
                fmi -> class = class_getconstant 
                        (c, forward_fieldmethints -> class_index, CONSTANT_Class);
                fmi -> name = nat -> name;
@@ -1417,6 +1526,7 @@ static void class_loadcpool (classinfo *c)
 
                }
 
+/*     class_showconstantpool(c); */
 
        dump_release (dumpsize);
 }
@@ -1444,6 +1554,9 @@ static int class_load (classinfo *c)
        count_class_loads++;
 #endif
 
+       /* XXX remove */
+       /*      loadverbose = 1; */
+       
        /* output for debugging purposes */
        if (loadverbose) {              
 
@@ -1453,8 +1566,9 @@ static int class_load (classinfo *c)
                }
        
        /* load classdata, throw exception on error */
+
        if (!suck_start (c->name)) {
-               throw_classnotfoundexception();            
+               throw_classnotfoundexception2(c->name);            
                return false;
        }
        
@@ -1469,9 +1583,11 @@ static int class_load (classinfo *c)
                error();
                }
 
-
        class_loadcpool (c);
-       
+       /*JOWENN*/
+       c->erroneous_state=0;
+       c->initializing_thread=0;       
+       /*JOWENN*/
         c -> classUsed = NOTUSED; /* not used initially CO-RT */
        c -> impldBy = NULL;
 
@@ -1498,6 +1614,9 @@ static int class_load (classinfo *c)
 
        /* load fields */
        c -> fieldscount = suck_u2 ();
+/*     utf_display(c->name);
+       printf(" ,Fieldscount: %d\n",c->fieldscount);*/
+
        c -> fields = GCNEW (fieldinfo, c -> fieldscount);
        for (i=0; i < c -> fieldscount; i++) {
                field_load (&(c->fields[i]), c);
@@ -1613,6 +1732,206 @@ static void class_addinterface (classinfo *c, classinfo *ic)
 }
 
 
+/******************* Function: class_new_array *********************************
+
+    This function is called by class_new to setup an array class.
+
+*******************************************************************************/
+
+void
+class_new_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       methodinfo *clone;
+       int namelen;
+
+       /* XXX remove logging */
+       /*
+       sprintf(logtext,"new array class: ");
+       utf_sprint(logtext+strlen(logtext),c->name);
+       dolog();
+       */
+       
+       /* Array classes are not loaded from classfiles. */
+       list_remove (&unloadedclasses, c);
+
+       /* Check array class name */
+       namelen = c->name->blength;
+       if (namelen < 2 || c->name->text[0] != '[')
+               panic("Invalid array class name.");
+
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. We have to create the component class. */
+                 comp = class_new(utf_new(c->name->text + 1,namelen - 1));
+                 break;
+
+         case 'L':
+                 /* XXX remove logging */
+                 /*
+                 sprintf(logtext,"Component class: ");
+                 utf_sprint(logtext+strlen(logtext),utf_new(c->name->text + 2,namelen - 3));
+                 dolog();
+                 if (class_get(utf_new(c->name->text + 2,namelen - 3)))
+                         log_text("Already created.");
+                 */
+                 
+                 /* c is an array of objects. */
+                 if (namelen < 4 || c->name->text[namelen-1] != ';')
+                         panic("Invalid array class name.");
+                 comp = class_new(utf_new(c->name->text + 2,namelen - 3));
+                 break;
+       }
+
+       /* Setup the array class */
+       c->super = class_java_lang_Object;
+
+    c->interfacescount = 2;
+    c->interfaces = MNEW(classinfo*,2);
+    c->interfaces[0] = class_java_lang_Cloneable;
+    c->interfaces[1] = class_java_io_Serializable;
+
+       c->methodscount = 1;
+       c->methods = MNEW (methodinfo, c->methodscount);
+
+       clone = c->methods;
+       memset(clone,0,sizeof(methodinfo));
+       clone->flags = ACC_PUBLIC; /* XXX protected? */
+       clone->name = utf_new_char("clone");
+       clone->descriptor = utf_new_char("()Ljava/lang/Object;");
+       clone->class = c;
+       clone->stubroutine = createnativestub(&builtin_clone_array,clone);
+       clone->monoPoly = MONO; /* XXX should be poly? */
+
+       /* XXX: field: length? */
+
+       /* The array class has to be linked */
+       list_addlast(&unlinkedclasses,c);
+       
+       /*
+     * Array classes which are created after the other classes have been
+     * loaded and linked are linked explicitely.
+     */
+       if (loader_inited)
+               loader_load(c->name);
+}
+
+/****************** Function: class_link_array *********************************
+
+    This function is called by class_link to create the
+    arraydescriptor for an array class.
+
+    This function returns NULL if the array cannot be linked because
+    the component type has not been linked yet.
+
+*******************************************************************************/
+
+static
+arraydescriptor *
+class_link_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       int namelen = c->name->blength;
+       arraydescriptor *desc;
+       vftbl *compvftbl;
+
+       /* XXX remove logging */
+
+       /*
+         sprintf(logtext,"linking array class: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
+       
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. */
+                 comp = class_get(utf_new(c->name->text + 1,namelen - 1));
+                 if (!comp) panic("Could not find component array class.");
+                 break;
+
+         case 'L':
+                 /* c is an array of objects. */
+                 comp = class_get(utf_new(c->name->text + 2,namelen - 3));
+                 if (!comp) panic("Could not find component class.");
+                 break;
+       }
+
+       /* If the component type has not been linked return NULL */
+       if (comp && !comp->linked)
+               return NULL;
+
+       /* Allocate the arraydescriptor */
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray,data);
+               
+               compvftbl = comp->vftbl;
+               if (!compvftbl)
+                       panic("Component class has no vftbl.");
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+               }
+               else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+               }
+       }
+       else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+                 case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
+                           desc->dataoffset = OFFSET(java_booleanarray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'B': desc->arraytype = ARRAYTYPE_BYTE;
+                           desc->dataoffset = OFFSET(java_bytearray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'C': desc->arraytype = ARRAYTYPE_CHAR;
+                           desc->dataoffset = OFFSET(java_chararray,data);
+                               desc->componentsize = sizeof(u2); break;
+                 case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
+                           desc->dataoffset = OFFSET(java_doublearray,data);
+                               desc->componentsize = sizeof(double); break;
+                 case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
+                           desc->dataoffset = OFFSET(java_floatarray,data);
+                               desc->componentsize = sizeof(float); break;
+                 case 'I': desc->arraytype = ARRAYTYPE_INT;
+                           desc->dataoffset = OFFSET(java_intarray,data);
+                               desc->componentsize = sizeof(s4); break;
+                 case 'J': desc->arraytype = ARRAYTYPE_LONG;
+                           desc->dataoffset = OFFSET(java_longarray,data);
+                               desc->componentsize = sizeof(s8); break;
+                 case 'S': desc->arraytype = ARRAYTYPE_SHORT;
+                           desc->dataoffset = OFFSET(java_shortarray,data);
+                               desc->componentsize = sizeof(s2); break;
+                 default:
+                         panic("Invalid array class name");
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+       }
+
+       /* XXX remove logging */
+       /*
+         print_arraydescriptor(stdout,desc); 
+         printf("\n");
+       */
+
+       return desc;
+}
+
 /********************** Function: class_link ***********************************
 
        Tries to link a class. The super class and every implemented interface must
@@ -1637,9 +1956,17 @@ void class_link(classinfo *c)
        classinfo *super = c->super;  /* super class                              */
        classinfo *ic, *c2;           /* intermediate class variables             */
        vftbl *v;                     /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */                     
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc = NULL;  /* descriptor for array classes       */
 
 
+       /* XXX remove log */
+       /*
+         sprintf(logtext,"trying to link: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
        /*  check if all superclasses are already linked, if not put c at end of
            unlinked list and return. Additionally initialize class fields.       */
 
@@ -1673,6 +2000,14 @@ void class_link(classinfo *c)
                        return; 
                }
 
+               /* handle array classes */
+               if (c->name->text[0] == '[')
+                       if ((arraydesc = class_link_array(c)) == NULL) {
+                               list_remove(&unlinkedclasses, c);
+                               list_addlast(&unlinkedclasses, c);
+                               return; 
+                       }
+               
                if (c->flags & ACC_INTERFACE)
                        c->index = interfaceindex++;
                else
@@ -1742,6 +2077,11 @@ void class_link(classinfo *c)
        v->class = c;
        v->vftbllength = vftbllength;
        v->interfacetablelength = interfacetablelength;
+       v->arraydesc = arraydesc;
+
+       /* store interface index in vftbl */
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
 
        /* copy virtual function table of super class */
 
@@ -1815,8 +2155,9 @@ void class_link(classinfo *c)
 
        c->linked = true;       
 
-       list_remove(&unlinkedclasses, c);
-       list_addlast(&linkedclasses, c);
+       list_remove (&unlinkedclasses, c);
+       list_addlast (&linkedclasses, c);
+
 }
 
 
@@ -1858,9 +2199,6 @@ static void class_freecpool (classinfo *c)
                        case CONSTANT_NameAndType:
                                FREE (info, constant_nameandtype);
                                break;
-                       case CONSTANT_Arraydescriptor:
-                               freearraydescriptor (info);
-                               break;
                        }
                        }
                }
@@ -1893,6 +2231,9 @@ static void class_free (classinfo *c)
        MFREE (c->methods, methodinfo, c->methodscount);
 
        if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
                for (i = 0; i < v->interfacetablelength; i++) {
                        MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
                        }
@@ -1909,8 +2250,8 @@ static void class_free (classinfo *c)
        if (c->innerclasscount)
                MFREE (c->innerclass, innerclassinfo, c->innerclasscount);
 
-       if (c->classvftbl)
-               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1));
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
        
        FREE (c, classinfo);
 }
@@ -1927,6 +2268,7 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
 
+       
        for (i = 0; i < c->fieldscount; i++) { 
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) 
                        return &(c->fields[i]);                                                         
@@ -1937,6 +2279,70 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 }
 
 
+/************************* Function: class_findmethod **************************
+       
+       Searches a 'classinfo' structure for a method having the given name and
+       type and returns the index in the class info structure.
+       If type is NULL, it is ignored.
+
+*******************************************************************************/
+
+s4 class_findmethodIndex (classinfo *c, utf *name, utf *desc)
+{
+       s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
+       for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
+               if ((c->methods[i].name == name) && ((desc == NULL) ||
+                                                  (c->methods[i].descriptor == desc)))
+                       return i;
+               }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
+       return -1;
+}
+
+
+
 /************************* Function: class_findmethod **************************
        
        Searches a 'classinfo' structure for a method having the given name and
@@ -1947,15 +2353,69 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 
 methodinfo *class_findmethod (classinfo *c, utf *name, utf *desc)
 {
+#if 0
        s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
        for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
                if ((c->methods[i].name == name) && ((desc == NULL) ||
                                                   (c->methods[i].descriptor == desc)))
                        return &(c->methods[i]);
                }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
        return NULL;
+#endif
+       s4 idx=class_findmethodIndex(c,name,desc);
+/*     if (idx==-1) log_text("class_findmethod: method not found");*/
+       if (idx==-1) return NULL;
+       return &(c->methods[idx]);
 }
 
+
+
+
+
+
 /************************* Function: class_findmethod_approx ******************
        
        like class_findmethod but ignores the return value when comparing the
@@ -2064,113 +2524,118 @@ bool class_issubclass(classinfo *sub, classinfo *super)
 
 *******************************************************************************/
 
+#ifdef USE_THREADS
+extern int blockInts;
+#endif
+
 void class_init(classinfo *c)
 {
-       methodinfo *m;
-       java_objectheader *exceptionptr;
-       s4 i;
-       int b;
+        methodinfo *m;
+        java_objectheader *exceptionptr;
+        s4 i;
+        int b;
 
-       if (!makeinitializations)
-               return;
-       if (c->initialized)
-               return;
 
-       c->initialized = true;
-       
-#ifdef STATISTICS
-       count_class_inits++;
-#endif
+        if (!makeinitializations)
+                return;
+        if (c->initialized)
+                return;
+        c -> initialized = true;
 
-       if (c->super)
-               class_init(c->super);
-       for (i = 0; i < c->interfacescount; i++)
-               class_init(c->interfaces[i]);  /* real */
 
-       m = class_findmethod(c, utf_clinit, utf_fidesc);
 
-       if (!m) {
-               if (initverbose) {
-                       sprintf(logtext, "Class ");
-                       utf_sprint(logtext+strlen(logtext), c->name);
-                       sprintf(logtext+strlen(logtext), " has no initializer");        
-                       dolog();
-               }
-               return;
-       }
-               
-       if (!(m->flags & ACC_STATIC))
-               panic("Class initializer is not static!");
-       
-       if (initverbose) {
-               sprintf(logtext, "Starting initializer for class: ");
-               utf_sprint(logtext + strlen(logtext), c->name);
-               dolog();
-       }
-
-#ifdef USE_THREADS
-       b = blockInts;
-       blockInts = 0;
+#ifdef STATISTICS
+        count_class_inits++;
 #endif
 
-       exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
+        if (c->super)
+                class_init (c->super);
+        for (i=0; i < c->interfacescount; i++)
+                class_init(c->interfaces[i]);  /* real */
+
+        m = class_findmethod (c, utf_clinit, utf_fidesc);
+        if (!m) {
+                if (initverbose) {
+                        sprintf (logtext, "Class ");
+                        utf_sprint (logtext+strlen(logtext), c->name);
+                        sprintf (logtext+strlen(logtext), " has no initializer");
+                        dolog ();
+                        }
+/*              goto callinitialize;*/
+                return;
+                }
+
+        if (! (m->flags & ACC_STATIC))
+                panic ("Class initializer is not static!");
+
+        if (initverbose) {
+                sprintf (logtext, "Starting initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
 
 #ifdef USE_THREADS
-       assert(blockInts == 0);
-       blockInts = b;
+        b = blockInts;
+        blockInts = 0;
 #endif
 
-       if (exceptionptr) {
-               printf("#### Initializer of ");
-               utf_display(c->name);
-               printf(" has thrown: ");
-               utf_display(exceptionptr->vftbl->class->name);
-               printf("\n");
-               fflush(stdout);
-       }
-
-       if (initverbose) {
-               sprintf(logtext, "Finished initializer for class: ");
-               utf_sprint(logtext + strlen(logtext), c->name);
-               dolog();
-       }
-
-       if (c->name == utf_systemclass) {
-               /* class java.lang.System requires explicit initialization */
-               
-               if (initverbose)
-                       printf("#### Initializing class System");
-
-               /* find initializing method */     
-               m = class_findmethod(c, 
-                                                        utf_initsystemclass,
-                                                        utf_fidesc);
-
-               if (!m) {
-                       /* no method found */
-                       printf("initializeSystemClass failed");
-                       return;
-               }
+        exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
 
 #ifdef USE_THREADS
-               b = blockInts;
-               blockInts = 0;
+        assert(blockInts == 0);
+        blockInts = b;
 #endif
 
-               exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
-
-#ifdef USE_THREADS
-               assert(blockInts == 0);
-               blockInts = b;
-#endif
+        if (exceptionptr) {
+                printf ("#### Initializer of ");
+                utf_display (c->name);
+                printf (" has thrown: ");
+                utf_display (exceptionptr->vftbl->class->name);
+                printf ("\n");
+                fflush (stdout);
+                }
+
+        if (initverbose) {
+                sprintf (logtext, "Finished initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
+        if (c->name == utf_systemclass) {
+                /* class java.lang.System requires explicit initialization */
+
+                if (initverbose)
+                        printf ("#### Initializing class System");
+
+                /* find initializing method */
+                m = class_findmethod (c,
+                                        utf_initsystemclass,
+                                        utf_fidesc);
+
+                if (!m) {
+                        /* no method found */
+                        /* printf("initializeSystemClass failed"); */
+                        return;
+                }
+                #ifdef USE_THREADS
+                        b = blockInts;
+                        blockInts = 0;
+                #endif
+
+                exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
+
+                #ifdef USE_THREADS
+                        assert(blockInts == 0);
+                        blockInts = b;
+                #endif
+
+                if (exceptionptr) {
+                        printf ("#### initializeSystemClass has thrown: ");
+                        utf_display (exceptionptr->vftbl->class->name);
+                        printf ("\n");
+                        fflush (stdout);
+                }
+        }
 
-               if (exceptionptr) {                     
-                       printf("#### initializeSystemClass has thrown: ");
-                       utf_display(exceptionptr->vftbl->class->name);
-                       printf("\n");
-                       fflush(stdout);
-               }
-       }
 }
 
 
@@ -2287,11 +2752,6 @@ void class_showconstanti(classinfo *c, int ii)
                        printf("Utf8 -> ");
                        utf_display(e);
                        break;
-               case CONSTANT_Arraydescriptor:  {
-                       printf("Arraydescriptor: ");
-                       displayarraydescriptor(e);
-               }
-               break;
                default: 
                        panic("Invalid type of ConstantPool-Entry");
                }
@@ -2373,11 +2833,6 @@ void class_showconstantpool (classinfo *c)
                                printf ("Utf8 -> ");
                                utf_display (e);
                                break;
-                       case CONSTANT_Arraydescriptor:  {
-                               printf ("Arraydescriptor: ");
-                               displayarraydescriptor (e);
-                       }
-                       break;
                        default: 
                                panic ("Invalid type of ConstantPool-Entry");
                        }
@@ -2439,8 +2894,6 @@ void class_showmethods (classinfo *c)
 /******************* General functions for the class loader *******************/
 /******************************************************************************/
 
-static int loader_inited = 0;
-
 /********************* Function: loader_load ***********************************
 
        Loads and links the class desired class and each class and interface
@@ -2449,11 +2902,18 @@ static int loader_inited = 0;
 
 *******************************************************************************/
 
+static int loader_load_running = 0;
+
 classinfo *loader_load (utf *topname)
 {
        classinfo *top;
        classinfo *c;
        long int starttime=0,stoptime=0;
+
+       /* avoid recursive calls */
+       if (loader_load_running)
+               return class_new(topname);
+       loader_load_running++;
        
        intsDisable();                           /* schani */
 
@@ -2486,6 +2946,8 @@ classinfo *loader_load (utf *topname)
 
        intsRestore();                          /* schani */
 
+       loader_load_running--;
+       
        return top; 
 }
 
@@ -2521,6 +2983,80 @@ void create_primitive_classes()
                        class_new( utf_new_char(primitivetype_table[i].wrapname) );
                 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
                primitivetype_table[i].class_wrap  -> impldBy = NULL;
+
+               /* create the primitive array class */
+               if (primitivetype_table[i].arrayname) {
+                       c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
+                       primitivetype_table[i].arrayclass = c;
+                       if (!c->linked) class_link(c);
+                       primitivetype_table[i].arrayvftbl = c->vftbl;
+               }
+       }
+}
+
+/**************** function: class_primitive_from_sig ***************************
+
+       return the primitive class indicated by the given signature character
+
+    If the descriptor does not indicate a valid primitive type the
+    return value is NULL.
+
+********************************************************************************/
+
+classinfo *class_primitive_from_sig(char sig)
+{
+       switch (sig) {
+         case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
+         case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
+         case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
+         case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
+         case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
+         case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
+         case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
+         case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
+         case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
+       }
+       return NULL;
+}
+
+/****************** function: class_from_descriptor ****************************
+
+    return the class indicated by the given descriptor
+
+    utf_ptr....first character of descriptor
+    end_ptr....first character after the end of the string
+    next.......if non-NULL, *next is set to the first character after
+               the descriptor
+    mode.......what to do if a class descriptor is parsed successfully:
+                   CLASSLOAD_SKIP...skip it and return something != NULL
+                   CLASSLOAD_NEW....get classinfo * via class_new
+                   CLASSLOAD_LOAD...get classinfo * via loader_load
+
+    If the descriptor is invalid the return value is NULL
+
+********************************************************************************/
+
+classinfo *class_from_descriptor(char *utf_ptr,char *end_ptr,char **next,int mode)
+{
+       char *start = utf_ptr;
+       bool error = false;
+       utf *name;
+       
+       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
+       if (error) return NULL;
+       if (next) *next = utf_ptr;
+
+       switch (*start) {
+         case 'L':
+                 start++;
+                 utf_ptr--;
+                 /* fallthrough */
+         case '[':
+                 if (mode == CLASSLOAD_SKIP) return class_java_lang_Object;
+                 name = utf_new(start,utf_ptr-start);
+                 return (mode == CLASSLOAD_LOAD) ? loader_load(name) : class_new(name);
+         default:
+                 return class_primitive_from_sig(*start);
        }
 }
 
@@ -2530,7 +3066,8 @@ void create_primitive_classes()
 
 ********************************************************************************/
 
-
+/* XXX delete */
+#if 0
 classinfo *create_array_class(utf *u)
 {  
        classinfo *c = class_new (u);
@@ -2540,9 +3077,47 @@ classinfo *create_array_class(utf *u)
        list_addlast (&unlinkedclasses, c);
        c -> super = class_java_lang_Object;
        class_link(c);
-
        return c;
 }
+#endif
+
+/*************** function: create_pseudo_classes *******************************
+
+       create pseudo classes used by the typechecker
+
+********************************************************************************/
+
+static void
+create_pseudo_classes()
+{
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+    
+    pseudo_class_Arraystub = class_new( utf_new_char(";Arraystub;") );
+    list_remove(&unloadedclasses,pseudo_class_Arraystub);
+
+    pseudo_class_Arraystub->super = class_java_lang_Object;
+    pseudo_class_Arraystub->interfacescount = 2;
+    pseudo_class_Arraystub->interfaces = MNEW(classinfo*,2);
+    pseudo_class_Arraystub->interfaces[0] =
+        class_java_lang_Cloneable;
+    pseudo_class_Arraystub->interfaces[1] =
+        class_java_io_Serializable;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Arraystub);
+    class_link(pseudo_class_Arraystub);
+
+       pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
+
+    /* pseudo class representing the null type */
+    
+    pseudo_class_Null = class_new( utf_new_char(";Null;") );
+    list_remove(&unloadedclasses,pseudo_class_Null);
+
+    pseudo_class_Null->super = class_java_lang_Object;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Null);
+    class_link(pseudo_class_Null);     
+}
 
 /********************** Function: loader_init **********************************
 
@@ -2551,14 +3126,17 @@ classinfo *create_array_class(utf *u)
 
 *******************************************************************************/
  
-void loader_init()
+void loader_init (u1 * stackbottom)
 {
-       utf *string_class;
        interfaceindex = 0;
        
-       list_init(&unloadedclasses, OFFSET(classinfo, listnode));
-       list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
-       list_init(&linkedclasses, OFFSET(classinfo, listnode));
+       
+       log_text("Entering loader_init");
+                               
+       
+       list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
+       list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
+       list_init (&linkedclasses, OFFSET(classinfo, listnode) );
 
        /* create utf-symbols for pointer comparison of frequently used strings */
        utf_innerclasses    = utf_new_char("InnerClasses");
@@ -2569,90 +3147,100 @@ void loader_init()
        utf_clinit              = utf_new_char("<clinit>");
        utf_initsystemclass = utf_new_char("initializeSystemClass");
        utf_systemclass     = utf_new_char("java/lang/System");
+       utf_vmclassloader =utf_new_char("java/lang/VMClassLoader");
+       utf_initialize =utf_new_char("initialize");
+       utf_initializedesc =utf_new_char("(I)V");
+
+       utf_vmclass =utf_new_char("java/lang/VMClass");
+
+        /* create some important classes */
+        /* These classes have to be created now because the classinfo
+         * pointers are used in the loading code.
+         */
+        class_java_lang_Object = class_new( utf_new_char ("java/lang/Object") );
+        class_java_lang_String = class_new( utf_new_char("java/lang/String") );
+        class_java_lang_Cloneable = class_new( utf_new_char ("java/lang/Cloneable") );
+        class_java_io_Serializable = class_new( utf_new_char ("java/io/Serializable") );
+
+        log_text("loader_init: java/lang/Object");
+        /* load the classes which were created above */
+        loader_load (class_java_lang_Object->name);
+
+        loader_inited=1; /*JOWENN*/
+
+        class_java_lang_Throwable =
+                loader_load( utf_new_char("java/lang/Throwable") );
+
+        log_text("loader_init:  loader_load: java/lang/ClassCastException");
+        class_java_lang_ClassCastException =
+                loader_load ( utf_new_char ("java/lang/ClassCastException") );
+        class_java_lang_NullPointerException =
+                loader_load ( utf_new_char ("java/lang/NullPointerException") );
+        class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
+             utf_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
+        class_java_lang_NegativeArraySizeException = loader_load (
+             utf_new_char ("java/lang/NegativeArraySizeException") );
+        class_java_lang_OutOfMemoryError = loader_load (
+             utf_new_char ("java/lang/OutOfMemoryError") );
+        class_java_lang_ArrayStoreException =
+                loader_load ( utf_new_char ("java/lang/ArrayStoreException") );
+        class_java_lang_ArithmeticException =
+                loader_load ( utf_new_char ("java/lang/ArithmeticException") );
+        class_java_lang_ThreadDeath =                             /* schani */
+                loader_load ( utf_new_char ("java/lang/ThreadDeath") );
+        /* create classes representing primitive types */
+        create_primitive_classes();
+
+        /* create classes used by the typechecker */
+        create_pseudo_classes();
+
+        /* correct vftbl-entries (retarded loading of class java/lang/String) */
+        stringtable_update();
+#ifdef USE_THREADS
+        if (stackbottom!=0)
+                initLocks();
+#endif
+
 
-       /* create class for arrays */
-       class_array = class_new(utf_new_char("The_Array_Class"));
-    class_array->classUsed = NOTUSED; /* not used initially CO-RT */
-       class_array->impldBy = NULL;
-
-       list_remove (&unloadedclasses, class_array);
-
-       /* create class for strings, load it after class Object was loaded */
-       string_class = utf_new_char("java/lang/String");
-       class_java_lang_String = class_new(string_class);
-    class_java_lang_String->classUsed = NOTUSED; /* not used initially CO-RT */
-       class_java_lang_String->impldBy = NULL;
-
-       list_remove(&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_Object = 
-               loader_load(utf_new_char("java/lang/Object"));
-
-       list_addlast(&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_String =
-               loader_load(string_class);
-       class_java_lang_ClassCastException = 
-               loader_load(utf_new_char("java/lang/ClassCastException"));
-       class_java_lang_NullPointerException = 
-               loader_load(utf_new_char("java/lang/NullPointerException"));
-       class_java_lang_ArrayIndexOutOfBoundsException =
-               loader_load(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
-       class_java_lang_NegativeArraySizeException =
-               loader_load(utf_new_char("java/lang/NegativeArraySizeException"));
-       class_java_lang_OutOfMemoryError =
-               loader_load(utf_new_char("java/lang/OutOfMemoryError"));
-       class_java_lang_ArrayStoreException =
-               loader_load(utf_new_char("java/lang/ArrayStoreException"));
-       class_java_lang_ArithmeticException = 
-               loader_load(utf_new_char("java/lang/ArithmeticException"));
-       class_java_lang_ThreadDeath =
-               loader_load(utf_new_char("java/lang/ThreadDeath"));
-
-       /* link class for arrays */
-       list_addlast(&unlinkedclasses, class_array);
-       class_array->super = class_java_lang_Object;
-       class_link(class_array);
-
-       /* correct vftbl-entries (retarded loading of class java/lang/String) */
-       stringtable_update(); 
-
-       /* create classes representing primitive types */
-       create_primitive_classes();
-               
-       proto_java_lang_ClassCastException = 
-               builtin_new(class_java_lang_ClassCastException);
-       heap_addreference((void**) &proto_java_lang_ClassCastException);
 
-       proto_java_lang_NullPointerException = 
-               builtin_new(class_java_lang_NullPointerException);
-       heap_addreference((void**) &proto_java_lang_NullPointerException);
+        log_text("loader_init: creating global proto_java_lang_ClassCastException");
+        proto_java_lang_ClassCastException =
+                builtin_new(class_java_lang_ClassCastException);
+        heap_addreference ( (void**) &proto_java_lang_ClassCastException);
 
-       proto_java_lang_ArrayIndexOutOfBoundsException = 
-               builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
-       heap_addreference((void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
+        log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
 
-       proto_java_lang_NegativeArraySizeException = 
-               builtin_new(class_java_lang_NegativeArraySizeException);
-       heap_addreference((void**) &proto_java_lang_NegativeArraySizeException);
+        proto_java_lang_NullPointerException =
+               builtin_new(class_java_lang_NullPointerException);
+        heap_addreference ( (void**) &proto_java_lang_NullPointerException);
+        log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
 
-       proto_java_lang_OutOfMemoryError = 
-               builtin_new(class_java_lang_OutOfMemoryError);
-       heap_addreference((void**) &proto_java_lang_OutOfMemoryError);
+        proto_java_lang_ArrayIndexOutOfBoundsException =
+                builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
 
-       proto_java_lang_ArithmeticException = 
-               builtin_new(class_java_lang_ArithmeticException);
-       heap_addreference((void**) &proto_java_lang_ArithmeticException);
+        proto_java_lang_NegativeArraySizeException =
+                builtin_new(class_java_lang_NegativeArraySizeException);
+        heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
 
-       proto_java_lang_ArrayStoreException = 
-               builtin_new(class_java_lang_ArrayStoreException);
-       heap_addreference((void**) &proto_java_lang_ArrayStoreException);
+        proto_java_lang_OutOfMemoryError =
+                builtin_new(class_java_lang_OutOfMemoryError);
+        heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
 
-       proto_java_lang_ThreadDeath =
-               builtin_new(class_java_lang_ThreadDeath);
-       heap_addreference((void**) &proto_java_lang_ThreadDeath);
+        proto_java_lang_ArithmeticException =
+               builtin_new(class_java_lang_ArithmeticException);
+        heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
+
+        proto_java_lang_ArrayStoreException =
+                builtin_new(class_java_lang_ArrayStoreException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
+
+        proto_java_lang_ThreadDeath =                             /* schani */
+                builtin_new(class_java_lang_ThreadDeath);
+        heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
+
+        loader_inited = 1;
 
-       loader_inited = 1;
 }
 
 
@@ -2695,6 +3283,7 @@ static void loader_compute_class_values (classinfo *c)
                subs = subs->nextsub;
                }
        c->vftbl->diffval = classvalue - c->vftbl->baseval;
+       
        /*
        {
        int i;
@@ -2705,6 +3294,7 @@ static void loader_compute_class_values (classinfo *c)
        printf("\n");
        }
        */
+       
 }
 
 
index 06213ca23560b8f56f15d0a5311823849f89f5a2..1e249fcd02516adb6f59beb42f9e675fd31c195f 100644 (file)
--- a/loader.h
+++ b/loader.h
@@ -26,8 +26,7 @@
 
    Authors: Reinhard Grafl
 
-   $Id: loader.h 593 2003-11-09 19:50:55Z twisti $
-
+   $Id: loader.h 664 2003-11-21 18:24:01Z jowenn $
 */
 
 
@@ -91,19 +90,29 @@ void class_init(classinfo *c);
 void class_showconstanti(classinfo *c, int ii);
 
 /* debug purposes */
-void class_showconstantpool(classinfo *c);
-void class_showmethods(classinfo *c);
+void class_showmethods (classinfo *c);
+void class_showconstantpool (classinfo *c);
+void print_arraydescriptor(FILE *file,arraydescriptor *desc);
 
 classinfo *loader_load(utf *topname);
 
 /* set buffer for reading classdata */
 void classload_buffer(u1 *buf,int len);
 
-/* create class representing specific arraytype */
+/* return the primitive class inidicated by the given signature character */
+classinfo *class_primitive_from_sig(char sig);
+
+/* return the class indicated by the given descriptor */
+#define CLASSLOAD_SKIP  0
+#define CLASSLOAD_NEW   1
+#define CLASSLOAD_LOAD  2
+classinfo *class_from_descriptor(char *utf_ptr,char *end_ptr,char **next,int mode);
+
+/* create class representing specific arraytype */ /* XXX delete */
 classinfo *create_array_class(utf *u);
 
-/* create the arraydescriptor for the arraytype specified by the utf-string */
-constant_arraydescriptor * buildarraydescriptor(char *utf, u4 namelen);
+/* (used by class_new, don't use directly) */
+void class_new_array(classinfo *c);
 
 void class_link(classinfo *c);
 
@@ -111,6 +120,9 @@ void field_display(fieldinfo *f);
 
 void method_display(methodinfo *m);
 
+utf* clinit_desc();
+utf* clinit_name();
+
 #endif /* _LOADER_H */
 
 
diff --git a/main.c b/main.c
index 0e1c462a79f961ac4b4dfa208a87a135b4608cef..55537b6d3075412a8a76da3e91a3ddfce3fceb78 100644 (file)
--- a/main.c
+++ b/main.c
@@ -37,7 +37,7 @@
      - Calling the class loader
      - Running the main method
 
-   $Id: main.c 657 2003-11-20 15:18:33Z carolyn $
+   $Id: main.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -759,16 +759,26 @@ int main(int argc, char **argv)
        if (verbose) {
                log_text("CACAO started -------------------------------------------------------");
        }
-       
-       suck_init(classpath);
-       native_setclasspath(classpath);
+
+       suck_init (classpath);
+       native_setclasspath (classpath);
                
        tables_init();
        heap_init(heapsize, heapstartsize, &dummy);
+
+       
+       
+       log_text("calling jit_init");
        jit_init();
-       loader_init();
 
-       native_loadclasses();
+
+
+       log_text("calling loader_init");
+
+       loader_init((u1*)&dummy);
+
+       log_text("calling native_loadclasses");
+       native_loadclasses ();
 
 
        /*********************** Load JAVA classes  ***************************/
@@ -793,12 +803,14 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       gc_init();
 
+
+       gc_init();      
 #ifdef USE_THREADS
        initThreads((u1*) &dummy);                   /* schani */
 #endif
 
+
        /************************* Start worker routines ********************/
 
        if (startit) {
@@ -819,7 +831,11 @@ int main(int argc, char **argv)
                for (i = opt_ind; i < argc; i++) {
                        a->data[i - opt_ind] = javastring_new(utf_new_char(argv[i]));
                }
-               local_exceptionptr = asm_calljavamethod(mainmethod, a, NULL, NULL, NULL);
+
+
+               /*class_showmethods(currentThread->group->header.vftbl->class); */
+       
+               local_exceptionptr = asm_calljavamethod (mainmethod, a, NULL, NULL, NULL );
        
                if (local_exceptionptr) {
                        printf("Exception in thread \"main\" ");
index 1dc65103c1991c51e5d77f76f8a737f211d54726..a06724a7d16dffed725af7cb4f8468fcbd4096d5 100644 (file)
--- a/native.c
+++ b/native.c
    The .hh files created with the header file generator are all
    included here as are the C functions implementing these methods.
 
-   $Id: native.c 595 2003-11-09 20:04:01Z twisti $
+   $Id: native.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
-
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
@@ -46,6 +45,7 @@
 #include <utime.h>
 #include <sys/utsname.h>
 
+#include "config.h"
 #include "global.h"
 #include "native.h"
 #include "nativetypes.hh"
@@ -68,6 +68,7 @@
 #endif
 #include <sys/stat.h>
 
+#include "../threads/threadio.h"                    
 
 /* searchpath for classfiles */
 static char *classpath;
@@ -78,7 +79,9 @@ static char *classpath;
 /******************** systemclasses required for native methods ***************/
 
 static classinfo *class_java_lang_Class;
-static classinfo *class_java_lang_Cloneable;
+static classinfo *class_java_lang_VMClass;
+static methodinfo *method_vmclass_init;
+/* static classinfo *class_java_lang_Cloneable=0; */ /* now in global.h */
 static classinfo *class_java_lang_CloneNotSupportedException;
 static classinfo *class_java_lang_System;
 static classinfo *class_java_lang_ClassLoader;
@@ -118,16 +121,36 @@ java_objectheader* exceptionptr = NULL;
 
 void use_class_as_object(classinfo *c) 
 {
-       vftbl *vt = class_java_lang_Class->vftbl;
-       vftbl *newtbl;
-       if (!c->classvftbl) {
-               c->classvftbl = true;
-               copy_vftbl(&newtbl, vt);
-               newtbl->class = c->header.vftbl->class;
-               newtbl->baseval = c->header.vftbl->baseval;
-               newtbl->diffval = c->header.vftbl->diffval;
-               c->header.vftbl = newtbl;
-       }
+        if (!class_java_lang_Class)
+                class_java_lang_Class =
+                        class_new ( utf_new_char ("java/lang/Class") );
+        vftbl *vt = class_java_lang_Class->vftbl;
+        vftbl *newtbl;
+        if (!c->classvftbl) {
+                c->classvftbl = true;
+                copy_vftbl(&newtbl, vt);
+                newtbl->class = c->header.vftbl->class;
+                newtbl->baseval = c->header.vftbl->baseval;
+                newtbl->diffval = c->header.vftbl->diffval;
+                c->header.vftbl = newtbl;
+        }
+        
+       if (!class_java_lang_VMClass) {
+               class_java_lang_VMClass =
+                                class_new ( utf_new_char("java/lang/VMClass"));
+                method_vmclass_init = 
+                               class_findmethod(class_java_lang_VMClass,utf_new_char("<init>"),
+                                       utf_new_char("(Lgnu/classpath/RawData;)V"));
+                if (method_vmclass_init==0) {
+                       class_showmethods(class_java_lang_VMClass);
+                        panic("Needed class initializer for VMClass could not be found");
+                }
+        }
+        {
+                java_objectheader *vmo = builtin_new (class_java_lang_VMClass);
+                asm_calljavamethod (method_vmclass_init, vmo, c, NULL, NULL);
+                c->vmClass=(java_lang_VMClass*)vmo;
+        }
 }
 
 /*********************** include Java Native Interface ************************/ 
@@ -136,54 +159,34 @@ void use_class_as_object(classinfo *c)
 
 /*************************** include native methods ***************************/ 
 
-#include "nat/Object.c"
-#include "nat/String.c"
-#include "nat/ClassLoader.c"
-#include "nat/Class.c"
-#include "nat/Compiler.c"
-#include "nat/Double.c"
-#include "nat/Float.c"
-#include "nat/Math.c"
-#include "nat/Package.c"
 #include "nat/Runtime.c"
-#include "nat/SecurityManager.c"
-#include "nat/System.c"
 #include "nat/Thread.c"
-#include "nat/Throwable.c"
-#include "nat/Finalizer.c"
-#include "nat/Array.c"
-#include "nat/Constructor.c"
-#include "nat/Field.c"
+#include "nat/VMClass.c"
 #include "nat/Method.c"
-#include "nat/FileDescriptor.c"
-#include "nat/FileInputStream.c"
-#include "nat/FileOutputStream.c"
-#include "nat/FileSystem.c"
-#include "nat/ObjectInputStream.c"
-#include "nat/ObjectStreamClass.c"
-#include "nat/RandomAccessFile.c"
-#include "nat/ResourceBundle.c"
-#include "nat/JarFile.c"
-#include "nat/Adler32.c"
-#include "nat/CRC32.c"
-#include "nat/Deflater.c"
-#include "nat/Inflater.c"
-#include "nat/ZipEntry.c"
-#include "nat/ZipFile.c"
-#include "nat/BigInteger.c"
-#include "nat/InetAddress.c"
-#include "nat/InetAddressImpl.c"
-#include "nat/DatagramPacket.c"
-#include "nat/PlainDatagramSocketImpl.c"
-#include "nat/PlainSocketImpl.c"
-#include "nat/SocketInputStream.c"
-#include "nat/SocketOutputStream.c"
-#include "nat/AccessController.c"
-#include "nat/ClassLoader_NativeLibrary.c"
-#include "nat/UnixFileSystem.c"
-
+#include "nat/VMSecurityManager.c"
+#include "nat/VMClassLoader.c"
+#include "nat/VMObject.c"
+#include "nat/Proxy.c"
+#include "nat/Field.c"
+#include "nat/VMSystem.c"
+#include "nat/Constructor.c"
+#include "nat/FileChannelImpl.c"
+#include "nat/VMObjectStreamClass.c"
+#include "nat/JOWENNTest1.c"
+
+#ifdef USE_GTK 
+#include "nat/GdkGraphics.c"
+#include "nat/GtkComponentPeer.c"
+#include "nat/GdkPixbufDecoder.c"
+#include "nat/GtkScrollPanePeer.c"
+#include "nat/GtkFileDialogPeer.c"
+#include "nat/GtkLabelPeer.c"
+#endif
 /************************** tables for methods ********************************/
 
+#undef JOWENN_DEBUG
+#undef JOWENN_DEBUG1
+
 /* table for locating native methods */
 static struct nativeref {
        char *classname;
@@ -235,13 +238,25 @@ static bool nativecompdone = false;
 
 void native_loadclasses()
 {
+       static int classesLoaded=0; /*temporary hack JoWenn*/
+       if (classesLoaded) return;
+       classesLoaded=1;
+/*     log_text("loadclasses entered");*/
+
+
+       /*class_java_lang_System =*/
+               (void)class_new ( utf_new_char ("java/lang/VMClass") );/*JoWenn*/
+               (void)class_new ( utf_new_char ("java/lang/Class") );/*JoWenn*/
        /* class_new adds the class to the list of classes to be loaded */
-       class_java_lang_Cloneable = 
-               class_new(utf_new_char("java/lang/Cloneable"));
+       if (!class_java_lang_Cloneable)
+               class_java_lang_Cloneable = 
+                       class_new ( utf_new_char ("java/lang/Cloneable") );
+/*     log_text("loadclasses: class_java_lang_Cloneable has been initialized");*/
        class_java_lang_CloneNotSupportedException = 
-               class_new(utf_new_char("java/lang/CloneNotSupportedException"));
-       class_java_lang_Class =
-               class_new(utf_new_char("java/lang/Class"));
+               class_new ( utf_new_char ("java/lang/CloneNotSupportedException") );
+       if (!class_java_lang_Class)
+               class_java_lang_Class =
+                       class_new ( utf_new_char ("java/lang/Class") );
        class_java_io_IOException = 
                class_new(utf_new_char("java/io/IOException"));
        class_java_io_FileNotFoundException = 
@@ -257,13 +272,12 @@ void native_loadclasses()
        class_java_lang_ClassFormatError =
                class_new(utf_new_char("java/lang/ClassFormatError"));  
        class_java_io_SyncFailedException =
-               class_new(utf_new_char("java/io/SyncFailedException"));
-       class_java_io_UnixFileSystem =
-               class_new(utf_new_char("java/io/UnixFileSystem"));
-       class_java_lang_System =
-               class_new(utf_new_char("java/lang/System"));
+               class_new ( utf_new_char ("java/io/SyncFailedException") );
+               
+/*     log_text("native_loadclasses: class_new(\"java/lang/ClassLoader\")");           */
        class_java_lang_ClassLoader =
-               class_new(utf_new_char("java/lang/ClassLoader"));
+               class_new ( utf_new_char ("java/lang/ClassLoader") );   
+/*     log_text("native_loadclasses: class_new(\"java/security/PrivilegedActionException\")");         */
        class_java_security_PrivilegedActionException =
                class_new(utf_new_char("java/security/PrivilegedActionException"));
 
@@ -283,7 +297,9 @@ void native_loadclasses()
 
        /* load classes for wrapping primitive types */
        class_java_lang_Double =
-               class_new(utf_new_char("java/lang/Double"));
+               class_new( utf_new_char ("java/lang/Double") );
+       class_init(class_java_lang_Double);
+
        class_java_lang_Float =
                class_new(utf_new_char("java/lang/Float"));
        class_java_lang_Character =
@@ -302,12 +318,15 @@ void native_loadclasses()
                class_new(utf_new_char("java/lang/Void"));
 
        /* load to avoid dynamic classloading */
-       class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
+/*JoWenn       class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
        class_new(utf_new_char("sun/net/www/protocol/jar/Handler"));    
-       class_new(utf_new_char("sun/io/CharToByteISO8859_1"));
+       class_new(utf_new_char("sun/io/CharToByteISO8859_1"));*/
        
        /* start classloader */
-       loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); 
+/*JoWenn       loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); */
+
+       classesLoaded=1;
+       log_text("native_loadclasses finished");
 }
 
 
@@ -342,24 +361,7 @@ void systemclassloader_addclass(classinfo *c)
 
 void systemclassloader_addlibrary(java_objectheader *o)
 {
-       methodinfo *m;
-
-       /* find method addElement of java.util.Vector */
-       m = class_resolvemethod(
-                                                       loader_load ( utf_new_char ("java/util/Vector") ),
-                                                       utf_new_char("addElement"),
-                                                       utf_new_char("(Ljava/lang/Object;)V")
-                                                       );
-
-       if (!m) panic("cannot initialize classloader");
-
-       /* call 'addElement' */
-       asm_calljavamethod(m,
-                                          SystemClassLoader->nativeLibraries,
-                                          o,
-                                          NULL,  
-                                          NULL
-                                          );       
+       log_text("systemclassloader_addlibrary");
 }
 
 /*****************************************************************************
@@ -370,15 +372,18 @@ void systemclassloader_addlibrary(java_objectheader *o)
 
 void init_systemclassloader() 
 {
-       if (!SystemClassLoader) {
-               /* create object and call initializer */
-               SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);  
-               heap_addreference((void**) &SystemClassLoader);
-
-               /* systemclassloader has no parent */
-               SystemClassLoader->parent      = NULL;
-               SystemClassLoader->initialized = true;
-       }
+  if (!SystemClassLoader) {
+       native_loadclasses();
+       log_text("Initializing new system class loader");
+       /* create object and call initializer */
+       SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);  
+       heap_addreference((void**) &SystemClassLoader);
+
+       /* systemclassloader has no parent */
+       SystemClassLoader->parent      = NULL;
+       SystemClassLoader->initialized = true;
+  }
+  log_text("leaving system class loader");
 }
 
 
@@ -396,7 +401,7 @@ void systemclassloader_addlibname(java_objectheader *o)
 
        if (!m) panic("cannot initialize classloader");
 
-       id = env.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
+       id = envTable.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
        if (!id) panic("can not access ClassLoader");
 
        asm_calljavamethod(m,
@@ -429,6 +434,24 @@ void throw_classnotfoundexception()
 }
 
 
+void throw_classnotfoundexception2(utf* classname)
+{
+       if (!class_java_lang_ClassNotFoundException) {
+               panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
+       }
+
+       /* throws a ClassNotFoundException */
+       exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
+
+        /*
+        sprintf (logtext, "Loading class: ");
+        utf_sprint (logtext+strlen(logtext), classname);
+        dolog();
+        log_text("Class not found");
+        */
+}
+
+
 /*********************** Function: native_findfunction *************************
 
        Looks up a method (must have the same class name, method name, descriptor
@@ -451,7 +474,7 @@ functionptr native_findfunction(utf *cname, utf *mname,
        int buffer_len;
 
        isstatic = isstatic ? true : false;
-
+       
        if (!nativecompdone) {
                for (i = 0; i < NATIVETABLESIZE; i++) {
                        nativecomptable[i].classname  = 
@@ -468,14 +491,57 @@ functionptr native_findfunction(utf *cname, utf *mname,
                nativecompdone = true;
        }
 
+#ifdef JOWENN_DEBUG
+       buffer_len = 
+         utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "searching matching function in native table:");
+        utf_sprint(buffer+strlen(buffer), mname);
+       strcpy(buffer+strlen(buffer), ": ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), " for class ");
+        utf_sprint(buffer+strlen(buffer), cname);
+
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif
+               
        for (i = 0; i < NATIVETABLESIZE; i++) {
                n = &(nativecomptable[i]);
 
                if (cname == n->classname && mname == n->methodname &&
                    desc == n->descriptor && isstatic == n->isstatic)
                        return n->func;
+#ifdef JOWENN_DEBUG
+                       else {
+                               if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
+                       
+                               else {
+                                       buffer_len = 
+                                         utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
+       
+                                       buffer = MNEW(char, buffer_len);
+
+                                       strcpy(buffer, "comparing with:");
+                                       utf_sprint(buffer+strlen(buffer), n->methodname);
+                                       strcpy (buffer+strlen(buffer), ": ");
+                                       utf_sprint(buffer+strlen(buffer), n->descriptor);
+                                       strcpy(buffer+strlen(buffer), " for class ");
+                                       utf_sprint(buffer+strlen(buffer), n->classname);
+
+                                       log_text(buffer);       
+
+                                       MFREE(buffer, char, buffer_len);
+                       
+                               }
+                       } 
+#endif
        }
 
+               
        /* no function was found, display warning */
 
        buffer_len = 
@@ -494,6 +560,10 @@ functionptr native_findfunction(utf *cname, utf *mname,
 
        MFREE(buffer, char, buffer_len);
 
+
+       exit(1);
+
+       
        return NULL;
 }
 
@@ -515,6 +585,8 @@ java_objectheader *javastring_new (utf *u)
        java_chararray *a;
        s4 i;
        
+/*     log_text("javastring_new");*/
+       
        s = (java_lang_String*) builtin_new (class_java_lang_String);
        a = builtin_newarray_char (utflength);
 
@@ -550,8 +622,9 @@ java_objectheader *javastring_new_char (char *text)
        java_lang_String *s;   /* result-string */
        java_chararray *a;
        
-       s = (java_lang_String*) builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
+       /*log_text("javastring_new_char");*/
+       s = (java_lang_String*) builtin_new (class_java_lang_String);
+       a = builtin_newarray_char (len);
 
        /* javastring or character-array could not be created */
        if ((!a) || (!s)) return NULL;
@@ -587,6 +660,8 @@ char *javastring_tochar (java_objectheader *so)
        java_chararray *a;
        s4 i;
        
+       log_text("javastring_tochar");
+       
        if (!s)
                return "";
        a = s->value;
@@ -635,8 +710,13 @@ java_objectheader *native_new_and_init(classinfo *c)
        methodinfo *m;
        java_objectheader *o = builtin_new(c);          /*          create object */
 
+        /*
+       printf("native_new_and_init ");
+       utf_display(c->name);
+       printf("\n");
+        */
        if (!o) return NULL;
-       
+       /* printf("o!=NULL\n"); */
        /* find initializer */
 
        m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
@@ -679,22 +759,20 @@ void stringtable_update ()
                                                                
                                js = (java_lang_String *) s->string;
                                
-                               if (!js || !(a = js->value)) {
+                               if (!js || !(a = js->value)) 
                                        /* error in hashtable found */
                                        panic("invalid literalstring in hashtable");
 
-                               } else {
-                                       if (!js->header.vftbl) 
-                                               /* vftbl of javastring is NULL */ 
-                                               js->header.vftbl = class_java_lang_String -> vftbl;
+                               if (!js->header.vftbl) 
+                                       /* vftbl of javastring is NULL */ 
+                                       js->header.vftbl = class_java_lang_String -> vftbl;
 
-                                       if (!a->header.objheader.vftbl) 
-                                               /* vftbl of character-array is NULL */ 
-                                               a->header.objheader.vftbl = class_array -> vftbl;
+                               if (!a->header.objheader.vftbl) 
+                                       /* vftbl of character-array is NULL */ 
+                                       a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
 
-                                       /* follow link in external hash chain */
-                                       s = s->hashlink;
-                               }
+                               /* follow link in external hash chain */
+                               s = s->hashlink;
                        }       
                }               
        }
@@ -747,12 +825,17 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
        utf *result;  /* resulting utf-string */
        int i;          
 
-       /* determine utf length in bytes and allocate memory */         
+       /* determine utf length in bytes and allocate memory */
+       /* printf("utf_new_u2: unicode_length=%d\n",unicode_length);            */
        buflength = u2_utflength(unicode_pos, unicode_length); 
        buffer    = MNEW(char,buflength);
  
        /* memory allocation failed */
-       if (!buffer) return NULL;
+       if (!buffer) {
+               printf("length: %d\n",buflength);
+               log_text("utf_new_u2:buffer==NULL");
+               return NULL;
+       }
 
        left = buflength;
        pos  = buffer;
@@ -793,6 +876,7 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
        
        /* insert utf-string into symbol-table */
        result = utf_new(buffer,buflength);
+
        MFREE(buffer, char, buflength);
        return result;
 }
@@ -806,7 +890,9 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
 utf *javastring_toutf(java_lang_String *string, bool isclassname)
 {
         java_lang_String *str = (java_lang_String *) string;
-       return utf_new_u2(str->value->data,str->count, isclassname);
+/*     printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count);
+       fflush(stdout);*/
+       return utf_new_u2(str->value->data+str->offset,str->count, isclassname);
 }
 
 /********************* function: literalstring_u2 *****************************
@@ -828,6 +914,11 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
     u4 slot;  
     u2 i;
 
+#if JOWENN_DEBUG1
+    printf("literalstring_u2: length: %d\n",length);    
+    log_text("literalstring_u2");
+#endif
+    
     /* find location in hashtable */
     key  = unicode_hashkey (a->data, length);
     slot = key & (string_hash.size-1);
@@ -846,6 +937,10 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
        if (!copymode)
          lit_mem_free(a, sizeof(java_chararray) + sizeof(u2)*(length-1)+10);
 
+#ifdef JOWENN_DEBUG1
+       log_text("literalstring_u2: foundentry");
+       utf_display(javastring_toutf(js,0));
+#endif
        return (java_objectheader *) js;
       }
 
@@ -864,10 +959,8 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
       stringdata = a;
 
     /* location in hashtable found, complete arrayheader */
-    if (class_array==NULL) panic("class_array not initialized");
-    stringdata -> header.objheader.vftbl = class_array -> vftbl;
+    stringdata -> header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
     stringdata -> header.size = length;        
-    stringdata -> header.arraytype = ARRAYTYPE_CHAR;   
 
     /* create new javastring */
     js = LNEW (java_lang_String);
@@ -919,6 +1012,10 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
       MFREE (string_hash.ptr, void*, string_hash.size);
       string_hash = newhash;
     }
+#ifdef JOWENN_DEBUG1
+       log_text("literalstring_u2: newly created");
+/*     utf_display(javastring_toutf(js,0));*/
+#endif
                        
     return (java_objectheader *) js;
 }
@@ -936,7 +1033,10 @@ java_objectheader *literalstring_new (utf *u)
     u4 utflength  = utf_strlen(u);   /* length of utf-string if uncompressed */
     java_chararray *a;               /* u2-array constructed from utf string */
     u4 i;
-    
+/*    log_text("literalstring_new"); */
+/*    utf_display(u);*/
+    /*if (utflength==0) while (1) sleep(60);*/
+/*    log_text("------------------");    */
     /* allocate memory */ 
     a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 ); 
     /* convert utf-string to u2-array */
@@ -970,9 +1070,16 @@ void literalstring_free (java_objectheader* sobj)
 
 void copy_vftbl(vftbl **dest, vftbl *src)
 {
-       *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr) * (src->vftbllength - 1));
+    *dest = src;
+#if 0
+    /* XXX this kind of copying does not work (in the general
+     * case). The interface tables would have to be copied, too. I
+     * don't see why we should make a copy anyway. -Edwin
+     */
+       *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
        memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
        memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
+#endif
 }
 
 /*****************************************************************************/
@@ -985,22 +1092,22 @@ void printNativeCall(nativeCall nc) {
 
   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
   for (i=0; i<nc.methCnt; i++) {  
-    printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
+      printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
 
     for (j=0; j<nc.callCnt[i]; j++) {  
-      printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
+        printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
        nc.methods[i].methodCalls[j].classname, 
        nc.methods[i].methodCalls[j].methodname, 
        nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
       }
     }
-printf("-+++++--------------------\n");fflush(stdout);
+  printf("-+++++--------------------\n");fflush(stdout);
 }
 
 /*--------------------------------------------------------*/
 void printCompNativeCall(nativeCompCall nc) {
   int i,j;
-printf("printCompNativeCall BEGIN\n");fflush(stdout);
+  printf("printCompNativeCall BEGIN\n");fflush(stdout); 
   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
   utf_display(nc.classname); fflush(stdout);
   
index f60b6972191e6c3a1031cfa5f9c9be0be53c9b0c..83dca4018aef096b9a9ec7e33a401957b9077cb4 100644 (file)
--- a/native.h
+++ b/native.h
@@ -57,6 +57,8 @@ void stringtable_update();
 /* throw classnotfoundexcetion */
 void throw_classnotfoundexception();
 
+void throw_classnotfoundexception2(utf* classname);
+
 /* make utf symbol from javastring */
 utf *javastring_toutf(struct java_lang_String *string, bool isclassname);
 
index 771873dd1f1f74deab669b68dddb34f39231bb53..2ca6ddc0660afc760777b888ee2efd25fc2a58a1 100644 (file)
@@ -37,7 +37,7 @@
      - Calling the class loader
      - Running the main method
 
-   $Id: cacao.c 657 2003-11-20 15:18:33Z carolyn $
+   $Id: cacao.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -759,16 +759,26 @@ int main(int argc, char **argv)
        if (verbose) {
                log_text("CACAO started -------------------------------------------------------");
        }
-       
-       suck_init(classpath);
-       native_setclasspath(classpath);
+
+       suck_init (classpath);
+       native_setclasspath (classpath);
                
        tables_init();
        heap_init(heapsize, heapstartsize, &dummy);
+
+       
+       
+       log_text("calling jit_init");
        jit_init();
-       loader_init();
 
-       native_loadclasses();
+
+
+       log_text("calling loader_init");
+
+       loader_init((u1*)&dummy);
+
+       log_text("calling native_loadclasses");
+       native_loadclasses ();
 
 
        /*********************** Load JAVA classes  ***************************/
@@ -793,12 +803,14 @@ int main(int argc, char **argv)
                exit(1);
        }
 
-       gc_init();
 
+
+       gc_init();      
 #ifdef USE_THREADS
        initThreads((u1*) &dummy);                   /* schani */
 #endif
 
+
        /************************* Start worker routines ********************/
 
        if (startit) {
@@ -819,7 +831,11 @@ int main(int argc, char **argv)
                for (i = opt_ind; i < argc; i++) {
                        a->data[i - opt_ind] = javastring_new(utf_new_char(argv[i]));
                }
-               local_exceptionptr = asm_calljavamethod(mainmethod, a, NULL, NULL, NULL);
+
+
+               /*class_showmethods(currentThread->group->header.vftbl->class); */
+       
+               local_exceptionptr = asm_calljavamethod (mainmethod, a, NULL, NULL, NULL );
        
                if (local_exceptionptr) {
                        printf("Exception in thread \"main\" ");
index 6c3bfb2b2eeb6121e9b30e6e7c63c70e48a30fe6..c78c767aec7a24afb786dfaef0c8eec690710e2a 100644 (file)
@@ -29,7 +29,7 @@
    Changes: Mark Probst
             Philipp Tomsich
 
-   $Id: headers.c 583 2003-11-09 19:14:31Z twisti $
+   $Id: headers.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -55,7 +55,14 @@ java_objectheader *javastring_new (utf *text)         /* schani */
 
 void throw_classnotfoundexception() 
 { 
-       panic("class not found"); 
+       panic("class not found----------"); 
+}
+/*  */
+void throw_classnotfoundexception2(utf* classname) 
+{ 
+       sprintf (logtext, "Loading class: ");
+        utf_sprint (logtext+strlen(logtext), classname);
+       panic("******class not found"); 
 }
 
 java_objectheader *literalstring_new (utf *u)
@@ -82,13 +89,14 @@ s8 asm_builtin_d2l(double a) { return 0; }
 void asm_builtin_monitorenter(java_objectheader *o) {}
 void asm_builtin_monitorexit(java_objectheader *o) {}
 
-s4 asm_builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *d) {return 0;}
+s4 asm_builtin_checkarraycast(java_objectheader *o,arraydescriptor *d) {return 0;}
 
 #if defined(__I386__)
 s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class) { return 0; }
-void asm_builtin_anewarray(s4 size, classinfo *elementtype) {}
-void asm_builtin_newarray_array(s4 size, constant_arraydescriptor *elementdesc) {}
+
+void asm_builtin_newarray (s4 size, vftbl *arrayvftbl) {}
 #endif
+
 void asm_builtin_aastore(java_objectarray *a, s4 index, java_objectheader *o) {}
 
 u1 *createcompilerstub(methodinfo *m) {return NULL;}
@@ -310,7 +318,11 @@ static void printmethod (methodinfo *m)
                printID (m->class->name);
                fprintf (file, "* this ");
 
-       };
+           } 
+       else
+           {
+               fprintf (file, ", jclass clazz ");
+           }
 
        if ((*utf_ptr)!=')') fprintf (file, ", "); 
                        
@@ -326,24 +338,17 @@ static void printmethod (methodinfo *m)
 
 /****************** remove package-name in fully-qualified classname *********************/
 
-static void simple_classname(char *buffer, utf *u)
+static void gen_header_filename(char *buffer, utf *u)
 {
-       int i, simplename_start;
-
-       for (i=utf_strlen(u)-1; i>=0; i--) { 
-
-               if (u->text[i] == '$') u->text[i] = '_'; else /* convert '$' to '_' */
-                       if (u->text[i] == '/') {
-                               /* beginning of simple name */
-                               simplename_start = i+1;
-                               break;
-                       }
-       }
-
-       for (i=simplename_start; i < utf_strlen(u); i++) 
-               buffer[i-simplename_start] = u->text[i];
-
-       buffer[i-simplename_start] = '\0';                
+  int i, simplename_start;
+  int slash_cnt=0;
+
+  
+  for (i=0;i<utf_strlen(u);i++) {
+       if ((u->text[i] == '/') || (u->text[i] == '$')) buffer[i] = '_';  /* convert '$' and '/' to '_' */
+       else buffer[i]=u->text[i];
+  }
+  buffer[utf_strlen(u)]='\0';
 }
 
 /*********** create headerfile for classes and store native methods in chain ************/
@@ -359,7 +364,7 @@ static void headerfile_generate (classinfo *c)
        chain_addlast (nativeclass_chain, c);                                                           
                                
        /* open headerfile for class */
-       simple_classname(classname,c->name);                                                                                                                                            
+       gen_header_filename(classname,c->name);                                                                                                                                         
 
        /* create chain for renaming fields */
        ident_chain = chain_new ();
@@ -468,7 +473,7 @@ static void headers_finish ()
        while (c) {
        
                dopadding=false;
-               simple_classname(classname,c->name);                                                                                                                                                                                    
+               gen_header_filename(classname,c->name);                                                                                                                                                                                 
                fprintf(file,"#include \"nat/%s.h\"\n",classname);              
                c = chain_next (nativeclass_chain);             
        }
@@ -561,15 +566,19 @@ int main(int argc, char **argv)
        
        fprintf(file, "/* This file is machine generated, don't edit it !*/\n\n"); 
 
-       fprintf(file, "#define offobjvftbl    %3d\n", (int) OFFSET(java_objectheader, vftbl));
-       fprintf(file, "#define offarraysize   %3d\n", (int) OFFSET(java_arrayheader, size));
-       fprintf(file, "#define offobjarrdata  %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
-       fprintf(file, "#define offbaseval     %3d\n", (int) OFFSET(vftbl, baseval));
-       fprintf(file, "#define offdiffval     %3d\n", (int) OFFSET(vftbl, diffval));
+       fprintf (file, "#define offobjvftbl    %3d\n", (int) OFFSET(java_objectheader, vftbl));
+       fprintf (file, "#define offarraysize   %3d\n", (int) OFFSET(java_arrayheader, size));
+       fprintf (file, "#define offobjarrdata  %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
+       fprintf (file, "#define offbaseval     %3d\n", (int) OFFSET(vftbl, baseval));
+       fprintf (file, "#define offdiffval     %3d\n\n", (int) OFFSET(vftbl, diffval));
 
-       fclose(file);
+       fprintf (file, "#define offjniitemtype %3d\n", (int) OFFSET(jni_callblock, itemtype));
+       fprintf (file, "#define offjniitem     %3d\n", (int) OFFSET(jni_callblock, item));
+       fprintf (file, "#define sizejniblock   %3d\n\n", (int) sizeof(jni_callblock));
 
-       suck_init(classpath);
+       fclose (file);
+
+       suck_init (classpath);
    
        tables_init();
        heap_init(heapsize, heapsize, &dummy);
@@ -616,6 +625,13 @@ int main(int argc, char **argv)
 }
 
 
+void setVMClassField(classinfo *c)
+{
+}
+
+
+void* Java_java_lang_VMObject_clone ( void *env ,  void  *clazz, void * this){return 0;}
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index d504479b89f425c304ec0b481ab62735cb66e068..7730cd67b5667f9dd8cb73a08778a9651c26da5a 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: ?
 
-   $Id: jni.c 557 2003-11-02 22:51:59Z twisti $
+   $Id: jni.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -37,6 +37,7 @@
 
 #define JNI_VERSION       0x00010002
 
+#include <jit/jit.h>
 
 /********************* accessing instance-fields **********************************/
 
 #define getField(obj,typ,var)     *((typ*) ((long int) obj + (long int) var->offset))
 #define setfield_critical(clazz,obj,name,sig,jdatatype,val) setField(obj,jdatatype,getFieldID_critical(env,clazz,name,sig),val); 
 
+
+
+u4 get_parametercount(methodinfo *m)
+{
+    utf  *descr    =  m->descriptor;    /* method-descriptor */
+    char *utf_ptr  =  descr->text;      /* current position in utf-text */
+    char *desc_end =  utf_end(descr);   /* points behind utf string     */
+    java_objectarray* result;
+    int parametercount = 0;
+   int i;
+
+    /* skip '(' */
+    utf_nextu2(&utf_ptr);
+
+    /* determine number of parameters */
+    while ( *utf_ptr != ')' ) {
+        get_type(&utf_ptr,desc_end,true);
+        parametercount++;
+    }
+
+    return parametercount;
+}
+
+
+
+void fill_callblock(void *obj,utf *descr,jni_callblock blk[], va_list data, char ret) {
+    char *utf__ptr  =  descr->text;      /* current position in utf-text */
+    char **utf_ptr  =  &utf__ptr;
+    char *desc_end =  utf_end(descr);   /* points behind utf string     */
+
+    int cnt;
+
+    jdouble d;
+    jlong l;
+    u4 dummy;
+    char c;
+       /*
+    log_text("fill_callblock");
+    utf_display(descr);
+    log_text("====");
+       */
+    /* skip '(' */
+    utf_nextu2(utf_ptr);
+
+    /* determine number of parameters */
+   if (obj) {
+          blk[0].itemtype=TYPE_ADR;
+          blk[0].item=(u8)(u4)obj;
+          cnt=1;
+   } else cnt=0;
+   while ( **utf_ptr != ')' ) {
+       if (*utf_ptr>=desc_end)
+               panic("illegal method descriptor");
+
+       switch (utf_nextu2(utf_ptr)) {
+       /* primitive types */
+             case 'B' :
+             case 'C' :
+             case 'S' : 
+             case 'Z' :
+                        blk[cnt].itemtype=TYPE_INT;
+                        blk[cnt].item=(u8) va_arg(data,int);
+                        break;
+             case 'I' :
+                        blk[cnt].itemtype=TYPE_INT;
+                        dummy=va_arg(data,u4);
+                        /*printf("fill_callblock: pos:%d, value:%d\n",cnt,dummy);*/
+                        blk[cnt].item=(u8)dummy;
+
+                        break;
+
+             case 'J' : 
+                        blk[cnt].itemtype=TYPE_LNG;
+                        blk[cnt].item=(u8)va_arg(data,jlong);
+                                break;
+             case 'F' : 
+                        blk[cnt].itemtype=TYPE_FLT;
+                        *((jfloat*)(&blk[cnt].item))=((jfloat)va_arg(data,jdouble));
+                        break;
+
+             case 'D' : 
+                        blk[cnt].itemtype=TYPE_DBL;
+                        *((jdouble*)(&blk[cnt].item))=(jdouble)va_arg(data,jdouble);
+                        break;
+             case 'V' : panic ("V not allowed as function parameter");
+                        break;
+             case 'L' : {
+                           char *start = *utf_ptr;
+                           while (utf_nextu2(utf_ptr)!=';')
+
+                           blk[cnt].itemtype=TYPE_ADR;
+                           blk[cnt].item=(u8)(u4)va_arg(data,void*);
+                           break;                      
+                        }
+             case '[' : {
+                         /* XXX */
+                           /* arrayclass */
+                                   char *start = *utf_ptr;
+                           char ch;
+                           while ((ch = utf_nextu2(utf_ptr))=='[')
+                           if (ch == 'L') {
+                               while (utf_nextu2(utf_ptr)!=';') {}
+                                   }
+       
+                            ch=utf_nextu2(utf_ptr);
+                           blk[cnt].itemtype=TYPE_ADR;
+                           blk[cnt].item=(u8)(u4)va_arg(data,void*);
+                           break;                      
+                        }
+       }
+       cnt++;
+   }
+
+   /*the standard doesn't say anything about return value checking, but it appears to be usefull*/
+   c=utf_nextu2(utf_ptr);
+   c=utf_nextu2(utf_ptr);
+   /*printf("%c  %c\n",ret,c);*/
+   if (ret=='O') {
+       if (!((c=='L') || (c=='['))) log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+   } else if (ret != c) log_text("\n====\nWarning call*Method called for function with wrong return type\n====");
+
+}
+
+
+
+jmethodID get_virtual(jobject obj,jmethodID methodID) {
+       if (obj->vftbl->class==methodID->class) return methodID;
+       return class_resolvemethod (obj->vftbl->class, methodID->name, methodID->descriptor);
+}
+
+jmethodID get_nonvirtual(jclass clazz,jmethodID methodID) {
+       if (clazz==methodID->class) return methodID;
+       return class_resolvemethod (clazz, methodID->name, methodID->descriptor);
+}
+
+jobject callObjectMethod (jobject obj, jmethodID methodID, va_list args)
+{      
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jobject ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+       
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,'O');
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+}
+
+
+/*core function for integer class methods (bool,byte,short,integer
+  This is basically needed for i386*/
+jint callIntegerMethod (jobject obj, jmethodID methodID, char retType, va_list args) {
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jint ret;
+
+/*     printf("%p,     %c\n",retType,methodID,retType);*/
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        
+       argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,retType);
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=(jint)asm_calljavafunction2(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
+/*core function for long class functions*/
+jlong callLongMethod (jobject obj, jmethodID methodID, va_list args) {
+        int argcount;
+        int i;
+        jni_callblock *blk;
+        jlong ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+       if (methodID==0) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError); 
+               return 0;
+       }
+        argcount=get_parametercount(methodID);
+
+       if (!( ((methodID->flags & ACC_STATIC) && (obj==0)) ||
+               ((!(methodID->flags & ACC_STATIC)) && (obj!=0)) )) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+       if (obj && (! builtin_instanceof(obj,methodID->class))) {
+               exceptionptr = native_new_and_init(class_java_lang_NoSuchMethodError);
+               return 0;
+       }
+
+
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,'L');
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2long(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
+/*core function for float class methods (float,double)*/
+jdouble callFloatMethod (jobject obj, jmethodID methodID, va_list args,char retType) {
+        int argcount=get_parametercount(methodID);
+        int i;
+        jni_callblock *blk;
+        jdouble ret;
+
+        /*
+        log_text("JNI-Call: CallObjectMethodV");
+        utf_display(methodID->name);
+        utf_display(methodID->descriptor);
+        printf("\nParmaeter count: %d\n",argcount);
+        utf_display(obj->vftbl->class->name);
+        printf("\n");
+        */
+        if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+                log_text("Too many arguments. CallObjectMethod does not support that");
+                return 0;
+        }
+
+        blk = MNEW(jni_callblock, 4 /*argcount+2*/);
+
+        fill_callblock(obj,methodID->descriptor,blk,args,retType);
+
+        /*      printf("parameter: obj: %p",blk[0].item); */
+        ret=asm_calljavafunction2double(methodID,argcount+1,(argcount+1)*sizeof(jni_callblock),blk);
+        MFREE(blk,jni_callblock,argcount+1);
+        /*      printf("(CallObjectMethodV)-->%p\n",ret); */
+        return ret;
+
+}
+
+
 /*************************** function: jclass_findfield ****************************
        
        searches for field with specified name and type in a 'classinfo'-structur
 fieldinfo *jclass_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
-       for (i = 0; i < c->fieldscount; i++) {
+/*     printf(" FieldCount: %d\n",c->fieldscount);
+       utf_display(c->name); */
+               for (i = 0; i < c->fieldscount; i++) {
+/*             utf_display(c->fields[i].name);
+               printf("\n");
+               utf_display(c->fields[i].descriptor);
+               printf("\n");*/
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
                        return &(c->fields[i]);
                }
@@ -93,7 +428,11 @@ jclass FindClass (JNIEnv* env, const char *name)
 {
        classinfo *c;  
   
-       c = loader_load(utf_new_char ((char *) name));
+       if (strcmp(name,"[B")==0) {
+               c = loader_load(utf_new_char("The_Array_Class"));
+       }
+       else
+               c = loader_load(utf_new_char_classname ((char *) name));
 
        if (!c) exceptionptr = native_new_and_init(class_java_lang_ClassFormatError);
 
@@ -110,7 +449,7 @@ jclass FindClass (JNIEnv* env, const char *name)
   
 jmethodID FromReflectedMethod (JNIEnv* env, jobject method)
 {
-       log_text("JNI-Call: FromReflectedMethod");
+       /* log_text("JNI-Call: FromReflectedMethod"); */
 }
 
 
@@ -140,7 +479,7 @@ jboolean IsAssignableForm (JNIEnv* env, jclass sub, jclass sup)
 
 jobject ToReflectedField (JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
 {
-       log_text("JNI-Call: ToReflectedField");
+       /* log_text("JNI-Call: ToReflectedField"); */
 }
 
 
@@ -291,7 +630,34 @@ jobject AllocObject (JNIEnv* env, jclass clazz)
 
 jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: NewObject");
+        java_objectheader *o;
+       void* args[3];
+       int argcount=get_parametercount(methodID);
+       int i;
+       va_list vaargs;
+
+       /* log_text("JNI-Call: NewObject"); */
+
+       if  (argcount>3) {
+               exceptionptr=native_new_and_init(loader_load(utf_new_char("java/lang/IllegalArgumentException")));
+               log_text("Too many arguments. NewObject does not support that");
+               return 0;
+       }
+
+       
+       o = builtin_new (clazz);         /*          create object */
+       
+        if (!o) return NULL;
+
+       va_start(vaargs,methodID);
+       for (i=0;i<argcount;i++) {
+               args[i]=va_arg(vaargs,void*);
+       }
+       va_end(vaargs);
+       exceptionptr=asm_calljavamethod(methodID,o,args[0],args[1],args[2]);
+
+        return o;
+
 }
 
 /*********************************************************************************** 
@@ -303,7 +669,7 @@ jobject NewObject (JNIEnv* env, jclass clazz, jmethodID methodID, ...)
 
 jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: NewObjectV");
+       /* log_text("JNI-Call: NewObjectV"); */
 }
 
 /*********************************************************************************** 
@@ -316,7 +682,7 @@ jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
 
 jobject NewObjectA (JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
 {
-       log_text("JNI-Call: NewObjectA");
+       /* log_text("JNI-Call: NewObjectA"); */
 }
 
 
@@ -374,43 +740,56 @@ jmethodID GetMethodID (JNIEnv* env, jclass clazz, const char *name, const char *
 }
 
 /******************** JNI-functions for calling instance methods ******************/
-
 jobject CallObjectMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallObjectMethod");
+       jobject ret;
+       va_list vaargs;
 
-       return NULL;
+/*     log_text("JNI-Call: CallObjectMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callObjectMethod(obj,methodID,vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jobject CallObjectMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallObjectMethodV");
-
-       return NULL;
+       return callObjectMethod(obj,methodID,args);
 }
 
 
 jobject CallObjectMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
 {
+
+
        log_text("JNI-Call: CallObjectMethodA");
 
        return NULL;
 }
 
 
+
+
 jboolean CallBooleanMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallBooleanMethod");
+       jboolean ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallBooleanMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jboolean CallBooleanMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallBooleanMethodV");
+       return (jboolean)callIntegerMethod(obj,get_virtual(obj,methodID),'Z',args);
 
-       return 0;
 }
 
 jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue * args)
@@ -422,39 +801,49 @@ jboolean CallBooleanMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalu
 
 jbyte CallByteMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallByteMethod");
+       jbyte ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallVyteMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'B',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jbyte CallByteMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallByteMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallByteMethodV");*/
+       return callIntegerMethod(obj,methodID,'B',args);
 }
 
 
 jbyte CallByteMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallByteMethodA");
-
-       return 0;
 }
 
 
 jchar CallCharMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallCharMethod");
+       jchar ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallCharMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'C',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 jchar CallCharMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallCharMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallCharMethodV");*/
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'C',args);
 }
 
 
@@ -468,17 +857,22 @@ jchar CallCharMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *arg
 
 jshort CallShortMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallShortMethod");
+       jshort ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallShortMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_virtual(obj,methodID),'S',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jshort CallShortMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallShortMethodV");
-
-       return 0;
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'S',args);
 }
 
 
@@ -493,17 +887,19 @@ jshort CallShortMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *a
 
 jint CallIntMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallIntMethod");
+        jint ret;
+        va_list vaargs;
 
-       return 0;
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(obj,get_virtual(obj,methodID),'I',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jint CallIntMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallIntMethodV");
-
-       return 0;
+       return callIntegerMethod(obj,get_virtual(obj,methodID),'I',args);
 }
 
 
@@ -543,17 +939,22 @@ jlong CallLongMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *arg
 
 jfloat CallFloatMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallFloatMethod");
+       jfloat ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallFloatMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_virtual(obj,methodID),vaargs,'F');
+       va_end(vaargs);
+       return ret;
 }
 
 
 jfloat CallFloatMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallFloatMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_virtual(obj,methodID),args,'F');
 }
 
 
@@ -568,24 +969,28 @@ jfloat CallFloatMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *a
 
 jdouble CallDoubleMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallDoubleMethod");
+       jdouble ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallDoubleMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_virtual(obj,methodID),vaargs,'D');
+       va_end(vaargs);
+       return ret;
 }
 
 
 jdouble CallDoubleMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallDoubleMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_virtual(obj,methodID),args,'D');
 }
 
 
 jdouble CallDoubleMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallDoubleMethodA");
-
        return 0;
 }
 
@@ -593,7 +998,14 @@ jdouble CallDoubleMethodA (JNIEnv *env, jobject obj, jmethodID methodID, jvalue
 
 void CallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',vaargs);
+        va_end(vaargs);
+
 
 }
 
@@ -601,6 +1013,7 @@ void CallVoidMethod (JNIEnv *env, jobject obj, jmethodID methodID, ...)
 void CallVoidMethodV (JNIEnv *env, jobject obj, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallVoidMethodV");
+       (void)callIntegerMethod(obj,get_virtual(obj,methodID),'V',args);
 
 }
 
@@ -640,17 +1053,23 @@ jobject CallNonvirtualObjectMethodA (JNIEnv *env, jobject obj, jclass clazz, jme
 
 jboolean CallNonvirtualBooleanMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualBooleanMethod");
+       jboolean ret;
+       va_list vaargs;
+
+/*     log_text("JNI-Call: CallNonvirtualBooleanMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',vaargs);
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jboolean CallNonvirtualBooleanMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualBooleanMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallNonvirtualBooleanMethodV");*/
+       return (jboolean)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'Z',args);
 }
 
 
@@ -665,17 +1084,23 @@ jboolean CallNonvirtualBooleanMethodA (JNIEnv *env, jobject obj, jclass clazz, j
 
 jbyte CallNonvirtualByteMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualByteMethod");
+       jbyte ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallNonvirutalByteMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jbyte CallNonvirtualByteMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualByteMethodV");
+       /*log_text("JNI-Call: CallNonvirtualByteMethodV"); */
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'B',args);
 
-       return 0;
 }
 
 
@@ -690,17 +1115,22 @@ jbyte CallNonvirtualByteMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jchar CallNonvirtualCharMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualCharMethod");
+       jchar ret;
+       va_list vaargs;
 
-       return 0;
+/*     log_text("JNI-Call: CallNonVirtualCharMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jchar CallNonvirtualCharMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualCharMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualCharMethodV");*/
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'C',args);
 }
 
 
@@ -715,17 +1145,22 @@ jchar CallNonvirtualCharMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jshort CallNonvirtualShortMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualShortMethod");
+       jshort ret;
+       va_list vaargs;
 
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualShortMethod");*/
+
+       va_start(vaargs,methodID);
+       ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',vaargs);
+       va_end(vaargs);
+       return ret;
 }
 
 
 jshort CallNonvirtualShortMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualShortMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualShortMethodV");*/
+       return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'S',args);
 }
 
 
@@ -740,17 +1175,23 @@ jshort CallNonvirtualShortMethodA (JNIEnv *env, jobject obj, jclass clazz, jmeth
 
 jint CallNonvirtualIntMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualIntMethod");
 
-       return 0;
+        jint ret;
+        va_list vaargs;
+
+       /*log_text("JNI-Call: CallNonvirtualIntMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jint CallNonvirtualIntMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualIntMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallNonvirtualIntMethodV");*/
+        return callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'I',args);
 }
 
 
@@ -790,17 +1231,24 @@ jlong CallNonvirtualLongMethodA (JNIEnv *env, jobject obj, jclass clazz, jmethod
 
 jfloat CallNonvirtualFloatMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualFloatMethod");
+       jfloat ret;
+       va_list vaargs;
+
+       /*log_text("JNI-Call: CallNonvirtualFloatMethod");*/
+
+
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'F');
+       va_end(vaargs);
+       return ret;
 
-       return 0;
 }
 
 
 jfloat CallNonvirtualFloatMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallNonvirtualFloatMethodV");
-
-       return 0;
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'F');
 }
 
 
@@ -815,17 +1263,22 @@ jfloat CallNonvirtualFloatMethodA (JNIEnv *env, jobject obj, jclass clazz, jmeth
 
 jdouble CallNonvirtualDoubleMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
+       jdouble ret;
+       va_list vaargs;
        log_text("JNI-Call: CallNonvirtualDoubleMethod");
 
-       return 0;
+       va_start(vaargs,methodID);
+       ret = callFloatMethod(obj,get_nonvirtual(clazz,methodID),vaargs,'D');
+       va_end(vaargs);
+       return ret;
+
 }
 
 
 jdouble CallNonvirtualDoubleMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualDoubleMethodV");
-
-       return 0;
+/*     log_text("JNI-Call: CallNonvirtualDoubleMethodV");*/
+       return callFloatMethod(obj,get_nonvirtual(clazz,methodID),args,'D');
 }
 
 
@@ -840,13 +1293,23 @@ jdouble CallNonvirtualDoubleMethodA (JNIEnv *env, jobject obj, jclass clazz, jme
 
 void CallNonvirtualVoidMethod (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallNonvirtualVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallNonvirtualVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',vaargs);
+        va_end(vaargs);
+
 }
 
 
 void CallNonvirtualVoidMethodV (JNIEnv *env, jobject obj, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallNonvirtualVoidMethodV");
+/*     log_text("JNI-Call: CallNonvirtualVoidMethodV");*/
+
+        (void)callIntegerMethod(obj,get_nonvirtual(clazz,methodID),'V',args);
+
 }
 
 
@@ -875,7 +1338,7 @@ jfieldID GetFieldID (JNIEnv *env, jclass clazz, const char *name, const char *si
 
 jfieldID getFieldID_critical(JNIEnv *env,jclass clazz,const char *name,const char *sig)
 {
-    jfieldID id = env->GetFieldID(env,clazz,name,sig);     
+    jfieldID id = GetFieldID(env,clazz,name,sig);     
     if (!id) panic("setfield_critical failed"); 
     return id;
 }
@@ -1028,20 +1491,24 @@ jobject CallStaticObjectMethodA (JNIEnv *env, jclass clazz, jmethodID methodID,
 
 jboolean CallStaticBooleanMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticBooleanMethod");
+        jboolean ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticBooleanMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jboolean)callIntegerMethod(0,methodID,'Z',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jboolean CallStaticBooleanMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticBooleanMethodV");
-
-       return 0;
+       return (jboolean)callIntegerMethod(0,methodID,'Z',args);
 }
 
-
 jboolean CallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue *args)
 {
        log_text("JNI-Call: CallStaticBooleanMethodA");
@@ -1052,17 +1519,22 @@ jboolean CallStaticBooleanMethodA (JNIEnv *env, jclass clazz, jmethodID methodID
 
 jbyte CallStaticByteMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticByteMethod");
+        jobject ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jbyte)callIntegerMethod(0,methodID,'B',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jbyte CallStaticByteMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticByteMethodV");
-
-       return 0;
+       return (jbyte)callIntegerMethod(0,methodID,'B',args);
 }
 
 
@@ -1075,17 +1547,22 @@ jbyte CallStaticByteMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jchar CallStaticCharMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticCharMethod");
+        jchar ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jchar)callIntegerMethod(0,methodID,'C',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jchar CallStaticCharMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticCharMethodV");
-
-       return 0;
+        return (jchar)callIntegerMethod(0,methodID,'C',args);
 }
 
 
@@ -1100,17 +1577,22 @@ jchar CallStaticCharMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jshort CallStaticShortMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticShortMethod");
+        jshort ret;
+        va_list vaargs;
 
-       return 0;
+/*      log_text("JNI-Call: CallStaticByteMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = (jshort)callIntegerMethod(0,methodID,'S',vaargs);
+        va_end(vaargs);
+        return ret;
 }
 
 
 jshort CallStaticShortMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticShortMethodV");
-
-       return 0;
+       /*log_text("JNI-Call: CallStaticShortMethodV");*/
+       return (jshort)callIntegerMethod(0,methodID,'S',args);
 }
 
 
@@ -1125,9 +1607,16 @@ jshort CallStaticShortMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jv
 
 jint CallStaticIntMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticIntMethod");
+        jobject ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticIntMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callIntegerMethod(0,methodID,'I',vaargs);
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
@@ -1135,7 +1624,7 @@ jint CallStaticIntMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_lis
 {
        log_text("JNI-Call: CallStaticIntMethodV");
 
-       return 0;
+       return callIntegerMethod(0,methodID,'I',args);
 }
 
 
@@ -1150,17 +1639,23 @@ jint CallStaticIntMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jvalue
 
 jlong CallStaticLongMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticLongMethod");
+        jobject ret;
+        va_list vaargs;
 
-       return 0;
-}
+/*      log_text("JNI-Call: CallStaticLongMethod");*/
 
+        va_start(vaargs,methodID);
+        ret = callLongMethod(0,methodID,vaargs);
+        va_end(vaargs);
+        return ret;
+
+}
 
 jlong CallStaticLongMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallStaticLongMethodV");
-
-       return 0;
+       
+       return callLongMethod(0,methodID,args);
 }
 
 
@@ -1175,17 +1670,24 @@ jlong CallStaticLongMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jval
 
 jfloat CallStaticFloatMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticFloatMethod");
+        jfloat ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticLongMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callFloatMethod(0,methodID,vaargs,'F');
+        va_end(vaargs);
+        return ret;
 
-       return 0;
 }
 
 
 jfloat CallStaticFloatMethodV (JNIEnv *env, jclass clazz, jmethodID methodID, va_list args)
 {
-       log_text("JNI-Call: CallStaticFloatMethodV");
 
-       return 0;
+       return callFloatMethod(0,methodID,args,'F');
+
 }
 
 
@@ -1193,16 +1695,23 @@ jfloat CallStaticFloatMethodA (JNIEnv *env, jclass clazz, jmethodID methodID, jv
 {
        log_text("JNI-Call: CallStaticFloatMethodA");
 
-       return 0;
 }
 
 
 
 jdouble CallStaticDoubleMethod (JNIEnv *env, jclass clazz, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticDoubleMethod");
 
-       return 0;
+        jdouble ret;
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticDoubleMethod");*/
+
+        va_start(vaargs,methodID);
+        ret = callFloatMethod(0,methodID,vaargs,'D');
+        va_end(vaargs);
+        return ret;
+
 }
 
 
@@ -1210,7 +1719,7 @@ jdouble CallStaticDoubleMethodV (JNIEnv *env, jclass clazz, jmethodID methodID,
 {
        log_text("JNI-Call: CallStaticDoubleMethodV");
 
-       return 0;
+       return callFloatMethod(0,methodID,args,'D');
 }
 
 
@@ -1225,7 +1734,13 @@ jdouble CallStaticDoubleMethodA (JNIEnv *env, jclass clazz, jmethodID methodID,
 
 void CallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...)
 {
-       log_text("JNI-Call: CallStaticVoidMethod");
+        va_list vaargs;
+
+/*      log_text("JNI-Call: CallStaticVoidMethod");*/
+
+        va_start(vaargs,methodID);
+        (void)callIntegerMethod(0,methodID,'V',vaargs);
+        va_end(vaargs);
 
 }
 
@@ -1233,6 +1748,7 @@ void CallStaticVoidMethod (JNIEnv *env, jclass cls, jmethodID methodID, ...)
 void CallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
 {
        log_text("JNI-Call: CallStaticVoidMethodV");
+        (void)callIntegerMethod(0,methodID,'V',args);
 
 }
 
@@ -1462,7 +1978,8 @@ void ReleaseStringChars (JNIEnv *env, jstring str, const jchar *chars)
 
 jstring NewStringUTF (JNIEnv *env, const char *utf)
 {
-    log_text("NewStringUTF called");
+/*    log_text("NewStringUTF called");*/
+    return javastring_new(utf_new_char(utf));
 }
 
 /****************** returns the utf8 length in bytes of a string *******************/
@@ -1478,14 +1995,20 @@ jsize GetStringUTFLength (JNIEnv *env, jstring string)
 
 const char* GetStringUTFChars (JNIEnv *env, jstring string, jboolean *isCopy)
 {
+    if (verbose) log_text("GetStringUTFChars:");
+
     return javastring_toutf((java_lang_String*) string,false)->text;
+       
 }
 
 /***************** native code no longer needs access to utf ***********************/
 
 void ReleaseStringUTFChars (JNIEnv *env, jstring str, const char* chars)
 {
+       /*
     log_text("JNI-Call: ReleaseStringUTFChars");
+    utf_display(utf_new_char(chars));
+       */
 }
 
 /************************** array operations ***************************************/
@@ -1522,10 +2045,10 @@ void SetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index, jobjec
 
        /* check if the class of value is a subclass of the element class of the array */
 
-       if (!builtin_instanceof(val, array->elementtype))
-           exceptionptr = proto_java_lang_ArrayStoreException;
-       else
-           array->data[index] = val;
+               if (!builtin_canstore((java_objectarray*)array,(java_objectheader*)val))
+                       exceptionptr = proto_java_lang_ArrayStoreException;
+               else
+                       array->data[index] = val;
     }
 }
 
@@ -1873,12 +2396,16 @@ jint MonitorExit (JNIEnv* env, jobject obj)
 
 
 /************************************* JavaVM interface ****************************/
-
+#ifdef __cplusplus
+#error CPP mode not supported yet
+#else
 jint GetJavaVM (JNIEnv* env, JavaVM **vm)
 {
     log_text("JNI-Call: GetJavaVM");
+    *vm=&javaVM;
     return 0;
 }
+#endif /*__cplusplus*/
 
 void GetStringRegion (JNIEnv* env, jstring str, jsize start, jsize len, jchar *buf)
 {
@@ -1896,22 +2423,12 @@ void GetStringUTFRegion (JNIEnv* env, jstring str, jsize start, jsize len, char
 
 void * GetPrimitiveArrayCritical (JNIEnv* env, jarray array, jboolean *isCopy)
 {
-       java_arrayheader *s = (java_arrayheader*) array;
-
-       switch (s->arraytype) {
-               case ARRAYTYPE_BYTE:    return (((java_bytearray*)    array)->data);
-               case ARRAYTYPE_BOOLEAN: return (((java_booleanarray*) array)->data);
-               case ARRAYTYPE_CHAR:    return (((java_chararray*)    array)->data);
-               case ARRAYTYPE_SHORT:   return (((java_shortarray*)   array)->data);
-               case ARRAYTYPE_INT:     return (((java_intarray*)     array)->data);
-               case ARRAYTYPE_LONG:    return (((java_longarray*)    array)->data);
-               case ARRAYTYPE_FLOAT:   return (((java_floatarray*)   array)->data);
-               case ARRAYTYPE_DOUBLE:  return (((java_doublearray*)  array)->data);
-               case ARRAYTYPE_OBJECT:  return (((java_objectarray*)  array)->data); 
-               case ARRAYTYPE_ARRAY:   return (((java_arrayarray*)   array)->data);
-       }
+       java_objectheader *s = (java_objectheader*) array;
+       arraydescriptor *desc = s->vftbl->arraydesc;
 
-       return NULL;
+       if (!desc) return NULL;
+
+       return ((u1*)s) + desc->dataoffset;
 }
 
 
@@ -1966,10 +2483,63 @@ jboolean ExceptionCheck (JNIEnv* env)
 
        return exceptionptr ? JNI_TRUE : JNI_FALSE;
 }
-       
+
+
+
+
+
+
+jint DestroyJavaVM (JavaVM *vm) {
+       log_text("DestroyJavaVM called");
+}
+
+jint AttachCurrentThread(JavaVM *vm, void **par1, void *par2) {
+       log_text("AttachCurrentThread called");
+}
+
+jint DetachCurrentThread (JavaVM *vm) {
+       log_text("DetachCurrentThread called");
+}
+   
+jint GetEnv (JavaVM *vm, void **environment, jint jniversion) {
+       *environment=&env;
+       return 0;
+}
+   
+jint AttachCurrentThreadAsDaemon (JavaVM *vm, void **par1, void *par2) {
+       log_text("AttachCurrentThreadAsDaemon called");
+}
+
+
+
+
+
+
+
+
+
+
+
+/********************************* JNI invocation table ******************************/
+
+struct _JavaVM javaVMTable={
+   NULL,
+   NULL,
+   NULL,
+   &DestroyJavaVM,
+   &AttachCurrentThread,
+   &DetachCurrentThread,
+   &GetEnv,
+   &AttachCurrentThreadAsDaemon
+
+};
+
+JavaVM javaVM=&javaVMTable;
+
 /********************************* JNI function table ******************************/
 
-JNIEnv env = {   
+struct JNI_Table envTable =     
+   {   
     NULL,
     NULL,
     NULL,
@@ -2199,7 +2769,10 @@ JNIEnv env = {
     &NewWeakGlobalRef,
     &DeleteWeakGlobalRef,
     &ExceptionCheck
-};
+    };
+
+
+JNIEnv env=&envTable;
 
 
 /*
index 140c1737c90034bbe5d81b1fc63b146a0fa5235b..ef49f19375e8ddc46aaaf3d48dc557e4e6c7478f 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: ?
 
-   $Id: jni.h 557 2003-11-02 22:51:59Z twisti $
+   $Id: jni.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
 #define jfieldID               fieldinfo*
 #define jmethodID             methodinfo*      
 
-struct _JavaVM;                                     /* opaque structure */
 typedef struct _JavaVM* JavaVM;
 
+struct _JavaVM{
+   void *(*reserved0) ();
+   void *(*reserved1) ();
+   void *(*reserved2) ();
+   jint (*DestroyJavaVM) (JavaVM *);
+   jint (*AttachCurrentThread) (JavaVM *, void **, void *);
+   jint (*DetachCurrentThread) (JavaVM *);
+   jint (*GetEnv) (JavaVM *, void **, jint);
+   jint (*AttachCurrentThreadAsDaemon) (JavaVM *, void **, void *);
+
+};
+
+
 typedef union jvalue {
     jboolean z;
     jbyte    b;
@@ -116,7 +128,7 @@ typedef struct {
        Java VM Interface 
 */
 
-typedef struct JNI_Table JNIEnv;
+typedef struct JNI_Table *JNIEnv;
 
 struct JNI_Table {
     
@@ -427,7 +439,6 @@ struct JNI_Table {
     jint (*MonitorExit) (JNIEnv*, jobject obj);
 
     /* JavaVM interface */
-
     jint (*GetJavaVM) (JNIEnv*, JavaVM **vm);
 
     void (*GetStringRegion) (JNIEnv*, jstring str, jsize start, jsize len, jchar *buf);
@@ -450,8 +461,9 @@ struct JNI_Table {
 
 extern JNIEnv env;
 
-#endif /* _JNI_H */
+extern JavaVM javaVM;
 
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 1dc65103c1991c51e5d77f76f8a737f211d54726..a06724a7d16dffed725af7cb4f8468fcbd4096d5 100644 (file)
    The .hh files created with the header file generator are all
    included here as are the C functions implementing these methods.
 
-   $Id: native.c 595 2003-11-09 20:04:01Z twisti $
+   $Id: native.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
-
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
@@ -46,6 +45,7 @@
 #include <utime.h>
 #include <sys/utsname.h>
 
+#include "config.h"
 #include "global.h"
 #include "native.h"
 #include "nativetypes.hh"
@@ -68,6 +68,7 @@
 #endif
 #include <sys/stat.h>
 
+#include "../threads/threadio.h"                    
 
 /* searchpath for classfiles */
 static char *classpath;
@@ -78,7 +79,9 @@ static char *classpath;
 /******************** systemclasses required for native methods ***************/
 
 static classinfo *class_java_lang_Class;
-static classinfo *class_java_lang_Cloneable;
+static classinfo *class_java_lang_VMClass;
+static methodinfo *method_vmclass_init;
+/* static classinfo *class_java_lang_Cloneable=0; */ /* now in global.h */
 static classinfo *class_java_lang_CloneNotSupportedException;
 static classinfo *class_java_lang_System;
 static classinfo *class_java_lang_ClassLoader;
@@ -118,16 +121,36 @@ java_objectheader* exceptionptr = NULL;
 
 void use_class_as_object(classinfo *c) 
 {
-       vftbl *vt = class_java_lang_Class->vftbl;
-       vftbl *newtbl;
-       if (!c->classvftbl) {
-               c->classvftbl = true;
-               copy_vftbl(&newtbl, vt);
-               newtbl->class = c->header.vftbl->class;
-               newtbl->baseval = c->header.vftbl->baseval;
-               newtbl->diffval = c->header.vftbl->diffval;
-               c->header.vftbl = newtbl;
-       }
+        if (!class_java_lang_Class)
+                class_java_lang_Class =
+                        class_new ( utf_new_char ("java/lang/Class") );
+        vftbl *vt = class_java_lang_Class->vftbl;
+        vftbl *newtbl;
+        if (!c->classvftbl) {
+                c->classvftbl = true;
+                copy_vftbl(&newtbl, vt);
+                newtbl->class = c->header.vftbl->class;
+                newtbl->baseval = c->header.vftbl->baseval;
+                newtbl->diffval = c->header.vftbl->diffval;
+                c->header.vftbl = newtbl;
+        }
+        
+       if (!class_java_lang_VMClass) {
+               class_java_lang_VMClass =
+                                class_new ( utf_new_char("java/lang/VMClass"));
+                method_vmclass_init = 
+                               class_findmethod(class_java_lang_VMClass,utf_new_char("<init>"),
+                                       utf_new_char("(Lgnu/classpath/RawData;)V"));
+                if (method_vmclass_init==0) {
+                       class_showmethods(class_java_lang_VMClass);
+                        panic("Needed class initializer for VMClass could not be found");
+                }
+        }
+        {
+                java_objectheader *vmo = builtin_new (class_java_lang_VMClass);
+                asm_calljavamethod (method_vmclass_init, vmo, c, NULL, NULL);
+                c->vmClass=(java_lang_VMClass*)vmo;
+        }
 }
 
 /*********************** include Java Native Interface ************************/ 
@@ -136,54 +159,34 @@ void use_class_as_object(classinfo *c)
 
 /*************************** include native methods ***************************/ 
 
-#include "nat/Object.c"
-#include "nat/String.c"
-#include "nat/ClassLoader.c"
-#include "nat/Class.c"
-#include "nat/Compiler.c"
-#include "nat/Double.c"
-#include "nat/Float.c"
-#include "nat/Math.c"
-#include "nat/Package.c"
 #include "nat/Runtime.c"
-#include "nat/SecurityManager.c"
-#include "nat/System.c"
 #include "nat/Thread.c"
-#include "nat/Throwable.c"
-#include "nat/Finalizer.c"
-#include "nat/Array.c"
-#include "nat/Constructor.c"
-#include "nat/Field.c"
+#include "nat/VMClass.c"
 #include "nat/Method.c"
-#include "nat/FileDescriptor.c"
-#include "nat/FileInputStream.c"
-#include "nat/FileOutputStream.c"
-#include "nat/FileSystem.c"
-#include "nat/ObjectInputStream.c"
-#include "nat/ObjectStreamClass.c"
-#include "nat/RandomAccessFile.c"
-#include "nat/ResourceBundle.c"
-#include "nat/JarFile.c"
-#include "nat/Adler32.c"
-#include "nat/CRC32.c"
-#include "nat/Deflater.c"
-#include "nat/Inflater.c"
-#include "nat/ZipEntry.c"
-#include "nat/ZipFile.c"
-#include "nat/BigInteger.c"
-#include "nat/InetAddress.c"
-#include "nat/InetAddressImpl.c"
-#include "nat/DatagramPacket.c"
-#include "nat/PlainDatagramSocketImpl.c"
-#include "nat/PlainSocketImpl.c"
-#include "nat/SocketInputStream.c"
-#include "nat/SocketOutputStream.c"
-#include "nat/AccessController.c"
-#include "nat/ClassLoader_NativeLibrary.c"
-#include "nat/UnixFileSystem.c"
-
+#include "nat/VMSecurityManager.c"
+#include "nat/VMClassLoader.c"
+#include "nat/VMObject.c"
+#include "nat/Proxy.c"
+#include "nat/Field.c"
+#include "nat/VMSystem.c"
+#include "nat/Constructor.c"
+#include "nat/FileChannelImpl.c"
+#include "nat/VMObjectStreamClass.c"
+#include "nat/JOWENNTest1.c"
+
+#ifdef USE_GTK 
+#include "nat/GdkGraphics.c"
+#include "nat/GtkComponentPeer.c"
+#include "nat/GdkPixbufDecoder.c"
+#include "nat/GtkScrollPanePeer.c"
+#include "nat/GtkFileDialogPeer.c"
+#include "nat/GtkLabelPeer.c"
+#endif
 /************************** tables for methods ********************************/
 
+#undef JOWENN_DEBUG
+#undef JOWENN_DEBUG1
+
 /* table for locating native methods */
 static struct nativeref {
        char *classname;
@@ -235,13 +238,25 @@ static bool nativecompdone = false;
 
 void native_loadclasses()
 {
+       static int classesLoaded=0; /*temporary hack JoWenn*/
+       if (classesLoaded) return;
+       classesLoaded=1;
+/*     log_text("loadclasses entered");*/
+
+
+       /*class_java_lang_System =*/
+               (void)class_new ( utf_new_char ("java/lang/VMClass") );/*JoWenn*/
+               (void)class_new ( utf_new_char ("java/lang/Class") );/*JoWenn*/
        /* class_new adds the class to the list of classes to be loaded */
-       class_java_lang_Cloneable = 
-               class_new(utf_new_char("java/lang/Cloneable"));
+       if (!class_java_lang_Cloneable)
+               class_java_lang_Cloneable = 
+                       class_new ( utf_new_char ("java/lang/Cloneable") );
+/*     log_text("loadclasses: class_java_lang_Cloneable has been initialized");*/
        class_java_lang_CloneNotSupportedException = 
-               class_new(utf_new_char("java/lang/CloneNotSupportedException"));
-       class_java_lang_Class =
-               class_new(utf_new_char("java/lang/Class"));
+               class_new ( utf_new_char ("java/lang/CloneNotSupportedException") );
+       if (!class_java_lang_Class)
+               class_java_lang_Class =
+                       class_new ( utf_new_char ("java/lang/Class") );
        class_java_io_IOException = 
                class_new(utf_new_char("java/io/IOException"));
        class_java_io_FileNotFoundException = 
@@ -257,13 +272,12 @@ void native_loadclasses()
        class_java_lang_ClassFormatError =
                class_new(utf_new_char("java/lang/ClassFormatError"));  
        class_java_io_SyncFailedException =
-               class_new(utf_new_char("java/io/SyncFailedException"));
-       class_java_io_UnixFileSystem =
-               class_new(utf_new_char("java/io/UnixFileSystem"));
-       class_java_lang_System =
-               class_new(utf_new_char("java/lang/System"));
+               class_new ( utf_new_char ("java/io/SyncFailedException") );
+               
+/*     log_text("native_loadclasses: class_new(\"java/lang/ClassLoader\")");           */
        class_java_lang_ClassLoader =
-               class_new(utf_new_char("java/lang/ClassLoader"));
+               class_new ( utf_new_char ("java/lang/ClassLoader") );   
+/*     log_text("native_loadclasses: class_new(\"java/security/PrivilegedActionException\")");         */
        class_java_security_PrivilegedActionException =
                class_new(utf_new_char("java/security/PrivilegedActionException"));
 
@@ -283,7 +297,9 @@ void native_loadclasses()
 
        /* load classes for wrapping primitive types */
        class_java_lang_Double =
-               class_new(utf_new_char("java/lang/Double"));
+               class_new( utf_new_char ("java/lang/Double") );
+       class_init(class_java_lang_Double);
+
        class_java_lang_Float =
                class_new(utf_new_char("java/lang/Float"));
        class_java_lang_Character =
@@ -302,12 +318,15 @@ void native_loadclasses()
                class_new(utf_new_char("java/lang/Void"));
 
        /* load to avoid dynamic classloading */
-       class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
+/*JoWenn       class_new(utf_new_char("sun/net/www/protocol/file/Handler"));
        class_new(utf_new_char("sun/net/www/protocol/jar/Handler"));    
-       class_new(utf_new_char("sun/io/CharToByteISO8859_1"));
+       class_new(utf_new_char("sun/io/CharToByteISO8859_1"));*/
        
        /* start classloader */
-       loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); 
+/*JoWenn       loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); */
+
+       classesLoaded=1;
+       log_text("native_loadclasses finished");
 }
 
 
@@ -342,24 +361,7 @@ void systemclassloader_addclass(classinfo *c)
 
 void systemclassloader_addlibrary(java_objectheader *o)
 {
-       methodinfo *m;
-
-       /* find method addElement of java.util.Vector */
-       m = class_resolvemethod(
-                                                       loader_load ( utf_new_char ("java/util/Vector") ),
-                                                       utf_new_char("addElement"),
-                                                       utf_new_char("(Ljava/lang/Object;)V")
-                                                       );
-
-       if (!m) panic("cannot initialize classloader");
-
-       /* call 'addElement' */
-       asm_calljavamethod(m,
-                                          SystemClassLoader->nativeLibraries,
-                                          o,
-                                          NULL,  
-                                          NULL
-                                          );       
+       log_text("systemclassloader_addlibrary");
 }
 
 /*****************************************************************************
@@ -370,15 +372,18 @@ void systemclassloader_addlibrary(java_objectheader *o)
 
 void init_systemclassloader() 
 {
-       if (!SystemClassLoader) {
-               /* create object and call initializer */
-               SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);  
-               heap_addreference((void**) &SystemClassLoader);
-
-               /* systemclassloader has no parent */
-               SystemClassLoader->parent      = NULL;
-               SystemClassLoader->initialized = true;
-       }
+  if (!SystemClassLoader) {
+       native_loadclasses();
+       log_text("Initializing new system class loader");
+       /* create object and call initializer */
+       SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader);  
+       heap_addreference((void**) &SystemClassLoader);
+
+       /* systemclassloader has no parent */
+       SystemClassLoader->parent      = NULL;
+       SystemClassLoader->initialized = true;
+  }
+  log_text("leaving system class loader");
 }
 
 
@@ -396,7 +401,7 @@ void systemclassloader_addlibname(java_objectheader *o)
 
        if (!m) panic("cannot initialize classloader");
 
-       id = env.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
+       id = envTable.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
        if (!id) panic("can not access ClassLoader");
 
        asm_calljavamethod(m,
@@ -429,6 +434,24 @@ void throw_classnotfoundexception()
 }
 
 
+void throw_classnotfoundexception2(utf* classname)
+{
+       if (!class_java_lang_ClassNotFoundException) {
+               panic("java.lang.ClassNotFoundException not found. Maybe wrong classpath?");
+       }
+
+       /* throws a ClassNotFoundException */
+       exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException);
+
+        /*
+        sprintf (logtext, "Loading class: ");
+        utf_sprint (logtext+strlen(logtext), classname);
+        dolog();
+        log_text("Class not found");
+        */
+}
+
+
 /*********************** Function: native_findfunction *************************
 
        Looks up a method (must have the same class name, method name, descriptor
@@ -451,7 +474,7 @@ functionptr native_findfunction(utf *cname, utf *mname,
        int buffer_len;
 
        isstatic = isstatic ? true : false;
-
+       
        if (!nativecompdone) {
                for (i = 0; i < NATIVETABLESIZE; i++) {
                        nativecomptable[i].classname  = 
@@ -468,14 +491,57 @@ functionptr native_findfunction(utf *cname, utf *mname,
                nativecompdone = true;
        }
 
+#ifdef JOWENN_DEBUG
+       buffer_len = 
+         utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "searching matching function in native table:");
+        utf_sprint(buffer+strlen(buffer), mname);
+       strcpy(buffer+strlen(buffer), ": ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), " for class ");
+        utf_sprint(buffer+strlen(buffer), cname);
+
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif
+               
        for (i = 0; i < NATIVETABLESIZE; i++) {
                n = &(nativecomptable[i]);
 
                if (cname == n->classname && mname == n->methodname &&
                    desc == n->descriptor && isstatic == n->isstatic)
                        return n->func;
+#ifdef JOWENN_DEBUG
+                       else {
+                               if (cname == n->classname && mname == n->methodname )  log_text("static and descriptor mismatch");
+                       
+                               else {
+                                       buffer_len = 
+                                         utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64;
+       
+                                       buffer = MNEW(char, buffer_len);
+
+                                       strcpy(buffer, "comparing with:");
+                                       utf_sprint(buffer+strlen(buffer), n->methodname);
+                                       strcpy (buffer+strlen(buffer), ": ");
+                                       utf_sprint(buffer+strlen(buffer), n->descriptor);
+                                       strcpy(buffer+strlen(buffer), " for class ");
+                                       utf_sprint(buffer+strlen(buffer), n->classname);
+
+                                       log_text(buffer);       
+
+                                       MFREE(buffer, char, buffer_len);
+                       
+                               }
+                       } 
+#endif
        }
 
+               
        /* no function was found, display warning */
 
        buffer_len = 
@@ -494,6 +560,10 @@ functionptr native_findfunction(utf *cname, utf *mname,
 
        MFREE(buffer, char, buffer_len);
 
+
+       exit(1);
+
+       
        return NULL;
 }
 
@@ -515,6 +585,8 @@ java_objectheader *javastring_new (utf *u)
        java_chararray *a;
        s4 i;
        
+/*     log_text("javastring_new");*/
+       
        s = (java_lang_String*) builtin_new (class_java_lang_String);
        a = builtin_newarray_char (utflength);
 
@@ -550,8 +622,9 @@ java_objectheader *javastring_new_char (char *text)
        java_lang_String *s;   /* result-string */
        java_chararray *a;
        
-       s = (java_lang_String*) builtin_new(class_java_lang_String);
-       a = builtin_newarray_char(len);
+       /*log_text("javastring_new_char");*/
+       s = (java_lang_String*) builtin_new (class_java_lang_String);
+       a = builtin_newarray_char (len);
 
        /* javastring or character-array could not be created */
        if ((!a) || (!s)) return NULL;
@@ -587,6 +660,8 @@ char *javastring_tochar (java_objectheader *so)
        java_chararray *a;
        s4 i;
        
+       log_text("javastring_tochar");
+       
        if (!s)
                return "";
        a = s->value;
@@ -635,8 +710,13 @@ java_objectheader *native_new_and_init(classinfo *c)
        methodinfo *m;
        java_objectheader *o = builtin_new(c);          /*          create object */
 
+        /*
+       printf("native_new_and_init ");
+       utf_display(c->name);
+       printf("\n");
+        */
        if (!o) return NULL;
-       
+       /* printf("o!=NULL\n"); */
        /* find initializer */
 
        m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
@@ -679,22 +759,20 @@ void stringtable_update ()
                                                                
                                js = (java_lang_String *) s->string;
                                
-                               if (!js || !(a = js->value)) {
+                               if (!js || !(a = js->value)) 
                                        /* error in hashtable found */
                                        panic("invalid literalstring in hashtable");
 
-                               } else {
-                                       if (!js->header.vftbl) 
-                                               /* vftbl of javastring is NULL */ 
-                                               js->header.vftbl = class_java_lang_String -> vftbl;
+                               if (!js->header.vftbl) 
+                                       /* vftbl of javastring is NULL */ 
+                                       js->header.vftbl = class_java_lang_String -> vftbl;
 
-                                       if (!a->header.objheader.vftbl) 
-                                               /* vftbl of character-array is NULL */ 
-                                               a->header.objheader.vftbl = class_array -> vftbl;
+                               if (!a->header.objheader.vftbl) 
+                                       /* vftbl of character-array is NULL */ 
+                                       a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
 
-                                       /* follow link in external hash chain */
-                                       s = s->hashlink;
-                               }
+                               /* follow link in external hash chain */
+                               s = s->hashlink;
                        }       
                }               
        }
@@ -747,12 +825,17 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
        utf *result;  /* resulting utf-string */
        int i;          
 
-       /* determine utf length in bytes and allocate memory */         
+       /* determine utf length in bytes and allocate memory */
+       /* printf("utf_new_u2: unicode_length=%d\n",unicode_length);            */
        buflength = u2_utflength(unicode_pos, unicode_length); 
        buffer    = MNEW(char,buflength);
  
        /* memory allocation failed */
-       if (!buffer) return NULL;
+       if (!buffer) {
+               printf("length: %d\n",buflength);
+               log_text("utf_new_u2:buffer==NULL");
+               return NULL;
+       }
 
        left = buflength;
        pos  = buffer;
@@ -793,6 +876,7 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
        
        /* insert utf-string into symbol-table */
        result = utf_new(buffer,buflength);
+
        MFREE(buffer, char, buflength);
        return result;
 }
@@ -806,7 +890,9 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname)
 utf *javastring_toutf(java_lang_String *string, bool isclassname)
 {
         java_lang_String *str = (java_lang_String *) string;
-       return utf_new_u2(str->value->data,str->count, isclassname);
+/*     printf("javastring_toutf offset: %d, len %d\n",str->offset, str->count);
+       fflush(stdout);*/
+       return utf_new_u2(str->value->data+str->offset,str->count, isclassname);
 }
 
 /********************* function: literalstring_u2 *****************************
@@ -828,6 +914,11 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
     u4 slot;  
     u2 i;
 
+#if JOWENN_DEBUG1
+    printf("literalstring_u2: length: %d\n",length);    
+    log_text("literalstring_u2");
+#endif
+    
     /* find location in hashtable */
     key  = unicode_hashkey (a->data, length);
     slot = key & (string_hash.size-1);
@@ -846,6 +937,10 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
        if (!copymode)
          lit_mem_free(a, sizeof(java_chararray) + sizeof(u2)*(length-1)+10);
 
+#ifdef JOWENN_DEBUG1
+       log_text("literalstring_u2: foundentry");
+       utf_display(javastring_toutf(js,0));
+#endif
        return (java_objectheader *) js;
       }
 
@@ -864,10 +959,8 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
       stringdata = a;
 
     /* location in hashtable found, complete arrayheader */
-    if (class_array==NULL) panic("class_array not initialized");
-    stringdata -> header.objheader.vftbl = class_array -> vftbl;
+    stringdata -> header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
     stringdata -> header.size = length;        
-    stringdata -> header.arraytype = ARRAYTYPE_CHAR;   
 
     /* create new javastring */
     js = LNEW (java_lang_String);
@@ -919,6 +1012,10 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode
       MFREE (string_hash.ptr, void*, string_hash.size);
       string_hash = newhash;
     }
+#ifdef JOWENN_DEBUG1
+       log_text("literalstring_u2: newly created");
+/*     utf_display(javastring_toutf(js,0));*/
+#endif
                        
     return (java_objectheader *) js;
 }
@@ -936,7 +1033,10 @@ java_objectheader *literalstring_new (utf *u)
     u4 utflength  = utf_strlen(u);   /* length of utf-string if uncompressed */
     java_chararray *a;               /* u2-array constructed from utf string */
     u4 i;
-    
+/*    log_text("literalstring_new"); */
+/*    utf_display(u);*/
+    /*if (utflength==0) while (1) sleep(60);*/
+/*    log_text("------------------");    */
     /* allocate memory */ 
     a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 ); 
     /* convert utf-string to u2-array */
@@ -970,9 +1070,16 @@ void literalstring_free (java_objectheader* sobj)
 
 void copy_vftbl(vftbl **dest, vftbl *src)
 {
-       *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr) * (src->vftbllength - 1));
+    *dest = src;
+#if 0
+    /* XXX this kind of copying does not work (in the general
+     * case). The interface tables would have to be copied, too. I
+     * don't see why we should make a copy anyway. -Edwin
+     */
+       *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1));
        memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr));
        memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr));
+#endif
 }
 
 /*****************************************************************************/
@@ -985,22 +1092,22 @@ void printNativeCall(nativeCall nc) {
 
   printf("\n%s's Native Methods call:\n",nc.classname); fflush(stdout);
   for (i=0; i<nc.methCnt; i++) {  
-    printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
+      printf("\tMethod=%s %s\n",nc.methods[i].methodname, nc.methods[i].descriptor);fflush(stdout);
 
     for (j=0; j<nc.callCnt[i]; j++) {  
-      printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
+        printf("\t\t<%i,%i>aCalled = %s %s %s\n",i,j,
        nc.methods[i].methodCalls[j].classname, 
        nc.methods[i].methodCalls[j].methodname, 
        nc.methods[i].methodCalls[j].descriptor);fflush(stdout);
       }
     }
-printf("-+++++--------------------\n");fflush(stdout);
+  printf("-+++++--------------------\n");fflush(stdout);
 }
 
 /*--------------------------------------------------------*/
 void printCompNativeCall(nativeCompCall nc) {
   int i,j;
-printf("printCompNativeCall BEGIN\n");fflush(stdout);
+  printf("printCompNativeCall BEGIN\n");fflush(stdout); 
   printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout);
   utf_display(nc.classname); fflush(stdout);
   
index f60b6972191e6c3a1031cfa5f9c9be0be53c9b0c..83dca4018aef096b9a9ec7e33a401957b9077cb4 100644 (file)
@@ -57,6 +57,8 @@ void stringtable_update();
 /* throw classnotfoundexcetion */
 void throw_classnotfoundexception();
 
+void throw_classnotfoundexception2(utf* classname);
+
 /* make utf symbol from javastring */
 utf *javastring_toutf(struct java_lang_String *string, bool isclassname);
 
index da8bb491fedc4fc1cb696fc6b035e8d29b7a235e..288a6cec8e5c26b9c1bdb0838c1cfd565e6f904d 100644 (file)
@@ -34,7 +34,7 @@
    calls instead of machine instructions, using the C calling
    convention.
 
-   $Id: builtin.c 624 2003-11-13 14:06:52Z twisti $
+   $Id: builtin.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -55,6 +55,7 @@
 
 #include "native-math.h"
 
+#undef DEBUG /*define DEBUG 1*/
 
 builtin_descriptor builtin_desc[] = {
        {(functionptr) builtin_instanceof,                 "instanceof"},
@@ -68,12 +69,13 @@ builtin_descriptor builtin_desc[] = {
        {(functionptr) asm_builtin_checkarraycast, "checkarraycast"},
        {(functionptr) asm_builtin_aastore,                "aastore"},
        {(functionptr) builtin_new,                                "new"},
+       {(functionptr) builtin_newarray,       "newarray"},
        {(functionptr) builtin_anewarray,          "anewarray"},
-       {(functionptr) builtin_newarray_array,     "newarray_array"},
 #if defined(__I386__)
-       /* have 2 parameters (needs stack manipulation) */
-       {(functionptr) asm_builtin_anewarray,      "anewarray"},
-       {(functionptr) asm_builtin_newarray_array, "newarray_array"},
+       /*
+        * have 2 parameters (needs stack manipulation)
+        */
+       {(functionptr) asm_builtin_newarray,       "newarray"},
 #endif
        {(functionptr) builtin_newarray_boolean,   "newarray_boolean"},
        {(functionptr) builtin_newarray_char,      "newarray_char"},
@@ -167,6 +169,7 @@ builtin_descriptor builtin_desc[] = {
 
 s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
 { 
+       classinfo *tmp;
        if (super->flags & ACC_INTERFACE)
                return (sub->vftbl->interfacetablelength > super->index) &&
                        (sub->vftbl->interfacetable[-super->index] != NULL);
@@ -181,10 +184,41 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
          return 0;
        */
 
+/*
+       for (tmp=sub;tmp!=0;tmp=tmp->super) {
+               printf("->");
+               utf_display(tmp->name);
+       }
+               printf("\n\n");
+       
+       for (tmp=super;tmp!=0;tmp=tmp->super) {
+               printf("->");
+               utf_display(tmp->name);
+       }
+               printf("\n");
+       
+
+       printf("sub->vftbl->baseval %d, super->vftbl->baseval %d\n diff %d, super->vftbl->diffval %d\n",
+                       sub->vftbl->baseval, super->vftbl->baseval, (unsigned)(sub->vftbl->baseval - super->vftbl->baseval),
+                       super->vftbl->diffval); */
+
        return (unsigned) (sub->vftbl->baseval - super->vftbl->baseval) <=
                (unsigned) (super->vftbl->diffval);
 }
 
+/* XXX inline this? */
+s4 builtin_isanysubclass_vftbl(vftbl *sub,vftbl *super)
+{
+       int base;
+       
+       if ((base = super->baseval) <= 0)
+               /* super is an interface */
+               return (sub->interfacetablelength > -base) &&
+                       (sub->interfacetable[base] != NULL);
+       return (unsigned) (sub->baseval - base)
+               <= (unsigned) (super->diffval);
+}
+
 
 /****************** function: builtin_instanceof *****************************
 
@@ -196,12 +230,22 @@ s4 builtin_isanysubclass (classinfo *sub, classinfo *super)
                         
 *****************************************************************************/
 
+/* XXX should use vftbl */
 s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
 {
 #ifdef DEBUG
        log_text ("builtin_instanceof called");
-#endif
-       
+
+       /* XXX remove log */
+       /*
+       sprintf(logtext,"instanceof(");
+       utf_sprint(logtext+strlen(logtext),obj->vftbl->class->name);
+       sprintf(logtext+strlen(logtext),",");
+       utf_sprint(logtext+strlen(logtext),class);
+       sprintf(logtext+strlen(logtext),")");
+       dolog();
+       */
+#endif 
        if (!obj) return 0;
        return builtin_isanysubclass (obj->vftbl->class, class);
 }
@@ -215,12 +259,23 @@ s4 builtin_instanceof(java_objectheader *obj, classinfo *class)
                          
 ****************************************************************************/
 
+/* XXX should use vftbl */
 s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
 {
 #ifdef DEBUG
        log_text("builtin_checkcast called");
 #endif
 
+       /* XXX remove log */
+       /*
+       sprintf(logtext,"checkcast(");
+       utf_sprint(logtext+strlen(logtext),obj->vftbl->class->name);
+       sprintf(logtext+strlen(logtext),",");
+       utf_sprint(logtext+strlen(logtext),class);
+       sprintf(logtext+strlen(logtext),")");
+       dolog();
+       */
+       
        if (obj == NULL)
                return 1;
        if (builtin_isanysubclass(obj->vftbl->class, class))
@@ -246,6 +301,8 @@ s4 builtin_checkcast(java_objectheader *obj, classinfo *class)
                        
 ******************************************************************************/
 
+/* XXX delete */
+#if 0
 static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
 {
        if (desc == target) return 1;
@@ -260,8 +317,23 @@ static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant
        default: return 1;
        }
 }
+#endif
 
+/* XXX inline this? */
+static s4 builtin_descriptorscompatible(arraydescriptor *desc,arraydescriptor *target)
+{
+       if (desc==target) return 1;
+       if (desc->arraytype != target->arraytype) return 0;
+       if (desc->arraytype != ARRAYTYPE_OBJECT) return 1;
+       
+       /* {both arrays are arrays of references} */
+       if (desc->dimension == target->dimension)
+               return builtin_isanysubclass_vftbl(desc->elementvftbl,target->elementvftbl);
+       if (desc->dimension < target->dimension) return 0;
 
+       /* {desc has higher dimension than target} */
+       return builtin_isanysubclass_vftbl(pseudo_class_Arraystub_vftbl,target->elementvftbl);
+}
 
 /******************** function: builtin_checkarraycast ***********************
 
@@ -280,6 +352,8 @@ static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant
                        
 *****************************************************************************/
 
+/* XXX delete */
+#if 0
 s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
 {
        java_arrayheader *a = (java_arrayheader*) o;
@@ -325,14 +399,32 @@ s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
                return 1;
        }
 }
+#endif
+
+s4 builtin_checkarraycast(java_objectheader *o,arraydescriptor *target)
+{
+       arraydescriptor *desc;
+       
+       if (!o) return 1;
+       if ((desc = o->vftbl->arraydesc) == NULL) return 0;
 
+       return builtin_descriptorscompatible(desc,target);
+}
 
+/* XXX delete */
+#if 0
 s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc)
 {
        if (!obj) return 1;
        return builtin_checkarraycast (obj, desc);
 }
+#endif
 
+s4 builtin_arrayinstanceof(java_objectheader *obj,arraydescriptor *desc)
+{
+       if (!obj) return 1;
+       return builtin_checkarraycast (obj, desc);
+}
 
 /************************** exception functions *******************************
 
@@ -342,7 +434,21 @@ java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr
 {
        if (verbose) {
                sprintf(logtext, "Builtin exception thrown: ");
-               utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
+               if (local_exceptionptr)
+                       utf_sprint(logtext + strlen(logtext), local_exceptionptr->vftbl->class->name);
+               else {
+                       sprintf(logtext+strlen(logtext),"%s","Error: <Nullpointer instead of exception>");
+                       if (!proto_java_lang_ClassCastException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ClassCastException==0");
+                       if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_NullPointerException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_ArrayIndexOutOfBoundsException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
+                       if (!proto_java_lang_NegativeArraySizeException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_NegativeArraySizeException==0");
+                       if (!proto_java_lang_OutOfMemoryError) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_OutOfMemoryError==0");
+                       if (!proto_java_lang_ArithmeticException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArithmeticException==0");
+                       if (!proto_java_lang_ArrayStoreException) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ArrayStoreException==0");
+                       if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
+                       if (!proto_java_lang_ThreadDeath) sprintf(logtext+strlen(logtext),"%s","proto_java_lang_ThreadDeath==0");
+                       }
                dolog();
        }
        exceptionptr = local_exceptionptr;
@@ -358,7 +464,8 @@ java_objectheader *builtin_throw_exception(java_objectheader *local_exceptionptr
 
 ******************************************************************************/
 
-
+/* XXX delete */
+#if 0
 s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
 {
        if (!o) return 1;
@@ -384,13 +491,133 @@ s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
                return 0;
        }
 }
+#endif
 
+s4 builtin_canstore (java_objectarray *a, java_objectheader *o)
+{
+       arraydescriptor *desc;
+       arraydescriptor *valuedesc;
+       vftbl *componentvftbl;
+       vftbl *valuevftbl;
+    int dim_m1;
+       int base;
+       
+       if (!o) return 1;
 
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->componentvftbl != NULL
+        *     *) o->vftbl is not an interface vftbl
+        */
+       
+       desc = a->header.objheader.vftbl->arraydesc;
+    componentvftbl = desc->componentvftbl;
+       valuevftbl = o->vftbl;
 
-/*****************************************************************************
-                                                 ARRAY OPERATIONS
-*****************************************************************************/
+       /* XXX remove log */
+       /*
+       log_text("builtin_canstore");
+       print_arraydescriptor(stdout,desc);
+       utf_sprint(logtext,valuevftbl->class->name);
+       dolog();
+       */
+
+    if ((dim_m1 = desc->dimension - 1) == 0) {
+               /* {a is a one-dimensional array} */
+               /* {a is an array of references} */
+               
+               if (valuevftbl == componentvftbl)
+                       return 1;
+
+               /* XXX remove log */
+               /* log_text("not same vftbl"); */
+
+               if ((base = componentvftbl->baseval) <= 0)
+                       /* an array of interface references */
+                       return (valuevftbl->interfacetablelength > -base &&
+                                       valuevftbl->interfacetable[base] != NULL);
+               
+               return (unsigned)(valuevftbl->baseval - base)
+                       <= (unsigned)(componentvftbl->diffval);
+    }
+    /* {a has dimension > 1} */
+       /* {componentvftbl->arraydesc != NULL} */
+
+       /* check if o is an array */
+       if ((valuedesc = valuevftbl->arraydesc) == NULL)
+               return 0;
+       /* {o is an array} */
+
+       return builtin_descriptorscompatible(valuedesc,componentvftbl->arraydesc);
+}
+
+/* This is an optimized version where a is guaranteed to be one-dimensional */
+s4 builtin_canstore_onedim (java_objectarray *a, java_objectheader *o)
+{
+       arraydescriptor *desc;
+       vftbl *elementvftbl;
+       vftbl *valuevftbl;
+       int base;
+       
+       if (!o) return 1;
+
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl != NULL
+        *     *) a->...vftbl->arraydesc->dimension == 1
+        *     *) o->vftbl is not an interface vftbl
+        */
 
+       desc = a->header.objheader.vftbl->arraydesc;
+    elementvftbl = desc->elementvftbl;
+       valuevftbl = o->vftbl;
+
+       /* {a is a one-dimensional array} */
+       
+       if (valuevftbl == elementvftbl)
+               return 1;
+
+       if ((base = elementvftbl->baseval) <= 0)
+               /* an array of interface references */
+               return (valuevftbl->interfacetablelength > -base &&
+                               valuevftbl->interfacetable[base] != NULL);
+       
+       return (unsigned)(valuevftbl->baseval - base)
+               <= (unsigned)(elementvftbl->diffval);
+}
+
+/* This is an optimized version where a is guaranteed to be a
+ * one-dimensional array of a class type */
+/* XXX this could be inlined by the code generator */
+s4 builtin_canstore_onedim_class (java_objectarray *a, java_objectheader *o)
+{
+       vftbl *elementvftbl;
+       vftbl *valuevftbl;
+       
+       if (!o) return 1;
+
+       /* The following is guaranteed (by verifier checks):
+        *
+        *     *) a->...vftbl->arraydesc != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl != NULL
+        *     *) a->...vftbl->arraydesc->elementvftbl is not an interface vftbl
+        *     *) a->...vftbl->arraydesc->dimension == 1
+        *     *) o->vftbl is not an interface vftbl
+        */
+
+    elementvftbl = a->header.objheader.vftbl->arraydesc->elementvftbl;
+       valuevftbl = o->vftbl;
+
+       /* {a is a one-dimensional array} */
+       
+       if (valuevftbl == elementvftbl)
+               return 1;
+
+       return (unsigned)(valuevftbl->baseval - elementvftbl->baseval)
+               <= (unsigned)(elementvftbl->diffval);
+}
 
 
 /******************** Function: builtin_new **********************************
@@ -427,128 +654,51 @@ java_objectheader *builtin_new(classinfo *c)
 
 
 
-/******************** function: builtin_anewarray ****************************
 
-       Creates an array of pointers to objects on the heap.
-       Parameters:
-               size ......... number of elements
-       elementtype .. pointer to the classinfo structure for the element type
-       
-       Return value:  pointer to the array or NULL if no memory is available
-
-*****************************************************************************/
-
-static
-void* __builtin_newarray(s4 base_size,
-                                                s4 size, 
-                                                bool references,
-                                                int elementsize,
-                                                int arraytype,
-                                                classinfo *el)
+java_arrayheader *builtin_newarray(s4 size,vftbl *arrayvftbl)
 {
-       java_arrayheader *a;
-
-#ifdef SIZE_FROM_CLASSINFO
-       s4 alignedsize = align_size(base_size + (size-1) * elementsize);
-       a = heap_allocate(alignedsize, references, NULL);
-#else  
-       a = heap_allocate(sizeof(java_objectarray) + (size-1) * elementsize, 
-                                         references, 
-                                         NULL);
-#endif
-       if (!a) return NULL;
+        /* XXX remove log */
+        /*
+        sprintf(logtext,"newarray size=%d class=",size);
+        utf_sprint(logtext+strlen(logtext),arrayvftbl->class->name);
+        dolog();
+        */
+
+        java_arrayheader *a;
+        arraydescriptor *desc = arrayvftbl->arraydesc;
+        s4 dataoffset = desc->dataoffset;
+        s4 componentsize = desc->componentsize;
 
 #ifdef SIZE_FROM_CLASSINFO
-       memset(a, 0, alignedsize);
+        s4 actualsize = align_size(dataoffset + size * componentsize);
 #else
-       memset(a, 0, base_size + (size-1) * elementsize);
-#endif 
-
-#if 0
-       {
-               classinfo *c;
-
-               switch (arraytype) {
-               case ARRAYTYPE_INT:
-                       c = create_array_class(utf_new_char("[I"));
-                       use_class_as_object(c, "int");
-                       break;
-
-               case ARRAYTYPE_LONG:
-                       c = create_array_class(utf_new_char("[J"));
-                       use_class_as_object(c, "long");
-                       break;
-
-               case ARRAYTYPE_FLOAT:
-                       c = create_array_class(utf_new_char("[F"));
-                       use_class_as_object(c, "float");
-                       break;
-
-               case ARRAYTYPE_DOUBLE:
-                       c = create_array_class(utf_new_char("[D"));
-                       use_class_as_object(c, "double");
-                       break;
-
-               case ARRAYTYPE_BYTE:
-                       c = create_array_class(utf_new_char("[B"));
-                       use_class_as_object(c, "byte");
-                       break;
-
-               case ARRAYTYPE_CHAR:
-                       c = create_array_class(utf_new_char("[C"));
-                       use_class_as_object(c, "char");
-                       break;
-
-               case ARRAYTYPE_SHORT:
-                       c = create_array_class(utf_new_char("[S"));
-                       use_class_as_object(c, "short");
-                       break;
-
-               case ARRAYTYPE_BOOLEAN:
-                       c = create_array_class(utf_new_char("[Z"));
-                       use_class_as_object(c, "boolean");
-                       break;
-
-               case ARRAYTYPE_OBJECT:
-                       {
-                               char *cname, *buf;
-                               cname = heap_allocate(utf_strlen(el->name), false, NULL);
-                               utf_sprint(cname, el->name);
-                               buf = heap_allocate(strlen(cname) + 3, false, NULL);
-                               /*  printf("\n\n[L%s;\n\n", cname); */
-                               sprintf(buf, "[L%s;", cname);
-                               c = create_array_class(utf_new_char(buf));
-                               /*              MFREE(buf, char, strlen(cname) + 3); */
-                               /*              MFREE(cname, char, utf_strlen(el->name)); */
-                               use_class_as_object(c, cname);
-                       }
-                       break;
-
-               case ARRAYTYPE_ARRAY:
-                       c = create_array_class(utf_new_char("[["));
-                       use_class_as_object(c, "java/lang/Boolean");
-                       break;
+        s4 actualsize = dataoffset + size * componentsize;
+#endif
+        a = (java_arrayheader *)
+                heap_allocate(actualsize,
+                                          (desc->arraytype == ARRAYTYPE_OBJECT),
+                                          NULL);
 
-               default:
-                       panic("unknown array type");
-               }
+        if (!a) return NULL;
+        memset(a,0,actualsize);
 
-               a->objheader.vftbl = c->vftbl;
-       }
-#else
-       a->objheader.vftbl = class_array->vftbl;
-#endif
-       a->size = size;
+        a->objheader.vftbl = arrayvftbl;
+        a->size = size;
 #ifdef SIZE_FROM_CLASSINFO
-       a->alignedsize = alignedsize;
+        a->alignedsize = actualsize;
 #endif
-       a->arraytype = arraytype;
-
-       return a;
+        return a;
 }
 
+java_objectarray *
+builtin_anewarray(s4 size,classinfo *component)
+{
+       return (java_objectarray*) builtin_newarray(size,class_array_of(component)->vftbl);
+}
 
-java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
+/* XXX delete */
+#if 0
+java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype)
 {
        java_objectarray *a;    
        a = (java_objectarray*)__builtin_newarray(sizeof(java_objectarray),
@@ -562,8 +712,7 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
        a->elementtype = elementtype;
        return a;
 }
-
-
+#endif
 
 /******************** function: builtin_newarray_array ***********************
 
@@ -577,8 +726,10 @@ java_objectarray *builtin_anewarray(s4 size, classinfo *elementtype)
 
 *****************************************************************************/
 
-java_arrayarray *builtin_newarray_array(s4 size, 
-                                                                               constant_arraydescriptor *elementdesc)
+/* XXX delete */
+#if 0
+java_arrayarray *builtin_newarray_array 
+               (s4 size, constant_arraydescriptor *elementdesc)
 {
        java_arrayarray *a; 
        a = (java_arrayarray*)__builtin_newarray(sizeof(java_arrayarray),
@@ -592,6 +743,7 @@ java_arrayarray *builtin_newarray_array(s4 size,
        a->elementdescriptor = elementdesc;
        return a;
 }
+#endif
 
 
 /******************** function: builtin_newarray_boolean ************************
@@ -603,7 +755,9 @@ java_arrayarray *builtin_newarray_array(s4 size,
 
 *****************************************************************************/
 
-java_booleanarray *builtin_newarray_boolean(s4 size)
+/* XXX delete */
+#if 0
+java_booleanarray *builtin_newarray_boolean (s4 size)
 {
        java_booleanarray *a;   
        a = (java_booleanarray*)__builtin_newarray(sizeof(java_booleanarray),
@@ -614,6 +768,47 @@ java_booleanarray *builtin_newarray_boolean(s4 size)
                                                                                           NULL);
        return a;
 }
+#endif
+
+java_intarray *builtin_newarray_int (s4 size)
+{
+       return (java_intarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_INT].arrayvftbl);
+}
+
+java_longarray *builtin_newarray_long (s4 size)
+{
+       return (java_longarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_LONG].arrayvftbl);
+}
+
+java_floatarray *builtin_newarray_float (s4 size)
+{
+       return (java_floatarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_FLOAT].arrayvftbl);
+}
+
+java_doublearray *builtin_newarray_double (s4 size)
+{
+       return (java_doublearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_DOUBLE].arrayvftbl);
+}
+
+java_bytearray *builtin_newarray_byte (s4 size)
+{
+       return (java_bytearray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BYTE].arrayvftbl);
+}
+
+java_chararray *builtin_newarray_char (s4 size)
+{
+       return (java_chararray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl);
+}
+
+java_shortarray *builtin_newarray_short (s4 size)
+{
+       return (java_shortarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_SHORT].arrayvftbl);
+}
+
+java_booleanarray *builtin_newarray_boolean (s4 size)
+{
+       return (java_booleanarray*) builtin_newarray(size,primitivetype_table[ARRAYTYPE_BOOLEAN].arrayvftbl);
+}
 
 /******************** function: builtin_newarray_char ************************
 
@@ -623,7 +818,9 @@ java_booleanarray *builtin_newarray_boolean(s4 size)
 
 *****************************************************************************/
 
-java_chararray *builtin_newarray_char(s4 size)
+/* XXX delete */
+#if 0
+java_chararray *builtin_newarray_char (s4 size)
 {
        java_chararray *a;      
        a = (java_chararray*)__builtin_newarray(sizeof(java_chararray),
@@ -644,7 +841,8 @@ java_chararray *builtin_newarray_char(s4 size)
 
 *****************************************************************************/
 
-java_floatarray *builtin_newarray_float(s4 size)
+/* XXX delete */
+java_floatarray *builtin_newarray_float (s4 size)
 {
        java_floatarray *a; 
        a = (java_floatarray*)__builtin_newarray(sizeof(java_floatarray),
@@ -665,7 +863,7 @@ java_floatarray *builtin_newarray_float(s4 size)
 
 *****************************************************************************/
 
-java_doublearray *builtin_newarray_double(s4 size)
+java_doublearray *builtin_newarray_double (s4 size)
 {
        java_doublearray *a;    
        a = (java_doublearray*)__builtin_newarray(sizeof(java_doublearray),
@@ -688,7 +886,8 @@ java_doublearray *builtin_newarray_double(s4 size)
 
 *****************************************************************************/
 
-java_bytearray *builtin_newarray_byte(s4 size)
+/* XXX delete */
+java_bytearray *builtin_newarray_byte (s4 size)
 {
        java_bytearray *a;      
        a = (java_bytearray*)__builtin_newarray(sizeof(java_bytearray),
@@ -709,6 +908,7 @@ java_bytearray *builtin_newarray_byte(s4 size)
 
 *****************************************************************************/
 
+/* XXX delete */
 java_shortarray *builtin_newarray_short(s4 size)
 {
        java_shortarray *a; 
@@ -730,6 +930,8 @@ java_shortarray *builtin_newarray_short(s4 size)
 
 *****************************************************************************/
 
+<<<<<<< builtin.c
+/* XXX delete */
 java_intarray *builtin_newarray_int(s4 size)
 {
        java_intarray *a;       
@@ -758,6 +960,8 @@ java_intarray *builtin_newarray_int(s4 size)
 
 *****************************************************************************/
 
+<<<<<<< builtin.c
+/* XXX delete */
 java_longarray *builtin_newarray_long(s4 size)
 {
        java_longarray *a;      
@@ -771,7 +975,7 @@ java_longarray *builtin_newarray_long(s4 size)
 }
 
 
-
+/* XXX delete */
 /***************** function: builtin_multianewarray ***************************
 
        Creates a multi-dimensional array on the heap. The dimensions are passed in
@@ -784,6 +988,7 @@ java_longarray *builtin_newarray_long(s4 size)
 
        /* Helper functions */
 
+/* XXX delete */
 static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
                                                                                         constant_arraydescriptor *desc)
 {
@@ -841,7 +1046,7 @@ static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
        return (java_arrayheader*) a;
 }
 
-
+/* XXX delete */
 java_arrayheader *builtin_multianewarray(java_intarray *dims,
                                                                                 constant_arraydescriptor *desc)
 {
@@ -906,15 +1111,62 @@ static java_arrayheader *nmultianewarray_part(int n, long *dims, int thisdim,
                
        return (java_arrayheader*) a;
 }
+#endif
+
+/**************** function: builtin_nmultianewarray ***************************
+
+       Creates a multi-dimensional array on the heap. The dimensions are passed in
+       an array of longs.
+
+    Arguments:
+        n............number of dimensions to create
+        arrayvftbl...vftbl of the array class
+        dims.........array containing the size of each dimension to create
 
+       Return value:  pointer to the array or NULL if no memory is available
+
+******************************************************************************/
+
+java_arrayheader *builtin_nmultianewarray (int n,
+                                                                                  vftbl *arrayvftbl, long *dims)
+{
+       int size, i;
+       java_arrayheader *a;
+       vftbl *componentvftbl;
+
+       /* create this dimension */
+       size = (int) dims[0];
+       a = builtin_newarray(size,arrayvftbl);
+       if (!a) return NULL;
+
+       /* if this is the last dimension return */
+       if (!--n) return a;
+
+       /* get the vftbl of the components to create */
+       componentvftbl = arrayvftbl->arraydesc->componentvftbl;
+       if (!componentvftbl) /* XXX the verifier could check this */
+               panic ("multianewarray with too many dimensions");
 
+       /* create the component arrays */
+       for (i = 0; i < size; i++) {
+               java_arrayheader *ea = 
+                       builtin_nmultianewarray(n,componentvftbl,dims+1);
+               if (!ea) return NULL;
+               ((java_objectarray*)a)->data[i] = (java_objectheader *) ea;
+       }
+
+       return a;
+}
+
+/* XXX delete */
+#if 0
 java_arrayheader *builtin_nmultianewarray (int size,
                                                                                   constant_arraydescriptor *desc, long *dims)
 {
        (void) builtin_newarray_int(size); /* for compatibility with -old */
        return nmultianewarray_part (size, dims, 0, desc);
 }
-
+#endif
 
 
 
@@ -929,6 +1181,8 @@ java_arrayheader *builtin_nmultianewarray (int size,
 
 *****************************************************************************/
 
+/* XXX delete */
+#if 0
 s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
 {
        if (builtin_canstore(a,o)) {
@@ -937,7 +1191,7 @@ s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
        }
        return 0;
 }
-
+#endif
 
 
 
@@ -963,7 +1217,23 @@ java_objectheader *builtin_trace_exception(java_objectheader *exceptionptr,
                methodindent--;
        if (verbose || runverbose) {
                printf("Exception ");
-               utf_display (exceptionptr->vftbl->class->name);
+               if (exceptionptr) {
+                       utf_display (exceptionptr->vftbl->class->name);
+               }
+               else {
+                       printf("Error: <Nullpointer instead of exception>");
+                       if (!proto_java_lang_ClassCastException) printf("%s","proto_java_lang_ClassCastException==0");
+                       if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_NullPointerException) printf("%s","proto_java_lang_NullPointerException==0");
+                       if (!proto_java_lang_ArrayIndexOutOfBoundsException) printf("%s","proto_java_lang_ArrayIndexOutOfBoundsException==0");
+                       if (!proto_java_lang_NegativeArraySizeException) printf("%s","proto_java_lang_NegativeArraySizeException==0");
+                       if (!proto_java_lang_OutOfMemoryError) printf("%s","proto_java_lang_OutOfMemoryError==0");
+                       if (!proto_java_lang_ArithmeticException) printf("%s","proto_java_lang_ArithmeticException==0");
+                       if (!proto_java_lang_ArrayStoreException) printf("%s","proto_java_lang_ArrayStoreException==0");
+                       if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
+                       if (!proto_java_lang_ThreadDeath) printf("%s","proto_java_lang_ThreadDeath==0");
+
+               }
                printf(" thrown in ");
                if (method) {
                        utf_display (method->class->name);
@@ -990,6 +1260,7 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
 #endif
                                                methodinfo *method)
 {
+
        int i;
        for (i = 0; i < methodindent; i++)
                logtext[i] = '\t';
@@ -1104,9 +1375,9 @@ void builtin_trace_args(s8 a0, s8 a1, s8 a2, s8 a3, s8 a4, s8 a5,
 #endif
 #endif
        }
-       sprintf(logtext + strlen(logtext), ")");
+       sprintf (logtext+strlen(logtext), ")");
+       dolog ();
 
-       dolog();
        methodindent++;
 }
 #endif
@@ -1281,7 +1552,7 @@ void builtin_monitorenter(java_objectheader *o)
        ++blockInts;
 
        hashValue = MUTEX_HASH_VALUE(o);
-       if (mutexHashTable[hashValue].object == o
+       if (mutexHashTable[hashValue].object == o 
                && mutexHashTable[hashValue].mutex.holder == currentThread)
                ++mutexHashTable[hashValue].mutex.count;
        else
@@ -1862,6 +2133,11 @@ float builtin_d2f(double a)
 }
 
 
+java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o) {
+        return Java_java_lang_VMObject_clone ( 0 ,  0, o);
+}
+
+
 /*
  * These are local overrides for various environment variables in Emacs.
  * Please do not remove this and leave it at the end of the file, where
index 0afdbf45137a27d7474916e94de1d0d5838cf21c..98bb11cd92e5b50eeecb17656a6f91a9ba0ce782 100644 (file)
@@ -26,14 +26,16 @@ extern java_objectheader* exceptionptr;
 
 s4 builtin_instanceof(java_objectheader *obj, classinfo *class);
 s4 builtin_isanysubclass (classinfo *sub, classinfo *super);
+s4 builtin_isanysubclass_vftbl (vftbl *sub, vftbl *super);
 s4 builtin_checkcast(java_objectheader *obj, classinfo *class);
 s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class);
-s4 builtin_arrayinstanceof(java_objectheader *obj, constant_arraydescriptor *desc);
-#if defined(__I386__)
-s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class);
+
+s4 builtin_arrayinstanceof(java_objectheader *obj, arraydescriptor *desc);
+#ifdef __I386__
+s4 asm_builtin_arrayinstanceof(java_objectheader *obj, classinfo *class); /* XXX ? */
 #endif
-s4 builtin_checkarraycast(java_objectheader *obj, constant_arraydescriptor *desc);
-s4 asm_builtin_checkarraycast(java_objectheader *obj, constant_arraydescriptor *desc);
+s4 builtin_checkarraycast(java_objectheader *obj, arraydescriptor *desc);
+s4 asm_builtin_checkarraycast(java_objectheader *obj, arraydescriptor *desc);
 
 java_objectheader *builtin_throw_exception (java_objectheader *exception);
 java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
@@ -42,12 +44,11 @@ java_objectheader *builtin_trace_exception (java_objectheader *exceptionptr,
 java_objectheader *builtin_new (classinfo *c);
 
 
-java_objectarray *builtin_anewarray (s4 size, classinfo *elementtype);
+java_arrayheader *builtin_newarray (s4 size, vftbl *arrayvftbl);
+java_objectarray *builtin_anewarray (s4 size, classinfo *component);
 #ifdef __I386__
-void asm_builtin_anewarray (s4 size, classinfo *elementtype);
-void asm_builtin_newarray_array (s4 size, constant_arraydescriptor *elementdesc);
+void asm_builtin_newarray (s4 size, vftbl *arrayvftbl);
 #endif
-java_arrayarray *builtin_newarray_array (s4 size, constant_arraydescriptor *elementdesc);
 java_booleanarray *builtin_newarray_boolean (s4 size);
 java_chararray *builtin_newarray_char (s4 size);
 java_floatarray *builtin_newarray_float (s4 size);
@@ -56,13 +57,10 @@ java_bytearray *builtin_newarray_byte (s4 size);
 java_shortarray *builtin_newarray_short (s4 size);
 java_intarray *builtin_newarray_int (s4 size);
 java_longarray *builtin_newarray_long (s4 size);
-java_arrayheader *builtin_multianewarray (java_intarray *dims,
-                       constant_arraydescriptor *desc);
-java_arrayheader *builtin_nmultianewarray (int size,
-                      constant_arraydescriptor *desc, long *dims);
+java_arrayheader *builtin_nmultianewarray (int n,
+                                           vftbl *arrayvftbl, long *dims);
 
 s4 builtin_canstore (java_objectarray *a, java_objectheader *o);
-s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
 void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o);
 
 #ifdef TRACE_ARGS_NUM
@@ -142,6 +140,8 @@ s8       asm_builtin_d2l (double a);
 
 float    builtin_d2f (double a);
 
+java_arrayheader *builtin_clone_array(void *env,java_arrayheader *o);
+
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 8f444cd832da8bb3536fa2af3a9578ad66d30822..6b8cee2828a3e2b403002b5ae656bb8064eaf5a8 100644 (file)
@@ -30,7 +30,7 @@
    Changes: Mark Probst
             Philipp Tomsich
 
-   $Id: global.h 655 2003-11-20 14:52:00Z carolyn $
+   $Id: global.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
  */
 #define SIZE_FROM_CLASSINFO
 
+/* standard includes **********************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "toolbox/memory.h"
+#include "toolbox/chain.h"
+#include "toolbox/list.h"
+#include "toolbox/loging.h"
+
+/* system dependent types *****************************************************/
+
+#include "types.h"
+
 
 /* additional data types ******************************************************/
 
@@ -65,6 +81,19 @@ typedef int   bool;             /* boolean data type */
 
 #define PRIMITIVETYPE_COUNT  9  /* number of primitive types */
 
+/* CAUTION: Don't change the numerical values! These constants are
+ * used as indices into the primitive type table.
+ */
+#define PRIMITIVETYPE_INT     0
+#define PRIMITIVETYPE_LONG    1
+#define PRIMITIVETYPE_FLOAT   2
+#define PRIMITIVETYPE_DOUBLE  3
+#define PRIMITIVETYPE_BYTE    4
+#define PRIMITIVETYPE_CHAR    5
+#define PRIMITIVETYPE_SHORT   6
+#define PRIMITIVETYPE_BOOLEAN 7
+#define PRIMITIVETYPE_VOID    8
+
 typedef void (*functionptr) (); /* generic function pointer */
 
 
@@ -104,7 +133,6 @@ void cacao_shutdown(s4 status);
 #define CONSTANT_NameAndType          12
 #define CONSTANT_Utf8                  1
 
-#define CONSTANT_Arraydescriptor      13
 #define CONSTANT_UNUSED                0
 
 #define ACC_PUBLIC                0x0001
@@ -118,7 +146,7 @@ void cacao_shutdown(s4 status);
 #define ACC_NATIVE                0x0100
 #define ACC_INTERFACE             0x0200
 #define ACC_ABSTRACT              0x0400
-
+#define ACC_STRICT               0x0800
 
 /* resolve typedef cycles *****************************************************/
 
@@ -130,6 +158,7 @@ typedef struct vftbl vftbl;
 typedef u1* methodptr;
 typedef struct fieldinfo  fieldinfo; 
 typedef struct methodinfo methodinfo; 
+typedef struct arraydescriptor arraydescriptor;
 
 
 /* constant pool entries *******************************************************
@@ -151,7 +180,6 @@ typedef struct methodinfo methodinfo;
     CONSTANT_Double              constant_double                    yes
     CONSTANT_NameAndType         constant_nameandtype               yes
     CONSTANT_Utf8                unicode                             no
-    CONSTANT_Arraydescriptor     constant_arraydescriptor           yes
     CONSTANT_UNUSED              -
 
 *******************************************************************************/
@@ -224,6 +252,16 @@ struct literalstring {
 };
 
 
+/* data structure for calls from c code to java methods */
+
+struct jni_callblock {
+       u1 itemtype;
+       u8 item;
+};
+
+typedef struct jni_callblock jni_callblock;
+
+
 /* data structure for accessing hashtables ************************************/
 
 typedef struct {            
@@ -276,11 +314,14 @@ typedef struct {            /* NameAndType (Field or Method)                  */
    types in the case of arrays of arrays (arraytype == ARRAYTYPE_ARRAY).
 */
 
+/* XXX delete */
+#if 0
 typedef struct constant_arraydescriptor {
        int arraytype;
        classinfo *objectclass;
        struct constant_arraydescriptor *elementdescriptor;
 } constant_arraydescriptor;
+#endif
 
 
 /* data structures of the runtime system **************************************/
@@ -300,21 +341,24 @@ struct java_objectheader {              /* header for all objects             */
 /* arrays **********************************************************************
 
        All arrays are objects (they need the object header with a pointer to a
-       vvftbl (array class table). There is only one class for all arrays. The
+       vvftbl (array class table). There is only one class for all arrays. The    XXX change
        type of an array is stored directly in the array object. Following types
        are defined:
 */
 
-#define ARRAYTYPE_INT      0
-#define ARRAYTYPE_LONG     1
-#define ARRAYTYPE_FLOAT    2
-#define ARRAYTYPE_DOUBLE   3
-#define ARRAYTYPE_BYTE     4
-#define ARRAYTYPE_CHAR     5
-#define ARRAYTYPE_SHORT    6
-#define ARRAYTYPE_BOOLEAN  7
-#define ARRAYTYPE_OBJECT   8
-#define ARRAYTYPE_ARRAY    9
+/* CAUTION: Don't change the numerical values! These constants (with
+ * the exception of ARRAYTYPE_OBJECT) are used as indices in the
+ * primitive type table.
+ */
+#define ARRAYTYPE_INT      PRIMITIVETYPE_INT
+#define ARRAYTYPE_LONG     PRIMITIVETYPE_LONG
+#define ARRAYTYPE_FLOAT    PRIMITIVETYPE_FLOAT
+#define ARRAYTYPE_DOUBLE   PRIMITIVETYPE_DOUBLE
+#define ARRAYTYPE_BYTE     PRIMITIVETYPE_BYTE
+#define ARRAYTYPE_CHAR     PRIMITIVETYPE_CHAR
+#define ARRAYTYPE_SHORT    PRIMITIVETYPE_SHORT
+#define ARRAYTYPE_BOOLEAN  PRIMITIVETYPE_BOOLEAN
+#define ARRAYTYPE_OBJECT   PRIMITIVETYPE_VOID     /* don't use as index! */
 
 typedef struct java_arrayheader {       /* header for all arrays              */
        java_objectheader objheader;        /* object header                      */
@@ -322,7 +366,6 @@ typedef struct java_arrayheader {       /* header for all arrays              */
 #ifdef SIZE_FROM_CLASSINFO
        s4 alignedsize; /* phil */
 #endif
-       s4 arraytype;                       /* array type from previous list      */
 } java_arrayheader;
 
 
@@ -377,16 +420,17 @@ typedef struct java_longarray {
 
 typedef struct java_objectarray {
        java_arrayheader header;
-       classinfo *elementtype;
        java_objectheader *data[1];
 } java_objectarray;
 
+/* XXX delete */
+#if 0
 typedef struct java_arrayarray {
        java_arrayheader header;
        constant_arraydescriptor *elementdescriptor;
        java_arrayheader *data[1];
 } java_arrayarray;
-
+#endif
 
 /* structure for primitive classes ********************************************/
 
@@ -396,6 +440,9 @@ typedef struct primitivetypeinfo {
        char *wrapname;                      /* name of class for wrapping        */
        char typesig;                        /* one character type signature      */
        char *name;                          /* name of primitive class           */
+       char *arrayname;                     /* name of primitive array class     */
+       classinfo *arrayclass;               /* primitive array class             */
+       vftbl *arrayvftbl;                   /* vftbl of primitive array class    */
 } primitivetypeinfo;
 
 
@@ -530,6 +577,15 @@ typedef struct innerclassinfo {
 
 struct classinfo {                /* class structure                          */
        java_objectheader header;     /* classes are also objects                 */
+       java_objectarray* signers;
+       struct java_security_ProtectionDomain* pd;
+       struct java_lang_VMClass* vmClass;
+       struct java_lang_reflect_Constructor* constructor;
+
+
+        s4 initializing_thread; /* gnu classpath*/
+        s4 erroneous_state; /* gnu classpath*/
+        struct gnu_classpath_RawData* vmData; /* gnu classpath*/
 
        s4          flags;            /* ACC flags                                */
        utf        *name;             /* class name                               */ 
@@ -578,6 +634,9 @@ struct classinfo {                /* class structure                          */
        classSetNode *impldBy;          /* implemented by class set */
 };
 
+/* check if class is an array class. Only use for linked classes! */
+#define CLASS_IS_ARRAY(clsinfo)  (clsinfo->vftbl->arraydesc != NULL)
+
 
 /* virtual function table ******************************************************
 
@@ -640,10 +699,13 @@ struct vftbl {
 
        classinfo   *class;                /* class, the vtbl belongs to          */
 
+       arraydescriptor *arraydesc;        /* for array classes, otherwise NULL   */
+
        s4           vftbllength;          /* virtual function table length       */
        s4           interfacetablelength; /* interface table length              */
 
        s4           baseval;              /* base for runtime type check         */
+                                          /* (-index for interfaces)             */
        s4           diffval;              /* high - base for runtime type check  */
 
        s4          *interfacevftbllength; /* length of interface vftbls          */
@@ -654,10 +716,31 @@ struct vftbl {
 #define VFTBLINTERFACETABLE(v,i)       (v)->interfacetable[-i]
 
 
+/* arraydescriptor ************************************************************
+
+    For every array class an arraydescriptor is allocated which
+    describes the array class.
+       The arraydescriptor is referenced from the vftbl of the array
+       class.
+
+*******************************************************************************/
+
+struct arraydescriptor {
+       vftbl *componentvftbl;   /* vftbl of the component type, NULL for primit. */
+       vftbl *elementvftbl;     /* vftbl of the element type, NULL for primitive */
+       short  arraytype;        /* ARRAYTYPE_* constant                          */
+       short  dimension;        /* dimension of the array (always >= 1)          */
+    s4     dataoffset;       /* offset of the array data from object pointer  */
+       s4     componentsize;    /* size of a component in bytes                  */
+};
+
 /* references to some system classes ******************************************/
 
 extern classinfo *class_java_lang_Object;
 extern classinfo *class_java_lang_String;
+extern classinfo *class_java_lang_Throwable;
+extern classinfo *class_java_lang_Cloneable;
+extern classinfo *class_java_io_Serializable;
 extern classinfo *class_java_lang_ClassCastException;
 extern classinfo *class_java_lang_NullPointerException;
 extern classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
@@ -666,7 +749,9 @@ extern classinfo *class_java_lang_OutOfMemoryError;
 extern classinfo *class_java_lang_ArithmeticException;
 extern classinfo *class_java_lang_ArrayStoreException;
 extern classinfo *class_java_lang_ThreadDeath;
-extern classinfo *class_array;
+extern classinfo *pseudo_class_Arraystub;
+extern classinfo *pseudo_class_Null;
+extern vftbl *pseudo_class_Arraystub_vftbl;
 
 /* instances of some system classes *******************************************/
 
@@ -712,10 +797,47 @@ extern int count_utf_new_found;
 
 /* table of primitive types ***************************************************/
 
+/* This array can be indexed by the PRIMITIVETYPE_ and ARRAYTYPE_
+ * constants (except ARRAYTYPE_OBJECT).
+ */
 extern primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT];
 
-#endif /* _GLOBAL_H */
 
+/* macros for descriptor parsing **********************************************/
+
+/* utf_ptr must point to the 'L' or the '[' of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * CAUTION: This macro does not check for an unexpected end of the
+ * descriptor.
+ */
+#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                           \
+            { while (*(utf_ptr)=='[') (utf_ptr)++;                      \
+              if (*(utf_ptr)++=='L')                                            \
+                  while(*(utf_ptr)++ != ';') /* skip */; }
+/* Input:
+ *     utf_ptr....points to first char of descriptor
+ *     end_ptr....points to first char after the end of the string
+ *     errorflag..must be initialized (to false) by the caller!
+ * Output:
+ *     utf_ptr....points to first char after the descriptor
+ *     errorflag..set to true if the string ended unexpectedly
+ */
+#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                                                    \
+            { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;                    \
+              if ((utf_ptr) == (end_ptr))                                                        \
+                  (errorflag) = true;                                                            \
+              else                                                                                   \
+                      if (*(utf_ptr)++=='L') {                                                        \
+                      while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';') /* skip */;  \
+                      if ((utf_ptr)[-1] != ';')                                          \
+                          (errorflag) = true; }}
+
+
+extern classinfo *class_array;
+
+#endif
 
 /*
  * These are local overrides for various environment variables in Emacs.
index 7237ba31107778f9ecd339046c82fab1466c26b2..3a98ba64761c0561b6a10a59e3536860256c6cfe 100644 (file)
@@ -29,7 +29,7 @@
 
    Changes: Christian Thalinger
 
-   $Id: asmpart.h 596 2003-11-09 20:05:07Z twisti $
+   $Id: asmpart.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -38,6 +38,7 @@
 #define _ASMPART_H
 
 #include "global.h"
+#include "jni.h"
 
 /* 
    determines if the byte support instruction set (21164a and higher)
@@ -72,6 +73,11 @@ java_objectheader *asm_calljavamethod(methodinfo *m, void *arg1, void *arg2,
 */
 java_objectheader *asm_calljavafunction(methodinfo *m, void *arg1, void *arg2,
                                         void *arg3, void *arg4);
+java_objectheader *asm_calljavafunction2(methodinfo *m, u4 count, u4 size , void *callblock);
+jdouble asm_calljavafunction2double(methodinfo *m, u4 count, u4 size , void *callblock);
+jlong asm_calljavafunction2long(methodinfo *m, u4 count, u4 size , void *callblock);
+
+
 
 void asm_handle_exception();
 void asm_handle_nat_exception();
index efba3cea6694850cad155fa91210fd7bd1584a95..cc6a5c5db89c5a5c00681ad375f312d66c00fc23 100644 (file)
    Contact: cacao@complang.tuwien.ac.at
 
    Authors: Reinhard Grafl
-
    Changes: Andreas Krall
             Roman Obermaiser
             Mark Probst
 
-   $Id: loader.c 593 2003-11-09 19:50:55Z twisti $
+   $Id: loader.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
 #include "toolbox/memory.h"
 #include "toolbox/loging.h"
 #include "threads/thread.h"
+#include <sys/stat.h>
+
+#ifdef USE_ZLIB
+#include "unzip.h"
+#endif
 
+#undef JOWENN_DEBUG
+#undef JOWENN_DEBUG1
+#undef JOWENN_DEBUG2
 
 /* global variables ***********************************************************/
 
@@ -87,17 +94,34 @@ static utf *utf_innerclasses;               /* InnerClasses                    */
 static utf *utf_constantvalue;                 /* ConstantValue                   */
 static utf *utf_code;                      /* Code                            */
 static utf *utf_finalize;                  /* finalize                            */
-static utf *utf_fidesc;                    /* ()V                                     */
+static utf *utf_fidesc;                    /* ()V changed                                   */
 static utf *utf_clinit;                    /* <clinit>                            */
-static utf *utf_initsystemclass;       /* initializeSystemClass   */
+static utf *utf_initsystemclass;       /* initializeSystemClass */
 static utf *utf_systemclass;           /* java/lang/System        */
+static utf *utf_vmclassloader; /*java/lang/VMClassLoader*/
+static utf *utf_vmclass; /*java/lang/VMClassLoader*/
+static utf *utf_initialize;
+static utf *utf_initializedesc;
 
-
+utf* clinit_desc(){
+       return utf_fidesc;
+}
+utf* clinit_name(){
+       return utf_clinit;
+}
 /* important system classes ***************************************************/
 
 classinfo *class_java_lang_Object;
 classinfo *class_java_lang_String;
-classinfo *class_array = NULL;
+
+classinfo *class_java_lang_Throwable;
+classinfo *class_java_lang_Cloneable;
+classinfo *class_java_io_Serializable;
+
+/* Pseudo classes for the typechecker */
+classinfo *pseudo_class_Arraystub = NULL;
+classinfo *pseudo_class_Null = NULL;
+vftbl *pseudo_class_Arraystub_vftbl = NULL;
 
 /* stefan */
 /* These are made static so they cannot be used for throwing in native */
@@ -111,6 +135,9 @@ static classinfo *class_java_lang_ArithmeticException;
 static classinfo *class_java_lang_ArrayStoreException;
 static classinfo *class_java_lang_ThreadDeath;
 
+static methodinfo method_clone_array;
+
+static int loader_inited = 0;
 
 /******************************************************************************
 
@@ -119,19 +146,20 @@ static classinfo *class_java_lang_ThreadDeath;
    the one character type signature and the name of the primitive class
  
  ******************************************************************************/
-primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
-       { NULL, NULL, "java/lang/Integer",   'I', "int"     },
-       { NULL, NULL, "java/lang/Long",      'J', "long"    },
-       { NULL, NULL, "java/lang/Float",     'F', "float"   },
-       { NULL, NULL, "java/lang/Double",    'D', "double"  },
-       { NULL, NULL, "java/lang/Byte",      'B', "byte"    },
-       { NULL, NULL, "java/lang/Character", 'C', "char"    },
-       { NULL, NULL, "java/lang/Short",     'S', "short"   },
-       { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" },
-       { NULL, NULL, "java/lang/Void",      'V', "void"    }
-};
 
+/* CAUTION: Don't change the order of the types. This table is indexed
+ * by the ARRAYTYPE_ constants (expcept ARRAYTYPE_OBJECT).
+ */
+primitivetypeinfo primitivetype_table[PRIMITIVETYPE_COUNT] = { 
+               { NULL, NULL, "java/lang/Integer",   'I', "int"     , "[I", NULL, NULL },
+               { NULL, NULL, "java/lang/Long",      'J', "long"    , "[J", NULL, NULL },
+               { NULL, NULL, "java/lang/Float",     'F', "float"   , "[F", NULL, NULL },
+               { NULL, NULL, "java/lang/Double",    'D', "double"  , "[D", NULL, NULL },
+               { NULL, NULL, "java/lang/Byte",      'B', "byte"    , "[B", NULL, NULL },
+               { NULL, NULL, "java/lang/Character", 'C', "char"    , "[C", NULL, NULL },
+               { NULL, NULL, "java/lang/Short",     'S', "short"   , "[S", NULL, NULL },
+               { NULL, NULL, "java/lang/Boolean",   'Z', "boolean" , "[Z", NULL, NULL },
+               { NULL, NULL, "java/lang/Void",      'V', "void"    , NULL, NULL, NULL }};
 
 /* instances of important system classes **************************************/
 
@@ -144,6 +172,50 @@ java_objectheader *proto_java_lang_ArithmeticException;
 java_objectheader *proto_java_lang_ArrayStoreException;
 java_objectheader *proto_java_lang_ThreadDeath;
 
+/* XXX delete */
+#if 0
+void override_array_class(classinfo *c) {
+       int i;
+       classinfo *sup;
+       utf *u=utf_new_char("clone");
+       sup=c->super;
+       class_showmethods(c);
+
+       for (i=0;i<sup->methodscount;i++) {
+               if (sup->methods[i].name==u) {
+                       method_clone_array.class = c;
+                       method_clone_array. flags = ACC_PUBLIC;
+                       method_clone_array.name =  utf_new_char("clone");
+                       method_clone_array.descriptor = utf_new_char("()Ljava/lang/Object;");
+
+                       method_clone_array.jcode = NULL;
+                       method_clone_array.exceptiontable = NULL;
+                       method_clone_array.entrypoint = NULL;
+                       method_clone_array.mcode = NULL;
+                       method_clone_array.stubroutine = NULL;
+                       method_clone_array.methodUsed = NOTUSED;
+                       method_clone_array.monoPoly = MONO;
+                       method_clone_array.subRedefs = 0;
+                       method_clone_array.subRedefsUsed = 0;
+                       method_clone_array.flags=0;
+                       method_clone_array.xta = NULL;
+                        method_clone_array.stubroutine = createnativestub (&builtin_clone_array, &method_clone_array);
+                       c->vftbl->table[sup->methods[i].vftblindex]=method_clone_array.stubroutine;
+                       log_text("Found !!!! :)))))))))))))))))))))))))))))))))))))))))))))))))");
+               }
+       
+
+       }
+}
+#endif
+
+
+
+
+
+
+
+
 
 /************* functions for reading classdata *********************************
 
@@ -275,7 +347,8 @@ bool suck_start (utf *classname) {
        FILE *classfile;
        int  filenamelen, err;
        struct stat buffer;
-       
+       int isZip;
+
        if (classbuffer)                /* classbuffer is already valid */
                return true;
 
@@ -296,41 +369,100 @@ bool suck_start (utf *classname) {
                        filename[filenamelen++] = *(pathpos++);
                        }
 
-               filename[filenamelen++] = '/';  
+               isZip=0;
+               if (filenamelen>4) {
+                       if ( ((filename[filenamelen-1]=='p') || (filename[filenamelen-1]=='P')) &
+                            ((filename[filenamelen-2]=='i') || (filename[filenamelen-1]=='I')) &
+                             ((filename[filenamelen-3]=='z') || (filename[filenamelen-1]=='Z')) ) {
+                               isZip=1;
+                       }
+               }
+
+               if (isZip) {
+#ifdef USE_ZLIB
+
+                       unzFile uf;
+
+                       filename[filenamelen++]='\0';
+                       uf=unzOpen(filename);
+                       if (uf!=0) {
+                               utf_ptr = classname->text;
+                               filenamelen=0;
+                               while (utf_ptr < utf_end(classname)) {
+                                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                                       c = *utf_ptr++;
+                                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                               c = '?'; 
+                                       filename[filenamelen++] = c;    
+                               }
+                               strcpy (filename+filenamelen, ".class");
+                               /*log_text(filename);*/
+                               if (unzLocateFile(uf,filename,1 /*case sensitive*/)==UNZ_OK) {
+                                       unz_file_info file_info;
+                                       log_text("Class found in zip file");
+                                       if (unzGetCurrentFileInfo(uf,&file_info,filename,
+                                               sizeof(filename),NULL,0,NULL,0) ==UNZ_OK) {
+                                               if (unzOpenCurrentFile(uf)==UNZ_OK) {
+                                                       classbuffer_size = file_info.uncompressed_size;                         
+                                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                                       classbuf_pos     = classbuffer-1;
+                                                       /*printf("classfile size: %d\n",file_info.uncompressed_size);*/
+                                                       if (unzReadCurrentFile(uf,classbuffer,classbuffer_size)==classbuffer_size) {
+                                                               unzCloseCurrentFile(uf);
+                                                               return true;
+                                                       } else {
+                                                               MFREE(classbuffer,u1,classbuffer_size);
+                                                               log_text("Error while unzipping");
+                                                       }
+                                               } else log_text("Error while opening file in archive");
+                                       } else log_text("Error while retrieving fileinfo");
+                               }; 
+                               unzCloseCurrentFile(uf);
+
+                       }
+#endif                 
+               } else {
+                       filename[filenamelen++] = '/';  
    
-               /* add classname to filename */
-
-               utf_ptr = classname->text;
-               while (utf_ptr < utf_end(classname)) {
-                       PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
-                       c = *utf_ptr++;
-                       if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
-                               c = '?'; 
-                       filename[filenamelen++] = c;    
+                       /* add classname to filename */
+
+                       utf_ptr = classname->text;
+                       while (utf_ptr < utf_end(classname)) {
+                               PANICIF (filenamelen >= MAXFILENAME, "Filename too long");
+                               c = *utf_ptr++;
+                               if ((c <= ' ' || c > 'z') && (c != '/'))     /* invalid character */ 
+                                       c = '?'; 
+                               filename[filenamelen++] = c;    
                        }
-      
-               /* add suffix */
+       
+                       /* add suffix */
+
+                       strcpy (filename+filenamelen, ".class");
 
-               strcpy (filename+filenamelen, ".class");
+                       classfile = fopen(filename, "r");
+                       if (classfile) {                                       /* file exists */
 
-               classfile = fopen(filename, "r");
-               if (classfile) {                                       /* file exists */
+                               /* XXX remove */
+                               /*
+                                 sprintf(logtext,"Opening file: %s",filename);
+                                 dolog();
+                               */
                        
-                       /* determine size of classfile */
+                               /* determine size of classfile */
 
-                       err = stat (filename, &buffer);
+                               err = stat (filename, &buffer);
 
-                       if (!err) {                                /* read classfile data */                            
-                               classbuffer_size = buffer.st_size;                              
-                               classbuffer      = MNEW(u1, classbuffer_size);
-                               classbuf_pos     = classbuffer-1;
-                               fread(classbuffer, 1, classbuffer_size, classfile);
-                               fclose(classfile);
-                               return true;
+                               if (!err) {                                /* read classfile data */                            
+                                       classbuffer_size = buffer.st_size;                              
+                                       classbuffer      = MNEW(u1, classbuffer_size);
+                                       classbuf_pos     = classbuffer-1;
+                                       fread(classbuffer, 1, classbuffer_size, classfile);
+                                       fclose(classfile);
+                                       return true;
+                               }
                        }
                }
        }
-
        if (verbose) {
                sprintf (logtext, "Warning: Can not open class file '%s'", filename);
                dolog();
@@ -460,7 +592,7 @@ voidptr innerclass_getconstant (classinfo *c, u4 pos, u4 ctype)
 
        /* check type of constantpool entry */
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (innerclass_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -524,73 +656,31 @@ static void checkfielddescriptor (char *utf_ptr, char *end_pos)
 {
        char *tstart;  /* pointer to start of classname */
        char ch;
-       
-       switch (*utf_ptr++) {
-       case 'B':
-       case 'C':
-       case 'I':
-       case 'S':
-       case 'Z':  
-       case 'J':  
-       case 'F':  
-       case 'D':
-               /* primitive type */  
-               break;
-
-       case 'L':
-               /* save start of classname */
-               tstart = utf_ptr;  
-               
-               /* determine length of classname */
-               while ( *utf_ptr++ != ';' )
-                       if (utf_ptr>=end_pos) 
-                               panic ("Missing ';' in objecttype-descriptor");
+       char *start = utf_ptr; /* XXX remove */
 
-               /* cause loading of referenced class */                 
-               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-               break;
-
-       case '[' : 
-               /* array type */
-               while ((ch = *utf_ptr++)=='[') 
-                       /* skip */ ;
-
-               /* component type of array */
-               switch (ch) {
-               case 'B':
-               case 'C':
-               case 'I':
-               case 'S':
-               case 'Z':  
-               case 'J':  
-               case 'F':  
-               case 'D':
-                       /* primitive type */  
-                       break;
-                       
-               case 'L':
-                       /* save start of classname */
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
-
-                       /* cause loading of referenced class */                 
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-
-               default:   
-                       panic ("Ill formed methodtype-descriptor");
-               }
-               break;
-                       
-       default:   
-               panic ("Ill formed methodtype-descriptor");
+       switch (*utf_ptr++) {
+         case 'B':
+         case 'C':
+         case 'I':
+         case 'S':
+         case 'Z':  
+         case 'J':  
+         case 'F':  
+         case 'D':
+                 /* primitive type */  
+                 break;
+                 
+         case '[':
+         case 'L':
+                 if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                         panic ("Ill formed descriptor");
+                 break;
+                 
+         default:   
+                 panic ("Ill formed descriptor");
        }                       
-
-        /* exceeding characters */             
+       
+       /* exceeding characters */              
        if (utf_ptr!=end_pos) panic ("descriptor has exceeding chars");
 }
 
@@ -608,12 +698,17 @@ static void checkmethoddescriptor (utf *d)
        char *end_pos = utf_end(d);  /* points behind utf string       */
        char *tstart;                /* pointer to start of classname  */
        char c,ch;
+       char *start; /* XXX remove */
 
        /* method descriptor must start with parenthesis */
+       /* XXX check length */
        if (*utf_ptr++ != '(') panic ("Missing '(' in method descriptor");
 
+       /* XXX check length */
        /* check arguments */
        while ((c = *utf_ptr++) != ')') {
+               start = utf_ptr-1; /* XXX remove */
+               
                switch (c) {
                case 'B':
                case 'C':
@@ -626,58 +721,15 @@ static void checkmethoddescriptor (utf *d)
                        /* primitive type */  
                        break;
 
+               case '[':
                case 'L':
-                       /* save start of classname */ 
-                       tstart = utf_ptr;
-                       
-                       /* determine length of classname */
-                       while ( *utf_ptr++ != ';' )
-                               if (utf_ptr>=end_pos) 
-                                       panic ("Missing ';' in objecttype-descriptor");
-                       
-                       /* cause loading of referenced class */
-                       class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                       break;
-          
-               case '[' :
-                       /* array type */ 
-                       while ((ch = *utf_ptr++)=='[') 
-                               /* skip */ ;
-
-                       /* component type of array */
-                       switch (ch) {
-                       case 'B':
-                       case 'C':
-                       case 'I':
-                       case 'S':
-                       case 'Z':  
-                       case 'J':  
-                       case 'F':  
-                       case 'D':
-                               /* primitive type */  
-                               break;
-
-                       case 'L':
-                               /* save start of classname */
-                               tstart = utf_ptr;
-                       
-                               /* determine length of classname */     
-                               while ( *utf_ptr++ != ';' )
-                                       if (utf_ptr>=end_pos) 
-                                               panic ("Missing ';' in objecttype-descriptor");
-
-                               /* cause loading of referenced class */
-                               class_new ( utf_new(tstart, utf_ptr-tstart-1) );
-                               break;
-
-                       default:   
-                               panic ("Ill formed methodtype-descriptor");
-                       } 
+                       if (!class_from_descriptor(start,end_pos,&utf_ptr,CLASSLOAD_NEW))
+                               panic ("Ill formed method descriptor");
                        break;
                        
                default:   
                        panic ("Ill formed methodtype-descriptor");
-               }                       
+               }
        }
 
        /* check returntype */
@@ -698,9 +750,13 @@ static void checkmethoddescriptor (utf *d)
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
 {
        constant_arraydescriptor *d;
+
+       /* class_new( utf_new(utf_ptr,namelen) ); */ /* XXX remove */
        
        if (*utf_ptr++ != '[') panic ("Attempt to build arraydescriptor for non-array");
 
@@ -737,6 +793,7 @@ constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
        }
        return d;
 }
+#endif
 
 
 /******************* Function: freearraydescriptor *****************************
@@ -745,6 +802,8 @@ constant_arraydescriptor * buildarraydescriptor(char *utf_ptr, u4 namelen)
        
 *******************************************************************************/
 
+/* XXX delete */
+#if 0
 static void freearraydescriptor (constant_arraydescriptor *d)
 {
        while (d) {
@@ -753,9 +812,12 @@ static void freearraydescriptor (constant_arraydescriptor *d)
                d = n;
                }
 }
+#endif
 
 /*********************** Function: displayarraydescriptor *********************/
 
+/* XXX delete */
+#if 0
 static void displayarraydescriptor (constant_arraydescriptor *d)
 {
        switch (d->arraytype) {
@@ -771,8 +833,44 @@ static void displayarraydescriptor (constant_arraydescriptor *d)
        case ARRAYTYPE_OBJECT: utf_display(d->objectclass->name); printf("[]"); break;
        }
 }
+#endif
 
+/***************** Function: print_arraydescriptor ****************************
 
+       Debugging helper for displaying an arraydescriptor
+       
+*******************************************************************************/
+
+void
+print_arraydescriptor(FILE *file,arraydescriptor *desc)
+{
+       if (!desc) {
+               fprintf(file,"<NULL>");
+               return;
+       }
+
+       fprintf(file,"{");
+       if (desc->componentvftbl) {
+               if (desc->componentvftbl->class)
+                       utf_fprint(file,desc->componentvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+               
+       fprintf(file,",");
+       if (desc->elementvftbl) {
+               if (desc->elementvftbl->class)
+                       utf_fprint(file,desc->elementvftbl->class->name);
+               else
+                       fprintf(file,"<no classinfo>");
+       }
+       else
+               fprintf(file,"0");
+       fprintf(file,",%d,%d,%d,%d}",desc->arraytype,desc->dimension,
+                       desc->dataoffset,desc->componentsize);
+}
 
 /******************************************************************************/
 /**************************  Functions for fields  ****************************/
@@ -1077,8 +1175,10 @@ voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
                panic ("Attempt to access constant outside range");
 
        /* check type of constantpool entry */
+
        if (c->cptags[pos] != ctype) {
-               sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
+               class_showconstantpool(c);
+               sprintf (logtext, "Type mismatch on constant: %d requested, %d here (class_getconstant)",
                 (int) ctype, (int) c->cptags[pos] );
                error();
                }
@@ -1334,21 +1434,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_classes) {
                utf *name =
                  class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
-               
-               if ( (name->blength>0) && (name->text[0]=='[') ) {
-                       /* check validity of descriptor */
-                       checkfielddescriptor (name->text, utf_end(name)); 
 
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
-                       cpinfos [forward_classes -> thisindex] = 
-                          buildarraydescriptor(name->text, name->blength);
+               cptags  [forward_classes -> thisindex] = CONSTANT_Class;
+               /* retrieve class from class-table */
+               cpinfos [forward_classes -> thisindex] = class_new (name);
 
-                       }
-               else {                                  
-                       cptags  [forward_classes -> thisindex] = CONSTANT_Class;
-                       /* retrieve class from class-table */
-                       cpinfos [forward_classes -> thisindex] = class_new (name);
-                       }
                forward_classes = forward_classes -> next;
                
                }
@@ -1356,7 +1446,11 @@ static void class_loadcpool (classinfo *c)
        while (forward_strings) {
                utf *text = 
                  class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
-       
+/*
+               log_text("forward_string:");
+               printf( "classpoolid: %d\n",forward_strings -> thisindex);
+               utf_display(text);
+               log_text("\n------------------"); */
                /* resolve utf-string */                
                cptags   [forward_strings -> thisindex] = CONSTANT_String;
                cpinfos  [forward_strings -> thisindex] = text;
@@ -1395,6 +1489,21 @@ static void class_loadcpool (classinfo *c)
                nat = class_getconstant
                        (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
 
+#ifdef JOWENN_DEBUG
+               log_text("trying to resolve:");
+               log_text(nat->name->text);
+               switch(forward_fieldmethints ->tag) {
+               case CONSTANT_Fieldref: 
+                               log_text("CONSTANT_Fieldref");
+                               break;
+               case CONSTANT_InterfaceMethodref: 
+                               log_text("CONSTANT_InterfaceMethodref");
+                               break;
+               case CONSTANT_Methodref: 
+                               log_text("CONSTANT_Methodref");
+                               break;
+               }
+#endif
                fmi -> class = class_getconstant 
                        (c, forward_fieldmethints -> class_index, CONSTANT_Class);
                fmi -> name = nat -> name;
@@ -1417,6 +1526,7 @@ static void class_loadcpool (classinfo *c)
 
                }
 
+/*     class_showconstantpool(c); */
 
        dump_release (dumpsize);
 }
@@ -1444,6 +1554,9 @@ static int class_load (classinfo *c)
        count_class_loads++;
 #endif
 
+       /* XXX remove */
+       /*      loadverbose = 1; */
+       
        /* output for debugging purposes */
        if (loadverbose) {              
 
@@ -1453,8 +1566,9 @@ static int class_load (classinfo *c)
                }
        
        /* load classdata, throw exception on error */
+
        if (!suck_start (c->name)) {
-               throw_classnotfoundexception();            
+               throw_classnotfoundexception2(c->name);            
                return false;
        }
        
@@ -1469,9 +1583,11 @@ static int class_load (classinfo *c)
                error();
                }
 
-
        class_loadcpool (c);
-       
+       /*JOWENN*/
+       c->erroneous_state=0;
+       c->initializing_thread=0;       
+       /*JOWENN*/
         c -> classUsed = NOTUSED; /* not used initially CO-RT */
        c -> impldBy = NULL;
 
@@ -1498,6 +1614,9 @@ static int class_load (classinfo *c)
 
        /* load fields */
        c -> fieldscount = suck_u2 ();
+/*     utf_display(c->name);
+       printf(" ,Fieldscount: %d\n",c->fieldscount);*/
+
        c -> fields = GCNEW (fieldinfo, c -> fieldscount);
        for (i=0; i < c -> fieldscount; i++) {
                field_load (&(c->fields[i]), c);
@@ -1613,6 +1732,206 @@ static void class_addinterface (classinfo *c, classinfo *ic)
 }
 
 
+/******************* Function: class_new_array *********************************
+
+    This function is called by class_new to setup an array class.
+
+*******************************************************************************/
+
+void
+class_new_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       methodinfo *clone;
+       int namelen;
+
+       /* XXX remove logging */
+       /*
+       sprintf(logtext,"new array class: ");
+       utf_sprint(logtext+strlen(logtext),c->name);
+       dolog();
+       */
+       
+       /* Array classes are not loaded from classfiles. */
+       list_remove (&unloadedclasses, c);
+
+       /* Check array class name */
+       namelen = c->name->blength;
+       if (namelen < 2 || c->name->text[0] != '[')
+               panic("Invalid array class name.");
+
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. We have to create the component class. */
+                 comp = class_new(utf_new(c->name->text + 1,namelen - 1));
+                 break;
+
+         case 'L':
+                 /* XXX remove logging */
+                 /*
+                 sprintf(logtext,"Component class: ");
+                 utf_sprint(logtext+strlen(logtext),utf_new(c->name->text + 2,namelen - 3));
+                 dolog();
+                 if (class_get(utf_new(c->name->text + 2,namelen - 3)))
+                         log_text("Already created.");
+                 */
+                 
+                 /* c is an array of objects. */
+                 if (namelen < 4 || c->name->text[namelen-1] != ';')
+                         panic("Invalid array class name.");
+                 comp = class_new(utf_new(c->name->text + 2,namelen - 3));
+                 break;
+       }
+
+       /* Setup the array class */
+       c->super = class_java_lang_Object;
+
+    c->interfacescount = 2;
+    c->interfaces = MNEW(classinfo*,2);
+    c->interfaces[0] = class_java_lang_Cloneable;
+    c->interfaces[1] = class_java_io_Serializable;
+
+       c->methodscount = 1;
+       c->methods = MNEW (methodinfo, c->methodscount);
+
+       clone = c->methods;
+       memset(clone,0,sizeof(methodinfo));
+       clone->flags = ACC_PUBLIC; /* XXX protected? */
+       clone->name = utf_new_char("clone");
+       clone->descriptor = utf_new_char("()Ljava/lang/Object;");
+       clone->class = c;
+       clone->stubroutine = createnativestub(&builtin_clone_array,clone);
+       clone->monoPoly = MONO; /* XXX should be poly? */
+
+       /* XXX: field: length? */
+
+       /* The array class has to be linked */
+       list_addlast(&unlinkedclasses,c);
+       
+       /*
+     * Array classes which are created after the other classes have been
+     * loaded and linked are linked explicitely.
+     */
+       if (loader_inited)
+               loader_load(c->name);
+}
+
+/****************** Function: class_link_array *********************************
+
+    This function is called by class_link to create the
+    arraydescriptor for an array class.
+
+    This function returns NULL if the array cannot be linked because
+    the component type has not been linked yet.
+
+*******************************************************************************/
+
+static
+arraydescriptor *
+class_link_array(classinfo *c)
+{
+       classinfo *comp = NULL;
+       int namelen = c->name->blength;
+       arraydescriptor *desc;
+       vftbl *compvftbl;
+
+       /* XXX remove logging */
+
+       /*
+         sprintf(logtext,"linking array class: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
+       
+       /* Check the component type */
+       switch (c->name->text[1]) {
+         case '[':
+                 /* c is an array of arrays. */
+                 comp = class_get(utf_new(c->name->text + 1,namelen - 1));
+                 if (!comp) panic("Could not find component array class.");
+                 break;
+
+         case 'L':
+                 /* c is an array of objects. */
+                 comp = class_get(utf_new(c->name->text + 2,namelen - 3));
+                 if (!comp) panic("Could not find component class.");
+                 break;
+       }
+
+       /* If the component type has not been linked return NULL */
+       if (comp && !comp->linked)
+               return NULL;
+
+       /* Allocate the arraydescriptor */
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray,data);
+               
+               compvftbl = comp->vftbl;
+               if (!compvftbl)
+                       panic("Component class has no vftbl.");
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+               }
+               else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+               }
+       }
+       else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+                 case 'Z': desc->arraytype = ARRAYTYPE_BOOLEAN;
+                           desc->dataoffset = OFFSET(java_booleanarray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'B': desc->arraytype = ARRAYTYPE_BYTE;
+                           desc->dataoffset = OFFSET(java_bytearray,data);
+                               desc->componentsize = sizeof(u1); break;
+                 case 'C': desc->arraytype = ARRAYTYPE_CHAR;
+                           desc->dataoffset = OFFSET(java_chararray,data);
+                               desc->componentsize = sizeof(u2); break;
+                 case 'D': desc->arraytype = ARRAYTYPE_DOUBLE;
+                           desc->dataoffset = OFFSET(java_doublearray,data);
+                               desc->componentsize = sizeof(double); break;
+                 case 'F': desc->arraytype = ARRAYTYPE_FLOAT;
+                           desc->dataoffset = OFFSET(java_floatarray,data);
+                               desc->componentsize = sizeof(float); break;
+                 case 'I': desc->arraytype = ARRAYTYPE_INT;
+                           desc->dataoffset = OFFSET(java_intarray,data);
+                               desc->componentsize = sizeof(s4); break;
+                 case 'J': desc->arraytype = ARRAYTYPE_LONG;
+                           desc->dataoffset = OFFSET(java_longarray,data);
+                               desc->componentsize = sizeof(s8); break;
+                 case 'S': desc->arraytype = ARRAYTYPE_SHORT;
+                           desc->dataoffset = OFFSET(java_shortarray,data);
+                               desc->componentsize = sizeof(s2); break;
+                 default:
+                         panic("Invalid array class name");
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+       }
+
+       /* XXX remove logging */
+       /*
+         print_arraydescriptor(stdout,desc); 
+         printf("\n");
+       */
+
+       return desc;
+}
+
 /********************** Function: class_link ***********************************
 
        Tries to link a class. The super class and every implemented interface must
@@ -1637,9 +1956,17 @@ void class_link(classinfo *c)
        classinfo *super = c->super;  /* super class                              */
        classinfo *ic, *c2;           /* intermediate class variables             */
        vftbl *v;                     /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */                     
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc = NULL;  /* descriptor for array classes       */
 
 
+       /* XXX remove log */
+       /*
+         sprintf(logtext,"trying to link: ");
+         utf_sprint(logtext+strlen(logtext),c->name);
+         dolog();
+       */
+       
        /*  check if all superclasses are already linked, if not put c at end of
            unlinked list and return. Additionally initialize class fields.       */
 
@@ -1673,6 +2000,14 @@ void class_link(classinfo *c)
                        return; 
                }
 
+               /* handle array classes */
+               if (c->name->text[0] == '[')
+                       if ((arraydesc = class_link_array(c)) == NULL) {
+                               list_remove(&unlinkedclasses, c);
+                               list_addlast(&unlinkedclasses, c);
+                               return; 
+                       }
+               
                if (c->flags & ACC_INTERFACE)
                        c->index = interfaceindex++;
                else
@@ -1742,6 +2077,11 @@ void class_link(classinfo *c)
        v->class = c;
        v->vftbllength = vftbllength;
        v->interfacetablelength = interfacetablelength;
+       v->arraydesc = arraydesc;
+
+       /* store interface index in vftbl */
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
 
        /* copy virtual function table of super class */
 
@@ -1815,8 +2155,9 @@ void class_link(classinfo *c)
 
        c->linked = true;       
 
-       list_remove(&unlinkedclasses, c);
-       list_addlast(&linkedclasses, c);
+       list_remove (&unlinkedclasses, c);
+       list_addlast (&linkedclasses, c);
+
 }
 
 
@@ -1858,9 +2199,6 @@ static void class_freecpool (classinfo *c)
                        case CONSTANT_NameAndType:
                                FREE (info, constant_nameandtype);
                                break;
-                       case CONSTANT_Arraydescriptor:
-                               freearraydescriptor (info);
-                               break;
                        }
                        }
                }
@@ -1893,6 +2231,9 @@ static void class_free (classinfo *c)
        MFREE (c->methods, methodinfo, c->methodscount);
 
        if ((v = c->vftbl) != NULL) {
+               if (v->arraydesc)
+                       mem_free(v->arraydesc,sizeof(arraydescriptor));
+               
                for (i = 0; i < v->interfacetablelength; i++) {
                        MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
                        }
@@ -1909,8 +2250,8 @@ static void class_free (classinfo *c)
        if (c->innerclasscount)
                MFREE (c->innerclass, innerclassinfo, c->innerclasscount);
 
-       if (c->classvftbl)
-               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1));
+       /*      if (c->classvftbl)
+               mem_free(c->header.vftbl, sizeof(vftbl) + sizeof(methodptr)*(c->vftbl->vftbllength-1)); */
        
        FREE (c, classinfo);
 }
@@ -1927,6 +2268,7 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 {
        s4 i;
 
+       
        for (i = 0; i < c->fieldscount; i++) { 
                if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc)) 
                        return &(c->fields[i]);                                                         
@@ -1937,6 +2279,70 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 }
 
 
+/************************* Function: class_findmethod **************************
+       
+       Searches a 'classinfo' structure for a method having the given name and
+       type and returns the index in the class info structure.
+       If type is NULL, it is ignored.
+
+*******************************************************************************/
+
+s4 class_findmethodIndex (classinfo *c, utf *name, utf *desc)
+{
+       s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
+       for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
+               if ((c->methods[i].name == name) && ((desc == NULL) ||
+                                                  (c->methods[i].descriptor == desc)))
+                       return i;
+               }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
+       return -1;
+}
+
+
+
 /************************* Function: class_findmethod **************************
        
        Searches a 'classinfo' structure for a method having the given name and
@@ -1947,15 +2353,69 @@ fieldinfo *class_findfield (classinfo *c, utf *name, utf *desc)
 
 methodinfo *class_findmethod (classinfo *c, utf *name, utf *desc)
 {
+#if 0
        s4 i;
+#if defined(JOWENN_DEBUG1) || defined(JOWENN_DEBUG2)
+       char *buffer;                   
+       int buffer_len, pos;
+#endif
+#ifdef JOWENN_DEBUG1
+
+       buffer_len = 
+         utf_strlen(name) + utf_strlen(desc) +utf_strlen(c->name)+ 64;
+       
+       buffer = MNEW(char, buffer_len);
+
+       strcpy(buffer, "class_findmethod: method:");
+        utf_sprint(buffer+strlen(buffer), name);
+       strcpy(buffer+strlen(buffer), ", desc: ");
+        utf_sprint(buffer+strlen(buffer), desc);
+       strcpy(buffer+strlen(buffer), ", classname: ");
+        utf_sprint(buffer+strlen(buffer), c->name);
+       
+       log_text(buffer);       
+
+       MFREE(buffer, char, buffer_len);
+#endif 
        for (i = 0; i < c->methodscount; i++) {
+#ifdef JOWENN_DEBUG2
+               buffer_len = 
+                 utf_strlen(c->methods[i].name) + utf_strlen(c->methods[i].descriptor)+ 64;
+       
+               buffer = MNEW(char, buffer_len);
+
+               strcpy(buffer, "class_findmethod: comparing to method:");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].name);
+               strcpy(buffer+strlen(buffer), ", desc: ");
+               utf_sprint(buffer+strlen(buffer), c->methods[i].descriptor);
+       
+               log_text(buffer);       
+
+               MFREE(buffer, char, buffer_len);
+               #endif  
+               
+               
                if ((c->methods[i].name == name) && ((desc == NULL) ||
                                                   (c->methods[i].descriptor == desc)))
                        return &(c->methods[i]);
                }
+#ifdef JOWENN_DEBUG2   
+       class_showconstantpool(c);
+       log_text("class_findmethod: returning NULL");
+#endif
        return NULL;
+#endif
+       s4 idx=class_findmethodIndex(c,name,desc);
+/*     if (idx==-1) log_text("class_findmethod: method not found");*/
+       if (idx==-1) return NULL;
+       return &(c->methods[idx]);
 }
 
+
+
+
+
+
 /************************* Function: class_findmethod_approx ******************
        
        like class_findmethod but ignores the return value when comparing the
@@ -2064,113 +2524,118 @@ bool class_issubclass(classinfo *sub, classinfo *super)
 
 *******************************************************************************/
 
+#ifdef USE_THREADS
+extern int blockInts;
+#endif
+
 void class_init(classinfo *c)
 {
-       methodinfo *m;
-       java_objectheader *exceptionptr;
-       s4 i;
-       int b;
+        methodinfo *m;
+        java_objectheader *exceptionptr;
+        s4 i;
+        int b;
 
-       if (!makeinitializations)
-               return;
-       if (c->initialized)
-               return;
 
-       c->initialized = true;
-       
-#ifdef STATISTICS
-       count_class_inits++;
-#endif
+        if (!makeinitializations)
+                return;
+        if (c->initialized)
+                return;
+        c -> initialized = true;
 
-       if (c->super)
-               class_init(c->super);
-       for (i = 0; i < c->interfacescount; i++)
-               class_init(c->interfaces[i]);  /* real */
 
-       m = class_findmethod(c, utf_clinit, utf_fidesc);
 
-       if (!m) {
-               if (initverbose) {
-                       sprintf(logtext, "Class ");
-                       utf_sprint(logtext+strlen(logtext), c->name);
-                       sprintf(logtext+strlen(logtext), " has no initializer");        
-                       dolog();
-               }
-               return;
-       }
-               
-       if (!(m->flags & ACC_STATIC))
-               panic("Class initializer is not static!");
-       
-       if (initverbose) {
-               sprintf(logtext, "Starting initializer for class: ");
-               utf_sprint(logtext + strlen(logtext), c->name);
-               dolog();
-       }
-
-#ifdef USE_THREADS
-       b = blockInts;
-       blockInts = 0;
+#ifdef STATISTICS
+        count_class_inits++;
 #endif
 
-       exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
+        if (c->super)
+                class_init (c->super);
+        for (i=0; i < c->interfacescount; i++)
+                class_init(c->interfaces[i]);  /* real */
+
+        m = class_findmethod (c, utf_clinit, utf_fidesc);
+        if (!m) {
+                if (initverbose) {
+                        sprintf (logtext, "Class ");
+                        utf_sprint (logtext+strlen(logtext), c->name);
+                        sprintf (logtext+strlen(logtext), " has no initializer");
+                        dolog ();
+                        }
+/*              goto callinitialize;*/
+                return;
+                }
+
+        if (! (m->flags & ACC_STATIC))
+                panic ("Class initializer is not static!");
+
+        if (initverbose) {
+                sprintf (logtext, "Starting initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
 
 #ifdef USE_THREADS
-       assert(blockInts == 0);
-       blockInts = b;
+        b = blockInts;
+        blockInts = 0;
 #endif
 
-       if (exceptionptr) {
-               printf("#### Initializer of ");
-               utf_display(c->name);
-               printf(" has thrown: ");
-               utf_display(exceptionptr->vftbl->class->name);
-               printf("\n");
-               fflush(stdout);
-       }
-
-       if (initverbose) {
-               sprintf(logtext, "Finished initializer for class: ");
-               utf_sprint(logtext + strlen(logtext), c->name);
-               dolog();
-       }
-
-       if (c->name == utf_systemclass) {
-               /* class java.lang.System requires explicit initialization */
-               
-               if (initverbose)
-                       printf("#### Initializing class System");
-
-               /* find initializing method */     
-               m = class_findmethod(c, 
-                                                        utf_initsystemclass,
-                                                        utf_fidesc);
-
-               if (!m) {
-                       /* no method found */
-                       printf("initializeSystemClass failed");
-                       return;
-               }
+        exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
 
 #ifdef USE_THREADS
-               b = blockInts;
-               blockInts = 0;
+        assert(blockInts == 0);
+        blockInts = b;
 #endif
 
-               exceptionptr = asm_calljavamethod(m, NULL, NULL, NULL, NULL);
-
-#ifdef USE_THREADS
-               assert(blockInts == 0);
-               blockInts = b;
-#endif
+        if (exceptionptr) {
+                printf ("#### Initializer of ");
+                utf_display (c->name);
+                printf (" has thrown: ");
+                utf_display (exceptionptr->vftbl->class->name);
+                printf ("\n");
+                fflush (stdout);
+                }
+
+        if (initverbose) {
+                sprintf (logtext, "Finished initializer for class: ");
+                utf_sprint (logtext+strlen(logtext), c->name);
+                dolog ();
+        }
+        if (c->name == utf_systemclass) {
+                /* class java.lang.System requires explicit initialization */
+
+                if (initverbose)
+                        printf ("#### Initializing class System");
+
+                /* find initializing method */
+                m = class_findmethod (c,
+                                        utf_initsystemclass,
+                                        utf_fidesc);
+
+                if (!m) {
+                        /* no method found */
+                        /* printf("initializeSystemClass failed"); */
+                        return;
+                }
+                #ifdef USE_THREADS
+                        b = blockInts;
+                        blockInts = 0;
+                #endif
+
+                exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
+
+                #ifdef USE_THREADS
+                        assert(blockInts == 0);
+                        blockInts = b;
+                #endif
+
+                if (exceptionptr) {
+                        printf ("#### initializeSystemClass has thrown: ");
+                        utf_display (exceptionptr->vftbl->class->name);
+                        printf ("\n");
+                        fflush (stdout);
+                }
+        }
 
-               if (exceptionptr) {                     
-                       printf("#### initializeSystemClass has thrown: ");
-                       utf_display(exceptionptr->vftbl->class->name);
-                       printf("\n");
-                       fflush(stdout);
-               }
-       }
 }
 
 
@@ -2287,11 +2752,6 @@ void class_showconstanti(classinfo *c, int ii)
                        printf("Utf8 -> ");
                        utf_display(e);
                        break;
-               case CONSTANT_Arraydescriptor:  {
-                       printf("Arraydescriptor: ");
-                       displayarraydescriptor(e);
-               }
-               break;
                default: 
                        panic("Invalid type of ConstantPool-Entry");
                }
@@ -2373,11 +2833,6 @@ void class_showconstantpool (classinfo *c)
                                printf ("Utf8 -> ");
                                utf_display (e);
                                break;
-                       case CONSTANT_Arraydescriptor:  {
-                               printf ("Arraydescriptor: ");
-                               displayarraydescriptor (e);
-                       }
-                       break;
                        default: 
                                panic ("Invalid type of ConstantPool-Entry");
                        }
@@ -2439,8 +2894,6 @@ void class_showmethods (classinfo *c)
 /******************* General functions for the class loader *******************/
 /******************************************************************************/
 
-static int loader_inited = 0;
-
 /********************* Function: loader_load ***********************************
 
        Loads and links the class desired class and each class and interface
@@ -2449,11 +2902,18 @@ static int loader_inited = 0;
 
 *******************************************************************************/
 
+static int loader_load_running = 0;
+
 classinfo *loader_load (utf *topname)
 {
        classinfo *top;
        classinfo *c;
        long int starttime=0,stoptime=0;
+
+       /* avoid recursive calls */
+       if (loader_load_running)
+               return class_new(topname);
+       loader_load_running++;
        
        intsDisable();                           /* schani */
 
@@ -2486,6 +2946,8 @@ classinfo *loader_load (utf *topname)
 
        intsRestore();                          /* schani */
 
+       loader_load_running--;
+       
        return top; 
 }
 
@@ -2521,6 +2983,80 @@ void create_primitive_classes()
                        class_new( utf_new_char(primitivetype_table[i].wrapname) );
                 primitivetype_table[i].class_wrap -> classUsed = NOTUSED; /* not used initially CO-RT */
                primitivetype_table[i].class_wrap  -> impldBy = NULL;
+
+               /* create the primitive array class */
+               if (primitivetype_table[i].arrayname) {
+                       c = class_new( utf_new_char(primitivetype_table[i].arrayname) );
+                       primitivetype_table[i].arrayclass = c;
+                       if (!c->linked) class_link(c);
+                       primitivetype_table[i].arrayvftbl = c->vftbl;
+               }
+       }
+}
+
+/**************** function: class_primitive_from_sig ***************************
+
+       return the primitive class indicated by the given signature character
+
+    If the descriptor does not indicate a valid primitive type the
+    return value is NULL.
+
+********************************************************************************/
+
+classinfo *class_primitive_from_sig(char sig)
+{
+       switch (sig) {
+         case 'I': return primitivetype_table[PRIMITIVETYPE_INT].class_primitive;
+         case 'J': return primitivetype_table[PRIMITIVETYPE_LONG].class_primitive;
+         case 'F': return primitivetype_table[PRIMITIVETYPE_FLOAT].class_primitive;
+         case 'D': return primitivetype_table[PRIMITIVETYPE_DOUBLE].class_primitive;
+         case 'B': return primitivetype_table[PRIMITIVETYPE_BYTE].class_primitive;
+         case 'C': return primitivetype_table[PRIMITIVETYPE_CHAR].class_primitive;
+         case 'S': return primitivetype_table[PRIMITIVETYPE_SHORT].class_primitive;
+         case 'Z': return primitivetype_table[PRIMITIVETYPE_BOOLEAN].class_primitive;
+         case 'V': return primitivetype_table[PRIMITIVETYPE_VOID].class_primitive;
+       }
+       return NULL;
+}
+
+/****************** function: class_from_descriptor ****************************
+
+    return the class indicated by the given descriptor
+
+    utf_ptr....first character of descriptor
+    end_ptr....first character after the end of the string
+    next.......if non-NULL, *next is set to the first character after
+               the descriptor
+    mode.......what to do if a class descriptor is parsed successfully:
+                   CLASSLOAD_SKIP...skip it and return something != NULL
+                   CLASSLOAD_NEW....get classinfo * via class_new
+                   CLASSLOAD_LOAD...get classinfo * via loader_load
+
+    If the descriptor is invalid the return value is NULL
+
+********************************************************************************/
+
+classinfo *class_from_descriptor(char *utf_ptr,char *end_ptr,char **next,int mode)
+{
+       char *start = utf_ptr;
+       bool error = false;
+       utf *name;
+       
+       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,error);
+       if (error) return NULL;
+       if (next) *next = utf_ptr;
+
+       switch (*start) {
+         case 'L':
+                 start++;
+                 utf_ptr--;
+                 /* fallthrough */
+         case '[':
+                 if (mode == CLASSLOAD_SKIP) return class_java_lang_Object;
+                 name = utf_new(start,utf_ptr-start);
+                 return (mode == CLASSLOAD_LOAD) ? loader_load(name) : class_new(name);
+         default:
+                 return class_primitive_from_sig(*start);
        }
 }
 
@@ -2530,7 +3066,8 @@ void create_primitive_classes()
 
 ********************************************************************************/
 
-
+/* XXX delete */
+#if 0
 classinfo *create_array_class(utf *u)
 {  
        classinfo *c = class_new (u);
@@ -2540,9 +3077,47 @@ classinfo *create_array_class(utf *u)
        list_addlast (&unlinkedclasses, c);
        c -> super = class_java_lang_Object;
        class_link(c);
-
        return c;
 }
+#endif
+
+/*************** function: create_pseudo_classes *******************************
+
+       create pseudo classes used by the typechecker
+
+********************************************************************************/
+
+static void
+create_pseudo_classes()
+{
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+    
+    pseudo_class_Arraystub = class_new( utf_new_char(";Arraystub;") );
+    list_remove(&unloadedclasses,pseudo_class_Arraystub);
+
+    pseudo_class_Arraystub->super = class_java_lang_Object;
+    pseudo_class_Arraystub->interfacescount = 2;
+    pseudo_class_Arraystub->interfaces = MNEW(classinfo*,2);
+    pseudo_class_Arraystub->interfaces[0] =
+        class_java_lang_Cloneable;
+    pseudo_class_Arraystub->interfaces[1] =
+        class_java_io_Serializable;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Arraystub);
+    class_link(pseudo_class_Arraystub);
+
+       pseudo_class_Arraystub_vftbl = pseudo_class_Arraystub->vftbl;
+
+    /* pseudo class representing the null type */
+    
+    pseudo_class_Null = class_new( utf_new_char(";Null;") );
+    list_remove(&unloadedclasses,pseudo_class_Null);
+
+    pseudo_class_Null->super = class_java_lang_Object;
+
+    list_addlast(&unlinkedclasses,pseudo_class_Null);
+    class_link(pseudo_class_Null);     
+}
 
 /********************** Function: loader_init **********************************
 
@@ -2551,14 +3126,17 @@ classinfo *create_array_class(utf *u)
 
 *******************************************************************************/
  
-void loader_init()
+void loader_init (u1 * stackbottom)
 {
-       utf *string_class;
        interfaceindex = 0;
        
-       list_init(&unloadedclasses, OFFSET(classinfo, listnode));
-       list_init(&unlinkedclasses, OFFSET(classinfo, listnode));
-       list_init(&linkedclasses, OFFSET(classinfo, listnode));
+       
+       log_text("Entering loader_init");
+                               
+       
+       list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
+       list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
+       list_init (&linkedclasses, OFFSET(classinfo, listnode) );
 
        /* create utf-symbols for pointer comparison of frequently used strings */
        utf_innerclasses    = utf_new_char("InnerClasses");
@@ -2569,90 +3147,100 @@ void loader_init()
        utf_clinit              = utf_new_char("<clinit>");
        utf_initsystemclass = utf_new_char("initializeSystemClass");
        utf_systemclass     = utf_new_char("java/lang/System");
+       utf_vmclassloader =utf_new_char("java/lang/VMClassLoader");
+       utf_initialize =utf_new_char("initialize");
+       utf_initializedesc =utf_new_char("(I)V");
+
+       utf_vmclass =utf_new_char("java/lang/VMClass");
+
+        /* create some important classes */
+        /* These classes have to be created now because the classinfo
+         * pointers are used in the loading code.
+         */
+        class_java_lang_Object = class_new( utf_new_char ("java/lang/Object") );
+        class_java_lang_String = class_new( utf_new_char("java/lang/String") );
+        class_java_lang_Cloneable = class_new( utf_new_char ("java/lang/Cloneable") );
+        class_java_io_Serializable = class_new( utf_new_char ("java/io/Serializable") );
+
+        log_text("loader_init: java/lang/Object");
+        /* load the classes which were created above */
+        loader_load (class_java_lang_Object->name);
+
+        loader_inited=1; /*JOWENN*/
+
+        class_java_lang_Throwable =
+                loader_load( utf_new_char("java/lang/Throwable") );
+
+        log_text("loader_init:  loader_load: java/lang/ClassCastException");
+        class_java_lang_ClassCastException =
+                loader_load ( utf_new_char ("java/lang/ClassCastException") );
+        class_java_lang_NullPointerException =
+                loader_load ( utf_new_char ("java/lang/NullPointerException") );
+        class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
+             utf_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
+        class_java_lang_NegativeArraySizeException = loader_load (
+             utf_new_char ("java/lang/NegativeArraySizeException") );
+        class_java_lang_OutOfMemoryError = loader_load (
+             utf_new_char ("java/lang/OutOfMemoryError") );
+        class_java_lang_ArrayStoreException =
+                loader_load ( utf_new_char ("java/lang/ArrayStoreException") );
+        class_java_lang_ArithmeticException =
+                loader_load ( utf_new_char ("java/lang/ArithmeticException") );
+        class_java_lang_ThreadDeath =                             /* schani */
+                loader_load ( utf_new_char ("java/lang/ThreadDeath") );
+        /* create classes representing primitive types */
+        create_primitive_classes();
+
+        /* create classes used by the typechecker */
+        create_pseudo_classes();
+
+        /* correct vftbl-entries (retarded loading of class java/lang/String) */
+        stringtable_update();
+#ifdef USE_THREADS
+        if (stackbottom!=0)
+                initLocks();
+#endif
+
 
-       /* create class for arrays */
-       class_array = class_new(utf_new_char("The_Array_Class"));
-    class_array->classUsed = NOTUSED; /* not used initially CO-RT */
-       class_array->impldBy = NULL;
-
-       list_remove (&unloadedclasses, class_array);
-
-       /* create class for strings, load it after class Object was loaded */
-       string_class = utf_new_char("java/lang/String");
-       class_java_lang_String = class_new(string_class);
-    class_java_lang_String->classUsed = NOTUSED; /* not used initially CO-RT */
-       class_java_lang_String->impldBy = NULL;
-
-       list_remove(&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_Object = 
-               loader_load(utf_new_char("java/lang/Object"));
-
-       list_addlast(&unloadedclasses, class_java_lang_String);
-
-       class_java_lang_String =
-               loader_load(string_class);
-       class_java_lang_ClassCastException = 
-               loader_load(utf_new_char("java/lang/ClassCastException"));
-       class_java_lang_NullPointerException = 
-               loader_load(utf_new_char("java/lang/NullPointerException"));
-       class_java_lang_ArrayIndexOutOfBoundsException =
-               loader_load(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
-       class_java_lang_NegativeArraySizeException =
-               loader_load(utf_new_char("java/lang/NegativeArraySizeException"));
-       class_java_lang_OutOfMemoryError =
-               loader_load(utf_new_char("java/lang/OutOfMemoryError"));
-       class_java_lang_ArrayStoreException =
-               loader_load(utf_new_char("java/lang/ArrayStoreException"));
-       class_java_lang_ArithmeticException = 
-               loader_load(utf_new_char("java/lang/ArithmeticException"));
-       class_java_lang_ThreadDeath =
-               loader_load(utf_new_char("java/lang/ThreadDeath"));
-
-       /* link class for arrays */
-       list_addlast(&unlinkedclasses, class_array);
-       class_array->super = class_java_lang_Object;
-       class_link(class_array);
-
-       /* correct vftbl-entries (retarded loading of class java/lang/String) */
-       stringtable_update(); 
-
-       /* create classes representing primitive types */
-       create_primitive_classes();
-               
-       proto_java_lang_ClassCastException = 
-               builtin_new(class_java_lang_ClassCastException);
-       heap_addreference((void**) &proto_java_lang_ClassCastException);
 
-       proto_java_lang_NullPointerException = 
-               builtin_new(class_java_lang_NullPointerException);
-       heap_addreference((void**) &proto_java_lang_NullPointerException);
+        log_text("loader_init: creating global proto_java_lang_ClassCastException");
+        proto_java_lang_ClassCastException =
+                builtin_new(class_java_lang_ClassCastException);
+        heap_addreference ( (void**) &proto_java_lang_ClassCastException);
 
-       proto_java_lang_ArrayIndexOutOfBoundsException = 
-               builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
-       heap_addreference((void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
+        log_text("loader_init: proto_java_lang_ClassCastException has been initialized");
 
-       proto_java_lang_NegativeArraySizeException = 
-               builtin_new(class_java_lang_NegativeArraySizeException);
-       heap_addreference((void**) &proto_java_lang_NegativeArraySizeException);
+        proto_java_lang_NullPointerException =
+               builtin_new(class_java_lang_NullPointerException);
+        heap_addreference ( (void**) &proto_java_lang_NullPointerException);
+        log_text("loader_init: proto_java_lang_NullPointerException has been initialized");
 
-       proto_java_lang_OutOfMemoryError = 
-               builtin_new(class_java_lang_OutOfMemoryError);
-       heap_addreference((void**) &proto_java_lang_OutOfMemoryError);
+        proto_java_lang_ArrayIndexOutOfBoundsException =
+                builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
 
-       proto_java_lang_ArithmeticException = 
-               builtin_new(class_java_lang_ArithmeticException);
-       heap_addreference((void**) &proto_java_lang_ArithmeticException);
+        proto_java_lang_NegativeArraySizeException =
+                builtin_new(class_java_lang_NegativeArraySizeException);
+        heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
 
-       proto_java_lang_ArrayStoreException = 
-               builtin_new(class_java_lang_ArrayStoreException);
-       heap_addreference((void**) &proto_java_lang_ArrayStoreException);
+        proto_java_lang_OutOfMemoryError =
+                builtin_new(class_java_lang_OutOfMemoryError);
+        heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
 
-       proto_java_lang_ThreadDeath =
-               builtin_new(class_java_lang_ThreadDeath);
-       heap_addreference((void**) &proto_java_lang_ThreadDeath);
+        proto_java_lang_ArithmeticException =
+               builtin_new(class_java_lang_ArithmeticException);
+        heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
+
+        proto_java_lang_ArrayStoreException =
+                builtin_new(class_java_lang_ArrayStoreException);
+        heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
+
+        proto_java_lang_ThreadDeath =                             /* schani */
+                builtin_new(class_java_lang_ThreadDeath);
+        heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
+
+        loader_inited = 1;
 
-       loader_inited = 1;
 }
 
 
@@ -2695,6 +3283,7 @@ static void loader_compute_class_values (classinfo *c)
                subs = subs->nextsub;
                }
        c->vftbl->diffval = classvalue - c->vftbl->baseval;
+       
        /*
        {
        int i;
@@ -2705,6 +3294,7 @@ static void loader_compute_class_values (classinfo *c)
        printf("\n");
        }
        */
+       
 }
 
 
index 06213ca23560b8f56f15d0a5311823849f89f5a2..1e249fcd02516adb6f59beb42f9e675fd31c195f 100644 (file)
@@ -26,8 +26,7 @@
 
    Authors: Reinhard Grafl
 
-   $Id: loader.h 593 2003-11-09 19:50:55Z twisti $
-
+   $Id: loader.h 664 2003-11-21 18:24:01Z jowenn $
 */
 
 
@@ -91,19 +90,29 @@ void class_init(classinfo *c);
 void class_showconstanti(classinfo *c, int ii);
 
 /* debug purposes */
-void class_showconstantpool(classinfo *c);
-void class_showmethods(classinfo *c);
+void class_showmethods (classinfo *c);
+void class_showconstantpool (classinfo *c);
+void print_arraydescriptor(FILE *file,arraydescriptor *desc);
 
 classinfo *loader_load(utf *topname);
 
 /* set buffer for reading classdata */
 void classload_buffer(u1 *buf,int len);
 
-/* create class representing specific arraytype */
+/* return the primitive class inidicated by the given signature character */
+classinfo *class_primitive_from_sig(char sig);
+
+/* return the class indicated by the given descriptor */
+#define CLASSLOAD_SKIP  0
+#define CLASSLOAD_NEW   1
+#define CLASSLOAD_LOAD  2
+classinfo *class_from_descriptor(char *utf_ptr,char *end_ptr,char **next,int mode);
+
+/* create class representing specific arraytype */ /* XXX delete */
 classinfo *create_array_class(utf *u);
 
-/* create the arraydescriptor for the arraytype specified by the utf-string */
-constant_arraydescriptor * buildarraydescriptor(char *utf, u4 namelen);
+/* (used by class_new, don't use directly) */
+void class_new_array(classinfo *c);
 
 void class_link(classinfo *c);
 
@@ -111,6 +120,9 @@ void field_display(fieldinfo *f);
 
 void method_display(methodinfo *m);
 
+utf* clinit_desc();
+utf* clinit_name();
+
 #endif /* _LOADER_H */
 
 
index b2cb65304bb5f0a768144976487799435968c216..b25f3f74122ebf01ac341099290f8b8f39737eab 100644 (file)
@@ -35,7 +35,7 @@
        - the heap
        - additional support functions
 
-   $Id: tables.c 584 2003-11-09 19:15:25Z twisti $
+   $Id: tables.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -348,6 +348,7 @@ utf *utf_new (char *text, u2 length)
        utf *u;            /* hashtable element */
        u2 i;
        
+/*     log_text("utf_new entered");*/
 #ifdef STATISTICS
        count_utf_new++;
 #endif
@@ -367,7 +368,15 @@ utf *utf_new (char *text, u2 length)
 #ifdef STATISTICS
                        count_utf_new_found++;
 #endif
-                       /* symbol found in hashtable */                                 
+/*                     log_text("symbol found in hash table");*/
+                       /* symbol found in hashtable */
+/*                                     utf_display(u);
+                                       {
+                                               utf blup;
+                                               blup.blength=length;
+                                               blup.text=text;
+                                               utf_display(&blup);
+                                       }*/
                        return u;
                }
        nomatch:
@@ -382,8 +391,9 @@ utf *utf_new (char *text, u2 length)
        u = NEW (utf);
        u->blength  = length;             /* length in bytes of utfstring */
        u->hashlink = utf_hash.ptr[slot]; /* link in external hashchain   */            
-       u->text     = mem_alloc(length);  /* allocate memory for utf-text */
+       u->text     = mem_alloc(length/*JOWENN*/+1);  /* allocate memory for utf-text */
        memcpy(u->text,text,length);      /* copy utf-text                */
+        u->text[length]='\0';/*JOWENN*/
        utf_hash.ptr[slot] = u;           /* insert symbol into table     */ 
 
        utf_hash.entries++;               /* update number of entries     */
@@ -424,7 +434,7 @@ utf *utf_new (char *text, u2 length)
                MFREE (utf_hash.ptr, void*, utf_hash.size);
                utf_hash = newhash;
        }
-       
+               /*utf_display(u);*/
        return u;
 }
 
@@ -441,6 +451,33 @@ utf *utf_new_char (char *text)
        return utf_new(text, strlen(text));
 }
 
+
+/********************* function: utf_new_char ********************************
+
+    creates a new utf symbol, the text for this symbol is passed
+    as a c-string ( = char* )
+    "." characters are going to be replaced by "/". since the above function is
+    used often, this is a separte function, instead of an if
+
+******************************************************************************/
+
+utf *utf_new_char_classname (char *text)
+{
+       if (strchr(text,'.')) {
+               char *txt=strdup(text);
+               char *end=txt+strlen(txt);
+               char *c;
+               utf *tmpRes;
+               for (c=txt;c<end;c++)
+                       if (*c=='.') *c='/';
+               tmpRes=utf_new(txt,strlen(txt));
+               free(txt);
+               return tmpRes;
+       }
+       else
+       return utf_new(text, strlen(text));
+}
+
 /************************** Funktion: utf_show ******************************
 
     writes the utf symbols in the utfhash to stdout and
@@ -683,30 +720,33 @@ classinfo *class_new(utf *u)
        count_class_infos += sizeof(classinfo);
 #endif
 
-       c = NEW(classinfo);
-       c->flags = 0;
-       c->name = u;
-       c->cpcount = 0;
-       c->cptags = NULL;
-       c->cpinfos = NULL;
-       c->super = NULL;
-       c->sub = NULL;
-       c->nextsub = NULL;
-       c->interfacescount = 0;
-       c->interfaces = NULL;
-       c->fieldscount = 0;
-       c->fields = NULL;
-       c->methodscount = 0;
-       c->methods = NULL;
-       c->linked = false;
-       c->index = 0;
-       c->instancesize = 0;
-       c->header.vftbl = NULL;
-       c->innerclasscount = 0;
-       c->innerclass = NULL;
-       c->vftbl = NULL;
-       c->initialized = false;
-       c->classvftbl = false;
+       c = NEW (classinfo);
+       c -> vmClass = 0;
+       c -> flags = 0;
+       c -> name = u;
+       c -> cpcount = 0;
+       c -> cptags = NULL;
+       c -> cpinfos = NULL;
+       c -> super = NULL;
+       c -> sub = NULL;
+       c -> nextsub = NULL;
+       c -> interfacescount = 0;
+       c -> interfaces = NULL;
+       c -> fieldscount = 0;
+       c -> fields = NULL;
+       c -> methodscount = 0;
+       c -> methods = NULL;
+       c -> linked = false;
+       c -> index = 0;
+       c -> instancesize = 0;
+       c -> header.vftbl = NULL;
+       c -> innerclasscount = 0;
+       c -> innerclass = NULL;
+       c -> vftbl = NULL;
+       c -> initialized = false;
+       c -> classvftbl = false;
+    c -> classUsed = 0;
+    c -> impldBy = NULL;
        
        /* prepare loading of the class */
        list_addlast(&unloadedclasses, c);
@@ -750,6 +790,10 @@ classinfo *class_new(utf *u)
                class_hash = newhash;
        }
                        
+    /* Array classes need further initialization. */
+    if (u->text[0] == '[')
+        class_new_array(c);
+        
        return c;
 }
 
@@ -791,6 +835,40 @@ classinfo *class_get(utf *u)
        return NULL;
 }
 
+/***************** Function: class_array_of ***********************************
+
+    Returns an array class with the given component class.
+    The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component)
+{
+    int namelen;
+    char *namebuf;
+
+    /* Assemble the array class name */
+    namelen = component->name->blength;
+    
+    if (component->name->text[0] == '[') {
+        /* the component is itself an array */
+        namebuf = DMNEW(char,namelen+1);
+        namebuf[0] = '[';
+        memcpy(namebuf+1,component->name->text,namelen);
+        namelen++;
+    }
+    else {
+        /* the component is a non-array class */
+        namebuf = DMNEW(char,namelen+3);
+        namebuf[0] = '[';
+        namebuf[1] = 'L';
+        memcpy(namebuf+2,component->name->text,namelen);
+        namebuf[2+namelen] = ';';
+        namelen+=3;
+    }
+
+    return class_new( utf_new(namebuf,namelen) );
+}
 
 /************************** function: utf_strlen ******************************
 
index a386c42acf5f8275a76cc6e5c6e44a25c8e2c454..99f365495d2c15c51b21fc02ccf3e7d24bddd18a 100644 (file)
@@ -26,7 +26,7 @@
 
    Authors: Reinhard Grafl
 
-   $Id: tables.h 557 2003-11-02 22:51:59Z twisti $
+   $Id: tables.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -63,6 +63,7 @@ void utf_display(utf *u);
 /* create new utf-symbol */
 utf *utf_new(char *text, u2 length);
 utf *utf_new_char(char *text);
+utf *utf_new_char_classname(char *text);
 
 /* show utf-table */
 void utf_show();
@@ -76,6 +77,9 @@ u4 utf_strlen(utf *u);
 /* search for class and create it if not found */
 classinfo *class_new(utf *u);
 
+/* return an array class with the given component class */
+classinfo *class_array_of(classinfo *component);
+
 /* get javatype according to a typedescriptor */
 u2 desc_to_type(utf *descriptor);
 
diff --git a/src/vm/unzip.c b/src/vm/unzip.c
new file mode 100644 (file)
index 0000000..4934694
--- /dev/null
@@ -0,0 +1,1299 @@
+#include "config.h"
+#ifdef USE_ZLIB
+
+/* unzip.c -- IO on .zip files using zlib 
+   Version 0.15 beta, Mar 19th, 1998,
+
+   Read unzip.h for more info
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+
+#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
+                      !defined(CASESENSITIVITYDEFAULT_NO)
+#define CASESENSITIVITYDEFAULT_NO
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+const char unz_copyright[] =
+   " unzip 0.15 Copyright 1998 Gilles Vollant ";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info_internal_s
+{
+    uLong offset_curfile;/* relative offset of local header 4 bytes */
+} unz_file_info_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+       char  *read_buffer;         /* internal buffer for compressed data */
+       z_stream stream;            /* zLib stream structure for inflate */
+
+       uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
+       uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+       uLong offset_local_extrafield;/* offset of the local extra field */
+       uInt  size_local_extrafield;/* size of the local extra field */
+       uLong pos_local_extrafield;   /* position in the local extra field in read*/
+
+       uLong crc32;                /* crc32 of all data uncompressed */
+       uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+       uLong rest_read_compressed; /* number of byte to be decompressed */
+       uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+       FILE* file;                 /* io structore of the zipfile */
+       uLong compression_method;   /* compression method (0==store) */
+       uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+} file_in_zip_read_info_s;
+
+
+/* unz_s contain internal information about the zipfile
+*/
+typedef struct
+{
+       FILE* file;                 /* io structore of the zipfile */
+       unz_global_info gi;       /* public global information */
+       uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+       uLong num_file;             /* number of the current file in the zipfile*/
+       uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
+       uLong current_file_ok;      /* flag about the usability of the current file*/
+       uLong central_pos;          /* position of the beginning of the central dir*/
+
+       uLong size_central_dir;     /* size of the central directory  */
+       uLong offset_central_dir;   /* offset of start of central directory with
+                                                                  respect to the starting disk number */
+
+       unz_file_info cur_file_info; /* public info about the current file in zip*/
+       unz_file_info_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
+                                           file if we are decompressing it */
+} unz_s;
+
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unzlocal_getByte(fin,pi)
+       FILE *fin;
+       int *pi;
+{
+    unsigned char c;
+       int err = fread(&c, 1, 1, fin);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ferror(fin)) 
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets 
+*/
+local int unzlocal_getShort (fin,pX)
+       FILE* fin;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(fin,&i);
+    x = (uLong)i;
+    
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<8;
+   
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unzlocal_getLong (fin,pX)
+       FILE* fin;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(fin,&i);
+    x = (uLong)i;
+    
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<24;
+   
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (fileName1,fileName2)
+       const char* fileName1;
+       const char* fileName2;
+{
+       for (;;)
+       {
+               char c1=*(fileName1++);
+               char c2=*(fileName2++);
+               if ((c1>='a') && (c1<='z'))
+                       c1 -= 0x20;
+               if ((c2>='a') && (c2<='z'))
+                       c2 -= 0x20;
+               if (c1=='\0')
+                       return ((c2=='\0') ? 0 : -1);
+               if (c2=='\0')
+                       return 1;
+               if (c1<c2)
+                       return -1;
+               if (c1>c2)
+                       return 1;
+       }
+}
+
+
+#ifdef  CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/* 
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+        (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
+       const char* fileName1;
+       const char* fileName2;
+       int iCaseSensitivity;
+{
+       if (iCaseSensitivity==0)
+               iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+       if (iCaseSensitivity==1)
+               return strcmp(fileName1,fileName2);
+
+       return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+} 
+
+#define BUFREADCOMMENT (0x400)
+
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local uLong unzlocal_SearchCentralDir(fin)
+       FILE *fin;
+{
+       unsigned char* buf;
+       uLong uSizeFile;
+       uLong uBackRead;
+       uLong uMaxBack=0xffff; /* maximum size of global comment */
+       uLong uPosFound=0;
+       
+       if (fseek(fin,0,SEEK_END) != 0)
+               return 0;
+
+
+       uSizeFile = ftell( fin );
+       
+       if (uMaxBack>uSizeFile)
+               uMaxBack = uSizeFile;
+
+       buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+       if (buf==NULL)
+               return 0;
+
+       uBackRead = 4;
+       while (uBackRead<uMaxBack)
+       {
+               uLong uReadSize,uReadPos ;
+               int i;
+               if (uBackRead+BUFREADCOMMENT>uMaxBack) 
+                       uBackRead = uMaxBack;
+               else
+                       uBackRead+=BUFREADCOMMENT;
+               uReadPos = uSizeFile-uBackRead ;
+               
+               uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 
+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
+               if (fseek(fin,uReadPos,SEEK_SET)!=0)
+                       break;
+
+               if (fread(buf,(uInt)uReadSize,1,fin)!=1)
+                       break;
+
+                for (i=(int)uReadSize-3; (i--)>0;)
+                       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 
+                               ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+                       {
+                               uPosFound = uReadPos+i;
+                               break;
+                       }
+
+               if (uPosFound!=0)
+                       break;
+       }
+       TRYFREE(buf);
+       return uPosFound;
+}
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
+        "zlib/zlib109.zip".
+        If the zipfile cannot be opened (file don't exist or in not valid), the
+          return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+          of this unzip package.
+*/
+extern unzFile ZEXPORT unzOpen (path)
+       const char *path;
+{
+       unz_s us;
+       unz_s *s;
+       uLong central_pos,uL;
+       FILE * fin ;
+
+       uLong number_disk;          /* number of the current dist, used for 
+                                                                  spaning ZIP, unsupported, always 0*/
+       uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                                                  for spaning ZIP, unsupported, always 0*/
+       uLong number_entry_CD;      /* total number of entries in
+                                      the central dir 
+                                      (same than number_entry on nospan) */
+
+       int err=UNZ_OK;
+
+    if (unz_copyright[0]!=' ')
+        return NULL;
+
+    fin=fopen(path,"rb");
+       if (fin==NULL)
+               return NULL;
+
+       central_pos = unzlocal_SearchCentralDir(fin);
+       if (central_pos==0)
+               err=UNZ_ERRNO;
+
+       if (fseek(fin,central_pos,SEEK_SET)!=0)
+               err=UNZ_ERRNO;
+
+       /* the signature, already checked */
+       if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* number of this disk */
+       if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* number of the disk with the start of the central directory */
+       if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* total number of entries in the central dir on this disk */
+       if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* total number of entries in the central dir */
+       if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if ((number_entry_CD!=us.gi.number_entry) ||
+               (number_disk_with_CD!=0) ||
+               (number_disk!=0))
+               err=UNZ_BADZIPFILE;
+
+       /* size of the central directory */
+       if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* offset of start of central directory with respect to the 
+             starting disk number */
+       if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* zipfile comment length */
+       if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if ((central_pos<us.offset_central_dir+us.size_central_dir) && 
+               (err==UNZ_OK))
+               err=UNZ_BADZIPFILE;
+
+       if (err!=UNZ_OK)
+       {
+               fclose(fin);
+               return NULL;
+       }
+
+       us.file=fin;
+       us.byte_before_the_zipfile = central_pos -
+                                   (us.offset_central_dir+us.size_central_dir);
+       us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+       
+
+       s=(unz_s*)ALLOC(sizeof(unz_s));
+       *s=us;
+       unzGoToFirstFile((unzFile)s);   
+       return (unzFile)s;      
+}
+
+
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (file)
+       unzFile file;
+{
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+       fclose(s->file);
+       TRYFREE(s);
+       return UNZ_OK;
+}
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
+       unzFile file;
+       unz_global_info *pglobal_info;
+{
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       *pglobal_info=s->gi;
+       return UNZ_OK;
+}
+
+
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
+    uLong ulDosDate;
+    tm_unz* ptm;
+{
+    uLong uDate;
+    uDate = (uLong)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+  Get Info about the current file in the zipfile, with internal only info
+*/
+local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
+                                                  unz_file_info *pfile_info,
+                                                  unz_file_info_internal 
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                                                                 uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                                                                 uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                                                                 uLong commentBufferSize));
+
+local int unzlocal_GetCurrentFileInfoInternal (file,
+                                              pfile_info,
+                                              pfile_info_internal,
+                                              szFileName, fileNameBufferSize,
+                                              extraField, extraFieldBufferSize,
+                                              szComment,  commentBufferSize)
+       unzFile file;
+       unz_file_info *pfile_info;
+       unz_file_info_internal *pfile_info_internal;
+       char *szFileName;
+       uLong fileNameBufferSize;
+       void *extraField;
+       uLong extraFieldBufferSize;
+       char *szComment;
+       uLong commentBufferSize;
+{
+       unz_s* s;
+       unz_file_info file_info;
+       unz_file_info_internal file_info_internal;
+       int err=UNZ_OK;
+       uLong uMagic;
+       long lSeek=0;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
+               err=UNZ_ERRNO;
+
+
+       /* we check the magic */
+       if (err==UNZ_OK)
+               if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
+                       err=UNZ_ERRNO;
+               else if (uMagic!=0x02014b50)
+                       err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+       if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       lSeek+=file_info.size_filename;
+       if ((err==UNZ_OK) && (szFileName!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_filename<fileNameBufferSize)
+               {
+                       *(szFileName+file_info.size_filename)='\0';
+                       uSizeRead = file_info.size_filename;
+               }
+               else
+                       uSizeRead = fileNameBufferSize;
+
+               if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+                       if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek -= uSizeRead;
+       }
+
+       
+       if ((err==UNZ_OK) && (extraField!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_file_extra<extraFieldBufferSize)
+                       uSizeRead = file_info.size_file_extra;
+               else
+                       uSizeRead = extraFieldBufferSize;
+
+               if (lSeek!=0)
+                       if (fseek(s->file,lSeek,SEEK_CUR)==0)
+                               lSeek=0;
+                       else
+                               err=UNZ_ERRNO;
+               if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+                       if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek += file_info.size_file_extra - uSizeRead;
+       }
+       else
+               lSeek+=file_info.size_file_extra; 
+
+       
+       if ((err==UNZ_OK) && (szComment!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_file_comment<commentBufferSize)
+               {
+                       *(szComment+file_info.size_file_comment)='\0';
+                       uSizeRead = file_info.size_file_comment;
+               }
+               else
+                       uSizeRead = commentBufferSize;
+
+               if (lSeek!=0)
+                       if (fseek(s->file,lSeek,SEEK_CUR)==0)
+                               lSeek=0;
+                       else
+                               err=UNZ_ERRNO;
+               if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+                       if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek+=file_info.size_file_comment - uSizeRead;
+       }
+       else
+               lSeek+=file_info.size_file_comment;
+
+       if ((err==UNZ_OK) && (pfile_info!=NULL))
+               *pfile_info=file_info;
+
+       if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+               *pfile_info_internal=file_info_internal;
+
+       return err;
+}
+
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo (file,
+                                                  pfile_info,
+                                                  szFileName, fileNameBufferSize,
+                                                  extraField, extraFieldBufferSize,
+                                                  szComment,  commentBufferSize)
+       unzFile file;
+       unz_file_info *pfile_info;
+       char *szFileName;
+       uLong fileNameBufferSize;
+       void *extraField;
+       uLong extraFieldBufferSize;
+       char *szComment;
+       uLong commentBufferSize;
+{
+       return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+                                                                                               szFileName,fileNameBufferSize,
+                                                                                               extraField,extraFieldBufferSize,
+                                                                                               szComment,commentBufferSize);
+}
+
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       s->pos_in_central_dir=s->offset_central_dir;
+       s->num_file=0;
+       err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                                                                        &s->cur_file_info_internal,
+                                                                                        NULL,0,NULL,0,NULL,0);
+       s->current_file_ok = (err == UNZ_OK);
+       return err;
+}
+
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (file)
+       unzFile file;
+{
+       unz_s* s;       
+       int err;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_END_OF_LIST_OF_FILE;
+       if (s->num_file+1==s->gi.number_entry)
+               return UNZ_END_OF_LIST_OF_FILE;
+
+       s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+                       s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+       s->num_file++;
+       err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                                                                          &s->cur_file_info_internal,
+                                                                                          NULL,0,NULL,0,NULL,0);
+       s->current_file_ok = (err == UNZ_OK);
+       return err;
+}
+
+
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzipStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
+       unzFile file;
+       const char *szFileName;
+       int iCaseSensitivity;
+{
+       unz_s* s;       
+       int err;
+
+       
+       uLong num_fileSaved;
+       uLong pos_in_central_dirSaved;
+
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+
+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+        return UNZ_PARAMERROR;
+
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_END_OF_LIST_OF_FILE;
+
+       num_fileSaved = s->num_file;
+       pos_in_central_dirSaved = s->pos_in_central_dir;
+
+       err = unzGoToFirstFile(file);
+
+       while (err == UNZ_OK)
+       {
+               char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+               unzGetCurrentFileInfo(file,NULL,
+                                                               szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                                               NULL,0,NULL,0);
+               if (unzStringFileNameCompare(szCurrentFileName,
+                                                                               szFileName,iCaseSensitivity)==0)
+                       return UNZ_OK;
+               err = unzGoToNextFile(file);
+       }
+
+       s->num_file = num_fileSaved ;
+       s->pos_in_central_dir = pos_in_central_dirSaved ;
+       return err;
+}
+
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
+                                                                                                       poffset_local_extrafield,
+                                                                                                       psize_local_extrafield)
+       unz_s* s;
+       uInt* piSizeVar;
+       uLong *poffset_local_extrafield;
+       uInt  *psize_local_extrafield;
+{
+       uLong uMagic,uData,uFlags;
+       uLong size_filename;
+       uLong size_extra_field;
+       int err=UNZ_OK;
+
+       *piSizeVar = 0;
+       *poffset_local_extrafield = 0;
+       *psize_local_extrafield = 0;
+
+       if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
+                                                               s->byte_before_the_zipfile,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+
+       if (err==UNZ_OK)
+               if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
+                       err=UNZ_ERRNO;
+               else if (uMagic!=0x04034b50)
+                       err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
+               err=UNZ_ERRNO;
+/*
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+               err=UNZ_BADZIPFILE;
+*/
+       if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+               err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
+                                     ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
+                                                         ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 
+                                                         ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+
+       if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+               err=UNZ_BADZIPFILE;
+
+       *piSizeVar += (uInt)size_filename;
+
+       if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
+               err=UNZ_ERRNO;
+       *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                                                       SIZEZIPLOCALHEADER + size_filename;
+       *psize_local_extrafield = (uInt)size_extra_field;
+
+       *piSizeVar += (uInt)size_extra_field;
+
+       return err;
+}
+                                                                                               
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+       int Store;
+       uInt iSizeVar;
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       uLong offset_local_extrafield;  /* offset of the local extra field */
+       uInt  size_local_extrafield;    /* size of the local extra field */
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+       if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
+                               &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+               return UNZ_BADZIPFILE;
+
+       pfile_in_zip_read_info = (file_in_zip_read_info_s*)
+                                                                           ALLOC(sizeof(file_in_zip_read_info_s));
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_INTERNALERROR;
+
+       pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+       pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+       pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+       pfile_in_zip_read_info->pos_local_extrafield=0;
+
+       if (pfile_in_zip_read_info->read_buffer==NULL)
+       {
+               TRYFREE(pfile_in_zip_read_info);
+               return UNZ_INTERNALERROR;
+       }
+
+       pfile_in_zip_read_info->stream_initialised=0;
+       
+       if ((s->cur_file_info.compression_method!=0) &&
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+               err=UNZ_BADZIPFILE;
+       Store = s->cur_file_info.compression_method==0;
+
+       pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+       pfile_in_zip_read_info->crc32=0;
+       pfile_in_zip_read_info->compression_method =
+            s->cur_file_info.compression_method;
+       pfile_in_zip_read_info->file=s->file;
+       pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+       if (!Store)
+       {
+         pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+         pfile_in_zip_read_info->stream.zfree = (free_func)0;
+         pfile_in_zip_read_info->stream.opaque = (voidpf)0; 
+      
+         err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+         if (err == Z_OK)
+           pfile_in_zip_read_info->stream_initialised=1;
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. 
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
+         * size of both compressed and uncompressed data
+         */
+       }
+       pfile_in_zip_read_info->rest_read_compressed = 
+            s->cur_file_info.compressed_size ;
+       pfile_in_zip_read_info->rest_read_uncompressed = 
+            s->cur_file_info.uncompressed_size ;
+
+       
+       pfile_in_zip_read_info->pos_in_zipfile = 
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 
+                         iSizeVar;
+       
+       pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+
+       s->pfile_in_zip_read = pfile_in_zip_read_info;
+    return UNZ_OK;
+}
+
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
+       unzFile file;
+       voidp buf;
+       unsigned len;
+{
+       int err=UNZ_OK;
+       uInt iRead = 0;
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+
+       if ((pfile_in_zip_read_info->read_buffer == NULL))
+               return UNZ_END_OF_LIST_OF_FILE;
+       if (len==0)
+               return 0;
+
+       pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+       pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+       
+       if (len>pfile_in_zip_read_info->rest_read_uncompressed)
+               pfile_in_zip_read_info->stream.avail_out = 
+                 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+       while (pfile_in_zip_read_info->stream.avail_out>0)
+       {
+               if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+               {
+                       uInt uReadThis = UNZ_BUFSIZE;
+                       if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                               uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+                       if (uReadThis == 0)
+                               return UNZ_EOF;
+                       if (fseek(pfile_in_zip_read_info->file,
+                      pfile_in_zip_read_info->pos_in_zipfile + 
+                         pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
+                               return UNZ_ERRNO;
+                       if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
+                         pfile_in_zip_read_info->file)!=1)
+                               return UNZ_ERRNO;
+                       pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+                       pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+                       
+                       pfile_in_zip_read_info->stream.next_in = 
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+                       pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+               }
+
+               if (pfile_in_zip_read_info->compression_method==0)
+               {
+                       uInt uDoCopy,i ;
+                       if (pfile_in_zip_read_info->stream.avail_out < 
+                            pfile_in_zip_read_info->stream.avail_in)
+                               uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+                       else
+                               uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+                               
+                       for (i=0;i<uDoCopy;i++)
+                               *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+                                       
+                       pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                                               pfile_in_zip_read_info->stream.next_out,
+                                                               uDoCopy);
+                       pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+                       pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+                       pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+                       pfile_in_zip_read_info->stream.next_out += uDoCopy;
+                       pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+                       iRead += uDoCopy;
+               }
+               else
+               {
+                       uLong uTotalOutBefore,uTotalOutAfter;
+                       const Bytef *bufBefore;
+                       uLong uOutThis;
+                       int flush=Z_SYNC_FLUSH;
+
+                       uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+                       bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+                       /*
+                       if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                                pfile_in_zip_read_info->stream.avail_out) &&
+                               (pfile_in_zip_read_info->rest_read_compressed == 0))
+                               flush = Z_FINISH;
+                       */
+                       err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+                       uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+                       uOutThis = uTotalOutAfter-uTotalOutBefore;
+                       
+                       pfile_in_zip_read_info->crc32 = 
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+                       pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+                       iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+            
+                       if (err==Z_STREAM_END)
+                               return (iRead==0) ? UNZ_EOF : iRead;
+                       if (err!=Z_OK) 
+                               break;
+               }
+       }
+
+       if (err==Z_OK)
+               return iRead;
+       return err;
+}
+
+
+/*
+  Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (file)
+       unzFile file;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+       return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+
+/*
+  return 1 if the end of file was reached, 0 elsewhere 
+*/
+extern int ZEXPORT unzeof (file)
+       unzFile file;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+       
+       if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+               return 1;
+       else
+               return 0;
+}
+
+
+
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field that can be read
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+       buf.
+  the return value is the number of bytes copied in buf, or (if <0) 
+       the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
+       unzFile file;
+       voidp buf;
+       unsigned len;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       uInt read_now;
+       uLong size_to_read;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+       size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 
+                               pfile_in_zip_read_info->pos_local_extrafield);
+
+       if (buf==NULL)
+               return (int)size_to_read;
+       
+       if (len>size_to_read)
+               read_now = (uInt)size_to_read;
+       else
+               read_now = (uInt)len ;
+
+       if (read_now==0)
+               return 0;
+       
+       if (fseek(pfile_in_zip_read_info->file,
+              pfile_in_zip_read_info->offset_local_extrafield + 
+                         pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+       if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
+               return UNZ_ERRNO;
+
+       return (int)read_now;
+}
+
+/*
+  Close the file in zip opened with unzipOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+
+       if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+       {
+               if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+                       err=UNZ_CRCERROR;
+       }
+
+
+       TRYFREE(pfile_in_zip_read_info->read_buffer);
+       pfile_in_zip_read_info->read_buffer = NULL;
+       if (pfile_in_zip_read_info->stream_initialised)
+               inflateEnd(&pfile_in_zip_read_info->stream);
+
+       pfile_in_zip_read_info->stream_initialised = 0;
+       TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+       return err;
+}
+
+
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
+       unzFile file;
+       char *szComment;
+       uLong uSizeBuf;
+{
+       int err=UNZ_OK;
+       unz_s* s;
+       uLong uReadThis ;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+
+       uReadThis = uSizeBuf;
+       if (uReadThis>s->gi.size_comment)
+               uReadThis = s->gi.size_comment;
+
+       if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+       if (uReadThis>0)
+    {
+      *szComment='\0';
+         if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
+               return UNZ_ERRNO;
+    }
+
+       if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+               *(szComment+s->gi.size_comment)='\0';
+       return (int)uReadThis;
+}
+
+#endif
diff --git a/src/vm/unzip.h b/src/vm/unzip.h
new file mode 100644 (file)
index 0000000..76692cb
--- /dev/null
@@ -0,0 +1,275 @@
+/* unzip.h -- IO for uncompress .zip files using zlib 
+   Version 0.15 beta, Mar 19th, 1998,
+
+   Copyright (C) 1998 Gilles Vollant
+
+   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+   Encryption and multi volume ZipFile (span) are not supported.
+   Old compressions used by old PKZip 1.x are not supported
+
+   THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
+   CAN CHANGE IN FUTURE VERSION !!
+   I WAIT FEEDBACK at mail info@winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+/* for more info about .ZIP format, see 
+      ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip */
+
+#ifndef _unz_H
+#define _unz_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__; 
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                                  (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO               (Z_ERRNO)
+#define UNZ_EOF                 (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s 
+{
+       uInt tm_sec;            /* seconds after the minute - [0,59] */
+       uInt tm_min;            /* minutes after the hour - [0,59] */
+       uInt tm_hour;           /* hours since midnight - [0,23] */
+       uInt tm_mday;           /* day of the month - [1,31] */
+       uInt tm_mon;            /* months since January - [0,11] */
+       uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info_s
+{
+       uLong number_entry;         /* total number of entries in
+                                      the central dir on this disk */
+       uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */ 
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */ 
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                                                                const char* fileName2,
+                                                                                                int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                               or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+       (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
+        "zlib/zlib111.zip".
+        If the zipfile cannot be opened (file don't exist or in not valid), the
+          return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+          of this unzip package.
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                       unz_global_info *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                                                                  char *szComment,
+                                          uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file, 
+                                    const char *szFileName,
+                                    int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                                            unz_file_info *pfile_info,
+                                            char *szFileName,
+                                            uLong fileNameBufferSize,
+                                            void *extraField,
+                                            uLong extraFieldBufferSize,
+                                            char *szComment,
+                                            uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+           the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+                       (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+                       (extraFieldBufferSize is the size of the buffer).
+                       This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+                       (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+                                                                                               
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file, 
+                                         voidp buf,
+                                         unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere 
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                                                                        voidp buf,
+                                                                                        unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+       buf.
+  the return value is the number of bytes copied in buf, or (if <0) 
+       the error code
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz_H */
index b2cb65304bb5f0a768144976487799435968c216..b25f3f74122ebf01ac341099290f8b8f39737eab 100644 (file)
--- a/tables.c
+++ b/tables.c
@@ -35,7 +35,7 @@
        - the heap
        - additional support functions
 
-   $Id: tables.c 584 2003-11-09 19:15:25Z twisti $
+   $Id: tables.c 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -348,6 +348,7 @@ utf *utf_new (char *text, u2 length)
        utf *u;            /* hashtable element */
        u2 i;
        
+/*     log_text("utf_new entered");*/
 #ifdef STATISTICS
        count_utf_new++;
 #endif
@@ -367,7 +368,15 @@ utf *utf_new (char *text, u2 length)
 #ifdef STATISTICS
                        count_utf_new_found++;
 #endif
-                       /* symbol found in hashtable */                                 
+/*                     log_text("symbol found in hash table");*/
+                       /* symbol found in hashtable */
+/*                                     utf_display(u);
+                                       {
+                                               utf blup;
+                                               blup.blength=length;
+                                               blup.text=text;
+                                               utf_display(&blup);
+                                       }*/
                        return u;
                }
        nomatch:
@@ -382,8 +391,9 @@ utf *utf_new (char *text, u2 length)
        u = NEW (utf);
        u->blength  = length;             /* length in bytes of utfstring */
        u->hashlink = utf_hash.ptr[slot]; /* link in external hashchain   */            
-       u->text     = mem_alloc(length);  /* allocate memory for utf-text */
+       u->text     = mem_alloc(length/*JOWENN*/+1);  /* allocate memory for utf-text */
        memcpy(u->text,text,length);      /* copy utf-text                */
+        u->text[length]='\0';/*JOWENN*/
        utf_hash.ptr[slot] = u;           /* insert symbol into table     */ 
 
        utf_hash.entries++;               /* update number of entries     */
@@ -424,7 +434,7 @@ utf *utf_new (char *text, u2 length)
                MFREE (utf_hash.ptr, void*, utf_hash.size);
                utf_hash = newhash;
        }
-       
+               /*utf_display(u);*/
        return u;
 }
 
@@ -441,6 +451,33 @@ utf *utf_new_char (char *text)
        return utf_new(text, strlen(text));
 }
 
+
+/********************* function: utf_new_char ********************************
+
+    creates a new utf symbol, the text for this symbol is passed
+    as a c-string ( = char* )
+    "." characters are going to be replaced by "/". since the above function is
+    used often, this is a separte function, instead of an if
+
+******************************************************************************/
+
+utf *utf_new_char_classname (char *text)
+{
+       if (strchr(text,'.')) {
+               char *txt=strdup(text);
+               char *end=txt+strlen(txt);
+               char *c;
+               utf *tmpRes;
+               for (c=txt;c<end;c++)
+                       if (*c=='.') *c='/';
+               tmpRes=utf_new(txt,strlen(txt));
+               free(txt);
+               return tmpRes;
+       }
+       else
+       return utf_new(text, strlen(text));
+}
+
 /************************** Funktion: utf_show ******************************
 
     writes the utf symbols in the utfhash to stdout and
@@ -683,30 +720,33 @@ classinfo *class_new(utf *u)
        count_class_infos += sizeof(classinfo);
 #endif
 
-       c = NEW(classinfo);
-       c->flags = 0;
-       c->name = u;
-       c->cpcount = 0;
-       c->cptags = NULL;
-       c->cpinfos = NULL;
-       c->super = NULL;
-       c->sub = NULL;
-       c->nextsub = NULL;
-       c->interfacescount = 0;
-       c->interfaces = NULL;
-       c->fieldscount = 0;
-       c->fields = NULL;
-       c->methodscount = 0;
-       c->methods = NULL;
-       c->linked = false;
-       c->index = 0;
-       c->instancesize = 0;
-       c->header.vftbl = NULL;
-       c->innerclasscount = 0;
-       c->innerclass = NULL;
-       c->vftbl = NULL;
-       c->initialized = false;
-       c->classvftbl = false;
+       c = NEW (classinfo);
+       c -> vmClass = 0;
+       c -> flags = 0;
+       c -> name = u;
+       c -> cpcount = 0;
+       c -> cptags = NULL;
+       c -> cpinfos = NULL;
+       c -> super = NULL;
+       c -> sub = NULL;
+       c -> nextsub = NULL;
+       c -> interfacescount = 0;
+       c -> interfaces = NULL;
+       c -> fieldscount = 0;
+       c -> fields = NULL;
+       c -> methodscount = 0;
+       c -> methods = NULL;
+       c -> linked = false;
+       c -> index = 0;
+       c -> instancesize = 0;
+       c -> header.vftbl = NULL;
+       c -> innerclasscount = 0;
+       c -> innerclass = NULL;
+       c -> vftbl = NULL;
+       c -> initialized = false;
+       c -> classvftbl = false;
+    c -> classUsed = 0;
+    c -> impldBy = NULL;
        
        /* prepare loading of the class */
        list_addlast(&unloadedclasses, c);
@@ -750,6 +790,10 @@ classinfo *class_new(utf *u)
                class_hash = newhash;
        }
                        
+    /* Array classes need further initialization. */
+    if (u->text[0] == '[')
+        class_new_array(c);
+        
        return c;
 }
 
@@ -791,6 +835,40 @@ classinfo *class_get(utf *u)
        return NULL;
 }
 
+/***************** Function: class_array_of ***********************************
+
+    Returns an array class with the given component class.
+    The array class is dynamically created if neccessary.
+
+*******************************************************************************/
+
+classinfo *class_array_of(classinfo *component)
+{
+    int namelen;
+    char *namebuf;
+
+    /* Assemble the array class name */
+    namelen = component->name->blength;
+    
+    if (component->name->text[0] == '[') {
+        /* the component is itself an array */
+        namebuf = DMNEW(char,namelen+1);
+        namebuf[0] = '[';
+        memcpy(namebuf+1,component->name->text,namelen);
+        namelen++;
+    }
+    else {
+        /* the component is a non-array class */
+        namebuf = DMNEW(char,namelen+3);
+        namebuf[0] = '[';
+        namebuf[1] = 'L';
+        memcpy(namebuf+2,component->name->text,namelen);
+        namebuf[2+namelen] = ';';
+        namelen+=3;
+    }
+
+    return class_new( utf_new(namebuf,namelen) );
+}
 
 /************************** function: utf_strlen ******************************
 
index a386c42acf5f8275a76cc6e5c6e44a25c8e2c454..99f365495d2c15c51b21fc02ccf3e7d24bddd18a 100644 (file)
--- a/tables.h
+++ b/tables.h
@@ -26,7 +26,7 @@
 
    Authors: Reinhard Grafl
 
-   $Id: tables.h 557 2003-11-02 22:51:59Z twisti $
+   $Id: tables.h 664 2003-11-21 18:24:01Z jowenn $
 
 */
 
@@ -63,6 +63,7 @@ void utf_display(utf *u);
 /* create new utf-symbol */
 utf *utf_new(char *text, u2 length);
 utf *utf_new_char(char *text);
+utf *utf_new_char_classname(char *text);
 
 /* show utf-table */
 void utf_show();
@@ -76,6 +77,9 @@ u4 utf_strlen(utf *u);
 /* search for class and create it if not found */
 classinfo *class_new(utf *u);
 
+/* return an array class with the given component class */
+classinfo *class_array_of(classinfo *component);
+
 /* get javatype according to a typedescriptor */
 u2 desc_to_type(utf *descriptor);
 
diff --git a/unzip.c b/unzip.c
new file mode 100644 (file)
index 0000000..4934694
--- /dev/null
+++ b/unzip.c
@@ -0,0 +1,1299 @@
+#include "config.h"
+#ifdef USE_ZLIB
+
+/* unzip.c -- IO on .zip files using zlib 
+   Version 0.15 beta, Mar 19th, 1998,
+
+   Read unzip.h for more info
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+
+#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) && \
+                      !defined(CASESENSITIVITYDEFAULT_NO)
+#define CASESENSITIVITYDEFAULT_NO
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+const char unz_copyright[] =
+   " unzip 0.15 Copyright 1998 Gilles Vollant ";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info_internal_s
+{
+    uLong offset_curfile;/* relative offset of local header 4 bytes */
+} unz_file_info_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+       char  *read_buffer;         /* internal buffer for compressed data */
+       z_stream stream;            /* zLib stream structure for inflate */
+
+       uLong pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
+       uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+       uLong offset_local_extrafield;/* offset of the local extra field */
+       uInt  size_local_extrafield;/* size of the local extra field */
+       uLong pos_local_extrafield;   /* position in the local extra field in read*/
+
+       uLong crc32;                /* crc32 of all data uncompressed */
+       uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+       uLong rest_read_compressed; /* number of byte to be decompressed */
+       uLong rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+       FILE* file;                 /* io structore of the zipfile */
+       uLong compression_method;   /* compression method (0==store) */
+       uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+} file_in_zip_read_info_s;
+
+
+/* unz_s contain internal information about the zipfile
+*/
+typedef struct
+{
+       FILE* file;                 /* io structore of the zipfile */
+       unz_global_info gi;       /* public global information */
+       uLong byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+       uLong num_file;             /* number of the current file in the zipfile*/
+       uLong pos_in_central_dir;   /* pos of the current file in the central dir*/
+       uLong current_file_ok;      /* flag about the usability of the current file*/
+       uLong central_pos;          /* position of the beginning of the central dir*/
+
+       uLong size_central_dir;     /* size of the central directory  */
+       uLong offset_central_dir;   /* offset of start of central directory with
+                                                                  respect to the starting disk number */
+
+       unz_file_info cur_file_info; /* public info about the current file in zip*/
+       unz_file_info_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip_read_info_s* pfile_in_zip_read; /* structure about the current
+                                           file if we are decompressing it */
+} unz_s;
+
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unzlocal_getByte(fin,pi)
+       FILE *fin;
+       int *pi;
+{
+    unsigned char c;
+       int err = fread(&c, 1, 1, fin);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ferror(fin)) 
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets 
+*/
+local int unzlocal_getShort (fin,pX)
+       FILE* fin;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(fin,&i);
+    x = (uLong)i;
+    
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<8;
+   
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unzlocal_getLong (fin,pX)
+       FILE* fin;
+    uLong *pX;
+{
+    uLong x ;
+    int i;
+    int err;
+
+    err = unzlocal_getByte(fin,&i);
+    x = (uLong)i;
+    
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unzlocal_getByte(fin,&i);
+    x += ((uLong)i)<<24;
+   
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (fileName1,fileName2)
+       const char* fileName1;
+       const char* fileName2;
+{
+       for (;;)
+       {
+               char c1=*(fileName1++);
+               char c2=*(fileName2++);
+               if ((c1>='a') && (c1<='z'))
+                       c1 -= 0x20;
+               if ((c2>='a') && (c2<='z'))
+                       c2 -= 0x20;
+               if (c1=='\0')
+                       return ((c2=='\0') ? 0 : -1);
+               if (c2=='\0')
+                       return 1;
+               if (c1<c2)
+                       return -1;
+               if (c1>c2)
+                       return 1;
+       }
+}
+
+
+#ifdef  CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/* 
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+        (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (fileName1,fileName2,iCaseSensitivity)
+       const char* fileName1;
+       const char* fileName2;
+       int iCaseSensitivity;
+{
+       if (iCaseSensitivity==0)
+               iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+       if (iCaseSensitivity==1)
+               return strcmp(fileName1,fileName2);
+
+       return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+} 
+
+#define BUFREADCOMMENT (0x400)
+
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local uLong unzlocal_SearchCentralDir(fin)
+       FILE *fin;
+{
+       unsigned char* buf;
+       uLong uSizeFile;
+       uLong uBackRead;
+       uLong uMaxBack=0xffff; /* maximum size of global comment */
+       uLong uPosFound=0;
+       
+       if (fseek(fin,0,SEEK_END) != 0)
+               return 0;
+
+
+       uSizeFile = ftell( fin );
+       
+       if (uMaxBack>uSizeFile)
+               uMaxBack = uSizeFile;
+
+       buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+       if (buf==NULL)
+               return 0;
+
+       uBackRead = 4;
+       while (uBackRead<uMaxBack)
+       {
+               uLong uReadSize,uReadPos ;
+               int i;
+               if (uBackRead+BUFREADCOMMENT>uMaxBack) 
+                       uBackRead = uMaxBack;
+               else
+                       uBackRead+=BUFREADCOMMENT;
+               uReadPos = uSizeFile-uBackRead ;
+               
+               uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? 
+                     (BUFREADCOMMENT+4) : (uSizeFile-uReadPos);
+               if (fseek(fin,uReadPos,SEEK_SET)!=0)
+                       break;
+
+               if (fread(buf,(uInt)uReadSize,1,fin)!=1)
+                       break;
+
+                for (i=(int)uReadSize-3; (i--)>0;)
+                       if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && 
+                               ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+                       {
+                               uPosFound = uReadPos+i;
+                               break;
+                       }
+
+               if (uPosFound!=0)
+                       break;
+       }
+       TRYFREE(buf);
+       return uPosFound;
+}
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib109.zip" or on an Unix computer
+        "zlib/zlib109.zip".
+        If the zipfile cannot be opened (file don't exist or in not valid), the
+          return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+          of this unzip package.
+*/
+extern unzFile ZEXPORT unzOpen (path)
+       const char *path;
+{
+       unz_s us;
+       unz_s *s;
+       uLong central_pos,uL;
+       FILE * fin ;
+
+       uLong number_disk;          /* number of the current dist, used for 
+                                                                  spaning ZIP, unsupported, always 0*/
+       uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                                                  for spaning ZIP, unsupported, always 0*/
+       uLong number_entry_CD;      /* total number of entries in
+                                      the central dir 
+                                      (same than number_entry on nospan) */
+
+       int err=UNZ_OK;
+
+    if (unz_copyright[0]!=' ')
+        return NULL;
+
+    fin=fopen(path,"rb");
+       if (fin==NULL)
+               return NULL;
+
+       central_pos = unzlocal_SearchCentralDir(fin);
+       if (central_pos==0)
+               err=UNZ_ERRNO;
+
+       if (fseek(fin,central_pos,SEEK_SET)!=0)
+               err=UNZ_ERRNO;
+
+       /* the signature, already checked */
+       if (unzlocal_getLong(fin,&uL)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* number of this disk */
+       if (unzlocal_getShort(fin,&number_disk)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* number of the disk with the start of the central directory */
+       if (unzlocal_getShort(fin,&number_disk_with_CD)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* total number of entries in the central dir on this disk */
+       if (unzlocal_getShort(fin,&us.gi.number_entry)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* total number of entries in the central dir */
+       if (unzlocal_getShort(fin,&number_entry_CD)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if ((number_entry_CD!=us.gi.number_entry) ||
+               (number_disk_with_CD!=0) ||
+               (number_disk!=0))
+               err=UNZ_BADZIPFILE;
+
+       /* size of the central directory */
+       if (unzlocal_getLong(fin,&us.size_central_dir)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* offset of start of central directory with respect to the 
+             starting disk number */
+       if (unzlocal_getLong(fin,&us.offset_central_dir)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       /* zipfile comment length */
+       if (unzlocal_getShort(fin,&us.gi.size_comment)!=UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if ((central_pos<us.offset_central_dir+us.size_central_dir) && 
+               (err==UNZ_OK))
+               err=UNZ_BADZIPFILE;
+
+       if (err!=UNZ_OK)
+       {
+               fclose(fin);
+               return NULL;
+       }
+
+       us.file=fin;
+       us.byte_before_the_zipfile = central_pos -
+                                   (us.offset_central_dir+us.size_central_dir);
+       us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+       
+
+       s=(unz_s*)ALLOC(sizeof(unz_s));
+       *s=us;
+       unzGoToFirstFile((unzFile)s);   
+       return (unzFile)s;      
+}
+
+
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzipOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (file)
+       unzFile file;
+{
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+       fclose(s->file);
+       TRYFREE(s);
+       return UNZ_OK;
+}
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo (file,pglobal_info)
+       unzFile file;
+       unz_global_info *pglobal_info;
+{
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       *pglobal_info=s->gi;
+       return UNZ_OK;
+}
+
+
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unzlocal_DosDateToTmuDate (ulDosDate, ptm)
+    uLong ulDosDate;
+    tm_unz* ptm;
+{
+    uLong uDate;
+    uDate = (uLong)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+  Get Info about the current file in the zipfile, with internal only info
+*/
+local int unzlocal_GetCurrentFileInfoInternal OF((unzFile file,
+                                                  unz_file_info *pfile_info,
+                                                  unz_file_info_internal 
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                                                                 uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                                                                 uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                                                                 uLong commentBufferSize));
+
+local int unzlocal_GetCurrentFileInfoInternal (file,
+                                              pfile_info,
+                                              pfile_info_internal,
+                                              szFileName, fileNameBufferSize,
+                                              extraField, extraFieldBufferSize,
+                                              szComment,  commentBufferSize)
+       unzFile file;
+       unz_file_info *pfile_info;
+       unz_file_info_internal *pfile_info_internal;
+       char *szFileName;
+       uLong fileNameBufferSize;
+       void *extraField;
+       uLong extraFieldBufferSize;
+       char *szComment;
+       uLong commentBufferSize;
+{
+       unz_s* s;
+       unz_file_info file_info;
+       unz_file_info_internal file_info_internal;
+       int err=UNZ_OK;
+       uLong uMagic;
+       long lSeek=0;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (fseek(s->file,s->pos_in_central_dir+s->byte_before_the_zipfile,SEEK_SET)!=0)
+               err=UNZ_ERRNO;
+
+
+       /* we check the magic */
+       if (err==UNZ_OK)
+               if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
+                       err=UNZ_ERRNO;
+               else if (uMagic!=0x02014b50)
+                       err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getShort(s->file,&file_info.version) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.version_needed) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.flag) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.compression_method) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.dosDate) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+    unzlocal_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+       if (unzlocal_getLong(s->file,&file_info.crc) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.compressed_size) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.uncompressed_size) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_filename) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_file_extra) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.size_file_comment) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.disk_num_start) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&file_info.internal_fa) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info.external_fa) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&file_info_internal.offset_curfile) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       lSeek+=file_info.size_filename;
+       if ((err==UNZ_OK) && (szFileName!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_filename<fileNameBufferSize)
+               {
+                       *(szFileName+file_info.size_filename)='\0';
+                       uSizeRead = file_info.size_filename;
+               }
+               else
+                       uSizeRead = fileNameBufferSize;
+
+               if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+                       if (fread(szFileName,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek -= uSizeRead;
+       }
+
+       
+       if ((err==UNZ_OK) && (extraField!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_file_extra<extraFieldBufferSize)
+                       uSizeRead = file_info.size_file_extra;
+               else
+                       uSizeRead = extraFieldBufferSize;
+
+               if (lSeek!=0)
+                       if (fseek(s->file,lSeek,SEEK_CUR)==0)
+                               lSeek=0;
+                       else
+                               err=UNZ_ERRNO;
+               if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+                       if (fread(extraField,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek += file_info.size_file_extra - uSizeRead;
+       }
+       else
+               lSeek+=file_info.size_file_extra; 
+
+       
+       if ((err==UNZ_OK) && (szComment!=NULL))
+       {
+               uLong uSizeRead ;
+               if (file_info.size_file_comment<commentBufferSize)
+               {
+                       *(szComment+file_info.size_file_comment)='\0';
+                       uSizeRead = file_info.size_file_comment;
+               }
+               else
+                       uSizeRead = commentBufferSize;
+
+               if (lSeek!=0)
+                       if (fseek(s->file,lSeek,SEEK_CUR)==0)
+                               lSeek=0;
+                       else
+                               err=UNZ_ERRNO;
+               if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+                       if (fread(szComment,(uInt)uSizeRead,1,s->file)!=1)
+                               err=UNZ_ERRNO;
+               lSeek+=file_info.size_file_comment - uSizeRead;
+       }
+       else
+               lSeek+=file_info.size_file_comment;
+
+       if ((err==UNZ_OK) && (pfile_info!=NULL))
+               *pfile_info=file_info;
+
+       if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+               *pfile_info_internal=file_info_internal;
+
+       return err;
+}
+
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo (file,
+                                                  pfile_info,
+                                                  szFileName, fileNameBufferSize,
+                                                  extraField, extraFieldBufferSize,
+                                                  szComment,  commentBufferSize)
+       unzFile file;
+       unz_file_info *pfile_info;
+       char *szFileName;
+       uLong fileNameBufferSize;
+       void *extraField;
+       uLong extraFieldBufferSize;
+       char *szComment;
+       uLong commentBufferSize;
+{
+       return unzlocal_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+                                                                                               szFileName,fileNameBufferSize,
+                                                                                               extraField,extraFieldBufferSize,
+                                                                                               szComment,commentBufferSize);
+}
+
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+       unz_s* s;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       s->pos_in_central_dir=s->offset_central_dir;
+       s->num_file=0;
+       err=unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                                                                        &s->cur_file_info_internal,
+                                                                                        NULL,0,NULL,0,NULL,0);
+       s->current_file_ok = (err == UNZ_OK);
+       return err;
+}
+
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (file)
+       unzFile file;
+{
+       unz_s* s;       
+       int err;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_END_OF_LIST_OF_FILE;
+       if (s->num_file+1==s->gi.number_entry)
+               return UNZ_END_OF_LIST_OF_FILE;
+
+       s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+                       s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+       s->num_file++;
+       err = unzlocal_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                                                                          &s->cur_file_info_internal,
+                                                                                          NULL,0,NULL,0,NULL,0);
+       s->current_file_ok = (err == UNZ_OK);
+       return err;
+}
+
+
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzipStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (file, szFileName, iCaseSensitivity)
+       unzFile file;
+       const char *szFileName;
+       int iCaseSensitivity;
+{
+       unz_s* s;       
+       int err;
+
+       
+       uLong num_fileSaved;
+       uLong pos_in_central_dirSaved;
+
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+
+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+        return UNZ_PARAMERROR;
+
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_END_OF_LIST_OF_FILE;
+
+       num_fileSaved = s->num_file;
+       pos_in_central_dirSaved = s->pos_in_central_dir;
+
+       err = unzGoToFirstFile(file);
+
+       while (err == UNZ_OK)
+       {
+               char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+               unzGetCurrentFileInfo(file,NULL,
+                                                               szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                                               NULL,0,NULL,0);
+               if (unzStringFileNameCompare(szCurrentFileName,
+                                                                               szFileName,iCaseSensitivity)==0)
+                       return UNZ_OK;
+               err = unzGoToNextFile(file);
+       }
+
+       s->num_file = num_fileSaved ;
+       s->pos_in_central_dir = pos_in_central_dirSaved ;
+       return err;
+}
+
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+local int unzlocal_CheckCurrentFileCoherencyHeader (s,piSizeVar,
+                                                                                                       poffset_local_extrafield,
+                                                                                                       psize_local_extrafield)
+       unz_s* s;
+       uInt* piSizeVar;
+       uLong *poffset_local_extrafield;
+       uInt  *psize_local_extrafield;
+{
+       uLong uMagic,uData,uFlags;
+       uLong size_filename;
+       uLong size_extra_field;
+       int err=UNZ_OK;
+
+       *piSizeVar = 0;
+       *poffset_local_extrafield = 0;
+       *psize_local_extrafield = 0;
+
+       if (fseek(s->file,s->cur_file_info_internal.offset_curfile +
+                                                               s->byte_before_the_zipfile,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+
+       if (err==UNZ_OK)
+               if (unzlocal_getLong(s->file,&uMagic) != UNZ_OK)
+                       err=UNZ_ERRNO;
+               else if (uMagic!=0x04034b50)
+                       err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
+               err=UNZ_ERRNO;
+/*
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+               err=UNZ_BADZIPFILE;
+*/
+       if (unzlocal_getShort(s->file,&uFlags) != UNZ_OK)
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getShort(s->file,&uData) != UNZ_OK)
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+               err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* date/time */
+               err=UNZ_ERRNO;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* crc */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) &&
+                                     ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size compr */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) &&
+                                                         ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+       if (unzlocal_getLong(s->file,&uData) != UNZ_OK) /* size uncompr */
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && 
+                                                         ((uFlags & 8)==0))
+               err=UNZ_BADZIPFILE;
+
+
+       if (unzlocal_getShort(s->file,&size_filename) != UNZ_OK)
+               err=UNZ_ERRNO;
+       else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+               err=UNZ_BADZIPFILE;
+
+       *piSizeVar += (uInt)size_filename;
+
+       if (unzlocal_getShort(s->file,&size_extra_field) != UNZ_OK)
+               err=UNZ_ERRNO;
+       *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                                                       SIZEZIPLOCALHEADER + size_filename;
+       *psize_local_extrafield = (uInt)size_extra_field;
+
+       *piSizeVar += (uInt)size_extra_field;
+
+       return err;
+}
+                                                                                               
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+       int Store;
+       uInt iSizeVar;
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       uLong offset_local_extrafield;  /* offset of the local extra field */
+       uInt  size_local_extrafield;    /* size of the local extra field */
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+       if (!s->current_file_ok)
+               return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+       if (unzlocal_CheckCurrentFileCoherencyHeader(s,&iSizeVar,
+                               &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+               return UNZ_BADZIPFILE;
+
+       pfile_in_zip_read_info = (file_in_zip_read_info_s*)
+                                                                           ALLOC(sizeof(file_in_zip_read_info_s));
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_INTERNALERROR;
+
+       pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+       pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+       pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+       pfile_in_zip_read_info->pos_local_extrafield=0;
+
+       if (pfile_in_zip_read_info->read_buffer==NULL)
+       {
+               TRYFREE(pfile_in_zip_read_info);
+               return UNZ_INTERNALERROR;
+       }
+
+       pfile_in_zip_read_info->stream_initialised=0;
+       
+       if ((s->cur_file_info.compression_method!=0) &&
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+               err=UNZ_BADZIPFILE;
+       Store = s->cur_file_info.compression_method==0;
+
+       pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+       pfile_in_zip_read_info->crc32=0;
+       pfile_in_zip_read_info->compression_method =
+            s->cur_file_info.compression_method;
+       pfile_in_zip_read_info->file=s->file;
+       pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+       if (!Store)
+       {
+         pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+         pfile_in_zip_read_info->stream.zfree = (free_func)0;
+         pfile_in_zip_read_info->stream.opaque = (voidpf)0; 
+      
+         err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+         if (err == Z_OK)
+           pfile_in_zip_read_info->stream_initialised=1;
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END. 
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the 
+         * size of both compressed and uncompressed data
+         */
+       }
+       pfile_in_zip_read_info->rest_read_compressed = 
+            s->cur_file_info.compressed_size ;
+       pfile_in_zip_read_info->rest_read_uncompressed = 
+            s->cur_file_info.uncompressed_size ;
+
+       
+       pfile_in_zip_read_info->pos_in_zipfile = 
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + 
+                         iSizeVar;
+       
+       pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+
+       s->pfile_in_zip_read = pfile_in_zip_read_info;
+    return UNZ_OK;
+}
+
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile  (file, buf, len)
+       unzFile file;
+       voidp buf;
+       unsigned len;
+{
+       int err=UNZ_OK;
+       uInt iRead = 0;
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+
+       if ((pfile_in_zip_read_info->read_buffer == NULL))
+               return UNZ_END_OF_LIST_OF_FILE;
+       if (len==0)
+               return 0;
+
+       pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+       pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+       
+       if (len>pfile_in_zip_read_info->rest_read_uncompressed)
+               pfile_in_zip_read_info->stream.avail_out = 
+                 (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+       while (pfile_in_zip_read_info->stream.avail_out>0)
+       {
+               if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+               {
+                       uInt uReadThis = UNZ_BUFSIZE;
+                       if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                               uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+                       if (uReadThis == 0)
+                               return UNZ_EOF;
+                       if (fseek(pfile_in_zip_read_info->file,
+                      pfile_in_zip_read_info->pos_in_zipfile + 
+                         pfile_in_zip_read_info->byte_before_the_zipfile,SEEK_SET)!=0)
+                               return UNZ_ERRNO;
+                       if (fread(pfile_in_zip_read_info->read_buffer,uReadThis,1,
+                         pfile_in_zip_read_info->file)!=1)
+                               return UNZ_ERRNO;
+                       pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+                       pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+                       
+                       pfile_in_zip_read_info->stream.next_in = 
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+                       pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+               }
+
+               if (pfile_in_zip_read_info->compression_method==0)
+               {
+                       uInt uDoCopy,i ;
+                       if (pfile_in_zip_read_info->stream.avail_out < 
+                            pfile_in_zip_read_info->stream.avail_in)
+                               uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+                       else
+                               uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+                               
+                       for (i=0;i<uDoCopy;i++)
+                               *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+                                       
+                       pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                                               pfile_in_zip_read_info->stream.next_out,
+                                                               uDoCopy);
+                       pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+                       pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+                       pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+                       pfile_in_zip_read_info->stream.next_out += uDoCopy;
+                       pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+                       iRead += uDoCopy;
+               }
+               else
+               {
+                       uLong uTotalOutBefore,uTotalOutAfter;
+                       const Bytef *bufBefore;
+                       uLong uOutThis;
+                       int flush=Z_SYNC_FLUSH;
+
+                       uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+                       bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+                       /*
+                       if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                                pfile_in_zip_read_info->stream.avail_out) &&
+                               (pfile_in_zip_read_info->rest_read_compressed == 0))
+                               flush = Z_FINISH;
+                       */
+                       err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+                       uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+                       uOutThis = uTotalOutAfter-uTotalOutBefore;
+                       
+                       pfile_in_zip_read_info->crc32 = 
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+                       pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+                       iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+            
+                       if (err==Z_STREAM_END)
+                               return (iRead==0) ? UNZ_EOF : iRead;
+                       if (err!=Z_OK) 
+                               break;
+               }
+       }
+
+       if (err==Z_OK)
+               return iRead;
+       return err;
+}
+
+
+/*
+  Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (file)
+       unzFile file;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+       return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+
+/*
+  return 1 if the end of file was reached, 0 elsewhere 
+*/
+extern int ZEXPORT unzeof (file)
+       unzFile file;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+       
+       if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+               return 1;
+       else
+               return 0;
+}
+
+
+
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field that can be read
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+       buf.
+  the return value is the number of bytes copied in buf, or (if <0) 
+       the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (file,buf,len)
+       unzFile file;
+       voidp buf;
+       unsigned len;
+{
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       uInt read_now;
+       uLong size_to_read;
+
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+       size_to_read = (pfile_in_zip_read_info->size_local_extrafield - 
+                               pfile_in_zip_read_info->pos_local_extrafield);
+
+       if (buf==NULL)
+               return (int)size_to_read;
+       
+       if (len>size_to_read)
+               read_now = (uInt)size_to_read;
+       else
+               read_now = (uInt)len ;
+
+       if (read_now==0)
+               return 0;
+       
+       if (fseek(pfile_in_zip_read_info->file,
+              pfile_in_zip_read_info->offset_local_extrafield + 
+                         pfile_in_zip_read_info->pos_local_extrafield,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+       if (fread(buf,(uInt)size_to_read,1,pfile_in_zip_read_info->file)!=1)
+               return UNZ_ERRNO;
+
+       return (int)read_now;
+}
+
+/*
+  Close the file in zip opened with unzipOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (file)
+       unzFile file;
+{
+       int err=UNZ_OK;
+
+       unz_s* s;
+       file_in_zip_read_info_s* pfile_in_zip_read_info;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+       if (pfile_in_zip_read_info==NULL)
+               return UNZ_PARAMERROR;
+
+
+       if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+       {
+               if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+                       err=UNZ_CRCERROR;
+       }
+
+
+       TRYFREE(pfile_in_zip_read_info->read_buffer);
+       pfile_in_zip_read_info->read_buffer = NULL;
+       if (pfile_in_zip_read_info->stream_initialised)
+               inflateEnd(&pfile_in_zip_read_info->stream);
+
+       pfile_in_zip_read_info->stream_initialised = 0;
+       TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+       return err;
+}
+
+
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (file, szComment, uSizeBuf)
+       unzFile file;
+       char *szComment;
+       uLong uSizeBuf;
+{
+       int err=UNZ_OK;
+       unz_s* s;
+       uLong uReadThis ;
+       if (file==NULL)
+               return UNZ_PARAMERROR;
+       s=(unz_s*)file;
+
+       uReadThis = uSizeBuf;
+       if (uReadThis>s->gi.size_comment)
+               uReadThis = s->gi.size_comment;
+
+       if (fseek(s->file,s->central_pos+22,SEEK_SET)!=0)
+               return UNZ_ERRNO;
+
+       if (uReadThis>0)
+    {
+      *szComment='\0';
+         if (fread(szComment,(uInt)uReadThis,1,s->file)!=1)
+               return UNZ_ERRNO;
+    }
+
+       if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+               *(szComment+s->gi.size_comment)='\0';
+       return (int)uReadThis;
+}
+
+#endif
diff --git a/unzip.h b/unzip.h
new file mode 100644 (file)
index 0000000..76692cb
--- /dev/null
+++ b/unzip.h
@@ -0,0 +1,275 @@
+/* unzip.h -- IO for uncompress .zip files using zlib 
+   Version 0.15 beta, Mar 19th, 1998,
+
+   Copyright (C) 1998 Gilles Vollant
+
+   This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
+     WinZip, InfoZip tools and compatible.
+   Encryption and multi volume ZipFile (span) are not supported.
+   Old compressions used by old PKZip 1.x are not supported
+
+   THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
+   CAN CHANGE IN FUTURE VERSION !!
+   I WAIT FEEDBACK at mail info@winimage.com
+   Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+
+*/
+/* for more info about .ZIP format, see 
+      ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
+   PkWare has also a specification at :
+      ftp://ftp.pkware.com/probdesc.zip */
+
+#ifndef _unz_H
+#define _unz_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__; 
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                                  (0)
+#define UNZ_END_OF_LIST_OF_FILE (-100)
+#define UNZ_ERRNO               (Z_ERRNO)
+#define UNZ_EOF                 (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s 
+{
+       uInt tm_sec;            /* seconds after the minute - [0,59] */
+       uInt tm_min;            /* minutes after the hour - [0,59] */
+       uInt tm_hour;           /* hours since midnight - [0,23] */
+       uInt tm_mday;           /* day of the month - [1,31] */
+       uInt tm_mon;            /* months since January - [0,11] */
+       uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info_s
+{
+       uLong number_entry;         /* total number of entries in
+                                      the central dir on this disk */
+       uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */ 
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */ 
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                                                                const char* fileName2,
+                                                                                                int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                               or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+       (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
+        "zlib/zlib111.zip".
+        If the zipfile cannot be opened (file don't exist or in not valid), the
+          return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+          of this unzip package.
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzipOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                       unz_global_info *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                                                                  char *szComment,
+                                          uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file, 
+                                    const char *szFileName,
+                                    int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                                            unz_file_info *pfile_info,
+                                            char *szFileName,
+                                            uLong fileNameBufferSize,
+                                            void *extraField,
+                                            uLong extraFieldBufferSize,
+                                            char *szComment,
+                                            uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+           the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+                       (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+                       (extraFieldBufferSize is the size of the buffer).
+                       This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+                       (commentBufferSize is the size of the buffer)
+*/
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+                                                                                               
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file, 
+                                         voidp buf,
+                                         unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere 
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                                                                        voidp buf,
+                                                                                        unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+       buf.
+  the return value is the number of bytes copied in buf, or (if <0) 
+       the error code
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz_H */