* main: Added suck_add.
[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 3937 2005-12-10 23:59:04Z 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())
1167                 throw_main_exception_exit();
1168
1169         suck_add(bootclasspath);
1170
1171         /* initialize the memory subsystem (must be done _after_
1172            threads_preinit) */
1173
1174         if (!memory_init())
1175                 throw_main_exception_exit();
1176
1177         /* initialize the finalizer stuff: lock, linked list (must be done
1178            _after_ threads_preinit) */
1179
1180         if (!finalizer_init())
1181                 throw_main_exception_exit();
1182
1183         /* install architecture dependent signal handler used for exceptions */
1184
1185         signal_init();
1186
1187         /* initialize the codegen subsystems */
1188
1189         codegen_init();
1190
1191         /* initializes jit compiler */
1192
1193         jit_init();
1194
1195         /* machine dependent initialization */
1196
1197         md_init();
1198
1199         /* initialize the loader subsystems (must be done _after_
1200        classcache_init) */
1201
1202         if (!loader_init((u1 *) &dummy))
1203                 throw_main_exception_exit();
1204
1205         if (!linker_init())
1206                 throw_main_exception_exit();
1207
1208         if (!native_init())
1209                 throw_main_exception_exit();
1210
1211         if (!exceptions_init())
1212                 throw_main_exception_exit();
1213
1214         if (!builtin_init())
1215                 throw_main_exception_exit();
1216
1217 #if defined(USE_THREADS)
1218         if (!threads_init((u1 *) &dummy))
1219                 throw_main_exception_exit();
1220 #endif
1221
1222         /* That's important, otherwise we get into trouble, if the Runtime
1223            static initializer is called before (circular dependency. This
1224            is with classpath 0.09. Another important thing is, that this
1225            has to happen after initThreads!!! */
1226
1227         if (!initialize_class(class_java_lang_System))
1228                 throw_main_exception_exit();
1229
1230         /* JNI init creates a Java object (this means running Java code) */
1231
1232         if (!jni_init())
1233                 throw_main_exception_exit();
1234
1235 #if defined(USE_THREADS)
1236         /* finally, start the finalizer thread */
1237
1238         if (!finalizer_start_thread())
1239                 throw_main_exception_exit();
1240 #endif
1241
1242         cacao_initializing = false;
1243
1244
1245         /* start worker routines **************************************************/
1246
1247         if (startit) {
1248                 classinfo        *mainclass;    /* java/lang/Class                    */
1249                 methodinfo       *m;
1250                 java_objectarray *a; 
1251                 s4                status;
1252
1253                 /* set return value to OK */
1254
1255                 status = 0;
1256
1257                 if (jar) {
1258                         /* open jar file with java.util.jar.JarFile */
1259                         mainstring = getmainclassnamefromjar(mainstring);
1260                 }
1261
1262                 /* load the main class */
1263
1264                 if (!(mainclass = load_class_from_sysloader(utf_new_char(mainstring))))
1265                         throw_main_exception_exit();
1266
1267                 /* error loading class, clear exceptionptr for new exception */
1268
1269                 if (*exceptionptr || !mainclass) {
1270 /*                      *exceptionptr = NULL; */
1271
1272 /*                      *exceptionptr = */
1273 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1274 /*                                                                        mainstring); */
1275                         throw_main_exception_exit();
1276                 }
1277
1278                 if (!link_class(mainclass))
1279                         throw_main_exception_exit();
1280                         
1281                 /* find the `main' method of the main class */
1282
1283                 m = class_resolveclassmethod(mainclass,
1284                                                                          utf_new_char("main"), 
1285                                                                          utf_new_char("([Ljava/lang/String;)V"),
1286                                                                          class_java_lang_Object,
1287                                                                          false);
1288
1289                 if (*exceptionptr) {
1290                         throw_main_exception_exit();
1291                 }
1292
1293                 /* there is no main method or it isn't static */
1294
1295                 if (!m || !(m->flags & ACC_STATIC)) {
1296                         *exceptionptr = NULL;
1297
1298                         *exceptionptr =
1299                                 new_exception_message(string_java_lang_NoSuchMethodError,
1300                                                                           "main");
1301                         throw_main_exception_exit();
1302                 }
1303
1304                 /* build argument array */
1305
1306                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
1307                 for (i = opt_ind; i < argc; i++) {
1308                         a->data[i - opt_ind] = 
1309                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
1310                 }
1311
1312 #ifdef TYPEINFO_DEBUG_TEST
1313                 /* test the typeinfo system */
1314                 typeinfo_test();
1315 #endif
1316                 /*class_showmethods(currentThread->group->header.vftbl->class); */
1317
1318 #if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
1319                 if(dbg) {
1320                         debuggee = fork();
1321                         if (debuggee == (-1)) {
1322                                 log_text("fork error");
1323                                 exit(1);
1324                         } else {
1325                                 if (debuggee == 0) {
1326                                         /* child: allow helper process to trace us  */
1327                                         if (TRACEME != 0)  exit(0);
1328                                         
1329                                         /* give parent/helper debugger process control */
1330                                         kill(0, SIGTRAP);  /* do we need this at this stage ? */
1331
1332                                         /* continue with normal startup */      
1333
1334                                 } else {
1335
1336                                         /* parent/helper debugger process */
1337                                         wait(&waitval);
1338
1339                                         remotedbgjvmtienv = new_jvmtienv();
1340                                         /* set eventcallbacks */
1341                                         if (JVMTI_ERROR_NONE == 
1342                                                 remotedbgjvmtienv->
1343                                                 SetEventCallbacks(remotedbgjvmtienv,
1344                                                                                   &jvmti_jdwp_EventCallbacks,
1345                                                                                   sizeof(jvmti_jdwp_EventCallbacks))){
1346                                                 log_text("unable to setup event callbacks");
1347                                                 cacao_exit(1);                                          
1348                                         }
1349
1350                                         /* setup listening process (JDWP) */
1351                                         setup_debugger_process(transport);
1352
1353                                         /* start to be debugged program */
1354                                         CONT(debuggee);
1355
1356                     /* exit debugger process - todo: cleanup */
1357                                         joinAllThreads();
1358                                         cacao_exit(0);
1359                                 }
1360                         }
1361                 }
1362                 else 
1363                         debuggee= -1;
1364                 
1365 #endif
1366                 /* here we go... */
1367
1368                 asm_calljavafunction(m, a, NULL, NULL, NULL);
1369
1370                 /* exception occurred? */
1371                 if (*exceptionptr) {
1372                         throw_main_exception();
1373                         status = 1;
1374                 }
1375
1376 #if defined(USE_THREADS)
1377 #if defined(NATIVE_THREADS)
1378                 joinAllThreads();
1379 #else
1380                 killThread(currentThread);
1381 #endif
1382 #endif
1383
1384                 /* now exit the JavaVM */
1385
1386 /*              (*jvm)->DestroyJavaVM(jvm); */
1387
1388                 cacao_exit(status);
1389         }
1390
1391         /************* If requested, compile all methods ********************/
1392
1393         if (compileall) {
1394                 classinfo *c;
1395                 methodinfo *m;
1396                 u4 slot;
1397                 s4 i;
1398                 classcache_name_entry *nmen;
1399                 classcache_class_entry *clsen;
1400
1401                 /* create all classes found in the bootclasspath */
1402                 /* XXX currently only works with zip/jar's */
1403
1404                 loader_load_all_classes();
1405
1406                 /* link all classes */
1407
1408                 for (slot = 0; slot < hashtable_classcache.size; slot++) {
1409                         nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
1410
1411                         for (; nmen; nmen = nmen->hashlink) {
1412                                 /* iterate over all class entries */
1413
1414                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1415                                         c = clsen->classobj;
1416
1417                                         if (!c)
1418                                                 continue;
1419
1420                                         if (!(c->state & CLASS_LINKED)) {
1421                                                 if (!link_class(c)) {
1422                                                         fprintf(stderr, "Error linking: ");
1423                                                         utf_fprint_classname(stderr, c->name);
1424                                                         fprintf(stderr, "\n");
1425
1426                                                         /* print out exception and cause */
1427
1428                                                         exceptions_print_exception(*exceptionptr);
1429
1430                                                         /* goto next class */
1431
1432                                                         continue;
1433                                                 }
1434                                         }
1435
1436                                         /* compile all class methods */
1437
1438                                         for (i = 0; i < c->methodscount; i++) {
1439                                                 m = &(c->methods[i]);
1440
1441                                                 if (m->jcode) {
1442                                                         if (!jit_compile(m)) {
1443                                                                 fprintf(stderr, "Error compiling: ");
1444                                                                 utf_fprint_classname(stderr, c->name);
1445                                                                 fprintf(stderr, ".");
1446                                                                 utf_fprint(stderr, m->name);
1447                                                                 utf_fprint(stderr, m->descriptor);
1448                                                                 fprintf(stderr, "\n");
1449
1450                                                                 /* print out exception and cause */
1451
1452                                                                 exceptions_print_exception(*exceptionptr);
1453                                                         }
1454                                                 }
1455                                         }
1456                                 }
1457                         }
1458                 }
1459         }
1460
1461
1462         /******** If requested, compile a specific method ***************/
1463
1464         if (specificmethodname) {
1465                 methodinfo *m;
1466
1467                 /* create, load and link the main class */
1468
1469                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1470                         throw_main_exception_exit();
1471
1472                 if (!link_class(mainclass))
1473                         throw_main_exception_exit();
1474
1475                 if (specificsignature) {
1476                         m = class_resolveclassmethod(mainclass,
1477                                                                                  utf_new_char(specificmethodname),
1478                                                                                  utf_new_char(specificsignature),
1479                                                                                  mainclass,
1480                                                                                  false);
1481                 } else {
1482                         m = class_resolveclassmethod(mainclass,
1483                                                                                  utf_new_char(specificmethodname),
1484                                                                                  NULL,
1485                                                                                  mainclass,
1486                                                                                  false);
1487                 }
1488
1489                 if (!m) {
1490                         char message[MAXLOGTEXT];
1491                         sprintf(message, "%s%s", specificmethodname,
1492                                         specificsignature ? specificsignature : "");
1493
1494                         *exceptionptr =
1495                                 new_exception_message(string_java_lang_NoSuchMethodException,
1496                                                                           message);
1497                                                                                  
1498                         throw_main_exception_exit();
1499                 }
1500                 
1501                 jit_compile(m);
1502         }
1503
1504         cacao_shutdown(0);
1505
1506         /* keep compiler happy */
1507
1508         return 0;
1509 }
1510
1511
1512 /* cacao_exit ******************************************************************
1513
1514    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1515
1516 *******************************************************************************/
1517
1518 void cacao_exit(s4 status)
1519 {
1520         methodinfo *m;
1521
1522         assert(class_java_lang_System);
1523         assert(class_java_lang_System->state & CLASS_LOADED);
1524
1525 #if defined(ENABLE_JVMTI)
1526         set_jvmti_phase(JVMTI_PHASE_DEAD);
1527         agentunload();
1528 #endif
1529
1530         if (!link_class(class_java_lang_System))
1531                 throw_main_exception_exit();
1532
1533         /* signal that we are exiting */
1534
1535         cacao_exiting = true;
1536
1537         /* call java.lang.System.exit(I)V */
1538
1539         m = class_resolveclassmethod(class_java_lang_System,
1540                                                                  utf_new_char("exit"),
1541                                                                  utf_int__void,
1542                                                                  class_java_lang_Object,
1543                                                                  true);
1544         
1545         if (!m)
1546                 throw_main_exception_exit();
1547
1548         /* call the exit function with passed exit status */
1549
1550         /* both inlinevirtual and outsiders not allowed on exit */
1551         /*   not sure if permanant or temp restriction          */
1552         if (inlinevirtuals) inlineoutsiders = false; 
1553
1554         asm_calljavafunction(m, (void *) (ptrint) status, NULL, NULL, NULL);
1555
1556         /* this should never happen */
1557
1558         if (*exceptionptr)
1559                 throw_exception_exit();
1560
1561         throw_cacao_exception_exit(string_java_lang_InternalError,
1562                                                            "System.exit(I)V returned without exception");
1563 }
1564
1565
1566 /*************************** Shutdown function *********************************
1567
1568         Terminates the system immediately without freeing memory explicitly (to be
1569         used only for abnormal termination)
1570         
1571 *******************************************************************************/
1572
1573 void cacao_shutdown(s4 status)
1574 {
1575
1576 #if defined(ENABLE_JVMTI)
1577         agentunload();
1578 #endif
1579
1580         if (opt_verbose || getcompilingtime || opt_stat) {
1581                 log_text("CACAO terminated by shutdown");
1582                 dolog("Exit status: %d\n", (s4) status);
1583         }
1584
1585         exit(status);
1586 }
1587
1588
1589 /* exit_handler ****************************************************************
1590
1591    The exit_handler function is called upon program termination.
1592
1593    ATTENTION: Don't free system resources here! Some threads may still
1594    be running as this is called from VMRuntime.exit(). The OS does the
1595    cleanup for us.
1596
1597 *******************************************************************************/
1598
1599 void exit_handler(void)
1600 {
1601         /********************* Print debug tables ************************/
1602
1603 #if defined(ENABLE_DEBUG)
1604         if (showmethods)
1605                 class_showmethods(mainclass);
1606
1607         if (showconstantpool)
1608                 class_showconstantpool(mainclass);
1609
1610         if (showutf)
1611                 utf_show();
1612 #endif
1613
1614 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
1615         clear_thread_flags();           /* restores standard file descriptor
1616                                        flags */
1617 #endif
1618
1619         if (opt_verbose || getcompilingtime || opt_stat) {
1620                 log_text("CACAO terminated");
1621
1622 #if defined(STATISTICS)
1623                 if (opt_stat) {
1624                         print_stats();
1625 #ifdef TYPECHECK_STATISTICS
1626                         typecheck_print_statistics(get_logfile());
1627 #endif
1628                 }
1629
1630                 mem_usagelog(1);
1631
1632                 if (getcompilingtime)
1633                         print_times();
1634 #endif
1635         }
1636         /* vm_print_profile(stderr);*/
1637 }
1638
1639
1640 /*
1641  * These are local overrides for various environment variables in Emacs.
1642  * Please do not remove this and leave it at the end of the file, where
1643  * Emacs will automagically detect them.
1644  * ---------------------------------------------------------------------
1645  * Local variables:
1646  * mode: c
1647  * indent-tabs-mode: t
1648  * c-basic-offset: 4
1649  * tab-width: 4
1650  * End:
1651  */