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