move code from natcalls.h into native.h
[cacao.git] / src / native / native.c
index 296362a1b43a73e919aa06f43ebfa07c472d7440..713aea418f6949b77208dca02ee7edf817919ac7 100644 (file)
@@ -1,4 +1,4 @@
-/* native.c - table of native functions
+/* native/native.c - table of native functions
 
    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
    The .hh files created with the header file generator are all
    included here as are the C functions implementing these methods.
 
-   $Id: native.c 673 2003-11-23 22:14:35Z jowenn $
+   $Id: native.c 1655 2004-12-02 16:51:20Z carolyn $
 
 */
 
+
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
 #include <assert.h>
 #include <sys/time.h>
 #include <utime.h>
-#include <sys/utsname.h>
-
-#include "config.h"
-#include "global.h"
-#include "native.h"
-#include "nativetypes.hh"
-#include "builtin.h"
-#include "asmpart.h"
-#include "tables.h"
-#include "loader.h"
-#include "toolbox/loging.h"
-#include "threads/thread.h"
-#include "threads/threadio.h"
-#include "threads/locks.h"
 
 /* Include files for IO functions */
 
 #endif
 #include <sys/stat.h>
 
-#include "../threads/threadio.h"                    
+#include "config.h"
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.h"
+#include "native/include/java_lang_Throwable.h"
+#include "toolbox/logging.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/global.h"
+#include "vm/loader.h"
+#include "vm/options.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
+#include "vm/jit/jit.h"
+#if 0
+#include "threads/thread.h"
+#include "threads/threadio.h"
+#include "threads/locks.h"
+#endif
+
+
+/* include table of native functions ******************************************/
+
+/* XXX quick hack? */
+#if defined(USE_GTK)
+#include "native/vm/GtkComponentPeer.c"
+#include "native/vm/GtkScrollPanePeer.c"
+#include "native/vm/GtkFileDialogPeer.c"
+#endif
+
+#include "nativetable.inc"
 
-/* searchpath for classfiles */
-static 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;
-/* 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_Class;
+classinfo *class_java_lang_VMClass;
+classinfo *class_java_lang_System;
+classinfo *class_java_lang_ClassLoader;
+classinfo *class_gnu_java_lang_SystemClassLoader;
+classinfo *class_java_lang_SecurityManager;
+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;
+
+methodinfo *method_vmclass_init;
+
 
 /* the system classloader object */
 struct java_lang_ClassLoader *SystemClassLoader = NULL;
 
 /* for raising exceptions from native methods */
-java_objectheader* exceptionptr = NULL;
+#if !defined(USE_THREADS) || !defined(NATIVE_THREADS)
+java_objectheader* _exceptionptr = NULL;
+#endif
 
 /************* use classinfo structure as java.lang.Class object **************/
 
 void use_class_as_object(classinfo *c) 
 {
-       /*log_text("use_class_as_object");*/
-        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;
-        }
+       if (!c->classvftbl) {
+               c->header.vftbl = class_java_lang_Class->vftbl;
+               c->classvftbl = true;
+       }
+            
 }
 
-/*********************** include Java Native Interface ************************/ 
-
-#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"
-#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;
-       char *methodname;
-       char *descriptor;
-       bool isstatic;
-       functionptr func;
-} nativetable [] = {
-
-#include "nativetable.hh"
-
-};
-
-
+#ifdef STATIC_CLASSPATH
 #define NATIVETABLESIZE  (sizeof(nativetable)/sizeof(struct nativeref))
 
 /* table for fast string comparison */
-static struct nativecompref {
-       utf *classname;
-       utf *methodname;
-       utf *descriptor;
-       bool isstatic;
-       functionptr func;
-} nativecomptable [NATIVETABLESIZE];
+static nativecompref nativecomptable[NATIVETABLESIZE];
 
 /* string comparsion table initialized */
 static bool nativecompdone = false;
+#endif
 
-
-/******************************************************************************/
-/******************************************************************************/
-#include "natcalls.h"
-
-/* string call comparison table initialized */
-
-/******************************************************************************/
 /******************************************************************************/
 
