added field and method resolution
[cacao.git] / src / cacao / cacao.c
index ceb4aa8831f3bd2707920ad3e9c2fe3d8343b4f2..1c4945840e96f99115b0d3441538d49d886240bb 100644 (file)
@@ -37,7 +37,7 @@
      - Calling the class loader
      - Running the main method
 
-   $Id: cacao.c 862 2004-01-06 23:42:01Z stefan $
+   $Id: cacao.c 1009 2004-03-31 22:44:07Z edwin $
 
 */
 
 #include "toolbox/loging.h"
 #include "toolbox/memory.h"
 #include "parseRTstats.h"
-#include "typeinfo.h" /* XXX remove debug */
 #include "nat/java_lang_Throwable.h"
 
+#ifdef TYPEINFO_DEBUG_TEST
+#include "typeinfo.h"
+#endif
 
 /* command line option */
 
 bool verbose =  false;
 bool compileall = false;
 bool runverbose = false;       /* trace all method invocation                */
+bool verboseexception = false;       /* trace all method invocation                */
 bool collectverbose = false;
 
 bool loadverbose = false;
@@ -76,6 +79,8 @@ bool opt_rt = false;           /* true if RTA parse should be used     RT-CO */
 bool opt_xta = false;          /* true if XTA parse should be used    XTA-CO */
 bool opt_vta = false;          /* true if VTA parse should be used    VTA-CO */
 
+bool opt_liberalutf = false;   /* Don't check overlong UTF-8 sequences       */
+
 bool showmethods = false;
 bool showconstantpool = false;
 bool showutf = false;
@@ -112,10 +117,10 @@ bool statistics = false;
 
 bool opt_verify = true;        /* true if classfiles should be verified      */
 
-
+char mainString[256];
 static classinfo *topclass;
 
-#ifndef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
 void **stackbottom = 0;
 #endif
 
@@ -156,7 +161,8 @@ void **stackbottom = 0;
 #define OPT_VTA         28
 #define OPT_VERBOSETC   29
 #define OPT_NOVERIFY    30
