40127052c40825d36b6e51ba0a9666cdb2aff9e2
[cacao.git] / src / cacao / cacao.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: cacao.c 1359 2004-07-28 10:48:36Z 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         classpath = MNEW(u1, 2);
354         strcpy(classpath, ".");
355
356         /* get classpath environment */
357         cp = getenv("CLASSPATH");
358         if (cp) {
359                 classpath = MREALLOC(classpath,
360                                                          u1,
361                                                          strlen(classpath),
362                                                          strlen(classpath) + 1 + strlen(cp) + 1);
363                 strcat(classpath, ":");
364                 strncat(classpath, cp, strlen(cp));
365         }
366
367         /***************** Interpret the command line *****************/
368    
369         checknull = false;
370         opt_noieee = false;
371
372         while ((i = get_opt(argc, argv)) != OPT_DONE) {
373                 switch (i) {
374                 case OPT_IGNORE: break;
375                         
376                 case OPT_CLASSPATH:
377                         classpath = MREALLOC(classpath,
378                                                                  u1,
379                                                                  strlen(classpath),
380                                                                  strlen(classpath) + 1 + strlen(opt_arg) + 1);
381                         strcat(classpath, ":");
382                         strncat(classpath, opt_arg, strlen(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
629         /* install architecture dependent signal handler used for exceptions */
630         init_exceptions();
631
632         /* initializes jit compiler and codegen stuff */
633         jit_init();
634
635         loader_init((u1 *) &dummy);
636
637         jit_init();
638
639         /* initialize exceptions used in the system */
640         init_system_exceptions();
641
642         native_loadclasses();
643
644 #if defined(USE_THREADS)
645         initThreads((u1 *) &dummy);
646 #endif
647
648         *threadrootmethod = NULL;
649
650         /*That's important, otherwise we get into trouble, if the Runtime static
651           initializer is called before (circular dependency. This is with
652           classpath 0.09. Another important thing is, that this has to happen
653           after initThreads!!! */
654
655         if (!class_init(class_new(utf_new_char("java/lang/System"))))
656                 throw_main_exception_exit();
657
658         cacao_initializing = false;
659
660         /************************* Start worker routines ********************/
661
662         if (startit) {
663                 methodinfo *mainmethod;
664                 java_objectarray *a; 
665
666                 /* create, load and link the main class */
667                 mainclass = class_new(utf_new_char(mainstring));
668
669                 if (!class_load(mainclass))
670                         throw_main_exception_exit();
671
672                 if (!class_link(mainclass))
673                         throw_main_exception_exit();
674
675                 mainmethod = class_resolveclassmethod(mainclass,
676                                                                                           utf_new_char("main"), 
677                                                                                           utf_new_char("([Ljava/lang/String;)V"),
678                                                                                           mainclass,
679                                                                                           false);
680
681                 /* problems with main method? */
682 /*              if (*exceptionptr) */
683 /*                      throw_exception_exit(); */
684
685                 /* there is no main method or it isn't static */
686                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
687                         *exceptionptr =
688                                 new_exception_message(string_java_lang_NoSuchMethodError,
689                                                                           "main");
690                         throw_main_exception_exit();
691                 }
692
693                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
694                 for (i = opt_ind; i < argc; i++) {
695                         a->data[i - opt_ind] = 
696                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
697                 }
698
699 #ifdef TYPEINFO_DEBUG_TEST
700                 /* test the typeinfo system */
701                 typeinfo_test();
702 #endif
703                 /*class_showmethods(currentThread->group->header.vftbl->class); */
704
705                 *threadrootmethod = mainmethod;
706
707
708                 /* here we go... */
709                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
710
711                 /* exception occurred? */
712                 if (*exceptionptr)
713                         throw_main_exception();
714
715 #if defined(USE_THREADS)
716 #if defined(NATIVE_THREADS)
717                 joinAllThreads();
718 #else
719                 killThread(currentThread);
720 #endif
721 #endif
722
723                 /* now exit the JavaVM */
724
725                 cacao_exit(0);
726         }
727
728         /************* If requested, compile all methods ********************/
729
730         if (compileall) {
731                 classinfo *c;
732                 methodinfo *m;
733                 u4 slot;
734                 s4 i;
735
736                 /* create all classes found in the classpath */
737                 /* XXX currently only works with zip/jar's */
738                 create_all_classes();
739
740                 /* load and link all classes */
741                 for (slot = 0; slot < class_hash.size; slot++) {
742                         c = class_hash.ptr[slot];
743
744                         while (c) {
745                                 if (!c->loaded)
746                                         if (!class_load(c))
747                                                 throw_main_exception_exit();
748
749                                 if (!c->linked)
750                                         if (!class_link(c))
751                                                 throw_main_exception_exit();
752
753                                 /* compile all class methods */
754                                 for (i = 0; i < c->methodscount; i++) {
755                                         m = &(c->methods[i]);
756                                         if (m->jcode) {
757                                                 (void) jit_compile(m);
758                                         }
759                                 }
760
761                                 c = c->hashlink;
762                         }
763                 }
764         }
765
766
767         /******** If requested, compile a specific method ***************/
768
769         if (specificmethodname) {
770                 methodinfo *m;
771
772                 /* create, load and link the main class */
773                 mainclass = class_new(utf_new_char(mainstring));
774
775                 if (!class_load(mainclass))
776                         throw_main_exception_exit();
777
778                 if (!class_link(mainclass))
779                         throw_main_exception_exit();
780
781                 if (specificsignature) {
782                         m = class_resolveclassmethod(mainclass,
783                                                                                  utf_new_char(specificmethodname),
784                                                                                  utf_new_char(specificsignature),
785                                                                                  mainclass,
786                                                                                  false);
787                 } else {
788                         m = class_resolveclassmethod(mainclass,
789                                                                                  utf_new_char(specificmethodname),
790                                                                                  NULL,
791                                                                                  mainclass,
792                                                                                  false);
793                 }
794
795                 if (!m) {
796                         char message[MAXLOGTEXT];
797                         sprintf(message, "%s%s", specificmethodname,
798                                         specificsignature ? specificsignature : "");
799
800                         *exceptionptr =
801                                 new_exception_message(string_java_lang_NoSuchMethodException,
802                                                                           message);
803                                                                                  
804                         throw_main_exception_exit();
805                 }
806                 
807                 jit_compile(m);
808         }
809
810         cacao_shutdown(0);
811
812         /* keep compiler happy */
813
814         return 0;
815 }
816
817
818 /* cacao_exit ******************************************************************
819
820    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
821
822 *******************************************************************************/
823
824 void cacao_exit(s4 status)
825 {
826         classinfo *c;
827         methodinfo *m;
828         java_lang_Runtime *rt;
829
830         /* class should already be loaded, but who knows... */
831
832         c = class_new(utf_new_char("java/lang/Runtime"));
833
834         if (!class_load(c))
835                 throw_main_exception_exit();
836
837         if (!class_link(c))
838                 throw_main_exception_exit();
839
840         /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
841
842         m = class_resolveclassmethod(c,
843                                                                  utf_new_char("getRuntime"),
844                                                                  utf_new_char("()Ljava/lang/Runtime;"),
845                                                                  class_java_lang_Object,
846                                                                  true);
847
848         if (!m)
849                 throw_main_exception_exit();
850
851         rt = (java_lang_Runtime *) asm_calljavafunction(m,
852                                                                                                         (void *) 0,
853                                                                                                         NULL,
854                                                                                                         NULL,
855                                                                                                         NULL);
856
857         /* exception occurred? */
858
859         if (*exceptionptr)
860                 throw_main_exception_exit();
861
862         /* then call Runtime.exit(I)V */
863
864         m = class_resolveclassmethod(c,
865                                                                  utf_new_char("exit"),
866                                                                  utf_new_char("(I)V"),
867                                                                  class_java_lang_Object,
868                                                                  true);
869         
870         if (!m)
871                 throw_main_exception_exit();
872
873         asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
874
875         /* this should never happen */
876
877         throw_cacao_exception_exit(string_java_lang_InternalError,
878                                                            "Problems with Runtime.exit(I)V");
879 }
880
881
882 /*************************** Shutdown function *********************************
883
884         Terminates the system immediately without freeing memory explicitly (to be
885         used only for abnormal termination)
886         
887 *******************************************************************************/
888
889 void cacao_shutdown(s4 status)
890 {
891         /**** RTAprint ***/
892
893         if (verbose || getcompilingtime || opt_stat) {
894                 log_text("CACAO terminated by shutdown");
895                 if (opt_stat)
896                         print_stats();
897                 if (getcompilingtime)
898                         print_times();
899                 mem_usagelog(0);
900                 dolog("Exit status: %d\n", (int) status);
901         }
902
903         exit(status);
904 }
905
906
907 /*
908  * These are local overrides for various environment variables in Emacs.
909  * Please do not remove this and leave it at the end of the file, where
910  * Emacs will automagically detect them.
911  * ---------------------------------------------------------------------
912  * Local variables:
913  * mode: c
914  * indent-tabs-mode: t
915  * c-basic-offset: 4
916  * tab-width: 4
917  * End:
918  */