-/*--------------- native method calls & classes used -------------------------*/
-
-
+/**include "natcalls.h" **/
 
 
 /*********************** function: native_loadclasses **************************
@@ -239,217 +161,93 @@ static bool nativecompdone = false;
 
 void native_loadclasses()
 {
-       static int classesLoaded=0; /*temporary hack JoWenn*/
-       if (classesLoaded) return;
-       classesLoaded=1;
-/*     log_text("loadclasses entered");*/
-
-
-       /*class_java_lang_System =*/
-               (void)class_new ( utf_new_char ("java/lang/VMClass") );/*JoWenn*/
-               (void)class_new ( utf_new_char ("java/lang/Class") );/*JoWenn*/
-       /* class_new adds the class to the list of classes to be loaded */
-       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") );
-       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_new(utf_new_char("java/io/FileNotFoundException"));
-       class_java_lang_ClassNotFoundException =
-               class_new(utf_new_char("java/lang/ClassNotFoundException"));
-       class_java_lang_InstantiationException =
-               class_new(utf_new_char("java/lang/InstantiationException"));
-       class_java_lang_NoSuchMethodError =
-               class_new(utf_new_char("java/lang/NoSuchMethodError"));
-       class_java_lang_NoSuchFieldError =
-               class_new(utf_new_char("java/lang/NoSuchFieldError"));  
-       class_java_lang_ClassFormatError =
-               class_new(utf_new_char("java/lang/ClassFormatError"));  
-       class_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") );   
-/*     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"));
-
-       class_java_lang_IllegalArgumentException =
-               class_new(utf_new_char("java/lang/IllegalArgumentException"));
-       class_java_lang_ArrayIndexOutOfBoundsException =
-               class_new(utf_new_char("java/lang/ArrayIndexOutOfBoundsException"));
-       class_java_lang_NoSuchFieldException =
-               class_new(utf_new_char("java/lang/NoSuchFieldException"));
-       class_java_lang_NoSuchMethodException = 
-               class_new(utf_new_char("java/lang/NoSuchMethodException"));
+       static int classesLoaded = 0; /*temporary hack JoWenn*/
 
-       /* load classes for wrapping primitive types */
-       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")); */
+       if (classesLoaded)
+               return;
 
-       classesLoaded=1;
-       log_text("native_loadclasses finished");
-}
+       classesLoaded = 1;
 
+       class_java_lang_Cloneable =
+               class_new(utf_new_char("java/lang/Cloneable"));
+       class_load(class_java_lang_Cloneable);
+       class_link(class_java_lang_Cloneable);
 
-/*************** adds a class to the vector of loaded classes ****************/
+       class_java_lang_Class =
+               class_new(utf_new_char("java/lang/Class"));
+       class_load(class_java_lang_Class);
+       class_link(class_java_lang_Class);
 
-void systemclassloader_addclass(classinfo *c)
-{
-       methodinfo *m;
+       class_java_lang_VMClass =
+               class_new(utf_new_char("java/lang/VMClass"));
+       class_load(class_java_lang_VMClass);
+       class_link(class_java_lang_VMClass);
 
-       /* find method addClass of 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");
-
-       /* 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
-                                          );
-}
-
-/*************** adds a library to the vector of loaded libraries *************/
-
-void systemclassloader_addlibrary(java_objectheader *o)
-{
-       log_text("systemclassloader_addlibrary");
-}
-
-/*****************************************************************************
-
-       create systemclassloader object and initialize instance fields  
-
-******************************************************************************/
+       class_java_lang_ClassLoader =
+               class_new(utf_new_char("java/lang/ClassLoader"));
+       class_load(class_java_lang_ClassLoader);
+       class_link(class_java_lang_ClassLoader);
 
-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");
-}
+       /* load classes for wrapping primitive types */
+       class_java_lang_Double = class_new(utf_new_char("java/lang/Double"));
+       class_load(class_java_lang_Double);
+       class_link(class_java_lang_Double);
 
