* src/vm/suck.c (vm/vm.h): Added.
[cacao.git] / src / cacao / cacao.c
index 27e3f30d6be0d5957c6687c795b51d104f5a8ee8..7c9ede157b9fc63337305b4a4433619bff77789a 100644 (file)
@@ -31,7 +31,7 @@
             Philipp Tomsich
             Christian Thalinger
 
-   $Id: cacao.c 4874 2006-05-05 14:36:18Z edwin $
+   $Id: cacao.c 5810 2006-10-20 13:54:54Z twisti $
 
 */
 
 #include "config.h"
 
 #include <assert.h>
+
+#if defined(ENABLE_LIBJVM)
+# include <ltdl.h>
+#endif
+
+#if defined(WITH_JRE_LAYOUT)
+# include <errno.h>
+# include <libgen.h>
+# include <unistd.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
 #include "vm/types.h"
 
 #include "native/jni.h"
-#include "native/include/java_lang_String.h"
 
 #if defined(ENABLE_JVMTI)
-#include "native/jvmti/jvmti.h"
-#include "native/jvmti/cacaodbg.h"
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-#include <pthread.h>
-#endif
+# include "native/jvmti/jvmti.h"
+# include "native/jvmti/cacaodbg.h"
 #endif
 
-#include "toolbox/logging.h"
-#include "vm/classcache.h"
-#include "vm/exceptions.h"
-#include "vm/global.h"
-#include "vm/loader.h"
-#include "vm/options.h"
-#include "vm/statistics.h"
-#include "vm/stringlocal.h"
-#include "vm/suck.h"
 #include "vm/vm.h"
-#include "vm/jit/asmpart.h"
-#include "vm/jit/jit.h"
-
-#ifdef TYPEINFO_DEBUG_TEST
-#include "vm/jit/verify/typeinfo.h"
-#endif
-
-#ifdef TYPECHECK_STATISTICS
-void typecheck_print_statistics(FILE *file);
-#endif
-
-/* 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_from_ascii(mainstring);
-
-       (void) vm_call_method(m, o, s);
-
-       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();
 
-       o = vm_call_method(m, o);
 
-       if (o == NULL) {
-               fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
-               vm_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();
-
-       o = vm_call_method(m, o);
-
-       if (o == NULL) {
-               fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
-               vm_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_from_ascii("Main-Class");
-
-       o = vm_call_method(m, o, s);
-
-       if (!o)
-               throw_main_exception_exit();
+/* forward declarations *******************************************************/
 
-       return javastring_tochar(o);
-}
-
-void exit_handler(void);
+static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv);
 
 
 /* main ************************************************************************
@@ -188,286 +78,129 @@ void exit_handler(void);
 
 int main(int argc, char **argv)
 {
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       void *dummy;
-#endif
-       s4 i;
-       
-       /* local variables ********************************************************/
+       char           *path;
 
-       JavaVMInitArgs *vm_args;
-       JavaVM         *jvm;                /* denotes a Java VM                  */
+#if defined(ENABLE_LIBJVM)     
+       /* Variables for JNI_CreateJavaVM dlopen call. */
+       lt_dlhandle     libjvm_handle;
+       lt_ptr          libjvm_createvm;
+       lt_ptr          libjvm_vm_run;
 
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
-       stackbottom = &dummy;
+       s4 (*JNI_CreateJavaVM)(JavaVM **, void **, void *);
+       void (*vm_run)(JavaVM *, JavaVMInitArgs *);
 #endif
-       
-       if (atexit(vm_exit_handler))
-               throw_cacao_exception_exit(string_java_lang_InternalError,
-                                                                  "Unable to register exit_handler");
-
-
-       /**************************** Program start *****************************/
 
-       if (opt_verbose)
-               log_text("CACAO started -------------------------------------------------------");
+       JavaVM         *vm;                 /* denotes a Java VM                  */
+       JNIEnv         *env;
+       JavaVMInitArgs *vm_args;
 
        /* prepare the options */
 
-       vm_args = options_prepare(argc, argv);
+       vm_args = cacao_options_prepare(argc, argv);
        
        /* load and initialize a Java VM, return a JNI interface pointer in env */
 
