e7db2d6af9125f74635a5f4b20331507bcca37d1
[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 1505 2004-11-14 14:15:58Z jowenn $
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("                                 uses/turns rt option on\n");
267         printf("                 e ............. inline methods with exceptions\n");
268         printf("                 p ............. optimize argument renaming\n");
269         printf("                 o ............. inline methods of foreign classes\n");
270         printf("          -rt .................. use rapid type analysis\n");
271         printf("          -xta ................. use x type analysis\n");
272         printf("          -vta ................. use variable type analysis\n");
273 }   
274
275
276 #ifdef TYPECHECK_STATISTICS
277 void typecheck_print_statistics(FILE *file);
278 #endif
279
280
281 /*
282  * void exit_handler(void)
283  * -----------------------
284  * The exit_handler function is called upon program termination to shutdown
285  * the various subsystems and release the resources allocated to the VM.
286  */
287 void exit_handler(void)
288 {
289         /********************* Print debug tables ************************/
290                                 
291         if (showmethods) class_showmethods(mainclass);
292         if (showconstantpool) class_showconstantpool(mainclass);
293         if (showutf) utf_show();
294
295 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
296         clear_thread_flags();           /* restores standard file descriptor
297                                        flags */
298 #endif
299
300         /************************ Free all resources *******************/
301
302         loader_close();
303         tables_close();
304
305         MFREE(classpath, u1, strlen(classpath));
306
307         if (verbose || getcompilingtime || opt_stat) {
308                 log_text("CACAO terminated");
309                 if (opt_stat) {
310                         print_stats();
311 #ifdef TYPECHECK_STATISTICS
312                         typecheck_print_statistics(get_logfile());
313 #endif
314                 }
315                 if (getcompilingtime)
316                         print_times();
317                 mem_usagelog(1);
318         }
319 }
320
321
322 /************************** Function: main *******************************
323
324    The main program.
325    
326 **************************************************************************/
327
328 int main(int argc, char **argv)
329 {
330         s4 i, j;
331         void *dummy;
332         
333         /********** interne (nur fuer main relevante Optionen) **************/
334    
335         char logfilename[200] = "";
336         u4 heapmaxsize = 64 * 1024 * 1024;
337         u4 heapstartsize = 200 * 1024;
338         char *cp;
339         bool startit = true;
340         char *specificmethodname = NULL;
341         char *specificsignature = NULL;
342
343 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
344         stackbottom = &dummy;
345 #endif
346         
347         if (atexit(exit_handler))
348                 throw_cacao_exception_exit(string_java_lang_InternalError,
349                                                                    "Unable to register exit_handler");
350
351
352         /************ Collect info from the environment ************************/
353
354         /* set an initial, minimal classpath */
355         classpath = MNEW(char, 2);
356         strcpy(classpath, ".");
357
358         /* get classpath environment */
359         cp = getenv("CLASSPATH");
360         if (cp) {
361                 classpath = MREALLOC(classpath,
362                                                          char,
363                                                          strlen(classpath),
364                                                          strlen(classpath) + 1 + strlen(cp) + 1);
365                 strcat(classpath, ":");
366                 strcat(classpath, cp);
367         }
368
369         /***************** Interpret the command line *****************/
370    
371         checknull = false;
372         opt_noieee = false;
373
374         while ((i = get_opt(argc, argv)) != OPT_DONE) {
375                 switch (i) {
376                 case OPT_IGNORE: break;
377                         
378                 case OPT_CLASSPATH:
379                         /* forget old classpath and set the argument as new classpath */
380                         MFREE(classpath, char, strlen(classpath));
381
382                         classpath = MNEW(char, strlen(opt_arg) + 1);
383                         strcpy(classpath, opt_arg);
384                         break;
385                                 
386                 case OPT_D:
387                         {
388                                 int n;
389                                 int l = strlen(opt_arg);
390                                 for (n = 0; n < l; n++) {
391                                         if (opt_arg[n] == '=') {
392                                                 opt_arg[n] = '\0';
393                                                 create_property(opt_arg, opt_arg + n + 1);
394                                                 goto didit;
395                                         }
396                                 }
397                                 print_usage();
398                                 exit(10);
399                                         
400                         didit: ;
401                         }       
402                         break;
403
404                 case OPT_MS:
405                 case OPT_MX:
406                         {
407                                 char c;
408                                 c = opt_arg[strlen(opt_arg) - 1];
409
410                                 if (c == 'k' || c == 'K') {
411                                         j = 1024 * atoi(opt_arg);
412
413                                 } else if (c == 'm' || c == 'M') {
414                                         j = 1024 * 1024 * atoi(opt_arg);
415
416                                 } else j = atoi(opt_arg);
417
418                                 if (i == OPT_MX) heapmaxsize = j;
419                                 else heapstartsize = j;
420                         }
421                         break;
422
423                 case OPT_VERBOSE1:
424                         verbose = true;
425                         break;
426
427                 case OPT_VERBOSE:
428                         verbose = true;
429                         loadverbose = true;
430                         linkverbose = true;
431                         initverbose = true;
432                         compileverbose = true;
433                         break;
434
435                 case OPT_VERBOSEEXCEPTION:
436                         verboseexception = true;
437                         break;
438
439                 case OPT_VERBOSEGC:
440                         collectverbose = true;
441                         break;
442
443 #ifdef TYPECHECK_VERBOSE
444                 case OPT_VERBOSETC:
445                         typecheckverbose = true;
446                         break;
447 #endif
448                                 
449                 case OPT_VERBOSECALL:
450                         runverbose = true;
451                         break;
452                                 
453                 case OPT_NOIEEE:
454                         opt_noieee = true;
455                         break;
456
457                 case OPT_NOVERIFY:
458                         opt_verify = false;
459                         break;
460
461                 case OPT_LIBERALUTF:
462                         opt_liberalutf = true;
463                         break;
464
465                 case OPT_SOFTNULL:
466                         checknull = true;
467                         break;
468
469                 case OPT_TIME:
470                         getcompilingtime = true;
471                         getloadingtime = true;
472                         break;
473                                         
474                 case OPT_STAT:
475                         opt_stat = true;
476                         break;
477                                         
478                 case OPT_LOG:
479                         strcpy(logfilename, opt_arg);
480                         break;
481                         
482                 case OPT_CHECK:
483                         for (j = 0; j < strlen(opt_arg); j++) {
484                                 switch (opt_arg[j]) {
485                                 case 'b':
486                                         checkbounds = false;
487                                         break;
488                                 case 's':
489                                         checksync = false;
490                                         break;
491                                 default:
492                                         print_usage();
493                                         exit(10);
494                                 }
495                         }
496                         break;
497                         
498                 case OPT_LOAD:
499                         startit = false;
500                         makeinitializations = false;
501                         break;
502
503                 case OPT_EAGER:
504                         opt_eager = true;
505                         break;
506
507                 case OPT_METHOD:
508                         startit = false;
509                         specificmethodname = opt_arg;
510                         makeinitializations = false;
511                         break;
512                         
513                 case OPT_SIGNATURE:
514                         specificsignature = opt_arg;
515                         break;
516                         
517                 case OPT_ALL:
518                         compileall = true;
519                         startit = false;
520                         makeinitializations = false;
521                         break;
522                         
523                 case OPT_SHOW:       /* Display options */
524                         for (j = 0; j < strlen(opt_arg); j++) {         
525                                 switch (opt_arg[j]) {
526                                 case 'a':
527                                         showdisassemble = true;
528                                         compileverbose = true;
529                                         break;
530                                 case 'c':
531                                         showconstantpool = true;
532                                         break;
533                                 case 'd':
534                                         showddatasegment = true;
535                                         break;
536                                 case 'i':
537                                         showintermediate = true;
538                                         compileverbose = true;
539                                         break;
540                                 case 'm':
541                                         showmethods = true;
542                                         break;
543                                 case 'u':
544                                         showutf = true;
545                                         break;
546                                 default:
547                                         print_usage();
548                                         exit(10);
549                                 }
550                         }
551                         break;
552                         
553                 case OPT_OLOOP:
554                         opt_loops = true;
555                         break;
556
557                 case OPT_INLINING:
558                         for (j = 0; j < strlen(opt_arg); j++) {         
559                                 switch (opt_arg[j]) {
560                                 case 'n':
561                                      /* define in options.h; Used in main.c, jit.c & inline.c */
562                                      #ifdef INAFTERMAIN
563                                         useinliningm = true;
564                                         useinlining = false;
565                                      #else
566                                         useinlining = true;
567                                      #endif
568                                         break;
569                                 case 'v':
570                                         inlinevirtuals = true;
571                                         opt_rt = true;
572                                         break;
573                                 case 'e':
574                                         inlineexceptions = true;
575                                         break;
576                                 case 'p':
577                                         inlineparamopt = true;
578                                         break;
579                                 case 'o':
580                                         inlineoutsiders = true;
581                                         break;
582                                 default:
583                                         print_usage();
584                                         exit(10);
585                                 }
586                         }
587                         break;
588
589                 case OPT_RT:
590                         opt_rt = true;
591                         break;
592
593                 case OPT_XTA:
594                         opt_xta = false; /**not yet **/
595                         break;
596
597                 case OPT_VTA:
598                         /***opt_vta = true; not yet **/
599                         break;
600
601                 default:
602                         print_usage();
603                         exit(10);
604                 }
605         }
606
607         if (opt_ind >= argc) {
608                 print_usage();
609                 exit(10);
610         }
611
612         mainstring = argv[opt_ind++];
613         for (i = strlen(mainstring) - 1; i >= 0; i--) {     /* Transform dots into slashes */
614                 if (mainstring[i] == '.') mainstring[i] = '/';  /* in the class name */
615         }
616
617
618         /**************************** Program start *****************************/
619
620         log_init(logfilename);
621         if (verbose)
622                 log_text("CACAO started -------------------------------------------------------");
623
624         /* initialize the garbage collector */
625         gc_init(heapmaxsize, heapstartsize);
626
627         tables_init();
628         suck_init(classpath);
629
630         cacao_initializing = true;
631
632 #if defined(USE_THREADS)
633 #if defined(NATIVE_THREADS)
634         initThreadsEarly();
635 #endif
636         initLocks();
637 #endif
638
639         /* install architecture dependent signal handler used for exceptions */
640         init_exceptions();
641
642         /* initializes jit compiler and codegen stuff */
643         jit_init();
644
645         loader_init((u1 *) &dummy);
646
647         jit_init();
648
649         /* initialize exceptions used in the system */
650         if (!init_system_exceptions())
651                 throw_main_exception_exit();
652
653         native_loadclasses();
654
655 #if defined(USE_THREADS)
656         initThreads((u1 *) &dummy);
657 #endif
658
659         *threadrootmethod = NULL;
660
661         /*That's important, otherwise we get into trouble, if the Runtime static
662           initializer is called before (circular dependency. This is with
663           classpath 0.09. Another important thing is, that this has to happen
664           after initThreads!!! */
665
666         if (!class_init(class_new(utf_new_char("java/lang/System"))))
667                 throw_main_exception_exit();
668
669         
670         
671 /*        jni_init(); */
672         cacao_initializing = false;
673
674         /************************* Start worker routines ********************/
675
676         if (startit) {
677                 methodinfo *mainmethod;
678                 java_objectarray *a;
679                 s4 result=0; 
680
681                 /* create, load and link the main class */
682                 mainclass = class_new(utf_new_char(mainstring));
683
684                 if (!class_load(mainclass))
685                         throw_main_exception_exit();
686
687                 if (!class_link(mainclass))
688                         throw_main_exception_exit();
689
690                 mainmethod = class_resolveclassmethod(mainclass,
691                                                                                           utf_new_char("main"), 
692                                                                                           utf_new_char("([Ljava/lang/String;)V"),
693                                                                                           mainclass,
694                                                                                           false);
695
696                 /* problems with main method? */
697 /*              if (*exceptionptr) */
698 /*                      throw_exception_exit(); */
699
700                 /* there is no main method or it isn't static */
701                 if (!mainmethod || !(mainmethod->flags & ACC_STATIC)) {
702                         *exceptionptr =
703                                 new_exception_message(string_java_lang_NoSuchMethodError,
704                                                                           "main");
705                         throw_main_exception_exit();
706                 }
707
708                 a = builtin_anewarray(argc - opt_ind, class_java_lang_String);
709                 for (i = opt_ind; i < argc; i++) {
710                         a->data[i - opt_ind] = 
711                                 (java_objectheader *) javastring_new(utf_new_char(argv[i]));
712                 }
713
714 #ifdef TYPEINFO_DEBUG_TEST
715                 /* test the typeinfo system */
716                 typeinfo_test();
717 #endif
718                 /*class_showmethods(currentThread->group->header.vftbl->class); */
719
720                 *threadrootmethod = mainmethod;
721
722
723                 /* here we go... */
724                 asm_calljavafunction(mainmethod, a, NULL, NULL, NULL);
725
726                 /* exception occurred? */
727                 if (*exceptionptr) {
728                         result=1;
729                         throw_main_exception();
730                 }
731
732 #if defined(USE_THREADS)
733 #if defined(NATIVE_THREADS)
734                 joinAllThreads();
735 #else
736                 killThread(currentThread);
737 #endif
738 #endif
739
740                 /* now exit the JavaVM */
741
742                 cacao_exit(result);
743         }
744
745         /************* If requested, compile all methods ********************/
746
747         if (compileall) {
748                 classinfo *c;
749                 methodinfo *m;
750                 u4 slot;
751                 s4 i;
752
753                 /* create all classes found in the classpath */
754                 /* XXX currently only works with zip/jar's */
755                 create_all_classes();
756
757                 /* load and link all classes */
758                 for (slot = 0; slot < class_hash.size; slot++) {
759                         c = class_hash.ptr[slot];
760
761                         while (c) {
762                                 if (!c->loaded)
763                                         if (!class_load(c))
764                                                 throw_main_exception_exit();
765
766                                 if (!c->linked)
767                                         if (!class_link(c))
768                                                 throw_main_exception_exit();
769
770                                 /* compile all class methods */
771                                 for (i = 0; i < c->methodscount; i++) {
772                                         m = &(c->methods[i]);
773                                         if (m->jcode) {
774                                                 (void) jit_compile(m);
775                                         }
776                                 }
777
778                                 c = c->hashlink;
779                         }
780                 }
781         }
782
783
784         /******** If requested, compile a specific method ***************/
785
786         if (specificmethodname) {
787                 methodinfo *m;
788
789                 /* create, load and link the main class */
790                 mainclass = class_new(utf_new_char(mainstring));
791
792                 if (!class_load(mainclass))
793                         throw_main_exception_exit();
794
795                 if (!class_link(mainclass))
796                         throw_main_exception_exit();
797
798                 if (specificsignature) {
799                         m = class_resolveclassmethod(mainclass,
800                                                                                  utf_new_char(specificmethodname),
801                                                                                  utf_new_char(specificsignature),
802                                                                                  mainclass,
803                                                                                  false);
804                 } else {
805                         m = class_resolveclassmethod(mainclass,
806                                                                                  utf_new_char(specificmethodname),
807                                                                                  NULL,
808                                                                                  mainclass,
809                                                                                  false);
810                 }
811
812                 if (!m) {
813                         char message[MAXLOGTEXT];
814                         sprintf(message, "%s%s", specificmethodname,
815                                         specificsignature ? specificsignature : "");
816
817                         *exceptionptr =
818                                 new_exception_message(string_java_lang_NoSuchMethodException,
819                                                                           message);
820                                                                                  
821                         throw_main_exception_exit();
822                 }
823                 
824                 jit_compile(m);
825         }
826
827         cacao_shutdown(0);
828
829         /* keep compiler happy */
830
831         return 0;
832 }
833
834
835 /* cacao_exit ******************************************************************
836
837    Calls java.lang.Runtime.exit(I)V to exit the JavaVM correctly.
838
839 *******************************************************************************/
840
841 void cacao_exit(s4 status)
842 {
843         classinfo *c;
844         methodinfo *m;
845         java_lang_Runtime *rt;
846
847         /* class should already be loaded, but who knows... */
848
849         c = class_new(utf_new_char("java/lang/Runtime"));
850
851         if (!class_load(c))
852                 throw_main_exception_exit();
853
854         if (!class_link(c))
855                 throw_main_exception_exit();
856
857         /* first call Runtime.getRuntime()Ljava.lang.Runtime; */
858
859         m = class_resolveclassmethod(c,
860                                                                  utf_new_char("getRuntime"),
861                                                                  utf_new_char("()Ljava/lang/Runtime;"),
862                                                                  class_java_lang_Object,
863                                                                  true);
864
865         if (!m)
866                 throw_main_exception_exit();
867
868         rt = (java_lang_Runtime *) asm_calljavafunction(m,
869                                                                                                         (void *) 0,
870                                                                                                         NULL,
871                                                                                                         NULL,
872                                                                                                         NULL);
873
874         /* exception occurred? */
875
876         if (*exceptionptr)
877                 throw_main_exception_exit();
878
879         /* then call Runtime.exit(I)V */
880
881         m = class_resolveclassmethod(c,
882                                                                  utf_new_char("exit"),
883                                                                  utf_new_char("(I)V"),
884                                                                  class_java_lang_Object,
885                                                                  true);
886         
887         if (!m)
888                 throw_main_exception_exit();
889
890         asm_calljavafunction(m, rt, (void *) status, NULL, NULL);
891
892         /* this should never happen */
893
894         throw_cacao_exception_exit(string_java_lang_InternalError,
895                                                            "Problems with Runtime.exit(I)V");
896 }
897
898
899 /*************************** Shutdown function *********************************
900
901         Terminates the system immediately without freeing memory explicitly (to be
902         used only for abnormal termination)
903         
904 *******************************************************************************/
905
906 void cacao_shutdown(s4 status)
907 {
908         if (verbose || getcompilingtime || opt_stat) {
909                 log_text("CACAO terminated by shutdown");
910                 dolog("Exit status: %d\n", (s4) status);
911         }
912
913         exit(status);
914 }
915
916
917 /*
918  * These are local overrides for various environment variables in Emacs.
919  * Please do not remove this and leave it at the end of the file, where
920  * Emacs will automagically detect them.
921  * ---------------------------------------------------------------------
922  * Local variables:
923  * mode: c
924  * indent-tabs-mode: t
925  * c-basic-offset: 4
926  * tab-width: 4
927  * End:
928  */