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