Move typedef's in front of includes.
[cacao.git] / main.c
1 /* main.c - contains main() and variables for the global options
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Reinhard Grafl
29
30    Changes: Andi Krall
31             Mark Probst
32             Philipp Tomsich
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: main.c 1590 2004-11-25 13:24:49Z christian $
41
42 */
43
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include "exceptions.h"
48 #include "main.h"
49 #include "options.h"
50 #include "global.h"
51 #include "tables.h"
52 #include "loader.h"
53 #include "jit/jit.h"
54 #include "asmpart.h"
55 #include "builtin.h"
56 #include "native.h"
57 #include "statistics.h"
58 #include "mm/boehm.h"
59 #include "threads/thread.h"
60 #include "toolbox/logging.h"
61 #include "toolbox/memory.h"
62 #include "jit/parseRTstats.h"
63 #include "nat/java_io_File.h"            /* required by java_lang_Runtime.h   */
64 #include "nat/java_util_Properties.h"    /* required by java_lang_Runtime.h   */
65 #include "nat/java_lang_Runtime.h"
66 #include "nat/java_lang_Throwable.h"
67
68 #ifdef TYPEINFO_DEBUG_TEST
69 #include "typeinfo.h"
70 #endif
71
72
73 bool cacao_initializing;
74
75 char *classpath;                        /* contains classpath                 */
76 char *mainstring;
77 static classinfo *mainclass;
78
79 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
80 void **stackbottom = 0;
81 #endif
82
83 /* define command line options ************************************************/
84
85 #define OPT_CLASSPATH   2
86 #define OPT_D           3
87 #define OPT_MS          4
88 #define OPT_MX          5
89 #define OPT_VERBOSE1    6
90 #define OPT_VERBOSE     7
91 #define OPT_VERBOSEGC   8
92 #define OPT_VERBOSECALL 9
93 #define OPT_NOIEEE      10
94 #define OPT_SOFTNULL    11
95 #define OPT_TIME        12
96 #define OPT_STAT        13
97 #define OPT_LOG         14
98 #define OPT_CHECK       15
99 #define OPT_LOAD        16
100 #define OPT_METHOD      17
101 #define OPT_SIGNATURE   18
102 #define OPT_SHOW        19
103 #define OPT_ALL         20
104 #define OPT_OLOOP       24
105 #define OPT_INLINING    25
106 #define OPT_RT          26
107 #define OPT_XTA         27 
108 #define OPT_VTA         28
109 #define OPT_VERBOSETC   29
110 #define OPT_NOVERIFY    30
111 #define OPT_LIBERALUTF  31
112 #define OPT_VERBOSEEXCEPTION 32
113 #define OPT_EAGER            33
114 #define OPT_LSRA 34
115
116
117 opt_struct opts[] = {
118         {"classpath",        true,   OPT_CLASSPATH},
119         {"cp",               true,   OPT_CLASSPATH},
120         {"D",                true,   OPT_D},
121         {"Xms",              true,   OPT_MS},
122         {"Xmx",              true,   OPT_MX},
123         {"ms",               true,   OPT_MS},
124         {"mx",               true,   OPT_MX},
125         {"noasyncgc",        false,  OPT_IGNORE},
126         {"noverify",         false,  OPT_NOVERIFY},
127         {"liberalutf",       false,  OPT_LIBERALUTF},
128         {"oss",              true,   OPT_IGNORE},
129         {"ss",               true,   OPT_IGNORE},
130         {"v",                false,  OPT_VERBOSE1},
131         {"verbose",          false,  OPT_VERBOSE},
132         {"verbosegc",        false,  OPT_VERBOSEGC},
133         {"verbosecall",      false,  OPT_VERBOSECALL},
134         {"verboseexception", false,  OPT_VERBOSEEXCEPTION},
135 #ifdef TYPECHECK_VERBOSE
136         {"verbosetc",        false,  OPT_VERBOSETC},
137 #endif
138 #if defined(__ALPHA__)
139         {"noieee",           false,  OPT_NOIEEE},
140 #endif
141         {"softnull",         false,  OPT_SOFTNULL},
142         {"time",             false,  OPT_TIME},
143         {"stat",             false,  OPT_STAT},
144         {"log",              true,   OPT_LOG},
145         {"c",                true,   OPT_CHECK},
146         {"l",                false,  OPT_LOAD},
147     { "eager",            false,  OPT_EAGER },
148         {"m",                true,   OPT_METHOD},
149         {"sig",              true,   OPT_SIGNATURE},
150         {"s",                true,   OPT_SHOW},
151         {"all",              false,  OPT_ALL},
152         {"oloop",            false,  OPT_OLOOP},
153         {"i",                    true,   OPT_INLINING},
154         {"rt",               false,  OPT_RT},
155         {"xta",              false,  OPT_XTA},
156         {"vta",              false,  OPT_VTA},
157         {"lsra", false, OPT_LSRA},
158         {NULL,               false,  0}
159 };
160
161
162 /******************** interne Function: print_usage ************************
163
164 Prints the correct usage syntax to stdout.
165
166 ***************************************************************************/
167
168 static void usage()
169 {
170         printf("USAGE: cacao [options] classname [program arguments]\n");
171         printf("Options:\n");
172         printf("          -cp path ............. specify a path to look for classes\n");
173         printf("          -classpath path ...... specify a path to look for classes\n");
174         printf("          -Dpropertyname=value . add an entry to the property list\n");
175         printf("          -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
176         printf("          -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
177         printf("          -mx maxmem[kK|mM] .... specify the size for the heap\n");
178         printf("          -ms initmem[kK|mM] ... specify the initial size for the heap\n");
179         printf("          -v ................... write state-information\n");
180         printf("          -verbose ............. write more information\n");
181         printf("          -verbosegc ........... write message for each GC\n");
182         printf("          -verbosecall ......... write message for each call\n");
183         printf("          -verboseexception .... write message for each step of stack unwinding\n");
184 #ifdef TYPECHECK_VERBOSE
185         printf("          -verbosetc ........... write debug messages while typechecking\n");
186 #endif
187 #if defined(__ALPHA__)
188         printf("          -noieee .............. don't use ieee compliant arithmetic\n");
189 #endif
190         printf("          -noverify ............ don't verify classfiles\n");
191         printf("          -liberalutf........... don't warn about overlong UTF-8 sequences\n");
192         printf("          -softnull ............ use software nullpointer check\n");
193         printf("          -time ................ measure the runtime\n");
194         printf("          -stat ................ detailed compiler statistics\n");
195         printf("          -log logfile ......... specify a name for the logfile\n");
196         printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
197         printf("                  s(ync) ....... don't check for synchronization\n");
198         printf("          -oloop ............... optimize array accesses in loops\n"); 
199         printf("          -l ................... don't start the class after loading\n");
200         printf("          -eager ............... perform eager class loading and linking\n");
201         printf("          -all ................. compile all methods, no execution\n");
202         printf("          -m ................... compile only a specific method\n");
203         printf("          -sig ................. specify signature for a specific method\n");
204         printf("          -s(how)a(ssembler) ... show disassembled listing\n");
205         printf("                 c(onstants) ... show the constant pool\n");
206         printf("                 d(atasegment).. show data segment listing\n");
207         printf("                 i(ntermediate). show intermediate representation\n");
208         printf("                 m(ethods)...... show class fields and methods\n");
209         printf("                 u(tf) ......... show the utf - hash\n");
210         printf("          -i     n ............. activate inlining\n");
211         printf("                 v ............. inline virtual methods\n");
212         printf("                                 uses/turns rt option on\n");
213         printf("                 e ............. inline methods with exceptions\n");
214         printf("                 p ............. optimize argument renaming\n");
215         printf("                 o ............. inline methods of foreign classes\n");
216         printf("          -rt .................. use rapid type analysis\n");
217         printf("          -xta ................. use x type analysis\n");
218         printf("          -vta ................. use variable type analysis\n");
219         printf("          -lsra ................ use linear scan register allocation\n");
220
221         /* exit with error code */
222
223         exit(1);
224 }   
225
226
227 #ifdef TYPECHECK_STATISTICS
228 void typecheck_print_statistics(FILE *file);
229 #endif
230
231
232 /*
233  * void exit_handler(void)
234  * -----------------------
235  * The exit_handler function is called upon program termination to shutdown
236  * the various subsystems and release the resources allocated to the VM.
237  */
238 void exit_handler(void)
239 {
240         /********************* Print debug tables ************************/
241                                 
242         if (showmethods) class_showmethods(mainclass);
243         if (showconstantpool) class_showconstantpool(mainclass);
244         if (showutf) utf_show();
245
246 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
247         clear_thread_flags();           /* restores standard file descriptor
248                                        flags */
249 #endif
250
251         /************************ Free all resources *******************/
252
253         loader_close();
254         tables_close();
255
256         MFREE(classpath, u1, strlen(classpath));
257
258         if (opt_verbose || getcompilingtime || opt_stat) {
259                 log_text("CACAO terminated");
260                 if (opt_stat) {
261                         print_stats();
262 #ifdef TYPECHECK_STATISTICS
263                         typecheck_print_statistics(get_logfile());
264 #endif
265                 }
266                 if (getcompilingtime)
267                         print_times();
268                 mem_usagelog(1);
269         }
270 }
271
272
273 /************************** Function: main *******************************
274
275    The main program.
276    
277 **************************************************************************/
278
279 int main(int argc, char **argv)
280 {
281         s4 i, j;
282         void *dummy;
283         
284         /********** interne (nur fuer main relevante Optionen) **************/
285    
286         char logfilename[200] = "";
287         u4 heapmaxsize = 64 * 1024 * 1024;
288         u4 heapstartsize = 200 * 1024;
289         char *cp;
290         bool startit = true;
291         char *specificmethodname = NULL;
292         char *specificsignature = NULL;
293
294 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
295         stackbottom = &dummy;
296 #endif
297         
298         if (atexit(exit_handler))
299                 throw_cacao_exception_exit(string_java_lang_InternalError,
300                                                                    "Unable to register exit_handler");
301
302
303         /************ Collect info from the environment ************************/
304
305         /* set an initial, minimal classpath */
306         classpath = MNEW(char, 2);
307         strcpy(classpath, ".");
308
309         /* get classpath environment */
310         cp = getenv("CLASSPATH");
311         if (cp) {
312                 classpath = MREALLOC(classpath,
313                                                          char,
314                                                          strlen(classpath),
315                                                          strlen(classpath) + 1 + strlen(cp) + 1);
316                 strcat(classpath, ":");
317                 strcat(classpath, cp);
318         }
319
320         /***************** Interpret the command line *****************/
321    
322         checknull = false;
323         opt_noieee = false;
324
325         while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
326                 switch (i) {
327                 case OPT_IGNORE:
328                         break;
329                         
330                 case OPT_CLASSPATH:
331                         /* forget old classpath and set the argument as new classpath */
332                         MFREE(classpath, char, strlen(classpath));
333
334                         classpath = MNEW(char, strlen(opt_arg) + 1);
335                         strcpy(classpath, opt_arg);
336                         break;
337                                 
338                 case OPT_D:
339                         {
340                                 int n;
341                                 int l = strlen(opt_arg);
342                                 for (n = 0; n < l; n++) {
343                                         if (opt_arg[n] == '=') {
344                                                 opt_arg[n] = '\0';
345                                                 create_property(opt_arg, opt_arg + n + 1);
346                                                 goto didit;
347                                         }
348                                 }
349                                 usage();
350                                         
351                         didit: ;
352                         }       
353                         break;
354
355                 case OPT_MS:
356                 case OPT_MX:
357                         {
358                                 char c;
359                                 c = opt_arg[strlen(opt_arg) - 1];
360
361                                 if (c == 'k' || c == 'K') {
362                                         j = 1024 * atoi(opt_arg);
363
364                                 } else if (c == 'm' || c == 'M') {
365                                         j = 1024 * 1024 * atoi(opt_arg);
366
367                                 } else j = atoi(opt_arg);
368
369                                 if (i == OPT_MX) heapmaxsize = j;
370                                 else heapstartsize = j;
371                         }
372                         break;
373
374                 case OPT_VERBOSE1:
375                         opt_verbose = true;
376                         break;
377
378                 case OPT_VERBOSE:
379                         opt_verbose = true;
380                         loadverbose = true;
381                         linkverbose = true;
382                         initverbose = true;
383                         compileverbose = true;
384                         break;
385
386                 case OPT_VERBOSEEXCEPTION:
387                         verboseexception = true;
388                         break;
389
390                 case OPT_VERBOSEGC:
391                         collectverbose = true;
392                         break;
393
394 #ifdef TYPECHECK_VERBOSE
395                 case OPT_VERBOSETC:
396                         typecheckverbose = true;
397                         break;
398 #endif
399                                 
400                 case OPT_VERBOSECALL:
401                         runverbose = true;
402                         break;
403                                 
404                 case OPT_NOIEEE:
405                         opt_noieee = true;
406                         break;
407
408                 case OPT_NOVERIFY:
409                         opt_verify = false;
410                         break;
411
412                 case OPT_LIBERALUTF:
413                         opt_liberalutf = true;
414                         break;
415
416                 case OPT_SOFTNULL:
417                         checknull = true;
418                         break;
419
420                 case OPT_TIME:
421                         getcompilingtime = true;
422                         getloadingtime = true;
423                         break;
424                                         
425                 case OPT_STAT:
426                         opt_stat = true;
427                         break;
428                                         
429                 case OPT_LOG:
430                         strcpy(logfilename, opt_arg);
431                         break;
432                         
433                 case OPT_CHECK:
434                         for (j = 0; j < strlen(opt_arg); j++) {
435                                 switch (opt_arg[j]) {
436                                 case 'b':
437                                         checkbounds = false;
438                                         break;
439                                 case 's':
440                                         checksync = false;
441                                         break;
442                                 default:
443                                         usage();
444                                 }
445                         }
446                         break;
447                         
448                 case OPT_LOAD:
449                         startit = false;
450                         makeinitializations = false;
451                         break;
452
453                 case OPT_EAGER:
454                         opt_eager = true;
455                         break;
456
457                 case OPT_METHOD:
458                         startit = false;
459                         specificmethodname = opt_arg;
460                         makeinitializations = false;
461                         break;
462                         
463                 case OPT_SIGNATURE:
464                         specificsignature = opt_arg;
465                         break;
466                         
467                 case OPT_ALL:
468                         compileall = true;
469                         startit = false;
470                         makeinitializations = false;
471                         break;
472                         
473                 case OPT_SHOW:       /* Display options */
474                         for (j = 0; j < strlen(opt_arg); j++) {         
475                                 switch (opt_arg[j]) {
476                                 case 'a':
477                                         showdisassemble = true;
478                                         compileverbose = true;
479                                         break;
480                                 case 'c':
481                                         showconstantpool = true;
482                                         break;
483                                 case 'd':
484                                         showddatasegment = true;
485                                         break;
486                                 case 'i':
487                                         showintermediate = true;
488                                         compileverbose = true;
489                                         break;
490                                 case 'm':
491                                         showmethods = true;
492                                         break;
493                                 case 'u':
494                                         showutf = true;
495                                         break;
496                                 default:
497                                         usage();
498                                 }
499                         }
500                         break;
501                         
502                 case OPT_OLOOP:
503                         opt_loops = true;
504                         break;
505
506                 case OPT_INLINING:
507                         for (j = 0; j < strlen(opt_arg); j++) {         
508                                 switch (opt_arg[j]) {
509                                 case 'n':
510                                      /* define in options.h; Used in main.c, jit.c & inline.c */
511                                      #ifdef INAFTERMAIN
512                                         useinliningm = true;
513                                         useinlining = false;
514                                      #else
515                                         useinlining = true;
516                                      #endif
517                                         break;
518                                 case 'v':
519                                         inlinevirtuals = true;
520                                         opt_rt = true;
521                                         break;
522                                 case 'e':
523                                         inlineexceptions = true;
524                                         break;
525                                 case 'p':
526                                         inlineparamopt = true;
527                                         break;
528                                 case 'o':
529                                         inlineoutsiders = true;
530                                         break;
531                                 default:
532                                         usage();
533                                 }
534                         }
535                         break;
536
537                 case OPT_RT:
538                         opt_rt = true;
539                         break;
540
541                 case OPT_XTA:
542                         opt_xta = false; /**not yet **/
543                         break;
544
545                 case OPT_VTA:
546                         /***opt_vta = true; not yet **/
547                         break;
548
549                 case OPT_LSRA:
550 #if defined(__I386__) || defined(__ALPHA__)
551                         opt_lsra = true;
552 #else
553                         printf("LSRA not available for this architecture\n");
554                         opt_lsra = false;
555 #endif
556                         break;
557
558                 default:
559                         usage();
560                 }
561         }
562
563         if (opt_ind >= argc)
564                 usage();
565
566 #if 0
567         {
568                 char *gnucp = "/home/twisti/src/cacao/cacaodev/classpath/lib/:";
569                 cp = classpath;
570
571                 classpath = MNEW(char, strlen(cp) + strlen(classpath) + 1);
572                 strcpy(classpath, gnucp);
573                 strcat(classpath, cp);
574
575                 MFREE(cp, char, strlen(cp));
576         }
577 #endif
578
579         mainstring = argv[opt_ind++];
580         for (i = strlen(mainstring) - 1; i >= 0; i--) {     /* Transform dots into slashes */
581                 if (mainstring[i] == '.') mainstring[i] = '/';  /* in the class name */
582         }
583
584
585         /**************************** Program start *****************************/
586
587         log_init(logfilename);
588         if (opt_verbose)
589                 log_text("CACAO started -------------------------------------------------------");
590
591         /* initialize the garbage collector */
592         gc_init(heapmaxsize, heapstartsize);
593
594         tables_init();
595         suck_init(classpath);
596
597         cacao_initializing = true;
598
599 #if defined(USE_THREADS)
600 #if defined(NATIVE_THREADS)
601         initThreadsEarly();
602 #endif
603         initLocks();
604 #endif
605
606         /* install architecture dependent signal handler used for exceptions */
607         init_exceptions();
608
609         /* initializes jit compiler and codegen stuff */
610         jit_init();
611
612         loader_init((u1 *) &dummy);
613
614         /* initialize exceptions used in the system */
615         if (!init_system_exceptions())
616                 throw_main_exception_exit();
617
618         native_loadclasses();
619
620 #if defined(USE_THREADS)
621         initThreads((u1 *) &dummy);
622 #endif
623
624         *threadrootmethod = NULL;
625
626         /*That's important, otherwise we get into trouble, if the Runtime static
627           initializer is called before (circular dependency. This is with
628           classpath 0.09. Another important thing is, that this has to happen
629           after initThreads!!! */
630
631         if (!class_init(class_new(utf_new_char("java/lang/System"))))
632                 throw_main_exception_exit();
633
634         
635         
636 /*        jni_init(); */
637         cacao_initializing = false;
638
639         /************************* Start worker routines ********************/
640
641         if (startit) {
642                 methodinfo *mainmethod;
643                 java_objectarray *a; 
644                 s4 status;
645
646                 /* set return value to OK */
647                 status = 0;
648
649                 /* create, load and link the main class */
650                 mainclass = class_new(utf_new_char(mainstring));
651
652                 if (!class_load(mainclass))
653                         throw_main_exception_exit();
654
655                 if (!class_link(mainclass))
656                         throw_main_exception_exit();
657
658                 mainmethod = class_resolveclassmethod(mainclass,
659                                                                                           utf_new_char("main"), 
660                                                                                           utf_new_char("([Ljava/lang/String;)V"),
661                                                                                           mainclass,
662                                                                                           false);
663
664                 /* problems with main method? */
665 /*              if (*exceptionptr) */
666 /*                      throw_exception_exit(); */
667
668                 /* there is no main method or it isn't static */
669                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
670                         *exceptionptr =
671                                 new_exception_message(string_java_lang_NoSuchMethodError,
672                                                                           "main");
673                         throw_main_exception_exit();
674                 }
675
676                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
677                 for (i = opt_ind; i < argc; i++) {
678                         a->data[i - opt_ind] = 
679                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
680                 }
681
682 #ifdef TYPEINFO_DEBUG_TEST
683                 /* test the typeinfo system */
684                 typeinfo_test();
685 #endif
686                 /*class_showmethods(currentThread->group->header.vftbl->class); */
687
688                 *threadrootmethod = mainmethod;
689
690
691                 /* here we go... */
692                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
693
694                 /* exception occurred? */
695                 if (*exceptionptr) {
696                         throw_main_exception();
697                         status = 1;
698                 }
699
700 #if defined(USE_THREADS)
701 #if defined(NATIVE_THREADS)
702                 joinAllThreads();
703 #else
704                 killThread(currentThread);
705 #endif
706 #endif
707
708                 /* now exit the JavaVM */
709
710                 cacao_exit(status);
711         }
712
713         /************* If requested, compile all methods ********************/
714
715         if (compileall) {
716                 classinfo *c;
717                 methodinfo *m;
718                 u4 slot;
719                 s4 i;
720
721                 /* create all classes found in the classpath */
722                 /* XXX currently only works with zip/jar's */
723                 create_all_classes();
724
725                 /* load and link all classes */
726                 for (slot = 0; slot < class_hash.size; slot++) {
727                         c = class_hash.ptr[slot];
728
729                         while (c) {
730                                 if (!c->loaded)
731                                         if (!class_load(c))
732                                                 throw_main_exception_exit();
733
734                                 if (!c->linked)
735                                         if (!class_link(c))
736                                                 throw_main_exception_exit();
737
738                                 /* compile all class methods */
739                                 for (i = 0; i < c->methodscount; i++) {
740                                         m = &(c->methods[i]);
741                                         if (m->jcode) {
742                                                 (void) jit_compile(m);
743                                         }
744                                 }
745
746                                 c = c->hashlink;
747                         }
748                 }
749         }
750
751
752         /******** If requested, compile a specific method ***************/
753
754         if (specificmethodname) {
755                 methodinfo *m;
756
757                 /* create, load and link the main class */
758                 mainclass = class_new(utf_new_char(mainstring));
759
760                 if (!class_load(mainclass))
761                         throw_main_exception_exit();
762
763                 if (!class_link(mainclass))
764                         throw_main_exception_exit();
765
766                 if (specificsignature) {
767                         m = class_resolveclassmethod(mainclass,
768                                                                                  utf_new_char(specificmethodname),
769                                                                                  utf_new_char(specificsignature),
770                                                                                  mainclass,
771                                                                                  false);
772                 } else {
773                         m = class_resolveclassmethod(mainclass,
774                                                                                  utf_new_char(specificmethodname),
775                                                                                  NULL,
776                                                                                  mainclass,
777                                                                                  false);
778                 }
779
780                 if (!m) {
781                         char message[MAXLOGTEXT];
782                         sprintf(message, "%s%s", specificmethodname,
783                                         specificsignature ? specificsignature : "");
784
785                         *exceptionptr =
786                                 new_exception_message(string_java_lang_NoSuchMethodException,
787                                                                           message);
788                                                                                  
789                         throw_main_exception_exit();
790                 }
791                 
792                 jit_compile(m);
793         }
794
795         cacao_shutdown(0);
796
797         /* keep compiler happy */
798
799         return 0;
800 }
801
802
803 /* cacao_exit ******************************************************************
804
805    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
806
807 *******************************************************************************/
808
809 void cacao_exit(s4 status)
810 {
811         classinfo *c;
812         methodinfo *m;
813
814         /* class should already be loaded, but who knows... */
815
816         c = class_new(utf_new_char("java/lang/System"));
817
818         if (!class_load(c))
819                 throw_main_exception_exit();
820
821         if (!class_link(c))
822                 throw_main_exception_exit();
823
824         /* call System.exit(I)V */
825
826         m = class_resolveclassmethod(c,
827                                                                  utf_new_char("exit"),
828                                                                  utf_new_char("(I)V"),
829                                                                  class_java_lang_Object,
830                                                                  true);
831         
832         if (!m)
833                 throw_main_exception_exit();
834
835         /* call the exit function with passed exit status */
836
837         asm_calljavafunction(m,
838 #if POINTERSIZE == 8
839                                                  (void *) (s8) status,
840 #else
841                                                  (void *) status,
842 #endif
843                                                  NULL,
844                                                  NULL,
845                                                  NULL);
846
847         /* this should never happen */
848
849         if (*exceptionptr)
850                 throw_exception_exit();
851
852         throw_cacao_exception_exit(string_java_lang_InternalError,
853                                                            "System.exit(I)V returned without exception");
854 }
855
856
857 /*************************** Shutdown function *********************************
858
859         Terminates the system immediately without freeing memory explicitly (to be
860         used only for abnormal termination)
861         
862 *******************************************************************************/
863
864 void cacao_shutdown(s4 status)
865 {
866         if (opt_verbose || getcompilingtime || opt_stat) {
867                 log_text("CACAO terminated by shutdown");
868                 dolog("Exit status: %d\n", (s4) status);
869         }
870
871         exit(status);
872 }
873
874
875 /*
876  * These are local overrides for various environment variables in Emacs.
877  * Please do not remove this and leave it at the end of the file, where
878  * Emacs will automagically detect them.
879  * ---------------------------------------------------------------------
880  * Local variables:
881  * mode: c
882  * indent-tabs-mode: t
883  * c-basic-offset: 4
884  * tab-width: 4
885  * End:
886  */