ebc42b1a29b08bf2d64a0107d7557ff85f4d78c7
[cacao.git] / src / cacao / cacao.c
1 /* src/cacao/cacao.c - contains main() of cacao
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Reinhard Grafl
28
29    Changes: Andi Krall
30             Mark Probst
31             Philipp Tomsich
32             Christian Thalinger
33
34    This module does the following tasks:
35      - Command line option handling
36      - Calling initialization routines
37      - Calling the class loader
38      - Running the main method
39
40    $Id: cacao.c 2950 2005-07-09 13:37:29Z twisti $
41
42 */
43
44
45 #include <assert.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #include "config.h"
50 #include "cacao/cacao.h"
51 #include "mm/boehm.h"
52 #include "mm/memory.h"
53 #include "native/jni.h"
54 #include "native/native.h"
55 #include "toolbox/logging.h"
56 #include "vm/exceptions.h"
57 #include "vm/global.h"
58 #include "vm/initialize.h"
59 #include "vm/loader.h"
60 #include "vm/options.h"
61 #include "vm/signallocal.h"
62 #include "vm/statistics.h"
63 #include "vm/stringlocal.h"
64 #include "vm/tables.h"
65 #include "vm/classcache.h"
66 #include "vm/jit/asmpart.h"
67 #include "vm/jit/jit.h"
68
69 #ifdef TYPEINFO_DEBUG_TEST
70 #include "vm/jit/verify/typeinfo.h"
71 #endif
72
73
74 /* define heap sizes **********************************************************/
75
76 #define HEAP_MAXSIZE      64 * 1024 * 1024; /* default 64MB                   */
77 #define HEAP_STARTSIZE    2 * 1024 * 1024;  /* default 2MB                    */
78
79
80 /* Invocation API variables ***************************************************/
81
82 JavaVM *jvm;                        /* denotes a Java VM                      */
83 JNIEnv *env;                        /* pointer to native method interface     */
84  
85 JDK1_1InitArgs vm_args;             /* JDK 1.1 VM initialization arguments    */
86
87
88 bool cacao_initializing;
89
90 char *bootclasspath;                    /* contains the boot classpath        */
91 char *classpath;                        /* contains the classpath             */
92
93 char *mainstring;
94 static classinfo *mainclass;
95
96 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
97 void **stackbottom = 0;
98 #endif
99
100
101 /* define command line options ************************************************/
102
103 #define OPT_CLASSPATH        2
104 #define OPT_D                3
105 #define OPT_MS               4
106 #define OPT_MX               5
107 #define OPT_VERBOSE1         6
108 #define OPT_VERBOSE          7
109 #define OPT_VERBOSESPECIFIC  8
110 #define OPT_VERBOSECALL      9
111 #define OPT_NOIEEE           10
112 #define OPT_SOFTNULL         11
113 #define OPT_TIME             12
114
115 #if defined(STATISTICS)
116 #define OPT_STAT             13
117 #endif /* defined(STATISTICS) */
118
119 #define OPT_LOG              14
120 #define OPT_CHECK            15
121 #define OPT_LOAD             16
122 #define OPT_METHOD           17
123 #define OPT_SIGNATURE        18
124 #define OPT_SHOW             19
125 #define OPT_ALL              20
126 #define OPT_OLOOP            24
127 #define OPT_INLINING         25
128
129 #define STATIC_ANALYSIS
130 #if defined(STATIC_ANALYSIS)
131 # define OPT_RT              26
132 # define OPT_XTA             27 
133 # define OPT_VTA             28
134 #endif /* defined(STATIC_ANALYSIS) */
135
136 #define OPT_VERBOSETC        29
137 #define OPT_NOVERIFY         30
138 #define OPT_LIBERALUTF       31
139 #define OPT_VERBOSEEXCEPTION 32
140 #define OPT_EAGER            33
141
142 #if defined(LSRA)
143 #define OPT_LSRA             34
144 #endif /* defined(LSRA) */
145
146 #define OPT_JAR              35
147 #define OPT_BOOTCLASSPATH    36
148 #define OPT_BOOTCLASSPATH_A  37
149 #define OPT_BOOTCLASSPATH_P  38
150 #define OPT_VERSION          39
151 #define OPT_SHOWVERSION      40
152
153 #define OPT_HELP             100
154 #define OPT_X                101
155
156
157 opt_struct opts[] = {
158         { "classpath",         true,  OPT_CLASSPATH },
159         { "cp",                true,  OPT_CLASSPATH },
160         { "D",                 true,  OPT_D },
161         { "Xms",               true,  OPT_MS },
162         { "Xmx",               true,  OPT_MX },
163         { "ms",                true,  OPT_MS },
164         { "mx",                true,  OPT_MX },
165         { "noasyncgc",         false, OPT_IGNORE },
166         { "noverify",          false, OPT_NOVERIFY },
167         { "liberalutf",        false, OPT_LIBERALUTF },
168         { "ss",                true,  OPT_IGNORE },
169         { "v",                 false, OPT_VERBOSE1 },
170         { "verbose",           false, OPT_VERBOSE },
171         { "verbose:",          true,  OPT_VERBOSESPECIFIC },
172         { "verbosecall",       false, OPT_VERBOSECALL },
173         { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
174 #ifdef TYPECHECK_VERBOSE
175         { "verbosetc",         false, OPT_VERBOSETC },
176 #endif
177 #if defined(__ALPHA__)
178         { "noieee",            false, OPT_NOIEEE },
179 #endif
180         { "softnull",          false, OPT_SOFTNULL },
181         { "time",              false, OPT_TIME },
182 #if defined(STATISTICS)
183         { "stat",              false, OPT_STAT },
184 #endif
185         { "log",               true,  OPT_LOG },
186         { "c",                 true,  OPT_CHECK },
187         { "l",                 false, OPT_LOAD },
188     { "eager",             false, OPT_EAGER },
189         { "m",                 true,  OPT_METHOD },
190         { "sig",               true,  OPT_SIGNATURE },
191         { "s",                 true,  OPT_SHOW },
192         { "all",               false, OPT_ALL },
193         { "oloop",             false, OPT_OLOOP },
194         { "i",                 true,  OPT_INLINING },
195 #ifdef STATIC_ANALYSIS
196         { "rt",                false, OPT_RT },
197         { "xta",               false, OPT_XTA },
198         { "vta",               false, OPT_VTA },
199 #endif
200 #ifdef LSRA
201         { "lsra",              false, OPT_LSRA },
202 #endif
203         { "jar",               false, OPT_JAR },
204         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
205         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
206         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
207         { "version",           false, OPT_VERSION },
208         { "showversion",       false, OPT_SHOWVERSION },
209         { "help",              false, OPT_HELP },
210         { "?",                 false, OPT_HELP },
211         { "X",                 false, OPT_X },
212         { NULL,                false, 0 }
213 };
214
215
216 /* usage ***********************************************************************
217
218    Prints the correct usage syntax to stdout.
219
220 *******************************************************************************/
221
222 static void usage(void)
223 {
224         printf("Usage: cacao [-options] classname [arguments]\n");
225         printf("               (to run a class file)\n");
226         printf("       cacao [-options] -jar jarfile [arguments]\n");
227         printf("               (to run a standalone jar file)\n\n");
228
229         printf("Java options:\n");
230         printf("    -cp <path>               specify a path to look for classes\n");
231         printf("    -classpath <path>        specify a path to look for classes\n");
232         printf("    -D<name>=<value>         add an entry to the property list\n");
233         printf("    -verbose[:class|gc|jni]  enable specific verbose output\n");
234         printf("    -version                 print product version and exit\n");
235         printf("    -showversion             print product version and continue\n");
236         printf("    -help, -?                print this help message\n");
237         printf("    -X                       print help on non-standard Java options\n\n");
238
239         printf("CACAO options:\n");
240         printf("    -v                       write state-information\n");
241         printf("    -verbose                 write more information\n");
242         printf("    -verbosegc               write message for each GC\n");
243         printf("    -verbosecall             write message for each call\n");
244         printf("    -verboseexception        write message for each step of stack unwinding\n");
245 #ifdef TYPECHECK_VERBOSE
246         printf("    -verbosetc               write debug messages while typechecking\n");
247 #endif
248 #if defined(__ALPHA__)
249         printf("    -noieee                  don't use ieee compliant arithmetic\n");
250 #endif
251         printf("    -noverify                don't verify classfiles\n");
252         printf("    -liberalutf              don't warn about overlong UTF-8 sequences\n");
253         printf("    -softnull                use software nullpointer check\n");
254         printf("    -time                    measure the runtime\n");
255 #if defined(STATISTICS)
256         printf("    -stat                    detailed compiler statistics\n");
257 #endif
258         printf("    -log logfile             specify a name for the logfile\n");
259         printf("    -c(heck)b(ounds)         don't check array bounds\n");
260         printf("            s(ync)           don't check for synchronization\n");
261         printf("    -oloop                   optimize array accesses in loops\n"); 
262         printf("    -l                       don't start the class after loading\n");
263         printf("    -eager                   perform eager class loading and linking\n");
264         printf("    -all                     compile all methods, no execution\n");
265         printf("    -m                       compile only a specific method\n");
266         printf("    -sig                     specify signature for a specific method\n");
267         printf("    -s(how)a(ssembler)       show disassembled listing\n");
268         printf("           c(onstants)       show the constant pool\n");
269         printf("           d(atasegment)     show data segment listing\n");
270         printf("           e(xceptionstubs)  show disassembled exception stubs (only with -sa)\n");
271         printf("           i(ntermediate)    show intermediate representation\n");
272         printf("           m(ethods)         show class fields and methods\n");
273         printf("           n(ative)          show disassembled native stubs\n");
274         printf("           u(tf)             show the utf - hash\n");
275         printf("    -i     n(line)           activate inlining\n");
276         printf("           v(irtual)         inline virtual methods (uses/turns rt option on)\n");
277         printf("           e(exception)      inline methods with exceptions\n");
278         printf("           p(aramopt)        optimize argument renaming\n");
279         printf("           o(utsiders)       inline methods of foreign classes\n");
280 #ifdef STATIC_ANALYSIS
281         printf("    -rt                      use rapid type analysis\n");
282         printf("    -xta                     use x type analysis\n");
283         printf("    -vta                     use variable type analysis\n");
284 #endif
285 #ifdef LSRA
286         printf("    -lsra                    use linear scan register allocation\n");
287 #endif
288
289         /* exit with error code */
290
291         exit(1);
292 }   
293
294
295 static void Xusage(void)
296 {
297         printf("    -Xbootclasspath:<zip/jar files and directories separated by :>\n");
298     printf("                      value is set as bootstrap class path\n");
299         printf("    -Xbootclasspath/a:<zip/jar files and directories separated by :>\n");
300         printf("                      value is appended to the bootstrap class path\n");
301         printf("    -Xbootclasspath/p:<zip/jar files and directories separated by :>\n");
302         printf("                      value is prepended to the bootstrap class path\n");
303         printf("    -Xms<size>        set the initial size of the heap (default: 2M)\n");
304         printf("    -Xmx<size>        set the maximum size of the heap (default: 64M)\n");
305
306         /* exit with error code */
307
308         exit(1);
309 }   
310
311
312 /* version *********************************************************************
313
314    Only prints cacao version information.
315
316 *******************************************************************************/
317
318 static void version(void)
319 {
320         printf("CACAO version "VERSION"\n");
321
322         printf("Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,\n");
323         printf("R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,\n");
324         printf("C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,\n");
325         printf("Institut f. Computersprachen - TU Wien\n\n");
326
327         printf("This program is free software; you can redistribute it and/or\n");
328         printf("modify it under the terms of the GNU General Public License as\n");
329         printf("published by the Free Software Foundation; either version 2, or (at\n");
330         printf("your option) any later version.\n\n");
331
332         printf("This program is distributed in the hope that it will be useful, but\n");
333         printf("WITHOUT ANY WARRANTY; without even the implied warranty of\n");
334         printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n");
335         printf("General Public License for more details.\n");
336 }
337
338
339 #ifdef TYPECHECK_STATISTICS
340 void typecheck_print_statistics(FILE *file);
341 #endif
342
343
344
345 /* getmainclassfromjar *********************************************************
346
347    Gets the name of the main class form a JAR's manifest file.
348
349 *******************************************************************************/
350
351 static char *getmainclassnamefromjar(char *mainstring)
352 {
353         classinfo         *c;
354         java_objectheader *o;
355         methodinfo        *m;
356         java_lang_String  *s;
357
358         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
359
360         if (!c)
361                 throw_main_exception_exit();
362         
363         /* create JarFile object */
364
365         o = builtin_new(c);
366
367         if (!o)
368                 throw_main_exception_exit();
369
370
371         m = class_resolveclassmethod(c,
372                                                                  utf_init, 
373                                                                  utf_java_lang_String__void,
374                                                                  class_java_lang_Object,
375                                                                  true);
376
377         if (!m)
378                 throw_main_exception_exit();
379
380         s = javastring_new_char(mainstring);
381
382         asm_calljavafunction(m, o, s, NULL, NULL);
383
384         if (*exceptionptr)
385                 throw_main_exception_exit();
386
387         /* get manifest object */
388
389         m = class_resolveclassmethod(c,
390                                                                  utf_new_char("getManifest"), 
391                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
392                                                                  class_java_lang_Object,
393                                                                  true);
394
395         if (!m)
396                 throw_main_exception_exit();
397
398         o = asm_calljavafunction(m, o, NULL, NULL, NULL);
399
400         if (!o) {
401                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
402                 cacao_exit(1);
403         }
404
405
406         /* get Main Attributes */
407
408         m = class_resolveclassmethod(o->vftbl->class,
409                                                                  utf_new_char("getMainAttributes"), 
410                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
411                                                                  class_java_lang_Object,
412                                                                  true);
413
414         if (!m)
415                 throw_main_exception_exit();
416
417         o = asm_calljavafunction(m, o, NULL, NULL, NULL);
418
419         if (!o) {
420                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
421                 cacao_exit(1);
422         }
423
424
425         /* get property Main-Class */
426
427         m = class_resolveclassmethod(o->vftbl->class,
428                                                                  utf_new_char("getValue"), 
429                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
430                                                                  class_java_lang_Object,
431                                                                  true);
432
433         if (!m)
434                 throw_main_exception_exit();
435
436         s = javastring_new_char("Main-Class");
437
438         o = asm_calljavafunction(m, o, s, NULL, NULL);
439
440         if (!o)
441                 throw_main_exception_exit();
442
443         return javastring_tochar(o);
444 }
445
446
447 /*
448  * void exit_handler(void)
449  * -----------------------
450  * The exit_handler function is called upon program termination to shutdown
451  * the various subsystems and release the resources allocated to the VM.
452  */
453 void exit_handler(void)
454 {
455         /********************* Print debug tables ************************/
456                                 
457         if (showmethods) class_showmethods(mainclass);
458         if (showconstantpool) class_showconstantpool(mainclass);
459         if (showutf) utf_show();
460
461 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
462         clear_thread_flags();           /* restores standard file descriptor
463                                        flags */
464 #endif
465
466         /************************ Free all resources *******************/
467
468         loader_close();
469         tables_close();
470
471         MFREE(classpath, u1, strlen(classpath));
472
473         if (opt_verbose || getcompilingtime || opt_stat) {
474                 log_text("CACAO terminated");
475
476 #if defined(STATISTICS)
477                 if (opt_stat) {
478                         print_stats();
479 #ifdef TYPECHECK_STATISTICS
480                         typecheck_print_statistics(get_logfile());
481 #endif
482                 }
483
484                 if (getcompilingtime)
485                         print_times();
486                 mem_usagelog(1);
487 #endif
488         }
489 }
490
491
492 /* main ************************************************************************
493
494    The main program.
495    
496 *******************************************************************************/
497
498 int main(int argc, char **argv)
499 {
500         s4 i, j;
501         void *dummy;
502         
503         /* local variables ********************************************************/
504    
505         char logfilename[200] = "";
506         u4 heapmaxsize;
507         u4 heapstartsize;
508         char *cp;
509         s4    cplen;
510         bool startit = true;
511         char *specificmethodname = NULL;
512         char *specificsignature = NULL;
513         bool jar = false;
514
515 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
516         stackbottom = &dummy;
517 #endif
518         
519         if (atexit(exit_handler))
520                 throw_cacao_exception_exit(string_java_lang_InternalError,
521                                                                    "Unable to register exit_handler");
522
523
524         /************ Collect info from the environment ************************/
525
526         /* set the bootclasspath */
527
528         cp = getenv("BOOTCLASSPATH");
529         if (cp) {
530                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
531                 strcpy(bootclasspath, cp);
532
533         } else {
534 #if !defined(WITH_EXTERNAL_CLASSPATH)
535                 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_RT_JAR_PATH) +
536                         strlen("0");
537
538                 bootclasspath = MNEW(char, cplen);
539                 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
540                 strcat(bootclasspath, CACAO_RT_JAR_PATH);
541 #else
542                 cplen = strlen(CACAO_INSTALL_PREFIX) + strlen(CACAO_VM_ZIP_PATH) +
543                         strlen(":") +
544                         strlen(EXTERNAL_CLASSPATH_PREFIX) +
545                         strlen(CLASSPATH_GLIBJ_ZIP_PATH) +
546                         strlen("0");
547
548                 bootclasspath = MNEW(char, cplen);
549                 strcpy(bootclasspath, CACAO_INSTALL_PREFIX);
550                 strcat(bootclasspath, CACAO_VM_ZIP_PATH);
551                 strcat(bootclasspath, ":");
552                 strcat(bootclasspath, EXTERNAL_CLASSPATH_PREFIX);
553                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP_PATH);
554 #endif
555         }
556
557
558         /* set the classpath */
559
560         cp = getenv("CLASSPATH");
561         if (cp) {
562                 classpath = MNEW(char, strlen(cp) + strlen("0"));
563                 strcat(classpath, cp);
564
565         } else {
566                 classpath = MNEW(char, strlen(".") + strlen("0"));
567                 strcpy(classpath, ".");
568         }
569
570
571         /***************** Interpret the command line *****************/
572    
573         checknull = false;
574         opt_noieee = false;
575
576         heapmaxsize = HEAP_MAXSIZE;
577         heapstartsize = HEAP_STARTSIZE;
578
579
580         while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
581                 switch (i) {
582                 case OPT_IGNORE:
583                         break;
584                         
585                 case OPT_BOOTCLASSPATH:
586                         /* Forget default bootclasspath and set the argument as new boot  */
587                         /* classpath.                                                     */
588                         MFREE(bootclasspath, char, strlen(bootclasspath));
589
590                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
591                         strcpy(bootclasspath, opt_arg);
592                         break;
593
594                 case OPT_BOOTCLASSPATH_A:
595                         /* append to end of bootclasspath */
596                         cplen = strlen(bootclasspath);
597
598                         bootclasspath = MREALLOC(bootclasspath,
599                                                                          char,
600                                                                          cplen,
601                                                                          cplen + strlen(":") +
602                                                                          strlen(opt_arg) + strlen("0"));
603
604                         strcat(bootclasspath, ":");
605                         strcat(bootclasspath, opt_arg);
606                         break;
607
608                 case OPT_BOOTCLASSPATH_P:
609                         /* prepend in front of bootclasspath */
610                         cp = bootclasspath;
611                         cplen = strlen(cp);
612
613                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
614                                                                  cplen + strlen("0"));
615
616                         strcpy(bootclasspath, opt_arg);
617                         strcat(bootclasspath, ":");
618                         strcat(bootclasspath, cp);
619
620                         MFREE(cp, char, cplen);
621                         break;
622
623                 case OPT_CLASSPATH:
624                         /* forget old classpath and set the argument as new classpath */
625                         MFREE(classpath, char, strlen(classpath));
626
627                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
628                         strcpy(classpath, opt_arg);
629                         break;
630
631                 case OPT_JAR:
632                         jar = true;
633                         break;
634                         
635                 case OPT_D:
636                         {
637                                 for (j = 0; j < strlen(opt_arg); j++) {
638                                         if (opt_arg[j] == '=') {
639                                                 opt_arg[j] = '\0';
640                                                 create_property(opt_arg, opt_arg + j + 1);
641                                                 goto didit;
642                                         }
643                                 }
644
645                                 /* if no '=' is given, just create an empty property */
646                                 create_property(opt_arg, "");
647                                         
648                         didit: ;
649                         }       
650                         break;
651
652                 case OPT_MS:
653                 case OPT_MX:
654                         {
655                                 char c;
656                                 c = opt_arg[strlen(opt_arg) - 1];
657
658                                 if (c == 'k' || c == 'K') {
659                                         j = 1024 * atoi(opt_arg);
660
661                                 } else if (c == 'm' || c == 'M') {
662                                         j = 1024 * 1024 * atoi(opt_arg);
663
664                                 } else j = atoi(opt_arg);
665
666                                 if (i == OPT_MX) heapmaxsize = j;
667                                 else heapstartsize = j;
668                         }
669                         break;
670
671                 case OPT_VERBOSE1:
672                         opt_verbose = true;
673                         break;
674
675                 case OPT_VERBOSE:
676                         opt_verbose = true;
677                         loadverbose = true;
678                         linkverbose = true;
679                         initverbose = true;
680                         compileverbose = true;
681                         break;
682
683                 case OPT_VERBOSESPECIFIC:
684                         if (strcmp("class", opt_arg) == 0) {
685                                 loadverbose = true;
686                                 linkverbose = true;
687
688                         } else if (strcmp("gc", opt_arg) == 0) {
689                                 opt_verbosegc = true;
690
691                         } else if (strcmp("jni", opt_arg) == 0) {
692                                 opt_verbosejni = true;
693                         }
694                         break;
695
696                 case OPT_VERBOSEEXCEPTION:
697                         verboseexception = true;
698                         break;
699
700 #ifdef TYPECHECK_VERBOSE
701                 case OPT_VERBOSETC:
702                         typecheckverbose = true;
703                         break;
704 #endif
705                                 
706                 case OPT_VERBOSECALL:
707                         runverbose = true;
708                         break;
709
710                 case OPT_VERSION:
711                         version();
712                         exit(0);
713                         break;
714
715                 case OPT_SHOWVERSION:
716                         version();
717                         break;
718
719                 case OPT_NOIEEE:
720                         opt_noieee = true;
721                         break;
722
723                 case OPT_NOVERIFY:
724                         opt_verify = false;
725                         break;
726
727                 case OPT_LIBERALUTF:
728                         opt_liberalutf = true;
729                         break;
730
731                 case OPT_SOFTNULL:
732                         checknull = true;
733                         break;
734
735                 case OPT_TIME:
736                         getcompilingtime = true;
737                         getloadingtime = true;
738                         break;
739                                         
740 #if defined(STATISTICS)
741                 case OPT_STAT:
742                         opt_stat = true;
743                         break;
744 #endif
745                                         
746                 case OPT_LOG:
747                         strcpy(logfilename, opt_arg);
748                         break;
749                         
750                 case OPT_CHECK:
751                         for (j = 0; j < strlen(opt_arg); j++) {
752                                 switch (opt_arg[j]) {
753                                 case 'b':
754                                         checkbounds = false;
755                                         break;
756                                 case 's':
757                                         checksync = false;
758                                         break;
759                                 default:
760                                         usage();
761                                 }
762                         }
763                         break;
764                         
765                 case OPT_LOAD:
766                         startit = false;
767                         makeinitializations = false;
768                         break;
769
770                 case OPT_EAGER:
771                         opt_eager = true;
772                         break;
773
774                 case OPT_METHOD:
775                         startit = false;
776                         specificmethodname = opt_arg;
777                         makeinitializations = false;
778                         break;
779                         
780                 case OPT_SIGNATURE:
781                         specificsignature = opt_arg;
782                         break;
783                         
784                 case OPT_ALL:
785                         compileall = true;
786                         startit = false;
787                         makeinitializations = false;
788                         break;
789                         
790                 case OPT_SHOW:       /* Display options */
791                         for (j = 0; j < strlen(opt_arg); j++) {         
792                                 switch (opt_arg[j]) {
793                                 case 'a':
794                                         opt_showdisassemble = true;
795                                         compileverbose = true;
796                                         break;
797                                 case 'c':
798                                         showconstantpool = true;
799                                         break;
800                                 case 'd':
801                                         opt_showddatasegment = true;
802                                         break;
803                                 case 'e':
804                                         opt_showexceptionstubs = true;
805                                         break;
806                                 case 'i':
807                                         opt_showintermediate = true;
808                                         compileverbose = true;
809                                         break;
810                                 case 'm':
811                                         showmethods = true;
812                                         break;
813                                 case 'n':
814                                         opt_shownativestub = true;
815                                         break;
816                                 case 'u':
817                                         showutf = true;
818                                         break;
819                                 default:
820                                         usage();
821                                 }
822                         }
823                         break;
824                         
825                 case OPT_OLOOP:
826                         opt_loops = true;
827                         break;
828
829                 case OPT_INLINING:
830                         for (j = 0; j < strlen(opt_arg); j++) {         
831                                 switch (opt_arg[j]) {
832                                 case 'n':
833                                      /* define in options.h; Used in main.c, jit.c & inline.c */
834 #ifdef INAFTERMAIN
835                                         useinliningm = true;
836                                         useinlining = false;
837 #else
838                                         useinlining = true;
839 #endif
840                                         break;
841                                 case 'v':
842                                         inlinevirtuals = true;
843                                         opt_rt = true;
844                                         break;
845                                 case 'e':
846                                         inlineexceptions = true;
847                                         break;
848                                 case 'p':
849                                         inlineparamopt = true;
850                                         break;
851                                 case 'o':
852                                         inlineoutsiders = true;
853                                         break;
854                                 default:
855                                         usage();
856                                 }
857                         }
858                         break;
859
860 #ifdef STATIC_ANALYSIS
861                 case OPT_RT:
862                         opt_rt = true; /* default for inlining */
863                         break;
864
865                 case OPT_XTA:
866                         opt_xta = true; /* in test currently */
867                         break;
868
869                 case OPT_VTA:
870                         printf("\nVTA is not yet available\n");
871                         opt_vta = false;
872                         /***opt_vta = true; not yet **/
873                         break;
874 #endif
875
876 #ifdef LSRA
877                 case OPT_LSRA:
878                         opt_lsra = true;
879                         break;
880 #endif
881
882                 case OPT_HELP:
883                         usage();
884                         break;
885
886                 case OPT_X:
887                         Xusage();
888                         break;
889
890                 default:
891                         printf("Unknown option: %s\n", argv[opt_ind]);
892                         usage();
893                 }
894         }
895
896         if (opt_ind >= argc)
897                 usage();
898
899
900         /* transform dots into slashes in the class name */
901
902         mainstring = argv[opt_ind++];
903
904         if (!jar) { 
905         /* do not mangle jar filename */
906
907                 for (i = strlen(mainstring) - 1; i >= 0; i--) {
908                         if (mainstring[i] == '.') mainstring[i] = '/';
909                 }
910
911         } else {
912                 /* put jarfile in classpath */
913
914                 cp = classpath;
915
916                 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
917                                                  strlen(classpath) + strlen("0"));
918
919                 strcpy(classpath, mainstring);
920                 strcat(classpath, ":");
921                 strcat(classpath, cp);
922                 
923                 MFREE(cp, char, strlen(cp));
924         }
925
926         /**************************** Program start *****************************/
927
928         log_init(logfilename);
929
930         if (opt_verbose)
931                 log_text("CACAO started -------------------------------------------------------");
932
933         /* initialize JavaVM */
934
935         vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
936
937         /* Get the default initialization arguments and set the class path */
938
939         JNI_GetDefaultJavaVMInitArgs(&vm_args);
940
941         vm_args.minHeapSize = heapstartsize;
942         vm_args.maxHeapSize = heapmaxsize;
943
944         vm_args.classpath = classpath;
945  
946         /* load and initialize a Java VM, return a JNI interface pointer in env */
947
948         JNI_CreateJavaVM(&jvm, &env, &vm_args);
949
950
951         /* initialize the garbage collector */
952
953         gc_init(heapmaxsize, heapstartsize);
954
955         tables_init();
956
957         /* initialize the loader with bootclasspath */
958
959         suck_init(bootclasspath);
960
961         cacao_initializing = true;
962
963 #if defined(USE_THREADS)
964 #if defined(NATIVE_THREADS)
965         initThreadsEarly();
966 #endif
967         initLocks();
968 #endif
969
970         /* install architecture dependent signal handler used for exceptions */
971
972         signal_init();
973
974         /* initialize the codegen sub systems */
975
976         codegen_init();
977
978         /* initializes jit compiler */
979
980         jit_init();
981
982         /* machine dependent initialization */
983
984         md_init();
985
986         /* initialize some cacao subsystems */
987
988         utf8_init();
989
990         if (!loader_init((u1 *) &dummy))
991                 throw_main_exception_exit();
992
993         if (!linker_init())
994                 throw_main_exception_exit();
995
996         if (!native_init())
997                 throw_main_exception_exit();
998
999         if (!exceptions_init())
1000                 throw_main_exception_exit();
1001
1002         if (!builtin_init())
1003                 throw_main_exception_exit();
1004
1005 #if defined(USE_THREADS)
1006         initThreads((u1 *) &dummy);
1007 #endif
1008
1009         *threadrootmethod = NULL;
1010
1011         /*That's important, otherwise we get into trouble, if the Runtime static
1012           initializer is called before (circular dependency. This is with
1013           classpath 0.09. Another important thing is, that this has to happen
1014           after initThreads!!! */
1015
1016         if (!initialize_class(class_java_lang_System))
1017                 throw_main_exception_exit();
1018
1019         cacao_initializing = false;
1020
1021
1022         /* start worker routines **************************************************/
1023
1024         if (startit) {
1025                 classinfo        *mainclass;    /* java/lang/Class                    */
1026                 methodinfo       *m;
1027                 java_objectarray *a; 
1028                 s4                status;
1029
1030                 /* set return value to OK */
1031
1032                 status = 0;
1033
1034                 if (jar) {
1035                         /* open jar file with java.util.jar.JarFile */
1036                         mainstring = getmainclassnamefromjar(mainstring);
1037                 }
1038
1039                 /* load the main class */
1040
1041                 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1042                         throw_main_exception_exit();
1043
1044                 /* error loading class, clear exceptionptr for new exception */
1045
1046                 if (*exceptionptr || !mainclass) {
1047 /*                      *exceptionptr = NULL; */
1048
1049 /*                      *exceptionptr = */
1050 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1051 /*                                                                        mainstring); */
1052                         throw_main_exception_exit();
1053                 }
1054
1055                 /* find the `main' method of the main class */
1056
1057                 m = class_resolveclassmethod(mainclass,
1058                                                                          utf_new_char("main"), 
1059                                                                          utf_new_char("([Ljava/lang/String;)V"),
1060                                                                          class_java_lang_Object,
1061                                                                          false);
1062
1063                 if (*exceptionptr) {
1064                         throw_main_exception_exit();
1065                 }
1066
1067                 /* there is no main method or it isn't static */
1068
1069                 if (!m || !(m->flags & ACC_STATIC)) {
1070                         *exceptionptr = NULL;
1071
1072                         *exceptionptr =
1073                                 new_exception_message(string_java_lang_NoSuchMethodError,
1074                                                                           "main");
1075                         throw_main_exception_exit();
1076                 }
1077
1078                 /* build argument array */
1079
1080                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1081                 for (i = opt_ind; i < argc; i++) {
1082                         a->data[i - opt_ind] = 
1083                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1084                 }
1085
1086 #ifdef TYPEINFO_DEBUG_TEST
1087                 /* test the typeinfo system */
1088                 typeinfo_test();
1089 #endif
1090                 /*class_showmethods(currentThread->group->header.vftbl->class); */
1091
1092                 *threadrootmethod = m;
1093
1094                 /* here we go... */
1095
1096                 asm_calljavafunction(m, a, NULL, NULL, NULL);
1097
1098                 /* exception occurred? */
1099                 if (*exceptionptr) {
1100                         throw_main_exception();
1101                         status = 1;
1102                 }
1103
1104 #if defined(USE_THREADS)
1105 #if defined(NATIVE_THREADS)
1106                 joinAllThreads();
1107 #else
1108                 killThread(currentThread);
1109 #endif
1110 #endif
1111
1112                 /* now exit the JavaVM */
1113
1114 /*              (*jvm)->DestroyJavaVM(jvm); */
1115
1116                 cacao_exit(status);
1117         }
1118
1119         /************* If requested, compile all methods ********************/
1120
1121         if (compileall) {
1122                 classinfo *c;
1123                 methodinfo *m;
1124                 u4 slot;
1125                 s4 i;
1126                 classcache_name_entry *nmen;
1127                 classcache_class_entry *clsen;
1128
1129                 /* create all classes found in the classpath */
1130                 /* XXX currently only works with zip/jar's */
1131
1132                 loader_load_all_classes();
1133
1134                 /* link all classes */
1135
1136                 for (slot = 0; slot < classcache_hash.size; slot++) {
1137                         nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
1138
1139                         for (; nmen; nmen = nmen->hashlink) {
1140                                 /* iterate over all class entries */
1141
1142                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1143                                         c = clsen->classobj;
1144
1145                                         if (!c)
1146                                                 continue;
1147
1148                                         assert(c);
1149                                         assert(c->loaded);
1150                                         /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
1151
1152                                         if (!c->linked)
1153                                                 if (!link_class(c))
1154                                                         throw_main_exception_exit();
1155
1156                                         /* compile all class methods */
1157                                         for (i = 0; i < c->methodscount; i++) {
1158                                                 m = &(c->methods[i]);
1159                                                 if (m->jcode) {
1160                                                         /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
1161                                                         (void) jit_compile(m);
1162                                                 }
1163                                         }
1164                                 }
1165                         }
1166                 }
1167         }
1168
1169
1170         /******** If requested, compile a specific method ***************/
1171
1172         if (specificmethodname) {
1173                 methodinfo *m;
1174
1175                 /* create, load and link the main class */
1176
1177                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1178                         throw_main_exception_exit();
1179
1180                 if (!link_class(mainclass))
1181                         throw_main_exception_exit();
1182
1183                 if (specificsignature) {
1184                         m = class_resolveclassmethod(mainclass,
1185                                                                                  utf_new_char(specificmethodname),
1186                                                                                  utf_new_char(specificsignature),
1187                                                                                  mainclass,
1188                                                                                  false);
1189                 } else {
1190                         m = class_resolveclassmethod(mainclass,
1191                                                                                  utf_new_char(specificmethodname),
1192                                                                                  NULL,
1193                                                                                  mainclass,
1194                                                                                  false);
1195                 }
1196
1197                 if (!m) {
1198                         char message[MAXLOGTEXT];
1199                         sprintf(message, "%s%s", specificmethodname,
1200                                         specificsignature ? specificsignature : "");
1201
1202                         *exceptionptr =
1203                                 new_exception_message(string_java_lang_NoSuchMethodException,
1204                                                                           message);
1205                                                                                  
1206                         throw_main_exception_exit();
1207                 }
1208                 
1209                 jit_compile(m);
1210         }
1211
1212         cacao_shutdown(0);
1213
1214         /* keep compiler happy */
1215
1216         return 0;
1217 }
1218
1219
1220 /* cacao_exit ******************************************************************
1221
1222    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1223
1224 *******************************************************************************/
1225
1226 void cacao_exit(s4 status)
1227 {
1228         methodinfo *m;
1229
1230
1231         assert(class_java_lang_System);
1232         assert(class_java_lang_System->loaded);
1233
1234         if (!link_class(class_java_lang_System))
1235                 throw_main_exception_exit();
1236
1237         /* call java.lang.System.exit(I)V */
1238
1239         m = class_resolveclassmethod(class_java_lang_System,
1240                                                                  utf_new_char("exit"),
1241                                                                  utf_int__void,
1242                                                                  class_java_lang_Object,
1243                                                                  true);
1244         
1245         if (!m)
1246                 throw_main_exception_exit();
1247
1248         /* call the exit function with passed exit status */
1249
1250         /* both inlinevirtual and outsiders not allowed on exit */
1251         /*   not sure if permanant or temp restriction          */
1252         if (inlinevirtuals) inlineoutsiders = false; 
1253
1254         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1255
1256         /* this should never happen */
1257
1258         if (*exceptionptr)
1259                 throw_exception_exit();
1260
1261         throw_cacao_exception_exit(string_java_lang_InternalError,
1262                                                            "System.exit(I)V returned without exception");
1263 }
1264
1265
1266 /*************************** Shutdown function *********************************
1267
1268         Terminates the system immediately without freeing memory explicitly (to be
1269         used only for abnormal termination)
1270         
1271 *******************************************************************************/
1272
1273 void cacao_shutdown(s4 status)
1274 {
1275         if (opt_verbose || getcompilingtime || opt_stat) {
1276                 log_text("CACAO terminated by shutdown");
1277                 dolog("Exit status: %d\n", (s4) status);
1278         }
1279
1280         exit(status);
1281 }
1282
1283
1284 /*
1285  * These are local overrides for various environment variables in Emacs.
1286  * Please do not remove this and leave it at the end of the file, where
1287  * Emacs will automagically detect them.
1288  * ---------------------------------------------------------------------
1289  * Local variables:
1290  * mode: c
1291  * indent-tabs-mode: t
1292  * c-basic-offset: 4
1293  * tab-width: 4
1294  * End:
1295  */