GNU header update.
[cacao.git] / src / native / vm / VMRuntime.c
index cac32f9eca933ce8cdccfd0612bde42ab04e2fb4..2e9c7083d4bc9e52d7808f0add0af4b54820298c 100644 (file)
@@ -1,9 +1,9 @@
-/* nat/Runtime.c - java/lang/Runtime
+/* native/vm/VMRuntime.c - java/lang/VMRuntime
 
-   Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
-   R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser,
-   M. Probst, S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck,
-   P. Tomsich, J. Wenninger
+   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
 
    This file is part of CACAO.
 
@@ -29,7 +29,7 @@
    Changes: Joseph Wenninger
             Christian Thalinger
 
-   $Id: VMRuntime.c 1449 2004-11-05 14:08:48Z twisti $
+   $Id: VMRuntime.c 1735 2004-12-07 14:33:27Z twisti $
 
 */
 
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/utsname.h>
-#include "exceptions.h"
-#include "main.h"
-#include "jni.h"
-#include "builtin.h"
-#include "exceptions.h"
-#include "loader.h"
-#include "native.h"
-#include "tables.h"
-#include "asmpart.h"
+
+#if !defined(STATIC_CLASSPATH)
+#include <dlfcn.h>
+#endif
+
+#include "config.h"
+#include "cacao/cacao.h"
 #include "mm/boehm.h"
+#include "mm/memory.h"
+#include "native/jni.h"
+#include "native/native.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 "toolbox/memory.h"
-#include "nat/java_io_File.h"
-#include "nat/java_lang_String.h"
-#include "nat/java_lang_Process.h"
-#include "nat/java_util_Properties.h"    /* needed for java_lang_Runtime.h */
-#include "nat/java_lang_VMRuntime.h"
+#include "vm/builtin.h"
+#include "vm/exceptions.h"
+#include "vm/loader.h"
+#include "vm/tables.h"
+#include "vm/jit/asmpart.h"
 
-#include "config.h"
-#ifndef STATIC_CLASSPATH
-#include <dlfcn.h>
+
+/* this should work on BSD */
+/*
+#if defined(__DARWIN__)
+#include <sys/sysctl.h>
 #endif
+*/
 
 #undef JOWENN_DEBUG
 
 /* should we run all finalizers on exit? */
 static bool finalizeOnExit = false;
 