+       class_java_lang_Float = class_new(utf_new_char("java/lang/Float"));
+       class_load(class_java_lang_Float);
+       class_link(class_java_lang_Float);
 
-/********************* add loaded library name  *******************************/
+       class_java_lang_Character =     class_new(utf_new_char("java/lang/Character"));
+       class_load(class_java_lang_Character);
+       class_link(class_java_lang_Character);
 
-void systemclassloader_addlibname(java_objectheader *o)
-{
-       methodinfo *m;
-       jfieldID id;
+       class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer"));
+       class_load(class_java_lang_Integer);
+       class_link(class_java_lang_Integer);
 
-       m = class_resolvemethod(loader_load(utf_new_char ("java/util/Vector")),
-                                                       utf_new_char("addElement"),
-                                                       utf_new_char("(Ljava/lang/Object;)V")
-                                                       );
+       class_java_lang_Long = class_new(utf_new_char("java/lang/Long"));
+       class_load(class_java_lang_Long);
+       class_link(class_java_lang_Long);
 
-       if (!m) panic("cannot initialize classloader");
+       class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte"));
+       class_load(class_java_lang_Byte);
+       class_link(class_java_lang_Byte);
 
-       id = envTable.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;");
-       if (!id) panic("can not access ClassLoader");
+       class_java_lang_Short = class_new(utf_new_char("java/lang/Short"));
+       class_load(class_java_lang_Short);
+       class_link(class_java_lang_Short);
 
-       asm_calljavamethod(m,
-                                          GetStaticObjectField(&env,class_java_lang_ClassLoader,id),
-                                          o,
-                                          NULL,  
-                                          NULL
-                                          );       
-}
+       class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean"));
+       class_load(class_java_lang_Boolean);
+       class_link(class_java_lang_Boolean);
 
+       class_java_lang_Void = class_new(utf_new_char("java/lang/Void"));
+       class_load(class_java_lang_Void);
+       class_link(class_java_lang_Void);
 
-/********************* function: native_setclasspath **************************/
-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);
-}
+       create systemclassloader object and initialize instance fields  
 
+******************************************************************************/
 
-void throw_classnotfoundexception2(utf* classname)
+void init_systemclassloader() 
 {
-       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");
-        */
+       log_text("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_new(utf_new_char("gnu/java/lang/SystemClassLoader")));
+
+               /* systemclassloader has no parent */
+               SystemClassLoader->parent      = NULL;
+               SystemClassLoader->initialized = true;
+       }
+       log_text("leaving system class loader");
 }
 
 
@@ -467,6 +265,7 @@ void throw_classnotfoundexception2(utf* classname)
 functionptr native_findfunction(utf *cname, utf *mname, 
                                                                utf *desc, bool isstatic)
 {
+#ifdef STATIC_CLASSPATH
        int i;
        /* entry of table for fast string comparison */
        struct nativecompref *n;
@@ -494,16 +293,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);       
 
@@ -527,16 +326,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
@@ -561,11 +359,14 @@ functionptr native_findfunction(utf *cname, utf *mname,
 
        MFREE(buffer, char, buffer_len);
 
+/*     exit(1); */
 
-       exit(1);
-
-       
+       /* keep compiler happy */
        return NULL;
+#else
+/* dynamic classpath */
+  return 0;
+#endif
 }
 
 
@@ -578,21 +379,27 @@ functionptr native_findfunction(utf *cname, utf *mname,
 
 *******************************************************************************/
 
-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   */
+       char *utf_ptr;                  /* current utf character in utf string    */
+       u4 utflength;                   /* length of utf-string if uncompressed   */
        java_lang_String *s;                /* result-string                          */
        java_chararray *a;
        s4 i;
-       
-/*     log_text("javastring_new");*/
-       
-       s = (java_lang_String*) builtin_new (class_java_lang_String);
-       a = builtin_newarray_char (utflength);
+
+       if (!u) {
+               *exceptionptr = new_nullpointerexception();
+               return NULL;
+       }
+
+       utf_ptr = u->text;
+       utflength = utf_strlen(u);
+
+       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))
+       if (!a || !s)
                return NULL;
 
        /* decompress utf-string */
