X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=src%2Fnative%2Fnative.c;h=1ab67dbe1d4f78ac3fb6227ad82dc8702afe37e0;hb=d75b6037acf17c342166b9c9bd6e657dfdd12cd9;hp=f8f277053ace3155ea26df4855e36af95bae3634;hpb=60a0c530596921c32405245c996852aedc0955eb;p=cacao.git diff --git a/src/native/native.c b/src/native/native.c index f8f277053..1ab67dbe1 100644 --- a/src/native/native.c +++ b/src/native/native.c @@ -1,40 +1,51 @@ -/****************************** native.c *************************************** +/* native/native.c - table of native functions - Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst + Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates, + R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner, + C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger, + Institut f. Computersprachen - TU Wien - See file COPYRIGHT for information on usage and disclaimer of warranties + This file is part of CACAO. - Enth"alt die Tabellen f"ur die native-methods. - Die vom Headerfile-Generator erzeugten -.hh - Dateien werden hier - eingebunden, und ebenso alle C-Funktionen, mit denen diese - Methoden implementiert werden. + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. - Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at - Roman Obermaisser EMAIL: cacao@complang.tuwien.ac.at - Andreas Krall EMAIL: cacao@complang.tuwien.ac.at + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. - Last Change: 1996/11/14 + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. -*******************************************************************************/ + Contact: cacao@complang.tuwien.ac.at + + Authors: Reinhard Grafl + Roman Obermaisser + Andreas Krall + + The .hh files created with the header file generator are all + included here as are the C functions implementing these methods. + + $Id: native.c 1735 2004-12-07 14:33:27Z twisti $ +*/ + + +#include #include #include -#include "global.h" -#include "native.h" -#include "nativetypes.hh" -#include "builtin.h" -#include "asmpart.h" -#include "tables.h" -#include "loader.h" #include #include #include #include +#include -#include "threads/thread.h" /* schani */ -#include "threads/locks.h" - -/* INCLUDE-Files fuer IO-Funktionen */ +/* Include files for IO functions */ #include #include @@ -44,407 +55,330 @@ #endif #include -#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_Cloneable; -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_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 **************/ -static void use_class_as_object (classinfo *c) +void use_class_as_object(classinfo *c) { - c->header.vftbl = class_java_lang_Class -> vftbl; -} - -/*********************** include Java Native Interface ************************/ - -#include "jni.c" - -/*************************** include native methods ***************************/ - -#include "nat/Object.c" -#include "nat/String.c" -#include "nat/ClassLoader.c" -#include "nat/Class.c" -#include "nat/Compiler.c" -#include "nat/Double.c" -#include "nat/Float.c" -#include "nat/Math.c" -#include "nat/Package.c" -#include "nat/Runtime.c" -#include "nat/SecurityManager.c" -#include "nat/System.c" -#include "nat/Thread.c" -#include "nat/Throwable.c" -#include "nat/Finalizer.c" -#include "nat/Array.c" -#include "nat/Constructor.c" -#include "nat/Field.c" -#include "nat/Method.c" -#include "nat/FileDescriptor.c" -#include "nat/FileInputStream.c" -#include "nat/FileOutputStream.c" -#include "nat/FileSystem.c" -#include "nat/ObjectInputStream.c" -#include "nat/ObjectStreamClass.c" -#include "nat/RandomAccessFile.c" -#include "nat/ResourceBundle.c" -#include "nat/JarFile.c" -#include "nat/Adler32.c" -#include "nat/CRC32.c" -#include "nat/Deflater.c" -#include "nat/Inflater.c" -#include "nat/ZipEntry.c" -#include "nat/ZipFile.c" -#include "nat/BigInteger.c" -#include "nat/InetAddress.c" -#include "nat/InetAddressImpl.c" -#include "nat/DatagramPacket.c" -#include "nat/PlainDatagramSocketImpl.c" -#include "nat/PlainSocketImpl.c" -#include "nat/SocketInputStream.c" -#include "nat/SocketOutputStream.c" -#include "nat/AccessController.c" -#include "nat/ClassLoader_NativeLibrary.c" -#include "nat/UnixFileSystem.c" - -/************************** tables for methods ********************************/ - -/* table for locating native methods */ -static struct nativeref { - char *classname; - char *methodname; - char *descriptor; - bool isstatic; - functionptr func; -} nativetable [] = { + if (!c->classvftbl) { + c->header.vftbl = class_java_lang_Class->vftbl; + c->classvftbl = true; + } + +} -#include "nativetable.hh" -}; +/************************** tables for methods ********************************/ +#undef JOWENN_DEBUG +#undef JOWENN_DEBUG1 +#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 -/*********************** function: native_loadclasses ************************** - - load classes required for native methods - -*******************************************************************************/ +/* XXX don't define this in a header file!!! */ -void native_loadclasses() +static struct nativeCall nativeCalls[] = { - /* class_new adds the class to the list of classes to be loaded */ - class_java_lang_Cloneable = - class_new ( utf_new_char ("java/lang/Cloneable") ); - class_java_lang_CloneNotSupportedException = - class_new ( utf_new_char ("java/lang/CloneNotSupportedException") ); - class_java_lang_Class = - class_new ( utf_new_char ("java/lang/Class") ); - class_java_io_IOException = - class_new ( utf_new_char ("java/io/IOException") ); - 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") ); - class_java_io_UnixFileSystem = - class_new ( utf_new_char ("java/io/UnixFileSystem") ); - class_java_lang_System = - class_new ( utf_new_char ("java/lang/System") ); - class_java_lang_ClassLoader = - class_new ( utf_new_char ("java/lang/ClassLoader") ); - 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") ); - - /* load classes for wrapping primitive types */ - class_java_lang_Double = - class_new( utf_new_char ("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 */ - 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 */ - loader_load(utf_new_char("sun/io/ByteToCharISO8859_1")); -} +#include "nativecalls.inc" +}; +#define NATIVECALLSSIZE (sizeof(nativeCalls) / sizeof(struct nativeCall)) -/*************** adds a class to the vector of loaded classes ****************/ +struct nativeCompCall nativeCompCalls[NATIVECALLSSIZE]; -void systemclassloader_addclass(classinfo *c) -{ - methodinfo *m; +/******************************************************************************/ - /* find method addClass of java.lang.ClassLoader */ - m = class_resolvemethod ( - class_java_lang_ClassLoader, - utf_new_char("addClass"), - utf_new_char("(Ljava/lang/Class;)") - ); +/**include "natcalls.h" **/ - if (!m) panic("warning: cannot initialize classloader"); - /* prepare class to be passed as argument */ - use_class_as_object (c); +/*********************** function: native_loadclasses ************************** - /* call 'addClass' */ - asm_calljavamethod(m, - (java_objectheader*) SystemClassLoader, - (java_objectheader*) c, - NULL, - NULL - ); -} + load classes required for native methods -/*************** adds a library to the vector of loaded libraries *************/ +*******************************************************************************/ -void systemclassloader_addlibrary(java_objectheader *o) +void native_loadclasses() { - methodinfo *m; + static int classesLoaded = 0; /*temporary hack JoWenn*/ - /* find method addElement of java.util.Vector */ - m = class_resolvemethod ( - loader_load ( utf_new_char ("java/util/Vector") ), - utf_new_char("addElement"), - utf_new_char("(Ljava/lang/Object;)V") - ); + if (classesLoaded) + return; - if (!m) panic("cannot initialize classloader"); + classesLoaded = 1; - /* call 'addElement' */ - asm_calljavamethod(m, - SystemClassLoader->nativeLibraries, - o, - NULL, - NULL - ); -} + class_java_lang_Cloneable = + class_new(utf_new_char("java/lang/Cloneable")); + class_load(class_java_lang_Cloneable); + class_link(class_java_lang_Cloneable); -/***************************************************************************** + class_java_lang_Class = + class_new(utf_new_char("java/lang/Class")); + class_load(class_java_lang_Class); + class_link(class_java_lang_Class); - create systemclassloader object and initialize instance fields + class_java_lang_VMClass = + class_new(utf_new_char("java/lang/VMClass")); + class_load(class_java_lang_VMClass); + class_link(class_java_lang_VMClass); -******************************************************************************/ + 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) { + /* 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); - /* create object and call initializer */ - SystemClassLoader = (java_lang_ClassLoader*) native_new_and_init(class_java_lang_ClassLoader); - heap_addreference((void**) &SystemClassLoader); + class_java_lang_Float = class_new(utf_new_char("java/lang/Float")); + class_load(class_java_lang_Float); + class_link(class_java_lang_Float); - /* systemclassloader has no parent */ - SystemClassLoader->parent = NULL; - SystemClassLoader->initialized = true; - } -} + class_java_lang_Character = class_new(utf_new_char("java/lang/Character")); + class_load(class_java_lang_Character); + class_link(class_java_lang_Character); + class_java_lang_Integer = class_new(utf_new_char("java/lang/Integer")); + class_load(class_java_lang_Integer); + class_link(class_java_lang_Integer); -/********************* add loaded library name *******************************/ + class_java_lang_Long = class_new(utf_new_char("java/lang/Long")); + class_load(class_java_lang_Long); + class_link(class_java_lang_Long); -void systemclassloader_addlibname(java_objectheader *o) -{ - methodinfo *m; - java_objectheader *LibraryNameVector; - jfieldID id; + class_java_lang_Byte = class_new(utf_new_char("java/lang/Byte")); + class_load(class_java_lang_Byte); + class_link(class_java_lang_Byte); - 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_Short = class_new(utf_new_char("java/lang/Short")); + class_load(class_java_lang_Short); + class_link(class_java_lang_Short); - if (!m) panic("cannot initialize classloader"); + class_java_lang_Boolean = class_new(utf_new_char("java/lang/Boolean")); + class_load(class_java_lang_Boolean); + class_link(class_java_lang_Boolean); - id = env.GetStaticFieldID(&env,class_java_lang_ClassLoader,"loadedLibraryNames","Ljava/util/Vector;"); - if (!id) panic("can not access ClassLoader"); + class_java_lang_Void = class_new(utf_new_char("java/lang/Void")); + class_load(class_java_lang_Void); + class_link(class_java_lang_Void); - asm_calljavamethod(m, - GetStaticObjectField(&env,class_java_lang_ClassLoader,id), - o, - NULL, - NULL - ); } -/********************* function: native_setclasspath **************************/ - -void native_setclasspath (char *path) -{ - /* set searchpath for classfiles */ - classpath = path; -} +/***************************************************************************** + + create systemclassloader object and initialize instance fields -/***************** function: throw_classnotfoundexception *********************/ +******************************************************************************/ -void throw_classnotfoundexception() +void init_systemclassloader() { - /* throws a ClassNotFoundException */ - exceptionptr = native_new_and_init (class_java_lang_ClassNotFoundException); + 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"); } -/*********************** Funktion: native_findfunction ************************* +/*********************** Function: native_findfunction ************************* - Sucht in der Tabelle die passende Methode (muss mit Klassennamen, - Methodennamen, Descriptor und 'static'-Status "ubereinstimmen), - und gibt den Funktionszeiger darauf zur"uck. - Return: Funktionszeiger oder NULL (wenn es keine solche Methode gibt) + Looks up a method (must have the same class name, method name, descriptor + and 'static'ness) and returns a function pointer to it. + Returns: function pointer or NULL (if there is no such method) - Anmerkung: Zu Beschleunigung des Suchens werden die als C-Strings - vorliegenden Namen/Descriptors in entsprechende unicode-Symbole - umgewandelt (beim ersten Aufruf dieser Funktion). + Remark: For faster operation, the names/descriptors are converted from C + strings to Unicode the first time this function is called. *******************************************************************************/ -functionptr native_findfunction (utf *cname, utf *mname, - utf *desc, bool isstatic) +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; - /* for warning message if no function is found */ + /* for warning message if no function is found */ char *buffer; - int buffer_len, pos; + int buffer_len; isstatic = isstatic ? true : false; - + if (!nativecompdone) { for (i = 0; i < NATIVETABLESIZE; i++) { nativecomptable[i].classname = - utf_new_char(nativetable[i].classname); + utf_new_char(nativetable[i].classname); nativecomptable[i].methodname = - utf_new_char(nativetable[i].methodname); + utf_new_char(nativetable[i].methodname); nativecomptable[i].descriptor = - utf_new_char(nativetable[i].descriptor); + utf_new_char(nativetable[i].descriptor); nativecomptable[i].isstatic = - nativetable[i].isstatic; + nativetable[i].isstatic; nativecomptable[i].func = - nativetable[i].func; - } - nativecompdone = true; + nativetable[i].func; } + nativecompdone = true; + } +#ifdef JOWENN_DEBUG + buffer_len = + utf_strlen(cname) + utf_strlen(mname) + utf_strlen(desc) + 64; + + buffer = MNEW(char, buffer_len); + + strcpy(buffer, "searching matching function in native table:"); + utf_sprint(buffer+strlen(buffer), mname); + strcpy(buffer+strlen(buffer), ": "); + utf_sprint(buffer+strlen(buffer), desc); + strcpy(buffer+strlen(buffer), " for class "); + utf_sprint(buffer+strlen(buffer), cname); + + log_text(buffer); + + MFREE(buffer, char, buffer_len); +#endif + for (i = 0; i < NATIVETABLESIZE; i++) { n = &(nativecomptable[i]); if (cname == n->classname && mname == n->methodname && desc == n->descriptor && isstatic == n->isstatic) return n->func; - } +#ifdef JOWENN_DEBUG + else { + if (cname == n->classname && mname == n->methodname ) log_text("static and descriptor mismatch"); + + else { + buffer_len = + utf_strlen(n->classname) + utf_strlen(n->methodname) + utf_strlen(n->descriptor) + 64; + + buffer = MNEW(char, buffer_len); + strcpy(buffer, "comparing with:"); + utf_sprint(buffer+strlen(buffer), n->methodname); + strcpy (buffer+strlen(buffer), ": "); + utf_sprint(buffer+strlen(buffer), n->descriptor); + strcpy(buffer+strlen(buffer), " for class "); + utf_sprint(buffer+strlen(buffer), n->classname); + + log_text(buffer); + + MFREE(buffer, char, buffer_len); + } + } +#endif + } + + /* no function was found, display warning */ buffer_len = - 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, "warning: native function "); - utf_sprint(buffer+strlen(buffer), mname); - strcpy(buffer+strlen(buffer), ": "); - utf_sprint(buffer+strlen(buffer), desc); - strcpy(buffer+strlen(buffer), " not found in class "); - utf_sprint(buffer+strlen(buffer), cname); + utf_sprint(buffer + strlen(buffer), mname); + strcpy(buffer + strlen(buffer), ": "); + utf_sprint(buffer + strlen(buffer), desc); + strcpy(buffer + strlen(buffer), " not found in class "); + utf_sprint(buffer + strlen(buffer), cname); log_text(buffer); MFREE(buffer, char, buffer_len); +/* exit(1); */ + + /* keep compiler happy */ return NULL; +#else +/* dynamic classpath */ + return 0; +#endif } @@ -457,19 +391,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; - - 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 */ @@ -477,13 +419,14 @@ java_objectheader *javastring_new (utf *u) a->data[i] = utf_nextu2(&utf_ptr); /* set fields of the javastring-object */ - s -> value = a; - s -> offset = 0; - s -> count = utflength; + s->value = a; + 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 @@ -493,29 +436,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; - - 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 -> offset = 0; - s -> count = len; + s->value = a; + s->offset = 0; + s->count = len; - return (java_objectheader*) s; + return s; } @@ -531,22 +482,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; 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; } @@ -558,21 +515,40 @@ 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 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 = new_exception(string_java_lang_NoSuchFieldException); + + return -1; +} + + /********************** function: native_new_and_init ************************* Creates a new object on the heap and calls the initializer. @@ -580,30 +556,156 @@ fieldinfo *class_findfield_approx (classinfo *c, utf *name) *******************************************************************************/ -java_objectheader *native_new_and_init (classinfo *c) +java_objectheader *native_new_and_init(classinfo *c) { methodinfo *m; - java_objectheader *o = builtin_new (c); /* create object */ + java_objectheader *o; - if (!o) return NULL; + 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("()V")); + m = class_findmethod(c, + utf_new_char(""), + 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); + + 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(""), + utf_new_char("(Ljava/lang/String;)V")); if (!m) { /* initializer not found */ - sprintf(logtext, "warning: class has no instance-initializer: "); - utf_sprint(logtext + strlen(logtext), c->name); - dolog(); + 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; + + /* find initializer */ + + m = class_findmethod(c, + utf_new_char(""), + utf_new_char("(I)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 */ + +#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(""), + 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_calljavamethod (m, o, NULL, NULL, NULL); + asm_calljavafunction(m, o, t, NULL, NULL); + return o; } + /******************** function: stringtable_update **************************** traverses the javastring hashtable and sets the vftbl-entries of @@ -626,17 +728,19 @@ 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 */ - a->header.objheader.vftbl = class_array -> vftbl; + a->header.objheader.vftbl = primitivetype_table[ARRAYTYPE_CHAR].arrayvftbl; /* follow link in external hash chain */ s = s->hashlink; @@ -652,30 +756,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, @@ -686,62 +789,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 */ + /* 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) 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 @@ -750,10 +856,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; - return utf_new_u2(str->value->data,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 @@ -764,131 +875,168 @@ 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; +/* #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); + js = (java_lang_String *) s->string; - return (java_objectheader *) js; - } + 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; + } - 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 */ - if (class_array==NULL) panic("class_array not initialized"); - stringdata -> header.objheader.vftbl = class_array -> vftbl; - stringdata -> header.size = length; - stringdata -> header.arraytype = ARRAYTYPE_CHAR; - - /* 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 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; - } - - return (java_objectheader *) js; + /* dispose old table */ + MFREE(string_hash.ptr, void*, string_hash.size); + string_hash = newhash; + } + + return (java_objectheader *) js; } -/******************** Funktion: literalstring_new ***************************** + +/******************** Function: literalstring_new ***************************** creates a new javastring with the text of the utf-symbol and inserts it into the string hashtable *******************************************************************************/ -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 */ - java_objectheader *js; u4 i; - + /* 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; 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); } @@ -898,21 +1046,472 @@ 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_t **dest, vftbl_t *src) +{ + *dest = src; +#if 0 + /* XXX this kind of copying does not work (in the general + * case). The interface tables would have to be copied, too. I + * don't see why we should make a copy anyway. -Edwin + */ + *dest = mem_alloc(sizeof(vftbl) + sizeof(methodptr)*(src->vftbllength-1)); + memcpy(*dest, src, sizeof(vftbl) - sizeof(methodptr)); + memcpy(&(*dest)->table, &src->table, src->vftbllength * sizeof(methodptr)); +#endif +} + + +/****************************************************************************************** + + 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_ptraCalled = %s %s %s\n",i,j, + nc.methods[i].methodCalls[j].classname, + nc.methods[i].methodCalls[j].methodname, + nc.methods[i].methodCalls[j].descriptor);fflush(stdout); + } + } + printf("-+++++--------------------\n");fflush(stdout); +} + +/*--------------------------------------------------------*/ +void printCompNativeCall(nativeCompCall nc) { + int i,j; + printf("printCompNativeCall BEGIN\n");fflush(stdout); + printf("\n%s's Native Comp Methods call:\n",nc.classname->text);fflush(stdout); + utf_display(nc.classname); fflush(stdout); + + for (i=0; itext,nc.methods[i].descriptor->text);fflush(stdout); + utf_display(nc.methods[i].methodname); fflush(stdout); + utf_display(nc.methods[i].descriptor);fflush(stdout); + printf("\n");fflush(stdout); + + for (j=0; jbCalled = ",i,j);fflush(stdout); + utf_display(nc.methods[i].methodCalls[j].classname);fflush(stdout); + utf_display(nc.methods[i].methodCalls[j].methodname); fflush(stdout); + utf_display(nc.methods[i].methodCalls[j].descriptor);fflush(stdout); + printf("\n");fflush(stdout); + } + } +printf("---------------------\n");fflush(stdout); +} + + +/*--------------------------------------------------------*/ +classMeth findNativeMethodCalls(utf *c, utf *m, utf *d ) +{ + int i = 0; + int j = 0; + int cnt = 0; + classMeth mc; + mc.i_class = i; + mc.j_method = j; + mc.methCnt = cnt; + + return mc; +} + +/*--------------------------------------------------------*/ +nativeCall* findNativeClassCalls(char *aclassname ) { +int i; + +for (i=0;iclassname = utf_new_char(nc.classname); + ncc->methCnt = nc.methCnt; + + for (i=0; imethods[i].methodname = utf_new_char(nc.methods[i].methodname); + ncc->methods[i].descriptor = utf_new_char(nc.methods[i].descriptor); + ncc->callCnt[i] = nc.callCnt[i]; + + for (j=0; jmethods[i].methodCalls[j].classname = utf_new_char(nc.methods[i].methodCalls[j].classname); + + if (strcmp("", nc.methods[i].methodCalls[j].methodname) != 0) { + ncc->methods[i].methodCalls[j].methodname = utf_new_char(nc.methods[i].methodCalls[j].methodname); + ncc->methods[i].methodCalls[j].descriptor = utf_new_char(nc.methods[i].methodCalls[j].descriptor); + } + else { + ncc->methods[i].methodCalls[j].methodname = NULL; + ncc->methods[i].methodCalls[j].descriptor = NULL; + } + } + } +} + + + +/*--------------------------------------------------------*/ + +bool natcall2utf(bool natcallcompdone) { +int i; + +if (natcallcompdone) + return true; + +for (i=0;i 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 + * Emacs will automagically detect them. + * --------------------------------------------------------------------- + * Local variables: + * mode: c + * indent-tabs-mode: t + * c-basic-offset: 4 + * tab-width: 4 + * End: + */