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