ce29c4e5d3b7071dc57b4dbfc9294ed0c4367b96
[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 1657 2004-12-03 15:27:32Z 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         cplen = strlen(INSTALL_PREFIX) + strlen(RT_JAR_PATH);
578         cp = classpath;
579
580         classpath = MNEW(char, cplen + strlen(classpath) + 1);
581         strcpy(classpath, INSTALL_PREFIX);
582         strcat(classpath, RT_JAR_PATH);
583         strcat(classpath, cp);
584
585         MFREE(cp, char, strlen(cp));
586
587
588         /* transform dots into slashes in the class name */
589         mainstring = argv[opt_ind++];
590         for (i = strlen(mainstring) - 1; i >= 0; i--) {
591                 if (mainstring[i] == '.') mainstring[i] = '/';
592         }
593
594
595         /**************************** Program start *****************************/
596
597         log_init(logfilename);
598         if (opt_verbose)
599                 log_text("CACAO started -------------------------------------------------------");
600
601         /* initialize the garbage collector */
602         gc_init(heapmaxsize, heapstartsize);
603
604         tables_init();
605         suck_init(classpath);
606
607         cacao_initializing = true;
608
609 #if defined(USE_THREADS)
610 #if defined(NATIVE_THREADS)
611         initThreadsEarly();
612 #endif
613         initLocks();
614 #endif
615
616         /* install architecture dependent signal handler used for exceptions */
617         init_exceptions();
618
619         /* initializes jit compiler and codegen stuff */
620         jit_init();
621
622         loader_init((u1 *) &dummy);
623
624         /* initialize exceptions used in the system */
625         if (!init_system_exceptions())
626                 throw_main_exception_exit();
627
628         native_loadclasses();
629
630 #if defined(USE_THREADS)
631         initThreads((u1 *) &dummy);
632 #endif
633
634         *threadrootmethod = NULL;
635
636         /*That's important, otherwise we get into trouble, if the Runtime static
637           initializer is called before (circular dependency. This is with
638           classpath 0.09. Another important thing is, that this has to happen
639           after initThreads!!! */
640
641         if (!class_init(class_new(utf_new_char("java/lang/System"))))
642                 throw_main_exception_exit();
643
644         
645         
646 /*        jni_init(); */
647         cacao_initializing = false;
648
649         /************************* Start worker routines ********************/
650
651         if (startit) {
652                 methodinfo *mainmethod;
653                 java_objectarray *a; 
654                 s4 status;
655
656                 /* set return value to OK */
657                 status = 0;
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                         status = 1;
708                 }
709
710 #if defined(USE_THREADS)
711 #if defined(NATIVE_THREADS)
712                 joinAllThreads();
713 #else
714                 killThread(currentThread);
715 #endif
716 #endif
717
718                 /* now exit the JavaVM */
719
720                 cacao_exit(status);
721         }
722
723         /************* If requested, compile all methods ********************/
724
725         if (compileall) {
726                 classinfo *c;
727                 methodinfo *m;
728                 u4 slot;
729                 s4 i;
730
731                 /* create all classes found in the classpath */
732                 /* XXX currently only works with zip/jar's */
733                 create_all_classes();
734
735                 /* load and link all classes */
736                 for (slot = 0; slot < class_hash.size; slot++) {
737                         c = class_hash.ptr[slot];
738
739                         while (c) {
740                                 if (!c->loaded)
741                                         if (!class_load(c))
742                                                 throw_main_exception_exit();
743
744                                 if (!c->linked)
745                                         if (!class_link(c))
746                                                 throw_main_exception_exit();
747
748                                 /* compile all class methods */
749                                 for (i = 0; i < c->methodscount; i++) {
750                                         m = &(c->methods[i]);
751                                         if (m->jcode) {
752                                                 (void) jit_compile(m);
753                                         }
754                                 }
755
756                                 c = c->hashlink;
757                         }
758                 }
759         }
760
761
762         /******** If requested, compile a specific method ***************/
763
764         if (specificmethodname) {
765                 methodinfo *m;
766
767                 /* create, load and link the main class */
768                 mainclass = class_new(utf_new_char(mainstring));
769
770                 if (!class_load(mainclass))
771                         throw_main_exception_exit();
772
773                 if (!class_link(mainclass))
774                         throw_main_exception_exit();
775
776                 if (specificsignature) {
777                         m = class_resolveclassmethod(mainclass,
778                                                                                  utf_new_char(specificmethodname),
779                                                                                  utf_new_char(specificsignature),
780                                                                                  mainclass,
781                                                                                  false);
782                 } else {
783                         m = class_resolveclassmethod(mainclass,
784                                                                                  utf_new_char(specificmethodname),
785                                                                                  NULL,
786                                                                                  mainclass,
787                                                                                  false);
788                 }
789
790                 if (!m) {
791                         char message[MAXLOGTEXT];
792                         sprintf(message, "%s%s", specificmethodname,
793                                         specificsignature ? specificsignature : "");
794
795                         *exceptionptr =
796                                 new_exception_message(string_java_lang_NoSuchMethodException,
797                                                                           message);
798                                                                                  
799                         throw_main_exception_exit();
800                 }
801                 
802                 jit_compile(m);
803         }
804
805         cacao_shutdown(0);
806
807         /* keep compiler happy */
808
809         return 0;
810 }
811
812
813 /* cacao_exit ******************************************************************
814
815    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
816
817 *******************************************************************************/
818
819 void cacao_exit(s4 status)
820 {
821         classinfo *c;
822         methodinfo *m;
823
824         /* class should already be loaded, but who knows... */
825
826         c = class_new(utf_new_char("java/lang/System"));
827
828         if (!class_load(c))
829                 throw_main_exception_exit();
830
831         if (!class_link(c))
832                 throw_main_exception_exit();
833
834         /* call System.exit(I)V */
835
836         m = class_resolveclassmethod(c,
837                                                                  utf_new_char("exit"),
838                                                                  utf_new_char("(I)V"),
839                                                                  class_java_lang_Object,
840                                                                  true);
841         
842         if (!m)
843                 throw_main_exception_exit();
844
845         /* call the exit function with passed exit status */
846
847         asm_calljavafunction(m,
848 #if POINTERSIZE == 8
849                                                  (void *) (s8) status,
850 #else
851                                                  (void *) status,
852 #endif
853                                                  NULL,
854                                                  NULL,
855                                                  NULL);
856
857         /* this should never happen */
858
859         if (*exceptionptr)
860                 throw_exception_exit();
861
862         throw_cacao_exception_exit(string_java_lang_InternalError,
863                                                            "System.exit(I)V returned without exception");
864 }
865
866
867 /*************************** Shutdown function *********************************
868
869         Terminates the system immediately without freeing memory explicitly (to be
870         used only for abnormal termination)
871         
872 *******************************************************************************/
873
874 void cacao_shutdown(s4 status)
875 {
876         if (opt_verbose || getcompilingtime || opt_stat) {
877                 log_text("CACAO terminated by shutdown");
878                 dolog("Exit status: %d\n", (s4) status);
879         }
880
881         exit(status);
882 }
883
884
885 /*
886  * These are local overrides for various environment variables in Emacs.
887  * Please do not remove this and leave it at the end of the file, where
888  * Emacs will automagically detect them.
889  * ---------------------------------------------------------------------
890  * Local variables:
891  * mode: c
892  * indent-tabs-mode: t
893  * c-basic-offset: 4
894  * tab-width: 4
895  * End:
896  */