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