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