@@ -604,9 +411,10 @@ java_objectheader *javastring_new (utf *u)
        s->offset = 0;
        s->count  = utflength;
 
-       return (java_objectheader*) s;
+       return s;
 }
 
+
 /********************** function: javastring_new_char **************************
 
        creates a new java/lang/String object which contains the convertet
@@ -616,30 +424,37 @@ 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 */
+       s4 len;                /* length of the string */
        java_lang_String *s;   /* result-string */
        java_chararray *a;
-       
-       /*log_text("javastring_new_char");*/
-       s = (java_lang_String*) builtin_new (class_java_lang_String);
-       a = builtin_newarray_char (len);
+
+       if (!text) {
+               *exceptionptr = new_nullpointerexception();
+               return NULL;
+       }
+
+       len = strlen(text);
+
+       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 s;
 }
 
 
@@ -655,24 +470,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;
 }
 
@@ -684,31 +503,36 @@ 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 = new_exception(string_java_lang_NoSuchFieldException);
+
        return NULL;
 }
 
-s4 class_findfield_index_approx (classinfo *c, utf *name)
+
+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);
+       *exceptionptr = new_exception(string_java_lang_NoSuchFieldException);
+
        return -1;
 }
 
@@ -723,35 +547,153 @@ s4 class_findfield_index_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)
+               return *exceptionptr;
+
+       o = builtin_new(c);                 /* create object                      */
+       
+       if (!o)
+               return NULL;
+
+       /* find initializer */
+
+       m = class_findmethod(c,
+                                                utf_new_char("<init>"),
+                                                utf_new_char("()V"));
+                                                     
+       if (!m) {                           /* initializer not found              */
+               if (opt_verbose) {
+                       char logtext[MAXLOGTEXT];
+                       sprintf(logtext, "Warning: class has no instance-initializer: ");
+                       utf_sprint_classname(logtext + strlen(logtext), c->name);
+                       log_text(logtext);
+               }
+               return o;
+       }
+
+       /* call initializer */
+
+       asm_calljavafunction(m, o, NULL, NULL, NULL);
 
-        /*
-       printf("native_new_and_init ");
-       utf_display(c->name);
-       printf("\n");
-        */
+       return o;
+}
+
+
+java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s)
+{
+       methodinfo *m;
+       java_objectheader *o;
+
+       if (!c)
+               return *exceptionptr;
+
+       o = builtin_new(c);          /* create object          */
+
+       if (!o)
+               return NULL;
+
+       /* find initializer */
+
+       m = class_findmethod(c,
+                                                utf_new_char("<init>"),
+                                                utf_new_char("(Ljava/lang/String;)V"));
+                                                     
+       if (!m) {                                       /* initializer not found  */
+               if (opt_verbose) {
+                       char logtext[MAXLOGTEXT];
+                       sprintf(logtext, "Warning: class has no instance-initializer: ");
+                       utf_sprint_classname(logtext + strlen(logtext), c->name);
+                       log_text(logtext);
+               }
+               return o;
+       }
+
+       /* call initializer */
+
+       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)
+               return *exceptionptr;
+
+       o = builtin_new(c);          /* create object          */
+       
        if (!o) return NULL;
-       /* printf("o!=NULL\n"); */
+
        /* find initializer */
 
-       m = class_findmethod(c, utf_new_char("<init>"), utf_new_char("()V"));
+       m = class_findmethod(c,
+                                                utf_new_char("<init>"),
+                                                utf_new_char("(I)V"));
                                                      
        if (!m) {                                       /* initializer not found  */
-               if (verbose) {
+               if (opt_verbose) {
+                       char logtext[MAXLOGTEXT];
                        sprintf(logtext, "Warning: class has no instance-initializer: ");
-                       utf_sprint(logtext + strlen(logtext), c->name);
-                       dolog();
+                       utf_sprint_classname(logtext + strlen(logtext), c->name);
+                       log_text(logtext);
                }
                return o;
        }
 
        /* call initializer */
 
-       asm_calljavamethod(m, o, NULL, NULL, NULL);
+#if defined(__I386__) || defined(__POWERPC__)
+       asm_calljavafunction(m, o, (void *) i, NULL, NULL);
+#else
+       asm_calljavafunction(m, o, (void *) (s8) i, NULL, NULL);
+#endif
 
        return o;
 }
 
