X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=native.c;h=2486a4c728b1fb7b98a7b622e85705d8cd248a42;hb=166a79e4b17e8290df0ef6faf8f0ef04a37b2cb4;hp=a06724a7d16dffed725af7cb4f8468fcbd4096d5;hpb=b3099e38cdfaf85d0c1ee434f05800103769ec4d;p=cacao.git diff --git a/native.c b/native.c index a06724a7d..2486a4c72 100644 --- a/native.c +++ b/native.c @@ -31,10 +31,11 @@ The .hh files created with the header file generator are all included here as are the C functions implementing these methods. - $Id: native.c 664 2003-11-21 18:24:01Z jowenn $ + $Id: native.c 951 2004-03-11 17:30:03Z jowenn $ */ + #include #include #include @@ -43,17 +44,19 @@ #include #include #include -#include #include "config.h" #include "global.h" +#include "jni.h" #include "native.h" #include "nativetypes.hh" #include "builtin.h" #include "asmpart.h" #include "tables.h" #include "loader.h" +#include "jni.h" #include "toolbox/loging.h" +#include "toolbox/memory.h" #include "threads/thread.h" #include "threads/threadio.h" #include "threads/locks.h" @@ -68,112 +71,141 @@ #endif #include -#include "../threads/threadio.h" +#include "threads/threadio.h" /* searchpath for classfiles */ -static char *classpath; +char *classpath; /* for java-string to char conversion */ #define MAXSTRINGSIZE 1000 /******************** systemclasses required for native methods ***************/ -static classinfo *class_java_lang_Class; -static classinfo *class_java_lang_VMClass; -static methodinfo *method_vmclass_init; +classinfo *class_java_lang_Class; +classinfo *class_java_lang_VMClass; +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; -static classinfo *class_java_lang_ClassNotFoundException; -static classinfo *class_java_lang_InstantiationException; -static classinfo *class_java_lang_NoSuchMethodError; -static classinfo *class_java_lang_NoSuchFieldError; -static classinfo *class_java_lang_ClassFormatError; -static classinfo *class_java_lang_IllegalArgumentException; -static classinfo *class_java_lang_ArrayIndexOutOfBoundsException; -static classinfo *class_java_lang_NoSuchFieldException; -static classinfo *class_java_io_SyncFailedException; -static classinfo *class_java_io_IOException; -static classinfo *class_java_io_FileNotFoundException; -static classinfo *class_java_io_UnixFileSystem; -static classinfo *class_java_security_PrivilegedActionException; -static classinfo *class_java_net_UnknownHostException; -static classinfo *class_java_net_SocketException; -static classinfo *class_java_lang_NoSuchMethodException; -static classinfo *class_java_lang_Double; -static classinfo *class_java_lang_Float; -static classinfo *class_java_lang_Long; -static classinfo *class_java_lang_Byte; -static classinfo *class_java_lang_Short; -static classinfo *class_java_lang_Boolean; -static classinfo *class_java_lang_Void; -static classinfo *class_java_lang_Character; -static classinfo *class_java_lang_Integer; +classinfo *class_java_lang_CloneNotSupportedException; +classinfo *class_java_lang_System; +classinfo *class_java_lang_ClassLoader; +classinfo *class_gnu_java_lang_SystemClassLoader; +classinfo *class_java_lang_NoClassDefFoundError; +classinfo *class_java_lang_ClassNotFoundException; +classinfo *class_java_lang_LinkageError; +classinfo *class_java_lang_InstantiationException; +classinfo *class_java_lang_NoSuchMethodError; +classinfo *class_java_lang_NoSuchFieldError; +classinfo *class_java_lang_ClassFormatError; +classinfo *class_java_lang_IllegalArgumentException; +classinfo *class_java_lang_ArrayIndexOutOfBoundsException; +classinfo *class_java_lang_NoSuchFieldException; +classinfo *class_java_io_SyncFailedException; +classinfo *class_java_io_IOException; +classinfo *class_java_io_FileNotFoundException; +classinfo *class_java_io_UnixFileSystem; +classinfo *class_java_security_PrivilegedActionException; +classinfo *class_java_lang_SecurityManager; +classinfo *class_java_net_UnknownHostException; +classinfo *class_java_net_SocketException; +classinfo *class_java_lang_NoSuchMethodException; +classinfo *class_java_lang_Double; +classinfo *class_java_lang_Float; +classinfo *class_java_lang_Long; +classinfo *class_java_lang_Byte; +classinfo *class_java_lang_Short; +classinfo *class_java_lang_Boolean; +classinfo *class_java_lang_Void; +classinfo *class_java_lang_Character; +classinfo *class_java_lang_Integer; + + +/* specify some exception strings for code generation */ +char *string_java_lang_NoClassDefFoundError = + "java/lang/NoClassDefFoundError"; + +char *string_java_lang_LinkageError = + "java/lang/LinkageError"; + +char *string_java_lang_ArrayIndexOutOfBoundsException = + "java/lang/ArrayIndexOutOfBoundsException"; + +char *string_java_lang_NegativeArraySizeException = + "java/lang/NegativeArraySizeException"; + +char *string_java_lang_ClassCastException = + "java/lang/ClassCastException"; + +char *string_java_lang_ArithmeticException = + "java/lang/ArithmeticException"; + +char *string_java_lang_ArithmeticException_message = + "/ by zero"; + +char *string_java_lang_NullPointerException = + "java/lang/NullPointerException"; + +char *string_java_lang_ArrayStoreException = + "java/lang/ArrayStoreException"; + /* the system classloader object */ struct java_lang_ClassLoader *SystemClassLoader = NULL; /* for raising exceptions from native methods */ -java_objectheader* exceptionptr = NULL; +THREADSPECIFIC java_objectheader* _exceptionptr = NULL; /************* use classinfo structure as java.lang.Class object **************/ void use_class_as_object(classinfo *c) { - 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; - } + vftbl *vt; +/* vftbl *newtbl; */ + + if (!class_java_lang_Class) + class_java_lang_Class = class_new(utf_new_char ("java/lang/Class")); + + vt = class_java_lang_Class->vftbl; + + + 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;*/ + + c->header.vftbl = class_java_lang_Class->vftbl; - 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(""), - 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; - } -} + if (!class_java_lang_VMClass) { + loader_load_sysclass(&class_java_lang_VMClass, + utf_new_char("java/lang/VMClass")); + + method_vmclass_init = + class_findmethod(class_java_lang_VMClass, + utf_new_char(""), + 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); -/*********************** include Java Native Interface ************************/ + if (!vmo) panic("Error while creating instance of java/lang/VMClass"); + asm_calljavafunction(method_vmclass_init, vmo, c, NULL, NULL); + c->vmClass = (java_lang_VMClass *) vmo; + /*log_text("VMCLASS has been attached");*/ + } + } +} -#include "jni.c" /*************************** include native methods ***************************/ -#include "nat/Runtime.c" -#include "nat/Thread.c" -#include "nat/VMClass.c" -#include "nat/Method.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" @@ -182,6 +214,8 @@ void use_class_as_object(classinfo *c) #include "nat/GtkFileDialogPeer.c" #include "nat/GtkLabelPeer.c" #endif + + /************************** tables for methods ********************************/ #undef JOWENN_DEBUG @@ -229,6 +263,63 @@ static bool nativecompdone = false; +/* throw some loader exceptions */ + +void throw_noclassdeffounderror_message(utf* classname) +{ + if (!class_java_lang_NoClassDefFoundError) { + panic("java.lang.NoClassDefFoundError not found. Maybe wrong classpath?"); + } + + /* throws a NoClassDefFoundError with message */ + *exceptionptr = native_new_and_init_string(class_java_lang_NoClassDefFoundError, + javastring_new(classname)); +} + + +void throw_linkageerror_message(utf* classname) +{ + if (!class_java_lang_LinkageError) { + panic("java.lang.LinkageError not found. Maybe wrong classpath?"); + } + + /* throws a LinkageError with message */ + *exceptionptr = native_new_and_init_string(class_java_lang_LinkageError, + javastring_new(classname)); +} + + +java_objectheader *new_exception(char *classname) +{ + classinfo *c = class_new(utf_new_char(classname)); + + if (!c->linked) + panic("exception class not linked"); + + return native_new_and_init(c); +} + +java_objectheader *new_exception_message(char *classname, char *message) +{ + classinfo *c = class_new(utf_new_char(classname)); + + if (!c->linked) + panic("exception class not linked"); + + return native_new_and_init_string(c, javastring_new_char(message)); +} + + +java_objectheader *new_exception_int(char *classname, s4 i) +{ + classinfo *c = class_new(utf_new_char(classname)); + + if (!c->linked) + panic("exception class not linked"); + + return native_new_and_init_int(c, i); +} + /*********************** function: native_loadclasses ************************** @@ -240,29 +331,34 @@ void native_loadclasses() { static int classesLoaded=0; /*temporary hack JoWenn*/ if (classesLoaded) return; - classesLoaded=1; + 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*/ + (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 */ if (!class_java_lang_Cloneable) class_java_lang_Cloneable = - class_new ( utf_new_char ("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_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_new(utf_new_char("java/lang/Class")); class_java_io_IOException = class_new(utf_new_char("java/io/IOException")); class_java_io_FileNotFoundException = class_new(utf_new_char("java/io/FileNotFoundException")); + class_java_lang_NoClassDefFoundError = + class_new(utf_new_char("java/lang/NoClassDefFoundError")); class_java_lang_ClassNotFoundException = class_new(utf_new_char("java/lang/ClassNotFoundException")); + class_java_lang_LinkageError = + class_new(utf_new_char("java/lang/LinkageError")); class_java_lang_InstantiationException = class_new(utf_new_char("java/lang/InstantiationException")); class_java_lang_NoSuchMethodError = @@ -272,19 +368,22 @@ void native_loadclasses() class_java_lang_ClassFormatError = class_new(utf_new_char("java/lang/ClassFormatError")); class_java_io_SyncFailedException = - class_new ( utf_new_char ("java/io/SyncFailedException") ); + class_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")); + class_gnu_java_lang_SystemClassLoader = + class_new(utf_new_char("gnu/java/lang/SystemClassLoader")); + /* log_text("native_loadclasses: class_new(\"java/security/PrivilegedActionException\")"); */ class_java_security_PrivilegedActionException = class_new(utf_new_char("java/security/PrivilegedActionException")); - class_java_net_UnknownHostException = - loader_load(utf_new_char("java/net/UnknownHostException")); - class_java_net_SocketException = - loader_load(utf_new_char("java/net/SocketException")); + loader_load_sysclass(&class_java_net_UnknownHostException, + utf_new_char("java/net/UnknownHostException")); + loader_load_sysclass(&class_java_net_SocketException, + utf_new_char("java/net/SocketException")); class_java_lang_IllegalArgumentException = class_new(utf_new_char("java/lang/IllegalArgumentException")); @@ -296,37 +395,19 @@ void native_loadclasses() class_new(utf_new_char("java/lang/NoSuchMethodException")); /* load classes for wrapping primitive types */ - class_java_lang_Double = - class_new( utf_new_char ("java/lang/Double") ); + class_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/Character")); - class_java_lang_Integer = - class_new(utf_new_char("java/lang/Integer")); - class_java_lang_Long = - class_new(utf_new_char("java/lang/Long")); - class_java_lang_Byte = - class_new(utf_new_char("java/lang/Byte")); - class_java_lang_Short = - class_new(utf_new_char("java/lang/Short")); - class_java_lang_Boolean = - class_new(utf_new_char("java/lang/Boolean")); - class_java_lang_Void = - class_new(utf_new_char("java/lang/Void")); - - /* load to avoid dynamic classloading */ -/*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"));*/ - - /* start classloader */ -/*JoWenn loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); */ + class_java_lang_Float = class_new(utf_new_char("java/lang/Float")); + class_java_lang_Character = class_new(utf_new_char("java/lang/Character")); + class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer")); + class_java_lang_Long = class_new(utf_new_char("java/lang/Long")); + class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte")); + class_java_lang_Short = class_new(utf_new_char("java/lang/Short")); + class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean")); + class_java_lang_Void = class_new(utf_new_char("java/lang/Void")); - classesLoaded=1; - log_text("native_loadclasses finished"); + classesLoaded = 1; } @@ -337,26 +418,27 @@ void systemclassloader_addclass(classinfo *c) methodinfo *m; /* find method addClass of java.lang.ClassLoader */ - m = class_resolvemethod( - class_java_lang_ClassLoader, + m = class_resolvemethod(class_java_lang_ClassLoader, utf_new_char("addClass"), utf_new_char("(Ljava/lang/Class;)") ); - if (!m) panic("warning: cannot initialize classloader"); + if (!m) + panic("warning: cannot initialize classloader"); /* prepare class to be passed as argument */ use_class_as_object (c); /* call 'addClass' */ - asm_calljavamethod(m, - (java_objectheader*) SystemClassLoader, - (java_objectheader*) c, - NULL, - NULL - ); + asm_calljavafunction(m, + (java_objectheader*) SystemClassLoader, + (java_objectheader*) c, + NULL, + NULL + ); } + /*************** adds a library to the vector of loaded libraries *************/ void systemclassloader_addlibrary(java_objectheader *o) @@ -364,6 +446,7 @@ void systemclassloader_addlibrary(java_objectheader *o) log_text("systemclassloader_addlibrary"); } + /***************************************************************************** create systemclassloader object and initialize instance fields @@ -372,18 +455,17 @@ void systemclassloader_addlibrary(java_objectheader *o) void init_systemclassloader() { - 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 (!SystemClassLoader) { + native_loadclasses(); + log_text("Initializing new system class loader"); + /* create object and call initializer */ + SystemClassLoader = (java_lang_ClassLoader *) native_new_and_init(class_gnu_java_lang_SystemClassLoader);/*class_java_lang_ClassLoader);*/ + + /* systemclassloader has no parent */ + SystemClassLoader->parent = NULL; + SystemClassLoader->initialized = true; + } + log_text("leaving system class loader"); } @@ -394,63 +476,35 @@ void systemclassloader_addlibname(java_objectheader *o) methodinfo *m; jfieldID id; - m = class_resolvemethod(loader_load(utf_new_char ("java/util/Vector")), + m = class_resolvemethod(loader_load_sysclass(NULL, utf_new_char("java/util/Vector")), utf_new_char("addElement"), - utf_new_char("(Ljava/lang/Object;)V") - ); + utf_new_char("(Ljava/lang/Object;)V")); if (!m) panic("cannot initialize classloader"); - id = envTable.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, - GetStaticObjectField(&env,class_java_lang_ClassLoader,id), - o, - NULL, - NULL - ); + asm_calljavafunction(m, + envTable.GetStaticObjectField(&env, class_java_lang_ClassLoader, id), + o, + NULL, + NULL); } /********************* function: native_setclasspath **************************/ -void native_setclasspath (char *path) +void native_setclasspath(char *path) { /* set searchpath for classfiles */ classpath = path; } -/***************** function: throw_classnotfoundexception *********************/ - -void throw_classnotfoundexception() -{ - 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); -} - - -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 ************************* @@ -493,16 +547,16 @@ functionptr native_findfunction(utf *cname, utf *mname, #ifdef JOWENN_DEBUG buffer_len = - utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64; + 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); + utf_sprint(buffer+strlen(buffer), mname); strcpy(buffer+strlen(buffer), ": "); - utf_sprint(buffer+strlen(buffer), desc); + utf_sprint(buffer+strlen(buffer), desc); strcpy(buffer+strlen(buffer), " for class "); - utf_sprint(buffer+strlen(buffer), cname); + utf_sprint(buffer+strlen(buffer), cname); log_text(buffer); @@ -526,16 +580,15 @@ functionptr native_findfunction(utf *cname, utf *mname, buffer = MNEW(char, buffer_len); strcpy(buffer, "comparing with:"); - utf_sprint(buffer+strlen(buffer), n->methodname); + utf_sprint(buffer+strlen(buffer), n->methodname); strcpy (buffer+strlen(buffer), ": "); - utf_sprint(buffer+strlen(buffer), n->descriptor); + utf_sprint(buffer+strlen(buffer), n->descriptor); strcpy(buffer+strlen(buffer), " for class "); - utf_sprint(buffer+strlen(buffer), n->classname); + utf_sprint(buffer+strlen(buffer), n->classname); log_text(buffer); MFREE(buffer, char, buffer_len); - } } #endif @@ -560,10 +613,9 @@ functionptr native_findfunction(utf *cname, utf *mname, MFREE(buffer, char, buffer_len); - exit(1); - + /* keep compiler happy */ return NULL; } @@ -577,7 +629,8 @@ functionptr native_findfunction(utf *cname, utf *mname, *******************************************************************************/ -java_objectheader *javastring_new (utf *u) +/* java_objectheader *javastring_new(utf *u) */ +java_lang_String *javastring_new(utf *u) { char *utf_ptr = u->text; /* current utf character in utf string */ int utflength = utf_strlen(u); /* length of utf-string if uncompressed */ @@ -587,8 +640,8 @@ java_objectheader *javastring_new (utf *u) /* log_text("javastring_new");*/ - s = (java_lang_String*) builtin_new (class_java_lang_String); - a = builtin_newarray_char (utflength); + s = (java_lang_String*) builtin_new(class_java_lang_String); + a = builtin_newarray_char(utflength); /* javastring or character-array could not be created */ if ((!a) || (!s)) @@ -603,9 +656,11 @@ java_objectheader *javastring_new (utf *u) s->offset = 0; s->count = utflength; - return (java_objectheader*) s; +/* return (java_objectheader*) s; */ + return s; } + /********************** function: javastring_new_char ************************** creates a new java/lang/String object which contains the convertet @@ -615,7 +670,7 @@ java_objectheader *javastring_new (utf *u) *******************************************************************************/ -java_objectheader *javastring_new_char (char *text) +java_lang_String *javastring_new_char(char *text) { s4 i; s4 len = strlen(text); /* length of the string */ @@ -623,22 +678,24 @@ java_objectheader *javastring_new_char (char *text) java_chararray *a; /*log_text("javastring_new_char");*/ - s = (java_lang_String*) builtin_new (class_java_lang_String); - a = builtin_newarray_char (len); + 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; + if ((!a) || (!s)) + return NULL; /* copy text */ for (i = 0; i < len; i++) a->data[i] = text[i]; /* set fields of the javastring-object */ - s->value = a; + s->value = a; s->offset = 0; - s->count = len; + s->count = len; - return (java_objectheader*) s; +/* return (java_objectheader*) s; */ + return s; } @@ -654,24 +711,28 @@ java_objectheader *javastring_new_char (char *text) static char stringbuffer[MAXSTRINGSIZE]; -char *javastring_tochar (java_objectheader *so) +char *javastring_tochar(java_objectheader *so) { - java_lang_String *s = (java_lang_String*) so; + java_lang_String *s = (java_lang_String *) so; java_chararray *a; s4 i; - log_text("javastring_tochar"); - if (!s) return ""; + a = s->value; + if (!a) return ""; + if (s->count > MAXSTRINGSIZE) return ""; + for (i = 0; i < s->count; i++) - stringbuffer[i] = a->data[s->offset+i]; + stringbuffer[i] = a->data[s->offset + i]; + stringbuffer[i] = '\0'; + return stringbuffer; } @@ -683,20 +744,35 @@ char *javastring_tochar (java_objectheader *so) *******************************************************************************/ -fieldinfo *class_findfield_approx (classinfo *c, utf *name) +fieldinfo *class_findfield_approx(classinfo *c, utf *name) { s4 i; for (i = 0; i < c->fieldscount; i++) { /* compare field names */ if ((c->fields[i].name == name)) return &(c->fields[i]); - } + } /* field was not found, raise exception */ - exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException); + *exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException); + return NULL; } +s4 class_findfield_index_approx (classinfo *c, utf *name) +{ + s4 i; + for (i = 0; i < c->fieldscount; i++) { + /* compare field names */ + if ((c->fields[i].name == name)) + return i; + } + + /* field was not found, raise exception */ + *exceptionptr = native_new_and_init(class_java_lang_NoSuchFieldException); + return -1; +} + /********************** function: native_new_and_init ************************* @@ -708,8 +784,13 @@ fieldinfo *class_findfield_approx (classinfo *c, utf *name) java_objectheader *native_new_and_init(classinfo *c) { methodinfo *m; - java_objectheader *o = builtin_new(c); /* create object */ + java_objectheader *o; + + /* if c==NULL it is probebly because loader_load failed */ + if (!c) return *exceptionptr; + o = builtin_new(c); /* create object */ + /* printf("native_new_and_init "); utf_display(c->name); @@ -719,24 +800,100 @@ java_objectheader *native_new_and_init(classinfo *c) /* printf("o!=NULL\n"); */ /* find initializer */ - m = class_findmethod(c, utf_new_char(""), utf_new_char("()V")); + m = class_findmethod(c, + utf_new_char(""), + utf_new_char("()V")); + + if (!m) { /* initializer not found */ + if (verbose) { + char logtext[MAXLOGTEXT]; + sprintf(logtext, "Warning: class has no instance-initializer: "); + utf_sprint(logtext + strlen(logtext), c->name); + log_text(logtext); + } + return o; + } + + /* call initializer */ + + asm_calljavafunction(m, o, NULL, NULL, NULL); + + return o; +} + + +java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) +{ + methodinfo *m; + java_objectheader *o; + + /* if c==NULL it is probebly because loader_load failed */ + if (!c) return *exceptionptr; + + o = builtin_new(c); /* create object */ + + if (!o) return NULL; + + /* find initializer */ + + m = class_findmethod(c, + utf_new_char(""), + utf_new_char("(Ljava/lang/String;)V")); if (!m) { /* initializer not found */ if (verbose) { + char logtext[MAXLOGTEXT]; sprintf(logtext, "Warning: class has no instance-initializer: "); utf_sprint(logtext + strlen(logtext), c->name); - dolog(); + log_text(logtext); } return o; } /* call initializer */ - asm_calljavamethod(m, o, NULL, NULL, NULL); + asm_calljavafunction(m, o, s, NULL, NULL); return o; } + +java_objectheader *native_new_and_init_int(classinfo *c, s4 i) +{ + methodinfo *m; + java_objectheader *o; + + /* if c == NULL it is probebly because loader_load failed */ + if (!c) return *exceptionptr; + + o = builtin_new(c); /* create object */ + + if (!o) return NULL; + + /* find initializer */ + + m = class_findmethod(c, + utf_new_char(""), + utf_new_char("(I)V")); + + if (!m) { /* initializer not found */ + if (verbose) { + char logtext[MAXLOGTEXT]; + sprintf(logtext, "Warning: class has no instance-initializer: "); + utf_sprint(logtext + strlen(logtext), c->name); + log_text(logtext); + } + return o; + } + + /* call initializer */ + + asm_calljavafunction(m, o, i, NULL, NULL); + + return o; +} + + /******************** function: stringtable_update **************************** traverses the javastring hashtable and sets the vftbl-entries of @@ -759,10 +916,12 @@ void stringtable_update () js = (java_lang_String *) s->string; - if (!js || !(a = js->value)) + if (!js || !js->value) /* error in hashtable found */ panic("invalid literalstring in hashtable"); + a = js->value; + if (!js->header.vftbl) /* vftbl of javastring is NULL */ js->header.vftbl = class_java_lang_String -> vftbl; @@ -785,30 +944,29 @@ void stringtable_update () *****************************************************************************/ - u4 u2_utflength(u2 *text, u4 u2_length) { u4 result_len = 0; /* utf length in bytes */ u2 ch; /* current unicode character */ u4 len; - for (len = 0; len < u2_length; len++) { - - /* next unicode character */ - ch = *text++; + for (len = 0; len < u2_length; len++) { + /* next unicode character */ + ch = *text++; - /* determine bytes required to store unicode character as utf */ - if (ch && (ch < 0x80)) - result_len++; - else if (ch < 0x800) - result_len += 2; - else - result_len += 3; + /* determine bytes required to store unicode character as utf */ + if (ch && (ch < 0x80)) + result_len++; + else if (ch < 0x800) + result_len += 2; + else + result_len += 3; } return result_len; } + /********************* function: utf_new_u2 *********************************** make utf symbol from u2 array, @@ -819,68 +977,71 @@ u4 u2_utflength(u2 *text, u4 u2_length) utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname) { char *buffer; /* memory buffer for unicode characters */ - char *pos; /* pointer to current position in buffer */ - u4 left; /* unicode characters left */ - u4 buflength; /* utf length in bytes of the u2 array */ + char *pos; /* pointer to current position in buffer */ + u4 left; /* unicode characters left */ + u4 buflength; /* utf length in bytes of the u2 array */ utf *result; /* resulting utf-string */ - int i; + int i; /* 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); + buffer = MNEW(char, buflength); /* memory allocation failed */ if (!buffer) { printf("length: %d\n",buflength); log_text("utf_new_u2:buffer==NULL"); - return NULL; } - left = buflength; + left = buflength; pos = buffer; - for (i = 0; i++ < unicode_length; unicode_pos++) { + for (i = 0; i++ < unicode_length; unicode_pos++) { /* next unicode character */ u2 c = *unicode_pos; if ((c != 0) && (c < 0x80)) { - /* 1 character */ - left--; + /* 1 character */ + left--; if ((int) left < 0) break; - /* convert classname */ - if (isclassname && c=='.') - *pos++ = '/'; - else - *pos++ = (char) c; + /* convert classname */ + if (isclassname && c == '.') + *pos++ = '/'; + else + *pos++ = (char) c; + } else if (c < 0x800) { - /* 2 characters */ + /* 2 characters */ unsigned char high = c >> 6; unsigned char low = c & 0x3F; - left = left - 2; + left = left - 2; if ((int) left < 0) break; *pos++ = high | 0xC0; *pos++ = low | 0x80; + } else { /* 3 characters */ char low = c & 0x3f; char mid = (c >> 6) & 0x3F; char high = c >> 12; - left = left - 3; + left = left - 3; if ((int) left < 0) break; *pos++ = high | 0xE0; *pos++ = mid | 0x80; *pos++ = low | 0x80; } - } + } /* insert utf-string into symbol-table */ result = utf_new(buffer,buflength); - MFREE(buffer, char, buflength); + MFREE(buffer, char, buflength); + return result; } + /********************* function: javastring_toutf ***************************** make utf symbol from javastring @@ -889,12 +1050,15 @@ utf *utf_new_u2(u2 *unicode_pos, u4 unicode_length, bool isclassname) utf *javastring_toutf(java_lang_String *string, bool isclassname) { - java_lang_String *str = (java_lang_String *) string; -/* 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); + java_lang_String *str = (java_lang_String *) string; + +/* 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 ***************************** searches for the javastring with the specified u2-array in @@ -905,7 +1069,8 @@ utf *javastring_toutf(java_lang_String *string, bool isclassname) *******************************************************************************/ -java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode ) +java_objectheader *literalstring_u2(java_chararray *a, u4 length, u4 offset, + bool copymode) { literalstring *s; /* hashtable element */ java_lang_String *js; /* u2-array wrapped in javastring */ @@ -914,63 +1079,70 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode u4 slot; u2 i; -#if JOWENN_DEBUG1 - printf("literalstring_u2: length: %d\n",length); - log_text("literalstring_u2"); +//#define DEBUG_LITERALSTRING_U2 +#ifdef DEBUG_LITERALSTRING_U2 + printf("literalstring_u2: length=%d, offset=%d\n", length, offset); + fflush(stdout); #endif /* find location in hashtable */ - key = unicode_hashkey (a->data, length); - slot = key & (string_hash.size-1); + key = unicode_hashkey(a->data + offset, length); + slot = key & (string_hash.size - 1); s = string_hash.ptr[slot]; while (s) { - - js = (java_lang_String *) s->string; - - if (js->count == length) { - /* compare text */ - for (i=0; ivalue->data[i] != a->data[i]) goto nomatch; - - /* string already in hashtable, free memory */ - 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)); + js = (java_lang_String *) s->string; + + if (length == js->count) { + /* compare text */ + for (i = 0; i < length; i++) { + if (a->data[offset + i] != js->value->data[i]) + goto nomatch; + } + + /* string already in hashtable, free memory */ + if (!copymode) + lit_mem_free(a, sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10); + +#ifdef DEBUG_LITERALSTRING_U2 + printf("literalstring_u2: foundentry at %p\n", js); + utf_display(javastring_toutf(js, 0)); + printf("\n\n"); + fflush(stdout); #endif - return (java_objectheader *) js; - } + return (java_objectheader *) js; + } - nomatch: - /* follow link in external hash chain */ - s = s->hashlink; + nomatch: + /* follow link in external hash chain */ + s = s->hashlink; } if (copymode) { - /* create copy of u2-array for new javastring */ - u4 arraysize = sizeof(java_chararray) + sizeof(u2)*(length-1)+10; - stringdata = lit_mem_alloc ( arraysize ); - memcpy(stringdata, a, arraysize ); - } - else - stringdata = a; + /* create copy of u2-array for new javastring */ + u4 arraysize = sizeof(java_chararray) + sizeof(u2) * (length - 1) + 10; + stringdata = lit_mem_alloc(arraysize); +/* memcpy(stringdata, a, arraysize); */ + memcpy(&(stringdata->header), &(a->header), sizeof(java_arrayheader)); + memcpy(&(stringdata->data), &(a->data) + offset, sizeof(u2) * (length - 1) + 10); + + } else { + stringdata = a; + } /* location in hashtable found, complete arrayheader */ - stringdata -> header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; - stringdata -> header.size = length; + stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; + stringdata->header.size = length; /* create new javastring */ - js = LNEW (java_lang_String); - js -> header.vftbl = class_java_lang_String -> vftbl; - js -> value = stringdata; - js -> offset = 0; - js -> count = length; + js = LNEW(java_lang_String); + js->header.vftbl = class_java_lang_String->vftbl; + js->value = stringdata; + js->offset = 0; + js->count = length; /* create new literalstring */ - s = NEW (literalstring); + s = NEW(literalstring); s->hashlink = string_hash.ptr[slot]; s->string = (java_objectheader *) js; string_hash.ptr[slot] = s; @@ -979,47 +1151,50 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode string_hash.entries++; /* reorganization of hashtable */ - if ( string_hash.entries > (string_hash.size*2)) { - - /* reorganization of hashtable, average length of + if (string_hash.entries > (string_hash.size * 2)) { + /* reorganization of hashtable, average length of the external chains is approx. 2 */ - u4 i; - literalstring *s; - hashtable newhash; /* the new hashtable */ + u4 i; + literalstring *s; + hashtable newhash; /* the new hashtable */ - /* create new hashtable, double the size */ - init_hashtable(&newhash, string_hash.size*2); - newhash.entries=string_hash.entries; + /* create new hashtable, double the size */ + init_hashtable(&newhash, string_hash.size * 2); + newhash.entries = string_hash.entries; - /* transfer elements to new hashtable */ - for (i=0; i hashlink; - js = (java_lang_String*) s->string; - slot = (unicode_hashkey(js->value->data,js->count)) & (newhash.size-1); + /* transfer elements to new hashtable */ + for (i = 0; i < string_hash.size; i++) { + s = string_hash.ptr[i]; + while (s) { + literalstring *nexts = s->hashlink; + js = (java_lang_String *) s->string; + slot = unicode_hashkey(js->value->data, js->count) & (newhash.size - 1); - s->hashlink = newhash.ptr[slot]; - newhash.ptr[slot] = s; + s->hashlink = newhash.ptr[slot]; + newhash.ptr[slot] = s; - /* follow link in external hash chain */ - s = nexts; - } - } + /* follow link in external hash chain */ + s = nexts; + } + } - /* dispose old table */ - MFREE (string_hash.ptr, void*, string_hash.size); - string_hash = newhash; + /* dispose old table */ + 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));*/ + +#ifdef DEBUG_LITERALSTRING_U2 + printf("literalstring_u2: newly created at %p\n", js); + utf_display(javastring_toutf(js, 0)); + printf("\n\n"); + fflush(stdout); #endif return (java_objectheader *) js; } + /******************** Function: literalstring_new ***************************** creates a new javastring with the text of the utf-symbol @@ -1027,7 +1202,7 @@ java_objectheader *literalstring_u2 (java_chararray *a, u4 length, bool copymode *******************************************************************************/ -java_objectheader *literalstring_new (utf *u) +java_objectheader *literalstring_new(utf *u) { char *utf_ptr = u->text; /* pointer to current unicode character in utf string */ u4 utflength = utf_strlen(u); /* length of utf-string if uncompressed */ @@ -1038,11 +1213,13 @@ java_objectheader *literalstring_new (utf *u) /*if (utflength==0) while (1) sleep(60);*/ /* log_text("------------------"); */ /* allocate memory */ - a = lit_mem_alloc (sizeof(java_chararray) + sizeof(u2)*(utflength-1)+10 ); + a = lit_mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10); + /* convert utf-string to u2-array */ - for (i=0; idata[i] = utf_nextu2(&utf_ptr); + for (i = 0; i < utflength; i++) + a->data[i] = utf_nextu2(&utf_ptr); - return literalstring_u2(a, utflength, false); + return literalstring_u2(a, utflength, 0, false); } @@ -1052,22 +1229,21 @@ java_objectheader *literalstring_new (utf *u) ******************************************************************************/ -void literalstring_free (java_objectheader* sobj) +void literalstring_free(java_objectheader* sobj) { - java_lang_String *s = (java_lang_String*) sobj; + java_lang_String *s = (java_lang_String *) sobj; java_chararray *a = s->value; log_text("literalstring_free called"); /* dispose memory of java.lang.String object */ - LFREE (s, java_lang_String); + LFREE(s, java_lang_String); + /* dispose memory of java-characterarray */ - LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1)); /* +10 ?? */ + LFREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */ } - - void copy_vftbl(vftbl **dest, vftbl *src) { *dest = src; @@ -1082,6 +1258,215 @@ void copy_vftbl(vftbl **dest, vftbl *src) #endif } + +/****************************************************************************************** + + creates method signature (excluding return type) from array of + class-objects representing the parameters of the method + +*******************************************************************************************/ + + +utf *create_methodsig(java_objectarray* types, char *retType) +{ + char *buffer; /* buffer for building the desciptor */ + char *pos; /* current position in buffer */ + utf *result; /* the method signature */ + u4 buffer_size = 3; /* minimal size=3: room for parenthesis and returntype */ + u4 i, j; + + if (!types) return NULL; + + /* determine required buffer-size */ + for (i = 0; i < types->header.size; i++) { + classinfo *c = (classinfo *) types->data[i]; + buffer_size = buffer_size + c->name->blength + 2; + } + + if (retType) buffer_size += strlen(retType); + + /* allocate buffer */ + buffer = MNEW(u1, buffer_size); + pos = buffer; + + /* method-desciptor starts with parenthesis */ + *pos++ = '('; + + for (i = 0; i < types->header.size; i++) { + char ch; + + /* current argument */ + classinfo *c = (classinfo *) types->data[i]; + + /* current position in utf-text */ + char *utf_ptr = c->name->text; + + /* determine type of argument */ + if ((ch = utf_nextu2(&utf_ptr)) == '[') { + /* arrayclass */ + for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) { + *pos++ = *utf_ptr; /* copy text */ + } + + } else { + /* check for primitive types */ + for (j = 0; j < PRIMITIVETYPE_COUNT; j++) { + char *utf_pos = utf_ptr - 1; + char *primitive = primitivetype_table[j].wrapname; + + /* compare text */ + while (utf_pos < utf_end(c->name)) { + if (*utf_pos++ != *primitive++) goto nomatch; + } + + /* primitive type found */ + *pos++ = primitivetype_table[j].typesig; + goto next_type; + + nomatch: + } + + /* no primitive type and no arrayclass, so must be object */ + *pos++ = 'L'; + + /* copy text */ + for (utf_ptr--; utf_ptr < utf_end(c->name); utf_ptr++) { + *pos++ = *utf_ptr; + } + + *pos++ = ';'; + + next_type: + } + } + + *pos++ = ')'; + + if (retType) { + for (i = 0; i < strlen(retType); i++) { + *pos++ = retType[i]; + } + } + + /* create utf-string */ + result = utf_new(buffer, (pos - buffer)); + MFREE(buffer, u1, buffer_size); + + return result; +} + + +/****************************************************************************************** + + retrieve the next argument or returntype from a descriptor + and return the corresponding class + +*******************************************************************************************/ + +classinfo *get_type(char **utf_ptr,char *desc_end, bool skip) +{ + classinfo *c = class_from_descriptor(*utf_ptr,desc_end,utf_ptr, + (skip) ? CLASSLOAD_SKIP : CLASSLOAD_LOAD); + if (!c) + /* unknown type */ + panic("illegal descriptor"); + + if (skip) return NULL; + + use_class_as_object(c); + return c; +} + + +/****************************************************************************************** + + use the descriptor of a method to generate a java/lang/Class array + which contains the classes of the parametertypes of the method + +*******************************************************************************************/ + +java_objectarray* get_parametertypes(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++; + } + + /* create class-array */ + result = builtin_anewarray(parametercount, class_java_lang_Class); + + utf_ptr = descr->text; + utf_nextu2(&utf_ptr); + + /* get returntype classes */ + for (i = 0; i < parametercount; i++) + result->data[i] = (java_objectheader *) get_type(&utf_ptr,desc_end, false); + + return result; +} + + + + + +/****************************************************************************************** + + get the exceptions which can be thrown by a method + +*******************************************************************************************/ + +java_objectarray* get_exceptiontypes(methodinfo *m) { + u2 exccount=m->thrownexceptionscount; + u2 i; + java_objectarray *result; + /* create class-array */ + result = builtin_anewarray(exccount, class_java_lang_Class); + for (i=0;ithrownexceptions[i]); + use_class_as_object(oh); + result->data[i]=oh; + } + return result; +} + + + + + +/****************************************************************************************** + + get the returntype class of a method + +*******************************************************************************************/ + +classinfo *get_returntype(methodinfo *m) +{ + char *utf_ptr; /* current position in utf-text */ + char *desc_end; /* points behind utf string */ + utf *desc = m->descriptor; /* method-descriptor */ + + utf_ptr = desc->text; + desc_end = utf_end(desc); + + /* ignore parametertypes */ + while ((utf_ptr0) { + if (start==class_java_lang_SecurityManager) { + size--; + start--; + } + } + tmpArray=builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl); + + for(i=0,current=start;iname);*/ + use_class_as_object(c); + tmpArray->data[i]=c; + } + return tmpArray; + +} + +java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end,classinfo **start) { +#warning platform dependend + int i; + classinfo **current; + classinfo *c; + classinfo *privilegedAction; + size_t size=(((size_t)start)-((size_t)end)) / sizeof (classinfo*); +/* log_text("builtin_asm_getclassloader"); + printf("end %p, start %p, size %ld\n",end,start,size);*/ + + if (!class_java_lang_SecurityManager) + class_java_lang_SecurityManager = class_new(utf_new_char ("java/lang/SecurityManager")); + if (size>0) { + if (start==class_java_lang_SecurityManager) { + size--; + start--; + } + } + + privilegedAction=class_new(utf_new_char("java/security/PrivilegedAction")); + + for(i=0,current=start;iclassloader) return c->classloader; + } + return NULL; + + + + +/* + log_text("Java_java_lang_VMSecurityManager_currentClassLoader"); + init_systemclassloader(); + + return SystemClassLoader;*/ +} + /* * 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