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