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