## 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 = \
native.h \
jni.h \
tables.c \
- tables.h
+ tables.h \
+ unzip.c
cacao_LDADD = \
jit/libjit.a \
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 \
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 $@
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.
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 $
*/
#define _ASMPART_H
#include "global.h"
+#include "jni.h"
/*
determines if the byte support instruction set (21164a and higher)
*/
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();
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 $
*/
#include "native-math.h"
+#undef DEBUG /*define DEBUG 1*/
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(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"},
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);
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 *****************************
*****************************************************************************/
+/* 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);
}
****************************************************************************/
+/* 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))
******************************************************************************/
+/* XXX delete */
+#if 0
static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
{
if (desc == target) return 1;
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 ***********************
*****************************************************************************/
+/* XXX delete */
+#if 0
s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
{
java_arrayheader *a = (java_arrayheader*) o;
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 *******************************
{
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;
******************************************************************************/
-
+/* XXX delete */
+#if 0
s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
{
if (!o) return 1;
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 **********************************
-/******************** 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),
a->elementtype = elementtype;
return a;
}
-
-
+#endif
/******************** function: builtin_newarray_array ***********************
*****************************************************************************/
-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),
a->elementdescriptor = elementdesc;
return a;
}
+#endif
/******************** function: builtin_newarray_boolean ************************
*****************************************************************************/
-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),
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 ************************
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
+/* XXX delete */
java_shortarray *builtin_newarray_short(s4 size)
{
java_shortarray *a;
*****************************************************************************/
+<<<<<<< builtin.c
+/* XXX delete */
java_intarray *builtin_newarray_int(s4 size)
{
java_intarray *a;
*****************************************************************************/
+<<<<<<< builtin.c
+/* XXX delete */
java_longarray *builtin_newarray_long(s4 size)
{
java_longarray *a;
}
-
+/* XXX delete */
/***************** function: builtin_multianewarray ***************************
Creates a multi-dimensional array on the heap. The dimensions are passed in
/* Helper functions */
+/* XXX delete */
static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
constant_arraydescriptor *desc)
{
return (java_arrayheader*) a;
}
-
+/* XXX delete */
java_arrayheader *builtin_multianewarray(java_intarray *dims,
constant_arraydescriptor *desc)
{
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
*****************************************************************************/
+/* XXX delete */
+#if 0
s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
{
if (builtin_canstore(a,o)) {
}
return 0;
}
-
+#endif
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);
#endif
methodinfo *method)
{
+
int i;
for (i = 0; i < methodindent; i++)
logtext[i] = '\t';
#endif
#endif
}
- sprintf(logtext + strlen(logtext), ")");
+ sprintf (logtext+strlen(logtext), ")");
+ dolog ();
- dolog();
methodindent++;
}
#endif
++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
}
+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
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,
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);
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
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.
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)
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 \
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 ../..
+
+
+
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 ******************************************************/
#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 */
#define CONSTANT_NameAndType 12
#define CONSTANT_Utf8 1
-#define CONSTANT_Arraydescriptor 13
#define CONSTANT_UNUSED 0
#define ACC_PUBLIC 0x0001
#define ACC_NATIVE 0x0100
#define ACC_INTERFACE 0x0200
#define ACC_ABSTRACT 0x0400
-
+#define ACC_STRICT 0x0800
/* resolve typedef cycles *****************************************************/
typedef u1* methodptr;
typedef struct fieldinfo fieldinfo;
typedef struct methodinfo methodinfo;
+typedef struct arraydescriptor arraydescriptor;
/* constant pool entries *******************************************************
CONSTANT_Double constant_double yes
CONSTANT_NameAndType constant_nameandtype yes
CONSTANT_Utf8 unicode no
- CONSTANT_Arraydescriptor constant_arraydescriptor yes
CONSTANT_UNUSED -
*******************************************************************************/
};
+/* 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 {
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 **************************************/
/* 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 */
#ifdef SIZE_FROM_CLASSINFO
s4 alignedsize; /* phil */
#endif
- s4 arraytype; /* array type from previous list */
} java_arrayheader;
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 ********************************************/
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;
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 */
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 ******************************************************
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 */
#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;
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 *******************************************/
/* 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.
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 $
*/
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)
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;}
printID (m->class->name);
fprintf (file, "* this ");
- };
+ }
+ else
+ {
+ fprintf (file, ", jclass clazz ");
+ }
if ((*utf_ptr)!=')') fprintf (file, ", ");
/****************** 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 ************/
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 ();
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);
}
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);
}
+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
Authors: ?
- $Id: jni.c 557 2003-11-02 22:51:59Z twisti $
+ $Id: jni.c 664 2003-11-21 18:24:01Z jowenn $
*/
#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]);
}
{
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);
jmethodID FromReflectedMethod (JNIEnv* env, jobject method)
{
- log_text("JNI-Call: FromReflectedMethod");
+ /* log_text("JNI-Call: FromReflectedMethod"); */
}
jobject ToReflectedField (JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
{
- log_text("JNI-Call: ToReflectedField");
+ /* log_text("JNI-Call: ToReflectedField"); */
}
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;
+
}
/***********************************************************************************
jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: NewObjectV");
+ /* log_text("JNI-Call: NewObjectV"); */
}
/***********************************************************************************
jobject NewObjectA (JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: NewObjectA");
+ /* log_text("JNI-Call: NewObjectA"); */
}
}
/******************** 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)
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);
}
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);
}
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);
}
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');
}
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;
}
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);
+
}
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);
}
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);
}
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;
}
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);
}
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);
}
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);
}
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');
}
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');
}
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);
+
}
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;
}
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");
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);
}
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);
}
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);
}
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;
}
{
log_text("JNI-Call: CallStaticIntMethodV");
- return 0;
+ return callIntegerMethod(0,methodID,'I',args);
}
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);
}
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');
+
}
{
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;
+
}
{
log_text("JNI-Call: CallStaticDoubleMethodV");
- return 0;
+ return callFloatMethod(0,methodID,args,'D');
}
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);
}
void CallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
{
log_text("JNI-Call: CallStaticVoidMethodV");
+ (void)callIntegerMethod(0,methodID,'V',args);
}
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 *******************/
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 ***************************************/
/* 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;
}
}
/************************************* 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)
{
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;
}
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,
&NewWeakGlobalRef,
&DeleteWeakGlobalRef,
&ExceptionCheck
-};
+ };
+
+
+JNIEnv env=&envTable;
/*
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;
Java VM Interface
*/
-typedef struct JNI_Table JNIEnv;
+typedef struct JNI_Table *JNIEnv;
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);
extern JNIEnv env;
-#endif /* _JNI_H */
+extern JavaVM javaVM;
+#endif
/*
* These are local overrides for various environment variables in Emacs.
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 ***********************************************************/
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 */
static classinfo *class_java_lang_ArrayStoreException;
static classinfo *class_java_lang_ThreadDeath;
+static methodinfo method_clone_array;
+
+static int loader_inited = 0;
/******************************************************************************
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 **************************************/
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 *********************************
FILE *classfile;
int filenamelen, err;
struct stat buffer;
-
+ int isZip;
+
if (classbuffer) /* classbuffer is already valid */
return true;
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();
/* 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();
}
{
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");
}
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':
/* 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 */
*******************************************************************************/
+/* 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");
}
return d;
}
+#endif
/******************* Function: freearraydescriptor *****************************
*******************************************************************************/
+/* XXX delete */
+#if 0
static void freearraydescriptor (constant_arraydescriptor *d)
{
while (d) {
d = n;
}
}
+#endif
/*********************** Function: displayarraydescriptor *********************/
+/* XXX delete */
+#if 0
static void displayarraydescriptor (constant_arraydescriptor *d)
{
switch (d->arraytype) {
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 ****************************/
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();
}
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;
}
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;
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;
}
+/* class_showconstantpool(c); */
dump_release (dumpsize);
}
count_class_loads++;
#endif
+ /* XXX remove */
+ /* loadverbose = 1; */
+
/* output for debugging purposes */
if (loadverbose) {
}
/* load classdata, throw exception on error */
+
if (!suck_start (c->name)) {
- throw_classnotfoundexception();
+ throw_classnotfoundexception2(c->name);
return false;
}
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;
/* 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);
}
+/******************* 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
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. */
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
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 */
c->linked = true;
- list_remove(&unlinkedclasses, c);
- list_addlast(&linkedclasses, c);
+ list_remove (&unlinkedclasses, c);
+ list_addlast (&linkedclasses, c);
+
}
case CONSTANT_NameAndType:
FREE (info, constant_nameandtype);
break;
- case CONSTANT_Arraydescriptor:
- freearraydescriptor (info);
- break;
}
}
}
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]);
}
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);
}
{
s4 i;
+
for (i = 0; i < c->fieldscount; i++) {
if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
return &(c->fields[i]);
}
+/************************* 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
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
*******************************************************************************/
+#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);
- }
- }
}
printf("Utf8 -> ");
utf_display(e);
break;
- case CONSTANT_Arraydescriptor: {
- printf("Arraydescriptor: ");
- displayarraydescriptor(e);
- }
- break;
default:
panic("Invalid type of ConstantPool-Entry");
}
printf ("Utf8 -> ");
utf_display (e);
break;
- case CONSTANT_Arraydescriptor: {
- printf ("Arraydescriptor: ");
- displayarraydescriptor (e);
- }
- break;
default:
panic ("Invalid type of ConstantPool-Entry");
}
/******************* 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
*******************************************************************************/
+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 */
intsRestore(); /* schani */
+ loader_load_running--;
+
return top;
}
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);
}
}
********************************************************************************/
-
+/* XXX delete */
+#if 0
classinfo *create_array_class(utf *u)
{
classinfo *c = class_new (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 **********************************
*******************************************************************************/
-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");
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;
}
subs = subs->nextsub;
}
c->vftbl->diffval = classvalue - c->vftbl->baseval;
+
/*
{
int i;
printf("\n");
}
*/
+
}
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 $
*/
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);
void method_display(methodinfo *m);
+utf* clinit_desc();
+utf* clinit_name();
+
#endif /* _LOADER_H */
- 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 $
*/
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 ***************************/
exit(1);
}
- gc_init();
+
+ gc_init();
#ifdef USE_THREADS
initThreads((u1*) &dummy); /* schani */
#endif
+
/************************* Start worker routines ********************/
if (startit) {
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\" ");
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>
#include <utime.h>
#include <sys/utsname.h>
+#include "config.h"
#include "global.h"
#include "native.h"
#include "nativetypes.hh"
#endif
#include <sys/stat.h>
+#include "../threads/threadio.h"
/* searchpath for classfiles */
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;
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 ************************/
/*************************** 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;
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 =
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"));
/* 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 =
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");
}
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");
}
/*****************************************************************************
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");
}
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,
}
+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
int buffer_len;
isstatic = isstatic ? true : false;
-
+
if (!nativecompdone) {
for (i = 0; i < NATIVETABLESIZE; i++) {
nativecomptable[i].classname =
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 =
MFREE(buffer, char, buffer_len);
+
+ exit(1);
+
+
return NULL;
}
java_chararray *a;
s4 i;
+/* log_text("javastring_new");*/
+
s = (java_lang_String*) builtin_new (class_java_lang_String);
a = builtin_newarray_char (utflength);
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;
java_chararray *a;
s4 i;
+ log_text("javastring_tochar");
+
if (!s)
return "";
a = s->value;
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"));
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;
}
}
}
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;
/* insert utf-string into symbol-table */
result = utf_new(buffer,buflength);
+
MFREE(buffer, char, buflength);
return result;
}
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 *****************************
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);
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;
}
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);
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;
}
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 */
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
}
/*****************************************************************************/
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);
/* 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);
- 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 $
*/
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 ***************************/
exit(1);
}
- gc_init();
+
+ gc_init();
#ifdef USE_THREADS
initThreads((u1*) &dummy); /* schani */
#endif
+
/************************* Start worker routines ********************/
if (startit) {
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\" ");
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 $
*/
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)
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;}
printID (m->class->name);
fprintf (file, "* this ");
- };
+ }
+ else
+ {
+ fprintf (file, ", jclass clazz ");
+ }
if ((*utf_ptr)!=')') fprintf (file, ", ");
/****************** 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 ************/
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 ();
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);
}
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);
}
+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
Authors: ?
- $Id: jni.c 557 2003-11-02 22:51:59Z twisti $
+ $Id: jni.c 664 2003-11-21 18:24:01Z jowenn $
*/
#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]);
}
{
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);
jmethodID FromReflectedMethod (JNIEnv* env, jobject method)
{
- log_text("JNI-Call: FromReflectedMethod");
+ /* log_text("JNI-Call: FromReflectedMethod"); */
}
jobject ToReflectedField (JNIEnv* env, jclass cls, jfieldID fieldID, jboolean isStatic)
{
- log_text("JNI-Call: ToReflectedField");
+ /* log_text("JNI-Call: ToReflectedField"); */
}
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;
+
}
/***********************************************************************************
jobject NewObjectV (JNIEnv* env, jclass clazz, jmethodID methodID, va_list args)
{
- log_text("JNI-Call: NewObjectV");
+ /* log_text("JNI-Call: NewObjectV"); */
}
/***********************************************************************************
jobject NewObjectA (JNIEnv* env, jclass clazz, jmethodID methodID, jvalue *args)
{
- log_text("JNI-Call: NewObjectA");
+ /* log_text("JNI-Call: NewObjectA"); */
}
}
/******************** 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)
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);
}
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);
}
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);
}
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');
}
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;
}
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);
+
}
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);
}
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);
}
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;
}
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);
}
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);
}
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);
}
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');
}
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');
}
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);
+
}
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;
}
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");
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);
}
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);
}
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);
}
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;
}
{
log_text("JNI-Call: CallStaticIntMethodV");
- return 0;
+ return callIntegerMethod(0,methodID,'I',args);
}
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);
}
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');
+
}
{
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;
+
}
{
log_text("JNI-Call: CallStaticDoubleMethodV");
- return 0;
+ return callFloatMethod(0,methodID,args,'D');
}
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);
}
void CallStaticVoidMethodV (JNIEnv *env, jclass cls, jmethodID methodID, va_list args)
{
log_text("JNI-Call: CallStaticVoidMethodV");
+ (void)callIntegerMethod(0,methodID,'V',args);
}
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 *******************/
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 ***************************************/
/* 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;
}
}
/************************************* 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)
{
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;
}
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,
&NewWeakGlobalRef,
&DeleteWeakGlobalRef,
&ExceptionCheck
-};
+ };
+
+
+JNIEnv env=&envTable;
/*
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;
Java VM Interface
*/
-typedef struct JNI_Table JNIEnv;
+typedef struct JNI_Table *JNIEnv;
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);
extern JNIEnv env;
-#endif /* _JNI_H */
+extern JavaVM javaVM;
+#endif
/*
* These are local overrides for various environment variables in Emacs.
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>
#include <utime.h>
#include <sys/utsname.h>
+#include "config.h"
#include "global.h"
#include "native.h"
#include "nativetypes.hh"
#endif
#include <sys/stat.h>
+#include "../threads/threadio.h"
/* searchpath for classfiles */
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;
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 ************************/
/*************************** 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;
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 =
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"));
/* 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 =
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");
}
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");
}
/*****************************************************************************
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");
}
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,
}
+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
int buffer_len;
isstatic = isstatic ? true : false;
-
+
if (!nativecompdone) {
for (i = 0; i < NATIVETABLESIZE; i++) {
nativecomptable[i].classname =
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 =
MFREE(buffer, char, buffer_len);
+
+ exit(1);
+
+
return NULL;
}
java_chararray *a;
s4 i;
+/* log_text("javastring_new");*/
+
s = (java_lang_String*) builtin_new (class_java_lang_String);
a = builtin_newarray_char (utflength);
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;
java_chararray *a;
s4 i;
+ log_text("javastring_tochar");
+
if (!s)
return "";
a = s->value;
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"));
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;
}
}
}
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;
/* insert utf-string into symbol-table */
result = utf_new(buffer,buflength);
+
MFREE(buffer, char, buflength);
return result;
}
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 *****************************
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);
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;
}
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);
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;
}
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 */
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
}
/*****************************************************************************/
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);
/* 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);
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 $
*/
#include "native-math.h"
+#undef DEBUG /*define DEBUG 1*/
builtin_descriptor builtin_desc[] = {
{(functionptr) builtin_instanceof, "instanceof"},
{(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"},
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);
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 *****************************
*****************************************************************************/
+/* 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);
}
****************************************************************************/
+/* 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))
******************************************************************************/
+/* XXX delete */
+#if 0
static s4 builtin_descriptorscompatible(constant_arraydescriptor *desc, constant_arraydescriptor *target)
{
if (desc == target) return 1;
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 ***********************
*****************************************************************************/
+/* XXX delete */
+#if 0
s4 builtin_checkarraycast(java_objectheader *o, constant_arraydescriptor *desc)
{
java_arrayheader *a = (java_arrayheader*) o;
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 *******************************
{
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;
******************************************************************************/
-
+/* XXX delete */
+#if 0
s4 builtin_canstore(java_objectarray *a, java_objectheader *o)
{
if (!o) return 1;
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 **********************************
-/******************** 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),
a->elementtype = elementtype;
return a;
}
-
-
+#endif
/******************** function: builtin_newarray_array ***********************
*****************************************************************************/
-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),
a->elementdescriptor = elementdesc;
return a;
}
+#endif
/******************** function: builtin_newarray_boolean ************************
*****************************************************************************/
-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),
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 ************************
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
-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),
*****************************************************************************/
+/* XXX delete */
java_shortarray *builtin_newarray_short(s4 size)
{
java_shortarray *a;
*****************************************************************************/
+<<<<<<< builtin.c
+/* XXX delete */
java_intarray *builtin_newarray_int(s4 size)
{
java_intarray *a;
*****************************************************************************/
+<<<<<<< builtin.c
+/* XXX delete */
java_longarray *builtin_newarray_long(s4 size)
{
java_longarray *a;
}
-
+/* XXX delete */
/***************** function: builtin_multianewarray ***************************
Creates a multi-dimensional array on the heap. The dimensions are passed in
/* Helper functions */
+/* XXX delete */
static java_arrayheader *multianewarray_part(java_intarray *dims, int thisdim,
constant_arraydescriptor *desc)
{
return (java_arrayheader*) a;
}
-
+/* XXX delete */
java_arrayheader *builtin_multianewarray(java_intarray *dims,
constant_arraydescriptor *desc)
{
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
*****************************************************************************/
+/* XXX delete */
+#if 0
s4 builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o)
{
if (builtin_canstore(a,o)) {
}
return 0;
}
-
+#endif
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);
#endif
methodinfo *method)
{
+
int i;
for (i = 0; i < methodindent; i++)
logtext[i] = '\t';
#endif
#endif
}
- sprintf(logtext + strlen(logtext), ")");
+ sprintf (logtext+strlen(logtext), ")");
+ dolog ();
- dolog();
methodindent++;
}
#endif
++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
}
+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
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,
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);
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
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.
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 ******************************************************/
#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 */
#define CONSTANT_NameAndType 12
#define CONSTANT_Utf8 1
-#define CONSTANT_Arraydescriptor 13
#define CONSTANT_UNUSED 0
#define ACC_PUBLIC 0x0001
#define ACC_NATIVE 0x0100
#define ACC_INTERFACE 0x0200
#define ACC_ABSTRACT 0x0400
-
+#define ACC_STRICT 0x0800
/* resolve typedef cycles *****************************************************/
typedef u1* methodptr;
typedef struct fieldinfo fieldinfo;
typedef struct methodinfo methodinfo;
+typedef struct arraydescriptor arraydescriptor;
/* constant pool entries *******************************************************
CONSTANT_Double constant_double yes
CONSTANT_NameAndType constant_nameandtype yes
CONSTANT_Utf8 unicode no
- CONSTANT_Arraydescriptor constant_arraydescriptor yes
CONSTANT_UNUSED -
*******************************************************************************/
};
+/* 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 {
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 **************************************/
/* 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 */
#ifdef SIZE_FROM_CLASSINFO
s4 alignedsize; /* phil */
#endif
- s4 arraytype; /* array type from previous list */
} java_arrayheader;
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 ********************************************/
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;
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 */
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 ******************************************************
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 */
#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;
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 *******************************************/
/* 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.
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 $
*/
#define _ASMPART_H
#include "global.h"
+#include "jni.h"
/*
determines if the byte support instruction set (21164a and higher)
*/
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();
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 ***********************************************************/
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 */
static classinfo *class_java_lang_ArrayStoreException;
static classinfo *class_java_lang_ThreadDeath;
+static methodinfo method_clone_array;
+
+static int loader_inited = 0;
/******************************************************************************
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 **************************************/
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 *********************************
FILE *classfile;
int filenamelen, err;
struct stat buffer;
-
+ int isZip;
+
if (classbuffer) /* classbuffer is already valid */
return true;
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();
/* 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();
}
{
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");
}
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':
/* 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 */
*******************************************************************************/
+/* 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");
}
return d;
}
+#endif
/******************* Function: freearraydescriptor *****************************
*******************************************************************************/
+/* XXX delete */
+#if 0
static void freearraydescriptor (constant_arraydescriptor *d)
{
while (d) {
d = n;
}
}
+#endif
/*********************** Function: displayarraydescriptor *********************/
+/* XXX delete */
+#if 0
static void displayarraydescriptor (constant_arraydescriptor *d)
{
switch (d->arraytype) {
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 ****************************/
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();
}
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;
}
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;
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;
}
+/* class_showconstantpool(c); */
dump_release (dumpsize);
}
count_class_loads++;
#endif
+ /* XXX remove */
+ /* loadverbose = 1; */
+
/* output for debugging purposes */
if (loadverbose) {
}
/* load classdata, throw exception on error */
+
if (!suck_start (c->name)) {
- throw_classnotfoundexception();
+ throw_classnotfoundexception2(c->name);
return false;
}
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;
/* 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);
}
+/******************* 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
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. */
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
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 */
c->linked = true;
- list_remove(&unlinkedclasses, c);
- list_addlast(&linkedclasses, c);
+ list_remove (&unlinkedclasses, c);
+ list_addlast (&linkedclasses, c);
+
}
case CONSTANT_NameAndType:
FREE (info, constant_nameandtype);
break;
- case CONSTANT_Arraydescriptor:
- freearraydescriptor (info);
- break;
}
}
}
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]);
}
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);
}
{
s4 i;
+
for (i = 0; i < c->fieldscount; i++) {
if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
return &(c->fields[i]);
}
+/************************* 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
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
*******************************************************************************/
+#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);
- }
- }
}
printf("Utf8 -> ");
utf_display(e);
break;
- case CONSTANT_Arraydescriptor: {
- printf("Arraydescriptor: ");
- displayarraydescriptor(e);
- }
- break;
default:
panic("Invalid type of ConstantPool-Entry");
}
printf ("Utf8 -> ");
utf_display (e);
break;
- case CONSTANT_Arraydescriptor: {
- printf ("Arraydescriptor: ");
- displayarraydescriptor (e);
- }
- break;
default:
panic ("Invalid type of ConstantPool-Entry");
}
/******************* 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
*******************************************************************************/
+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 */
intsRestore(); /* schani */
+ loader_load_running--;
+
return top;
}
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);
}
}
********************************************************************************/
-
+/* XXX delete */
+#if 0
classinfo *create_array_class(utf *u)
{
classinfo *c = class_new (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 **********************************
*******************************************************************************/
-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");
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;
}
subs = subs->nextsub;
}
c->vftbl->diffval = classvalue - c->vftbl->baseval;
+
/*
{
int i;
printf("\n");
}
*/
+
}
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 $
*/
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);
void method_display(methodinfo *m);
+utf* clinit_desc();
+utf* clinit_name();
+
#endif /* _LOADER_H */
- 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 $
*/
utf *u; /* hashtable element */
u2 i;
+/* log_text("utf_new entered");*/
#ifdef STATISTICS
count_utf_new++;
#endif
#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:
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 */
MFREE (utf_hash.ptr, void*, utf_hash.size);
utf_hash = newhash;
}
-
+ /*utf_display(u);*/
return u;
}
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
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);
class_hash = newhash;
}
+ /* Array classes need further initialization. */
+ if (u->text[0] == '[')
+ class_new_array(c);
+
return c;
}
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 ******************************
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 $
*/
/* 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();
/* 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);
--- /dev/null
+#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
--- /dev/null
+/* 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 */
- 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 $
*/
utf *u; /* hashtable element */
u2 i;
+/* log_text("utf_new entered");*/
#ifdef STATISTICS
count_utf_new++;
#endif
#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:
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 */
MFREE (utf_hash.ptr, void*, utf_hash.size);
utf_hash = newhash;
}
-
+ /*utf_display(u);*/
return u;
}
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
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);
class_hash = newhash;
}
+ /* Array classes need further initialization. */
+ if (u->text[0] == '[')
+ class_new_array(c);
+
return c;
}
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 ******************************
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 $
*/
/* 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();
/* 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);
--- /dev/null
+#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
--- /dev/null
+/* 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 */