+
+java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t)
+{
+       methodinfo *m;
+       java_objectheader *o;
+
+       if (!c)
+               return *exceptionptr;
+
+       o = builtin_new(c);          /* create object          */
+       
+       if (!o) return NULL;
+
+       /* find initializer */
+
+       m = class_findmethod(c,
+                                                utf_new_char("<init>"),
+                                                utf_new_char("(Ljava/lang/Throwable;)V"));
+                                                     
+       if (!m) {                                       /* initializer not found  */
+               if (opt_verbose) {
+                       char logtext[MAXLOGTEXT];
+                       sprintf(logtext, "Warning: class has no instance-initializer: ");
+                       utf_sprint_classname(logtext + strlen(logtext), c->name);
+                       log_text(logtext);
+               }
+               return o;
+       }
+
+       /* call initializer */
+
+       asm_calljavafunction(m, o, t, NULL, NULL);
+
+       return o;
+}
+
+
 /******************** function: stringtable_update ****************************
 
        traverses the javastring hashtable and sets the vftbl-entries of
@@ -774,13 +716,15 @@ 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;
+                                       js->header.vftbl = class_java_lang_String->vftbl;
 
                                if (!a->header.objheader.vftbl) 
                                        /* vftbl of character-array is NULL */ 
@@ -800,30 +744,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, 
@@ -834,67 +777,65 @@ 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");
-       }
-
-       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
@@ -903,12 +844,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 
@@ -919,121 +863,146 @@ 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 */
     java_chararray *stringdata;      /* copy of u2-array */      
-    u4 key;   
-    u4 slot;  
+    u4 key;
+    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; i<length; i++) 
-         if (js->value->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)
+                               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 = 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;        
-
-    /* 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;
-
-    /* create new literalstring */
-    s = NEW (literalstring);
-    s->hashlink = string_hash.ptr[slot];
-    s->string   = (java_objectheader *) js;
-    string_hash.ptr[slot] = s;
-
-    /* update numbe of hashtable entries */
-    string_hash.entries++;
-
-    /* reorganization of hashtable */       
-    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 */
+    stringdata->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl;
+    stringdata->header.size = length;
+
+       /* if we use eager loading, we have to check loaded String class */
+       if (opt_eager) {
+               class_java_lang_String =
+                       class_new_intern(utf_new_char("java/lang/String"));
+
+               if (!class_load(class_java_lang_String))
+                       return NULL;
+
+               list_addfirst(&unlinkedclasses, class_java_lang_String);
+       }
+
+       /* create new javastring */
+       js = NEW(java_lang_String);
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       initObjectLock(&js->header);
+#endif
+       js->header.vftbl = class_java_lang_String->vftbl;
+       js->value  = stringdata;
+       js->offset = 0;
+       js->count  = length;
+
+#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
+                       
+       /* create new literalstring */
+       s = NEW(literalstring);
+       s->hashlink = string_hash.ptr[slot];
+       s->string   = (java_objectheader *) js;
+       string_hash.ptr[slot] = s;
+
+       /* update number of hashtable entries */
+       string_hash.entries++;
+
+       /* reorganization of hashtable */       
+       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 */
       
-      /* 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<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);
+               /* 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;
-    }
-#ifdef JOWENN_DEBUG1
-       log_text("literalstring_u2: newly created");
-/*     utf_display(javastring_toutf(js,0));*/
-#endif
-                       
-    return (java_objectheader *) js;
+               /* dispose old table */ 
+               MFREE(string_hash.ptr, void*, string_hash.size);
+               string_hash = newhash;
+       }
+
+       return (java_objectheader *) js;
 }
 