-
+#define OPT_LIBERALUTF  31
+#define OPT_VERBOSEEXCEPTION 32
 
 struct {char *name; bool arg; int value;} opts[] = {
        {"classpath",   true,   OPT_CLASSPATH},
@@ -165,12 +171,14 @@ struct {char *name; bool arg; int value;} opts[] = {
        {"mx",          true,   OPT_MX},
        {"noasyncgc",   false,  OPT_IGNORE},
        {"noverify",    false,  OPT_NOVERIFY},
+       {"liberalutf",  false,  OPT_LIBERALUTF},
        {"oss",         true,   OPT_IGNORE},
        {"ss",          true,   OPT_IGNORE},
        {"v",           false,  OPT_VERBOSE1},
        {"verbose",     false,  OPT_VERBOSE},
        {"verbosegc",   false,  OPT_VERBOSEGC},
        {"verbosecall", false,  OPT_VERBOSECALL},
+       {"verboseexception", false, OPT_VERBOSEEXCEPTION},
 #ifdef TYPECHECK_VERBOSE
        {"verbosetc",   false,  OPT_VERBOSETC},
 #endif
@@ -263,6 +271,7 @@ static void print_usage()
        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
@@ -270,6 +279,7 @@ static void print_usage()
        printf("          -noieee .............. don't use ieee compliant arithmetic\n");
 #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");
        printf("          -stat ................ detailed compiler statistics\n");
@@ -311,7 +321,7 @@ static void print_times()
        s8 runtime = totaltime - loadingtime - compilingtime;
        char logtext[MAXLOGTEXT];
 
-#if defined(__I386__)
+#if defined(__I386__) || defined(__POWERPC__)
        sprintf(logtext, "Time for loading classes: %lld secs, %lld millis",
 #else
        sprintf(logtext, "Time for loading classes: %ld secs, %ld millis",
@@ -319,7 +329,7 @@ static void print_times()
                        loadingtime / 1000000, (loadingtime % 1000000) / 1000);
        log_text(logtext);
 
-#if defined(__I386__)
+#if defined(__I386__) || defined(__POWERPC__) 
        sprintf(logtext, "Time for compiling code:  %lld secs, %lld millis",
 #else
        sprintf(logtext, "Time for compiling code:  %ld secs, %ld millis",
@@ -327,7 +337,7 @@ static void print_times()
                        compilingtime / 1000000, (compilingtime % 1000000) / 1000);
        log_text(logtext);
 
-#if defined(__I386__)
+#if defined(__I386__) || defined(__POWERPC__) 
        sprintf(logtext, "Time for running program: %lld secs, %lld millis",
 #else
        sprintf(logtext, "Time for running program: %ld secs, %ld millis",
@@ -335,7 +345,7 @@ static void print_times()
                        runtime / 1000000, (runtime % 1000000) / 1000);
        log_text(logtext);
 
-#if defined(__I386__)
+#if defined(__I386__) || defined(__POWERPC__) 
        sprintf(logtext, "Total time: %lld secs, %lld millis",
 #else
        sprintf(logtext, "Total time: %ld secs, %ld millis",
@@ -542,6 +552,9 @@ void class_compile_methods()
        }
 }
 
+#ifdef TYPECHECK_STATISTICS
+void typecheck_print_statistics(FILE *file);
+#endif
 
 /*
  * void exit_handler(void)
@@ -557,7 +570,7 @@ void exit_handler(void)
        if (showconstantpool) class_showconstantpool(topclass);
        if (showutf) utf_show();
 
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
        clear_thread_flags();           /* restores standard file descriptor
                                       flags */
 #endif
@@ -573,8 +586,12 @@ void exit_handler(void)
 
        if (verbose || getcompilingtime || statistics) {
                log_text("CACAO terminated");
-               if (statistics)
+               if (statistics) {
                        print_stats();
+#ifdef TYPECHECK_STATISTICS
+                       typecheck_print_statistics(get_logfile());
+#endif
+               }
                if (getcompilingtime)
                        print_times();
                mem_usagelog(1);
@@ -597,14 +614,14 @@ int main(int argc, char **argv)
        /********** interne (nur fuer main relevante Optionen) **************/
    
        char logfilename[200] = "";
-       u4 heapsize = 64000000;
+       u4 heapmaxsize = 64000000;
        u4 heapstartsize = 200000;
        char classpath[500] = ".";
        bool startit = true;
        char *specificmethodname = NULL;
        char *specificsignature = NULL;
 
-#ifndef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
        stackbottom = &dummy;
 #endif
        
@@ -660,7 +677,7 @@ int main(int argc, char **argv)
                        }
                        else j = atoi(opt_arg);
                                
-                       if (i == OPT_MX) heapsize = j;
+                       if (i == OPT_MX) heapmaxsize = j;
                        else heapstartsize = j;
                        break;
 
@@ -675,6 +692,10 @@ int main(int argc, char **argv)
                        compileverbose = true;
                        break;
                                
+               case OPT_VERBOSEEXCEPTION:
+                       verboseexception = true;
+                       break;
+
                case OPT_VERBOSEGC:
                        collectverbose = true;
                        break;
@@ -697,6 +718,10 @@ int main(int argc, char **argv)
                        opt_verify = false;
                        break;
 
+               case OPT_LIBERALUTF:
+                       opt_liberalutf = true;
+                       break;
+
                case OPT_SOFTNULL:
                        checknull = true;
                        break;
@@ -834,58 +859,59 @@ int main(int argc, char **argv)
                exit(10);
        }
 
+       cp = argv[opt_ind++];
+       for (i = strlen(cp) - 1; i >= 0; i--) {     /* Transform dots into slashes */
+               if (cp[i] == '.') cp[i] = '/';          /* in the class name */
+       }
 
-       /**************************** Program start *****************************/
+        strcpy(mainString,cp);
 
+
+       /**************************** Program start *****************************/
        log_init(logfilename);
        if (verbose) {
                log_text("CACAO started -------------------------------------------------------");
        }
 
+       /* initalize the gc heap */
+       heap_init(heapmaxsize, heapstartsize);
+
        native_setclasspath(classpath);
                
        tables_init();
        suck_init(classpath);
 
-       heap_init(heapsize, heapstartsize, &dummy);
-
        jit_init();
 
+#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+       initThreadsEarly();
+#endif
+
        loader_init((u1 *) &dummy);
 
        native_loadclasses();
 
+       /* initialize the garbage collector */
+       gc_init();
+
+#if defined(USE_THREADS)
+       initThreads((u1*) &dummy);
+#endif
 
        /*********************** Load JAVA classes  ***************************/
    
-       cp = argv[opt_ind++];
-       for (i = strlen(cp) - 1; i >= 0; i--) {     /* Transform dots into slashes */
-               if (cp[i] == '.') cp[i] = '/';          /* in the class name */
-       }
-
        /*printf("-------------------->%s\n",cp);*/
        topclass = loader_load(utf_new_char(cp));
        /*class_showmethods(topclass);  */
 
-       if (*exceptionptr != 0) {
-               printf("Exception in thread \"main\" ");
-               utf_display((*exceptionptr)->vftbl->class->name);
-               printf(": ");
-               utf_display(javastring_toutf(((java_lang_Throwable *) *exceptionptr)->detailMessage, false));
-               printf("\n");
-
-               *exceptionptr = 0;
-       }
-
-       if (topclass == 0) {
-               /* should we print out something? we already have the exception */
-               exit(1);
+       if (*exceptionptr) {
+               throw_exception_exit();
        }
 
        /* initialize the garbage collector */
        gc_init();
 
-#ifdef USE_THREADS
+#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
        initThreads((u1*) &dummy);
 #endif
 
@@ -898,9 +924,11 @@ int main(int argc, char **argv)
 
 /*             heap_addreference((void**) &a); */
 
-               mainmethod = class_findmethod(topclass,
+               mainmethod = class_resolveclassmethod(topclass,
                                                                          utf_new_char("main"), 
-                                                                         utf_new_char("([Ljava/lang/String;)V")
+                                                                         utf_new_char("([Ljava/lang/String;)V"),
+                                                                               topclass,
+                                                                               true
                                                                          );
 
                /* there is no main method or it isn't static */
@@ -921,25 +949,47 @@ int main(int argc, char **argv)
 #endif
                /*class_showmethods(currentThread->group->header.vftbl->class); */
 
+               *threadrootmethod = mainmethod;
+
                /* here we go... */
                asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
        
                if (*exceptionptr) {
-                       printf("Exception in thread \"main\" ");
-                       utf_display((*exceptionptr)->vftbl->class->name);
+                       methodinfo *main_unhandled_print =
+                               class_resolvemethod_approx((*exceptionptr)->vftbl->class,
+                                                                                  utf_new_char("printStackTrace"),
+                                                                                  utf_new_char("()V"));
+
+                       if (main_unhandled_print) {
+                               java_objectheader *exo = *exceptionptr;
+                               *exceptionptr = NULL;
+                               asm_calljavafunction(main_unhandled_print, exo, NULL, NULL, NULL);
+
+                       } else {
+                               java_lang_String *msg;
+
+                               printf("Exception in thread \"main\" ");
+                               utf_display_classname((*exceptionptr)->vftbl->class->name);
 
-                       /* do we have a detail message? */
-                       if (((java_lang_Throwable *) *exceptionptr)->detailMessage) {
-                               printf(": ");
-                               utf_display(javastring_toutf(((java_lang_Throwable *) *exceptionptr)->detailMessage, false));
+                               /* do we have a detail message? */
+                               msg = ((java_lang_Throwable *) *exceptionptr)->detailMessage;
+                               if (msg) {
+                                       printf(": ");
+                                       utf_display(javastring_toutf(msg, false));
+                               }
+                               printf("\n");
                        }
-                       printf("\n");
                }
 
-#ifdef USE_THREADS
+#if defined(USE_THREADS)
+#if defined(NATIVE_THREADS)
+               joinAllThreads();
+#else
                killThread(currentThread);
-#endif
                fprintf(stderr, "still here\n");
+#endif
+#endif
+               exit(0);
        }
 
        /************* If requested, compile all methods ********************/