Fix LDC, LDC_W, and INSTANCEOF opcodes, more debugging
[jamvm-avr32-jem.git] / src / jam.c
blobd2b7227cb6d4d4099a14714ece2b5a515124cdd1
1 /*
2 * Copyright (C) 2003, 2004, 2005, 2006, 2007
3 * Robert Lougher <rob@lougher.org.uk>.
5 * This file is part of JamVM.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22 #include <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
27 #include "jam.h"
28 #include "class.h"
30 #ifdef USE_ZIP
31 #define BCP_MESSAGE "<jar/zip files and directories separated by :>"
32 #else
33 #define BCP_MESSAGE "<directories separated by :>"
34 #endif
36 void showNonStandardOptions() {
37 printf(" -Xbootclasspath:%s\n", BCP_MESSAGE);
38 printf("\t\t locations where to find the system classes\n");
39 printf(" -Xbootclasspath/a:%s\n", BCP_MESSAGE);
40 printf("\t\t locations are appended to the bootstrap class path\n");
41 printf(" -Xbootclasspath/p:%s\n", BCP_MESSAGE);
42 printf("\t\t locations are prepended to the bootstrap class path\n");
43 printf(" -Xbootclasspath/c:%s\n", BCP_MESSAGE);
44 printf("\t\t locations where to find Classpath's classes\n");
45 printf(" -Xbootclasspath/v:%s\n", BCP_MESSAGE);
46 printf("\t\t locations where to find JamVM's classes\n");
47 printf(" -Xnoasyncgc\t turn off asynchronous garbage collection\n");
48 printf(" -Xcompactalways always compact the heap when garbage-collecting\n");
49 printf(" -Xnocompact\t turn off heap-compaction\n");
50 #ifdef INLINING
51 printf(" -Xnoinlining\t turn off interpreter inlining\n");
52 printf(" -Xshowreloc\t show opcode relocatability\n");
53 printf(" -Xreplication:[none|always|<value>]\n");
54 printf("\t\t none : always re-use super-instructions\n");
55 printf("\t\t always : never re-use super-instructions\n");
56 printf("\t\t <value> copy when usage reaches threshold value\n");
57 printf(" -Xcodemem:[unlimited|<size>] (default maximum heapsize/4)\n");
58 #endif
59 printf(" -Xms<size>\t set the initial size of the heap (default = %dM)\n", DEFAULT_MIN_HEAP/MB);
60 printf(" -Xmx<size>\t set the maximum size of the heap (default = %dM)\n", DEFAULT_MAX_HEAP/MB);
61 printf(" -Xss<size>\t set the Java stack size for each thread (default = %dK)\n", DEFAULT_STACK/KB);
62 printf("\t\t size may be followed by K,k or M,m (e.g. 2M)\n");
65 void showUsage(char *name) {
66 printf("Usage: %s [-options] class [arg1 arg2 ...]\n", name);
67 printf(" (to run a class file)\n");
68 printf(" or %s [-options] -jar jarfile [arg1 arg2 ...]\n", name);
69 printf(" (to run a standalone jar file)\n");
70 printf("\nwhere options include:\n");
71 printf(" -help\t\t print out this message\n");
72 printf(" -version\t print out version number and copyright information\n");
73 printf(" -showversion show version number and copyright and continue\n");
74 printf(" -fullversion show jpackage-compatible version number and exit\n");
75 printf(" -cp -classpath <jar/zip files and directories separated by :>\n");
76 printf("\t\t locations where to find application classes\n");
77 printf(" -verbose[:class|gc|jni]\n");
78 printf("\t\t :class print out information about class loading, etc.\n");
79 printf("\t\t :gc print out results of garbage collection\n");
80 printf("\t\t :jni print out native method dynamic resolution\n");
81 printf(" -D<name>=<value> set a system property\n");
82 printf(" -X\t\t show help on non-standard options\n");
85 void showVersionAndCopyright() {
86 printf("java version \"%s\"\n", JAVA_COMPAT_VERSION);
87 printf("JamVM version %s\n", VERSION);
88 printf("Copyright (C) 2003-2007 Robert Lougher <rob@lougher.org.uk>\n\n");
89 printf("This program is free software; you can redistribute it and/or\n");
90 printf("modify it under the terms of the GNU General Public License\n");
91 printf("as published by the Free Software Foundation; either version 2,\n");
92 printf("or (at your option) any later version.\n\n");
93 printf("This program is distributed in the hope that it will be useful,\n");
94 printf("but WITHOUT ANY WARRANTY; without even the implied warranty of\n");
95 printf("MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n");
96 printf("GNU General Public License for more details.\n");
98 printf("\nBuild information:\n\nExecution Engine: ");
100 #ifdef THREADED
101 #ifdef DIRECT
102 #ifdef INLINING
103 printf("inline-");
104 #else /* INLINING */
105 printf("direct-");
106 #endif /* INLINING */
107 #endif /* DIRECT */
108 printf("threaded interpreter");
109 #ifdef USE_CACHE
110 printf(" with stack-caching\n");
111 #else /* USE_CACHE*/
112 printf("\n");
113 #endif /* USE_CACHE */
114 #else /* THREADED */
115 printf("switch-based interpreter\n");
116 #endif /*THREADED */
118 #if defined(__GNUC__) && defined(__VERSION__)
119 printf("Compiled with: gcc %s\n", __VERSION__);
120 #endif
122 printf("\nBoot Library Path: %s\n", getBootDllPath());
123 printf("Boot Class Path: %s\n", DFLT_BCP);
126 void showFullVersion() {
127 printf("java full version \"jamvm-%s\"\n", JAVA_COMPAT_VERSION);
130 int parseCommandLine(int argc, char *argv[], InitArgs *args) {
131 int is_jar = FALSE;
132 int status = 1;
133 int i;
135 Property props[argc-1];
136 int props_count = 0;
138 for(i = 1; i < argc; i++) {
139 if(*argv[i] != '-') {
140 if(args->min_heap > args->max_heap) {
141 printf("Minimum heap size greater than max!\n");
142 goto exit;
145 if((args->props_count = props_count)) {
146 args->commandline_props = (Property*)sysMalloc(props_count * sizeof(Property));
147 memcpy(args->commandline_props, &props[0], props_count * sizeof(Property));
150 if(is_jar) {
151 args->classpath = argv[i];
152 argv[i] = "jamvm/java/lang/JarLauncher";
155 return i;
158 if(strcmp(argv[i], "-help") == 0) {
159 status = 0;
160 break;
162 } else if(strcmp(argv[i], "-X") == 0) {
163 showNonStandardOptions();
164 status = 0;
165 goto exit;
167 } else if(strcmp(argv[i], "-version") == 0) {
168 showVersionAndCopyright();
169 status = 0;
170 goto exit;
172 } else if(strcmp(argv[i], "-showversion") == 0) {
173 showVersionAndCopyright();
175 } else if(strcmp(argv[i], "-fullversion") == 0) {
176 showFullVersion();
177 status = 0;
178 goto exit;
180 } else if(strncmp(argv[i], "-verbose", 8) == 0) {
181 char *type = &argv[i][8];
183 if(*type == '\0' || strcmp(type, ":class") == 0)
184 args->verboseclass = TRUE;
186 else if(strcmp(type, ":gc") == 0 || strcmp(type, "gc") == 0)
187 args->verbosegc = TRUE;
189 else if(strcmp(type, ":jni") == 0)
190 args->verbosedll = TRUE;
192 } else if(strcmp(argv[i], "-Xnoasyncgc") == 0)
193 args->noasyncgc = TRUE;
195 else if(strncmp(argv[i], "-ms", 3) == 0 || strncmp(argv[i], "-Xms", 4) == 0) {
196 args->min_heap = parseMemValue(argv[i] + (argv[i][1] == 'm' ? 3 : 4));
197 if(args->min_heap < MIN_HEAP) {
198 printf("Invalid minimum heap size: %s (min %dK)\n", argv[i], MIN_HEAP/KB);
199 goto exit;
202 } else if(strncmp(argv[i], "-mx", 3) == 0 || strncmp(argv[i], "-Xmx", 4) == 0) {
203 args->max_heap = parseMemValue(argv[i] + (argv[i][1] == 'm' ? 3 : 4));
204 if(args->max_heap < MIN_HEAP) {
205 printf("Invalid maximum heap size: %s (min is %dK)\n", argv[i], MIN_HEAP/KB);
206 goto exit;
209 } else if(strncmp(argv[i], "-ss", 3) == 0 || strncmp(argv[i], "-Xss", 4) == 0) {
210 args->java_stack = parseMemValue(argv[i] + (argv[i][1] == 's' ? 3 : 4));
211 if(args->java_stack < MIN_STACK) {
212 printf("Invalid Java stack size: %s (min is %dK)\n", argv[i], MIN_STACK/KB);
213 goto exit;
216 } else if(strncmp(argv[i], "-D", 2) == 0) {
217 char *pntr, *key = strcpy(sysMalloc(strlen(argv[i]+2) + 1), argv[i]+2);
218 for(pntr = key; *pntr && (*pntr != '='); pntr++);
219 if(*pntr)
220 *pntr++ = '\0';
221 props[props_count].key = key;
222 props[props_count++].value = pntr;
224 } else if(strcmp(argv[i], "-classpath") == 0 || strcmp(argv[i], "-cp") == 0) {
226 if(i == (argc-1)) {
227 printf("%s : missing path list\n", argv[i]);
228 goto exit;
230 args->classpath = argv[++i];
232 } else if(strncmp(argv[i], "-Xbootclasspath:", 16) == 0) {
234 args->bootpathopt = '\0';
235 args->bootpath = argv[i] + 16;
237 } else if(strncmp(argv[i], "-Xbootclasspath/a:", 18) == 0 ||
238 strncmp(argv[i], "-Xbootclasspath/p:", 18) == 0 ||
239 strncmp(argv[i], "-Xbootclasspath/c:", 18) == 0 ||
240 strncmp(argv[i], "-Xbootclasspath/v:", 18) == 0) {
242 args->bootpathopt = argv[i][16];
243 args->bootpath = argv[i] + 18;
245 } else if(strcmp(argv[i], "-jar") == 0) {
246 is_jar = TRUE;
248 } else if(strcmp(argv[i], "-Xnocompact") == 0) {
249 args->compact_specified = TRUE;
250 args->do_compact = FALSE;
252 } else if(strcmp(argv[i], "-Xcompactalways") == 0) {
253 args->compact_specified = args->do_compact = TRUE;
254 #ifdef INLINING
255 } else if(strcmp(argv[i], "-Xnoinlining") == 0) {
256 /* Turning inlining off is equivalent to setting
257 code memory to zero */
258 args->codemem = 0;
260 } else if(strncmp(argv[i], "-Xreplication:", 14) == 0) {
261 char *pntr = argv[i] + 14;
263 if(strcmp(pntr, "none") == 0)
264 args->replication = INT_MAX;
265 else
266 if(strcmp(pntr, "always") == 0)
267 args->replication = 0;
268 else
269 args->replication = strtol(pntr, NULL, 0);
271 } else if(strncmp(argv[i], "-Xcodemem:", 10) == 0) {
272 char *pntr = argv[i] + 10;
274 args->codemem = strncmp(pntr, "unlimited", 10) == 0 ?
275 INT_MAX : parseMemValue(pntr);
277 } else if(strcmp(argv[i], "-Xshowreloc") == 0) {
278 showRelocatability();
279 status = 0;
280 goto exit;
281 #endif
282 } else {
283 printf("Unrecognised command line option: %s\n", argv[i]);
284 break;
288 showUsage(argv[0]);
290 exit:
291 exit(status);
294 int main(int argc, char *argv[]) {
295 Class *array_class, *main_class;
296 Object *system_loader, *array;
297 MethodBlock *mb;
298 InitArgs args;
299 int class_arg;
300 char *cpntr;
301 int status;
302 int i;
304 setDefaultInitArgs(&args);
305 class_arg = parseCommandLine(argc, argv, &args);
307 args.main_stack_base = &array_class;
308 initVM(&args);
310 if((system_loader = getSystemClassLoader()) == NULL) {
311 printf("Cannot create system class loader\n");
312 printException();
313 exitVM(1);
316 mainThreadSetContextClassLoader(system_loader);
318 for(cpntr = argv[class_arg]; *cpntr; cpntr++)
319 if(*cpntr == '.')
320 *cpntr = '/';
322 if((main_class = findClassFromClassLoader(argv[class_arg], system_loader)) != NULL)
323 initClass(main_class);
325 if(exceptionOccurred()) {
326 printException();
327 exitVM(1);
330 mb = lookupMethod(main_class, "main", "([Ljava/lang/String;)V");
331 if(!mb || !(mb->access_flags & ACC_STATIC)) {
332 printf("Static method \"main\" not found in %s\n", argv[class_arg]);
333 exitVM(1);
336 /* Create the String array holding the command line args */
338 i = class_arg + 1;
339 if((array_class = findArrayClass("[Ljava/lang/String;")) &&
340 (array = allocArray(array_class, argc - i, sizeof(Object*)))) {
341 Object **args = (Object**)ARRAY_DATA(array) - i;
343 for(; i < argc; i++)
344 if(!(args[i] = Cstr2String(argv[i])))
345 break;
346 #if defined(JEM) && !JAM_ON_STACK
347 else
348 args[i] = (Object*)INST_DATA(args[i]);
349 #endif
351 /* Call the main method */
352 if(i == argc)
353 executeStaticMethod(main_class, mb, array);
356 /* ExceptionOccurred returns the exception or NULL, which is OK
357 for normal conditionals, but not here... */
358 if((status = exceptionOccurred() ? 1 : 0))
359 printException();
361 /* Wait for all but daemon threads to die */
362 mainThreadWaitToExitVM();
363 exitVM(status);