* src/vm/vm.c (vm_call_float_array): New function.
[cacao.git] / src / vm / vm.c
1 /* src/vm/vm.c - VM startup and shutdown functions
2
3    Copyright (C) 1996-2005, 2006, 2007 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    $Id: vm.c 8106 2007-06-19 22:50:17Z twisti $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <errno.h>
34 #include <stdint.h>
35 #include <stdlib.h>
36
37 #if defined(WITH_JRE_LAYOUT)
38 # include <libgen.h>
39 # include <unistd.h>
40 #endif
41
42 #include "vm/types.h"
43
44 #include "arch.h"
45 #include "md-abi.h"
46
47 #include "vm/jit/abi-asm.h"
48
49 #include "mm/gc-common.h"
50 #include "mm/memory.h"
51
52 #include "native/jni.h"
53 #include "native/native.h"
54 #include "native/include/java_lang_String.h" /* required by java_lang_Class.h */
55 #include "native/include/java_lang_Class.h"
56
57 #include "native/include/java_lang_Byte.h"
58 #include "native/include/java_lang_Character.h"
59 #include "native/include/java_lang_Short.h"
60 #include "native/include/java_lang_Integer.h"
61 #include "native/include/java_lang_Boolean.h"
62 #include "native/include/java_lang_Long.h"
63 #include "native/include/java_lang_Float.h"
64 #include "native/include/java_lang_Double.h"
65
66 #include "threads/threads-common.h"
67
68 #include "toolbox/logging.h"
69
70 #include "vm/builtin.h"
71 #include "vm/exceptions.h"
72 #include "vm/finalizer.h"
73 #include "vm/global.h"
74 #include "vm/initialize.h"
75 #include "vm/properties.h"
76 #include "vm/signallocal.h"
77 #include "vm/stringlocal.h"
78 #include "vm/vm.h"
79
80 #include "vm/jit/jit.h"
81 #include "vm/jit/md.h"
82 #include "vm/jit/asmpart.h"
83
84 #if defined(ENABLE_PROFILING)
85 # include "vm/jit/optimizing/profile.h"
86 #endif
87
88 #include "vm/jit/optimizing/recompile.h"
89
90 #include "vmcore/classcache.h"
91 #include "vmcore/options.h"
92 #include "vmcore/primitive.h"
93 #include "vmcore/statistics.h"
94 #include "vmcore/suck.h"
95
96 #if defined(ENABLE_JVMTI)
97 # include "native/jvmti/cacaodbg.h"
98 #endif
99
100 #if defined(ENABLE_VMLOG)
101 #include <vmlog_cacao.h>
102 #endif
103
104
105 /* Invocation API variables ***************************************************/
106
107 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
108 _Jv_JNIEnv *_Jv_env;                    /* pointer to native method interface */
109
110
111 /* global variables ***********************************************************/
112
113 s4 vms = 0;                             /* number of VMs created              */
114
115 bool vm_initializing = false;
116 bool vm_exiting = false;
117
118 char      *cacao_prefix = NULL;
119 char      *cacao_libjvm = NULL;
120 char      *classpath_libdir = NULL;
121
122 char      *_Jv_bootclasspath;           /* contains the boot classpath        */
123 char      *_Jv_classpath;               /* contains the classpath             */
124 char      *_Jv_java_library_path;
125
126 char      *mainstring = NULL;
127 classinfo *mainclass = NULL;
128
129 char *specificmethodname = NULL;
130 char *specificsignature = NULL;
131
132 bool startit = true;
133
134 #if defined(ENABLE_INTRP)
135 u1 *intrp_main_stack = NULL;
136 #endif
137
138
139 /* define heap sizes **********************************************************/
140
141 #define HEAP_MAXSIZE      128 * 1024 * 1024 /* default 128MB                  */
142 #define HEAP_STARTSIZE      2 * 1024 * 1024 /* default 2MB                    */
143 #define STACK_SIZE                64 * 1024 /* default 64kB                   */
144
145
146 /* define command line options ************************************************/
147
148 enum {
149         OPT_FOO,
150
151         /* Java options */
152
153         OPT_JAR,
154
155         OPT_D32,
156         OPT_D64,
157
158         OPT_CLASSPATH,
159         OPT_D,
160
161         OPT_VERBOSE,
162
163         OPT_VERSION,
164         OPT_SHOWVERSION,
165         OPT_FULLVERSION,
166
167         OPT_HELP,
168         OPT_X,
169         OPT_XX,
170
171         OPT_EA,
172         OPT_DA,
173
174         OPT_ESA,
175         OPT_DSA,
176
177         /* Java non-standard options */
178
179         OPT_JIT,
180         OPT_INTRP,
181
182         OPT_BOOTCLASSPATH,
183         OPT_BOOTCLASSPATH_A,
184         OPT_BOOTCLASSPATH_P,
185
186         OPT_BOOTCLASSPATH_C,
187
188 #if defined(ENABLE_PROFILING)
189         OPT_PROF,
190         OPT_PROF_OPTION,
191 #endif
192
193         OPT_MS,
194         OPT_MX,
195
196         /* CACAO options */
197
198         OPT_VERBOSE1,
199         OPT_NOIEEE,
200
201 #if defined(ENABLE_STATISTICS)
202         OPT_TIME,
203         OPT_STAT,
204 #endif
205
206         OPT_LOG,
207         OPT_CHECK,
208         OPT_LOAD,
209         OPT_SHOW,
210         OPT_DEBUGCOLOR,
211
212 #if !defined(NDEBUG)
213         OPT_ALL,
214         OPT_METHOD,
215         OPT_SIGNATURE,
216 #endif
217
218 #if defined(ENABLE_VERIFIER)
219         OPT_NOVERIFY,
220 #if defined(TYPECHECK_VERBOSE)
221         OPT_VERBOSETC,
222 #endif
223 #endif /* defined(ENABLE_VERIFIER) */
224         OPT_EAGER,
225
226         /* optimization options */
227
228 #if defined(ENABLE_LOOP)
229         OPT_OLOOP,
230 #endif
231         
232 #if defined(ENABLE_IFCONV)
233         OPT_IFCONV,
234 #endif
235
236 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
237         OPT_LSRA,
238 #endif
239
240 #if defined(ENABLE_INLINING)
241         OPT_INLINING,
242 #if !defined(NDEBUG)
243         OPT_INLINE_LOG,
244 #endif
245 #if defined(ENABLE_INLINING_DEBUG)
246         OPT_INLINE_DEBUG_ALL,
247         OPT_INLINE_DEBUG_END,
248         OPT_INLINE_DEBUG_MIN,
249         OPT_INLINE_DEBUG_MAX,
250         OPT_INLINE_REPLACE_VERBOSE,
251         OPT_INLINE_REPLACE_VERBOSE2,
252 #endif /* defined(ENABLE_INLINING_DEBUG) */
253 #endif /* defined(ENABLE_INLINING) */
254
255 #if defined(ENABLE_INTRP)
256         /* interpreter options */
257
258         OPT_NO_DYNAMIC,
259         OPT_NO_REPLICATION,
260         OPT_NO_QUICKSUPER,
261         OPT_STATIC_SUPERS,
262         OPT_TRACE,
263 #endif
264
265         OPT_SS,
266
267 #ifdef ENABLE_JVMTI
268         OPT_DEBUG,
269         OPT_XRUNJDWP,
270         OPT_NOAGENT,
271         OPT_AGENTLIB,
272         OPT_AGENTPATH,
273 #endif
274
275 #if defined(ENABLE_DEBUG_FILTER)
276         OPT_FILTER_VERBOSECALL_INCLUDE,
277         OPT_FILTER_VERBOSECALL_EXCLUDE,
278         OPT_FILTER_SHOW_METHOD,
279 #endif
280
281         DUMMY
282 };
283
284
285 opt_struct opts[] = {
286         { "foo",               false, OPT_FOO },
287
288         /* Java options */
289
290         { "jar",               false, OPT_JAR },
291
292         { "d32",               false, OPT_D32 },
293         { "d64",               false, OPT_D64 },
294         { "client",            false, OPT_IGNORE },
295         { "server",            false, OPT_IGNORE },
296         { "jvm",               false, OPT_IGNORE },
297         { "hotspot",           false, OPT_IGNORE },
298
299         { "classpath",         true,  OPT_CLASSPATH },
300         { "cp",                true,  OPT_CLASSPATH },
301         { "D",                 true,  OPT_D },
302         { "version",           false, OPT_VERSION },
303         { "showversion",       false, OPT_SHOWVERSION },
304         { "fullversion",       false, OPT_FULLVERSION },
305         { "help",              false, OPT_HELP },
306         { "?",                 false, OPT_HELP },
307         { "X",                 false, OPT_X },
308         { "XX:",               true,  OPT_XX },
309
310         { "ea:",               true,  OPT_EA },
311         { "da:",               true,  OPT_DA },
312         { "ea",                false, OPT_EA },
313         { "da",                false, OPT_DA },
314
315         { "esa",                     false, OPT_ESA },
316         { "enablesystemassertions",  false, OPT_ESA },
317         { "dsa",                     false, OPT_DSA },
318         { "disablesystemassertions", false, OPT_DSA },
319
320         { "noasyncgc",         false, OPT_IGNORE },
321 #if defined(ENABLE_VERIFIER)
322         { "noverify",          false, OPT_NOVERIFY },
323 #endif
324         { "v",                 false, OPT_VERBOSE1 },
325         { "verbose:",          true,  OPT_VERBOSE },
326
327 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
328         { "verbosetc",         false, OPT_VERBOSETC },
329 #endif
330 #if defined(__ALPHA__)
331         { "noieee",            false, OPT_NOIEEE },
332 #endif
333 #if defined(ENABLE_STATISTICS)
334         { "time",              false, OPT_TIME },
335         { "stat",              false, OPT_STAT },
336 #endif
337         { "log",               true,  OPT_LOG },
338         { "c",                 true,  OPT_CHECK },
339         { "l",                 false, OPT_LOAD },
340         { "eager",             false, OPT_EAGER },
341
342 #if !defined(NDEBUG)
343         { "all",               false, OPT_ALL },
344         { "sig",               true,  OPT_SIGNATURE },
345 #endif
346
347 #if defined(ENABLE_LOOP)
348         { "oloop",             false, OPT_OLOOP },
349 #endif
350 #if defined(ENABLE_IFCONV)
351         { "ifconv",            false, OPT_IFCONV },
352 #endif
353 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
354         { "lsra",              false, OPT_LSRA },
355 #endif
356
357 #if defined(ENABLE_INTRP)
358         /* interpreter options */
359
360         { "trace",             false, OPT_TRACE },
361         { "static-supers",     true,  OPT_STATIC_SUPERS },
362         { "no-dynamic",        false, OPT_NO_DYNAMIC },
363         { "no-replication",    false, OPT_NO_REPLICATION },
364         { "no-quicksuper",     false, OPT_NO_QUICKSUPER },
365 #endif
366
367         /* JVMTI Agent Command Line Options */
368 #ifdef ENABLE_JVMTI
369         { "agentlib:",         true,  OPT_AGENTLIB },
370         { "agentpath:",        true,  OPT_AGENTPATH },
371 #endif
372
373         /* Java non-standard options */
374
375         { "Xjit",              false, OPT_JIT },
376         { "Xint",              false, OPT_INTRP },
377         { "Xbootclasspath:",   true,  OPT_BOOTCLASSPATH },
378         { "Xbootclasspath/a:", true,  OPT_BOOTCLASSPATH_A },
379         { "Xbootclasspath/p:", true,  OPT_BOOTCLASSPATH_P },
380         { "Xbootclasspath/c:", true,  OPT_BOOTCLASSPATH_C },
381
382 #ifdef ENABLE_JVMTI
383         { "Xdebug",            false, OPT_DEBUG },
384         { "Xnoagent",          false, OPT_NOAGENT },
385         { "Xrunjdwp",          true,  OPT_XRUNJDWP },
386 #endif 
387
388         { "Xms",               true,  OPT_MS },
389         { "ms",                true,  OPT_MS },
390         { "Xmx",               true,  OPT_MX },
391         { "mx",                true,  OPT_MX },
392         { "Xss",               true,  OPT_SS },
393         { "ss",                true,  OPT_SS },
394
395 #if defined(ENABLE_PROFILING)
396         { "Xprof:",            true,  OPT_PROF_OPTION },
397         { "Xprof",             false, OPT_PROF },
398 #endif
399
400         /* inlining options */
401
402 #if defined(ENABLE_INLINING)
403 #if defined(ENABLE_INLINING_DEBUG)
404         { "ia",                false, OPT_INLINE_DEBUG_ALL },
405         { "ii",                true,  OPT_INLINE_DEBUG_MIN },
406         { "im",                true,  OPT_INLINE_DEBUG_MAX },
407         { "ie",                true,  OPT_INLINE_DEBUG_END },
408         { "ir",                false, OPT_INLINE_REPLACE_VERBOSE },
409         { "iR",                false, OPT_INLINE_REPLACE_VERBOSE2 },
410 #endif /* defined(ENABLE_INLINING_DEBUG) */
411 #if !defined(NDEBUG)
412         { "il",                false, OPT_INLINE_LOG },
413 #endif
414         { "i",                 false, OPT_INLINING },
415 #endif /* defined(ENABLE_INLINING) */
416
417         /* keep these at the end of the list */
418
419 #if !defined(NDEBUG)
420         { "m",                 true,  OPT_METHOD },
421 #endif
422
423         { "s",                 true,  OPT_SHOW },
424         { "debug-color",      false,  OPT_DEBUGCOLOR },
425
426 #if defined(ENABLE_DEBUG_FILTER)
427         { "XXfi",              true,  OPT_FILTER_VERBOSECALL_INCLUDE },
428         { "XXfx",              true,  OPT_FILTER_VERBOSECALL_EXCLUDE },
429         { "XXfm",              true,  OPT_FILTER_SHOW_METHOD },
430 #endif
431
432         { NULL,                false, 0 }
433 };
434
435
436 /* usage ***********************************************************************
437
438    Prints the correct usage syntax to stdout.
439
440 *******************************************************************************/
441
442 void usage(void)
443 {
444         puts("Usage: cacao [-options] classname [arguments]");
445         puts("               (to run a class file)");
446         puts("   or  cacao [-options] -jar jarfile [arguments]");
447         puts("               (to run a standalone jar file)\n");
448
449         puts("where options include:");
450         puts("    -d32                     use 32-bit data model if available");
451         puts("    -d64                     use 64-bit data model if available");
452         puts("    -client                  compatibility (currently ignored)");
453         puts("    -server                  compatibility (currently ignored)");
454         puts("    -jvm                     compatibility (currently ignored)");
455         puts("    -hotspot                 compatibility (currently ignored)\n");
456
457         puts("    -cp <path>               specify a path to look for classes");
458         puts("    -classpath <path>        specify a path to look for classes");
459         puts("    -D<name>=<value>         add an entry to the property list");
460         puts("    -verbose[:class|gc|jni]  enable specific verbose output");
461         puts("    -version                 print product version and exit");
462         puts("    -fullversion             print jpackage-compatible product version and exit");
463         puts("    -showversion             print product version and continue");
464         puts("    -help, -?                print this help message");
465         puts("    -X                       print help on non-standard Java options");
466         puts("    -XX                      print help on CACAO options");
467     puts("    -ea[:<packagename>...|:<classname>]");
468     puts("    -enableassertions[:<packagename>...|:<classname>]");
469         puts("                             enable assertions with specified granularity");
470         puts("    -da[:<packagename>...|:<classname>]");
471         puts("    -disableassertions[:<packagename>...|:<classname>]");
472         puts("                             disable assertions with specified granularity");
473         puts("    -esa | -enablesystemassertions");
474         puts("                             enable system assertions");
475         puts("    -dsa | -disablesystemassertions");
476         puts("                             disable system assertions");
477
478 #ifdef ENABLE_JVMTI
479         puts("    -agentlib:<agent-lib-name>=<options>  library to load containg JVMTI agent");
480         puts ("                                         for jdwp help use: -agentlib:jdwp=help");
481         puts("    -agentpath:<path-to-agent>=<options>  path to library containg JVMTI agent");
482 #endif
483
484         /* exit with error code */
485
486         exit(1);
487 }   
488
489
490 static void Xusage(void)
491 {
492 #if defined(ENABLE_JIT)
493         puts("    -Xjit                    JIT mode execution (default)");
494 #endif
495 #if defined(ENABLE_INTRP)
496         puts("    -Xint                    interpreter mode execution");
497 #endif
498         puts("    -Xbootclasspath:<zip/jar files and directories separated by :>");
499     puts("                             value is set as bootstrap class path");
500         puts("    -Xbootclasspath/a:<zip/jar files and directories separated by :>");
501         puts("                             value is appended to the bootstrap class path");
502         puts("    -Xbootclasspath/p:<zip/jar files and directories separated by :>");
503         puts("                             value is prepended to the bootstrap class path");
504         puts("    -Xbootclasspath/c:<zip/jar files and directories separated by :>");
505         puts("                             value is used as Java core library, but the");
506         puts("                             hardcoded VM interface classes are prepended");
507         printf("    -Xms<size>               set the initial size of the heap (default: %dMB)\n", HEAP_STARTSIZE / 1024 / 1024);
508         printf("    -Xmx<size>               set the maximum size of the heap (default: %dMB)\n", HEAP_MAXSIZE / 1024 / 1024);
509         printf("    -Xss<size>               set the thread stack size (default: %dkB)\n", STACK_SIZE / 1024);
510
511 #if defined(ENABLE_PROFILING)
512         puts("    -Xprof[:bb]              collect and print profiling data");
513 #endif
514
515 #if defined(ENABLE_JVMTI)
516     /* -Xdebug option depend on gnu classpath JDWP options. options: 
517          transport=dt_socket,address=<hostname:port>,server=(y|n),suspend(y|n) */
518         puts("    -Xdebug                  enable remote debugging\n");
519         puts("    -Xrunjdwp transport=[dt_socket|...],address=<hostname:port>,server=[y|n],suspend=[y|n]\n");
520         puts("                             enable remote debugging\n");
521 #endif 
522
523         /* exit with error code */
524
525         exit(1);
526 }   
527
528
529 static void XXusage(void)
530 {
531         puts("    -v                       write state-information");
532 #if !defined(NDEBUG)
533         puts("    -verbose[:call|exception|jit|memory|threads]");
534         puts("                             enable specific verbose output");
535         puts("    -debug-color             colored output for ANSI terms");
536 #endif
537 #ifdef TYPECHECK_VERBOSE
538         puts("    -verbosetc               write debug messages while typechecking");
539 #endif
540 #if defined(__ALPHA__)
541         puts("    -noieee                  don't use ieee compliant arithmetic");
542 #endif
543 #if defined(ENABLE_VERIFIER)
544         puts("    -noverify                don't verify classfiles");
545 #endif
546 #if defined(ENABLE_STATISTICS)
547         puts("    -time                    measure the runtime");
548         puts("    -stat                    detailed compiler statistics");
549 #endif
550         puts("    -log logfile             specify a name for the logfile");
551         puts("    -c(heck)b(ounds)         don't check array bounds");
552         puts("            s(ync)           don't check for synchronization");
553 #if defined(ENABLE_LOOP)
554         puts("    -oloop                   optimize array accesses in loops");
555 #endif
556         puts("    -l                       don't start the class after loading");
557         puts("    -eager                   perform eager class loading and linking");
558 #if !defined(NDEBUG)
559         puts("    -all                     compile all methods, no execution");
560         puts("    -m                       compile only a specific method");
561         puts("    -sig                     specify signature for a specific method");
562 #endif
563
564         puts("    -s...                    show...");
565         puts("      (c)onstants            the constant pool");
566         puts("      (m)ethods              class fields and methods");
567         puts("      (u)tf                  the utf - hash");
568         puts("      (i)ntermediate         intermediate representation");
569 #if defined(ENABLE_DISASSEMBLER)
570         puts("      (a)ssembler            disassembled listing");
571         puts("      n(o)ps                 show NOPs in disassembler output");
572         puts("      (e)xceptionstubs       disassembled exception stubs (only with -sa)");
573         puts("      (n)ative               disassembled native stubs");
574 #endif
575         puts("      (d)atasegment          data segment listing");
576
577 #if defined(ENABLE_INLINING)
578         puts("    -i                       activate inlining");
579 #if !defined(NDEBUG)
580         puts("    -il                      log inlining");
581 #endif
582 #if defined(ENABLE_INLINING_DEBUG)
583         puts("    -ia                      use inlining for all methods");
584         puts("    -ii <size>               set minimum size for inlined result");
585         puts("    -im <size>               set maximum size for inlined result");
586         puts("    -ie <number>             stop inlining after the given number of roots");
587         puts("    -ir                      log on-stack replacement");
588         puts("    -iR                      log on-stack replacement, more verbose");
589 #endif /* defined(ENABLE_INLINING_DEBUG) */
590 #endif /* defined(ENABLE_INLINING) */
591
592 #if defined(ENABLE_IFCONV)
593         puts("    -ifconv                  use if-conversion");
594 #endif
595 #if defined(ENABLE_LSRA)
596         puts("    -lsra                    use linear scan register allocation");
597 #endif
598 #if defined(ENABLE_SSA)
599         puts("    -lsra                    use linear scan register allocation (with SSA)");
600 #endif
601 #if defined(ENABLE_DEBUG_FILTER)
602         puts("    -XXfi <regex>            begin of dynamic scope for verbosecall filter");
603         puts("    -XXfx <regex>            end of dynamic scope for verbosecall filter");
604         puts("    -XXfm <regex>            filter for show options");
605 #endif
606         /* exit with error code */
607
608         exit(1);
609 }
610
611
612 /* version *********************************************************************
613
614    Only prints cacao version information.
615
616 *******************************************************************************/
617
618 static void version(bool opt_exit)
619 {
620         puts("java version \""JAVA_VERSION"\"");
621         puts("CACAO version "VERSION"");
622
623         puts("Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,");
624         puts("C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,");
625         puts("E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,");
626         puts("J. Wenninger, Institut f. Computersprachen - TU Wien\n");
627
628         puts("This program is free software; you can redistribute it and/or");
629         puts("modify it under the terms of the GNU General Public License as");
630         puts("published by the Free Software Foundation; either version 2, or (at");
631         puts("your option) any later version.\n");
632
633         puts("This program is distributed in the hope that it will be useful, but");
634         puts("WITHOUT ANY WARRANTY; without even the implied warranty of");
635         puts("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU");
636         puts("General Public License for more details.\n");
637
638         puts("Configure/Build options:\n");
639         puts("  ./configure: "VERSION_CONFIGURE_ARGS"");
640 #if defined(__VERSION__)
641         puts("  CC         : "VERSION_CC" ("__VERSION__")");
642 #else
643         puts("  CC         : "VERSION_CC"");
644 #endif
645         puts("  CFLAGS     : "VERSION_CFLAGS"\n");
646
647         puts("Default variables:\n");
648         printf("  maximum heap size              : %d\n", HEAP_MAXSIZE);
649         printf("  initial heap size              : %d\n", HEAP_STARTSIZE);
650         printf("  stack size                     : %d\n", STACK_SIZE);
651 #if defined(WITH_CLASSPATH_GNU)
652         puts("  java.boot.class.path           : "CACAO_VM_ZIP":"CLASSPATH_CLASSES"");
653 #else
654         puts("  java.boot.class.path           : "CLASSPATH_CLASSES"");
655 #endif
656         puts("  gnu.classpath.boot.library.path: "CLASSPATH_LIBDIR"/classpath\n");
657
658         puts("Runtime variables:\n");
659         printf("  maximum heap size              : %d\n", opt_heapmaxsize);
660         printf("  initial heap size              : %d\n", opt_heapstartsize);
661         printf("  stack size                     : %d\n", opt_stacksize);
662         printf("  libjvm.so                      : %s\n", cacao_libjvm);
663         printf("  java.boot.class.path           : %s\n", _Jv_bootclasspath);
664         printf("  gnu.classpath.boot.library.path: %s\n", classpath_libdir);
665         printf("  java.class.path                : %s\n", _Jv_classpath);
666
667         /* exit normally, if requested */
668
669         if (opt_exit)
670                 exit(0);
671 }
672
673
674 /* fullversion *****************************************************************
675
676    Prints a Sun compatible version information (required e.g. by
677    jpackage, www.jpackage.org).
678
679 *******************************************************************************/
680
681 static void fullversion(void)
682 {
683         puts("java full version \"cacao-"JAVA_VERSION"\"");
684
685         /* exit normally */
686
687         exit(0);
688 }
689
690
691 /* forward declarations *******************************************************/
692
693 static char *vm_get_mainclass_from_jar(char *mainstring);
694 #if !defined(NDEBUG)
695 static void  vm_compile_all(void);
696 static void  vm_compile_method(void);
697 #endif
698
699
700 /* vm_createjvm ****************************************************************
701
702    Implementation for JNI_CreateJavaVM.
703
704 *******************************************************************************/
705
706 bool vm_createjvm(JavaVM **p_vm, void **p_env, void *vm_args)
707 {
708         JavaVMInitArgs *_vm_args;
709         _Jv_JNIEnv     *env;
710         _Jv_JavaVM     *vm;
711
712         /* get the arguments for the new JVM */
713
714         _vm_args = (JavaVMInitArgs *) vm_args;
715
716         /* get the VM and Env tables (must be set before vm_create) */
717
718         env = NEW(_Jv_JNIEnv);
719
720 #if defined(ENABLE_JNI)
721         env->env = &_Jv_JNINativeInterface;
722 #endif
723
724         /* XXX Set the global variable.  Maybe we should do that differently. */
725
726         _Jv_env = env;
727
728         /* create and fill a JavaVM structure */
729
730         vm = NEW(_Jv_JavaVM);
731
732 #if defined(ENABLE_JNI)
733         vm->functions = &_Jv_JNIInvokeInterface;
734 #endif
735
736         /* XXX Set the global variable.  Maybe we should do that differently. */
737         /* XXX JVMTI Agents needs a JavaVM  */
738
739         _Jv_jvm = vm;
740
741         /* actually create the JVM */
742
743         if (!vm_create(_vm_args))
744                 goto error;
745
746 #if defined(ENABLE_JNI)
747         /* setup the local ref table (must be created after vm_create) */
748
749         if (!jni_init_localref_table())
750                 goto error;
751 #endif
752
753         /* now return the values */
754
755         *p_vm  = (JavaVM *) vm;
756         *p_env = (void *) env;
757
758         return true;
759
760  error:
761         /* release allocated memory */
762
763         FREE(env, _Jv_JNIEnv);
764         FREE(vm, _Jv_JavaVM);
765
766         return false;
767 }
768
769
770 /* vm_create *******************************************************************
771
772    Creates a JVM.  Called by vm_createjvm.
773
774 *******************************************************************************/
775
776 bool vm_create(JavaVMInitArgs *vm_args)
777 {
778         char *cp;
779         s4    len;
780         s4    opt;
781         s4    i, j;
782         bool  opt_version;
783         bool  opt_exit;
784
785 #if defined(ENABLE_JVMTI)
786         lt_dlhandle  handle;
787         char *libname, *agentarg;
788         bool jdwp,agentbypath;
789         jdwp = agentbypath = false;
790 #endif
791
792 #if defined(ENABLE_VMLOG)
793         vmlog_cacao_init(vm_args);
794 #endif
795
796         /* check the JNI version requested */
797
798         switch (vm_args->version) {
799         case JNI_VERSION_1_1:
800                 break;
801         case JNI_VERSION_1_2:
802         case JNI_VERSION_1_4:
803                 break;
804         default:
805                 return false;
806         }
807
808         /* we only support 1 JVM instance */
809
810         if (vms > 0)
811                 return false;
812
813         if (atexit(vm_exit_handler))
814                 vm_abort("atexit failed: %s\n", strerror(errno));
815
816         if (opt_verbose)
817                 log_text("CACAO started -------------------------------------------------------");
818
819         /* We need to check if the actual size of a java.lang.Class object
820            is smaller or equal than the assumption made in
821            src/vmcore/class.h. */
822
823         if (sizeof(java_lang_Class) > sizeof(dummy_java_lang_Class))
824                 vm_abort("vm_create: java_lang_Class structure is bigger than classinfo.object (%d > %d)", sizeof(java_lang_Class), sizeof(dummy_java_lang_Class));
825
826         /* set the VM starttime */
827
828         _Jv_jvm->starttime = builtin_currenttimemillis();
829
830         /* get stuff from the environment *****************************************/
831
832 #if defined(WITH_JRE_LAYOUT)
833         /* SUN also uses a buffer of 4096-bytes (strace is your friend). */
834
835         cacao_prefix = MNEW(char, 4096);
836
837         if (readlink("/proc/self/exe", cacao_prefix, 4095) == -1)
838                 vm_abort("readlink failed: %s\n", strerror(errno));
839
840         /* get the path of the current executable */
841
842         cacao_prefix = dirname(cacao_prefix);
843
844         if ((strlen(cacao_prefix) + strlen("/..") + strlen("0")) > 4096)
845                 vm_abort("libjvm name to long for buffer\n");
846
847         /* concatenate the library name */
848
849         strcat(cacao_prefix, "/..");
850
851         /* now set path to libjvm.so */
852
853         len = strlen(cacao_prefix) + strlen("/lib/libjvm") + strlen("0");
854
855         cacao_libjvm = MNEW(char, len);
856         strcpy(cacao_libjvm, cacao_prefix);
857         strcat(cacao_libjvm, "/lib/libjvm");
858
859         /* and finally set the path to GNU Classpath libraries */
860
861         len = strlen(cacao_prefix) + strlen("/lib/classpath") + strlen("0");
862
863         classpath_libdir = MNEW(char, len);
864         strcpy(classpath_libdir, cacao_prefix);
865         strcat(classpath_libdir, "/lib/classpath");
866 #else
867         cacao_prefix     = CACAO_PREFIX;
868         cacao_libjvm     = CACAO_LIBDIR"/libjvm";
869         classpath_libdir = CLASSPATH_LIBDIR"/classpath";
870 #endif
871
872         /* set the bootclasspath */
873
874         cp = getenv("BOOTCLASSPATH");
875
876         if (cp != NULL) {
877                 _Jv_bootclasspath = MNEW(char, strlen(cp) + strlen("0"));
878                 strcpy(_Jv_bootclasspath, cp);
879         }
880         else {
881 #if defined(WITH_JRE_LAYOUT)
882                 len =
883 # if defined(WITH_CLASSPATH_GNU)
884                         strlen(cacao_prefix) +
885                         strlen("/share/cacao/vm.zip") +
886                         strlen(":") +
887 # endif
888                         strlen(cacao_prefix) +
889                         strlen("/share/classpath/glibj.zip") +
890                         strlen("0");
891
892                 _Jv_bootclasspath = MNEW(char, len);
893 # if defined(WITH_CLASSPATH_GNU)
894                 strcat(_Jv_bootclasspath, cacao_prefix);
895                 strcat(_Jv_bootclasspath, "/share/cacao/vm.zip");
896                 strcat(_Jv_bootclasspath, ":");
897 # endif
898                 strcat(_Jv_bootclasspath, cacao_prefix);
899                 strcat(_Jv_bootclasspath, "/share/classpath/glibj.zip");
900 #else
901                 len =
902 # if defined(WITH_CLASSPATH_GNU)
903                         strlen(CACAO_VM_ZIP) +
904                         strlen(":") +
905 # endif
906                         strlen(CLASSPATH_CLASSES) +
907                         strlen("0");
908
909                 _Jv_bootclasspath = MNEW(char, len);
910 # if defined(WITH_CLASSPATH_GNU)
911                 strcat(_Jv_bootclasspath, CACAO_VM_ZIP);
912                 strcat(_Jv_bootclasspath, ":");
913 # endif
914                 strcat(_Jv_bootclasspath, CLASSPATH_CLASSES);
915 #endif
916         }
917
918         /* set the classpath */
919
920         cp = getenv("CLASSPATH");
921
922         if (cp != NULL) {
923                 _Jv_classpath = MNEW(char, strlen(cp) + strlen("0"));
924                 strcat(_Jv_classpath, cp);
925         }
926         else {
927                 _Jv_classpath = MNEW(char, strlen(".") + strlen("0"));
928                 strcpy(_Jv_classpath, ".");
929         }
930
931         /* get and set java.library.path */
932
933         _Jv_java_library_path = getenv("LD_LIBRARY_PATH");
934
935         if (_Jv_java_library_path == NULL)
936                 _Jv_java_library_path = "";
937
938         /* interpret the options **************************************************/
939
940         opt_version       = false;
941         opt_exit          = false;
942
943         opt_noieee        = false;
944
945         opt_heapmaxsize   = HEAP_MAXSIZE;
946         opt_heapstartsize = HEAP_STARTSIZE;
947         opt_stacksize     = STACK_SIZE;
948
949
950 #if defined(ENABLE_JVMTI)
951         /* initialize JVMTI related  **********************************************/
952         jvmti = false;
953 #endif
954
955         /* initialize and fill properties before command-line handling */
956
957         if (!properties_init())
958                 vm_abort("properties_init failed");
959
960         /* iterate over all passed options */
961
962         while ((opt = options_get(opts, vm_args)) != OPT_DONE) {
963                 switch (opt) {
964                 case OPT_FOO:
965                         opt_foo = true;
966                         break;
967
968                 case OPT_IGNORE:
969                         break;
970                         
971                 case OPT_JAR:
972                         opt_jar = true;
973                         break;
974
975                 case OPT_D32:
976 #if SIZEOF_VOID_P == 8
977                         puts("Running a 32-bit JVM is not supported on this platform.");
978                         exit(1);
979 #endif
980                         break;
981
982                 case OPT_D64:
983 #if SIZEOF_VOID_P == 4
984                         puts("Running a 64-bit JVM is not supported on this platform.");
985                         exit(1);
986 #endif
987                         break;
988
989                 case OPT_CLASSPATH:
990                         /* forget old classpath and set the argument as new classpath */
991                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
992
993                         _Jv_classpath = MNEW(char, strlen(opt_arg) + strlen("0"));
994                         strcpy(_Jv_classpath, opt_arg);
995                         break;
996
997                 case OPT_D:
998                         for (i = 0; i < strlen(opt_arg); i++) {
999                                 if (opt_arg[i] == '=') {
1000                                         opt_arg[i] = '\0';
1001                                         properties_add(opt_arg, opt_arg + i + 1);
1002                                         goto opt_d_done;
1003                                 }
1004                         }
1005
1006                         /* if no '=' is given, just create an empty property */
1007
1008                         properties_add(opt_arg, "");
1009
1010                 opt_d_done:
1011                         break;
1012
1013                 case OPT_BOOTCLASSPATH:
1014                         /* Forget default bootclasspath and set the argument as
1015                            new boot classpath. */
1016
1017                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1018
1019                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
1020                         strcpy(_Jv_bootclasspath, opt_arg);
1021                         break;
1022
1023                 case OPT_BOOTCLASSPATH_A:
1024                         /* append to end of bootclasspath */
1025
1026                         len = strlen(_Jv_bootclasspath);
1027
1028                         _Jv_bootclasspath = MREALLOC(_Jv_bootclasspath,
1029                                                                                  char,
1030                                                                                  len + strlen("0"),
1031                                                                                  len + strlen(":") +
1032                                                                                  strlen(opt_arg) + strlen("0"));
1033
1034                         strcat(_Jv_bootclasspath, ":");
1035                         strcat(_Jv_bootclasspath, opt_arg);
1036                         break;
1037
1038                 case OPT_BOOTCLASSPATH_P:
1039                         /* prepend in front of bootclasspath */
1040
1041                         cp = _Jv_bootclasspath;
1042                         len = strlen(cp);
1043
1044                         _Jv_bootclasspath = MNEW(char, strlen(opt_arg) + strlen(":") +
1045                                                                          len + strlen("0"));
1046
1047                         strcpy(_Jv_bootclasspath, opt_arg);
1048                         strcat(_Jv_bootclasspath, ":");
1049                         strcat(_Jv_bootclasspath, cp);
1050
1051                         MFREE(cp, char, len);
1052                         break;
1053
1054                 case OPT_BOOTCLASSPATH_C:
1055                         /* use as Java core library, but prepend VM interface classes */
1056
1057                         MFREE(_Jv_bootclasspath, char, strlen(_Jv_bootclasspath));
1058
1059                         len = strlen(CACAO_VM_ZIP) +
1060                                 strlen(":") +
1061                                 strlen(opt_arg) +
1062                                 strlen("0");
1063
1064                         _Jv_bootclasspath = MNEW(char, len);
1065
1066                         strcpy(_Jv_bootclasspath, CACAO_VM_ZIP);
1067                         strcat(_Jv_bootclasspath, ":");
1068                         strcat(_Jv_bootclasspath, opt_arg);
1069                         break;
1070
1071 #if defined(ENABLE_JVMTI)
1072                 case OPT_DEBUG:
1073                         /* this option exists only for compatibility reasons */
1074                         break;
1075
1076                 case OPT_NOAGENT:
1077                         /* I don't know yet what Xnoagent should do. This is only for 
1078                            compatiblity with eclipse - motse */
1079                         break;
1080
1081                 case OPT_XRUNJDWP:
1082                         agentbypath = true;
1083                         jvmti       = true;
1084                         jdwp        = true;
1085
1086                         len =
1087                                 strlen(CACAO_LIBDIR) +
1088                                 strlen("/libjdwp.so=") +
1089                                 strlen(opt_arg) +
1090                                 strlen("0");
1091
1092                         agentarg = MNEW(char, len);
1093
1094                         strcpy(agentarg, CACAO_LIBDIR);
1095                         strcat(agentarg, "/libjdwp.so=");
1096                         strcat(agentarg, &opt_arg[1]);
1097                         break;
1098
1099                 case OPT_AGENTPATH:
1100                         agentbypath = true;
1101
1102                 case OPT_AGENTLIB:
1103                         jvmti = true;
1104                         agentarg = opt_arg;
1105                         break;
1106 #endif
1107                         
1108                 case OPT_MX:
1109                 case OPT_MS:
1110                 case OPT_SS:
1111                         {
1112                                 char c;
1113                                 c = opt_arg[strlen(opt_arg) - 1];
1114
1115                                 if ((c == 'k') || (c == 'K')) {
1116                                         j = atoi(opt_arg) * 1024;
1117
1118                                 } else if ((c == 'm') || (c == 'M')) {
1119                                         j = atoi(opt_arg) * 1024 * 1024;
1120
1121                                 } else
1122                                         j = atoi(opt_arg);
1123
1124                                 if (opt == OPT_MX)
1125                                         opt_heapmaxsize = j;
1126                                 else if (opt == OPT_MS)
1127                                         opt_heapstartsize = j;
1128                                 else
1129                                         opt_stacksize = j;
1130                         }
1131                         break;
1132
1133                 case OPT_VERBOSE1:
1134                         opt_verbose = true;
1135                         break;
1136
1137                 case OPT_VERBOSE:
1138                         if (strcmp("class", opt_arg) == 0) {
1139                                 opt_verboseclass = true;
1140                         }
1141                         else if (strcmp("gc", opt_arg) == 0) {
1142                                 opt_verbosegc = true;
1143                         }
1144                         else if (strcmp("jni", opt_arg) == 0) {
1145                                 opt_verbosejni = true;
1146                         }
1147 #if !defined(NDEBUG)
1148                         else if (strcmp("call", opt_arg) == 0) {
1149                                 opt_verbosecall = true;
1150                         }
1151                         else if (strcmp("exception", opt_arg) == 0) {
1152                                 opt_verboseexception = true;
1153                         }
1154                         else if (strcmp("jit", opt_arg) == 0) {
1155                                 opt_verbose = true;
1156                                 loadverbose = true;
1157                                 linkverbose = true;
1158                                 initverbose = true;
1159                                 compileverbose = true;
1160                         }
1161                         else if (strcmp("memory", opt_arg) == 0) {
1162                                 opt_verbosememory = true;
1163
1164 # if defined(ENABLE_STATISTICS)
1165                                 /* we also need statistics */
1166
1167                                 opt_stat = true;
1168 # endif
1169                         }
1170                         else if (strcmp("threads", opt_arg) == 0) {
1171                                 opt_verbosethreads = true;
1172                         }
1173 #endif
1174                         else {
1175                                 printf("Unknown -verbose option: %s\n", opt_arg);
1176                                 usage();
1177                         }
1178                         break;
1179
1180                 case OPT_DEBUGCOLOR:
1181                         opt_debugcolor = true;
1182                         break;
1183
1184 #if defined(ENABLE_VERIFIER) && defined(TYPECHECK_VERBOSE)
1185                 case OPT_VERBOSETC:
1186                         opt_typecheckverbose = true;
1187                         break;
1188 #endif
1189                                 
1190                 case OPT_VERSION:
1191                         opt_version = true;
1192                         opt_exit    = true;
1193                         break;
1194
1195                 case OPT_FULLVERSION:
1196                         fullversion();
1197                         break;
1198
1199                 case OPT_SHOWVERSION:
1200                         opt_version = true;
1201                         break;
1202
1203                 case OPT_NOIEEE:
1204                         opt_noieee = true;
1205                         break;
1206
1207 #if defined(ENABLE_VERIFIER)
1208                 case OPT_NOVERIFY:
1209                         opt_verify = false;
1210                         break;
1211 #endif
1212
1213 #if defined(ENABLE_STATISTICS)
1214                 case OPT_TIME:
1215                         opt_getcompilingtime = true;
1216                         opt_getloadingtime = true;
1217                         break;
1218                                         
1219                 case OPT_STAT:
1220                         opt_stat = true;
1221                         break;
1222 #endif
1223                                         
1224                 case OPT_LOG:
1225                         log_init(opt_arg);
1226                         break;
1227                         
1228                 case OPT_CHECK:
1229                         for (i = 0; i < strlen(opt_arg); i++) {
1230                                 switch (opt_arg[i]) {
1231                                 case 'b':
1232                                         checkbounds = false;
1233                                         break;
1234                                 case 's':
1235                                         checksync = false;
1236                                         break;
1237                                 default:
1238                                         usage();
1239                                 }
1240                         }
1241                         break;
1242                         
1243                 case OPT_LOAD:
1244                         opt_run = false;
1245                         makeinitializations = false;
1246                         break;
1247
1248                 case OPT_EAGER:
1249                         opt_eager = true;
1250                         break;
1251
1252 #if !defined(NDEBUG)
1253                 case OPT_ALL:
1254                         compileall = true;
1255                         opt_run = false;
1256                         makeinitializations = false;
1257                         break;
1258
1259                 case OPT_METHOD:
1260                         opt_run = false;
1261                         opt_method = opt_arg;
1262                         makeinitializations = false;
1263                         break;
1264
1265                 case OPT_SIGNATURE:
1266                         opt_signature = opt_arg;
1267                         break;
1268 #endif
1269
1270                 case OPT_SHOW:       /* Display options */
1271                         for (i = 0; i < strlen(opt_arg); i++) {         
1272                                 switch (opt_arg[i]) {
1273                                 case 'c':
1274                                         showconstantpool = true;
1275                                         break;
1276
1277                                 case 'u':
1278                                         showutf = true;
1279                                         break;
1280
1281                                 case 'm':
1282                                         showmethods = true;
1283                                         break;
1284
1285                                 case 'i':
1286                                         opt_showintermediate = true;
1287                                         compileverbose = true;
1288                                         break;
1289
1290 #if defined(ENABLE_DISASSEMBLER)
1291                                 case 'a':
1292                                         opt_showdisassemble = true;
1293                                         compileverbose = true;
1294                                         break;
1295
1296                                 case 'o':
1297                                         opt_shownops = true;
1298                                         break;
1299
1300                                 case 'e':
1301                                         opt_showexceptionstubs = true;
1302                                         break;
1303
1304                                 case 'n':
1305                                         opt_shownativestub = true;
1306                                         break;
1307 #endif
1308
1309                                 case 'd':
1310                                         opt_showddatasegment = true;
1311                                         break;
1312
1313                                 default:
1314                                         usage();
1315                                 }
1316                         }
1317                         break;
1318                         
1319 #if defined(ENABLE_LOOP)
1320                 case OPT_OLOOP:
1321                         opt_loops = true;
1322                         break;
1323 #endif
1324
1325 #if defined(ENABLE_INLINING)
1326 #if defined(ENABLE_INLINING_DEBUG)
1327                 case OPT_INLINE_DEBUG_ALL:
1328                         opt_inline_debug_all = true;
1329                         break;
1330                 case OPT_INLINE_DEBUG_END:
1331                         opt_inline_debug_end_counter = atoi(opt_arg);
1332                         break;
1333                 case OPT_INLINE_DEBUG_MIN:
1334                         opt_inline_debug_min_size = atoi(opt_arg);
1335                         break;
1336                 case OPT_INLINE_DEBUG_MAX:
1337                         opt_inline_debug_max_size = atoi(opt_arg);
1338                         break;
1339                 case OPT_INLINE_REPLACE_VERBOSE:
1340                         opt_replace_verbose = 1;
1341                         break;
1342                 case OPT_INLINE_REPLACE_VERBOSE2:
1343                         opt_replace_verbose = 2;
1344                         break;
1345 #endif /* defined(ENABLE_INLINING_DEBUG) */
1346 #if !defined(NDEBUG)
1347                 case OPT_INLINE_LOG:
1348                         opt_inline_debug_log = true;
1349                         break;
1350 #endif /* !defined(NDEBUG) */
1351
1352                 case OPT_INLINING:
1353                         opt_inlining = true;
1354                         break;
1355 #endif /* defined(ENABLE_INLINING) */
1356
1357 #if defined(ENABLE_IFCONV)
1358                 case OPT_IFCONV:
1359                         opt_ifconv = true;
1360                         break;
1361 #endif
1362
1363 #if defined(ENABLE_LSRA) || defined(ENABLE_SSA)
1364                 case OPT_LSRA:
1365                         opt_lsra = true;
1366                         break;
1367 #endif
1368
1369                 case OPT_HELP:
1370                         usage();
1371                         break;
1372
1373                 case OPT_X:
1374                         Xusage();
1375                         break;
1376
1377                 case OPT_XX:
1378                         options_xx(opt_arg);
1379                         break;
1380
1381                 case OPT_EA:
1382                         /* currently ignored */
1383                         break;
1384
1385                 case OPT_DA:
1386                         /* currently ignored */
1387                         break;
1388
1389                 case OPT_ESA:
1390                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = true;
1391                         break;
1392
1393                 case OPT_DSA:
1394                         _Jv_jvm->Java_java_lang_VMClassLoader_defaultAssertionStatus = false;
1395                         break;
1396
1397 #if defined(ENABLE_PROFILING)
1398                 case OPT_PROF_OPTION:
1399                         /* use <= to get the last \0 too */
1400
1401                         for (i = 0, j = 0; i <= strlen(opt_arg); i++) {
1402                                 if (opt_arg[i] == ',')
1403                                         opt_arg[i] = '\0';
1404
1405                                 if (opt_arg[i] == '\0') {
1406                                         if (strcmp("bb", opt_arg + j) == 0)
1407                                                 opt_prof_bb = true;
1408
1409                                         else {
1410                                                 printf("Unknown option: -Xprof:%s\n", opt_arg + j);
1411                                                 usage();
1412                                         }
1413
1414                                         /* set k to next char */
1415
1416                                         j = i + 1;
1417                                 }
1418                         }
1419                         /* fall through */
1420
1421                 case OPT_PROF:
1422                         opt_prof = true;
1423                         break;
1424 #endif
1425
1426                 case OPT_JIT:
1427 #if defined(ENABLE_JIT)
1428                         opt_jit = true;
1429 #else
1430                         printf("-Xjit option not enabled.\n");
1431                         exit(1);
1432 #endif
1433                         break;
1434
1435                 case OPT_INTRP:
1436 #if defined(ENABLE_INTRP)
1437                         opt_intrp = true;
1438 #else
1439                         printf("-Xint option not enabled.\n");
1440                         exit(1);
1441 #endif
1442                         break;
1443
1444 #if defined(ENABLE_INTRP)
1445                 case OPT_STATIC_SUPERS:
1446                         opt_static_supers = atoi(opt_arg);
1447                         break;
1448
1449                 case OPT_NO_DYNAMIC:
1450                         opt_no_dynamic = true;
1451                         break;
1452
1453                 case OPT_NO_REPLICATION:
1454                         opt_no_replication = true;
1455                         break;
1456
1457                 case OPT_NO_QUICKSUPER:
1458                         opt_no_quicksuper = true;
1459                         break;
1460
1461                 case OPT_TRACE:
1462                         vm_debug = true;
1463                         break;
1464 #endif
1465
1466 #if defined(ENABLE_DEBUG_FILTER)
1467                 case OPT_FILTER_VERBOSECALL_INCLUDE:
1468                         opt_filter_verbosecall_include = opt_arg;
1469                         break;
1470
1471                 case OPT_FILTER_VERBOSECALL_EXCLUDE:
1472                         opt_filter_verbosecall_exclude = opt_arg;
1473                         break;
1474
1475                 case OPT_FILTER_SHOW_METHOD:
1476                         opt_filter_show_method = opt_arg;
1477                         break;
1478
1479 #endif
1480                 default:
1481                         printf("Unknown option: %s\n",
1482                                    vm_args->options[opt_index].optionString);
1483                         usage();
1484                 }
1485         }
1486
1487         /* get the main class *****************************************************/
1488
1489         if (opt_index < vm_args->nOptions) {
1490                 mainstring = vm_args->options[opt_index++].optionString;
1491
1492                 /* Put the jar file into the classpath (if any). */
1493
1494                 if (opt_jar == true) {
1495                         /* free old classpath */
1496
1497                         MFREE(_Jv_classpath, char, strlen(_Jv_classpath));
1498
1499                         /* put jarfile into classpath */
1500
1501                         _Jv_classpath = MNEW(char, strlen(mainstring) + strlen("0"));
1502
1503                         strcpy(_Jv_classpath, mainstring);
1504                 }
1505                 else {
1506                         /* replace .'s with /'s in classname */
1507
1508                         for (i = strlen(mainstring) - 1; i >= 0; i--)
1509                                 if (mainstring[i] == '.')
1510                                         mainstring[i] = '/';
1511                 }
1512         }
1513
1514 #if defined(ENABLE_JVMTI)
1515         if (jvmti) {
1516                 jvmti_set_phase(JVMTI_PHASE_ONLOAD);
1517                 jvmti_agentload(agentarg, agentbypath, &handle, &libname);
1518
1519                 if (jdwp)
1520                         MFREE(agentarg, char, strlen(agentarg));
1521
1522                 jvmti_set_phase(JVMTI_PHASE_PRIMORDIAL);
1523         }
1524 #endif
1525
1526         /* initialize this JVM ****************************************************/
1527
1528         vm_initializing = true;
1529
1530 #if defined(ENABLE_THREADS)
1531         /* pre-initialize some core thread stuff, like the stopworldlock,
1532            thus this has to happen _before_ gc_init()!!! */
1533
1534         threads_preinit();
1535 #endif
1536
1537         /* initialize the garbage collector */
1538
1539         gc_init(opt_heapmaxsize, opt_heapstartsize);
1540
1541         /* install architecture dependent signal handlers */
1542
1543         if (!signal_init())
1544                 vm_abort("vm_create: signal_init failed");
1545
1546 #if defined(ENABLE_INTRP)
1547         /* Allocate main thread stack on the Java heap. */
1548
1549         if (opt_intrp) {
1550                 intrp_main_stack = GCMNEW(u1, opt_stacksize);
1551                 MSET(intrp_main_stack, 0, u1, opt_stacksize);
1552         }
1553 #endif
1554
1555         /* AFTER: threads_preinit */
1556
1557         if (!string_init())
1558                 vm_abort("vm_create: string_init failed");
1559
1560         /* AFTER: threads_preinit */
1561
1562         if (!utf8_init())
1563                 vm_abort("vm_create: utf8_init failed");
1564
1565         /* AFTER: thread_preinit */
1566
1567         if (!suck_init())
1568                 vm_abort("vm_create: suck_init failed");
1569
1570         suck_add_from_property("java.endorsed.dirs");
1571
1572         /* Now we have all options handled and we can print the version
1573            information.
1574
1575            AFTER: suck_add_from_property("java.endorsed.dirs"); */
1576
1577         if (opt_version)
1578                 version(opt_exit);
1579
1580         /* AFTER: utf8_init */
1581
1582         suck_add(_Jv_bootclasspath);
1583
1584         /* Now re-set some of the properties that may have changed. This
1585            must be done after _all_ environment variables have been
1586            processes (e.g. -jar handling).
1587
1588            AFTER: suck_add_from_property, since it may change the
1589            _Jv_bootclasspath pointer. */
1590
1591         if (!properties_postinit())
1592                 vm_abort("vm_create: properties_postinit failed");
1593
1594         /* initialize the classcache hashtable stuff: lock, hashtable
1595            (must be done _after_ threads_preinit) */
1596
1597         if (!classcache_init())
1598                 vm_abort("vm_create: classcache_init failed");
1599
1600         /* initialize the memory subsystem (must be done _after_
1601            threads_preinit) */
1602
1603         if (!memory_init())
1604                 vm_abort("vm_create: memory_init failed");
1605
1606         /* initialize the finalizer stuff (must be done _after_
1607            threads_preinit) */
1608
1609         if (!finalizer_init())
1610                 vm_abort("vm_create: finalizer_init failed");
1611
1612         /* initialize the codegen subsystems */
1613
1614         codegen_init();
1615
1616         /* initializes jit compiler */
1617
1618         jit_init();
1619
1620         /* machine dependent initialization */
1621
1622 #if defined(ENABLE_JIT)
1623 # if defined(ENABLE_INTRP)
1624         if (opt_intrp)
1625                 intrp_md_init();
1626         else
1627 # endif
1628                 md_init();
1629 #else
1630         intrp_md_init();
1631 #endif
1632
1633         /* initialize the loader subsystems (must be done _after_
1634        classcache_init) */
1635
1636         if (!loader_init())
1637                 vm_abort("vm_create: loader_init failed");
1638
1639         /* Link some important VM classes. */
1640         /* AFTER: utf8_init */
1641
1642         if (!linker_init())
1643                 vm_abort("vm_create: linker_init failed");
1644
1645         if (!primitive_init())
1646                 vm_abort("vm_create: primitive_init failed");
1647
1648         /* Initialize the native subsystem. */
1649
1650         if (!native_init())
1651                 vm_abort("vm_create: native_init failed");
1652
1653         if (!exceptions_init())
1654                 vm_abort("vm_create: exceptions_init failed");
1655
1656         if (!builtin_init())
1657                 vm_abort("vm_create: builtin_init failed");
1658
1659 #if defined(ENABLE_JNI)
1660         /* Initialize the JNI subsystem (must be done _before_
1661            threads_init, as threads_init can call JNI methods
1662            (e.g. NewGlobalRef). */
1663
1664         if (!jni_init())
1665                 vm_abort("vm_create: jni_init failed");
1666 #endif
1667
1668 #if defined(ENABLE_THREADS)
1669         if (!threads_init())
1670                 vm_abort("vm_create: threads_init failed");
1671 #endif
1672
1673 #if defined(ENABLE_PROFILING)
1674         /* initialize profiling */
1675
1676         if (!profile_init())
1677                 vm_abort("vm_create: profile_init failed");
1678 #endif
1679
1680 #if defined(ENABLE_THREADS)
1681         /* initialize recompilation */
1682
1683         if (!recompile_init())
1684                 vm_abort("vm_create: recompile_init failed");
1685
1686         /* start the signal handler thread */
1687
1688 #if defined(__LINUX__)
1689         /* XXX Remove for exact-GC. */
1690         if (threads_pthreads_implementation_nptl)
1691 #endif
1692                 if (!signal_start_thread())
1693                         vm_abort("vm_create: signal_start_thread failed");
1694
1695         /* finally, start the finalizer thread */
1696
1697         if (!finalizer_start_thread())
1698                 vm_abort("vm_create: finalizer_start_thread failed");
1699
1700 # if !defined(NDEBUG)
1701         /* start the memory profiling thread */
1702
1703         if (opt_verbosememory)
1704                 if (!memory_start_thread())
1705                         vm_abort("vm_create: memory_start_thread failed");
1706 # endif
1707
1708         /* start the recompilation thread (must be done before the
1709            profiling thread) */
1710
1711         if (!recompile_start_thread())
1712                 vm_abort("vm_create: recompile_start_thread failed");
1713
1714 # if defined(ENABLE_PROFILING)
1715         /* start the profile sampling thread */
1716
1717 /*      if (opt_prof) */
1718 /*              if (!profile_start_thread()) */
1719 /*                      vm_abort("vm_create: profile_start_thread failed"); */
1720 # endif
1721 #endif
1722
1723 #if defined(ENABLE_JVMTI)
1724         if (jvmti) {
1725                 /* add agent library to native library hashtable */
1726                 native_hashtable_library_add(utf_new_char(libname), class_java_lang_Object->classloader, handle);
1727         }
1728 #endif
1729
1730         /* increment the number of VMs */
1731
1732         vms++;
1733
1734         /* initialization is done */
1735
1736         vm_initializing = false;
1737
1738         /* everything's ok */
1739
1740         return true;
1741 }
1742
1743
1744 /* vm_run **********************************************************************
1745
1746    Runs the main-method of the passed class.
1747
1748 *******************************************************************************/
1749
1750 void vm_run(JavaVM *vm, JavaVMInitArgs *vm_args)
1751 {
1752         utf               *mainutf;
1753         classinfo         *mainclass;
1754         java_objectheader *e;
1755         methodinfo        *m;
1756         java_objectarray  *oa; 
1757         s4                 oalength;
1758         utf               *u;
1759         java_objectheader *s;
1760         s4                 status;
1761         s4                 i;
1762
1763 #if !defined(NDEBUG)
1764         if (compileall) {
1765                 vm_compile_all();
1766                 return;
1767         }
1768
1769         if (opt_method != NULL) {
1770                 vm_compile_method();
1771                 return;
1772         }
1773 #endif /* !defined(NDEBUG) */
1774
1775         /* should we run the main-method? */
1776
1777         if (mainstring == NULL)
1778                 usage();
1779
1780         /* set return value to OK */
1781
1782         status = 0;
1783
1784         if (opt_jar == true) {
1785                 /* open jar file with java.util.jar.JarFile */
1786
1787                 mainstring = vm_get_mainclass_from_jar(mainstring);
1788
1789                 if (mainstring == NULL)
1790                         vm_exit(1);
1791         }
1792
1793         /* load the main class */
1794
1795         mainutf = utf_new_char(mainstring);
1796
1797 #if defined(ENABLE_JAVAME_CLDC1_1)
1798         mainclass = load_class_bootstrap(mainutf);
1799 #else
1800         mainclass = load_class_from_sysloader(mainutf);
1801 #endif
1802
1803         /* error loading class */
1804
1805         e = exceptions_get_and_clear_exception();
1806
1807         if ((e != NULL) || (mainclass == NULL)) {
1808                 exceptions_throw_noclassdeffounderror_cause(e);
1809                 exceptions_print_stacktrace(); 
1810                 vm_exit(1);
1811         }
1812
1813         if (!link_class(mainclass)) {
1814                 exceptions_print_stacktrace();
1815                 vm_exit(1);
1816         }
1817                         
1818         /* find the `main' method of the main class */
1819
1820         m = class_resolveclassmethod(mainclass,
1821                                                                  utf_new_char("main"), 
1822                                                                  utf_new_char("([Ljava/lang/String;)V"),
1823                                                                  class_java_lang_Object,
1824                                                                  false);
1825
1826         if (exceptions_get_exception()) {
1827                 exceptions_print_stacktrace();
1828                 vm_exit(1);
1829         }
1830
1831         /* there is no main method or it isn't static */
1832
1833         if ((m == NULL) || !(m->flags & ACC_STATIC)) {
1834                 exceptions_clear_exception();
1835                 exceptions_throw_nosuchmethoderror(mainclass,
1836                                                                                    utf_new_char("main"), 
1837                                                                                    utf_new_char("([Ljava/lang/String;)V"));
1838
1839                 exceptions_print_stacktrace();
1840                 vm_exit(1);
1841         }
1842
1843         /* build argument array */
1844
1845         oalength = vm_args->nOptions - opt_index;
1846
1847         oa = builtin_anewarray(oalength, class_java_lang_String);
1848
1849         for (i = 0; i < oalength; i++) {
1850                 u = utf_new_char(vm_args->options[opt_index + i].optionString);
1851                 s = javastring_new(u);
1852
1853                 oa->data[i] = s;
1854         }
1855
1856 #ifdef TYPEINFO_DEBUG_TEST
1857         /* test the typeinfo system */
1858         typeinfo_test();
1859 #endif
1860         /*class_showmethods(currentThread->group->header.vftbl->class); */
1861
1862 #if defined(ENABLE_JVMTI)
1863         jvmti_set_phase(JVMTI_PHASE_LIVE);
1864 #endif
1865
1866         /* set ThreadMXBean variables */
1867
1868         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount++;
1869         _Jv_jvm->java_lang_management_ThreadMXBean_TotalStartedThreadCount++;
1870
1871         if (_Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount >
1872                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount)
1873                 _Jv_jvm->java_lang_management_ThreadMXBean_PeakThreadCount =
1874                         _Jv_jvm->java_lang_management_ThreadMXBean_ThreadCount;
1875
1876         /* start the main thread */
1877
1878         (void) vm_call_method(m, NULL, oa);
1879
1880         /* exception occurred? */
1881
1882         if (exceptions_get_exception()) {
1883                 exceptions_print_stacktrace();
1884                 status = 1;
1885         }
1886
1887         /* unload the JavaVM */
1888
1889         (void) vm_destroy(vm);
1890
1891         /* and exit */
1892
1893         vm_exit(status);
1894 }
1895
1896
1897 /* vm_destroy ******************************************************************
1898
1899    Unloads a Java VM and reclaims its resources.
1900
1901 *******************************************************************************/
1902
1903 s4 vm_destroy(JavaVM *vm)
1904 {
1905 #if defined(ENABLE_THREADS)
1906         threads_join_all_threads();
1907 #endif
1908
1909         /* everything's ok */
1910
1911         return 0;
1912 }
1913
1914
1915 /* vm_exit *********************************************************************
1916
1917    Calls java.lang.System.exit(I)V to exit the JavaVM correctly.
1918
1919 *******************************************************************************/
1920
1921 void vm_exit(s4 status)
1922 {
1923         methodinfo *m;
1924
1925         /* signal that we are exiting */
1926
1927         vm_exiting = true;
1928
1929         assert(class_java_lang_System);
1930         assert(class_java_lang_System->state & CLASS_LOADED);
1931
1932 #if defined(ENABLE_JVMTI)
1933         if (jvmti || (dbgcom!=NULL)) {
1934                 jvmti_set_phase(JVMTI_PHASE_DEAD);
1935                 if (jvmti) jvmti_agentunload();
1936         }
1937 #endif
1938
1939         if (!link_class(class_java_lang_System)) {
1940                 exceptions_print_stacktrace();
1941                 exit(1);
1942         }
1943
1944         /* call java.lang.System.exit(I)V */
1945
1946         m = class_resolveclassmethod(class_java_lang_System,
1947                                                                  utf_new_char("exit"),
1948                                                                  utf_int__void,
1949                                                                  class_java_lang_Object,
1950                                                                  true);
1951         
1952         if (m == NULL) {
1953                 exceptions_print_stacktrace();
1954                 exit(1);
1955         }
1956
1957         /* call the exit function with passed exit status */
1958
1959         (void) vm_call_method(m, NULL, status);
1960
1961         /* If we had an exception, just ignore the exception and exit with
1962            the proper code. */
1963
1964         vm_shutdown(status);
1965 }
1966
1967
1968 /* vm_shutdown *****************************************************************
1969
1970    Terminates the system immediately without freeing memory explicitly
1971    (to be used only for abnormal termination).
1972         
1973 *******************************************************************************/
1974
1975 void vm_shutdown(s4 status)
1976 {
1977         if (opt_verbose 
1978 #if defined(ENABLE_STATISTICS)
1979                 || opt_getcompilingtime || opt_stat
1980 #endif
1981            ) 
1982         {
1983                 log_text("CACAO terminated by shutdown");
1984                 dolog("Exit status: %d\n", (s4) status);
1985
1986         }
1987
1988 #if defined(ENABLE_JVMTI)
1989         /* terminate cacaodbgserver */
1990         if (dbgcom!=NULL) {
1991                 pthread_mutex_lock(&dbgcomlock);
1992                 dbgcom->running=1;
1993                 pthread_mutex_unlock(&dbgcomlock);
1994                 jvmti_cacaodbgserver_quit();
1995         }       
1996 #endif
1997
1998         exit(status);
1999 }
2000
2001
2002 /* vm_exit_handler *************************************************************
2003
2004    The exit_handler function is called upon program termination.
2005
2006    ATTENTION: Don't free system resources here! Some threads may still
2007    be running as this is called from VMRuntime.exit(). The OS does the
2008    cleanup for us.
2009
2010 *******************************************************************************/
2011
2012 void vm_exit_handler(void)
2013 {
2014 #if !defined(NDEBUG)
2015         if (showmethods)
2016                 class_showmethods(mainclass);
2017
2018         if (showconstantpool)
2019                 class_showconstantpool(mainclass);
2020
2021         if (showutf)
2022                 utf_show();
2023
2024 # if defined(ENABLE_PROFILING)
2025         if (opt_prof)
2026                 profile_printstats();
2027 # endif
2028 #endif /* !defined(NDEBUG) */
2029
2030 #if defined(ENABLE_RT_TIMING)
2031         rt_timing_print_time_stats(stderr);
2032 #endif
2033
2034 #if defined(ENABLE_CYCLES_STATS)
2035         builtin_print_cycles_stats(stderr);
2036         stacktrace_print_cycles_stats(stderr);
2037 #endif
2038
2039         if (opt_verbose 
2040 #if defined(ENABLE_STATISTICS)
2041                 || opt_getcompilingtime || opt_stat
2042 #endif
2043            ) 
2044         {
2045                 log_text("CACAO terminated");
2046
2047 #if defined(ENABLE_STATISTICS)
2048                 if (opt_stat) {
2049                         print_stats();
2050 #ifdef TYPECHECK_STATISTICS
2051                         typecheck_print_statistics(get_logfile());
2052 #endif
2053                 }
2054
2055                 if (opt_getcompilingtime)
2056                         print_times();
2057 #endif /* defined(ENABLE_STATISTICS) */
2058         }
2059         /* vm_print_profile(stderr);*/
2060 }
2061
2062
2063 /* vm_abort ********************************************************************
2064
2065    Prints an error message and aborts the VM.
2066
2067 *******************************************************************************/
2068
2069 void vm_abort(const char *text, ...)
2070 {
2071         va_list ap;
2072
2073         /* print the log message */
2074
2075         log_start();
2076
2077         va_start(ap, text);
2078         log_vprint(text, ap);
2079         va_end(ap);
2080
2081         log_finish();
2082
2083         /* now abort the VM */
2084
2085         abort();
2086 }
2087
2088
2089 /* vm_get_mainclass_from_jar ***************************************************
2090
2091    Gets the name of the main class from a JAR's manifest file.
2092
2093 *******************************************************************************/
2094
2095 static char *vm_get_mainclass_from_jar(char *mainstring)
2096 {
2097         classinfo         *c;
2098         java_objectheader *o;
2099         methodinfo        *m;
2100         java_objectheader *s;
2101
2102         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
2103
2104         if (c == NULL) {
2105                 exceptions_print_stacktrace();
2106                 return NULL;
2107         }
2108
2109         /* create JarFile object */
2110
2111         o = builtin_new(c);
2112
2113         if (o == NULL) {
2114                 exceptions_print_stacktrace();
2115                 return NULL;
2116         }
2117
2118         m = class_resolveclassmethod(c,
2119                                                                  utf_init, 
2120                                                                  utf_java_lang_String__void,
2121                                                                  class_java_lang_Object,
2122                                                                  true);
2123
2124         if (m == NULL) {
2125                 exceptions_print_stacktrace();
2126                 return NULL;
2127         }
2128
2129         s = javastring_new_from_ascii(mainstring);
2130
2131         (void) vm_call_method(m, o, s);
2132
2133         if (exceptions_get_exception()) {
2134                 exceptions_print_stacktrace();
2135                 return NULL;
2136         }
2137
2138         /* get manifest object */
2139
2140         m = class_resolveclassmethod(c,
2141                                                                  utf_new_char("getManifest"), 
2142                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
2143                                                                  class_java_lang_Object,
2144                                                                  true);
2145
2146         if (m == NULL) {
2147                 exceptions_print_stacktrace();
2148                 return NULL;
2149         }
2150
2151         o = vm_call_method(m, o);
2152
2153         if (o == NULL) {
2154                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
2155                 return NULL;
2156         }
2157
2158
2159         /* get Main Attributes */
2160
2161         m = class_resolveclassmethod(o->vftbl->class,
2162                                                                  utf_new_char("getMainAttributes"), 
2163                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
2164                                                                  class_java_lang_Object,
2165                                                                  true);
2166
2167         if (m == NULL) {
2168                 exceptions_print_stacktrace();
2169                 return NULL;
2170         }
2171
2172         o = vm_call_method(m, o);
2173
2174         if (o == NULL) {
2175                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
2176                 return NULL;
2177         }
2178
2179
2180         /* get property Main-Class */
2181
2182         m = class_resolveclassmethod(o->vftbl->class,
2183                                                                  utf_new_char("getValue"), 
2184                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
2185                                                                  class_java_lang_Object,
2186                                                                  true);
2187
2188         if (m == NULL) {
2189                 exceptions_print_stacktrace();
2190                 return NULL;
2191         }
2192
2193         s = javastring_new_from_ascii("Main-Class");
2194
2195         o = vm_call_method(m, o, s);
2196
2197         if (o == NULL) {
2198                 exceptions_print_stacktrace();
2199                 return NULL;
2200         }
2201
2202         return javastring_tochar(o);
2203 }
2204
2205
2206 /* vm_compile_all **************************************************************
2207
2208    Compile all methods found in the bootclasspath.
2209
2210 *******************************************************************************/
2211
2212 #if !defined(NDEBUG)
2213 static void vm_compile_all(void)
2214 {
2215         classinfo              *c;
2216         methodinfo             *m;
2217         u4                      slot;
2218         classcache_name_entry  *nmen;
2219         classcache_class_entry *clsen;
2220         s4                      i;
2221
2222         /* create all classes found in the bootclasspath */
2223         /* XXX currently only works with zip/jar's */
2224
2225         loader_load_all_classes();
2226
2227         /* link all classes */
2228
2229         for (slot = 0; slot < hashtable_classcache.size; slot++) {
2230                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
2231
2232                 for (; nmen; nmen = nmen->hashlink) {
2233                         /* iterate over all class entries */
2234
2235                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
2236                                 c = clsen->classobj;
2237
2238                                 if (c == NULL)
2239                                         continue;
2240
2241                                 if (!(c->state & CLASS_LINKED)) {
2242                                         if (!link_class(c)) {
2243                                                 fprintf(stderr, "Error linking: ");
2244                                                 utf_fprint_printable_ascii_classname(stderr, c->name);
2245                                                 fprintf(stderr, "\n");
2246
2247                                                 /* print out exception and cause */
2248
2249                                                 exceptions_print_current_exception();
2250
2251                                                 /* goto next class */
2252
2253                                                 continue;
2254                                         }
2255                                 }
2256
2257                                 /* compile all class methods */
2258
2259                                 for (i = 0; i < c->methodscount; i++) {
2260                                         m = &(c->methods[i]);
2261
2262                                         if (m->jcode != NULL) {
2263                                                 if (!jit_compile(m)) {
2264                                                         fprintf(stderr, "Error compiling: ");
2265                                                         utf_fprint_printable_ascii_classname(stderr, c->name);
2266                                                         fprintf(stderr, ".");
2267                                                         utf_fprint_printable_ascii(stderr, m->name);
2268                                                         utf_fprint_printable_ascii(stderr, m->descriptor);
2269                                                         fprintf(stderr, "\n");
2270
2271                                                         /* print out exception and cause */
2272
2273                                                         exceptions_print_current_exception();
2274                                                 }
2275                                         }
2276                                 }
2277                         }
2278                 }
2279         }
2280 }
2281 #endif /* !defined(NDEBUG) */
2282
2283
2284 /* vm_compile_method ***********************************************************
2285
2286    Compile a specific method.
2287
2288 *******************************************************************************/
2289
2290 #if !defined(NDEBUG)
2291 static void vm_compile_method(void)
2292 {
2293         methodinfo *m;
2294
2295         /* create, load and link the main class */
2296
2297         mainclass = load_class_bootstrap(utf_new_char(mainstring));
2298
2299         if (mainclass == NULL)
2300                 exceptions_print_stacktrace();
2301
2302         if (!link_class(mainclass))
2303                 exceptions_print_stacktrace();
2304
2305         if (opt_signature != NULL) {
2306                 m = class_resolveclassmethod(mainclass,
2307                                                                          utf_new_char(opt_method),
2308                                                                          utf_new_char(opt_signature),
2309                                                                          mainclass,
2310                                                                          false);
2311         }
2312         else {
2313                 m = class_resolveclassmethod(mainclass,
2314                                                                          utf_new_char(opt_method),
2315                                                                          NULL,
2316                                                                          mainclass,
2317                                                                          false);
2318         }
2319
2320         if (m == NULL)
2321                 vm_abort("vm_compile_method: java.lang.NoSuchMethodException: %s.%s",
2322                                  opt_method, opt_signature ? opt_signature : "");
2323                 
2324         jit_compile(m);
2325 }
2326 #endif /* !defined(NDEBUG) */
2327
2328
2329 /* vm_array_store_int **********************************************************
2330
2331    Helper function to store an integer into the argument array, taking
2332    care of architecture specific issues.
2333
2334 *******************************************************************************/
2335
2336 static void vm_array_store_int(uint64_t *array, paramdesc *pd, int32_t value)
2337 {
2338         int32_t index;
2339
2340         if (!pd->inmemory) {
2341                 index        = pd->index;
2342                 array[index] = (int64_t) value;
2343         }
2344         else {
2345                 index        = ARG_CNT + pd->regoff;
2346 #if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2347                 array[index] = ((int64_t) value) << 32;
2348 #else
2349                 array[index] = (int64_t) value;
2350 #endif
2351         }
2352 }
2353
2354
2355 /* vm_array_store_lng **********************************************************
2356
2357    Helper function to store a long into the argument array, taking
2358    care of architecture specific issues.
2359
2360 *******************************************************************************/
2361
2362 static void vm_array_store_lng(uint64_t *array, paramdesc *pd, int64_t value)
2363 {
2364         int32_t index;
2365
2366 #if SIZEOF_VOID_P == 8
2367         if (!pd->inmemory)
2368                 index = pd->index;
2369         else
2370                 index = ARG_CNT + pd->regoff;
2371
2372         array[index] = value;
2373 #else
2374         if (!pd->inmemory) {
2375                 /* move low and high 32-bits into it's own argument slot */
2376
2377                 index        = GET_LOW_REG(pd->index);
2378                 array[index] = value & 0x00000000ffffffff;
2379
2380                 index        = GET_HIGH_REG(pd->index);
2381                 array[index] = value >> 32;
2382         }
2383         else {
2384                 index        = ARG_CNT + pd->regoff;
2385                 array[index] = value;
2386         }
2387 #endif
2388 }
2389
2390
2391 /* vm_array_store_flt **********************************************************
2392
2393    Helper function to store a float into the argument array, taking
2394    care of architecture specific issues.
2395
2396 *******************************************************************************/
2397
2398 static void vm_array_store_flt(uint64_t *array, paramdesc *pd, uint64_t value)
2399 {
2400         int32_t index;
2401
2402         if (!pd->inmemory) {
2403                 index        = INT_ARG_CNT + pd->index;
2404 #if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2405                 array[index] = value >> 32;
2406 #else
2407                 array[index] = value;
2408 #endif
2409         }
2410         else {
2411                 index        = ARG_CNT + pd->regoff;
2412                 array[index] = value;
2413         }
2414 }
2415
2416
2417 /* vm_array_store_dbl **********************************************************
2418
2419    Helper function to store a double into the argument array, taking
2420    care of architecture specific issues.
2421
2422 *******************************************************************************/
2423
2424 static void vm_array_store_dbl(uint64_t *array, paramdesc *pd, uint64_t value)
2425 {
2426         int32_t index;
2427
2428         if (!pd->inmemory)
2429                 index = INT_ARG_CNT + pd->index;
2430         else
2431                 index = ARG_CNT + pd->regoff;
2432
2433         array[index] = value;
2434 }
2435
2436
2437 /* vm_array_store_adr **********************************************************
2438
2439    Helper function to store an address into the argument array, taking
2440    care of architecture specific issues.
2441
2442 *******************************************************************************/
2443
2444 static void vm_array_store_adr(uint64_t *array, paramdesc *pd, void *value)
2445 {
2446         int32_t index;
2447
2448         if (!pd->inmemory) {
2449 #if defined(HAS_ADDRESS_REGISTER_FILE)
2450                 /* When the architecture has address registers, place them
2451                    after integer and float registers. */
2452
2453                 index        = INT_ARG_CNT + FLT_ARG_CNT + pd->index;
2454 #else
2455                 index        = pd->index;
2456 #endif
2457                 array[index] = (uint64_t) (intptr_t) value;
2458         }
2459         else {
2460                 index        = ARG_CNT + pd->regoff;
2461 #if SIZEOF_VOID_P == 8
2462                 array[index] = (uint64_t) (intptr_t) value;
2463 #else
2464 # if WORDS_BIGENDIAN == 1 && !defined(__POWERPC64__)
2465                 array[index] = ((uint64_t) (intptr_t) value) << 32;
2466 # else
2467                 array[index] = (uint64_t) (intptr_t) value;
2468 # endif
2469 #endif
2470         }
2471 }
2472
2473
2474 /* vm_vmargs_from_valist *******************************************************
2475
2476    XXX
2477
2478 *******************************************************************************/
2479
2480 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
2481 static void vm_vmargs_from_valist(methodinfo *m, java_objectheader *o,
2482                                                                   vm_arg *vmargs, va_list ap)
2483 {
2484         typedesc *paramtypes;
2485         s4        i;
2486
2487         paramtypes = m->parseddesc->paramtypes;
2488
2489         /* if method is non-static fill first block and skip `this' pointer */
2490
2491         i = 0;
2492
2493         if (o != NULL) {
2494                 /* the `this' pointer */
2495                 vmargs[0].type   = TYPE_ADR;
2496                 vmargs[0].data.l = (u8) (ptrint) o;
2497
2498                 paramtypes++;
2499                 i++;
2500         } 
2501
2502         for (; i < m->parseddesc->paramcount; i++, paramtypes++) {
2503                 switch (paramtypes->type) {
2504                 case TYPE_INT:
2505                         vmargs[i].type   = TYPE_INT;
2506                         vmargs[i].data.l = (s8) va_arg(ap, s4);
2507                         break;
2508
2509                 case TYPE_LNG:
2510                         vmargs[i].type   = TYPE_LNG;
2511                         vmargs[i].data.l = (s8) va_arg(ap, s8);
2512                         break;
2513
2514                 case TYPE_FLT:
2515                         vmargs[i].type   = TYPE_FLT;
2516 #if defined(__ALPHA__)
2517                         /* this keeps the assembler function much simpler */
2518
2519                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2520 #else
2521                         vmargs[i].data.f = (jfloat) va_arg(ap, jdouble);
2522 #endif
2523                         break;
2524
2525                 case TYPE_DBL:
2526                         vmargs[i].type   = TYPE_DBL;
2527                         vmargs[i].data.d = (jdouble) va_arg(ap, jdouble);
2528                         break;
2529
2530                 case TYPE_ADR: 
2531                         vmargs[i].type   = TYPE_ADR;
2532                         vmargs[i].data.l = (u8) (ptrint) va_arg(ap, void*);
2533                         break;
2534                 }
2535         }
2536 }
2537 #else
2538 uint64_t *vm_array_from_valist(methodinfo *m, java_objectheader *o, va_list ap)
2539 {
2540         methoddesc *md;
2541         paramdesc  *pd;
2542         typedesc   *td;
2543         uint64_t   *array;
2544         int32_t     i;
2545         imm_union   value;
2546
2547         /* get the descriptors */
2548
2549         md = m->parseddesc;
2550         pd = md->params;
2551         td = md->paramtypes;
2552
2553         /* allocate argument array */
2554
2555         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2556
2557         /* if method is non-static fill first block and skip `this' pointer */
2558
2559         i = 0;
2560
2561         if (o != NULL) {
2562                 /* the `this' pointer */
2563                 vm_array_store_adr(array, pd, o);
2564
2565                 pd++;
2566                 td++;
2567                 i++;
2568         } 
2569
2570         for (; i < md->paramcount; i++, pd++, td++) {
2571                 switch (td->type) {
2572                 case TYPE_INT:
2573                         value.i = va_arg(ap, int32_t);
2574                         vm_array_store_int(array, pd, value.i);
2575                         break;
2576
2577                 case TYPE_LNG:
2578                         value.l = va_arg(ap, int64_t);
2579                         vm_array_store_lng(array, pd, value.l);
2580                         break;
2581
2582                 case TYPE_FLT:
2583 #if defined(__ALPHA__) || defined(__POWERPC64__)
2584                         /* this keeps the assembler function much simpler */
2585
2586                         value.d = (double) va_arg(ap, double);
2587 #else
2588                         value.f = (float) va_arg(ap, double);
2589 #endif
2590                         vm_array_store_flt(array, pd, value.l);
2591                         break;
2592
2593                 case TYPE_DBL:
2594                         value.d = va_arg(ap, double);
2595                         vm_array_store_dbl(array, pd, value.l);
2596                         break;
2597
2598                 case TYPE_ADR: 
2599                         value.a = va_arg(ap, void*);
2600                         vm_array_store_adr(array, pd, value.a);
2601                         break;
2602                 }
2603         }
2604
2605         return array;
2606 }
2607 #endif
2608
2609
2610 /* vm_vmargs_from_jvalue *******************************************************
2611
2612    XXX
2613
2614 *******************************************************************************/
2615
2616 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
2617 static void vm_vmargs_from_jvalue(methodinfo *m, java_objectheader *o,
2618                                                                   vm_arg *vmargs, jvalue *args)
2619 {
2620         typedesc *paramtypes;
2621         s4        i;
2622         s4        j;
2623
2624         paramtypes = m->parseddesc->paramtypes;
2625
2626         /* if method is non-static fill first block and skip `this' pointer */
2627
2628         i = 0;
2629
2630         if (o != NULL) {
2631                 /* the `this' pointer */
2632                 vmargs[0].type   = TYPE_ADR;
2633                 vmargs[0].data.l = (u8) (ptrint) o;
2634
2635                 paramtypes++;
2636                 i++;
2637         } 
2638
2639         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2640                 switch (paramtypes->decltype) {
2641                 case TYPE_INT:
2642                         vmargs[i].type   = TYPE_INT;
2643                         vmargs[i].data.l = (s8) args[j].i;
2644                         break;
2645
2646                 case TYPE_LNG:
2647                         vmargs[i].type   = TYPE_LNG;
2648                         vmargs[i].data.l = (s8) args[j].j;
2649                         break;
2650
2651                 case TYPE_FLT:
2652                         vmargs[i].type = TYPE_FLT;
2653 #if defined(__ALPHA__)
2654                         /* this keeps the assembler function much simpler */
2655
2656                         vmargs[i].data.d = (jdouble) args[j].f;
2657 #else
2658                         vmargs[i].data.f = args[j].f;
2659 #endif
2660                         break;
2661
2662                 case TYPE_DBL:
2663                         vmargs[i].type   = TYPE_DBL;
2664                         vmargs[i].data.d = args[j].d;
2665                         break;
2666
2667                 case TYPE_ADR: 
2668                         vmargs[i].type   = TYPE_ADR;
2669                         vmargs[i].data.l = (u8) (ptrint) args[j].l;
2670                         break;
2671                 }
2672         }
2673 }
2674 #else
2675 static uint64_t *vm_array_from_jvalue(methodinfo *m, java_objectheader *o,
2676                                                                           jvalue *args)
2677 {
2678         methoddesc *md;
2679         paramdesc  *pd;
2680         typedesc   *td;
2681         uint64_t   *array;
2682         int32_t     i;
2683         int32_t     j;
2684
2685         /* get the descriptors */
2686
2687         md = m->parseddesc;
2688         pd = md->params;
2689         td = md->paramtypes;
2690
2691         /* allocate argument array */
2692
2693 #if defined(HAS_ADDRESS_REGISTER_FILE)
2694         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + ADR_ARG_CNT + md->memuse);
2695 #else
2696         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2697 #endif
2698
2699         /* if method is non-static fill first block and skip `this' pointer */
2700
2701         i = 0;
2702
2703         if (o != NULL) {
2704                 /* the `this' pointer */
2705                 vm_array_store_adr(array, pd, o);
2706
2707                 pd++;
2708                 td++;
2709                 i++;
2710         } 
2711
2712         for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
2713                 switch (td->decltype) {
2714                 case TYPE_INT:
2715                         vm_array_store_int(array, pd, args[j].i);
2716                         break;
2717
2718                 case TYPE_LNG:
2719                         vm_array_store_lng(array, pd, args[j].j);
2720                         break;
2721
2722                 case TYPE_FLT:
2723                         vm_array_store_flt(array, pd, args[j].j);
2724                         break;
2725
2726                 case TYPE_DBL:
2727                         vm_array_store_dbl(array, pd, args[j].j);
2728                         break;
2729
2730                 case TYPE_ADR: 
2731                         vm_array_store_adr(array, pd, args[j].l);
2732                         break;
2733                 }
2734         }
2735
2736         return array;
2737 }
2738 #endif
2739
2740 /* vm_vmargs_from_objectarray **************************************************
2741
2742    XXX
2743
2744 *******************************************************************************/
2745
2746 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
2747 bool vm_vmargs_from_objectarray(methodinfo *m, java_objectheader *o,
2748                                                                 vm_arg *vmargs, java_objectarray *params)
2749 {
2750         java_objectheader *param;
2751         typedesc          *paramtypes;
2752         classinfo         *c;
2753         int32_t            i;
2754         int32_t            j;
2755         int64_t            value;
2756
2757         paramtypes = m->parseddesc->paramtypes;
2758
2759         /* if method is non-static fill first block and skip `this' pointer */
2760
2761         i = 0;
2762
2763         if (o != NULL) {
2764                 /* this pointer */
2765                 vmargs[0].type   = TYPE_ADR;
2766                 vmargs[0].data.l = (uint64_t) (intptr_t) o;
2767
2768                 paramtypes++;
2769                 i++;
2770         }
2771
2772         for (j = 0; i < m->parseddesc->paramcount; i++, j++, paramtypes++) {
2773                 switch (paramtypes->type) {
2774                 /* primitive types */
2775                 case TYPE_INT:
2776                 case TYPE_LNG:
2777                 case TYPE_FLT:
2778                 case TYPE_DBL:
2779                         param = params->data[j];
2780
2781                         if (param == NULL)
2782                                 goto illegal_arg;
2783
2784                         /* internally used data type */
2785                         vmargs[i].type = paramtypes->type;
2786
2787                         /* convert the value according to its declared type */
2788
2789                         c = param->vftbl->class;
2790
2791                         switch (paramtypes->decltype) {
2792                         case PRIMITIVETYPE_BOOLEAN:
2793                                 if (c == class_java_lang_Boolean)
2794                                         value = (int64_t) ((java_lang_Boolean *) param)->value;
2795                                 else
2796                                         goto illegal_arg;
2797
2798                                 vmargs[i].data.l = value;
2799                                 break;
2800
2801                         case PRIMITIVETYPE_BYTE:
2802                                 if (c == class_java_lang_Byte)
2803                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2804                                 else
2805                                         goto illegal_arg;
2806
2807                                 vmargs[i].data.l = value;
2808                                 break;
2809
2810                         case PRIMITIVETYPE_CHAR:
2811                                 if (c == class_java_lang_Character)
2812                                         value = (int64_t) ((java_lang_Character *) param)->value;
2813                                 else
2814                                         goto illegal_arg;
2815
2816                                 vmargs[i].data.l = value;
2817                                 break;
2818
2819                         case PRIMITIVETYPE_SHORT:
2820                                 if (c == class_java_lang_Short)
2821                                         value = (int64_t) ((java_lang_Short *) param)->value;
2822                                 else if (c == class_java_lang_Byte)
2823                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2824                                 else
2825                                         goto illegal_arg;
2826
2827                                 vmargs[i].data.l = value;
2828                                 break;
2829
2830                         case PRIMITIVETYPE_INT:
2831                                 if (c == class_java_lang_Integer)
2832                                         value = (int64_t) ((java_lang_Integer *) param)->value;
2833                                 else if (c == class_java_lang_Short)
2834                                         value = (int64_t) ((java_lang_Short *) param)->value;
2835                                 else if (c == class_java_lang_Byte)
2836                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2837                                 else
2838                                         goto illegal_arg;
2839
2840                                 vmargs[i].data.l = value;
2841                                 break;
2842
2843                         case PRIMITIVETYPE_LONG:
2844                                 if (c == class_java_lang_Long)
2845                                         value = (int64_t) ((java_lang_Long *) param)->value;
2846                                 else if (c == class_java_lang_Integer)
2847                                         value = (int64_t) ((java_lang_Integer *) param)->value;
2848                                 else if (c == class_java_lang_Short)
2849                                         value = (int64_t) ((java_lang_Short *) param)->value;
2850                                 else if (c == class_java_lang_Byte)
2851                                         value = (int64_t) ((java_lang_Byte *) param)->value;
2852                                 else
2853                                         goto illegal_arg;
2854
2855                                 vmargs[i].data.l = value;
2856                                 break;
2857
2858                         case PRIMITIVETYPE_FLOAT:
2859                                 if (c == class_java_lang_Float)
2860                                         vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2861                                 else
2862                                         goto illegal_arg;
2863                                 break;
2864
2865                         case PRIMITIVETYPE_DOUBLE:
2866                                 if (c == class_java_lang_Double)
2867                                         vmargs[i].data.d = (jdouble) ((java_lang_Double *) param)->value;
2868                                 else if (c == class_java_lang_Float)
2869                                         vmargs[i].data.f = (jfloat) ((java_lang_Float *) param)->value;
2870                                 else
2871                                         goto illegal_arg;
2872                                 break;
2873
2874                         default:
2875                                 goto illegal_arg;
2876                         }
2877                         break;
2878                 
2879                 case TYPE_ADR:
2880                         if (!resolve_class_from_typedesc(paramtypes, true, true, &c))
2881                                 return false;
2882
2883                         if (params->data[j] != 0) {
2884                                 if (paramtypes->arraydim > 0) {
2885                                         if (!builtin_arrayinstanceof(params->data[j], c))
2886                                                 goto illegal_arg;
2887
2888                                 } else {
2889                                         if (!builtin_instanceof(params->data[j], c))
2890                                                 goto illegal_arg;
2891                                 }
2892                         }
2893
2894                         vmargs[i].type   = TYPE_ADR;
2895                         vmargs[i].data.l = (u8) (ptrint) params->data[j];
2896                         break;
2897
2898                 default:
2899                         goto illegal_arg;
2900                 }
2901         }
2902
2903 /*      if (rettype) */
2904 /*              *rettype = descr->returntype.decltype; */
2905
2906         return true;
2907
2908 illegal_arg:
2909         exceptions_throw_illegalargumentexception();
2910         return false;
2911 }
2912 #else
2913 uint64_t *vm_array_from_objectarray(methodinfo *m, java_objectheader *o,
2914                                                                         java_objectarray *params)
2915 {
2916         methoddesc        *md;
2917         paramdesc         *pd;
2918         typedesc          *td;
2919         uint64_t          *array;
2920         java_objectheader *param;
2921         classinfo         *c;
2922         int32_t            i;
2923         int32_t            j;
2924         imm_union          value;
2925
2926         /* get the descriptors */
2927
2928         md = m->parseddesc;
2929         pd = md->params;
2930         td = md->paramtypes;
2931
2932         /* allocate argument array */
2933
2934         array = DMNEW(uint64_t, INT_ARG_CNT + FLT_ARG_CNT + md->memuse);
2935
2936         /* if method is non-static fill first block and skip `this' pointer */
2937
2938         i = 0;
2939
2940         if (o != NULL) {
2941                 /* this pointer */
2942                 vm_array_store_adr(array, pd, o);
2943
2944                 pd++;
2945                 td++;
2946                 i++;
2947         }
2948
2949         for (j = 0; i < md->paramcount; i++, j++, pd++, td++) {
2950                 param = params->data[j];
2951
2952                 switch (td->type) {
2953                 case TYPE_INT:
2954                         if (param == NULL)
2955                                 goto illegal_arg;
2956
2957                         /* convert the value according to its declared type */
2958
2959                         c = param->vftbl->class;
2960
2961                         switch (td->decltype) {
2962                         case PRIMITIVETYPE_BOOLEAN:
2963                                 if (c == class_java_lang_Boolean)
2964                                         value.i = ((java_lang_Boolean *) param)->value;
2965                                 else
2966                                         goto illegal_arg;
2967                                 break;
2968
2969                         case PRIMITIVETYPE_BYTE:
2970                                 if (c == class_java_lang_Byte)
2971                                         value.i = ((java_lang_Byte *) param)->value;
2972                                 else
2973                                         goto illegal_arg;
2974                                 break;
2975
2976                         case PRIMITIVETYPE_CHAR:
2977                                 if (c == class_java_lang_Character)
2978                                         value.i = ((java_lang_Character *) param)->value;
2979                                 else
2980                                         goto illegal_arg;
2981                                 break;
2982
2983                         case PRIMITIVETYPE_SHORT:
2984                                 if (c == class_java_lang_Short)
2985                                         value.i = ((java_lang_Short *) param)->value;
2986                                 else if (c == class_java_lang_Byte)
2987                                         value.i = ((java_lang_Byte *) param)->value;
2988                                 else
2989                                         goto illegal_arg;
2990                                 break;
2991
2992                         case PRIMITIVETYPE_INT:
2993                                 if (c == class_java_lang_Integer)
2994                                         value.i = ((java_lang_Integer *) param)->value;
2995                                 else if (c == class_java_lang_Short)
2996                                         value.i = ((java_lang_Short *) param)->value;
2997                                 else if (c == class_java_lang_Byte)
2998                                         value.i = ((java_lang_Byte *) param)->value;
2999                                 else
3000                                         goto illegal_arg;
3001                                 break;
3002
3003                         default:
3004                                 goto illegal_arg;
3005                         }
3006
3007                         vm_array_store_int(array, pd, value.i);
3008                         break;
3009
3010                 case TYPE_LNG:
3011                         if (param == NULL)
3012                                 goto illegal_arg;
3013
3014                         /* convert the value according to its declared type */
3015
3016                         c = param->vftbl->class;
3017
3018                         switch (td->decltype) {
3019                         case PRIMITIVETYPE_LONG:
3020                                 if (c == class_java_lang_Long)
3021                                         value.l = ((java_lang_Long *) param)->value;
3022                                 else if (c == class_java_lang_Integer)
3023                                         value.l = (int64_t) ((java_lang_Integer *) param)->value;
3024                                 else if (c == class_java_lang_Short)
3025                                         value.l = (int64_t) ((java_lang_Short *) param)->value;
3026                                 else if (c == class_java_lang_Byte)
3027                                         value.l = (int64_t) ((java_lang_Byte *) param)->value;
3028                                 else
3029                                         goto illegal_arg;
3030                                 break;
3031
3032                         default:
3033                                 goto illegal_arg;
3034                         }
3035
3036                         vm_array_store_lng(array, pd, value.l);
3037                         break;
3038
3039                 case TYPE_FLT:
3040                         if (param == NULL)
3041                                 goto illegal_arg;
3042
3043                         /* convert the value according to its declared type */
3044
3045                         c = param->vftbl->class;
3046
3047                         switch (td->decltype) {
3048                         case PRIMITIVETYPE_FLOAT:
3049                                 if (c == class_java_lang_Float)
3050                                         value.f = ((java_lang_Float *) param)->value;
3051                                 else
3052                                         goto illegal_arg;
3053                                 break;
3054
3055                         default:
3056                                 goto illegal_arg;
3057                         }
3058
3059                         vm_array_store_flt(array, pd, value.l);
3060                         break;
3061
3062                 case TYPE_DBL:
3063                         if (param == NULL)
3064                                 goto illegal_arg;
3065
3066                         /* convert the value according to its declared type */
3067
3068                         c = param->vftbl->class;
3069
3070                         switch (td->decltype) {
3071                         case PRIMITIVETYPE_DOUBLE:
3072                                 if (c == class_java_lang_Double)
3073                                         value.d = ((java_lang_Double *) param)->value;
3074                                 else if (c == class_java_lang_Float)
3075                                         value.f = ((java_lang_Float *) param)->value;
3076                                 else
3077                                         goto illegal_arg;
3078                                 break;
3079
3080                         default:
3081                                 goto illegal_arg;
3082                         }
3083
3084                         vm_array_store_dbl(array, pd, value.l);
3085                         break;
3086                 
3087                 case TYPE_ADR:
3088                         if (!resolve_class_from_typedesc(td, true, true, &c))
3089                                 return false;
3090
3091                         if (param != NULL) {
3092                                 if (td->arraydim > 0) {
3093                                         if (!builtin_arrayinstanceof(param, c))
3094                                                 goto illegal_arg;
3095                                 }
3096                                 else {
3097                                         if (!builtin_instanceof(param, c))
3098                                                 goto illegal_arg;
3099                                 }
3100                         }
3101
3102                         vm_array_store_adr(array, pd, param);
3103                         break;
3104
3105                 default:
3106                         goto illegal_arg;
3107                 }
3108         }
3109
3110         return array;
3111
3112 illegal_arg:
3113         exceptions_throw_illegalargumentexception();
3114         return NULL;
3115 }
3116 #endif
3117
3118
3119 /* vm_call_method **************************************************************
3120
3121    Calls a Java method with a variable number of arguments and returns
3122    an address.
3123
3124 *******************************************************************************/
3125
3126 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
3127 {
3128         va_list            ap;
3129         java_objectheader *ro;
3130
3131         va_start(ap, o);
3132         ro = vm_call_method_valist(m, o, ap);
3133         va_end(ap);
3134
3135         return ro;
3136 }
3137
3138
3139 /* vm_call_method_valist *******************************************************
3140
3141    Calls a Java method with a variable number of arguments, passed via
3142    a va_list, and returns an address.
3143
3144 *******************************************************************************/
3145
3146 java_objectheader *vm_call_method_valist(methodinfo *m, java_objectheader *o,
3147                                                                                  va_list ap)
3148 {
3149 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3150         s4                 vmargscount;
3151         vm_arg            *vmargs;
3152         java_objectheader *ro;
3153         s4                 dumpsize;
3154
3155         /* mark start of dump memory area */
3156
3157         dumpsize = dump_size();
3158
3159         /* get number of Java method arguments */
3160
3161         vmargscount = m->parseddesc->paramcount;
3162
3163         /* allocate vm_arg array */
3164
3165         vmargs = DMNEW(vm_arg, vmargscount);
3166
3167         /* fill the vm_arg array from a va_list */
3168
3169         vm_vmargs_from_valist(m, o, vmargs, ap);
3170
3171         /* call the Java method */
3172
3173         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3174
3175         /* release dump area */
3176
3177         dump_release(dumpsize);
3178
3179         return ro;
3180 #else
3181         java_objectheader *ro;
3182         int32_t            dumpsize;
3183         uint64_t          *array;
3184
3185         /* mark start of dump memory area */
3186
3187         dumpsize = dump_size();
3188
3189         /* fill the argument array from a va_list */
3190
3191         array = vm_array_from_valist(m, o, ap);
3192
3193         /* call the Java method */
3194
3195         ro = vm_call_array(m, array);
3196
3197         /* release dump area */
3198
3199         dump_release(dumpsize);
3200
3201         return ro;
3202 #endif
3203 }
3204
3205
3206 /* vm_call_method_jvalue *******************************************************
3207
3208    Calls a Java method with a variable number of arguments, passed via
3209    a jvalue array, and returns an address.
3210
3211 *******************************************************************************/
3212
3213 java_objectheader *vm_call_method_jvalue(methodinfo *m, java_objectheader *o,
3214                                                                                  jvalue *args)
3215 {
3216 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3217         s4                 vmargscount;
3218         vm_arg            *vmargs;
3219         java_objectheader *ro;
3220         s4                 dumpsize;
3221
3222         /* mark start of dump memory area */
3223
3224         dumpsize = dump_size();
3225
3226         /* get number of Java method arguments */
3227
3228         vmargscount = m->parseddesc->paramcount;
3229
3230         /* allocate vm_arg array */
3231
3232         vmargs = DMNEW(vm_arg, vmargscount);
3233
3234         /* fill the vm_arg array from a va_list */
3235
3236         vm_vmargs_from_jvalue(m, o, vmargs, args);
3237
3238         /* call the Java method */
3239
3240         ro = vm_call_method_vmarg(m, vmargscount, vmargs);
3241
3242         /* release dump area */
3243
3244         dump_release(dumpsize);
3245
3246         return ro;
3247 #else
3248         java_objectheader *ro;
3249         int32_t            dumpsize;
3250         uint64_t          *array;
3251
3252         /* mark start of dump memory area */
3253
3254         dumpsize = dump_size();
3255
3256         /* fill the argument array from a va_list */
3257
3258         array = vm_array_from_jvalue(m, o, args);
3259
3260         /* call the Java method */
3261
3262         ro = vm_call_array(m, array);
3263
3264         /* release dump area */
3265
3266         dump_release(dumpsize);
3267
3268         return ro;
3269 #endif
3270 }
3271
3272
3273 /* vm_call_array ***************************************************************
3274
3275    Calls a Java method with a variable number of arguments, passed via
3276    an argument array, and returns an address.
3277
3278 *******************************************************************************/
3279
3280 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3281 java_objectheader *vm_call_method_vmarg(methodinfo *m, s4 vmargscount,
3282                                                                                 vm_arg *vmargs)
3283 {
3284         java_objectheader *o;
3285
3286         STATISTICS(count_calls_native_to_java++);
3287
3288 #if defined(ENABLE_JIT)
3289 # if defined(ENABLE_INTRP)
3290         if (opt_intrp)
3291                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3292         else
3293 # endif
3294                 o = asm_vm_call_method(m, vmargscount, vmargs);
3295 #else
3296         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3297 #endif
3298
3299         return o;
3300 }
3301 #else
3302 java_objectheader *vm_call_array(methodinfo *m, uint64_t *array)
3303 {
3304         methoddesc        *md;
3305         java_objectheader *o;
3306
3307         md = m->parseddesc;
3308
3309         /* compile the method if not already done */
3310
3311         if (m->code == NULL)
3312                 if (!jit_compile(m))
3313                         return NULL;
3314
3315         STATISTICS(count_calls_native_to_java++);
3316
3317 #if defined(ENABLE_JIT)
3318 # if defined(ENABLE_INTRP)
3319         if (opt_intrp)
3320                 o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3321         else
3322 # endif
3323                 o = asm_vm_call_method(m->code->entrypoint, array, md->memuse);
3324 #else
3325         o = intrp_asm_vm_call_method(m, vmargscount, vmargs);
3326 #endif
3327
3328         return o;
3329 }
3330 #endif
3331
3332
3333 /* vm_call_int_array ***********************************************************
3334
3335    Calls a Java method with a variable number of arguments, passed via
3336    an argument array, and returns an integer (int32_t).
3337
3338 *******************************************************************************/
3339
3340 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3341 s4 vm_call_method_int_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3342 {
3343         s4 i;
3344
3345         STATISTICS(count_calls_native_to_java++);
3346
3347 #if defined(ENABLE_JIT)
3348 # if defined(ENABLE_INTRP)
3349         if (opt_intrp)
3350                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3351         else
3352 # endif
3353                 i = asm_vm_call_method_int(m, vmargscount, vmargs);
3354 #else
3355         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3356 #endif
3357
3358         return i;
3359 }
3360 #else
3361 int32_t vm_call_int_array(methodinfo *m, uint64_t *array)
3362 {
3363         methoddesc *md;
3364         int32_t     i;
3365
3366         md = m->parseddesc;
3367
3368         /* compile the method if not already done */
3369
3370         if (m->code == NULL)
3371                 if (!jit_compile(m))
3372                         return 0;
3373
3374         STATISTICS(count_calls_native_to_java++);
3375
3376 #if defined(ENABLE_JIT)
3377 # if defined(ENABLE_INTRP)
3378         if (opt_intrp)
3379                 i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3380         else
3381 # endif
3382                 i = asm_vm_call_method_int(m->code->entrypoint, array, md->memuse);
3383 #else
3384         i = intrp_asm_vm_call_method_int(m, vmargscount, vmargs);
3385 #endif
3386
3387         return i;
3388 }
3389 #endif
3390
3391
3392 /* vm_call_method_int **********************************************************
3393
3394    Calls a Java method with a variable number of arguments and returns
3395    an integer (s4).
3396
3397 *******************************************************************************/
3398
3399 s4 vm_call_method_int(methodinfo *m, java_objectheader *o, ...)
3400 {
3401         va_list ap;
3402         s4      i;
3403
3404         va_start(ap, o);
3405         i = vm_call_method_int_valist(m, o, ap);
3406         va_end(ap);
3407
3408         return i;
3409 }
3410
3411
3412 /* vm_call_method_int_valist ***************************************************
3413
3414    Calls a Java method with a variable number of arguments, passed via
3415    a va_list, and returns an integer (int32_t).
3416
3417 *******************************************************************************/
3418
3419 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3420 s4 vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3421 {
3422         s4      vmargscount;
3423         vm_arg *vmargs;
3424         s4      i;
3425         s4      dumpsize;
3426
3427         /* mark start of dump memory area */
3428
3429         dumpsize = dump_size();
3430
3431         /* get number of Java method arguments */
3432
3433         vmargscount = m->parseddesc->paramcount;
3434
3435         /* allocate vm_arg array */
3436
3437         vmargs = DMNEW(vm_arg, vmargscount);
3438
3439         /* fill the vm_arg array from a va_list */
3440
3441         vm_vmargs_from_valist(m, o, vmargs, ap);
3442
3443         /* call the Java method */
3444
3445         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3446
3447         /* release dump area */
3448
3449         dump_release(dumpsize);
3450
3451         return i;
3452 }
3453 #else
3454 int32_t vm_call_method_int_valist(methodinfo *m, java_objectheader *o, va_list ap)
3455 {
3456         int32_t   dumpsize;
3457         uint64_t *array;
3458         int32_t   i;
3459
3460         /* mark start of dump memory area */
3461
3462         dumpsize = dump_size();
3463
3464         /* fill the argument array from a va_list */
3465
3466         array = vm_array_from_valist(m, o, ap);
3467
3468         /* call the Java method */
3469
3470         i = vm_call_int_array(m, array);
3471
3472         /* release dump area */
3473
3474         dump_release(dumpsize);
3475
3476         return i;
3477 }
3478 #endif
3479
3480
3481 /* vm_call_method_int_jvalue ***************************************************
3482
3483    Calls a Java method with a variable number of arguments, passed via
3484    a jvalue array, and returns an integer (s4).
3485
3486 *******************************************************************************/
3487
3488 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3489 s4 vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
3490 {
3491         s4      vmargscount;
3492         vm_arg *vmargs;
3493         s4      i;
3494         s4      dumpsize;
3495
3496         /* mark start of dump memory area */
3497
3498         dumpsize = dump_size();
3499
3500         /* get number of Java method arguments */
3501
3502         vmargscount = m->parseddesc->paramcount;
3503
3504         /* allocate vm_arg array */
3505
3506         vmargs = DMNEW(vm_arg, vmargscount);
3507
3508         /* fill the vm_arg array from a va_list */
3509
3510         vm_vmargs_from_jvalue(m, o, vmargs, args);
3511
3512         /* call the Java method */
3513
3514         i = vm_call_method_int_vmarg(m, vmargscount, vmargs);
3515
3516         /* release dump area */
3517
3518         dump_release(dumpsize);
3519
3520         return i;
3521 }
3522 #else
3523 int32_t vm_call_method_int_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
3524 {
3525         int32_t   dumpsize;
3526         uint64_t *array;
3527         int32_t   i;
3528
3529         /* mark start of dump memory area */
3530
3531         dumpsize = dump_size();
3532
3533         /* fill the argument array from a va_list */
3534
3535         array = vm_array_from_jvalue(m, o, args);
3536
3537         /* call the Java method */
3538
3539         i = vm_call_int_array(m, array);
3540
3541         /* release dump area */
3542
3543         dump_release(dumpsize);
3544
3545         return i;
3546 }
3547 #endif
3548
3549
3550 /* vm_call_long_array **********************************************************
3551
3552    Calls a Java method with a variable number of arguments, passed via
3553    an argument array, and returns a long (int64_t).
3554
3555 *******************************************************************************/
3556
3557 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3558 s8 vm_call_method_long_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3559 {
3560         s8 l;
3561
3562         STATISTICS(count_calls_native_to_java++);
3563
3564 #if defined(ENABLE_JIT)
3565 # if defined(ENABLE_INTRP)
3566         if (opt_intrp)
3567                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3568         else
3569 # endif
3570                 l = asm_vm_call_method_long(m, vmargscount, vmargs);
3571 #else
3572         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3573 #endif
3574
3575         return l;
3576 }
3577 #else
3578 int64_t vm_call_long_array(methodinfo *m, uint64_t *array)
3579 {
3580         methoddesc *md;
3581         int64_t     l;
3582
3583         md = m->parseddesc;
3584
3585         /* compile the method if not already done */
3586
3587         if (m->code == NULL)
3588                 if (!jit_compile(m))
3589                         return 0;
3590
3591         STATISTICS(count_calls_native_to_java++);
3592
3593 #if defined(ENABLE_JIT)
3594 # if defined(ENABLE_INTRP)
3595         if (opt_intrp)
3596                 l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3597         else
3598 # endif
3599                 l = asm_vm_call_method_long(m->code->entrypoint, array, md->memuse);
3600 #else
3601         l = intrp_asm_vm_call_method_long(m, vmargscount, vmargs);
3602 #endif
3603
3604         return l;
3605 }
3606 #endif
3607
3608
3609 /* vm_call_method_long *********************************************************
3610
3611    Calls a Java method with a variable number of arguments and returns
3612    a long (s8).
3613
3614 *******************************************************************************/
3615
3616 s8 vm_call_method_long(methodinfo *m, java_objectheader *o, ...)
3617 {
3618         va_list ap;
3619         s8      l;
3620
3621         va_start(ap, o);
3622         l = vm_call_method_long_valist(m, o, ap);
3623         va_end(ap);
3624
3625         return l;
3626 }
3627
3628
3629 /* vm_call_method_long_valist **************************************************
3630
3631    Calls a Java method with a variable number of arguments, passed via
3632    a va_list, and returns a long (s8).
3633
3634 *******************************************************************************/
3635
3636 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3637 s8 vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3638 {
3639         s4      vmargscount;
3640         vm_arg *vmargs;
3641         s8      l;
3642         s4      dumpsize;
3643
3644         /* mark start of dump memory area */
3645
3646         dumpsize = dump_size();
3647
3648         /* get number of Java method arguments */
3649
3650         vmargscount = m->parseddesc->paramcount;
3651
3652         /* allocate vm_arg array */
3653
3654         vmargs = DMNEW(vm_arg, vmargscount);
3655
3656         /* fill the vm_arg array from a va_list */
3657
3658         vm_vmargs_from_valist(m, o, vmargs, ap);
3659
3660         /* call the Java method */
3661
3662         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3663
3664         /* release dump area */
3665
3666         dump_release(dumpsize);
3667
3668         return l;
3669 }
3670 #else
3671 int64_t vm_call_method_long_valist(methodinfo *m, java_objectheader *o, va_list ap)
3672 {
3673         int32_t   dumpsize;
3674         uint64_t *array;
3675         int64_t   l;
3676
3677         /* mark start of dump memory area */
3678
3679         dumpsize = dump_size();
3680
3681         /* fill the argument array from a va_list */
3682
3683         array = vm_array_from_valist(m, o, ap);
3684
3685         /* call the Java method */
3686
3687         l = vm_call_long_array(m, array);
3688
3689         /* release dump area */
3690
3691         dump_release(dumpsize);
3692
3693         return l;
3694 }
3695 #endif
3696
3697
3698 /* vm_call_method_long_jvalue **************************************************
3699
3700    Calls a Java method with a variable number of arguments, passed via
3701    a jvalue array, and returns a long (s8).
3702
3703 *******************************************************************************/
3704
3705 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3706 s8 vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
3707 {
3708         s4      vmargscount;
3709         vm_arg *vmargs;
3710         s8      l;
3711         s4      dumpsize;
3712
3713         /* mark start of dump memory area */
3714
3715         dumpsize = dump_size();
3716
3717         /* get number of Java method arguments */
3718
3719         vmargscount = m->parseddesc->paramcount;
3720
3721         /* allocate vm_arg array */
3722
3723         vmargs = DMNEW(vm_arg, vmargscount);
3724
3725         /* fill the vm_arg array from a va_list */
3726
3727         vm_vmargs_from_jvalue(m, o, vmargs, args);
3728
3729         /* call the Java method */
3730
3731         l = vm_call_method_long_vmarg(m, vmargscount, vmargs);
3732
3733         /* release dump area */
3734
3735         dump_release(dumpsize);
3736
3737         return l;
3738 }
3739 #else
3740 int64_t vm_call_method_long_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
3741 {
3742         int32_t   dumpsize;
3743         uint64_t *array;
3744         int64_t   l;
3745
3746         /* mark start of dump memory area */
3747
3748         dumpsize = dump_size();
3749
3750         /* fill the argument array from a va_list */
3751
3752         array = vm_array_from_jvalue(m, o, args);
3753
3754         /* call the Java method */
3755
3756         l = vm_call_long_array(m, array);
3757
3758         /* release dump area */
3759
3760         dump_release(dumpsize);
3761
3762         return l;
3763 }
3764 #endif
3765
3766
3767 /* vm_call_float_array *********************************************************
3768
3769    Calls a Java method with a variable number of arguments and returns
3770    an float.
3771
3772 *******************************************************************************/
3773
3774 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3775 float vm_call_method_float_vmarg(methodinfo *m, s4 vmargscount, vm_arg *vmargs)
3776 {
3777         float f;
3778
3779         vm_abort("IMPLEMENT ME!");
3780
3781         STATISTICS(count_calls_native_to_java++);
3782
3783 #if defined(ENABLE_JIT)
3784 # if defined(ENABLE_INTRP)
3785         if (opt_intrp)
3786                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3787         else
3788 # endif
3789                 f = asm_vm_call_method_float(m, vmargscount, vmargs);
3790 #else
3791         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3792 #endif
3793
3794         return f;
3795 }
3796 #else
3797 float vm_call_float_array(methodinfo *m, uint64_t *array)
3798 {
3799         methoddesc *md;
3800         float       f;
3801
3802         md = m->parseddesc;
3803
3804         /* compile the method if not already done */
3805
3806         if (m->code == NULL)
3807                 if (!jit_compile(m))
3808                         return 0;
3809
3810         STATISTICS(count_calls_native_to_java++);
3811
3812 #if defined(ENABLE_JIT)
3813 # if defined(ENABLE_INTRP)
3814         if (opt_intrp)
3815                 f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3816         else
3817 # endif
3818                 f = asm_vm_call_method_float(m->code->entrypoint, array, md->memuse);
3819 #else
3820         f = intrp_asm_vm_call_method_float(m, vmargscount, vmargs);
3821 #endif
3822
3823         return f;
3824 }
3825 #endif
3826
3827
3828 /* vm_call_method_float ********************************************************
3829
3830    Calls a Java method with a variable number of arguments and returns
3831    an float.
3832
3833 *******************************************************************************/
3834
3835 float vm_call_method_float(methodinfo *m, java_objectheader *o, ...)
3836 {
3837         va_list ap;
3838         float   f;
3839
3840         va_start(ap, o);
3841         f = vm_call_method_float_valist(m, o, ap);
3842         va_end(ap);
3843
3844         return f;
3845 }
3846
3847
3848 /* vm_call_method_float_valist *************************************************
3849
3850    Calls a Java method with a variable number of arguments, passed via
3851    a va_list, and returns a float.
3852
3853 *******************************************************************************/
3854
3855 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3856 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o,
3857                                                                   va_list ap)
3858 {
3859         s4      vmargscount;
3860         vm_arg *vmargs;
3861         float   f;
3862         s4      dumpsize;
3863
3864         /* mark start of dump memory area */
3865
3866         dumpsize = dump_size();
3867
3868         /* get number of Java method arguments */
3869
3870         vmargscount = m->parseddesc->paramcount;
3871
3872         /* allocate vm_arg array */
3873
3874         vmargs = DMNEW(vm_arg, vmargscount);
3875
3876         /* fill the vm_arg array from a va_list */
3877
3878         vm_vmargs_from_valist(m, o, vmargs, ap);
3879
3880         /* call the Java method */
3881
3882         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
3883
3884         /* release dump area */
3885
3886         dump_release(dumpsize);
3887
3888         return f;
3889 }
3890 #else
3891 float vm_call_method_float_valist(methodinfo *m, java_objectheader *o, va_list ap)
3892 {
3893         int32_t   dumpsize;
3894         uint64_t *array;
3895         float     f;
3896
3897         /* mark start of dump memory area */
3898
3899         dumpsize = dump_size();
3900
3901         /* fill the argument array from a va_list */
3902
3903         array = vm_array_from_valist(m, o, ap);
3904
3905         /* call the Java method */
3906
3907         f = vm_call_float_array(m, array);
3908
3909         /* release dump area */
3910
3911         dump_release(dumpsize);
3912
3913         return f;
3914 }
3915 #endif
3916
3917
3918 /* vm_call_method_float_jvalue *************************************************
3919
3920    Calls a Java method with a variable number of arguments, passed via
3921    a jvalue array, and returns a float.
3922
3923 *******************************************************************************/
3924
3925 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3926 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o,
3927                                                                   jvalue *args)
3928 {
3929         s4      vmargscount;
3930         vm_arg *vmargs;
3931         float   f;
3932         s4      dumpsize;
3933
3934         /* mark start of dump memory area */
3935
3936         dumpsize = dump_size();
3937
3938         /* get number of Java method arguments */
3939
3940         vmargscount = m->parseddesc->paramcount;
3941
3942         /* allocate vm_arg array */
3943
3944         vmargs = DMNEW(vm_arg, vmargscount);
3945
3946         /* fill the vm_arg array from a va_list */
3947
3948         vm_vmargs_from_jvalue(m, o, vmargs, args);
3949
3950         /* call the Java method */
3951
3952         f = vm_call_method_float_vmarg(m, vmargscount, vmargs);
3953
3954         /* release dump area */
3955
3956         dump_release(dumpsize);
3957
3958         return f;
3959 }
3960 #else
3961 float vm_call_method_float_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
3962 {
3963         int32_t   dumpsize;
3964         uint64_t *array;
3965         float     f;
3966
3967         /* mark start of dump memory area */
3968
3969         dumpsize = dump_size();
3970
3971         /* fill the argument array from a va_list */
3972
3973         array = vm_array_from_jvalue(m, o, args);
3974
3975         /* call the Java method */
3976
3977         f = vm_call_float_array(m, array);
3978
3979         /* release dump area */
3980
3981         dump_release(dumpsize);
3982
3983         return f;
3984 }
3985 #endif
3986
3987
3988 /* vm_call_double_array ********************************************************
3989
3990    Calls a Java method with a variable number of arguments and returns
3991    a double.
3992
3993 *******************************************************************************/
3994
3995 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
3996 double vm_call_method_double_vmarg(methodinfo *m, s4 vmargscount,
3997                                                                    vm_arg *vmargs)
3998 {
3999         double d;
4000
4001         vm_abort("IMPLEMENT ME!");
4002
4003         STATISTICS(count_calls_native_to_java++);
4004
4005 #if defined(ENABLE_JIT)
4006 # if defined(ENABLE_INTRP)
4007         if (opt_intrp)
4008                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4009         else
4010 # endif
4011                 d = asm_vm_call_method_double(m, vmargscount, vmargs);
4012 #else
4013         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4014 #endif
4015
4016         return d;
4017 }
4018 #else
4019 double vm_call_double_array(methodinfo *m, uint64_t *array)
4020 {
4021         methoddesc *md;
4022         double      d;
4023
4024         md = m->parseddesc;
4025
4026         /* compile the method if not already done */
4027
4028         if (m->code == NULL)
4029                 if (!jit_compile(m))
4030                         return 0;
4031
4032         STATISTICS(count_calls_native_to_java++);
4033
4034 #if defined(ENABLE_JIT)
4035 # if defined(ENABLE_INTRP)
4036         if (opt_intrp)
4037                 d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4038         else
4039 # endif
4040                 d = asm_vm_call_method_double(m->code->entrypoint, array, md->memuse);
4041 #else
4042         d = intrp_asm_vm_call_method_double(m, vmargscount, vmargs);
4043 #endif
4044
4045         return d;
4046 }
4047 #endif
4048
4049
4050 /* vm_call_method_double *******************************************************
4051
4052    Calls a Java method with a variable number of arguments and returns
4053    a double.
4054
4055 *******************************************************************************/
4056
4057 double vm_call_method_double(methodinfo *m, java_objectheader *o, ...)
4058 {
4059         va_list ap;
4060         double  d;
4061
4062         va_start(ap, o);
4063         d = vm_call_method_double_valist(m, o, ap);
4064         va_end(ap);
4065
4066         return d;
4067 }
4068
4069
4070 /* vm_call_method_double_valist ************************************************
4071
4072    Calls a Java method with a variable number of arguments, passed via
4073    a va_list, and returns a double.
4074
4075 *******************************************************************************/
4076
4077 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
4078 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o,
4079                                                                         va_list ap)
4080 {
4081         s4      vmargscount;
4082         vm_arg *vmargs;
4083         double  d;
4084         s4      dumpsize;
4085
4086         /* mark start of dump memory area */
4087
4088         dumpsize = dump_size();
4089
4090         /* get number of Java method arguments */
4091
4092         vmargscount = m->parseddesc->paramcount;
4093
4094         /* allocate vm_arg array */
4095
4096         vmargs = DMNEW(vm_arg, vmargscount);
4097
4098         /* fill the vm_arg array from a va_list */
4099
4100         vm_vmargs_from_valist(m, o, vmargs, ap);
4101
4102         /* call the Java method */
4103
4104         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4105
4106         /* release dump area */
4107
4108         dump_release(dumpsize);
4109
4110         return d;
4111 }
4112 #else
4113 double vm_call_method_double_valist(methodinfo *m, java_objectheader *o, va_list ap)
4114 {
4115         int32_t   dumpsize;
4116         uint64_t *array;
4117         double    d;
4118
4119         /* mark start of dump memory area */
4120
4121         dumpsize = dump_size();
4122
4123         /* fill the argument array from a va_list */
4124
4125         array = vm_array_from_valist(m, o, ap);
4126
4127         /* call the Java method */
4128
4129         d = vm_call_double_array(m, array);
4130
4131         /* release dump area */
4132
4133         dump_release(dumpsize);
4134
4135         return d;
4136 }
4137 #endif
4138
4139
4140 /* vm_call_method_double_jvalue ************************************************
4141
4142    Calls a Java method with a variable number of arguments, passed via
4143    a jvalue array, and returns a double.
4144
4145 *******************************************************************************/
4146
4147 #if !defined(__MIPS__) && !defined(__X86_64__) && !defined(__POWERPC64__)
4148 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o,
4149                                                                         jvalue *args)
4150 {
4151         s4      vmargscount;
4152         vm_arg *vmargs;
4153         double  d;
4154         s4      dumpsize;
4155
4156         /* mark start of dump memory area */
4157
4158         dumpsize = dump_size();
4159
4160         /* get number of Java method arguments */
4161
4162         vmargscount = m->parseddesc->paramcount;
4163
4164         /* allocate vm_arg array */
4165
4166         vmargs = DMNEW(vm_arg, vmargscount);
4167
4168         /* fill the vm_arg array from a va_list */
4169
4170         vm_vmargs_from_jvalue(m, o, vmargs, args);
4171
4172         /* call the Java method */
4173
4174         d = vm_call_method_double_vmarg(m, vmargscount, vmargs);
4175
4176         /* release dump area */
4177
4178         dump_release(dumpsize);
4179
4180         return d;
4181 }
4182 #else
4183 double vm_call_method_double_jvalue(methodinfo *m, java_objectheader *o, jvalue *args)
4184 {
4185         int32_t   dumpsize;
4186         uint64_t *array;
4187         double    d;
4188
4189         /* mark start of dump memory area */
4190
4191         dumpsize = dump_size();
4192
4193         /* fill the argument array from a va_list */
4194
4195         array = vm_array_from_jvalue(m, o, args);
4196
4197         /* call the Java method */
4198
4199         d = vm_call_double_array(m, array);
4200
4201         /* release dump area */
4202
4203         dump_release(dumpsize);
4204
4205         return d;
4206 }
4207 #endif
4208
4209
4210 /*
4211  * These are local overrides for various environment variables in Emacs.
4212  * Please do not remove this and leave it at the end of the file, where
4213  * Emacs will automagically detect them.
4214  * ---------------------------------------------------------------------
4215  * Local variables:
4216  * mode: c
4217  * indent-tabs-mode: t
4218  * c-basic-offset: 4
4219  * tab-width: 4
4220  * End:
4221  */