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