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