* Removed all Id tags.
[cacao.git] / src / cacao / cacao.c
index 0a5bc942b2c522a8375505238476b6873ff54c6d..ac005387bfbc27aad3c8abd55b6ee0ed5f59559f 100644 (file)
@@ -1,6 +1,6 @@
 /* src/cacao/cacao.c - contains main() of cacao
 
-   Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+   Copyright (C) 1996-2005, 2006, 2007 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, J. Wenninger, Institut f. Computersprachen - TU Wien
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
    02110-1301, USA.
 
-   Contact: cacao@cacaojvm.org
-
-   Authors: Reinhard Grafl
-
-   Changes: Andi Krall
-            Mark Probst
-            Philipp Tomsich
-            Christian Thalinger
-
-   This module does the following tasks:
-     - Command line option handling
-     - Calling initialization routines
-     - Calling the class loader
-     - Running the main method
-
-   $Id: cacao.c 4396 2006-01-31 23:27:41Z twisti $
-
 */
 
 
 #include "config.h"
 
 #include <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "cacao/cacao.h"
-#include "mm/boehm.h"
-#include "mm/memory.h"
-#include "native/jni.h"
-#include "native/native.h"
-
-#if defined(ENABLE_JVMTI)
-#include "native/jvmti/jvmti.h"
-#include "native/jvmti/dbg.h"
-#include <sys/types.h>
-#include <signal.h>
-#include <sys/wait.h>
-#endif
-
-#include "toolbox/logging.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/finalizer.h"
-#include "vm/global.h"
-#include "vm/initialize.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/properties.h"
-#include "vm/signallocal.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
-#include "vm/jit/profile.h"
-
-#ifdef TYPEINFO_DEBUG_TEST
-#include "vm/jit/verify/typeinfo.h"
-#endif
-
-
-/* define heap sizes **********************************************************/
-
-#define HEAP_MAXSIZE      64 * 1024 * 1024  /* default 64MB                   */
-#define HEAP_STARTSIZE    2 * 1024 * 1024   /* default 2MB                    */
-#define STACK_SIZE        128 * 1024        /* default 128kB                  */
-
-#if defined(ENABLE_INTRP)
-u1 *intrp_main_stack;
-#endif
-
-
-/* CACAO related stuff ********************************************************/
-
-bool cacao_initializing;
-bool cacao_exiting;
-
-
-/* Invocation API variables ***************************************************/
-
-JavaVM *jvm;                        /* denotes a Java VM                      */
-JNIEnv *env;                        /* pointer to native method interface     */
-JDK1_1InitArgs vm_args;             /* JDK 1.1 VM initialization arguments    */
-
-
-char *mainstring;
-static classinfo *mainclass;
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-void **stackbottom = 0;
-#endif
-
-
-/* define command line options ************************************************/
-
-enum {
-       OPT_CLASSPATH,
-       OPT_D,
-       OPT_MS,
-       OPT_MX,
-       OPT_VERBOSE1,
-       OPT_VERBOSE,
-       OPT_VERBOSESPECIFIC,
-       OPT_VERBOSECALL,
-       OPT_NOIEEE,
-       OPT_SOFTNULL,
-       OPT_TIME,
-
-#if defined(ENABLE_STATISTICS)
-       OPT_STAT,
-#endif
-
-       OPT_LOG,
-       OPT_CHECK,
-       OPT_LOAD,
-       OPT_METHOD,
-       OPT_SIGNATURE,
-       OPT_SHOW,
-       OPT_ALL,
-       OPT_OLOOP,
-       OPT_INLINING,
-
-       OPT_VERBOSETC,
-       OPT_NOVERIFY,
-       OPT_LIBERALUTF,
-       OPT_VERBOSEEXCEPTION,
-       OPT_EAGER,
-
-#if defined(ENABLE_LSRA)
-       OPT_LSRA,
-#endif
-
-       OPT_JAR,
-       OPT_BOOTCLASSPATH,
-       OPT_BOOTCLASSPATH_A,
-       OPT_BOOTCLASSPATH_P,
-       OPT_VERSION,
-       OPT_SHOWVERSION,
-       OPT_FULLVERSION,
-
-       OPT_HELP,
-       OPT_X,
-
-       OPT_JIT,
-       OPT_INTRP,
-
-       OPT_PROF,
-       OPT_PROF_OPTION,
-
-#if defined(ENABLE_INTRP)
-       /* interpreter options */
-
-       OPT_NO_DYNAMIC,
-       OPT_NO_REPLICATION,
-       OPT_NO_QUICKSUPER,
-       OPT_STATIC_SUPERS,
-       OPT_TRACE,
-#endif
-
-       OPT_SS,
-
-#ifdef ENABLE_JVMTI
-       OPT_DEBUG,
-       OPT_AGENTLIB,
-       OPT_AGENTPATH,
-#endif
-
-       DUMMY
-};
-
-
-opt_struct opts[] = {
-       { "classpath",         true,  OPT_CLASSPATH },
-       { "cp",                true,  OPT_CLASSPATH },
-       { "D",                 true,  OPT_D },
-       { "noasyncgc",         false, OPT_IGNORE },
-       { "noverify",          false, OPT_NOVERIFY },
-       { "liberalutf",        false, OPT_LIBERALUTF },
-       { "v",                 false, OPT_VERBOSE1 },
-       { "verbose",           false, OPT_VERBOSE },
-       { "verbose:",          true,  OPT_VERBOSESPECIFIC },
-       { "verbosecall",       false, OPT_VERBOSECALL },
-       { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
-#ifdef TYPECHECK_VERBOSE
-       { "verbosetc",         false, OPT_VERBOSETC },
-#endif
-#if defined(__ALPHA__)
-       { "noieee",            false, OPT_NOIEEE },
-#endif
-       { "softnull",          false, OPT_SOFTNULL },
-       { "time",              false, OPT_TIME },
-#if defined(ENABLE_STATISTICS)
-       { "stat",              false, OPT_STAT },
-#endif
-       { "log",               true,  OPT_LOG },
-       { "c",                 true,  OPT_CHECK },
-       { "l",                 false, OPT_LOAD },
-       { "eager",             false, OPT_EAGER },
-       { "sig",               true,  OPT_SIGNATURE },
-       { "all",               false, OPT_ALL },
-       { "oloop",             false, OPT_OLOOP },
-#if defined(ENABLE_LSRA)
-       { "lsra",              false, OPT_LSRA },
-#endif
-       { "jar",               false, OPT_JAR },
-       { "version",           false, OPT_VERSION },
-       { "showversion",       false, OPT_SHOWVERSION },
-       { "fullversion",       false, OPT_FULLVERSION },
-       { "help",              false, OPT_HELP },
-       { "?",                 false, OPT_HELP },
-
-#if defined(ENABLE_INTRP)
-       /* interpreter options */
-
-       { "trace",             false, OPT_TRACE },
-       { "static-supers",     true,  OPT_STATIC_SUPERS },
-       { "no-dynamic",        false, OPT_NO_DYNAMIC },
-       { "no-replication",    false, OPT_NO_REPLICATION },
-       { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
-#endif
-
-       /* JVMTI Agent Command Line Options */
-#ifdef ENABLE_JVMTI
-       { "agentlib:",         true,  OPT_AGENTLIB },
-       { "agentpath:",        true,  OPT_AGENTPATH },
-#endif
-
-       /* X options */
-
-       { "X",                 false, OPT_X },
-       { "Xjit",              false, OPT_JIT },
-       { "Xint",              false, OPT_INTRP },
-       { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
-       { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
-       { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
-#ifdef ENABLE_JVMTI
-       { "Xdebug",            false, OPT_DEBUG },
-#endif 
-       { "Xms",               true,  OPT_MS },
-       { "Xmx",               true,  OPT_MX },
-       { "Xprof:",            true,  OPT_PROF_OPTION },
-       { "Xprof",             false, OPT_PROF },
-       { "Xss",               true,  OPT_SS },
-       { "ms",                true,  OPT_MS },
-       { "mx",                true,  OPT_MX },
-       { "ss",                true,  OPT_SS },
-
-       /* keep these at the end of the list */
 
-       { "i",                 true,  OPT_INLINING },
-       { "m",                 true,  OPT_METHOD },
-       { "s",                 true,  OPT_SHOW },
-
-       { NULL,                false, 0 }
-};
-
-
-/* usage ***********************************************************************
-
-   Prints the correct usage syntax to stdout.
-
-*******************************************************************************/
-
-static void usage(void)
-{
-       printf("Usage: cacao [-options] classname [arguments]\n");
-       printf("               (to run a class file)\n");
-       printf("       cacao [-options] -jar jarfile [arguments]\n");
-       printf("               (to run a standalone jar file)\n\n");
-
-       printf("Java options:\n");
-       printf("    -cp <path>               specify a path to look for classes\n");
-       printf("    -classpath <path>        specify a path to look for classes\n");
-       printf("    -D<name>=<value>         add an entry to the property list\n");
-       printf("    -verbose[:class|gc|jni]  enable specific verbose output\n");
-       printf("    -version                 print product version and exit\n");
-       printf("    -fullversion             print jpackage-compatible product version and exit\n");
-       printf("    -showversion             print product version and continue\n");
-       printf("    -help, -?                print this help message\n");
-       printf("    -X                       print help on non-standard Java options\n\n");
-
-#ifdef ENABLE_JVMTI
-       printf("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent\n");
-       printf("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent\n");
+#if defined(ENABLE_LIBJVM)
+# include <ltdl.h>
 #endif
 
-       printf("CACAO options:\n");
-       printf("    -v                       write state-information\n");
-       printf("    -verbose                 write more information\n");
-       printf("    -verbosegc               write message for each GC\n");
-       printf("    -verbosecall             write message for each call\n");
-       printf("    -verboseexception        write message for each step of stack unwinding\n");
-#ifdef TYPECHECK_VERBOSE
-       printf("    -verbosetc               write debug messages while typechecking\n");
-#endif
-#if defined(__ALPHA__)
-       printf("    -noieee                  don't use ieee compliant arithmetic\n");
+#if defined(WITH_JRE_LAYOUT)
+# include <errno.h>
+# include <libgen.h>
+# include <unistd.h>
 #endif
-       printf("    -noverify                don't verify classfiles\n");
-       printf("    -liberalutf              don't warn about overlong UTF-8 sequences\n");
-       printf("    -softnull                use software nullpointer check\n");
-       printf("    -time                    measure the runtime\n");
-#if defined(ENABLE_STATISTICS)
-       printf("    -stat                    detailed compiler statistics\n");
-#endif
-       printf("    -log logfile             specify a name for the logfile\n");
-       printf("    -c(heck)b(ounds)         don't check array bounds\n");
-       printf("            s(ync)           don't check for synchronization\n");
-       printf("    -oloop                   optimize array accesses in loops\n"); 
-       printf("    -l                       don't start the class after loading\n");
-       printf("    -eager                   perform eager class loading and linking\n");
-       printf("    -all                     compile all methods, no execution\n");
-       printf("    -m                       compile only a specific method\n");
-       printf("    -sig                     specify signature for a specific method\n");
-       printf("    -s(how)a(ssembler)       show disassembled listing\n");
-       printf("           c(onstants)       show the constant pool\n");
-       printf("           d(atasegment)     show data segment listing\n");
-       printf("           e(xceptionstubs)  show disassembled exception stubs (only with -sa)\n");
-       printf("           i(ntermediate)    show intermediate representation\n");
-       printf("           m(ethods)         show class fields and methods\n");
-       printf("           n(ative)          show disassembled native stubs\n");
-       printf("           u(tf)             show the utf - hash\n");
-       printf("    -i     n(line)           activate inlining\n");
-       printf("           v(irtual)         inline virtual methods (uses/turns rt option on)\n");
-       printf("           e(exception)      inline methods with exceptions\n");
-       printf("           p(aramopt)        optimize argument renaming\n");
-       printf("           o(utsiders)       inline methods of foreign classes\n");
-#if defined(ENABLE_LSRA)
-       printf("    -lsra                    use linear scan register allocation\n");
-#endif
-
-       /* exit with error code */
-
-       exit(1);
-}   
-
-
-static void Xusage(void)
-{
-#if defined(ENABLE_JIT)
-       printf("    -Xjit             JIT mode execution (default)\n");
-#endif
-#if defined(ENABLE_INTRP)
-       printf("    -Xint             interpreter mode execution\n");
-#endif
-       printf("    -Xbootclasspath:<zip/jar files and directories separated by :>\n");
-    printf("                      value is set as bootstrap class path\n");
-       printf("    -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
-       printf("                      value is appended to the bootstrap class path\n");
-       printf("    -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
-       printf("                      value is prepended to the bootstrap class path\n");
-       printf("    -Xms<size>        set the initial size of the heap (default: 2MB)\n");
-       printf("    -Xmx<size>        set the maximum size of the heap (default: 64MB)\n");
-       printf("    -Xss<size>        set the thread stack size (default: 128kB)\n");
-       printf("    -Xprof[:bb]       collect and print profiling data\n");
-#if defined(ENABLE_JVMTI)
-       printf("    -Xdebug<transport> enable remote debugging\n");
-#endif 
-
-       /* exit with error code */
-
-       exit(1);
-}   
-
-
-/* version *********************************************************************
-
-   Only prints cacao version information.
-
-*******************************************************************************/
-
-static void version(void)
-{
-       printf("java version \""JAVA_VERSION"\"\n");
-       printf("CACAO version "VERSION"\n");
-
-       printf("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,\n");
-       printf("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,\n");
-       printf("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,\n");
-       printf("J. Wenninger, Institut f. Computersprachen - TU Wien\n\n");
-
-       printf("This program is free software; you can redistribute it and/or\n");
-       printf("modify it under the terms of the GNU General Public License as\n");
-       printf("published by the Free Software Foundation; either version 2, or (at\n");
-       printf("your option) any later version.\n\n");
-
-       printf("This program is distributed in the hope that it will be useful, but\n");
-       printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
-       printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n");
-       printf("General Public License for more details.\n");
-}
-
-
-/* fullversion *****************************************************************
-
-   Prints a Sun compatible version information (required e.g. by
-   jpackage, www.jpackage.org).
-
-*******************************************************************************/
-
-static void fullversion(void)
-{
-       printf("java full version \"cacao-"JAVA_VERSION"\"\n");
-
-       /* exit normally */
-
-       exit(0);
-}
-
 
-#ifdef TYPECHECK_STATISTICS
-void typecheck_print_statistics(FILE *file);
-#endif
+#include <stdlib.h>
+#include <string.h>
 
-/* setup_debugger_process *****************************************************
+#include "vm/types.h"
 
-   Helper function to start JDWP threads
+#include "native/jni.h"
 
-*******************************************************************************/
 #if defined(ENABLE_JVMTI)
-
-static void setup_debugger_process(char* transport) {
-       java_objectheader *o;
-       methodinfo *m;
-       java_lang_String  *s;
-
-       /* new gnu.classpath.jdwp.Jdwp() */
-       mainclass = 
-               load_class_from_sysloader(utf_new_char("gnu.classpath.jdwp.Jdwp"));
-       if (!mainclass)
-               throw_main_exception_exit();
-
-       o = builtin_new(mainclass);
-
-       if (!o)
-               throw_main_exception_exit();
-       
-       m = class_resolveclassmethod(mainclass,
-                                                                utf_init, 
-                                                                utf_java_lang_String__void,
-                                                                class_java_lang_Object,
-                                                                true);
-       if (!m)
-               throw_main_exception_exit();
-
-       ASM_CALLJAVAFUNCTION(m, o, NULL, NULL, NULL);
-
-       /* configure(transport,NULL) */
-       m = class_resolveclassmethod(
-               mainclass, utf_new_char("configure"), 
-               utf_new_char("(Ljava/lang/String;Ljava/lang/Thread;)V"),
-               class_java_lang_Object,
-               false);
-
-
-       s = javastring_new_char(transport);
-
-       ASM_CALLJAVAFUNCTION(m, o, s, NULL, NULL);
-
-       if (!m)
-               throw_main_exception_exit();
-
-       /* _doInitialization */
-       m = class_resolveclassmethod(mainclass,
-                                                                utf_new_char("_doInitialization"), 
-                                                                utf_new_char("()V"),
-                                                                mainclass,
-                                                                false);
-       
-       if (!m)
-               throw_main_exception_exit();
-
-       ASM_CALLJAVAFUNCTION(m, o, NULL, NULL, NULL);
-}
+# include "native/jvmti/jvmti.h"
+# include "native/jvmti/cacaodbg.h"
 #endif
 
+#include "vm/vm.h"
 
-/* getmainclassfromjar *********************************************************
-
-   Gets the name of the main class form a JAR's manifest file.
-
-*******************************************************************************/
-
-static char *getmainclassnamefromjar(char *mainstring)
-{
-       classinfo         *c;
-       java_objectheader *o;
-       methodinfo        *m;
-       java_lang_String  *s;
-
-       c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
-
-       if (!c)
-               throw_main_exception_exit();
-       
-       /* create JarFile object */
-
-       o = builtin_new(c);
-
-       if (!o)
-               throw_main_exception_exit();
-
-
-       m = class_resolveclassmethod(c,
-                                                                utf_init, 
-                                                                utf_java_lang_String__void,
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (!m)
-               throw_main_exception_exit();
-
-       s = javastring_new_char(mainstring);
-
-       ASM_CALLJAVAFUNCTION(m, o, s, NULL, NULL);
-
-       if (*exceptionptr)
-               throw_main_exception_exit();
-
-       /* get manifest object */
-
-       m = class_resolveclassmethod(c,
-                                                                utf_new_char("getManifest"), 
-                                                                utf_new_char("()Ljava/util/jar/Manifest;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (!m)
-               throw_main_exception_exit();
-
-       ASM_CALLJAVAFUNCTION_ADR(o, m, o, NULL, NULL, NULL);
-
-       if (!o) {
-               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
-               cacao_exit(1);
-       }
-
-
-       /* get Main Attributes */
-
-       m = class_resolveclassmethod(o->vftbl->class,
-                                                                utf_new_char("getMainAttributes"), 
-                                                                utf_new_char("()Ljava/util/jar/Attributes;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (!m)
-               throw_main_exception_exit();
-
-       ASM_CALLJAVAFUNCTION_ADR(o, m, o, NULL, NULL, NULL);
-
-       if (!o) {
-               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
-               cacao_exit(1);
-       }
-
-
-       /* get property Main-Class */
-
-       m = class_resolveclassmethod(o->vftbl->class,
-                                                                utf_new_char("getValue"), 
-                                                                utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
-                                                                class_java_lang_Object,
-                                                                true);
-
-       if (!m)
-               throw_main_exception_exit();
 
-       s = javastring_new_char("Main-Class");
+/* forward declarations *******************************************************/
 
-       ASM_CALLJAVAFUNCTION_ADR(o, m, o, s, NULL, NULL);
-
-       if (!o)
-               throw_main_exception_exit();
-
-       return javastring_tochar(o);
-}
-
-
-void exit_handler(void);
+static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv);
 
 
 /* main ************************************************************************
@@ -616,932 +67,117 @@ void exit_handler(void);
 
 int main(int argc, char **argv)
 {
-       s4 i, j, k;
-       void *dummy;
-       
-       /* local variables ********************************************************/
-   
-       char logfilename[200] = "";
-       u4 heapmaxsize;
-       u4 heapstartsize;
-       char *cp;
-       s4    cplen;
-       bool startit = true;
-       char *specificmethodname = NULL;
-       char *specificsignature = NULL;
-       bool jar = false;
-#if defined(ENABLE_JVMTI)
-       bool dbg = false;
-       char *transport;
-       int waitval;
+#if defined(ENABLE_LIBJVM) && !defined(WITH_STATIC_CLASSPATH)
+       char           *path;
 #endif
 
+#if defined(ENABLE_LIBJVM)     
+       /* Variables for JNI_CreateJavaVM dlopen call. */
+       lt_dlhandle     libjvm_handle;
+       lt_ptr          libjvm_vm_createjvm;
+       lt_ptr          libjvm_vm_run;
+       const char     *lterror;
 
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       stackbottom = &dummy;
+       bool (*vm_createjvm)(JavaVM **, void **, void *);
+       void (*vm_run)(JavaVM *, JavaVMInitArgs *);
 #endif
-       
-       if (atexit(exit_handler))
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Unable to register exit_handler");
 
-       /* initialize global variables */
+       JavaVM         *vm;                 /* denotes a Java VM                  */
+       JNIEnv         *env;
+       JavaVMInitArgs *vm_args;
 
-       cacao_exiting = false;
+       /* prepare the options */
 
+       vm_args = cacao_options_prepare(argc, argv);
+       
+       /* load and initialize a Java VM, return a JNI interface pointer in env */
 
-       /************ Collect info from the environment ************************/
-
-#if defined(DISABLE_GC)
-       nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
-#endif
-
-       /* set the bootclasspath */
-
-       cp = getenv("BOOTCLASSPATH");
-
-       if (cp) {
-               bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
-               strcpy(bootclasspath, cp);
+#if defined(ENABLE_LIBJVM) && !defined(WITH_STATIC_CLASSPATH)
+# if defined(WITH_JRE_LAYOUT)
+       /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
 
-       } else {
-               cplen = strlen(CACAO_VM_ZIP_PATH) +
-                       strlen(":") +
-                       strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
-                       strlen("0");
+       path = malloc(sizeof(char) * 4096);
 
-               bootclasspath = MNEW(char, cplen);
-               strcat(bootclasspath, CACAO_VM_ZIP_PATH);
-               strcat(bootclasspath, ":");
-               strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
+       if (readlink("/proc/self/exe", path, 4095) == -1) {
+               fprintf(stderr, "main: readlink failed: %s\n", strerror(errno));
+               abort();
        }
 
+       /* get the path of the current executable */
 
-       /* set the classpath */
-
-       cp = getenv("CLASSPATH");
-
-       if (cp) {
-               classpath = MNEW(char, strlen(cp) + strlen("0"));
-               strcat(classpath, cp);
+       path = dirname(path);
 
-       } else {
-               classpath = MNEW(char, strlen(".") + strlen("0"));
-               strcpy(classpath, ".");
+       if ((strlen(path) + strlen("/../lib/libjvm") + strlen("0")) > 4096) {
+               fprintf(stderr, "main: libjvm name to long for buffer\n");
+               abort();
        }
 
+       /* concatinate the library name */
 
-       /***************** Interpret the command line *****************/
-   
-       checknull = false;
-       opt_noieee = false;
-
-       heapmaxsize = HEAP_MAXSIZE;
-       heapstartsize = HEAP_STARTSIZE;
-       opt_stacksize = STACK_SIZE;
-
-       /* initialize properties before commandline handling */
-
-       if (!properties_init())
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Unable to init properties");
-
-       while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
-               switch (i) {
-               case OPT_IGNORE:
-                       break;
-                       
-               case OPT_BOOTCLASSPATH:
-                       /* Forget default bootclasspath and set the argument as new boot  */
-                       /* classpath.                                                     */
-                       MFREE(bootclasspath, char, strlen(bootclasspath));
-
-                       bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
-                       strcpy(bootclasspath, opt_arg);
-                       break;
-
-               case OPT_BOOTCLASSPATH_A:
-                       /* append to end of bootclasspath */
-                       cplen = strlen(bootclasspath);
-
-                       bootclasspath = MREALLOC(bootclasspath,
-                                                                        char,
-                                                                        cplen,
-                                                                        cplen + strlen(":") +
-                                                                        strlen(opt_arg) + strlen("0"));
-
-                       strcat(bootclasspath, ":");
-                       strcat(bootclasspath, opt_arg);
-                       break;
-
-               case OPT_BOOTCLASSPATH_P:
-                       /* prepend in front of bootclasspath */
-                       cp = bootclasspath;
-                       cplen = strlen(cp);
-
-                       bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
-                                                                cplen + strlen("0"));
-
-                       strcpy(bootclasspath, opt_arg);
-                       strcat(bootclasspath, ":");
-                       strcat(bootclasspath, cp);
-
-                       MFREE(cp, char, cplen);
-                       break;
-
-               case OPT_CLASSPATH:
-                       /* forget old classpath and set the argument as new classpath */
-                       MFREE(classpath, char, strlen(classpath));
-
-                       classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
-                       strcpy(classpath, opt_arg);
-                       break;
-
-               case OPT_JAR:
-                       jar = true;
-                       break;
-
-#if defined(ENABLE_JVMTI)
-               case OPT_DEBUG:
-                       dbg = true;
-                       transport = opt_arg;
-                       break;
-
-               case OPT_AGENTPATH:
-               case OPT_AGENTLIB:
-                       set_jvmti_phase(JVMTI_PHASE_ONLOAD);
-                       agentload(opt_arg);
-                       set_jvmti_phase(JVMTI_PHASE_PRIMORDIAL);
-                       break;
-#endif
-                       
-               case OPT_D:
-                       {
-                               for (j = 0; j < strlen(opt_arg); j++) {
-                                       if (opt_arg[j] == '=') {
-                                               opt_arg[j] = '\0';
-                                               properties_add(opt_arg, opt_arg + j + 1);
-                                               goto didit;
-                                       }
-                               }
-
-                               /* if no '=' is given, just create an empty property */
-
-                               properties_add(opt_arg, "");
-                                       
-                       didit:
-                               ;
-                       }       
-                       break;
-
-               case OPT_MX:
-               case OPT_MS:
-               case OPT_SS:
-                       {
-                               char c;
-                               c = opt_arg[strlen(opt_arg) - 1];
-
-                               if (c == 'k' || c == 'K') {
-                                       j = 1024 * atoi(opt_arg);
-
-                               } else if (c == 'm' || c == 'M') {
-                                       j = 1024 * 1024 * atoi(opt_arg);
-
-                               } else
-                                       j = atoi(opt_arg);
-
-                               if (i == OPT_MX)
-                                       heapmaxsize = j;
-                               else if (i == OPT_MS)
-                                       heapstartsize = j;
-                               else
-                                       opt_stacksize = j;
-                       }
-                       break;
-
-               case OPT_VERBOSE1:
-                       opt_verbose = true;
-                       break;
-
-               case OPT_VERBOSE:
-                       opt_verbose = true;
-                       loadverbose = true;
-                       linkverbose = true;
-                       initverbose = true;
-                       compileverbose = true;
-                       break;
-
-               case OPT_VERBOSESPECIFIC:
-                       if (strcmp("class", opt_arg) == 0)
-                               opt_verboseclass = true;
-
-                       else if (strcmp("gc", opt_arg) == 0)
-                               opt_verbosegc = true;
-
-                       else if (strcmp("jni", opt_arg) == 0)
-                               opt_verbosejni = true;
-                       break;
-
-               case OPT_VERBOSEEXCEPTION:
-                       opt_verboseexception = true;
-                       break;
-
-#ifdef TYPECHECK_VERBOSE
-               case OPT_VERBOSETC:
-                       typecheckverbose = true;
-                       break;
-#endif
-                               
-               case OPT_VERBOSECALL:
-                       runverbose = true;
-                       break;
-
-               case OPT_VERSION:
-                       version();
-                       exit(0);
-                       break;
-
-               case OPT_FULLVERSION:
-                       fullversion();
-                       break;
-
-               case OPT_SHOWVERSION:
-                       version();
-                       break;
-
-               case OPT_NOIEEE:
-                       opt_noieee = true;
-                       break;
-
-               case OPT_NOVERIFY:
-                       opt_verify = false;
-                       break;
-
-               case OPT_LIBERALUTF:
-                       opt_liberalutf = true;
-                       break;
-
-               case OPT_SOFTNULL:
-                       checknull = true;
-                       break;
-
-               case OPT_TIME:
-                       getcompilingtime = true;
-                       getloadingtime = true;
-                       break;
-                                       
-#if defined(ENABLE_STATISTICS)
-               case OPT_STAT:
-                       opt_stat = true;
-                       break;
-#endif
-                                       
-               case OPT_LOG:
-                       strcpy(logfilename, opt_arg);
-                       break;
-                       
-               case OPT_CHECK:
-                       for (j = 0; j < strlen(opt_arg); j++) {
-                               switch (opt_arg[j]) {
-                               case 'b':
-                                       checkbounds = false;
-                                       break;
-                               case 's':
-                                       checksync = false;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-               case OPT_LOAD:
-                       startit = false;
-                       makeinitializations = false;
-                       break;
-
-               case OPT_EAGER:
-                       opt_eager = true;
-                       break;
-
-               case OPT_METHOD:
-                       startit = false;
-                       specificmethodname = opt_arg;
-                       makeinitializations = false;
-                       break;
-                       
-               case OPT_SIGNATURE:
-                       specificsignature = opt_arg;
-                       break;
-                       
-               case OPT_ALL:
-                       compileall = true;
-                       startit = false;
-                       makeinitializations = false;
-                       break;
-                       
-               case OPT_SHOW:       /* Display options */
-                       for (j = 0; j < strlen(opt_arg); j++) {         
-                               switch (opt_arg[j]) {
-                               case 'a':
-                                       opt_showdisassemble = true;
-                                       compileverbose = true;
-                                       break;
-                               case 'c':
-                                       showconstantpool = true;
-                                       break;
-                               case 'd':
-                                       opt_showddatasegment = true;
-                                       break;
-                               case 'e':
-                                       opt_showexceptionstubs = true;
-                                       break;
-                               case 'i':
-                                       opt_showintermediate = true;
-                                       compileverbose = true;
-                                       break;
-                               case 'm':
-                                       showmethods = true;
-                                       break;
-                               case 'n':
-                                       opt_shownativestub = true;
-                                       break;
-                               case 'u':
-                                       showutf = true;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-                       
-               case OPT_OLOOP:
-                       opt_loops = true;
-                       break;
-
-               case OPT_INLINING:
-                       for (j = 0; j < strlen(opt_arg); j++) {         
-                               switch (opt_arg[j]) {
-                               case 'n':
-                                    /* define in options.h; Used in main.c, jit.c & inline.c */
-                                       /* inlining is currently deactivated */
-                                       break;
-                               case 'v':
-                                       inlinevirtuals = true;
-                                       break;
-                               case 'e':
-                                       inlineexceptions = true;
-                                       break;
-                               case 'p':
-                                       inlineparamopt = true;
-                                       break;
-                               case 'o':
-                                       inlineoutsiders = true;
-                                       break;
-                               default:
-                                       usage();
-                               }
-                       }
-                       break;
-
-#if defined(ENABLE_LSRA)
-               case OPT_LSRA:
-                       opt_lsra = true;
-                       break;
-#endif
-
-               case OPT_HELP:
-                       usage();
-                       break;
-
-               case OPT_X:
-                       Xusage();
-                       break;
-
-               case OPT_PROF_OPTION:
-                       /* use <= to get the last \0 too */
-
-                       for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
-                               if (opt_arg[j] == ',')
-                                       opt_arg[j] = '\0';
-
-                               if (opt_arg[j] == '\0') {
-                                       if (strcmp("bb", opt_arg + k) == 0)
-                                               opt_prof_bb = true;
-
-                                       else {
-                                               printf("Unknown option: -Xprof:%s\n", opt_arg + k);
-                                               usage();
-                                       }
-
-                                       /* set k to next char */
-
-                                       k = j + 1;
-                               }
-                       }
-                       /* fall through */
-
-               case OPT_PROF:
-                       opt_prof = true;
-                       break;
-
-               case OPT_JIT:
-#if defined(ENABLE_JIT)
-                       opt_jit = true;
-#else
-                       printf("-Xjit option not enabled.\n");
-                       exit(1);
-#endif
-                       break;
-
-               case OPT_INTRP:
-#if defined(ENABLE_INTRP)
-                       opt_intrp = true;
-#else
-                       printf("-Xint option not enabled.\n");
-                       exit(1);
-#endif
-                       break;
-
-#if defined(ENABLE_INTRP)
-               case OPT_STATIC_SUPERS:
-                       opt_static_supers = atoi(opt_arg);
-                       break;
-
-               case OPT_NO_DYNAMIC:
-                       opt_no_dynamic = true;
-                       break;
-
-               case OPT_NO_REPLICATION:
-                       opt_no_replication = true;
-                       break;
-
-               case OPT_NO_QUICKSUPER:
-                       opt_no_quicksuper = true;
-                       break;
-
-               case OPT_TRACE:
-                       vm_debug = true;
-                       break;
-#endif
+       strcat(path, "/../lib/libjvm");
+# else
+       path = CACAO_LIBDIR"/libjvm";
+# endif
 
-               default:
-                       printf("Unknown option: %s\n", argv[opt_ind]);
-                       usage();
-               }
+       if (lt_dlinit()) {
+               fprintf(stderr, "main: lt_dlinit failed: %s\n", lt_dlerror());
+               abort();
        }
 
-       if (opt_ind >= argc)
-               usage();
-
+       /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
+          If not found, try the absolute path. */
 
-       /* transform dots into slashes in the class name */
+       if (!(libjvm_handle = lt_dlopenext("libjvm"))) {
+               /* save the error message */
 
-       mainstring = argv[opt_ind++];
+               lterror = strdup(lt_dlerror());
 
-       if (!jar) { 
-        /* do not mangle jar filename */
+               if (!(libjvm_handle = lt_dlopenext(path))) {
+                       /* print the first error message too */
 
-               for (i = strlen(mainstring) - 1; i >= 0; i--) {
-                       if (mainstring[i] == '.') mainstring[i] = '/';
-               }
+                       fprintf(stderr, "main: lt_dlopenext failed: %s\n", lterror);
 
-       } else {
-               /* put jarfile in classpath */
+                       /* and now the current one */
 
-               cp = classpath;
+                       fprintf(stderr, "main: lt_dlopenext failed: %s\n", lt_dlerror());
+                       abort();
+               }
 
-               classpath = MNEW(char, strlen(mainstring) + strlen(":") +
-                                                strlen(classpath) + strlen("0"));
+               /* free the error string */
 
-               strcpy(classpath, mainstring);
-               strcat(classpath, ":");
-               strcat(classpath, cp);
-               
-               MFREE(cp, char, strlen(cp));
+               free((void *) lterror);
        }
 
-       /**************************** Program start *****************************/
-
-       log_init(logfilename);
-
-       if (opt_verbose)
-               log_text("CACAO started -------------------------------------------------------");
-
-       /* initialize JavaVM */
-
-       vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
-
-       /* Get the default initialization arguments and set the class path */
-
-       JNI_GetDefaultJavaVMInitArgs(&vm_args);
-
-       vm_args.minHeapSize = heapstartsize;
-       vm_args.maxHeapSize = heapmaxsize;
-
-       vm_args.classpath = classpath;
-       /* load and initialize a Java VM, return a JNI interface pointer in env */
-
-       JNI_CreateJavaVM(&jvm, &env, &vm_args);
-
-#if defined(ENABLE_JVMTI)
-       set_jvmti_phase(JVMTI_PHASE_START);
-#endif
-
-       /* initialize the garbage collector */
-
-       gc_init(heapmaxsize, heapstartsize);
-
-#if defined(ENABLE_INTRP)
-       /* allocate main thread stack */
-
-       if (opt_intrp) {
-               intrp_main_stack = (u1 *) alloca(opt_stacksize);
-               MSET(intrp_main_stack, 0, u1, opt_stacksize);
+       if (!(libjvm_vm_createjvm = lt_dlsym(libjvm_handle, "vm_createjvm"))) {
+               fprintf(stderr, "main: lt_dlsym failed: %s\n", lt_dlerror());
+               abort();
        }
-#endif
-
-       cacao_initializing = true;
-
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-       threads_preinit();
-#endif
-       initLocks();
-#endif
-
-       /* initialize the string hashtable stuff: lock (must be done
-          _after_ threads_preinit) */
-
-       if (!string_init())
-               throw_main_exception_exit();
-
-       /* initialize the utf8 hashtable stuff: lock, often used utf8
-          strings (must be done _after_ threads_preinit) */
-
-       if (!utf8_init())
-               throw_main_exception_exit();
-
-       /* initialize the classcache hashtable stuff: lock, hashtable
-          (must be done _after_ threads_preinit) */
-
-       if (!classcache_init())
-               throw_main_exception_exit();
-
-       /* initialize the loader with bootclasspath (must be done _after_
-          thread_preinit) */
-
-       if (!suck_init())
-               throw_main_exception_exit();
-
-       suck_add_from_property("java.endorsed.dirs");
-       suck_add(bootclasspath);
-
-       /* initialize the memory subsystem (must be done _after_
-          threads_preinit) */
-
-       if (!memory_init())
-               throw_main_exception_exit();
-
-       /* initialize the finalizer stuff: lock, linked list (must be done
-          _after_ threads_preinit) */
-
-       if (!finalizer_init())
-               throw_main_exception_exit();
-
-       /* install architecture dependent signal handler used for exceptions */
-
-       signal_init();
-
-       /* initialize the codegen subsystems */
-
-       codegen_init();
-
-       /* initializes jit compiler */
-
-       jit_init();
-
-       /* machine dependent initialization */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       if (opt_intrp)
-               intrp_md_init();
-       else
-# endif
-               md_init();
-#else
-       intrp_md_init();
-#endif
-
-       /* initialize the loader subsystems (must be done _after_
-       classcache_init) */
-
-       if (!loader_init((u1 *) &dummy))
-               throw_main_exception_exit();
-
-       if (!linker_init())
-               throw_main_exception_exit();
-
-       if (!native_init())
-               throw_main_exception_exit();
-
-       if (!exceptions_init())
-               throw_main_exception_exit();
-
-       if (!builtin_init())
-               throw_main_exception_exit();
-
-#if defined(USE_THREADS)
-       if (!threads_init((u1 *) &dummy))
-               throw_main_exception_exit();
-#endif
-
-       /* That's important, otherwise we get into trouble, if the Runtime
-          static initializer is called before (circular dependency. This
-          is with classpath 0.09. Another important thing is, that this
-          has to happen after initThreads!!! */
-
-       if (!initialize_class(class_java_lang_System))
-               throw_main_exception_exit();
-
-       /* JNI init creates a Java object (this means running Java code) */
-
-       if (!jni_init())
-               throw_main_exception_exit();
-
-#if defined(USE_THREADS)
-       /* finally, start the finalizer thread */
-
-       if (!finalizer_start_thread())
-               throw_main_exception_exit();
-#endif
-
-       cacao_initializing = false;
-
-
-       /* start worker routines **************************************************/
-
-       if (startit) {
-               classinfo        *mainclass;    /* java/lang/Class                    */
-               methodinfo       *m;
-               java_objectarray *a; 
-               s4                status;
-
-               /* set return value to OK */
-
-               status = 0;
-
-               if (jar) {
-                       /* open jar file with java.util.jar.JarFile */
-                       mainstring = getmainclassnamefromjar(mainstring);
-               }
-
-               /* load the main class */
-
-               if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
-                       throw_main_exception_exit();
-
-               /* error loading class, clear exceptionptr for new exception */
-
-               if (*exceptionptr || !mainclass) {
-/*                     *exceptionptr = NULL; */
-
-/*                     *exceptionptr = */
-/*                             new_exception_message(string_java_lang_NoClassDefFoundError, */
-/*                                                                       mainstring); */
-                       throw_main_exception_exit();
-               }
-
-               if (!link_class(mainclass))
-                       throw_main_exception_exit();
-                       
-               /* find the `main' method of the main class */
-
-               m = class_resolveclassmethod(mainclass,
-                                                                        utf_new_char("main"), 
-                                                                        utf_new_char("([Ljava/lang/String;)V"),
-                                                                        class_java_lang_Object,
-                                                                        false);
-
-               if (*exceptionptr) {
-                       throw_main_exception_exit();
-               }
-
-               /* there is no main method or it isn't static */
-
-               if (!m || !(m->flags & ACC_STATIC)) {
-                       *exceptionptr = NULL;
-
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_NoSuchMethodError,
-                                                                         "main");
-                       throw_main_exception_exit();
-               }
-
-               /* build argument array */
-
-               a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
-               for (i = opt_ind; i < argc; i++) {
-                       a->data[i - opt_ind] = 
-                               (java_objectheader *) javastring_new(utf_new_char(argv[i]));
-               }
 
-#ifdef TYPEINFO_DEBUG_TEST
-               /* test the typeinfo system */
-               typeinfo_test();
-#endif
-               /*class_showmethods(currentThread->group->header.vftbl->class); */
-
-#if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
-               if(dbg) {
-                       debuggee = fork();
-                       if (debuggee == (-1)) {
-                               log_text("fork error");
-                               exit(1);
-                       } else {
-                               if (debuggee == 0) {
-                                       /* child: allow helper process to trace us  */
-                                       if (TRACEME != 0)  exit(0);
-                                       
-                                       /* give parent/helper debugger process control */
-                                       kill(0, SIGTRAP);  /* do we need this at this stage ? */
-
-                                       /* continue with normal startup */      
-
-                               } else {
-
-                                       /* parent/helper debugger process */
-                                       wait(&waitval);
-
-                                       remotedbgjvmtienv = new_jvmtienv();
-                                       /* set eventcallbacks */
-                                       if (JVMTI_ERROR_NONE == 
-                                               remotedbgjvmtienv->
-                                               SetEventCallbacks(remotedbgjvmtienv,
-                                                                                 &jvmti_jdwp_EventCallbacks,
-                                                                                 sizeof(jvmti_jdwp_EventCallbacks))){
-                                               log_text("unable to setup event callbacks");
-                                               cacao_exit(1);                                          
-                                       }
-
-                                       /* setup listening process (JDWP) */
-                                       setup_debugger_process(transport);
-
-                                       /* start to be debugged program */
-                                       CONT(debuggee);
-
-                    /* exit debugger process - todo: cleanup */
-                                       joinAllThreads();
-                                       cacao_exit(0);
-                               }
-                       }
-               }
-               else 
-                       debuggee= -1;
-               
+       vm_createjvm =
+               (bool (*)(JavaVM **, void **, void *)) (ptrint) libjvm_vm_createjvm;
 #endif
-               /* here we go... */
 
-               ASM_CALLJAVAFUNCTION(m, a, NULL, NULL, NULL);
+       /* create the Java VM */
 
-               /* exception occurred? */
+       (void) vm_createjvm(&vm, (void *) &env, vm_args);
 
-               if (*exceptionptr) {
-                       throw_main_exception();
-                       status = 1;
-               }
-
-#if defined(USE_THREADS)
-#if defined(NATIVE_THREADS)
-               joinAllThreads();
-#else
-               killThread(currentThread);
-#endif
+#if defined(ENABLE_JVMTI)
+       pthread_mutex_init(&dbgcomlock,NULL);
+       if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
 #endif
 
-               /* now exit the JavaVM */
-
-/*             (*jvm)->DestroyJavaVM(jvm); */
-
-               cacao_exit(status);
+#if !defined(WITH_STATIC_CLASSPATH) && defined(ENABLE_LIBJVM)
+       if (!(libjvm_vm_run = lt_dlsym(libjvm_handle, "vm_run"))) {
+               fprintf(stderr, "lt_dlsym failed: %s\n", lt_dlerror());
+               abort();
        }
 
-       /************* If requested, compile all methods ********************/
-
-       if (compileall) {
-               classinfo *c;
-               methodinfo *m;
-               u4 slot;
-               s4 i;
-               classcache_name_entry *nmen;
-               classcache_class_entry *clsen;
-
-               /* create all classes found in the bootclasspath */
-               /* XXX currently only works with zip/jar's */
-
-               loader_load_all_classes();
-
-               /* link all classes */
-
-               for (slot = 0; slot < hashtable_classcache.size; slot++) {
-                       nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
-
-                       for (; nmen; nmen = nmen->hashlink) {
-                               /* iterate over all class entries */
-
-                               for (clsen = nmen->classes; clsen; clsen = clsen->next) {
-                                       c = clsen->classobj;
-
-                                       if (!c)
-                                               continue;
-
-                                       if (!(c->state & CLASS_LINKED)) {
-                                               if (!link_class(c)) {
-                                                       fprintf(stderr, "Error linking: ");
-                                                       utf_fprint_classname(stderr, c->name);
-                                                       fprintf(stderr, "\n");
-
-                                                       /* print out exception and cause */
-
-                                                       exceptions_print_exception(*exceptionptr);
-
-                                                       /* goto next class */
-
-                                                       continue;
-                                               }
-                                       }
-
-                                       /* compile all class methods */
-
-                                       for (i = 0; i < c->methodscount; i++) {
-                                               m = &(c->methods[i]);
-
-                                               if (m->jcode) {
-                                                       if (!jit_compile(m)) {
-                                                               fprintf(stderr, "Error compiling: ");
-                                                               utf_fprint_classname(stderr, c->name);
-                                                               fprintf(stderr, ".");
-                                                               utf_fprint(stderr, m->name);
-                                                               utf_fprint(stderr, m->descriptor);
-                                                               fprintf(stderr, "\n");
-
-                                                               /* print out exception and cause */
-
-                                                               exceptions_print_exception(*exceptionptr);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-
-       /******** If requested, compile a specific method ***************/
-
-       if (specificmethodname) {
-               methodinfo *m;
-
-               /* create, load and link the main class */
-
-               if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
-                       throw_main_exception_exit();
-
-               if (!link_class(mainclass))
-                       throw_main_exception_exit();
+       vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run;
+#endif
 
-               if (specificsignature) {
-                       m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(specificmethodname),
-                                                                                utf_new_char(specificsignature),
-                                                                                mainclass,
-                                                                                false);
-               } else {
-                       m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(specificmethodname),
-                                                                                NULL,
-                                                                                mainclass,
-                                                                                false);
-               }
+       /* run the VM */
 
-               if (!m) {
-                       char message[MAXLOGTEXT];
-                       sprintf(message, "%s%s", specificmethodname,
-                                       specificsignature ? specificsignature : "");
-
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_NoSuchMethodException,
-                                                                         message);
-                                                                                
-                       throw_main_exception_exit();
-               }
-               
-               jit_compile(m);
-       }
-
-       cacao_shutdown(0);
+       vm_run(vm, vm_args);
 
        /* keep compiler happy */
 
@@ -1549,134 +185,28 @@ int main(int argc, char **argv)
 }
 
 
-/* cacao_exit ******************************************************************
-
-   Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
-
-*******************************************************************************/
-
-void cacao_exit(s4 status)
-{
-       methodinfo *m;
-
-       assert(class_java_lang_System);
-       assert(class_java_lang_System->state & CLASS_LOADED);
-
-#if defined(ENABLE_JVMTI)
-       set_jvmti_phase(JVMTI_PHASE_DEAD);
-       agentunload();
-#endif
-
-       if (!link_class(class_java_lang_System))
-               throw_main_exception_exit();
-
-       /* signal that we are exiting */
-
-       cacao_exiting = true;
-
-       /* call java.lang.System.exit(I)V */
-
-       m = class_resolveclassmethod(class_java_lang_System,
-                                                                utf_new_char("exit"),
-                                                                utf_int__void,
-                                                                class_java_lang_Object,
-                                                                true);
-       
-       if (!m)
-               throw_main_exception_exit();
-
-       /* call the exit function with passed exit status */
-
-       /* both inlinevirtual and outsiders not allowed on exit */
-       /*   not sure if permanant or temp restriction          */
-       if (inlinevirtuals) inlineoutsiders = false; 
-
-       ASM_CALLJAVAFUNCTION(m, (void *) (ptrint) status, NULL, NULL, NULL);
-
-       /* this should never happen */
-
-       if (*exceptionptr)
-               throw_exception_exit();
-
-       throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                          "System.exit(I)V returned without exception");
-}
-
-
-/*************************** Shutdown function *********************************
+/* cacao_options_prepare *******************************************************
 
-       Terminates the system immediately without freeing memory explicitly (to be
-       used only for abnormal termination)
-       
-*******************************************************************************/
-
-void cacao_shutdown(s4 status)
-{
-
-#if defined(ENABLE_JVMTI)
-       agentunload();
-#endif
-
-       if (opt_verbose || getcompilingtime || opt_stat) {
-               log_text("CACAO terminated by shutdown");
-               dolog("Exit status: %d\n", (s4) status);
-       }
-
-       exit(status);
-}
-
-
-/* exit_handler ****************************************************************
-
-   The exit_handler function is called upon program termination.
-
-   ATTENTION: Don't free system resources here! Some threads may still
-   be running as this is called from VMRuntime.exit(). The OS does the
-   cleanup for us.
+   Prepare the JavaVMInitArgs.
 
 *******************************************************************************/
 
-void exit_handler(void)
+static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv)
 {
-       /********************* Print debug tables ************************/
+       JavaVMInitArgs *vm_args;
+       s4              i;
 
-#if !defined(NDEBUG)
-       if (showmethods)
-               class_showmethods(mainclass);
+       vm_args = malloc(sizeof(JavaVMInitArgs));
 
-       if (showconstantpool)
-               class_showconstantpool(mainclass);
+       vm_args->version            = JNI_VERSION_1_2;
+       vm_args->nOptions           = argc - 1;
+       vm_args->options            = malloc(sizeof(JavaVMOption) * argc);
+       vm_args->ignoreUnrecognized = JNI_FALSE;
 
-       if (showutf)
-               utf_show();
+       for (i = 1; i < argc; i++)
+               vm_args->options[i - 1].optionString = argv[i];
 
-       if (opt_prof)
-               profile_printstats();
-#endif
-
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       clear_thread_flags();           /* restores standard file descriptor
-                                      flags */
-#endif
-
-       if (opt_verbose || getcompilingtime || opt_stat) {
-               log_text("CACAO terminated");
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat) {
-                       print_stats();
-#ifdef TYPECHECK_STATISTICS
-                       typecheck_print_statistics(get_logfile());
-#endif
-               }
-
-               mem_usagelog(1);
-
-               if (getcompilingtime)
-                       print_times();
-#endif
-       }
-       /* vm_print_profile(stderr);*/
+       return vm_args;
 }