-       JNI_CreateJavaVM(&jvm, (void **) &_Jv_env, vm_args);
-
-#if defined(ENABLE_JVMTI)
-       if (dbgprocess && jvmti && jdwp) /* is this the parent/debugger process ? */
-               set_jvmti_phase(JVMTI_PHASE_START);
-#endif
-
-       /* do we have a main class? */
-
-       if (mainstring == NULL)
-               usage();
-
+#if !defined(WITH_STATIC_CLASSPATH) && defined(ENABLE_LIBJVM)
+# if defined(WITH_JRE_LAYOUT)
+       /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
 
-       /* start worker routines **************************************************/
+       path = malloc(sizeof(char) * 4096);
 
-       if (opt_run == true) {
-               utf              *mainutf;
-               classinfo        *mainclass;
-               methodinfo       *m;
-               java_objectarray *oa; 
-               s4                oalength;
-               java_lang_String *s;
-               s4                status;
-
-               /* set return value to OK */
-
-               status = 0;
-
-               if (opt_jar == true) {
-                       /* open jar file with java.util.jar.JarFile */
-                       mainstring = getmainclassnamefromjar(mainstring);
-               }
-
-               /* load the main class */
-
-               mainutf = utf_new_char(mainstring);
-
-               if (!(mainclass = load_class_from_sysloader(mainutf)))
-                       throw_main_exception_exit();
-
-               /* error loading class, clear exceptionptr for new exception */
+       if (readlink("/proc/self/exe", path, 4095) == -1) {
+               fprintf(stderr, "readlink failed: %s\n", strerror(errno));
+               abort();
+       }
 
-               if (*exceptionptr || !mainclass) {
-/*                     *exceptionptr = NULL; */
+       /* get the path of the current executable */
 
-/*                     *exceptionptr = */
-/*                             new_exception_message(string_java_lang_NoClassDefFoundError, */
-/*                                                                       mainstring); */
-                       throw_main_exception_exit();
-               }
+       path = dirname(path);
 
-               if (!link_class(mainclass))
-                       throw_main_exception_exit();
-                       
-               /* find the `main' method of the main class */
+       if ((strlen(path) + strlen("/../lib/libjvm") + strlen("0")) > 4096) {
+               fprintf(stderr, "libjvm name to long for buffer\n");
+               abort();
+       }
 
-               m = class_resolveclassmethod(mainclass,
-                                                                        utf_new_char("main"), 
-                                                                        utf_new_char("([Ljava/lang/String;)V"),
-                                                                        class_java_lang_Object,
-                                                                        false);
+       /* concatinate the library name */
 
-               if (*exceptionptr) {
-                       throw_main_exception_exit();
-               }
+       strcat(path, "/../lib/libjvm");
+# else
+       path = CACAO_LIBDIR"/libjvm";
+# endif
 
-               /* there is no main method or it isn't static */
+       if (lt_dlinit()) {
+               fprintf(stderr, "lt_dlinit failed: %s\n", lt_dlerror());
+               abort();
+       }
 
-               if (!m || !(m->flags & ACC_STATIC)) {
-                       *exceptionptr = NULL;
+       /* First try to open where dlopen searches, e.g. LD_LIBRARY_PATH.
+          If not found, try the absolute path. */
 
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_NoSuchMethodError,
-                                                                         "main");
-                       throw_main_exception_exit();
+       if (!(libjvm_handle = lt_dlopenext("libjvm"))) {
+               if (!(libjvm_handle = lt_dlopenext(path))) {
+                       fprintf(stderr, "lt_dlopenext failed: %s\n", lt_dlerror());
+                       abort();
                }
+       }
 
-               /* build argument array */
-
-               oalength = vm_args->nOptions - opt_index;
+       if (!(libjvm_createvm = lt_dlsym(libjvm_handle, "JNI_CreateJavaVM"))) {
+               fprintf(stderr, "lt_dlsym failed: %s\n", lt_dlerror());
+               abort();
+       }
 
-               oa = builtin_anewarray(oalength, class_java_lang_String);
+       JNI_CreateJavaVM =
+               (s4 (*)(JavaVM **, void **, void *)) (ptrint) libjvm_createvm;
+#endif
 
-               for (i = 0; i < oalength; i++) {
-                       s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString));
-                       oa->data[i] = (java_objectheader *) s;
-               }
+       /* create the Java VM */
 
