* configure.ac: Default to AC_ENABLE_SHARED and AC_DISABLE_STATIC.
[cacao.git] / src / native / vm / VMRuntime.c
index 00062651862f6ff810f355ba2d91d55a3ccd7a9f..70f910acc35f0bce72e8566fecf0a736bfd6b32c 100644 (file)
@@ -1,9 +1,9 @@
-/* native/vm/VMRuntime.c - java/lang/VMRuntime
+/* src/native/vm/VMRuntime.c - java/lang/VMRuntime
 
-   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
+   Copyright (C) 1996-2005, 2006 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
 
    This file is part of CACAO.
 
 
    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.
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
 
-   Contact: cacao@complang.tuwien.ac.at
+   Contact: cacao@cacaojvm.org
 
    Authors: Roman Obermaiser
 
    Changes: Joseph Wenninger
             Christian Thalinger
 
-   $Id: VMRuntime.c 1767 2004-12-16 16:46:57Z motse $
+   $Id: VMRuntime.c 4530 2006-02-21 09:11:53Z twisti $
 
 */
 
 
+#include "config.h"
+
+#include <assert.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include <sys/utsname.h>
 
-#if !defined(STATIC_CLASSPATH)
-#include <dlfcn.h>
+#if !defined(WITH_STATIC_CLASSPATH)
+# include <ltdl.h>
 #endif
 
-#include "config.h"
-#include "cacao/cacao.h"
+#if defined(__DARWIN__)
+# define OS_INLINE    /* required for <libkern/ppc/OSByteOrder.h> */
+# include <mach/mach.h>
+#endif
+
+#include "vm/types.h"
+
 #include "mm/boehm.h"
 #include "mm/memory.h"
 #include "native/jni.h"
 #include "native/include/java_io_File.h"
 #include "native/include/java_lang_String.h"
 #include "native/include/java_lang_Process.h"
-#include "native/include/java_util_Properties.h"     /* java_lang_VMRuntime.h */
-#include "native/include/java_lang_VMRuntime.h"
 #include "toolbox/logging.h"
 #include "vm/builtin.h"
 #include "vm/exceptions.h"
 #include "vm/loader.h"
-#include "vm/tables.h"
-#include "vm/jit/asmpart.h"
+#include "vm/stringlocal.h"
+#include "vm/vm.h"
 
 
 /* this should work on BSD */
 #endif
 */
 
-#undef JOWENN_DEBUG
 
 /* should we run all finalizers on exit? */
 static bool finalizeOnExit = false;
 
-/* temporary property structure */
-
-typedef struct property property;
-
-struct property {
-       char     *key;
-       char     *value;
-       property *next;
-};
 
-static property *properties = NULL;
-
-
-/* create_property *************************************************************
-
-   Create a property entry for a command line property definition.
-
-*******************************************************************************/
-
-void create_property(char *key, char *value)
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    exitInternal
+ * Signature: (I)V
+ */
+JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
 {
-       property *p;
-
-       p = NEW(property);
-       p->key = key;
-       p->value = value;
-       p->next = properties;
-       properties = p;
-}
-
-
-/* insert_property *************************************************************
-
-   Used for inserting a property into the system's properties table. Method m
-   (usually put) and the properties table must be given.
-
-*******************************************************************************/
+       if (finalizeOnExit)
+               gc_finalize_all();
 
-static void insert_property(methodinfo *m, java_util_Properties *p, char *key,
-                                                       char *value)
-{
-       asm_calljavafunction(m,
-                                                p,
-                                                javastring_new_char(key),
-                                                javastring_new_char(value),
-                                                NULL);
+       vm_shutdown(par1);
 }
 
 
 /*
- * Class:     java_lang_VMRuntime
- * Method:    execInternal
- * Signature: ([Ljava/lang/String;[Ljava/lang/String;Ljava/io/File;)Ljava/lang/Process;
+ * Class:     java/lang/VMRuntime
+ * Method:    freeMemory
+ * Signature: ()J
  */
-JNIEXPORT java_lang_Process* JNICALL Java_java_lang_VMRuntime_execInternal(JNIEnv *env, jclass clazz, java_objectarray *cmd, java_objectarray *shellenv, java_io_File *workingdir)
+JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
 {
-       log_text("Java_java_lang_Runtime_execInternal called");
-
-       return NULL;
+       return gc_get_free_bytes();
 }
 
 
 /*
  * Class:     java/lang/VMRuntime
- * Method:    exitInternal
- * Signature: (I)V
+ * Method:    totalMemory
+ * Signature: ()J
  */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_exit(JNIEnv *env, jclass clazz, s4 par1)
+JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
 {
-       if (finalizeOnExit)
-               gc_finalize_all();
-
-       cacao_shutdown(par1);
+       return gc_get_heap_size();
 }
 
 
 /*
- * Class:     java/lang/Runtime
- * Method:    freeMemory
+ * Class:     java_lang_VMRuntime
+ * Method:    maxMemory
  * Signature: ()J
  */
-JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_freeMemory(JNIEnv *env, jclass clazz)
+JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
 {
-       return gc_get_free_bytes();
+       return gc_get_max_heap_size();
 }
 
 
 /*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    gc
  * Signature: ()V
  */
@@ -173,7 +138,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_gc(JNIEnv *env, jclass clazz)
 
 
 /*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    runFinalization
  * Signature: ()V
  */
@@ -184,21 +149,20 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalization(JNIEnv *env, jcl
 
 
 /*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    runFinalizersOnExit
  * Signature: (Z)V
  */
 JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizersOnExit(JNIEnv *env, jclass clazz, s4 value)
 {
-#ifdef __GNUC__
-#warning threading
-#endif
+       /* XXX threading */
+
        finalizeOnExit = value;
 }
 
 
 /*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    runFinalizationsForExit
  * Signature: ()V
  */
@@ -216,18 +180,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *e
 
 
 /*
- * Class:     java/lang/Runtime
- * Method:    totalMemory
- * Signature: ()J
- */
-JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_totalMemory(JNIEnv *env, jclass clazz)
-{
-       return gc_get_heap_size();
-}
-
-
-/*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    traceInstructions
  * Signature: (Z)V
  */
@@ -238,7 +191,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_traceInstructions(JNIEnv *env, j
 
 
 /*
- * Class:     java/lang/Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    traceMethodCalls
  * Signature: (Z)V
  */
@@ -295,247 +248,124 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, j
 
 
 /*
- * Class:     java_lang_Runtime
+ * Class:     java/lang/VMRuntime
  * Method:    nativeLoad
- * Signature: (Ljava/lang/String;)I
+ * Signature: (Ljava/lang/String;Ljava/lang/ClassLoader;)I
  */
-JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *par1)
+JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass clazz, java_lang_String *filename, java_lang_ClassLoader *loader)
 {
-       int retVal=0;
-
-#ifdef JOWENN_DEBUG
-       char *buffer;
-       int buffer_len;
-#endif
-       utf *data;
-
-#ifdef JOWENN_DEBUG
-       log_text("Java_java_lang_VMRuntime_nativeLoad");
+#if !defined(WITH_STATIC_CLASSPATH)
+       utf         *name;
+       lt_dlhandle  handle;
+       lt_ptr       onload;
+       s4           version;
 #endif
 
-       data = javastring_toutf(par1, 0);
-       
-       if (!data) {
-               log_text("nativeLoad: Error: empty string");
-               return 1;
+       if (filename == NULL) {
+               exceptions_throw_nullpointerexception();
+               return 0;
        }
-       
-#if JOWENN_DEBUG       
-       buffer_len = utf_strlen(data) + 40;
-
-       buffer = MNEW(char, buffer_len);
-       strcpy(buffer, "Java_java_lang_VMRuntime_nativeLoad:");
-       utf_sprint(buffer + strlen((char *) data), data);
-       log_text(buffer);       
-        
-  
-       MFREE(buffer, char, buffer_len);
-#endif
-
-#ifndef STATIC_CLASSPATH
-       /*here it could be interesting to store the references in a list eg for nicely cleaning up or for certain platforms*/
-        if (dlopen(data->text,RTLD_NOW | RTLD_GLOBAL)) {
-               /*log_text("LIBLOADED");*/
-                retVal=1;
-        }
-#else
-       retVal=1;
-#endif
 
-       return retVal;
-}
+#if defined(WITH_STATIC_CLASSPATH)
+       return 1;
+#else /* defined(WITH_STATIC_CLASSPATH) */
+       name = javastring_toutf(filename, 0);
 
+       /* is the library already loaded? */
 
-/*
- * Class:     java/lang/VMRuntime
- * Method:    nativeGetLibname
- * Signature: (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
- */
-JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_nativeGetLibname(JNIEnv *env, jclass clazz, java_lang_String *pathname, java_lang_String *libname)
-{
-       char *buffer;
-       int buffer_len;
-       utf *u;
-       java_lang_String *s;
+       if (native_hashtable_library_find(name, (java_objectheader *) loader))
+               return 1;
 
-       if (!libname) {
-               *exceptionptr = new_nullpointerexception();
-               return NULL;
-       }
+       /* try to open the library */
 
-       u = javastring_toutf(libname, 0);
-       
-       if (!u) {
-               log_text("nativeGetLibName: Error: empty string");
-               return 0;;
-       }
-       
-       buffer_len = utf_strlen(u) + 6 /*lib .so */ +1 /*0*/;
-       buffer = MNEW(char, buffer_len);
+       if (!(handle = lt_dlopen(name->text)))
+               return 0;
 
-       sprintf(buffer, "lib");
-       utf_sprint(buffer + 3, u);
-       strcat(buffer, ".so");
+       /* resolve JNI_OnLoad function */
 
-#ifdef JOWENN_DEBUG
-       log_text("nativeGetLibName:");
-       log_text(buffer);
-#endif
-       
-       s = javastring_new_char(buffer);        
+       if ((onload = lt_dlsym(handle, "JNI_OnLoad"))) {
+               JNIEXPORT s4 (JNICALL *JNI_OnLoad) (JavaVM *, void *);
+               JavaVM *vm;
 
-       MFREE(buffer, char, buffer_len);
+               JNI_OnLoad = (JNIEXPORT s4 (JNICALL *)(JavaVM *, void *)) (ptrint) onload;
 
-       return s;
-}
+               (*env)->GetJavaVM(env, &vm);
 
+               version = JNI_OnLoad(vm, NULL);
 
-/*
- * Class:     java_lang_VMRuntime
- * Method:    insertSystemProperties
- * Signature: (Ljava/util/Properties;)V
- */
-JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *env, jclass clazz, java_util_Properties *p)
-{
+               /* if the version is not 1.2 and not 1.4 the library cannot be loaded */
 
-#define BUFFERSIZE 200
-       methodinfo *m;
-       char cwd[BUFFERSIZE];
-       char *java_home;
-       char *user;
-       char *home;
-       struct utsname utsnamebuf;
-#if !defined(STATIC_CLASSPATH)
-       char *libpath;
-       s4    libpathlen;
-#endif
+               if ((version != JNI_VERSION_1_2) && (version != JNI_VERSION_1_4)) {
+                       lt_dlclose(handle);
 
-       if (!p) {
-               *exceptionptr = new_nullpointerexception();
-               return;
+                       return 0;
+               }
        }
 
-       /* get properties from system */
-
-       (void) getcwd(cwd, BUFFERSIZE);
-       java_home = getenv("JAVA_HOME");
-       user = getenv("USER");
-       home = getenv("HOME");
-       uname(&utsnamebuf);
-
-       /* search for method to add properties */
-
-       m = class_resolveclassmethod(p->header.vftbl->class,
-                                                                utf_new_char("put"),
-                                                                utf_new_char("(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"),
-                                                                clazz,
-                                                                true);
-
-       if (!m)
-               return;
-
-       insert_property(m, p, "java.version", VERSION);
-       insert_property(m, p, "java.vendor", "CACAO Team");
-       insert_property(m, p, "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/");
-       insert_property(m, p, "java.home", java_home ? java_home : "null");
-       insert_property(m, p, "java.vm.specification.version", "1.0");
-       insert_property(m, p, "java.vm.specification.vendor", "Sun Microsystems Inc.");
-       insert_property(m, p, "java.vm.specification.name", "Java Virtual Machine Specification");
-       insert_property(m, p, "java.vm.version", VERSION);
-       insert_property(m, p, "java.vm.vendor", "CACAO Team");
-       insert_property(m, p, "java.vm.name", "CACAO");
-       insert_property(m, p, "java.specification.version", "1.4");
-       insert_property(m, p, "java.specification.vendor", "Sun Microsystems Inc.");
-       insert_property(m, p, "java.specification.name", "Java Platform API Specification");
-       insert_property(m, p, "java.class.version", "48.0");
-       insert_property(m, p, "java.class.path", classpath);
-
-#if defined(STATIC_CLASSPATH)
-       insert_property(m, p, "java.library.path" , ".");
-#else
-       libpathlen = strlen(INSTALL_PREFIX) + strlen(CACAO_LIBRARY_PATH) + 1;
+       /* insert the library name into the library hash */
 
-       if (getenv("CACAO_LIB_OVERRIDE"))
-               libpathlen += strlen(getenv("CACAO_LIB_OVERRIDE")) + 1;
+       native_hashtable_library_add(name, (java_objectheader *) loader, handle);
 
-       if (getenv("LD_LIBRARY_PATH"))
-               libpathlen += strlen(getenv("LD_LIBRARY_PATH")) + 1;
+       return 1;
+#endif /* defined(WITH_STATIC_CLASSPATH) */
+}
 
-       libpath = MNEW(char, libpathlen);
 
-       if (getenv("CACAO_LIB_OVERRIDE")) {
-               strcat(libpath, getenv("CACAO_LIB_OVERRIDE"));
-               strcat(libpath, ":");
+/*
+ * Class:     java/lang/VMRuntime
+ * Method:    mapLibraryName
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT java_lang_String* JNICALL Java_java_lang_VMRuntime_mapLibraryName(JNIEnv *env, jclass clazz, java_lang_String *libname)
+{
+       utf              *u;
+       char             *buffer;
+       s4                buffer_len;
+       s4                dumpsize;
+       java_lang_String *s;
+
+       if (!libname) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
        }
 
-       strcat(libpath, INSTALL_PREFIX);
-       strcat(libpath, CACAO_LIBRARY_PATH);
+       u = javastring_toutf(libname, 0);
+
+       /* calculate length of library name */
 
-       if (getenv("LD_LIBRARY_PATH")) {
-               strcat(libpath, ":");
-               strcat(libpath, getenv("LD_LIBRARY_PATH"));
-       }
-       insert_property(m, p, "java.library.path", libpath);
+       buffer_len = strlen("lib");
 
-       MFREE(libpath, char, libpathlen);
-#endif
+       buffer_len += utf_strlen(u);
 
-       insert_property(m, p, "java.io.tmpdir", "/tmp");
-       insert_property(m, p, "java.compiler", "cacao.jit");
-       insert_property(m, p, "java.ext.dirs", "");
-       insert_property(m, p, "os.name", utsnamebuf.sysname);
-       insert_property(m, p, "os.arch", utsnamebuf.machine);
-       insert_property(m, p, "os.version", utsnamebuf.release);
-       insert_property(m, p, "file.separator", "/");
-       /* insert_property(m, p, "file.encoding", "null"); -- this must be set properly */
-       insert_property(m, p, "path.separator", ":");
-       insert_property(m, p, "line.separator", "\n");
-       insert_property(m, p, "user.name", user ? user : "null");
-       insert_property(m, p, "user.home", home ? home : "null");
-       insert_property(m, p, "user.dir", cwd ? cwd : "null");
-
-#ifdef USE_GTK
-       /* disable gthread-jni's portable native sync due to yet unresolved 
-          threading issues */
-       insert_property(m, p, "gnu.classpath.awt.gtk.portable.native.sync", "false");
+#if defined(__DARWIN__)
+       buffer_len += strlen(".dylib");
+#else
+       buffer_len += strlen(".so");
 #endif
 
-#if 0
-       /* how do we get them? */
-       { "user.language", "en" },
-       { "user.region", "US" },
-       { "user.country", "US" },
-       { "user.timezone", "Europe/Vienna" },
+       buffer_len += strlen("0");
 
-       /* XXX do we need this one? */
-       { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
-#endif
-       insert_property(m, p, "java.protocol.handler.pkgs", "gnu.java.net.protocol");
+       dumpsize = dump_size();
+       buffer = DMNEW(char, buffer_len);
 
-       /* insert properties defined on commandline */
+       /* generate library name */
 
-       while (properties) {
-               property *tp;
+       strcpy(buffer, "lib");
+       utf_strcat(buffer, u);
 
-               insert_property(m, p, properties->key, properties->value);
+#if defined(__DARWIN__)
+       strcat(buffer, ".dylib");
+#else
+       strcat(buffer, ".so");
+#endif
 
-               tp = properties;
-               properties = properties->next;
-               FREE(tp, property);
-       }
+       s = javastring_new_char(buffer);
 
-       return;
-}
+       /* release memory */
 
+       dump_release(dumpsize);
 
-/*
- * Class:     java_lang_VMRuntime
- * Method:    maxMemory
- * Signature: ()J
- */
-JNIEXPORT s8 JNICALL Java_java_lang_VMRuntime_maxMemory(JNIEnv *env, jclass clazz)
-{
-       return gc_get_max_heap_size();
+       return s;
 }