1 /* src/cacao/cacao.c - contains main() of cacao
3 Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4 C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5 E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6 J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@cacaojvm.org
27 Authors: Reinhard Grafl
34 $Id: cacao.c 4552 2006-03-04 17:15:44Z twisti $
48 #include "mm/memory.h"
49 #include "native/jni.h"
50 #include "native/include/java_lang_String.h"
52 #if defined(ENABLE_JVMTI)
53 #include "native/jvmti/jvmti.h"
54 #include "native/jvmti/dbg.h"
55 #include <sys/types.h>
60 #include "toolbox/logging.h"
61 #include "vm/classcache.h"
62 #include "vm/exceptions.h"
63 #include "vm/global.h"
64 #include "vm/loader.h"
65 #include "vm/options.h"
66 #include "vm/statistics.h"
67 #include "vm/stringlocal.h"
70 #include "vm/jit/asmpart.h"
71 #include "vm/jit/jit.h"
73 #ifdef TYPEINFO_DEBUG_TEST
74 #include "vm/jit/verify/typeinfo.h"
78 #ifdef TYPECHECK_STATISTICS
79 void typecheck_print_statistics(FILE *file);
82 /* setup_debugger_process *****************************************************
84 Helper function to start JDWP threads
86 *******************************************************************************/
87 #if defined(ENABLE_JVMTI)
89 static void setup_debugger_process(char* transport) {
94 /* new gnu.classpath.jdwp.Jdwp() */
96 load_class_from_sysloader(utf_new_char("gnu.classpath.jdwp.Jdwp"));
98 throw_main_exception_exit();
100 o = builtin_new(mainclass);
103 throw_main_exception_exit();
105 m = class_resolveclassmethod(mainclass,
107 utf_java_lang_String__void,
108 class_java_lang_Object,
111 throw_main_exception_exit();
113 (void) vm_call_method_intern(m, o, NULL, NULL, NULL);
115 /* configure(transport,NULL) */
116 m = class_resolveclassmethod(
117 mainclass, utf_new_char("configure"),
118 utf_new_char("(Ljava/lang/String;Ljava/lang/Thread;)V"),
119 class_java_lang_Object,
123 s = javastring_new_char(transport);
125 (void) vm_call_method_intern(m, o, s, NULL, NULL);
128 throw_main_exception_exit();
130 /* _doInitialization */
131 m = class_resolveclassmethod(mainclass,
132 utf_new_char("_doInitialization"),
138 throw_main_exception_exit();
140 (void) vm_call_method_intern(m, o, NULL, NULL, NULL);
145 /* getmainclassfromjar *********************************************************
147 Gets the name of the main class form a JAR's manifest file.
149 *******************************************************************************/
151 static char *getmainclassnamefromjar(char *mainstring)
154 java_objectheader *o;
158 c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
161 throw_main_exception_exit();
163 /* create JarFile object */
168 throw_main_exception_exit();
171 m = class_resolveclassmethod(c,
173 utf_java_lang_String__void,
174 class_java_lang_Object,
178 throw_main_exception_exit();
180 s = javastring_new_char(mainstring);
182 (void) vm_call_method_intern(m, o, s, NULL, NULL);
185 throw_main_exception_exit();
187 /* get manifest object */
189 m = class_resolveclassmethod(c,
190 utf_new_char("getManifest"),
191 utf_new_char("()Ljava/util/jar/Manifest;"),
192 class_java_lang_Object,
196 throw_main_exception_exit();
198 o = vm_call_method_intern(m, o, NULL, NULL, NULL);
201 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
206 /* get Main Attributes */
208 m = class_resolveclassmethod(o->vftbl->class,
209 utf_new_char("getMainAttributes"),
210 utf_new_char("()Ljava/util/jar/Attributes;"),
211 class_java_lang_Object,
215 throw_main_exception_exit();
217 o = vm_call_method_intern(m, o, NULL, NULL, NULL);
220 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
225 /* get property Main-Class */
227 m = class_resolveclassmethod(o->vftbl->class,
228 utf_new_char("getValue"),
229 utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
230 class_java_lang_Object,
234 throw_main_exception_exit();
236 s = javastring_new_char("Main-Class");
238 o = vm_call_method_intern(m, o, s, NULL, NULL);
241 throw_main_exception_exit();
243 return javastring_tochar(o);
247 void exit_handler(void);
250 /* main ************************************************************************
254 *******************************************************************************/
256 int main(int argc, char **argv)
261 /* local variables ********************************************************/
263 JavaVMInitArgs *vm_args;
264 JavaVM *jvm; /* denotes a Java VM */
266 #if defined(ENABLE_JVMTI)
272 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
273 stackbottom = &dummy;
276 if (atexit(vm_exit_handler))
277 throw_cacao_exception_exit(string_java_lang_InternalError,
278 "Unable to register exit_handler");
281 /**************************** Program start *****************************/
284 log_text("CACAO started -------------------------------------------------------");
286 /* prepare the options */
288 vm_args = options_prepare(argc, argv);
290 /* load and initialize a Java VM, return a JNI interface pointer in env */
292 JNI_CreateJavaVM(&jvm, (void **) &_Jv_env, vm_args);
294 #if defined(ENABLE_JVMTI)
295 set_jvmti_phase(JVMTI_PHASE_START);
298 /* do we have a main class? */
300 if (mainstring == NULL)
304 /* start worker routines **************************************************/
306 if (opt_run == true) {
308 classinfo *mainclass;
310 java_objectarray *oa;
315 /* set return value to OK */
319 if (opt_jar == true) {
320 /* open jar file with java.util.jar.JarFile */
321 mainstring = getmainclassnamefromjar(mainstring);
324 /* load the main class */
326 mainutf = utf_new_char(mainstring);
328 if (!(mainclass = load_class_from_sysloader(mainutf)))
329 throw_main_exception_exit();
331 /* error loading class, clear exceptionptr for new exception */
333 if (*exceptionptr || !mainclass) {
334 /* *exceptionptr = NULL; */
336 /* *exceptionptr = */
337 /* new_exception_message(string_java_lang_NoClassDefFoundError, */
339 throw_main_exception_exit();
342 if (!link_class(mainclass))
343 throw_main_exception_exit();
345 /* find the `main' method of the main class */
347 m = class_resolveclassmethod(mainclass,
348 utf_new_char("main"),
349 utf_new_char("([Ljava/lang/String;)V"),
350 class_java_lang_Object,
354 throw_main_exception_exit();
357 /* there is no main method or it isn't static */
359 if (!m || !(m->flags & ACC_STATIC)) {
360 *exceptionptr = NULL;
363 new_exception_message(string_java_lang_NoSuchMethodError,
365 throw_main_exception_exit();
368 /* build argument array */
370 oalength = vm_args->nOptions - opt_index;
372 oa = builtin_anewarray(oalength, class_java_lang_String);
374 for (i = 0; i < oalength; i++) {
375 s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString));
376 oa->data[i] = (java_objectheader *) s;
379 #ifdef TYPEINFO_DEBUG_TEST
380 /* test the typeinfo system */
383 /*class_showmethods(currentThread->group->header.vftbl->class); */
385 #if defined(ENABLE_JVMTI) && defined(NATIVE_THREADS)
388 if (debuggee == (-1)) {
389 log_text("fork error");
393 /* child: allow helper process to trace us */
394 if (TRACEME != 0) exit(0);
396 /* give parent/helper debugger process control */
397 kill(0, SIGTRAP); /* do we need this at this stage ? */
399 /* continue with normal startup */
403 /* parent/helper debugger process */
406 remotedbgjvmtienv = new_jvmtienv();
407 /* set eventcallbacks */
408 if (JVMTI_ERROR_NONE ==
410 SetEventCallbacks(remotedbgjvmtienv,
411 &jvmti_jdwp_EventCallbacks,
412 sizeof(jvmti_jdwp_EventCallbacks))){
413 log_text("unable to setup event callbacks");
417 /* setup listening process (JDWP) */
418 setup_debugger_process(transport);
420 /* start to be debugged program */
423 /* exit debugger process - todo: cleanup */
435 (void) vm_call_method_intern(m, oa, NULL, NULL, NULL);
437 /* exception occurred? */
440 throw_main_exception();
444 /* unload the JavaVM */
453 /************* If requested, compile all methods ********************/
460 classcache_name_entry *nmen;
461 classcache_class_entry *clsen;
463 /* create all classes found in the bootclasspath */
464 /* XXX currently only works with zip/jar's */
466 loader_load_all_classes();
468 /* link all classes */
470 for (slot = 0; slot < hashtable_classcache.size; slot++) {
471 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
473 for (; nmen; nmen = nmen->hashlink) {
474 /* iterate over all class entries */
476 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
482 if (!(c->state & CLASS_LINKED)) {
483 if (!link_class(c)) {
484 fprintf(stderr, "Error linking: ");
485 utf_fprint_classname(stderr, c->name);
486 fprintf(stderr, "\n");
488 /* print out exception and cause */
490 exceptions_print_exception(*exceptionptr);
492 /* goto next class */
498 /* compile all class methods */
500 for (i = 0; i < c->methodscount; i++) {
501 m = &(c->methods[i]);
504 if (!jit_compile(m)) {
505 fprintf(stderr, "Error compiling: ");
506 utf_fprint_classname(stderr, c->name);
507 fprintf(stderr, ".");
508 utf_fprint(stderr, m->name);
509 utf_fprint(stderr, m->descriptor);
510 fprintf(stderr, "\n");
512 /* print out exception and cause */
514 exceptions_print_exception(*exceptionptr);
524 /******** If requested, compile a specific method ***************/
526 if (opt_method != NULL) {
529 /* create, load and link the main class */
531 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
532 throw_main_exception_exit();
534 if (!link_class(mainclass))
535 throw_main_exception_exit();
537 if (opt_signature != NULL) {
538 m = class_resolveclassmethod(mainclass,
539 utf_new_char(opt_method),
540 utf_new_char(opt_signature),
544 m = class_resolveclassmethod(mainclass,
545 utf_new_char(opt_method),
552 char message[MAXLOGTEXT];
553 sprintf(message, "%s%s", opt_method,
554 opt_signature ? opt_signature : "");
557 new_exception_message(string_java_lang_NoSuchMethodException,
560 throw_main_exception_exit();
568 /* keep compiler happy */
575 * These are local overrides for various environment variables in Emacs.
576 * Please do not remove this and leave it at the end of the file, where
577 * Emacs will automagically detect them.
578 * ---------------------------------------------------------------------
581 * indent-tabs-mode: t