+
 /******************** Function: literalstring_new *****************************
 
     creates a new javastring with the text of the utf-symbol
@@ -1041,22 +1010,21 @@ 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 */
     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 ); 
+    a = mem_alloc(sizeof(java_chararray) + sizeof(u2) * (utflength - 1) + 10);
+
     /* convert utf-string to u2-array */
-    for (i=0; i<utflength; i++) a->data[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);
 }
 
 
@@ -1066,23 +1034,20 @@ 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);
+       FREE(s, java_lang_String);
+
        /* dispose memory of java-characterarray */
-       LFREE (a, sizeof(java_chararray) + sizeof(u2)*(a->header.size-1)); /* +10 ?? */
+       FREE(a, sizeof(java_chararray) + sizeof(u2) * (a->header.size - 1)); /* +10 ?? */
 }
 
 
-
-
-void copy_vftbl(vftbl **dest, vftbl *src)
+void copy_vftbl(vftbl_t **dest, vftbl_t *src)
 {
     *dest = src;
 #if 0
@@ -1096,6 +1061,221 @@ 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(char, 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, char, 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;
+}
+
+
+/* get_parametertypes **********************************************************
+
+   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_exceptiontypes **********************************************************
+
+   get the exceptions which can be thrown by a method
+
+*******************************************************************************/
+
+java_objectarray* get_exceptiontypes(methodinfo *m)
+{
+    u2 excount;
+    u2 i;
+    java_objectarray *result;
+
+       excount = m->thrownexceptionscount;
+
+    /* create class-array */
+    result = builtin_anewarray(excount, class_java_lang_Class);
+
+    for (i = 0; i < excount; i++) {
+               java_objectheader *o = (java_objectheader *) (m->thrownexceptions[i]);
+               use_class_as_object((classinfo *) o);
+               result->data[i] = o;
+    }
+
+    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_ptr<desc_end) && utf_nextu2(&utf_ptr)!=')')
+               /* skip */ ;
+
+       return get_type(&utf_ptr,desc_end, false);
+}
+
+
 /*****************************************************************************/
 /*****************************************************************************/
 
@@ -1215,9 +1395,102 @@ for (i=0;i<NATIVECALLSSIZE; i++) {
 
 return true;
 }
+
 /*--------------------------------------------------------*/
 
 
+java_objectarray *builtin_asm_createclasscontextarray(classinfo **end, classinfo **start)
+{
+#if defined(__GNUC__)
+#warning platform dependend
+#endif
+       java_objectarray *tmpArray;
+       int i;
+       classinfo **current;
+       classinfo *c;
+       size_t size;
+
+       size = (((size_t) start) - ((size_t) end)) / sizeof(classinfo*);
+
+       /*printf("end %p, start %p, size %ld\n",end,start,size);*/
+       if (!class_java_lang_Class)
+               class_java_lang_Class = class_new(utf_new_char("java/lang/Class"));
+
+       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--;
+               }
+       }
+
+       tmpArray =
+               builtin_newarray(size, class_array_of(class_java_lang_Class)->vftbl);
+
+       for(i = 0, current = start; i < size; i++, current--) {
+               c = *current;
+               /*              printf("%d\n",i);
+                utf_display(c->name);*/
+               use_class_as_object(c);
+               tmpArray->data[i] = (java_objectheader *) c;
+       }
+
+       return tmpArray;
+}
+
+
+java_lang_ClassLoader *builtin_asm_getclassloader(classinfo **end, classinfo **start)
+{
+#if defined(__GNUC__)
+#warning platform dependend
+#endif
+       int i;
+       classinfo **current;
+       classinfo *c;
+       classinfo *privilegedAction;
+       size_t size;
+
+       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; i < size; i++, current--) {
+               c = *current;
+
+               if (c == privilegedAction)
+                       return NULL;
+
+               if (c->classloader)
+                       return (java_lang_ClassLoader *) 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