-#define MAXPROPS 100
-#if 0
-static int activeprops = 29;
-
-
-/* insert all properties as defined in VMRuntime.java */
-
-static char *proplist[MAXPROPS][2] = {
-       { "java.version", VERSION },
-       { "java.vendor", "CACAO Team" },
-       { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
-       { "java.home", NULL },
-       { "java.vm.specification.version", "1.0" },
-
-       { "java.vm.specification.vendor", "Sun Microsystems Inc." },
-       { "java.vm.specification.name", "Java Virtual Machine Specification" },
-       { "java.vm.version", VERSION },
-       { "java.vm.vendor", "CACAO Team" },
-       { "java.vm.name", "CACAO" },
-
-       { "java.specification.version", "1.4" },
-       { "java.specification.vendor", "Sun Microsystems Inc." },
-       { "java.specification.name", "Java Platform API Specification" },
-       { "java.class.version", "48.0" },
-       { "java.class.path", NULL },
-
-       { "java.library.path" , NULL },
-       { "java.io.tmpdir", "/tmp"},
-       { "java.compiler", "cacao.jit" },
-       { "java.ext.dirs", NULL },
-       { "os.name", NULL },
-
-       { "os.arch", NULL },
-       { "os.version", NULL },
-       { "file.separator", "/" },
-       { "java.library.path", NULL},
-       { "java.class.version", "45.3" },
-
-       { "java.version", PACKAGE":"VERSION },
-       { "java.vendor", "CACAO Team" },
-       { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
-       { "java.vm.name", "CACAO"}, 
-       { "java.tmpdir", "/tmp/"},
-
-       { "java.io.tmpdir", "/tmp/"},
-       { "path.separator", ":" },
-       { "line.separator", "\n" },
-       { "user.name", NULL },
-       { "user.home", NULL },
-
-       { "user.dir",  NULL },
-       { "user.language", "en" },
-       { "user.region", "US" },
-       { "user.country", "US" },
-       { "user.timezone", "Europe/Vienna" },
+/* temporary property structure */
 
-       /* XXX do we need this one? */
-       { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
-};
-#endif
-static int activeprops = 20;  
-static char *proplist[MAXPROPS][2] = {
-       { "java.class.path", NULL },
-       { "java.home", NULL },
-       { "user.home", NULL },  
-       { "user.name", NULL },
-       { "user.dir",  NULL },
-                                
-       { "os.arch", NULL },
-       { "os.name", NULL },
-       { "os.version", NULL },
-        { "java.library.path",NULL},
-                                         
-       { "java.class.version", "45.3" },
-       { "java.version", PACKAGE":"VERSION },
-       { "java.vendor", "CACAO Team" },
-       { "java.vendor.url", "http://www.complang.tuwien.ac.at/java/cacao/" },
-       { "java.vm.name", "CACAO"}, 
-       { "java.tmpdir", "/tmp/"},
-       { "java.io.tmpdir", "/tmp/"},
-
-       { "path.separator", ":" },
-       { "file.separator", "/" },
-       { "line.separator", "\n" },
-       { "java.protocol.handler.pkgs", "gnu.java.net.protocol"}
+typedef struct property property;
+
+struct property {
+       char     *key;
+       char     *value;
+       property *next;
 };
 
-void attach_property(char *name, char *value)
+static property *properties = NULL;
+
+
+/* create_property *************************************************************
+
+   Create a property entry for a command line property definition.
+
+*******************************************************************************/
+
+void create_property(char *key, char *value)
 {
-       if (activeprops >= MAXPROPS)
-               panic("Too many properties defined");
+       property *p;
 
-       proplist[activeprops][0] = name;
-       proplist[activeprops][1] = value;
-       activeprops++;
+       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.
+
+*******************************************************************************/
+
+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);
 }
 
 
@@ -247,12 +206,12 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_runFinalizationForExit(JNIEnv *e
 {
 /*     if (finalizeOnExit) { */
 /*             gc_call(); */
-       //      gc_finalize_all();
+       /* gc_finalize_all(); */
 /*     } */
 /*     log_text("Java_java_lang_VMRuntime_runFinalizationForExit called"); */
-       //gc_finalize_all();
-       //gc_invoke_finalizers();
-       //gc_call();
+       /*gc_finalize_all();*/
+       /*gc_invoke_finalizers();*/
+       /*gc_call();*/
 }
 
 
@@ -302,6 +261,33 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_availableProcessors(JNIEnv *env, j
 #elif defined(_SC_NPROCESSORS_ONLN)
        return (s4) sysconf(_SC_NPROCESSORS_ONLN);
 
+#elif defined(__DARWIN__)
+       /* this should work in BSD */
+       /*
+       int ncpu, mib[2], rc;
+       size_t len;
+
+       mib[0] = CTL_HW;
+       mib[1] = HW_NCPU;
+       len = sizeof(ncpu);
+       rc = sysctl(mib, 2, &ncpu, &len, NULL, 0);
+
+       return (s4) ncpu;
+       */
+
+       host_basic_info_data_t hinfo;
+       mach_msg_type_number_t hinfo_count = HOST_BASIC_INFO_COUNT;
+       kern_return_t rc;
+
+       rc = host_info(mach_host_self(), HOST_BASIC_INFO,
+                                  (host_info_t) &hinfo, &hinfo_count);
+       if (rc != KERN_SUCCESS) {
+               return -1;
+       }
+
+    return (s4) hinfo.avail_cpus;
+
 #else
        return 1;
 #endif
@@ -317,11 +303,15 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass cla
 {
        int retVal=0;
 
+#ifdef JOWENN_DEBUG
        char *buffer;
        int buffer_len;
+#endif
        utf *data;
 
+#ifdef JOWENN_DEBUG
        log_text("Java_java_lang_VMRuntime_nativeLoad");
+#endif
 
        data = javastring_toutf(par1, 0);
        
@@ -330,9 +320,9 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass cla
                return 1;
        }
        
+#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);
@@ -340,12 +330,12 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass cla
         
   
        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");
+               /*log_text("LIBLOADED");*/
                 retVal=1;
         }
 #else
@@ -357,37 +347,46 @@ JNIEXPORT s4 JNICALL Java_java_lang_VMRuntime_nativeLoad(JNIEnv *env, jclass cla
 
 
 /*
- * Class:     java_lang_VMRuntime
+ * 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 *par1, java_lang_String *par2)
+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 *data;
-       java_lang_String *resultString; 
-       data = javastring_toutf(par2, 0);
+       utf *u;
+       java_lang_String *s;
+
+       if (!libname) {
+               *exceptionptr = new_nullpointerexception();
+               return NULL;
+       }
+
+       u = javastring_toutf(libname, 0);
        
-       if (!data) {
+       if (!u) {
                log_text("nativeGetLibName: Error: empty string");
                return 0;;
        }
        
-       buffer_len = utf_strlen(data) + 6 /*lib .so */ +1 /*0*/;
+       buffer_len = utf_strlen(u) + 6 /*lib .so */ +1 /*0*/;
        buffer = MNEW(char, buffer_len);
-       sprintf(buffer,"lib");
-       utf_sprint(buffer+3,data);
-       strcat(buffer,".so");
+
+       sprintf(buffer, "lib");
+       utf_sprint(buffer + 3, u);
+       strcat(buffer, ".so");
+
 #ifdef JOWENN_DEBUG
-        log_text("nativeGetLibName:");
+       log_text("nativeGetLibName:");
        log_text(buffer);
 #endif
        
-       resultString=javastring_new_char(buffer);       
+       s = javastring_new_char(buffer);        
 
        MFREE(buffer, char, buffer_len);
-       return resultString;
+
+       return s;
 }
 
 
@@ -400,55 +399,32 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *e
 {
 
 #define BUFFERSIZE 200
-       u4 i;
        methodinfo *m;
-       char buffer[BUFFERSIZE];
+       char cwd[BUFFERSIZE];
+       char *java_home;
+       char *user;
+       char *home;
        struct utsname utsnamebuf;
-
-#if 0
-       proplist[14][1] = classpath;
-       //proplist[1][1] = getenv("JAVA_HOME");
-
-       /* get properties from system */
-       uname(&utsnamebuf);
-       proplist[19][1] = utsnamebuf.sysname;
-       proplist[20][1] = utsnamebuf.machine;
-       proplist[21][1] = utsnamebuf.release;
-
-       proplist[25][1] = getenv("USER");
-       proplist[26][1] = getenv("HOME");
-       proplist[27][1] = getcwd(buffer, BUFFERSIZE);
-
-#if defined(STATIC_CLASSPATH)
-       proplist[23][1] = ".";
-#else
-       proplist[23][1] = getenv("LD_LIBRARY_PATH");
-#endif
-#endif
-       proplist[0][1] = classpath;
-       proplist[1][1] = getenv("JAVA_HOME");
-       proplist[2][1] = getenv("HOME");
-       proplist[3][1] = getenv("USER");
-       proplist[4][1] = getcwd(buffer, BUFFERSIZE);
-
-       /* get properties from system */
-       uname(&utsnamebuf);
-       proplist[5][1] = utsnamebuf.machine;
-       proplist[6][1] = utsnamebuf.sysname;
-       proplist[7][1] = utsnamebuf.release;
-
-#if defined(STATIC_CLASSPATH)
-       proplist[8][1] = ".";
-#else
-       proplist[8][1] = getenv("LD_LIBRARY_PATH");
+#if !defined(STATIC_CLASSPATH)
+       char *libpath;
+       s4    libpathlen;
 #endif
 
        if (!p) {
-               *exceptionptr = new_exception(string_java_lang_NullPointerException);
+               *exceptionptr = new_nullpointerexception();
                return;
        }
 
+       /* 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;"),
@@ -458,16 +434,88 @@ JNIEXPORT void JNICALL Java_java_lang_VMRuntime_insertSystemProperties(JNIEnv *e
        if (!m)
                return;
 
-       /* add the properties */
-       for (i = 0; i < activeprops; i++) {
-               if (proplist[i][1] == NULL)
-                       proplist[i][1] = "null";
+       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;
+
+       if (getenv("CACAO_LIB_OVERRIDE"))
+               libpathlen += strlen(getenv("CACAO_LIB_OVERRIDE")) + 1;
+
+       if (getenv("LD_LIBRARY_PATH"))
+               libpathlen += strlen(getenv("LD_LIBRARY_PATH")) + 1;
+
+       libpath = MNEW(char, libpathlen);
+
+       if (getenv("CACAO_LIB_OVERRIDE")) {
+               strcat(libpath, getenv("CACAO_LIB_OVERRIDE"));
+               strcat(libpath, ":");
+       }
+
+       strcat(libpath, INSTALL_PREFIX);
+       strcat(libpath, CACAO_LIBRARY_PATH);
+
+       if (getenv("LD_LIBRARY_PATH")) {
+               strcat(libpath, ":");
+               strcat(libpath, getenv("LD_LIBRARY_PATH"));
+       }
+       insert_property(m, p, "java.library.path", libpath);
+
+       MFREE(libpath, char, libpathlen);
+#endif
+
+       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");
+
+#if 0
+       /* how do we get them? */
+       { "user.language", "en" },
+       { "user.region", "US" },
+       { "user.country", "US" },
+       { "user.timezone", "Europe/Vienna" },
+
+       /* 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");
+
+       /* insert properties defined on commandline */
+
+       while (properties) {
+               property *tp;
+
+               insert_property(m, p, properties->key, properties->value);
 
-               asm_calljavafunction(m,
-                                                        p,
-                                                        javastring_new_char(proplist[i][0]),
-                                                        javastring_new_char(proplist[i][1]),
-                                                        NULL);
+               tp = properties;
+               properties = properties->next;
+               FREE(tp, property);
        }
 
        return;