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