* src/vm/resolve.c (resolve_method_lazy): Removed dependence on
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, 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., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes: Martin Platter
30
31    $Id: vm.c 4357 2006-01-22 23:33:38Z twisti $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <errno.h>
40 #include <stdlib.h>
41
42 #if defined(WITH_JRE_LAYOUT)
43 # include <libgen.h>
44 # include <unistd.h>
45 #endif
46
47 #include "vm/types.h"
48
49 #include "mm/boehm.h"
50 #include "mm/memory.h"
51 #include "native/jni.h"
52 #include "native/native.h"
53
54 #if defined(ENABLE_THREADS)
55 # include "threads/native/threads.h"
56 #endif
57
58 #include "vm/classcache.h"
59 #include "vm/exceptions.h"
60 #include "vm/finalizer.h"
61 #include "vm/global.h"
62 #include "vm/initialize.h"
63 #include "vm/options.h"
64 #include "vm/properties.h"
65 #include "vm/signallocal.h"
66 #include "vm/stringlocal.h"
67 #include "vm/suck.h"
68 #include "vm/vm.h"
69 #include "vm/jit/jit.h"
70 #include "vm/jit/asmpart.h"
71
72 #include "vm/jit/recompile.h"
73
74 #include "vm/jit/profile/profile.h"
75 #include "vm/rt-timing.h"
76
77 #if defined(ENABLE_JVMTI)
78 #include "native/jvmti/cacaodbg.h"
79 #endif
80
81
82 /* Invocation API variables ***************************************************/
83
84 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
85 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
86
87
88 /* global variables ***********************************************************/
89
90 s4 vms = 0;                             /* number of VMs created              */
91
92 bool vm_initializing = false;
93 bool vm_exiting = false;
94
95 char      *cacao_prefix = NULL;
96 char      *cacao_libjvm = NULL;
97 char      *classpath_libdir = NULL;
98
99 char      *mainstring = NULL;
100 classinfo *mainclass = NULL;
101
102 char *specificmethodname = NULL;
103 char *specificsignature = NULL;
104
105 bool startit = true;
106
107 #if defined(ENABLE_INTRP)
108 u1 *intrp_main_stack = NULL;
109 #endif
110
111
112 /* define heap sizes **********************************************************/
113
114 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
115 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
116 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
117
118
119 /* define command line options ************************************************/
120
121 enum {
122         OPT_FOO,
123
124         /* Java options */
125
126         OPT_JAR,
127
128         OPT_D32,
129         OPT_D64,
130
131         OPT_CLASSPATH,
132         OPT_D,
133
134         OPT_VERBOSE,
135
136         OPT_VERSION,
137         OPT_SHOWVERSION,
138         OPT_FULLVERSION,
139
140         OPT_HELP,
141         OPT_X,
142
143         OPT_ESA,
144         OPT_DSA,
145
146         /* Java non-standard options */
147
148         OPT_JIT,
149         OPT_INTRP,
150
151         OPT_BOOTCLASSPATH,
152         OPT_BOOTCLASSPATH_A,
153         OPT_BOOTCLASSPATH_P,
154
155         OPT_GLIBJ,
156
157         OPT_PROF,
158         OPT_PROF_OPTION,
159
160         OPT_MS,
161         OPT_MX,
162
163         /* CACAO options */
164
165         OPT_VERBOSE1,
166         OPT_NOIEEE,
167         OPT_SOFTNULL,
168
169 #if defined(ENABLE_STATISTICS)
170         OPT_TIME,
171         OPT_STAT,
172 #endif
173
174         OPT_LOG,
175         OPT_CHECK,
176         OPT_LOAD,
177         OPT_SHOW,
178         OPT_DEBUGCOLOR,
179
180 #if !defined(NDEBUG)
181         OPT_ALL,
182         OPT_METHOD,
183         OPT_SIGNATURE,
184 #endif
185
186 #if defined(ENABLE_VERIFIER)
187         OPT_NOVERIFY,
188 #if defined(TYPECHECK_VERBOSE)
189         OPT_VERBOSETC,
190 #endif
191 #endif /* defined(ENABLE_VERIFIER) */
192         OPT_EAGER,
193
194         /* optimization options */
195
196 #if defined(ENABLE_LOOP)
197         OPT_OLOOP,
198 #endif
199         
200 #if defined(ENABLE_IFCONV)
201         OPT_IFCONV,
202 #endif
203
204 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
205         OPT_LSRA,
206 #endif
207
208 #if defined(ENABLE_INLINING)
209         OPT_INLINING,
210 #endif
211
212 #if defined(ENABLE_INTRP)
213         /* interpreter options */
214
215         OPT_NO_DYNAMIC,
216         OPT_NO_REPLICATION,
217         OPT_NO_QUICKSUPER,
218         OPT_STATIC_SUPERS,
219         OPT_TRACE,
220 #endif
221
222         OPT_SS,
223
224 #ifdef ENABLE_JVMTI
225         OPT_DEBUG,
226         OPT_XRUNJDWP,
227         OPT_NOAGENT,
228         OPT_AGENTLIB,
229         OPT_AGENTPATH,
230 #endif
231
232         DUMMY
233 };
234
235
236 opt_struct opts[] = {
237         { "foo",               false, OPT_FOO },
238
239         /* Java options */
240
241         { "jar",               false, OPT_JAR },
242
243         { "d32",               false, OPT_D32 },
244         { "d64",               false, OPT_D64 },
245         { "client",            false, OPT_IGNORE },
246         { "server",            false, OPT_IGNORE },
247         { "jvm",               false, OPT_IGNORE },
248         { "hotspot",           false, OPT_IGNORE },
249
250         { "classpath",         true,  OPT_CLASSPATH },
251         { "cp",                true,  OPT_CLASSPATH },
252         { "D",                 true,  OPT_D },
253         { "version",           false, OPT_VERSION },
254         { "showversion",       false, OPT_SHOWVERSION },
255         { "fullversion",       false, OPT_FULLVERSION },
256         { "help",              false, OPT_HELP },
257         { "?",                 false, OPT_HELP },
258         { "X",                 false, OPT_X },
259
260         { "esa",                     false, OPT_ESA },
261         { "enablesystemassertions",  false, OPT_ESA },
262         { "dsa",                     false, OPT_DSA },
263         { "disablesystemassertions", false, OPT_DSA },
264
265         { "noasyncgc",         false, OPT_IGNORE },
266 #if defined(ENABLE_VERIFIER)
267         { "noverify",          false, OPT_NOVERIFY },
268 #endif
269         { "v",                 false, OPT_VERBOSE1 },
270         { "verbose:",          true,  OPT_VERBOSE },
271
272 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
273         { "verbosetc",         false, OPT_VERBOSETC },
274 #endif
275 #if defined(__ALPHA__)
276         { "noieee",            false, OPT_NOIEEE },
277 #endif
278         { "softnull",          false, OPT_SOFTNULL },
279 #if defined(ENABLE_STATISTICS)
280         { "time",              false, OPT_TIME },
281         { "stat",              false, OPT_STAT },
282 #endif
283         { "log",               true,  OPT_LOG },
284         { "c",                 true,  OPT_CHECK },
285         { "l",                 false, OPT_LOAD },
286         { "eager",             false, OPT_EAGER },
287
288 #if !defined(NDEBUG)
289         { "all",               false, OPT_ALL },
290         { "sig",               true,  OPT_SIGNATURE },
291 #endif
292
293 #if defined(ENABLE_LOOP)
294         { "oloop",             false, OPT_OLOOP },
295 #endif
296 #if defined(ENABLE_IFCONV)
297         { "ifconv",            false, OPT_IFCONV },
298 #endif
299 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
300         { "lsra",              false, OPT_LSRA },
301 #endif
302
303 #if defined(ENABLE_INTRP)
304         /* interpreter options */
305
306         { "trace",             false, OPT_TRACE },
307         { "static-supers",     true,  OPT_STATIC_SUPERS },
308         { "no-dynamic",        false, OPT_NO_DYNAMIC },
309         { "no-replication",    false, OPT_NO_REPLICATION },
310         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
311 #endif
312
313         /* JVMTI Agent Command Line Options */
314 #ifdef ENABLE_JVMTI
315         { "agentlib:",         true,  OPT_AGENTLIB },
316         { "agentpath:",        true,  OPT_AGENTPATH },
317 #endif
318
319         /* Java non-standard options */
320
321         { "Xjit",              false, OPT_JIT },
322         { "Xint",              false, OPT_INTRP },
323         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
324         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
325         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
326         { "Xglibj:",           true,  OPT_GLIBJ },
327
328 #ifdef ENABLE_JVMTI
329         { "Xdebug",            false, OPT_DEBUG },
330         { "Xnoagent",          false, OPT_NOAGENT },
331         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
332 #endif 
333
334         { "Xms",               true,  OPT_MS },
335         { "ms",                true,  OPT_MS },
336         { "Xmx",               true,  OPT_MX },
337         { "mx",                true,  OPT_MX },
338         { "Xss",               true,  OPT_SS },
339         { "ss",                true,  OPT_SS },
340         { "Xprof:",            true,  OPT_PROF_OPTION },
341         { "Xprof",             false, OPT_PROF },
342
343         /* keep these at the end of the list */
344
345 #if defined(ENABLE_INLINING)
346         { "i",                 true,  OPT_INLINING },
347 #endif
348
349 #if !defined(NDEBUG)
350         { "m",                 true,  OPT_METHOD },
351 #endif
352
353         { "s",                 true,  OPT_SHOW },
354         { "debug-color",      false,  OPT_DEBUGCOLOR },
355
356         { NULL,                false, 0 }
357 };
358
359
360 /* usage ***********************************************************************
361
362    Prints the correct usage syntax to stdout.
363
364 *******************************************************************************/
365
366 void usage(void)
367 {
368         puts("Usage: cacao [-options] classname [arguments]");
369         puts("               (to run a class file)");
370         puts("   or  cacao [-options] -jar jarfile [arguments]");
371         puts("               (to run a standalone jar file)\n");
372
373         puts("Java options:");
374         puts("    -d32                     use 32-bit data model if available");
375         puts("    -d64                     use 64-bit data model if available");
376         puts("    -client                  compatibility (currently ignored)");
377         puts("    -server                  compatibility (currently ignored)");
378         puts("    -jvm                     compatibility (currently ignored)");
379         puts("    -hotspot                 compatibility (currently ignored)\n");
380
381         puts("    -cp <path>               specify a path to look for classes");
382         puts("    -classpath <path>        specify a path to look for classes");
383         puts("    -D<name>=<value>         add an entry to the property list");
384         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
385         puts("    -version                 print product version and exit");
386         puts("    -fullversion             print jpackage-compatible product version and exit");
387         puts("    -showversion             print product version and continue");
388         puts("    -help, -?                print this help message");
389         puts("    -X                       print help on non-standard Java options");
390         puts("    -esa | -enablesystemassertions");
391         puts("                             enable system assertions");
392         puts("    -dsa | -disablesystemassertions");
393         puts("                             disable system assertions");
394         puts("");
395
396 #ifdef ENABLE_JVMTI
397         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
398         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
399         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
400 #endif
401
402         puts("CACAO options:");
403         puts("    -v                       write state-information");
404         puts("    -verbose[:call|exception|jit]");
405         puts("                             enable specific verbose output");
406         puts("    -debug-color             colored output for ANSI terms");
407 #ifdef TYPECHECK_VERBOSE
408         puts("    -verbosetc               write debug messages while typechecking");
409 #endif
410 #if defined(__ALPHA__)
411         puts("    -noieee                  don't use ieee compliant arithmetic");
412 #endif
413 #if defined(ENABLE_VERIFIER)
414         puts("    -noverify                don't verify classfiles");
415 #endif
416         puts("    -softnull                use software nullpointer check");
417 #if defined(ENABLE_STATISTICS)
418         puts("    -time                    measure the runtime");
419         puts("    -stat                    detailed compiler statistics");
420 #endif
421         puts("    -log logfile             specify a name for the logfile");
422         puts("    -c(heck)b(ounds)         don't check array bounds");
423         puts("            s(ync)           don't check for synchronization");
424 #if defined(ENABLE_LOOP)
425         puts("    -oloop                   optimize array accesses in loops");
426 #endif
427         puts("    -l                       don't start the class after loading");
428         puts("    -eager                   perform eager class loading and linking");
429 #if !defined(NDEBUG)
430         puts("    -all                     compile all methods, no execution");
431         puts("    -m                       compile only a specific method");
432         puts("    -sig                     specify signature for a specific method");
433 #endif
434
435         puts("    -s(how)...               show...");
436         puts("           c(onstants)       the constant pool");
437         puts("           m(ethods)         class fields and methods");
438         puts("           u(tf)             the utf - hash");
439         puts("           i(ntermediate)    intermediate representation");
440 #if defined(ENABLE_DISASSEMBLER)
441         puts("           a(ssembler)       disassembled listing");
442         puts("           e(xceptionstubs)  disassembled exception stubs (only with -sa)");
443         puts("           n(ative)          disassembled native stubs");
444 #endif
445         puts("           d(atasegment)     data segment listing");
446 #if defined(ENABLE_INLINING)
447         puts("    -i     n(line)           activate inlining");
448         puts("           v(irtual)         inline virtual methods (uses/turns rt option on)");
449         puts("           e(exception)      inline methods with exceptions");
450         puts("           p(aramopt)        optimize argument renaming");
451         puts("           o(utsiders)       inline methods of foreign classes");
452 #endif /* defined(ENABLE_INLINING) */
453 #if defined(ENABLE_IFCONV)
454         puts("    -ifconv                  use if-conversion");
455 #endif
456 #if defined(ENABLE_LSRA)
457         puts("    -lsra                    use linear scan register allocation");
458 #endif
459 #if defined(ENABLE_SSA)
460         puts("    -lsra                    use linear scan register allocation (with SSA)");
461 #endif
462
463         /* exit with error code */
464
465         exit(1);
466 }   
467
468
469 static void Xusage(void)
470 {
471 #if defined(ENABLE_JIT)
472         puts("    -Xjit                    JIT mode execution (default)");
473 #endif
474 #if defined(ENABLE_INTRP)
475         puts("    -Xint                    interpreter mode execution");
476 #endif
477         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
478     puts("                             value is set as bootstrap class path");
479         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
480         puts("                             value is appended to the bootstrap class path");
481         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
482         puts("                             value is prepended to the bootstrap class path");
483         puts("    -Xglibj:<zip/jar files and directories separated by :>");
484         puts("                             value is used as Java core library, but the");
485         puts("                             hardcoded VM interface classes are prepended");
486         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
487         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
488         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
489         puts("    -Xprof[:bb]              collect and print profiling data");
490 #if defined(ENABLE_JVMTI)
491     /* -Xdebug option depend on gnu classpath JDWP options. options: 
492          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
493         puts("    -Xdebug                  enable remote debugging\n");
494         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
495         puts("                             enable remote debugging\n");
496 #endif 
497
498         /* exit with error code */
499
500         exit(1);
501 }   
502
503
504 /* version *********************************************************************
505
506    Only prints cacao version information.
507
508 *******************************************************************************/
509
510 static void version(bool opt_exit)
511 {
512         puts("java version \""JAVA_VERSION"\"");
513         puts("CACAO version "VERSION"");
514
515         puts("Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,");
516         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
517         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
518         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
519
520         puts("This program is free software; you can redistribute it and/or");
521         puts("modify it under the terms of the GNU General Public License as");
522         puts("published by the Free Software Foundation; either version 2, or (at");
523         puts("your option) any later version.\n");
524
525         puts("This program is distributed in the hope that it will be useful, but");
526         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
527         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
528         puts("General Public License for more details.\n");
529
530         puts("Configure/Build options:\n");
531         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
532 #if defined(__VERSION__)
533         puts("  CC         : "VERSION_CC" ("__VERSION__")");
534 #else
535         puts("  CC         : "VERSION_CC"");
536 #endif
537         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
538
539         puts("Default variables:\n");
540         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
541         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
542         printf("  stack size                     : %d\n", STACK_SIZE);
543         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_GLIBJ_ZIP"");
544         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
545
546         puts("Runtime variables:\n");
547         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
548         printf("  initial heap size              : %d\n", opt_heapstartsize);
549         printf("  stack size                     : %d\n", opt_stacksize);
550         printf("  java.boot.class.path           : %s\n", bootclasspath);
551         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
552
553         /* exit normally, if requested */
554
555         if (opt_exit)
556                 exit(0);
557 }
558
559
560 /* fullversion *****************************************************************
561
562    Prints a Sun compatible version information (required e.g. by
563    jpackage, www.jpackage.org).
564
565 *******************************************************************************/
566
567 static void fullversion(void)
568 {
569         puts("java full version \"cacao-"JAVA_VERSION"\"");
570
571         /* exit normally */
572
573         exit(0);
574 }
575
576
577 /* forward declarations *******************************************************/
578
579 static char *vm_get_mainclass_from_jar(char *mainstring);
580 #if !defined(NDEBUG)
581 static void  vm_compile_all(void);
582 static void  vm_compile_method(void);
583 #endif
584
585
586 /* vm_create *******************************************************************
587
588    Creates a JVM.  Called by JNI_CreateJavaVM.
589
590 *******************************************************************************/
591
592 bool vm_create(JavaVMInitArgs *vm_args)
593 {
594         char *cp;
595         s4    len;
596         s4    opt;
597         s4    i, j, k;
598         bool  opt_version;
599         bool  opt_exit;
600
601 #if defined(ENABLE_JVMTI)
602         lt_dlhandle  handle;
603         char *libname, *agentarg;
604         bool jdwp,agentbypath;
605         jdwp = agentbypath = false;
606 #endif
607
608         /* check the JNI version requested */
609
610         switch (vm_args->version) {
611         case JNI_VERSION_1_1:
612                 break;
613         case JNI_VERSION_1_2:
614         case JNI_VERSION_1_4:
615                 break;
616         default:
617                 return false;
618         }
619
620         /* we only support 1 JVM instance */
621
622         if (vms > 0)
623                 return false;
624
625         if (atexit(vm_exit_handler))
626                 vm_abort("atexit failed: %s\n", strerror(errno));
627
628         if (opt_verbose)
629                 log_text("CACAO started -------------------------------------------------------");
630
631         /* set the VM starttime */
632
633         _Jv_jvm->starttime = builtin_currenttimemillis();
634
635         /* get stuff from the environment *****************************************/
636
637 #if defined(DISABLE_GC)
638         nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
639 #endif
640
641 #if defined(WITH_JRE_LAYOUT)
642         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
643
644         cacao_prefix = MNEW(char, 4096);
645
646         if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
647                 vm_abort("readlink failed: %s\n", strerror(errno));
648
649         /* get the path of the current executable */
650
651         cacao_prefix = dirname(cacao_prefix);
652
653         if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
654                 vm_abort("libjvm name to long for buffer\n");
655
656         /* concatenate the library name */
657
658         strcat(cacao_prefix, "/..");
659
660         /* now set path to libjvm.so */
661
662         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
663
664         cacao_libjvm = MNEW(char, len);
665         strcpy(cacao_libjvm, cacao_prefix);
666         strcat(cacao_libjvm, "/lib/libjvm");
667
668         /* and finally set the path to GNU Classpath libraries */
669
670         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
671
672         classpath_libdir = MNEW(char, len);
673         strcpy(classpath_libdir, cacao_prefix);
674         strcat(classpath_libdir, "/lib/classpath");
675 #else
676         cacao_prefix     = CACAO_PREFIX;
677         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
678         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
679 #endif
680
681         /* set the bootclasspath */
682
683         cp = getenv("BOOTCLASSPATH");
684
685         if (cp != NULL) {
686                 bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
687                 strcpy(bootclasspath, cp);
688         }
689         else {
690 #if defined(WITH_JRE_LAYOUT)
691                 len =
692                         strlen(cacao_prefix) +
693                         strlen("/share/cacao/vm.zip") +
694                         strlen(":") +
695                         strlen(cacao_prefix) +
696                         strlen("/share/classpath/glibj.zip") +
697                         strlen("0");
698
699                 bootclasspath = MNEW(char, len);
700                 strcat(bootclasspath, cacao_prefix);
701                 strcat(bootclasspath, "/share/cacao/vm.zip");
702                 strcat(bootclasspath, ":");
703                 strcat(bootclasspath, cacao_prefix);
704                 strcat(bootclasspath, "/share/classpath/glibj.zip");
705 #else
706                 len = strlen(CACAO_VM_ZIP) +
707                         strlen(":") +
708                         strlen(CLASSPATH_GLIBJ_ZIP) +
709                         strlen("0");
710
711                 bootclasspath = MNEW(char, len);
712                 strcat(bootclasspath, CACAO_VM_ZIP);
713                 strcat(bootclasspath, ":");
714                 strcat(bootclasspath, CLASSPATH_GLIBJ_ZIP);
715 #endif
716         }
717
718         /* set the classpath */
719
720         cp = getenv("CLASSPATH");
721
722         if (cp != NULL) {
723                 classpath = MNEW(char, strlen(cp) + strlen("0"));
724                 strcat(classpath, cp);
725         }
726         else {
727                 classpath = MNEW(char, strlen(".") + strlen("0"));
728                 strcpy(classpath, ".");
729         }
730
731
732         /* interpret the options **************************************************/
733
734         opt_version       = false;
735         opt_exit          = false;
736
737         checknull         = false;
738         opt_noieee        = false;
739
740         opt_heapmaxsize   = HEAP_MAXSIZE;
741         opt_heapstartsize = HEAP_STARTSIZE;
742         opt_stacksize     = STACK_SIZE;
743
744
745 #if defined(ENABLE_JVMTI)
746         /* initialize JVMTI related  **********************************************/
747         jvmti = false;
748 #endif
749
750         /* initialize properties before commandline handling */
751
752         if (!properties_init())
753                 throw_cacao_exception_exit(string_java_lang_InternalError,
754                                                                    "Unable to init properties");
755
756         /* add some default properties */
757
758         properties_add("java.endorsed.dirs", ""CACAO_PREFIX"/jre/lib/endorsed");
759
760         /* iterate over all passed options */
761
762         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
763                 switch (opt) {
764                 case OPT_FOO:
765                         opt_foo = true;
766                         break;
767
768                 case OPT_IGNORE:
769                         break;
770                         
771                 case OPT_JAR:
772                         opt_jar = true;
773                         break;
774
775                 case OPT_D32:
776 #if SIZEOF_VOID_P == 8
777                         puts("Running a 32-bit JVM is not supported on this platform.");
778                         exit(1);
779 #endif
780                         break;
781
782                 case OPT_D64:
783 #if SIZEOF_VOID_P == 4
784                         puts("Running a 64-bit JVM is not supported on this platform.");
785                         exit(1);
786 #endif
787                         break;
788
789                 case OPT_CLASSPATH:
790                         /* forget old classpath and set the argument as new classpath */
791                         MFREE(classpath, char, strlen(classpath));
792
793                         classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
794                         strcpy(classpath, opt_arg);
795                         break;
796
797                 case OPT_D:
798                         for (j = 0; j < strlen(opt_arg); j++) {
799                                 if (opt_arg[j] == '=') {
800                                         opt_arg[j] = '\0';
801                                         properties_add(opt_arg, opt_arg + j + 1);
802                                         goto opt_d_done;
803                                 }
804                         }
805
806                         /* if no '=' is given, just create an empty property */
807
808                         properties_add(opt_arg, "");
809
810                 opt_d_done:
811                         break;
812
813                 case OPT_BOOTCLASSPATH:
814                         /* Forget default bootclasspath and set the argument as
815                            new boot classpath. */
816
817                         MFREE(bootclasspath, char, strlen(bootclasspath));
818
819                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
820                         strcpy(bootclasspath, opt_arg);
821                         break;
822
823                 case OPT_BOOTCLASSPATH_A:
824                         /* append to end of bootclasspath */
825
826                         len = strlen(bootclasspath);
827
828                         bootclasspath = MREALLOC(bootclasspath,
829                                                                          char,
830                                                                          len,
831                                                                          len + strlen(":") +
832                                                                          strlen(opt_arg) + strlen("0"));
833
834                         strcat(bootclasspath, ":");
835                         strcat(bootclasspath, opt_arg);
836                         break;
837
838                 case OPT_BOOTCLASSPATH_P:
839                         /* prepend in front of bootclasspath */
840
841                         cp = bootclasspath;
842                         len = strlen(cp);
843
844                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
845                                                                  len + strlen("0"));
846
847                         strcpy(bootclasspath, opt_arg);
848                         strcat(bootclasspath, ":");
849                         strcat(bootclasspath, cp);
850
851                         MFREE(cp, char, len);
852                         break;
853
854                 case OPT_GLIBJ:
855                         /* use as Java core library, but prepend VM interface classes */
856
857                         MFREE(bootclasspath, char, strlen(bootclasspath));
858
859                         len = strlen(CACAO_VM_ZIP) +
860                                 strlen(":") +
861                                 strlen(opt_arg) +
862                                 strlen("0");
863
864                         bootclasspath = MNEW(char, len);
865
866                         strcpy(bootclasspath, CACAO_VM_ZIP);
867                         strcat(bootclasspath, ":");
868                         strcat(bootclasspath, opt_arg);
869                         break;
870
871 #if defined(ENABLE_JVMTI)
872                 case OPT_DEBUG:
873                         /* this option exists only for compatibility reasons */
874                         break;
875
876                 case OPT_NOAGENT:
877                         /* I don't know yet what Xnoagent should do. This is only for 
878                            compatiblity with eclipse - motse */
879                         break;
880
881                 case OPT_XRUNJDWP:
882                         agentbypath = true;
883                         jvmti       = true;
884                         jdwp        = true;
885
886                         len =
887                                 strlen(CACAO_LIBDIR) +
888                                 strlen("/libjdwp.so=") +
889                                 strlen(opt_arg) +
890                                 strlen("0");
891
892                         agentarg = MNEW(char, len);
893
894                         strcpy(agentarg, CACAO_LIBDIR);
895                         strcat(agentarg, "/libjdwp.so=");
896                         strcat(agentarg, &opt_arg[1]);
897                         break;
898
899                 case OPT_AGENTPATH:
900                         agentbypath = true;
901
902                 case OPT_AGENTLIB:
903                         jvmti = true;
904                         agentarg = opt_arg;
905                         break;
906 #endif
907                         
908                 case OPT_MX:
909                 case OPT_MS:
910                 case OPT_SS:
911                         {
912                                 char c;
913                                 c = opt_arg[strlen(opt_arg) - 1];
914
915                                 if ((c == 'k') || (c == 'K')) {
916                                         j = atoi(opt_arg) * 1024;
917
918                                 } else if ((c == 'm') || (c == 'M')) {
919                                         j = atoi(opt_arg) * 1024 * 1024;
920
921                                 } else
922                                         j = atoi(opt_arg);
923
924                                 if (opt == OPT_MX)
925                                         opt_heapmaxsize = j;
926                                 else if (opt == OPT_MS)
927                                         opt_heapstartsize = j;
928                                 else
929                                         opt_stacksize = j;
930                         }
931                         break;
932
933                 case OPT_VERBOSE1:
934                         opt_verbose = true;
935                         break;
936
937                 case OPT_VERBOSE:
938                         if (strcmp("class", opt_arg) == 0)
939                                 opt_verboseclass = true;
940
941                         else if (strcmp("gc", opt_arg) == 0)
942                                 opt_verbosegc = true;
943
944                         else if (strcmp("jni", opt_arg) == 0)
945                                 opt_verbosejni = true;
946
947                         else if (strcmp("call", opt_arg) == 0)
948                                 opt_verbosecall = true;
949
950                         else if (strcmp("jit", opt_arg) == 0) {
951                                 opt_verbose = true;
952                                 loadverbose = true;
953                                 linkverbose = true;
954                                 initverbose = true;
955                                 compileverbose = true;
956                         }
957                         else if (strcmp("exception", opt_arg) == 0)
958                                 opt_verboseexception = true;
959                         break;
960                 case OPT_DEBUGCOLOR:
961                         opt_debugcolor = true;
962                         break;
963
964 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
965                 case OPT_VERBOSETC:
966                         opt_typecheckverbose = true;
967                         break;
968 #endif
969                                 
970                 case OPT_VERSION:
971                         opt_version = true;
972                         opt_exit    = true;
973                         break;
974
975                 case OPT_FULLVERSION:
976                         fullversion();
977                         break;
978
979                 case OPT_SHOWVERSION:
980                         opt_version = true;
981                         break;
982
983                 case OPT_NOIEEE:
984                         opt_noieee = true;
985                         break;
986
987 #if defined(ENABLE_VERIFIER)
988                 case OPT_NOVERIFY:
989                         opt_verify = false;
990                         break;
991 #endif
992
993                 case OPT_SOFTNULL:
994                         checknull = true;
995                         break;
996
997 #if defined(ENABLE_STATISTICS)
998                 case OPT_TIME:
999                         opt_getcompilingtime = true;
1000                         opt_getloadingtime = true;
1001                         break;
1002                                         
1003                 case OPT_STAT:
1004                         opt_stat = true;
1005                         break;
1006 #endif
1007                                         
1008                 case OPT_LOG:
1009                         log_init(opt_arg);
1010                         break;
1011                         
1012                 case OPT_CHECK:
1013                         for (j = 0; j < strlen(opt_arg); j++) {
1014                                 switch (opt_arg[j]) {
1015                                 case 'b':
1016                                         checkbounds = false;
1017                                         break;
1018                                 case 's':
1019                                         checksync = false;
1020                                         break;
1021                                 default:
1022                                         usage();
1023                                 }
1024                         }
1025                         break;
1026                         
1027                 case OPT_LOAD:
1028                         opt_run = false;
1029                         makeinitializations = false;
1030                         break;
1031
1032                 case OPT_EAGER:
1033                         opt_eager = true;
1034                         break;
1035
1036 #if !defined(NDEBUG)
1037                 case OPT_ALL:
1038                         compileall = true;
1039                         opt_run = false;
1040                         makeinitializations = false;
1041                         break;
1042
1043                 case OPT_METHOD:
1044                         opt_run = false;
1045                         opt_method = opt_arg;
1046                         makeinitializations = false;
1047                         break;
1048
1049                 case OPT_SIGNATURE:
1050                         opt_signature = opt_arg;
1051                         break;
1052 #endif
1053
1054                 case OPT_SHOW:       /* Display options */
1055                         for (j = 0; j < strlen(opt_arg); j++) {         
1056                                 switch (opt_arg[j]) {
1057                                 case 'c':
1058                                         showconstantpool = true;
1059                                         break;
1060
1061                                 case 'u':
1062                                         showutf = true;
1063                                         break;
1064
1065                                 case 'm':
1066                                         showmethods = true;
1067                                         break;
1068
1069                                 case 'i':
1070                                         opt_showintermediate = true;
1071                                         compileverbose = true;
1072                                         break;
1073
1074 #if defined(ENABLE_DISASSEMBLER)
1075                                 case 'a':
1076                                         opt_showdisassemble = true;
1077                                         compileverbose = true;
1078                                         break;
1079
1080                                 case 'e':
1081                                         opt_showexceptionstubs = true;
1082                                         break;
1083
1084                                 case 'n':
1085                                         opt_shownativestub = true;
1086                                         break;
1087 #endif
1088
1089                                 case 'd':
1090                                         opt_showddatasegment = true;
1091                                         break;
1092
1093                                 default:
1094                                         usage();
1095                                 }
1096                         }
1097                         break;
1098                         
1099 #if defined(ENABLE_LOOP)
1100                 case OPT_OLOOP:
1101                         opt_loops = true;
1102                         break;
1103 #endif
1104
1105 #if defined(ENABLE_INLINING)
1106                 case OPT_INLINING:
1107                         for (j = 0; j < strlen(opt_arg); j++) {         
1108                                 switch (opt_arg[j]) {
1109                                 case 'n':
1110                                         /* define in options.h; Used in main.c, jit.c
1111                                            & inline.c inlining is currently
1112                                            deactivated */
1113                                         break;
1114                                 case 'v':
1115                                         inlinevirtuals = true;
1116                                         break;
1117                                 case 'e':
1118                                         inlineexceptions = true;
1119                                         break;
1120                                 case 'p':
1121                                         inlineparamopt = true;
1122                                         break;
1123                                 case 'o':
1124                                         inlineoutsiders = true;
1125                                         break;
1126                                 default:
1127                                         usage();
1128                                 }
1129                         }
1130                         break;
1131 #endif /* defined(ENABLE_INLINING) */
1132
1133 #if defined(ENABLE_IFCONV)
1134                 case OPT_IFCONV:
1135                         opt_ifconv = true;
1136                         break;
1137 #endif
1138
1139 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1140                 case OPT_LSRA:
1141                         opt_lsra = true;
1142                         break;
1143 #endif
1144
1145                 case OPT_HELP:
1146                         usage();
1147                         break;
1148
1149                 case OPT_X:
1150                         Xusage();
1151                         break;
1152
1153                 case OPT_ESA:
1154                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1155                         break;
1156
1157                 case OPT_DSA:
1158                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1159                         break;
1160
1161                 case OPT_PROF_OPTION:
1162                         /* use <= to get the last \0 too */
1163
1164                         for (j = 0, k = 0; j <= strlen(opt_arg); j++) {
1165                                 if (opt_arg[j] == ',')
1166                                         opt_arg[j] = '\0';
1167
1168                                 if (opt_arg[j] == '\0') {
1169                                         if (strcmp("bb", opt_arg + k) == 0)
1170                                                 opt_prof_bb = true;
1171
1172                                         else {
1173                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + k);
1174                                                 usage();
1175                                         }
1176
1177                                         /* set k to next char */
1178
1179                                         k = j + 1;
1180                                 }
1181                         }
1182                         /* fall through */
1183
1184                 case OPT_PROF:
1185                         opt_prof = true;
1186                         break;
1187
1188                 case OPT_JIT:
1189 #if defined(ENABLE_JIT)
1190                         opt_jit = true;
1191 #else
1192                         printf("-Xjit option not enabled.\n");
1193                         exit(1);
1194 #endif
1195                         break;
1196
1197                 case OPT_INTRP:
1198 #if defined(ENABLE_INTRP)
1199                         opt_intrp = true;
1200 #if defined(ENABLE_VERIFIER)
1201                         /* XXX currently the verifier does not work with the interpreter */
1202                         opt_verify = false;
1203 #endif
1204 #else
1205                         printf("-Xint option not enabled.\n");
1206                         exit(1);
1207 #endif
1208                         break;
1209
1210 #if defined(ENABLE_INTRP)
1211                 case OPT_STATIC_SUPERS:
1212                         opt_static_supers = atoi(opt_arg);
1213                         break;
1214
1215                 case OPT_NO_DYNAMIC:
1216                         opt_no_dynamic = true;
1217                         break;
1218
1219                 case OPT_NO_REPLICATION:
1220                         opt_no_replication = true;
1221                         break;
1222
1223                 case OPT_NO_QUICKSUPER:
1224                         opt_no_quicksuper = true;
1225                         break;
1226
1227                 case OPT_TRACE:
1228                         vm_debug = true;
1229                         break;
1230 #endif
1231
1232                 default:
1233                         printf("Unknown option: %s\n",
1234                                    vm_args->options[opt_index].optionString);
1235                         usage();
1236                 }
1237         }
1238
1239
1240         /* Now we have all options handled and we can print the version
1241            information. */
1242
1243         if (opt_version)
1244                 version(opt_exit);
1245
1246
1247         /* get the main class *****************************************************/
1248
1249         if (opt_index < vm_args->nOptions) {
1250                 mainstring = vm_args->options[opt_index++].optionString;
1251
1252                 /* Put the jar file into the classpath (if any). */
1253
1254                 if (opt_jar == true) {
1255                         /* free old classpath */
1256
1257                         MFREE(classpath, char, strlen(classpath));
1258
1259                         /* put jarfile into classpath */
1260
1261                         classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1262
1263                         strcpy(classpath, mainstring);
1264                 }
1265                 else {
1266                         /* replace .'s with /'s in classname */
1267
1268                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1269                                 if (mainstring[i] == '.')
1270                                         mainstring[i] = '/';
1271                 }
1272         }
1273
1274 #if defined(ENABLE_JVMTI)
1275         if (jvmti) {
1276                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1277                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1278
1279                 if (jdwp)
1280                         MFREE(agentarg, char, strlen(agentarg));
1281
1282                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1283         }
1284
1285 #endif
1286
1287
1288         /* initialize this JVM ****************************************************/
1289
1290         vm_initializing = true;
1291
1292         /* initialize the garbage collector */
1293
1294         gc_init(opt_heapmaxsize, opt_heapstartsize);
1295
1296 #if defined(ENABLE_INTRP)
1297         /* Allocate main thread stack on the Java heap. */
1298
1299         if (opt_intrp) {
1300                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1301                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1302         }
1303 #endif
1304
1305 #if defined(ENABLE_THREADS)
1306         threads_preinit();
1307 #endif
1308
1309         /* initialize the string hashtable stuff: lock (must be done
1310            _after_ threads_preinit) */
1311
1312         if (!string_init())
1313                 throw_main_exception_exit();
1314
1315         /* initialize the utf8 hashtable stuff: lock, often used utf8
1316            strings (must be done _after_ threads_preinit) */
1317
1318         if (!utf8_init())
1319                 throw_main_exception_exit();
1320
1321         /* initialize the classcache hashtable stuff: lock, hashtable
1322            (must be done _after_ threads_preinit) */
1323
1324         if (!classcache_init())
1325                 throw_main_exception_exit();
1326
1327         /* initialize the loader with bootclasspath (must be done _after_
1328            thread_preinit) */
1329
1330         if (!suck_init())
1331                 throw_main_exception_exit();
1332
1333         suck_add_from_property("java.endorsed.dirs");
1334         suck_add(bootclasspath);
1335
1336         /* initialize the memory subsystem (must be done _after_
1337            threads_preinit) */
1338
1339         if (!memory_init())
1340                 throw_main_exception_exit();
1341
1342         /* initialize the finalizer stuff (must be done _after_
1343            threads_preinit) */
1344
1345         if (!finalizer_init())
1346                 throw_main_exception_exit();
1347
1348         /* install architecture dependent signal handler used for exceptions */
1349
1350         signal_init();
1351
1352         /* initialize the codegen subsystems */
1353
1354         codegen_init();
1355
1356         /* initializes jit compiler */
1357
1358         jit_init();
1359
1360         /* machine dependent initialization */
1361
1362 #if defined(ENABLE_JIT)
1363 # if defined(ENABLE_INTRP)
1364         if (opt_intrp)
1365                 intrp_md_init();
1366         else
1367 # endif
1368                 md_init();
1369 #else
1370         intrp_md_init();
1371 #endif
1372
1373         /* initialize the loader subsystems (must be done _after_
1374        classcache_init) */
1375
1376         if (!loader_init())
1377                 throw_main_exception_exit();
1378
1379         if (!linker_init())
1380                 throw_main_exception_exit();
1381
1382         if (!native_init())
1383                 throw_main_exception_exit();
1384
1385         if (!exceptions_init())
1386                 throw_main_exception_exit();
1387
1388         if (!builtin_init())
1389                 throw_main_exception_exit();
1390
1391         /* Initialize the JNI subsystem (must be done _before_
1392            threads_init, as threads_init can call JNI methods
1393            (e.g. NewGlobalRef). */
1394
1395         if (!jni_init())
1396                 throw_main_exception_exit();
1397
1398 #if defined(ENABLE_THREADS)
1399         if (!threads_init())
1400                 throw_main_exception_exit();
1401 #endif
1402
1403         /* That's important, otherwise we get into trouble, if the Runtime
1404            static initializer is called before (circular dependency. This
1405            is with classpath 0.09. Another important thing is, that this
1406            has to happen after initThreads!!! */
1407
1408         if (!initialize_class(class_java_lang_System))
1409                 throw_main_exception_exit();
1410
1411 #if defined(ENABLE_PROFILING)
1412         /* initialize profiling */
1413
1414         if (!profile_init())
1415                 throw_main_exception_exit();
1416 #endif
1417
1418 #if defined(ENABLE_THREADS)
1419         /* initialize recompilation */
1420
1421         if (!recompile_init())
1422                 throw_main_exception_exit();
1423                 
1424         /* finally, start the finalizer thread */
1425
1426         if (!finalizer_start_thread())
1427                 throw_main_exception_exit();
1428
1429         /* start the recompilation thread (must be done before the
1430            profiling thread) */
1431
1432         if (!recompile_start_thread())
1433                 throw_main_exception_exit();
1434
1435 # if defined(ENABLE_PROFILING)
1436         /* start the profile sampling thread */
1437
1438         if (opt_prof)
1439                 if (!profile_start_thread())
1440                         throw_main_exception_exit();
1441 # endif
1442 #endif
1443
1444 #if defined(ENABLE_JVMTI)
1445         if (jvmti) {
1446                 /* add agent library to native library hashtable */
1447                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1448         }
1449 #endif
1450
1451         /* increment the number of VMs */
1452
1453         vms++;
1454
1455         /* initialization is done */
1456
1457         vm_initializing = false;
1458
1459         /* everything's ok */
1460
1461         return true;
1462 }
1463
1464
1465 /* vm_run **********************************************************************
1466
1467    Runs the main-method of the passed class.
1468
1469 *******************************************************************************/
1470
1471 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1472 {
1473         utf              *mainutf;
1474         classinfo        *mainclass;
1475         methodinfo       *m;
1476         java_objectarray *oa; 
1477         s4                oalength;
1478         utf              *u;
1479         java_lang_String *s;
1480         s4                status;
1481         s4                i;
1482
1483 #if !defined(NDEBUG)
1484         if (compileall) {
1485                 vm_compile_all();
1486                 return;
1487         }
1488
1489         if (opt_method != NULL) {
1490                 vm_compile_method();
1491                 return;
1492         }
1493 #endif /* !defined(NDEBUG) */
1494
1495         /* should we run the main-method? */
1496
1497         if (mainstring == NULL)
1498                 usage();
1499
1500         /* set return value to OK */
1501
1502         status = 0;
1503
1504         if (opt_jar == true)
1505                 /* open jar file with java.util.jar.JarFile */
1506                 mainstring = vm_get_mainclass_from_jar(mainstring);
1507
1508         /* load the main class */
1509
1510         mainutf = utf_new_char(mainstring);
1511
1512         if (!(mainclass = load_class_from_sysloader(mainutf)))
1513                 throw_main_exception_exit();
1514
1515         /* error loading class, clear exceptionptr for new exception */
1516
1517         if (*exceptionptr || !mainclass) {
1518                 /*                      *exceptionptr = NULL; */
1519
1520                 /*                      *exceptionptr = */
1521                 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
1522                 /*                                                                        mainstring); */
1523                 throw_main_exception_exit();
1524         }
1525
1526         if (!link_class(mainclass))
1527                 throw_main_exception_exit();
1528                         
1529         /* find the `main' method of the main class */
1530
1531         m = class_resolveclassmethod(mainclass,
1532                                                                  utf_new_char("main"), 
1533                                                                  utf_new_char("([Ljava/lang/String;)V"),
1534                                                                  class_java_lang_Object,
1535                                                                  false);
1536
1537         if (*exceptionptr) {
1538                 throw_main_exception_exit();
1539         }
1540
1541         /* there is no main method or it isn't static */
1542
1543         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1544                 *exceptionptr = NULL;
1545
1546                 *exceptionptr =
1547                         new_exception_message(string_java_lang_NoSuchMethodError, "main");
1548                 throw_main_exception_exit();
1549         }
1550
1551         /* build argument array */
1552
1553         oalength = vm_args->nOptions - opt_index;
1554
1555         oa = builtin_anewarray(oalength, class_java_lang_String);
1556
1557         for (i = 0; i < oalength; i++) {
1558                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1559                 s = javastring_new(u);
1560
1561                 oa->data[i] = (java_objectheader *) s;
1562         }
1563
1564 #ifdef TYPEINFO_DEBUG_TEST
1565         /* test the typeinfo system */
1566         typeinfo_test();
1567 #endif
1568         /*class_showmethods(currentThread->group->header.vftbl->class); */
1569
1570 #if defined(ENABLE_JVMTI)
1571         jvmti_set_phase(JVMTI_PHASE_LIVE);
1572 #endif
1573
1574         /* increase total started thread count */
1575
1576         _Jv_jvm->total_started_thread_count++;
1577
1578         /* start the main thread */
1579
1580         (void) vm_call_method(m, NULL, oa);
1581
1582         /* exception occurred? */
1583
1584         if (*exceptionptr) {
1585                 throw_main_exception();
1586                 status = 1;
1587         }
1588
1589         /* unload the JavaVM */
1590
1591         vm_destroy(vm);
1592
1593         /* and exit */
1594
1595         vm_exit(status);
1596 }
1597
1598
1599 /* vm_destroy ******************************************************************
1600
1601    Unloads a Java VM and reclaims its resources.
1602
1603 *******************************************************************************/
1604
1605 s4 vm_destroy(JavaVM *vm)
1606 {
1607 #if defined(ENABLE_THREADS)
1608         threads_join_all_threads();
1609 #endif
1610
1611         /* everything's ok */
1612
1613         return 0;
1614 }
1615
1616
1617 /* vm_exit *********************************************************************
1618
1619    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1620
1621 *******************************************************************************/
1622
1623 void vm_exit(s4 status)
1624 {
1625         methodinfo *m;
1626
1627         /* signal that we are exiting */
1628
1629         vm_exiting = true;
1630
1631         assert(class_java_lang_System);
1632         assert(class_java_lang_System->state & CLASS_LOADED);
1633
1634 #if defined(ENABLE_JVMTI)
1635         if (jvmti || (dbgcom!=NULL)) {
1636                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1637                 if (jvmti) jvmti_agentunload();
1638         }
1639 #endif
1640
1641         if (!link_class(class_java_lang_System))
1642                 throw_main_exception_exit();
1643
1644         /* call java.lang.System.exit(I)V */
1645
1646         m = class_resolveclassmethod(class_java_lang_System,
1647                                                                  utf_new_char("exit"),
1648                                                                  utf_int__void,
1649                                                                  class_java_lang_Object,
1650                                                                  true);
1651         
1652         if (m == NULL)
1653                 throw_main_exception_exit();
1654
1655         /* call the exit function with passed exit status */
1656
1657         (void) vm_call_method(m, NULL, status);
1658
1659         /* If we had an exception, just ignore the exception and exit with
1660            the proper code. */
1661
1662         vm_shutdown(status);
1663 }
1664
1665
1666 /* vm_shutdown *****************************************************************
1667
1668    Terminates the system immediately without freeing memory explicitly
1669    (to be used only for abnormal termination).
1670         
1671 *******************************************************************************/
1672
1673 void vm_shutdown(s4 status)
1674 {
1675         if (opt_verbose 
1676 #if defined(ENABLE_STATISTICS)
1677                 || opt_getcompilingtime || opt_stat
1678 #endif
1679            ) 
1680         {
1681                 log_text("CACAO terminated by shutdown");
1682                 dolog("Exit status: %d\n", (s4) status);
1683
1684         }
1685
1686 #if defined(ENABLE_JVMTI)
1687         /* terminate cacaodbgserver */
1688         if (dbgcom!=NULL) {
1689                 pthread_mutex_lock(&dbgcomlock);
1690                 dbgcom->running=1;
1691                 pthread_mutex_unlock(&dbgcomlock);
1692                 jvmti_cacaodbgserver_quit();
1693         }       
1694 #endif
1695
1696         exit(status);
1697 }
1698
1699
1700 /* vm_exit_handler *************************************************************
1701
1702    The exit_handler function is called upon program termination.
1703
1704    ATTENTION: Don't free system resources here! Some threads may still
1705    be running as this is called from VMRuntime.exit(). The OS does the
1706    cleanup for us.
1707
1708 *******************************************************************************/
1709
1710 void vm_exit_handler(void)
1711 {
1712 #if !defined(NDEBUG)
1713         if (showmethods)
1714                 class_showmethods(mainclass);
1715
1716         if (showconstantpool)
1717                 class_showconstantpool(mainclass);
1718
1719         if (showutf)
1720                 utf_show();
1721
1722 # if defined(ENABLE_PROFILING)
1723         if (opt_prof)
1724                 profile_printstats();
1725 # endif
1726 #endif /* !defined(NDEBUG) */
1727
1728 #if defined(ENABLE_RT_TIMING)
1729         rt_timing_print_time_stats(stderr);
1730 #endif
1731
1732 #if defined(ENABLE_CYCLES_STATS)
1733         builtin_print_cycles_stats(stderr);
1734         stacktrace_print_cycles_stats(stderr);
1735 #endif
1736
1737         if (opt_verbose 
1738 #if defined(ENABLE_STATISTICS)
1739                 || opt_getcompilingtime || opt_stat
1740 #endif
1741            ) 
1742         {
1743                 log_text("CACAO terminated");
1744
1745 #if defined(ENABLE_STATISTICS)
1746                 if (opt_stat) {
1747                         print_stats();
1748 #ifdef TYPECHECK_STATISTICS
1749                         typecheck_print_statistics(get_logfile());
1750 #endif
1751                 }
1752
1753                 mem_usagelog(1);
1754
1755                 if (opt_getcompilingtime)
1756                         print_times();
1757 #endif /* defined(ENABLE_STATISTICS) */
1758         }
1759         /* vm_print_profile(stderr);*/
1760 }
1761
1762
1763 /* vm_abort ********************************************************************
1764
1765    Prints an error message and aborts the VM.
1766
1767 *******************************************************************************/
1768
1769 void vm_abort(const char *text, ...)
1770 {
1771         va_list ap;
1772
1773         /* print the log message */
1774
1775         log_start();
1776
1777         va_start(ap, text);
1778         log_vprint(text, ap);
1779         va_end(ap);
1780
1781         log_finish();
1782
1783         /* now abort the VM */
1784
1785         abort();
1786 }
1787
1788
1789 /* vm_get_mainclass_from_jar ***************************************************
1790
1791    Gets the name of the main class from a JAR's manifest file.
1792
1793 *******************************************************************************/
1794
1795 static char *vm_get_mainclass_from_jar(char *mainstring)
1796 {
1797         classinfo         *c;
1798         java_objectheader *o;
1799         methodinfo        *m;
1800         java_lang_String  *s;
1801
1802         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
1803
1804         if (c == NULL)
1805                 throw_main_exception_exit();
1806         
1807         /* create JarFile object */
1808
1809         o = builtin_new(c);
1810
1811         if (o == NULL)
1812                 throw_main_exception_exit();
1813
1814
1815         m = class_resolveclassmethod(c,
1816                                                                  utf_init, 
1817                                                                  utf_java_lang_String__void,
1818                                                                  class_java_lang_Object,
1819                                                                  true);
1820
1821         if (m == NULL)
1822                 throw_main_exception_exit();
1823
1824         s = javastring_new_from_ascii(mainstring);
1825
1826         (void) vm_call_method(m, o, s);
1827
1828         if (*exceptionptr)
1829                 throw_main_exception_exit();
1830
1831         /* get manifest object */
1832
1833         m = class_resolveclassmethod(c,
1834                                                                  utf_new_char("getManifest"), 
1835                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
1836                                                                  class_java_lang_Object,
1837                                                                  true);
1838
1839         if (m == NULL)
1840                 throw_main_exception_exit();
1841
1842         o = vm_call_method(m, o);
1843
1844         if (o == NULL) {
1845                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
1846                 vm_exit(1);
1847         }
1848
1849
1850         /* get Main Attributes */
1851
1852         m = class_resolveclassmethod(o->vftbl->class,
1853                                                                  utf_new_char("getMainAttributes"), 
1854                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
1855                                                                  class_java_lang_Object,
1856                                                                  true);
1857
1858         if (m == NULL)
1859                 throw_main_exception_exit();
1860
1861         o = vm_call_method(m, o);
1862
1863         if (o == NULL) {
1864                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
1865                 vm_exit(1);
1866         }
1867
1868
1869         /* get property Main-Class */
1870
1871         m = class_resolveclassmethod(o->vftbl->class,
1872                                                                  utf_new_char("getValue"), 
1873                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
1874                                                                  class_java_lang_Object,
1875                                                                  true);
1876
1877         if (m == NULL)
1878                 throw_main_exception_exit();
1879
1880         s = javastring_new_from_ascii("Main-Class");
1881
1882         o = vm_call_method(m, o, s);
1883
1884         if (o == NULL)
1885                 throw_main_exception_exit();
1886
1887         return javastring_tochar(o);
1888 }
1889
1890
1891 /* vm_compile_all **************************************************************
1892
1893    Compile all methods found in the bootclasspath.
1894
1895 *******************************************************************************/
1896
1897 #if !defined(NDEBUG)
1898 static void vm_compile_all(void)
1899 {
1900         classinfo              *c;
1901         methodinfo             *m;
1902         u4                      slot;
1903         classcache_name_entry  *nmen;
1904         classcache_class_entry *clsen;
1905         s4                      i;
1906
1907         /* create all classes found in the bootclasspath */
1908         /* XXX currently only works with zip/jar's */
1909
1910         loader_load_all_classes();
1911
1912         /* link all classes */
1913
1914         for (slot = 0; slot < hashtable_classcache.size; slot++) {
1915                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
1916
1917                 for (; nmen; nmen = nmen->hashlink) {
1918                         /* iterate over all class entries */
1919
1920                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
1921                                 c = clsen->classobj;
1922
1923                                 if (c == NULL)
1924                                         continue;
1925
1926                                 if (!(c->state & CLASS_LINKED)) {
1927                                         if (!link_class(c)) {
1928                                                 fprintf(stderr, "Error linking: ");
1929                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
1930                                                 fprintf(stderr, "\n");
1931
1932                                                 /* print out exception and cause */
1933
1934                                                 exceptions_print_exception(*exceptionptr);
1935
1936                                                 /* goto next class */
1937
1938                                                 continue;
1939                                         }
1940                                 }
1941
1942                                 /* compile all class methods */
1943
1944                                 for (i = 0; i < c->methodscount; i++) {
1945                                         m = &(c->methods[i]);
1946
1947                                         if (m->jcode != NULL) {
1948                                                 if (!jit_compile(m)) {
1949                                                         fprintf(stderr, "Error compiling: ");
1950                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
1951                                                         fprintf(stderr, ".");
1952                                                         utf_fprint_printable_ascii(stderr, m->name);
1953                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
1954                                                         fprintf(stderr, "\n");
1955
1956                                                         /* print out exception and cause */
1957
1958                                                         exceptions_print_exception(*exceptionptr);
1959                                                 }
1960                                         }
1961                                 }
1962                         }
1963                 }
1964         }
1965 }
1966 #endif /* !defined(NDEBUG) */
1967
1968
1969 /* vm_compile_method ***********************************************************
1970
1971    Compile a specific method.
1972
1973 *******************************************************************************/
1974
1975 #if !defined(NDEBUG)
1976 static void vm_compile_method(void)
1977 {
1978         methodinfo *m;
1979
1980         /* create, load and link the main class */
1981
1982         if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
1983                 throw_main_exception_exit();
1984
1985         if (!link_class(mainclass))
1986                 throw_main_exception_exit();
1987
1988         if (opt_signature != NULL) {
1989                 m = class_resolveclassmethod(mainclass,
1990                                                                          utf_new_char(opt_method),
1991                                                                          utf_new_char(opt_signature),
1992                                                                          mainclass,
1993                                                                          false);
1994         }
1995         else {
1996                 m = class_resolveclassmethod(mainclass,
1997                                                                          utf_new_char(opt_method),
1998                                                                          NULL,
1999                                                                          mainclass,
2000                                                                          false);
2001         }
2002
2003         if (m == NULL) {
2004                 char message[MAXLOGTEXT];
2005                 sprintf(message, "%s%s", opt_method,
2006                                 opt_signature ? opt_signature : "");
2007
2008                 *exceptionptr =
2009                         new_exception_message(string_java_lang_NoSuchMethodException,
2010                                                                   message);
2011                                                                                  
2012                 throw_main_exception_exit();
2013         }
2014                 
2015         jit_compile(m);
2016 }
2017 #endif /* !defined(NDEBUG) */
2018
2019
2020 /* vm_vmargs_from_valist *******************************************************
2021
2022    XXX
2023
2024 *******************************************************************************/
2025
2026 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2027                                                                   vm_arg *vmargs, va_list ap)
2028 {
2029         typedesc *paramtypes;
2030         s4        i;
2031
2032         paramtypes = m->parseddesc->paramtypes;
2033
2034         /* if method is non-static fill first block and skip `this' pointer */
2035
2036         i = 0;
2037
2038         if (o != NULL) {
2039                 /* the `this' pointer */
2040                 vmargs[0].type   = TYPE_ADR;
2041                 vmargs[0].data.l = (u8) (ptrint) o;
2042
2043                 paramtypes++;
2044                 i++;
2045         } 
2046
2047         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2048                 switch (paramtypes->decltype) {
2049                 /* primitive types */
2050                 case PRIMITIVETYPE_BOOLEAN: 
2051                 case PRIMITIVETYPE_BYTE:
2052                 case PRIMITIVETYPE_CHAR:
2053                 case PRIMITIVETYPE_SHORT: 
2054                 case PRIMITIVETYPE_INT:
2055                         vmargs[i].type   = TYPE_INT;
2056                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2057                         break;
2058
2059                 case PRIMITIVETYPE_LONG:
2060                         vmargs[i].type   = TYPE_LNG;
2061                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2062                         break;
2063
2064                 case PRIMITIVETYPE_FLOAT:
2065                         vmargs[i].type   = TYPE_FLT;
2066 #if defined(__ALPHA__)
2067                         /* this keeps the assembler function much simpler */
2068
2069                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2070 #else
2071                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2072 #endif
2073                         break;
2074
2075                 case PRIMITIVETYPE_DOUBLE:
2076                         vmargs[i].type   = TYPE_DBL;
2077                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2078                         break;
2079
2080                 case TYPE_ADR: 
2081                         vmargs[i].type   = TYPE_ADR;
2082                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2083                         break;
2084                 }
2085         }
2086 }
2087
2088
2089 /* vm_vmargs_from_jvalue *******************************************************
2090
2091    XXX
2092
2093 *******************************************************************************/
2094
2095 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2096                                                                   vm_arg *vmargs, jvalue *args)
2097 {
2098         typedesc *paramtypes;
2099         s4        i;
2100         s4        j;
2101
2102         paramtypes = m->parseddesc->paramtypes;
2103
2104         /* if method is non-static fill first block and skip `this' pointer */
2105
2106         i = 0;
2107
2108         if (o != NULL) {
2109                 /* the `this' pointer */
2110                 vmargs[0].type   = TYPE_ADR;
2111                 vmargs[0].data.l = (u8) (ptrint) o;
2112
2113                 paramtypes++;
2114                 i++;
2115         } 
2116
2117         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2118                 switch (paramtypes->decltype) {
2119                 /* primitive types */
2120                 case PRIMITIVETYPE_BOOLEAN: 
2121                 case PRIMITIVETYPE_BYTE:
2122                 case PRIMITIVETYPE_CHAR:
2123                 case PRIMITIVETYPE_SHORT: 
2124                 case PRIMITIVETYPE_INT:
2125                         vmargs[i].type   = TYPE_INT;
2126                         vmargs[i].data.l = (s8) args[j].i;
2127                         break;
2128
2129                 case PRIMITIVETYPE_LONG:
2130                         vmargs[i].type   = TYPE_LNG;
2131                         vmargs[i].data.l = (s8) args[j].j;
2132                         break;
2133
2134                 case PRIMITIVETYPE_FLOAT:
2135                         vmargs[i].type = TYPE_FLT;
2136 #if defined(__ALPHA__)
2137                         /* this keeps the assembler function much simpler */
2138
2139                         vmargs[i].data.d = (jdouble) args[j].f;
2140 #else
2141                         vmargs[i].data.f = args[j].f;
2142 #endif
2143                         break;
2144
2145                 case PRIMITIVETYPE_DOUBLE:
2146                         vmargs[i].type   = TYPE_DBL;
2147                         vmargs[i].data.d = args[j].d;
2148                         break;
2149
2150                 case TYPE_ADR: 
2151                         vmargs[i].type   = TYPE_ADR;
2152                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2153                         break;
2154                 }
2155         }
2156 }
2157
2158
2159 /* vm_call_method **************************************************************
2160
2161    Calls a Java method with a variable number of arguments and returns
2162    an address.
2163
2164 *******************************************************************************/
2165
2166 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
2167 {
2168         va_list            ap;
2169         java_objectheader *ro;
2170
2171         va_start(ap, o);
2172         ro = vm_call_method_valist(m, o, ap);
2173         va_end(ap);
2174
2175         return ro;
2176 }
2177
2178
2179 /* vm_call_method_valist *******************************************************
2180
2181    Calls a Java method with a variable number of arguments, passed via
2182    a va_list, and returns an address.
2183
2184 *******************************************************************************/
2185
2186 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
2187                                                                                  va_list ap)
2188 {
2189         s4                 vmargscount;
2190         vm_arg            *vmargs;
2191         java_objectheader *ro;
2192         s4                 dumpsize;
2193
2194         /* mark start of dump memory area */
2195
2196         dumpsize = dump_size();
2197
2198         /* get number of Java method arguments */
2199
2200         vmargscount = m->parseddesc->paramcount;
2201
2202         /* allocate vm_arg array */
2203
2204         vmargs = DMNEW(vm_arg, vmargscount);
2205
2206         /* fill the vm_arg array from a va_list */
2207
2208         vm_vmargs_from_valist(m, o, vmargs, ap);
2209
2210         /* call the Java method */
2211
2212         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2213
2214         /* release dump area */
2215
2216         dump_release(dumpsize);
2217
2218         return ro;
2219 }
2220
2221
2222 /* vm_call_method_jvalue *******************************************************
2223
2224    Calls a Java method with a variable number of arguments, passed via
2225    a jvalue array, and returns an address.
2226
2227 *******************************************************************************/
2228
2229 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
2230                                                                                  jvalue *args)
2231 {
2232         s4                 vmargscount;
2233         vm_arg            *vmargs;
2234         java_objectheader *ro;
2235         s4                 dumpsize;
2236
2237         /* mark start of dump memory area */
2238
2239         dumpsize = dump_size();
2240
2241         /* get number of Java method arguments */
2242
2243         vmargscount = m->parseddesc->paramcount;
2244
2245         /* allocate vm_arg array */
2246
2247         vmargs = DMNEW(vm_arg, vmargscount);
2248
2249         /* fill the vm_arg array from a va_list */
2250
2251         vm_vmargs_from_jvalue(m, o, vmargs, args);
2252
2253         /* call the Java method */
2254
2255         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
2256
2257         /* release dump area */
2258
2259         dump_release(dumpsize);
2260
2261         return ro;
2262 }
2263
2264
2265 /* vm_call_method_vmarg ********************************************************
2266
2267    Calls a Java method with a variable number of arguments, passed via
2268    a vm_arg array, and returns an address.
2269
2270 *******************************************************************************/
2271
2272 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
2273                                                                                 vm_arg *vmargs)
2274 {
2275         java_objectheader *o;
2276
2277 #if defined(ENABLE_JIT)
2278 # if defined(ENABLE_INTRP)
2279         if (opt_intrp)
2280                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2281         else
2282 # endif
2283                 o = asm_vm_call_method(m, vmargscount, vmargs);
2284 #else
2285         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
2286 #endif
2287
2288         return o;
2289 }
2290
2291
2292 /* vm_call_method_int **********************************************************
2293
2294    Calls a Java method with a variable number of arguments and returns
2295    an integer (s4).
2296
2297 *******************************************************************************/
2298
2299 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
2300 {
2301         va_list ap;
2302         s4      i;
2303
2304         va_start(ap, o);
2305         i = vm_call_method_int_valist(m, o, ap);
2306         va_end(ap);
2307
2308         return i;
2309 }
2310
2311
2312 /* vm_call_method_int_valist ***************************************************
2313
2314    Calls a Java method with a variable number of arguments, passed via
2315    a va_list, and returns an integer (s4).
2316
2317 *******************************************************************************/
2318
2319 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
2320 {
2321         s4      vmargscount;
2322         vm_arg *vmargs;
2323         s4      i;
2324         s4      dumpsize;
2325
2326         /* mark start of dump memory area */
2327
2328         dumpsize = dump_size();
2329
2330         /* get number of Java method arguments */
2331
2332         vmargscount = m->parseddesc->paramcount;
2333
2334         /* allocate vm_arg array */
2335
2336         vmargs = DMNEW(vm_arg, vmargscount);
2337
2338         /* fill the vm_arg array from a va_list */
2339
2340         vm_vmargs_from_valist(m, o, vmargs, ap);
2341
2342         /* call the Java method */
2343
2344         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2345
2346         /* release dump area */
2347
2348         dump_release(dumpsize);
2349
2350         return i;
2351 }
2352
2353
2354 /* vm_call_method_int_jvalue ***************************************************
2355
2356    Calls a Java method with a variable number of arguments, passed via
2357    a jvalue array, and returns an integer (s4).
2358
2359 *******************************************************************************/
2360
2361 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2362 {
2363         s4      vmargscount;
2364         vm_arg *vmargs;
2365         s4      i;
2366         s4      dumpsize;
2367
2368         /* mark start of dump memory area */
2369
2370         dumpsize = dump_size();
2371
2372         /* get number of Java method arguments */
2373
2374         vmargscount = m->parseddesc->paramcount;
2375
2376         /* allocate vm_arg array */
2377
2378         vmargs = DMNEW(vm_arg, vmargscount);
2379
2380         /* fill the vm_arg array from a va_list */
2381
2382         vm_vmargs_from_jvalue(m, o, vmargs, args);
2383
2384         /* call the Java method */
2385
2386         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
2387
2388         /* release dump area */
2389
2390         dump_release(dumpsize);
2391
2392         return i;
2393 }
2394
2395
2396 /* vm_call_method_int_vmarg ****************************************************
2397
2398    Calls a Java method with a variable number of arguments, passed via
2399    a vm_arg array, and returns an integer (s4).
2400
2401 *******************************************************************************/
2402
2403 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2404 {
2405         s4 i;
2406
2407 #if defined(ENABLE_JIT)
2408 # if defined(ENABLE_INTRP)
2409         if (opt_intrp)
2410                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2411         else
2412 # endif
2413                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
2414 #else
2415         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
2416 #endif
2417
2418         return i;
2419 }
2420
2421
2422 /* vm_call_method_long *********************************************************
2423
2424    Calls a Java method with a variable number of arguments and returns
2425    a long (s8).
2426
2427 *******************************************************************************/
2428
2429 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
2430 {
2431         va_list ap;
2432         s8      l;
2433
2434         va_start(ap, o);
2435         l = vm_call_method_long_valist(m, o, ap);
2436         va_end(ap);
2437
2438         return l;
2439 }
2440
2441
2442 /* vm_call_method_long_valist **************************************************
2443
2444    Calls a Java method with a variable number of arguments, passed via
2445    a va_list, and returns a long (s8).
2446
2447 *******************************************************************************/
2448
2449 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
2450 {
2451         s4      vmargscount;
2452         vm_arg *vmargs;
2453         s8      l;
2454         s4      dumpsize;
2455
2456         /* mark start of dump memory area */
2457
2458         dumpsize = dump_size();
2459
2460         /* get number of Java method arguments */
2461
2462         vmargscount = m->parseddesc->paramcount;
2463
2464         /* allocate vm_arg array */
2465
2466         vmargs = DMNEW(vm_arg, vmargscount);
2467
2468         /* fill the vm_arg array from a va_list */
2469
2470         vm_vmargs_from_valist(m, o, vmargs, ap);
2471
2472         /* call the Java method */
2473
2474         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2475
2476         /* release dump area */
2477
2478         dump_release(dumpsize);
2479
2480         return l;
2481 }
2482
2483
2484 /* vm_call_method_long_jvalue **************************************************
2485
2486    Calls a Java method with a variable number of arguments, passed via
2487    a jvalue array, and returns a long (s8).
2488
2489 *******************************************************************************/
2490
2491 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
2492 {
2493         s4      vmargscount;
2494         vm_arg *vmargs;
2495         s8      l;
2496         s4      dumpsize;
2497
2498         /* mark start of dump memory area */
2499
2500         dumpsize = dump_size();
2501
2502         /* get number of Java method arguments */
2503
2504         vmargscount = m->parseddesc->paramcount;
2505
2506         /* allocate vm_arg array */
2507
2508         vmargs = DMNEW(vm_arg, vmargscount);
2509
2510         /* fill the vm_arg array from a va_list */
2511
2512         vm_vmargs_from_jvalue(m, o, vmargs, args);
2513
2514         /* call the Java method */
2515
2516         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
2517
2518         /* release dump area */
2519
2520         dump_release(dumpsize);
2521
2522         return l;
2523 }
2524
2525
2526 /* vm_call_method_long_vmarg ***************************************************
2527
2528    Calls a Java method with a variable number of arguments, passed via
2529    a vm_arg array, and returns a long (s8).
2530
2531 *******************************************************************************/
2532
2533 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2534 {
2535         s8 l;
2536
2537 #if defined(ENABLE_JIT)
2538 # if defined(ENABLE_INTRP)
2539         if (opt_intrp)
2540                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2541         else
2542 # endif
2543                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
2544 #else
2545         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
2546 #endif
2547
2548         return l;
2549 }
2550
2551
2552 /* vm_call_method_float ********************************************************
2553
2554    Calls a Java method with a variable number of arguments and returns
2555    an float.
2556
2557 *******************************************************************************/
2558
2559 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
2560 {
2561         va_list ap;
2562         float   f;
2563
2564         va_start(ap, o);
2565         f = vm_call_method_float_valist(m, o, ap);
2566         va_end(ap);
2567
2568         return f;
2569 }
2570
2571
2572 /* vm_call_method_float_valist *************************************************
2573
2574    Calls a Java method with a variable number of arguments, passed via
2575    a va_list, and returns a float.
2576
2577 *******************************************************************************/
2578
2579 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
2580                                                                   va_list ap)
2581 {
2582         s4      vmargscount;
2583         vm_arg *vmargs;
2584         float   f;
2585         s4      dumpsize;
2586
2587         /* mark start of dump memory area */
2588
2589         dumpsize = dump_size();
2590
2591         /* get number of Java method arguments */
2592
2593         vmargscount = m->parseddesc->paramcount;
2594
2595         /* allocate vm_arg array */
2596
2597         vmargs = DMNEW(vm_arg, vmargscount);
2598
2599         /* fill the vm_arg array from a va_list */
2600
2601         vm_vmargs_from_valist(m, o, vmargs, ap);
2602
2603         /* call the Java method */
2604
2605         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2606
2607         /* release dump area */
2608
2609         dump_release(dumpsize);
2610
2611         return f;
2612 }
2613
2614
2615 /* vm_call_method_float_jvalue *************************************************
2616
2617    Calls a Java method with a variable number of arguments, passed via
2618    a jvalue array, and returns a float.
2619
2620 *******************************************************************************/
2621
2622 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
2623                                                                   jvalue *args)
2624 {
2625         s4      vmargscount;
2626         vm_arg *vmargs;
2627         float   f;
2628         s4      dumpsize;
2629
2630         /* mark start of dump memory area */
2631
2632         dumpsize = dump_size();
2633
2634         /* get number of Java method arguments */
2635
2636         vmargscount = m->parseddesc->paramcount;
2637
2638         /* allocate vm_arg array */
2639
2640         vmargs = DMNEW(vm_arg, vmargscount);
2641
2642         /* fill the vm_arg array from a va_list */
2643
2644         vm_vmargs_from_jvalue(m, o, vmargs, args);
2645
2646         /* call the Java method */
2647
2648         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
2649
2650         /* release dump area */
2651
2652         dump_release(dumpsize);
2653
2654         return f;
2655 }
2656
2657
2658 /* vm_call_method_float_vmarg **************************************************
2659
2660    Calls a Java method with a variable number of arguments and returns
2661    an float.
2662
2663 *******************************************************************************/
2664
2665 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
2666 {
2667         float f;
2668
2669 #if defined(ENABLE_JIT)
2670 # if defined(ENABLE_INTRP)
2671         if (opt_intrp)
2672                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2673         else
2674 # endif
2675                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
2676 #else
2677         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
2678 #endif
2679
2680         return f;
2681 }
2682
2683
2684 /* vm_call_method_double *******************************************************
2685
2686    Calls a Java method with a variable number of arguments and returns
2687    a double.
2688
2689 *******************************************************************************/
2690
2691 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
2692 {
2693         va_list ap;
2694         double  d;
2695
2696         va_start(ap, o);
2697         d = vm_call_method_double_valist(m, o, ap);
2698         va_end(ap);
2699
2700         return d;
2701 }
2702
2703
2704 /* vm_call_method_double_valist ************************************************
2705
2706    Calls a Java method with a variable number of arguments, passed via
2707    a va_list, and returns a double.
2708
2709 *******************************************************************************/
2710
2711 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
2712                                                                         va_list ap)
2713 {
2714         s4      vmargscount;
2715         vm_arg *vmargs;
2716         double  d;
2717         s4      dumpsize;
2718
2719         /* mark start of dump memory area */
2720
2721         dumpsize = dump_size();
2722
2723         /* get number of Java method arguments */
2724
2725         vmargscount = m->parseddesc->paramcount;
2726
2727         /* allocate vm_arg array */
2728
2729         vmargs = DMNEW(vm_arg, vmargscount);
2730
2731         /* fill the vm_arg array from a va_list */
2732
2733         vm_vmargs_from_valist(m, o, vmargs, ap);
2734
2735         /* call the Java method */
2736
2737         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2738
2739         /* release dump area */
2740
2741         dump_release(dumpsize);
2742
2743         return d;
2744 }
2745
2746
2747 /* vm_call_method_double_jvalue ************************************************
2748
2749    Calls a Java method with a variable number of arguments, passed via
2750    a jvalue array, and returns a double.
2751
2752 *******************************************************************************/
2753
2754 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
2755                                                                         jvalue *args)
2756 {
2757         s4      vmargscount;
2758         vm_arg *vmargs;
2759         double  d;
2760         s4      dumpsize;
2761
2762         /* mark start of dump memory area */
2763
2764         dumpsize = dump_size();
2765
2766         /* get number of Java method arguments */
2767
2768         vmargscount = m->parseddesc->paramcount;
2769
2770         /* allocate vm_arg array */
2771
2772         vmargs = DMNEW(vm_arg, vmargscount);
2773
2774         /* fill the vm_arg array from a va_list */
2775
2776         vm_vmargs_from_jvalue(m, o, vmargs, args);
2777
2778         /* call the Java method */
2779
2780         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
2781
2782         /* release dump area */
2783
2784         dump_release(dumpsize);
2785
2786         return d;
2787 }
2788
2789
2790 /* vm_call_method_double_vmarg *************************************************
2791
2792    Calls a Java method with a variable number of arguments and returns
2793    a double.
2794
2795 *******************************************************************************/
2796
2797 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
2798                                                                    vm_arg *vmargs)
2799 {
2800         double d;
2801
2802 #if defined(ENABLE_JIT)
2803 # if defined(ENABLE_INTRP)
2804         if (opt_intrp)
2805                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2806         else
2807 # endif
2808                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
2809 #else
2810         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
2811 #endif
2812
2813         return d;
2814 }
2815
2816
2817 /*
2818  * These are local overrides for various environment variables in Emacs.
2819  * Please do not remove this and leave it at the end of the file, where
2820  * Emacs will automagically detect them.
2821  * ---------------------------------------------------------------------
2822  * Local variables:
2823  * mode: c
2824  * indent-tabs-mode: t
2825  * c-basic-offset: 4
2826  * tab-width: 4
2827  * End:
2828  */