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