delay jni init til the firt NewGlobalRef call
[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 1470 2004-11-08 22:57:28Z motse $
41
42 */
43
44
45 #include <stdlib.h>
46 #include <string.h>
47 #include "exceptions.h"
48 #include "main.h"
49 #include "options.h"
50 #include "global.h"
51 #include "tables.h"
52 #include "loader.h"
53 #include "jit/jit.h"
54 #include "asmpart.h"
55 #include "builtin.h"
56 #include "native.h"
57 #include "statistics.h"
58 #include "mm/boehm.h"
59 #include "threads/thread.h"
60 #include "toolbox/logging.h"
61 #include "toolbox/memory.h"
62 #include "jit/parseRTstats.h"
63 #include "nat/java_io_File.h"            /* required by java_lang_Runtime.h   */
64 #include "nat/java_util_Properties.h"    /* required by java_lang_Runtime.h   */
65 #include "nat/java_lang_Runtime.h"
66 #include "nat/java_lang_Throwable.h"
67
68 #ifdef TYPEINFO_DEBUG_TEST
69 #include "typeinfo.h"
70 #endif
71
72
73 bool cacao_initializing;
74
75 char *classpath;                        /* contains classpath                 */
76 char *mainstring;
77 static classinfo *mainclass;
78
79 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
80 void **stackbottom = 0;
81 #endif
82
83
84 /* internal function: get_opt *************************************************
85         
86         decodes the next command line option
87         
88 ******************************************************************************/
89
90 #define OPT_DONE       -1
91 #define OPT_ERROR       0
92 #define OPT_IGNORE      1
93
94 #define OPT_CLASSPATH   2
95 #define OPT_D           3
96 #define OPT_MS          4
97 #define OPT_MX          5
98 #define OPT_VERBOSE1    6
99 #define OPT_VERBOSE     7
100 #define OPT_VERBOSEGC   8
101 #define OPT_VERBOSECALL 9
102 #define OPT_NOIEEE      10
103 #define OPT_SOFTNULL    11
104 #define OPT_TIME        12
105 #define OPT_STAT        13
106 #define OPT_LOG         14
107 #define OPT_CHECK       15
108 #define OPT_LOAD        16
109 #define OPT_METHOD      17
110 #define OPT_SIGNATURE   18
111 #define OPT_SHOW        19
112 #define OPT_ALL         20
113 #define OPT_OLOOP       24
114 #define OPT_INLINING    25
115 #define OPT_RT          26
116 #define OPT_XTA         27 
117 #define OPT_VTA         28
118 #define OPT_VERBOSETC   29
119 #define OPT_NOVERIFY    30
120 #define OPT_LIBERALUTF  31
121 #define OPT_VERBOSEEXCEPTION 32
122 #define OPT_EAGER            33
123
124
125 struct {char *name; bool arg; int value;} opts[] = {
126         {"classpath",        true,   OPT_CLASSPATH},
127         {"cp",               true,   OPT_CLASSPATH},
128         {"D",                true,   OPT_D},
129         {"Xms",              true,   OPT_MS},
130         {"Xmx",              true,   OPT_MX},
131         {"ms",               true,   OPT_MS},
132         {"mx",               true,   OPT_MX},
133         {"noasyncgc",        false,  OPT_IGNORE},
134         {"noverify",         false,  OPT_NOVERIFY},
135         {"liberalutf",       false,  OPT_LIBERALUTF},
136         {"oss",              true,   OPT_IGNORE},
137         {"ss",               true,   OPT_IGNORE},
138         {"v",                false,  OPT_VERBOSE1},
139         {"verbose",          false,  OPT_VERBOSE},
140         {"verbosegc",        false,  OPT_VERBOSEGC},
141         {"verbosecall",      false,  OPT_VERBOSECALL},
142         {"verboseexception", false,  OPT_VERBOSEEXCEPTION},
143 #ifdef TYPECHECK_VERBOSE
144         {"verbosetc",        false,  OPT_VERBOSETC},
145 #endif
146 #if defined(__ALPHA__)
147         {"noieee",           false,  OPT_NOIEEE},
148 #endif
149         {"softnull",         false,  OPT_SOFTNULL},
150         {"time",             false,  OPT_TIME},
151         {"stat",             false,  OPT_STAT},
152         {"log",              true,   OPT_LOG},
153         {"c",                true,   OPT_CHECK},
154         {"l",                false,  OPT_LOAD},
155     { "eager",            false,  OPT_EAGER },
156         {"m",                true,   OPT_METHOD},
157         {"sig",              true,   OPT_SIGNATURE},
158         {"s",                true,   OPT_SHOW},
159         {"all",              false,  OPT_ALL},
160         {"oloop",            false,  OPT_OLOOP},
161         {"i",                    true,   OPT_INLINING},
162         {"rt",               false,  OPT_RT},
163         {"xta",              false,  OPT_XTA},
164         {"vta",              false,  OPT_VTA},
165         {NULL,               false,  0}
166 };
167
168 static int opt_ind = 1;
169 static char *opt_arg;
170
171
172 static int get_opt(int argc, char **argv)
173 {
174         char *a;
175         int i;
176         
177         if (opt_ind >= argc) return OPT_DONE;
178         
179         a = argv[opt_ind];
180         if (a[0] != '-') return OPT_DONE;
181
182         for (i = 0; opts[i].name; i++) {
183                 if (!opts[i].arg) {
184                         if (strcmp(a + 1, opts[i].name) == 0) { /* boolean option found */
185                                 opt_ind++;
186                                 return opts[i].value;
187                         }
188
189                 } else {
190                         if (strcmp(a + 1, opts[i].name) == 0) { /* parameter option found */
191                                 opt_ind++;
192                                 if (opt_ind < argc) {
193                                         opt_arg = argv[opt_ind];
194                                         opt_ind++;
195                                         return opts[i].value;
196                                 }
197                                 return OPT_ERROR;
198
199                         } else {
200                                 size_t l = strlen(opts[i].name);
201                                 if (strlen(a + 1) > l) {
202                                         if (memcmp(a + 1, opts[i].name, l) == 0) {
203                                                 opt_ind++;
204                                                 opt_arg = a + 1 + l;
205                                                 return opts[i].value;
206                                         }
207                                 }
208                         }
209                 }
210         } /* end for */ 
211
212         return OPT_ERROR;
213 }
214
215
216 /******************** interne Function: print_usage ************************
217
218 Prints the correct usage syntax to stdout.
219
220 ***************************************************************************/
221
222 static void print_usage()
223 {
224         printf("USAGE: cacao [options] classname [program arguments]\n");
225         printf("Options:\n");
226         printf("          -cp path ............. specify a path to look for classes\n");
227         printf("          -classpath path ...... specify a path to look for classes\n");
228         printf("          -Dpropertyname=value . add an entry to the property list\n");
229         printf("          -Xmx maxmem[kK|mM] ... specify the size for the heap\n");
230         printf("          -Xms initmem[kK|mM] .. specify the initial size for the heap\n");
231         printf("          -mx maxmem[kK|mM] .... specify the size for the heap\n");
232         printf("          -ms initmem[kK|mM] ... specify the initial size for the heap\n");
233         printf("          -v ................... write state-information\n");
234         printf("          -verbose ............. write more information\n");
235         printf("          -verbosegc ........... write message for each GC\n");
236         printf("          -verbosecall ......... write message for each call\n");
237         printf("          -verboseexception .... write message for each step of stack unwinding\n");
238 #ifdef TYPECHECK_VERBOSE
239         printf("          -verbosetc ........... write debug messages while typechecking\n");
240 #endif
241 #if defined(__ALPHA__)
242         printf("          -noieee .............. don't use ieee compliant arithmetic\n");
243 #endif
244         printf("          -noverify ............ don't verify classfiles\n");
245         printf("          -liberalutf........... don't warn about overlong UTF-8 sequences\n");
246         printf("          -softnull ............ use software nullpointer check\n");
247         printf("          -time ................ measure the runtime\n");
248         printf("          -stat ................ detailed compiler statistics\n");
249         printf("          -log logfile ......... specify a name for the logfile\n");
250         printf("          -c(heck)b(ounds) ..... don't check array bounds\n");
251         printf("                  s(ync) ....... don't check for synchronization\n");
252         printf("          -oloop ............... optimize array accesses in loops\n"); 
253         printf("          -l ................... don't start the class after loading\n");
254         printf("          -eager ............... perform eager class loading and linking\n");
255         printf("          -all ................. compile all methods, no execution\n");
256         printf("          -m ................... compile only a specific method\n");
257         printf("          -sig ................. specify signature for a specific method\n");
258         printf("          -s(how)a(ssembler) ... show disassembled listing\n");
259         printf("                 c(onstants) ... show the constant pool\n");
260         printf("                 d(atasegment).. show data segment listing\n");
261         printf("                 i(ntermediate). show intermediate representation\n");
262         printf("                 m(ethods)...... show class fields and methods\n");
263         printf("                 u(tf) ......... show the utf - hash\n");
264         printf("          -i     n ............. activate inlining\n");
265         printf("                 v ............. inline virtual methods\n");
266         printf("                 e ............. inline methods with exceptions\n");
267         printf("                 p ............. optimize argument renaming\n");
268         printf("                 o ............. inline methods of foreign classes\n");
269         printf("          -rt .................. use rapid type analysis\n");
270         printf("          -xta ................. use x type analysis\n");
271         printf("          -vta ................. use variable type analysis\n");
272 }   
273
274
275 #ifdef TYPECHECK_STATISTICS
276 void typecheck_print_statistics(FILE *file);
277 #endif
278
279
280 /*
281  * void exit_handler(void)
282  * -----------------------
283  * The exit_handler function is called upon program termination to shutdown
284  * the various subsystems and release the resources allocated to the VM.
285  */
286 void exit_handler(void)
287 {
288         /********************* Print debug tables ************************/
289                                 
290         if (showmethods) class_showmethods(mainclass);
291         if (showconstantpool) class_showconstantpool(mainclass);
292         if (showutf) utf_show();
293
294 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
295         clear_thread_flags();           /* restores standard file descriptor
296                                        flags */
297 #endif
298
299         /************************ Free all resources *******************/
300
301         loader_close();
302         tables_close();
303
304         MFREE(classpath, u1, strlen(classpath));
305
306         if (verbose || getcompilingtime || opt_stat) {
307                 log_text("CACAO terminated");
308                 if (opt_stat) {
309                         print_stats();
310 #ifdef TYPECHECK_STATISTICS
311                         typecheck_print_statistics(get_logfile());
312 #endif
313                 }
314                 if (getcompilingtime)
315                         print_times();
316                 mem_usagelog(1);
317         }
318 }
319
320
321 /************************** Function: main *******************************
322
323    The main program.
324    
325 **************************************************************************/
326
327 int main(int argc, char **argv)
328 {
329         s4 i, j;
330         void *dummy;
331         
332         /********** interne (nur fuer main relevante Optionen) **************/
333    
334         char logfilename[200] = "";
335         u4 heapmaxsize = 64 * 1024 * 1024;
336         u4 heapstartsize = 200 * 1024;
337         char *cp;
338         bool startit = true;
339         char *specificmethodname = NULL;
340         char *specificsignature = NULL;
341
342 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
343         stackbottom = &dummy;
344 #endif
345         
346         if (atexit(exit_handler))
347                 throw_cacao_exception_exit(string_java_lang_InternalError,
348                                                                    "Unable to register exit_handler");
349
350
351         /************ Collect info from the environment ************************/
352
353         /* set an initial, minimal classpath */
354         classpath = MNEW(char, 2);
355         strcpy(classpath, ".");
356
357         /* get classpath environment */
358         cp = getenv("CLASSPATH");
359         if (cp) {
360                 classpath = MREALLOC(classpath,
361                                                          char,
362                                                          strlen(classpath),
363                                                          strlen(classpath) + 1 + strlen(cp) + 1);
364                 strcat(classpath, ":");
365                 strcat(classpath, cp);
366         }
367
368         /***************** Interpret the command line *****************/
369    
370         checknull = false;
371         opt_noieee = false;
372
373         while ((i = get_opt(argc, argv)) != OPT_DONE) {
374                 switch (i) {
375                 case OPT_IGNORE: break;
376                         
377                 case OPT_CLASSPATH:
378                         /* forget old classpath and set the argument as new classpath */
379                         MFREE(classpath, char, strlen(classpath));
380
381                         classpath = MNEW(char, strlen(opt_arg) + 1);
382                         strcpy(classpath, opt_arg);
383                         break;
384                                 
385                 case OPT_D:
386                         {
387                                 int n;
388                                 int l = strlen(opt_arg);
389                                 for (n = 0; n < l; n++) {
390                                         if (opt_arg[n] == '=') {
391                                                 opt_arg[n] = '\0';
392                                                 create_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         if (opt_ind >= argc) {
600                 print_usage();
601                 exit(10);
602         }
603
604         mainstring = argv[opt_ind++];
605         for (i = strlen(mainstring) - 1; i >= 0; i--) {     /* Transform dots into slashes */
606                 if (mainstring[i] == '.') mainstring[i] = '/';  /* in the class name */
607         }
608
609
610         /**************************** Program start *****************************/
611
612         log_init(logfilename);
613         if (verbose)
614                 log_text("CACAO started -------------------------------------------------------");
615
616         /* initialize the garbage collector */
617         gc_init(heapmaxsize, heapstartsize);
618
619         tables_init();
620         suck_init(classpath);
621
622         cacao_initializing = true;
623
624 #if defined(USE_THREADS)
625 #if defined(NATIVE_THREADS)
626         initThreadsEarly();
627 #endif
628         initLocks();
629 #endif
630
631         /* install architecture dependent signal handler used for exceptions */
632         init_exceptions();
633
634         /* initializes jit compiler and codegen stuff */
635         jit_init();
636
637         loader_init((u1 *) &dummy);
638
639         jit_init();
640
641         /* initialize exceptions used in the system */
642         init_system_exceptions();
643
644         native_loadclasses();
645
646 #if defined(USE_THREADS)
647         initThreads((u1 *) &dummy);
648 #endif
649
650         *threadrootmethod = NULL;
651
652         /*That's important, otherwise we get into trouble, if the Runtime static
653           initializer is called before (circular dependency. This is with
654           classpath 0.09. Another important thing is, that this has to happen
655           after initThreads!!! */
656
657         if (!class_init(class_new(utf_new_char("java/lang/System"))))
658                 throw_main_exception_exit();
659
660         
661         
662 /*        jni_init(); */
663         cacao_initializing = false;
664
665         /************************* Start worker routines ********************/
666
667         if (startit) {
668                 methodinfo *mainmethod;
669                 java_objectarray *a; 
670
671                 /* create, load and link the main class */
672                 mainclass = class_new(utf_new_char(mainstring));
673
674                 if (!class_load(mainclass))
675                         throw_main_exception_exit();
676
677                 if (!class_link(mainclass))
678                         throw_main_exception_exit();
679
680                 mainmethod = class_resolveclassmethod(mainclass,
681                                                                                           utf_new_char("main"), 
682                                                                                           utf_new_char("([Ljava/lang/String;)V"),
683                                                                                           mainclass,
684                                                                                           false);
685
686                 /* problems with main method? */
687 /*              if (*exceptionptr) */
688 /*                      throw_exception_exit(); */
689
690                 /* there is no main method or it isn't static */
691                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
692                         *exceptionptr =
693                                 new_exception_message(string_java_lang_NoSuchMethodError,
694                                                                           "main");
695                         throw_main_exception_exit();
696                 }
697
698                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
699                 for (i = opt_ind; i < argc; i++) {
700                         a->data[i - opt_ind] = 
701                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
702                 }
703
704 #ifdef TYPEINFO_DEBUG_TEST
705                 /* test the typeinfo system */
706                 typeinfo_test();
707 #endif
708                 /*class_showmethods(currentThread->group->header.vftbl->class); */
709
710                 *threadrootmethod = mainmethod;
711
712
713                 /* here we go... */
714                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
715
716                 /* exception occurred? */
717                 if (*exceptionptr)
718                         throw_main_exception();
719
720 #if defined(USE_THREADS)
721 #if defined(NATIVE_THREADS)
722                 joinAllThreads();
723 #else
724                 killThread(currentThread);
725 #endif
726 #endif
727
728                 /* now exit the JavaVM */
729
730                 cacao_exit(0);
731         }
732
733         /************* If requested, compile all methods ********************/
734
735         if (compileall) {
736                 classinfo *c;
737                 methodinfo *m;
738                 u4 slot;
739                 s4 i;
740
741                 /* create all classes found in the classpath */
742                 /* XXX currently only works with zip/jar's */
743                 create_all_classes();
744
745                 /* load and link all classes */
746                 for (slot = 0; slot < class_hash.size; slot++) {
747                         c = class_hash.ptr[slot];
748
749                         while (c) {
750                                 if (!c->loaded)
751                                         if (!class_load(c))
752                                                 throw_main_exception_exit();
753
754                                 if (!c->linked)
755                                         if (!class_link(c))
756                                                 throw_main_exception_exit();
757
758                                 /* compile all class methods */
759                                 for (i = 0; i < c->methodscount; i++) {
760                                         m = &(c->methods[i]);
761                                         if (m->jcode) {
762                                                 (void) jit_compile(m);
763                                         }
764                                 }
765
766                                 c = c->hashlink;
767                         }
768                 }
769         }
770
771
772         /******** If requested, compile a specific method ***************/
773
774         if (specificmethodname) {
775                 methodinfo *m;
776
777                 /* create, load and link the main class */
778                 mainclass = class_new(utf_new_char(mainstring));
779
780                 if (!class_load(mainclass))
781                         throw_main_exception_exit();
782
783                 if (!class_link(mainclass))
784                         throw_main_exception_exit();
785
786                 if (specificsignature) {
787                         m = class_resolveclassmethod(mainclass,
788                                                                                  utf_new_char(specificmethodname),
789                                                                                  utf_new_char(specificsignature),
790                                                                                  mainclass,
791                                                                                  false);
792                 } else {
793                         m = class_resolveclassmethod(mainclass,
794                                                                                  utf_new_char(specificmethodname),
795                                                                                  NULL,
796                                                                                  mainclass,
797                                                                                  false);
798                 }
799
800                 if (!m) {
801                         char message[MAXLOGTEXT];
802                         sprintf(message, "%s%s", specificmethodname,
803                                         specificsignature ? specificsignature : "");
804
805                         *exceptionptr =
806                                 new_exception_message(string_java_lang_NoSuchMethodException,
807                                                                           message);
808                                                                                  
809                         throw_main_exception_exit();
810                 }
811                 
812                 jit_compile(m);
813         }
814
815         cacao_shutdown(0);
816
817         /* keep compiler happy */
818
819         return 0;
820 }
821
822
823 /* cacao_exit ******************************************************************
824
825    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
826
827 *******************************************************************************/
828
829 void cacao_exit(s4 status)
830 {
831         classinfo *c;
832         methodinfo *m;
833         java_lang_Runtime *rt;
834
835         /* class should already be loaded, but who knows... */
836
837         c = class_new(utf_new_char("java/lang/Runtime"));
838
839         if (!class_load(c))
840                 throw_main_exception_exit();
841
842         if (!class_link(c))
843                 throw_main_exception_exit();
844
845         /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
846
847         m = class_resolveclassmethod(c,
848                                                                  utf_new_char("getRuntime"),
849                                                                  utf_new_char("()Ljava/lang/Runtime;"),
850                                                                  class_java_lang_Object,
851                                                                  true);
852
853         if (!m)
854                 throw_main_exception_exit();
855
856         rt = (java_lang_Runtime *) asm_calljavafunction(m,
857                                                                                                         (void *) 0,
858                                                                                                         NULL,
859                                                                                                         NULL,
860                                                                                                         NULL);
861
862         /* exception occurred? */
863
864         if (*exceptionptr)
865                 throw_main_exception_exit();
866
867         /* then call Runtime.exit(I)V */
868
869         m = class_resolveclassmethod(c,
870                                                                  utf_new_char("exit"),
871                                                                  utf_new_char("(I)V"),
872                                                                  class_java_lang_Object,
873                                                                  true);
874         
875         if (!m)
876                 throw_main_exception_exit();
877
878         asm_calljavafunction(m, rt, (void *) 0, NULL, NULL);
879
880         /* this should never happen */
881
882         throw_cacao_exception_exit(string_java_lang_InternalError,
883                                                            "Problems with Runtime.exit(I)V");
884 }
885
886
887 /*************************** Shutdown function *********************************
888
889         Terminates the system immediately without freeing memory explicitly (to be
890         used only for abnormal termination)
891         
892 *******************************************************************************/
893
894 void cacao_shutdown(s4 status)
895 {
896         if (verbose || getcompilingtime || opt_stat) {
897                 log_text("CACAO terminated by shutdown");
898                 dolog("Exit status: %d\n", (s4) status);
899         }
900
901         exit(status);
902 }
903
904
905 /*
906  * These are local overrides for various environment variables in Emacs.
907  * Please do not remove this and leave it at the end of the file, where
908  * Emacs will automagically detect them.
909  * ---------------------------------------------------------------------
910  * Local variables:
911  * mode: c
912  * indent-tabs-mode: t
913  * c-basic-offset: 4
914  * tab-width: 4
915  * End:
916  */