-#ifdef TYPEINFO_DEBUG_TEST
-               /* test the typeinfo system */
-               typeinfo_test();
-#endif
-               /*class_showmethods(currentThread->group->header.vftbl->class); */
+       JNI_CreateJavaVM(&vm, (void *) &env, vm_args);
 
 #if defined(ENABLE_JVMTI)
-               /* if this is the parent process than start the jdwp listening */
-               if (jvmti || jdwp) {
-                       fprintf(stderr, "jdwp/debugger set herewego brkpt %p\n",&&herewego);
-                       setsysbrkpt(HEREWEGOBRK,&&herewego);
-                       if (dbgprocess && jdwp) cacaodbglisten(transport);
-               }
-
-               if (!dbgprocess) {
-                       fprintf(stderr,"debuggee: herewe go\n");
-                       fflush(stderr);
-               }
-               /* here we go... */
-       herewego:
+       pthread_mutex_init(&dbgcomlock,NULL);
+       if (jvmti) jvmti_set_phase(JVMTI_PHASE_START);
 #endif
-               (void) vm_call_method(m, NULL, oa);
-
-               /* exception occurred? */
 
-               if (*exceptionptr) {
-                       throw_main_exception();
-                       status = 1;
-               }
-
-               /* unload the JavaVM */
-
-               vm_destroy(jvm);
-
-               /* and exit */
-
-               vm_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();
        }
 
+       vm_run = (void (*)(JavaVM *, JavaVMInitArgs *)) (ptrint) libjvm_vm_run;
+#endif
 
-       /* If requested, compile all methods. *************************************/
-
-#if !defined(NDEBUG)
-       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);
-                                                       }
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-#endif /* !defined(NDEBUG) */
+       /* run the VM */
 
+       vm_run(vm, vm_args);
 
-       /* If requested, compile a specific method. *******************************/
+       /* keep compiler happy */
 
-#if !defined(NDEBUG)
-       if (opt_method != NULL) {
-               methodinfo *m;
+       return 0;
+}
 
-               /* create, load and link the main class */
 
-               if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
-                       throw_main_exception_exit();
+/* cacao_options_prepare *******************************************************
 
-               if (!link_class(mainclass))
-                       throw_main_exception_exit();
+   Prepare the JavaVMInitArgs.
 
-               if (opt_signature != NULL) {
-                       m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(opt_method),
-                                                                                utf_new_char(opt_signature),
-                                                                                mainclass,
-                                                                                false);
-               } else {
-                       m = class_resolveclassmethod(mainclass,
-                                                                                utf_new_char(opt_method),
-                                                                                NULL,
-                                                                                mainclass,
-                                                                                false);
-               }
+*******************************************************************************/
 
-               if (!m) {
-                       char message[MAXLOGTEXT];
-                       sprintf(message, "%s%s", opt_method,
-                                       opt_signature ? opt_signature : "");
+static JavaVMInitArgs *cacao_options_prepare(int argc, char **argv)
+{
+       JavaVMInitArgs *vm_args;
+       s4              i;
 
-                       *exceptionptr =
-                               new_exception_message(string_java_lang_NoSuchMethodException,
-                                                                         message);
-                                                                                
-                       throw_main_exception_exit();
-               }
-               
-               jit_compile(m);
-       }
+       vm_args = malloc(sizeof(JavaVMInitArgs));
 
-       vm_shutdown(0);
-#endif /* !defined(NDEBUG) */
+       vm_args->version            = JNI_VERSION_1_2;
+       vm_args->nOptions           = argc - 1;
+       vm_args->options            = malloc(sizeof(JavaVMOption) * argc);
+       vm_args->ignoreUnrecognized = JNI_FALSE;
 
-       /* keep compiler happy */
+       for (i = 1; i < argc; i++)
+               vm_args->options[i - 1].optionString = argv[i];
 
-       return 0;
+       return vm_args;
 }