97431961e036c644e1909a31e946c5e5d65099fd
[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 2897 2005-07-04 20:39:26Z 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         { "oss",               true,  OPT_IGNORE },
169         { "ss",                true,  OPT_IGNORE },
170         { "v",                 false, OPT_VERBOSE1 },
171         { "verbose",           false, OPT_VERBOSE },
172         { "verbose:",          true,  OPT_VERBOSESPECIFIC },
173         { "verbosecall",       false, OPT_VERBOSECALL },
174         { "verboseexception",  false, OPT_VERBOSEEXCEPTION },
175 #ifdef TYPECHECK_VERBOSE
176         { "verbosetc",         false, OPT_VERBOSETC },
177 #endif
178 #if defined(__ALPHA__)
179         { "noieee",            false, OPT_NOIEEE },
180 #endif
181         { "softnull",          false, OPT_SOFTNULL },
182         { "time",              false, OPT_TIME },
183 #if defined(STATISTICS)
184         { "stat",              false, OPT_STAT },
185 #endif
186         { "log",               true,  OPT_LOG },
187         { "c",                 true,  OPT_CHECK },
188         { "l",                 false, OPT_LOAD },
189     { "eager",             false, OPT_EAGER },
190         { "m",                 true,  OPT_METHOD },
191         { "sig",               true,  OPT_SIGNATURE },
192         { "s",                 true,  OPT_SHOW },
193         { "all",               false, OPT_ALL },
194         { "oloop",             false, OPT_OLOOP },
195         { "i",                 true,  OPT_INLINING },
196 #ifdef STATIC_ANALYSIS
197         { "rt",                false, OPT_RT },
198         { "xta",               false, OPT_XTA },
199         { "vta",               false, OPT_VTA },
200 #endif
201 #ifdef LSRA
202         { "lsra",              false, OPT_LSRA },
203 #endif
204         { "jar",               false, OPT_JAR },
205         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
206         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
207         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
208         { "version",           false, OPT_VERSION },
209         { "showversion",       false, OPT_SHOWVERSION },
210         { "help",              false, OPT_HELP },
211         { "?",                 false, OPT_HELP },
212         { "X",                 false, OPT_X },
213         { NULL,                false, 0 }
214 };
215
216
217 /* usage ***********************************************************************
218
219    Prints the correct usage syntax to stdout.
220
221 *******************************************************************************/
222
223 static void usage(void)
224 {
225         printf("Usage: cacao [-options] classname [arguments]\n");
226         printf("               (to run a class file)\n");
227         printf("       cacao [-options] -jar jarfile [arguments]\n");
228         printf("               (to run a standalone jar file)\n\n");
229
230         printf("Java options:\n");
231         printf("    -cp <path>               specify a path to look for classes\n");
232         printf("    -classpath <path>        specify a path to look for classes\n");
233         printf("    -D<name>=<value>         add an entry to the property list\n");
234         printf("    -verbose[:class|gc|jni]  enable specific verbose output\n");
235         printf("    -version                 print product version and exit\n");
236         printf("    -showversion             print product version and continue\n");
237         printf("    -help, -?                print this help message\n");
238         printf("    -X                       print help on non-standard Java options\n\n");
239
240         printf("CACAO options:\n");
241         printf("    -v                       write state-information\n");
242         printf("    -verbose                 write more information\n");
243         printf("    -verbosegc               write message for each GC\n");
244         printf("    -verbosecall             write message for each call\n");
245         printf("    -verboseexception        write message for each step of stack unwinding\n");
246 #ifdef TYPECHECK_VERBOSE
247         printf("    -verbosetc               write debug messages while typechecking\n");
248 #endif
249 #if defined(__ALPHA__)
250         printf("    -noieee                  don't use ieee compliant arithmetic\n");
251 #endif
252         printf("    -noverify                don't verify classfiles\n");
253         printf("    -liberalutf              don't warn about overlong UTF-8 sequences\n");
254         printf("    -softnull                use software nullpointer check\n");
255         printf("    -time                    measure the runtime\n");
256 #if defined(STATISTICS)
257         printf("    -stat                    detailed compiler statistics\n");
258 #endif
259         printf("    -log logfile             specify a name for the logfile\n");
260         printf("    -c(heck)b(ounds)         don't check array bounds\n");
261         printf("            s(ync)           don't check for synchronization\n");
262         printf("    -oloop                   optimize array accesses in loops\n"); 
263         printf("    -l                       don't start the class after loading\n");
264         printf("    -eager                   perform eager class loading and linking\n");
265         printf("    -all                     compile all methods, no execution\n");
266         printf("    -m                       compile only a specific method\n");
267         printf("    -sig                     specify signature for a specific method\n");
268         printf("    -s(how)a(ssembler)       show disassembled listing\n");
269         printf("           c(onstants)       show the constant pool\n");
270         printf("           d(atasegment)     show data segment listing\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                                         showdisassemble = true;
795                                         compileverbose = true;
796                                         break;
797                                 case 'c':
798                                         showconstantpool = true;
799                                         break;
800                                 case 'd':
801                                         showddatasegment = true;
802                                         break;
803                                 case 'i':
804                                         showintermediate = true;
805                                         compileverbose = true;
806                                         break;
807                                 case 'm':
808                                         showmethods = true;
809                                         break;
810                                 case 'n':
811                                         opt_shownativestub = true;
812                                         break;
813                                 case 'u':
814                                         showutf = true;
815                                         break;
816                                 default:
817                                         usage();
818                                 }
819                         }
820                         break;
821                         
822                 case OPT_OLOOP:
823                         opt_loops = true;
824                         break;
825
826                 case OPT_INLINING:
827                         for (j = 0; j < strlen(opt_arg); j++) {         
828                                 switch (opt_arg[j]) {
829                                 case 'n':
830                                      /* define in options.h; Used in main.c, jit.c & inline.c */
831 #ifdef INAFTERMAIN
832                                         useinliningm = true;
833                                         useinlining = false;
834 #else
835                                         useinlining = true;
836 #endif
837                                         break;
838                                 case 'v':
839                                         inlinevirtuals = true;
840                                         opt_rt = true;
841                                         break;
842                                 case 'e':
843                                         inlineexceptions = true;
844                                         break;
845                                 case 'p':
846                                         inlineparamopt = true;
847                                         break;
848                                 case 'o':
849                                         inlineoutsiders = true;
850                                         break;
851                                 default:
852                                         usage();
853                                 }
854                         }
855                         break;
856
857 #ifdef STATIC_ANALYSIS
858                 case OPT_RT:
859                         opt_rt = true; /* default for inlining */
860                         break;
861
862                 case OPT_XTA:
863                         opt_xta = true; /* in test currently */
864                         break;
865
866                 case OPT_VTA:
867                         printf("\nVTA is not yet available\n");
868                         opt_vta = false;
869                         /***opt_vta = true; not yet **/
870                         break;
871 #endif
872
873 #ifdef LSRA
874                 case OPT_LSRA:
875                         opt_lsra = true;
876                         break;
877 #endif
878
879                 case OPT_HELP:
880                         usage();
881                         break;
882
883                 case OPT_X:
884                         Xusage();
885                         break;
886
887                 default:
888                         printf("Unknown option: %s\n", argv[opt_ind]);
889                         usage();
890                 }
891         }
892
893         if (opt_ind >= argc)
894                 usage();
895
896
897         /* transform dots into slashes in the class name */
898
899         mainstring = argv[opt_ind++];
900
901         if (!jar) { 
902         /* do not mangle jar filename */
903
904                 for (i = strlen(mainstring) - 1; i >= 0; i--) {
905                         if (mainstring[i] == '.') mainstring[i] = '/';
906                 }
907
908         } else {
909                 /* put jarfile in classpath */
910
911                 cp = classpath;
912
913                 classpath = MNEW(char, strlen(mainstring) + strlen(":") +
914                                                  strlen(classpath) + strlen("0"));
915
916                 strcpy(classpath, mainstring);
917                 strcat(classpath, ":");
918                 strcat(classpath, cp);
919                 
920                 MFREE(cp, char, strlen(cp));
921         }
922
923         /**************************** Program start *****************************/
924
925         log_init(logfilename);
926
927         if (opt_verbose)
928                 log_text("CACAO started -------------------------------------------------------");
929
930         /* initialize JavaVM */
931
932         vm_args.version = 0x00010001; /* New in 1.1.2: VM version */
933
934         /* Get the default initialization arguments and set the class path */
935
936         JNI_GetDefaultJavaVMInitArgs(&vm_args);
937
938         vm_args.minHeapSize = heapstartsize;
939         vm_args.maxHeapSize = heapmaxsize;
940
941         vm_args.classpath = classpath;
942  
943         /* load and initialize a Java VM, return a JNI interface pointer in env */
944
945         JNI_CreateJavaVM(&jvm, &env, &vm_args);
946
947
948         /* initialize the garbage collector */
949
950         gc_init(heapmaxsize, heapstartsize);
951
952         tables_init();
953
954         /* initialize the loader with bootclasspath */
955
956         suck_init(bootclasspath);
957
958         cacao_initializing = true;
959
960 #if defined(USE_THREADS)
961 #if defined(NATIVE_THREADS)
962         initThreadsEarly();
963 #endif
964         initLocks();
965 #endif
966
967         /* install architecture dependent signal handler used for exceptions */
968
969         signal_init();
970
971         /* initialize the codegen sub systems */
972
973         codegen_init();
974
975         /* initializes jit compiler */
976
977         jit_init();
978
979         /* machine dependent initialization */
980
981         md_init();
982
983         /* initialize some cacao subsystems */
984
985         utf8_init();
986
987         if (!loader_init((u1 *) &dummy))
988                 throw_main_exception_exit();
989
990         if (!linker_init())
991                 throw_main_exception_exit();
992
993         if (!native_init())
994                 throw_main_exception_exit();
995
996         if (!exceptions_init())
997                 throw_main_exception_exit();
998
999         if (!builtin_init())
1000                 throw_main_exception_exit();
1001
1002 #if defined(USE_THREADS)
1003         initThreads((u1 *) &dummy);
1004 #endif
1005
1006         *threadrootmethod = NULL;
1007
1008         /*That's important, otherwise we get into trouble, if the Runtime static
1009           initializer is called before (circular dependency. This is with
1010           classpath 0.09. Another important thing is, that this has to happen
1011           after initThreads!!! */
1012
1013         if (!initialize_class(class_java_lang_System))
1014                 throw_main_exception_exit();
1015
1016         cacao_initializing = false;
1017
1018
1019         /* start worker routines **************************************************/
1020
1021         if (startit) {
1022                 classinfo        *mainclass;    /* java/lang/Class                    */
1023                 methodinfo       *m;
1024                 java_objectarray *a; 
1025                 s4                status;
1026
1027                 /* set return value to OK */
1028
1029                 status = 0;
1030
1031                 if (jar) {
1032                         /* open jar file with java.util.jar.JarFile */
1033                         mainstring = getmainclassnamefromjar(mainstring);
1034                 }
1035
1036                 /* load the main class */
1037
1038                 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1039                         throw_main_exception_exit();
1040
1041                 /* error loading class, clear exceptionptr for new exception */
1042
1043                 if (*exceptionptr || !mainclass) {
1044 /*                      *exceptionptr = NULL; */
1045
1046 /*                      *exceptionptr = */
1047 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1048 /*                                                                        mainstring); */
1049                         throw_main_exception_exit();
1050                 }
1051
1052                 /* find the `main' method of the main class */
1053
1054                 m = class_resolveclassmethod(mainclass,
1055                                                                          utf_new_char("main"), 
1056                                                                          utf_new_char("([Ljava/lang/String;)V"),
1057                                                                          class_java_lang_Object,
1058                                                                          false);
1059
1060                 if (*exceptionptr) {
1061                         throw_main_exception_exit();
1062                 }
1063
1064                 /* there is no main method or it isn't static */
1065
1066                 if (!m || !(m->flags & ACC_STATIC)) {
1067                         *exceptionptr = NULL;
1068
1069                         *exceptionptr =
1070                                 new_exception_message(string_java_lang_NoSuchMethodError,
1071                                                                           "main");
1072                         throw_main_exception_exit();
1073                 }
1074
1075                 /* build argument array */
1076
1077                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1078                 for (i = opt_ind; i < argc; i++) {
1079                         a->data[i - opt_ind] = 
1080                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1081                 }
1082
1083 #ifdef TYPEINFO_DEBUG_TEST
1084                 /* test the typeinfo system */
1085                 typeinfo_test();
1086 #endif
1087                 /*class_showmethods(currentThread->group->header.vftbl->class); */
1088
1089                 *threadrootmethod = m;
1090
1091                 /* here we go... */
1092
1093                 asm_calljavafunction(m, a, NULL, NULL, NULL);
1094
1095                 /* exception occurred? */
1096                 if (*exceptionptr) {
1097                         throw_main_exception();
1098                         status = 1;
1099                 }
1100
1101 #if defined(USE_THREADS)
1102 #if defined(NATIVE_THREADS)
1103                 joinAllThreads();
1104 #else
1105                 killThread(currentThread);
1106 #endif
1107 #endif
1108
1109                 /* now exit the JavaVM */
1110
1111 /*              (*jvm)->DestroyJavaVM(jvm); */
1112
1113                 cacao_exit(status);
1114         }
1115
1116         /************* If requested, compile all methods ********************/
1117
1118         if (compileall) {
1119                 classinfo *c;
1120                 methodinfo *m;
1121                 u4 slot;
1122                 s4 i;
1123                 classcache_name_entry *nmen;
1124                 classcache_class_entry *clsen;
1125
1126                 /* create all classes found in the classpath */
1127                 /* XXX currently only works with zip/jar's */
1128
1129                 loader_load_all_classes();
1130
1131                 /* link all classes */
1132
1133                 for (slot = 0; slot < classcache_hash.size; slot++) {
1134                         nmen = (classcache_name_entry *) classcache_hash.ptr[slot];
1135
1136                         for (; nmen; nmen = nmen->hashlink) {
1137                                 /* iterate over all class entries */
1138
1139                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1140                                         c = clsen->classobj;
1141
1142                                         if (!c)
1143                                                 continue;
1144
1145                                         assert(c);
1146                                         assert(c->loaded);
1147                                         /*utf_fprint_classname(stderr,c->name);fprintf(stderr,"\n");*/
1148
1149                                         if (!c->linked)
1150                                                 if (!link_class(c))
1151                                                         throw_main_exception_exit();
1152
1153                                         /* compile all class methods */
1154                                         for (i = 0; i < c->methodscount; i++) {
1155                                                 m = &(c->methods[i]);
1156                                                 if (m->jcode) {
1157                                                         /*fprintf(stderr,"    compiling:");utf_fprint(stderr,m->name);fprintf(stderr,"\n");*/
1158                                                         (void) jit_compile(m);
1159                                                 }
1160                                         }
1161                                 }
1162                         }
1163                 }
1164         }
1165
1166
1167         /******** If requested, compile a specific method ***************/
1168
1169         if (specificmethodname) {
1170                 methodinfo *m;
1171
1172                 /* create, load and link the main class */
1173
1174                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1175                         throw_main_exception_exit();
1176
1177                 if (!link_class(mainclass))
1178                         throw_main_exception_exit();
1179
1180                 if (specificsignature) {
1181                         m = class_resolveclassmethod(mainclass,
1182                                                                                  utf_new_char(specificmethodname),
1183                                                                                  utf_new_char(specificsignature),
1184                                                                                  mainclass,
1185                                                                                  false);
1186                 } else {
1187                         m = class_resolveclassmethod(mainclass,
1188                                                                                  utf_new_char(specificmethodname),
1189                                                                                  NULL,
1190                                                                                  mainclass,
1191                                                                                  false);
1192                 }
1193
1194                 if (!m) {
1195                         char message[MAXLOGTEXT];
1196                         sprintf(message, "%s%s", specificmethodname,
1197                                         specificsignature ? specificsignature : "");
1198
1199                         *exceptionptr =
1200                                 new_exception_message(string_java_lang_NoSuchMethodException,
1201                                                                           message);
1202                                                                                  
1203                         throw_main_exception_exit();
1204                 }
1205                 
1206                 jit_compile(m);
1207         }
1208
1209         cacao_shutdown(0);
1210
1211         /* keep compiler happy */
1212
1213         return 0;
1214 }
1215
1216
1217 /* cacao_exit ******************************************************************
1218
1219    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1220
1221 *******************************************************************************/
1222
1223 void cacao_exit(s4 status)
1224 {
1225         methodinfo *m;
1226
1227
1228         assert(class_java_lang_System);
1229         assert(class_java_lang_System->loaded);
1230
1231         if (!link_class(class_java_lang_System))
1232                 throw_main_exception_exit();
1233
1234         /* call java.lang.System.exit(I)V */
1235
1236         m = class_resolveclassmethod(class_java_lang_System,
1237                                                                  utf_new_char("exit"),
1238                                                                  utf_int__void,
1239                                                                  class_java_lang_Object,
1240                                                                  true);
1241         
1242         if (!m)
1243                 throw_main_exception_exit();
1244
1245         /* call the exit function with passed exit status */
1246
1247         /* both inlinevirtual and outsiders not allowed on exit */
1248         /*   not sure if permanant or temp restriction          */
1249         if (inlinevirtuals) inlineoutsiders = false; 
1250
1251         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1252
1253         /* this should never happen */
1254
1255         if (*exceptionptr)
1256                 throw_exception_exit();
1257
1258         throw_cacao_exception_exit(string_java_lang_InternalError,
1259                                                            "System.exit(I)V returned without exception");
1260 }
1261
1262
1263 /*************************** Shutdown function *********************************
1264
1265         Terminates the system immediately without freeing memory explicitly (to be
1266         used only for abnormal termination)
1267         
1268 *******************************************************************************/
1269
1270 void cacao_shutdown(s4 status)
1271 {
1272         if (opt_verbose || getcompilingtime || opt_stat) {
1273                 log_text("CACAO terminated by shutdown");
1274                 dolog("Exit status: %d\n", (s4) status);
1275         }
1276
1277         exit(status);
1278 }
1279
1280
1281 /*
1282  * These are local overrides for various environment variables in Emacs.
1283  * Please do not remove this and leave it at the end of the file, where
1284  * Emacs will automagically detect them.
1285  * ---------------------------------------------------------------------
1286  * Local variables:
1287  * mode: c
1288  * indent-tabs-mode: t
1289  * c-basic-offset: 4
1290  * tab-width: 4
1291  * End:
1292  */