* src/cacao/cacao.c (main): remove debug code
[cacao.git] / src / cacao / cacao.c
1 /* src/cacao/cacao.c - contains main() of cacao
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Reinhard Grafl
28
29    Changes: Andi Krall
30             Mark Probst
31             Philipp Tomsich
32             Christian Thalinger
33
34    $Id: cacao.c 4688 2006-03-24 11:50:00Z motse $
35
36 */
37
38
39 #include "config.h"
40
41 #include <assert.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include "vm/types.h"
46
47 #include "native/jni.h"
48 #include "native/include/java_lang_String.h"
49
50 #if defined(ENABLE_JVMTI)
51 #include "native/jvmti/jvmti.h"
52 #include "native/jvmti/cacaodbg.h"
53 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
54 #include <pthread.h>
55 #endif
56 #endif
57
58 #include "toolbox/logging.h"
59 #include "vm/classcache.h"
60 #include "vm/exceptions.h"
61 #include "vm/global.h"
62 #include "vm/loader.h"
63 #include "vm/options.h"
64 #include "vm/statistics.h"
65 #include "vm/stringlocal.h"
66 #include "vm/suck.h"
67 #include "vm/vm.h"
68 #include "vm/jit/asmpart.h"
69 #include "vm/jit/jit.h"
70
71 #ifdef TYPEINFO_DEBUG_TEST
72 #include "vm/jit/verify/typeinfo.h"
73 #endif
74
75 #ifdef TYPECHECK_STATISTICS
76 void typecheck_print_statistics(FILE *file);
77 #endif
78
79 /* getmainclassfromjar *********************************************************
80
81    Gets the name of the main class form a JAR's manifest file.
82
83 *******************************************************************************/
84
85 static char *getmainclassnamefromjar(char *mainstring)
86 {
87         classinfo         *c;
88         java_objectheader *o;
89         methodinfo        *m;
90         java_lang_String  *s;
91
92         c = load_class_from_sysloader(utf_new_char("java/util/jar/JarFile"));
93
94         if (!c)
95                 throw_main_exception_exit();
96         
97         /* create JarFile object */
98
99         o = builtin_new(c);
100
101         if (!o)
102                 throw_main_exception_exit();
103
104
105         m = class_resolveclassmethod(c,
106                                                                  utf_init, 
107                                                                  utf_java_lang_String__void,
108                                                                  class_java_lang_Object,
109                                                                  true);
110
111         if (!m)
112                 throw_main_exception_exit();
113
114         s = javastring_new_char(mainstring);
115
116         (void) vm_call_method(m, o, s);
117
118         if (*exceptionptr)
119                 throw_main_exception_exit();
120
121         /* get manifest object */
122
123         m = class_resolveclassmethod(c,
124                                                                  utf_new_char("getManifest"), 
125                                                                  utf_new_char("()Ljava/util/jar/Manifest;"),
126                                                                  class_java_lang_Object,
127                                                                  true);
128
129         if (!m)
130                 throw_main_exception_exit();
131
132         o = vm_call_method(m, o);
133
134         if (o == NULL) {
135                 fprintf(stderr, "Could not get manifest from %s (invalid or corrupt jarfile?)\n", mainstring);
136                 vm_exit(1);
137         }
138
139
140         /* get Main Attributes */
141
142         m = class_resolveclassmethod(o->vftbl->class,
143                                                                  utf_new_char("getMainAttributes"), 
144                                                                  utf_new_char("()Ljava/util/jar/Attributes;"),
145                                                                  class_java_lang_Object,
146                                                                  true);
147
148         if (!m)
149                 throw_main_exception_exit();
150
151         o = vm_call_method(m, o);
152
153         if (o == NULL) {
154                 fprintf(stderr, "Could not get main attributes from %s (invalid or corrupt jarfile?)\n", mainstring);
155                 vm_exit(1);
156         }
157
158
159         /* get property Main-Class */
160
161         m = class_resolveclassmethod(o->vftbl->class,
162                                                                  utf_new_char("getValue"), 
163                                                                  utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"),
164                                                                  class_java_lang_Object,
165                                                                  true);
166
167         if (!m)
168                 throw_main_exception_exit();
169
170         s = javastring_new_char("Main-Class");
171
172         o = vm_call_method(m, o, s);
173
174         if (!o)
175                 throw_main_exception_exit();
176
177         return javastring_tochar(o);
178 }
179
180 void exit_handler(void);
181
182
183 /* main ************************************************************************
184
185    The main program.
186    
187 *******************************************************************************/
188
189 int main(int argc, char **argv)
190 {
191 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
192         void *dummy;
193 #endif
194         s4 i;
195         
196         /* local variables ********************************************************/
197
198         JavaVMInitArgs *vm_args;
199         JavaVM         *jvm;                /* denotes a Java VM                  */
200
201
202 #if defined(USE_THREADS) && !defined(NATIVE_THREADS)
203         stackbottom = &dummy;
204 #endif
205         
206         if (atexit(vm_exit_handler))
207                 throw_cacao_exception_exit(string_java_lang_InternalError,
208                                                                    "Unable to register exit_handler");
209
210
211         /**************************** Program start *****************************/
212
213         if (opt_verbose)
214                 log_text("CACAO started -------------------------------------------------------");
215
216         /* prepare the options */
217
218         vm_args = options_prepare(argc, argv);
219         
220         /* load and initialize a Java VM, return a JNI interface pointer in env */
221
222         JNI_CreateJavaVM(&jvm, (void **) &_Jv_env, vm_args);
223
224 #if defined(ENABLE_JVMTI)
225         if (dbgprocess && jvmti && jdwp) /* is this the parent/debugger process ? */
226                 set_jvmti_phase(JVMTI_PHASE_START);
227 #endif
228
229         /* do we have a main class? */
230
231         if (mainstring == NULL)
232                 usage();
233
234
235         /* start worker routines **************************************************/
236
237         if (opt_run == true) {
238                 utf              *mainutf;
239                 classinfo        *mainclass;
240                 methodinfo       *m;
241                 java_objectarray *oa; 
242                 s4                oalength;
243                 java_lang_String *s;
244                 s4                status;
245
246                 /* set return value to OK */
247
248                 status = 0;
249
250                 if (opt_jar == true) {
251                         /* open jar file with java.util.jar.JarFile */
252                         mainstring = getmainclassnamefromjar(mainstring);
253                 }
254
255                 /* load the main class */
256
257                 mainutf = utf_new_char(mainstring);
258
259                 if (!(mainclass = load_class_from_sysloader(mainutf)))
260                         throw_main_exception_exit();
261
262                 /* error loading class, clear exceptionptr for new exception */
263
264                 if (*exceptionptr || !mainclass) {
265 /*                      *exceptionptr = NULL; */
266
267 /*                      *exceptionptr = */
268 /*                              new_exception_message(string_java_lang_NoClassDefFoundError, */
269 /*                                                                        mainstring); */
270                         throw_main_exception_exit();
271                 }
272
273                 if (!link_class(mainclass))
274                         throw_main_exception_exit();
275                         
276                 /* find the `main' method of the main class */
277
278                 m = class_resolveclassmethod(mainclass,
279                                                                          utf_new_char("main"), 
280                                                                          utf_new_char("([Ljava/lang/String;)V"),
281                                                                          class_java_lang_Object,
282                                                                          false);
283
284                 if (*exceptionptr) {
285                         throw_main_exception_exit();
286                 }
287
288                 /* there is no main method or it isn't static */
289
290                 if (!m || !(m->flags & ACC_STATIC)) {
291                         *exceptionptr = NULL;
292
293                         *exceptionptr =
294                                 new_exception_message(string_java_lang_NoSuchMethodError,
295                                                                           "main");
296                         throw_main_exception_exit();
297                 }
298
299                 /* build argument array */
300
301                 oalength = vm_args->nOptions - opt_index;
302
303                 oa = builtin_anewarray(oalength, class_java_lang_String);
304
305                 for (i = 0; i < oalength; i++) {
306                         s = javastring_new(utf_new_char(vm_args->options[opt_index + i].optionString));
307                         oa->data[i] = (java_objectheader *) s;
308                 }
309
310 #ifdef TYPEINFO_DEBUG_TEST
311                 /* test the typeinfo system */
312                 typeinfo_test();
313 #endif
314                 /*class_showmethods(currentThread->group->header.vftbl->class); */
315
316
317
318 #if defined(ENABLE_JVMTI)
319                 /* if this is the parent process than start the jdwp listening */
320                 if (jvmti || jdwp) {
321                         fprintf(stderr, "jdwp/debugger set herewego brkpt %p\n",&&herewego);
322                         setsysbrkpt(HEREWEGOBRK,&&herewego);
323                         if (dbgprocess && jdwp) cacaodbglisten(transport); 
324                 }
325
326                 
327                 if (!dbgprocess) {
328                         fprintf(stderr,"debuggee: herewe go\n");
329                         fflush(stderr);
330                 }
331 #endif
332                 /* here we go... */
333         herewego:
334                 (void) vm_call_method(m, NULL, oa);
335
336                 /* exception occurred? */
337
338                 if (*exceptionptr) {
339                         throw_main_exception();
340                         status = 1;
341                 }
342
343                 /* unload the JavaVM */
344
345                 vm_destroy(jvm);
346
347                 /* and exit */
348
349                 vm_exit(status);
350         }
351
352         /************* If requested, compile all methods ********************/
353
354         if (compileall) {
355                 classinfo *c;
356                 methodinfo *m;
357                 u4 slot;
358                 s4 i;
359                 classcache_name_entry *nmen;
360                 classcache_class_entry *clsen;
361
362                 /* create all classes found in the bootclasspath */
363                 /* XXX currently only works with zip/jar's */
364
365                 loader_load_all_classes();
366
367                 /* link all classes */
368
369                 for (slot = 0; slot < hashtable_classcache.size; slot++) {
370                         nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
371
372                         for (; nmen; nmen = nmen->hashlink) {
373                                 /* iterate over all class entries */
374
375                                 for (clsen = nmen->classes; clsen; clsen = clsen->next) {
376                                         c = clsen->classobj;
377
378                                         if (!c)
379                                                 continue;
380
381                                         if (!(c->state & CLASS_LINKED)) {
382                                                 if (!link_class(c)) {
383                                                         fprintf(stderr, "Error linking: ");
384                                                         utf_fprint_classname(stderr, c->name);
385                                                         fprintf(stderr, "\n");
386
387                                                         /* print out exception and cause */
388
389                                                         exceptions_print_exception(*exceptionptr);
390
391                                                         /* goto next class */
392
393                                                         continue;
394                                                 }
395                                         }
396
397                                         /* compile all class methods */
398
399                                         for (i = 0; i < c->methodscount; i++) {
400                                                 m = &(c->methods[i]);
401
402                                                 if (m->jcode) {
403                                                         if (!jit_compile(m)) {
404                                                                 fprintf(stderr, "Error compiling: ");
405                                                                 utf_fprint_classname(stderr, c->name);
406                                                                 fprintf(stderr, ".");
407                                                                 utf_fprint(stderr, m->name);
408                                                                 utf_fprint(stderr, m->descriptor);
409                                                                 fprintf(stderr, "\n");
410
411                                                                 /* print out exception and cause */
412
413                                                                 exceptions_print_exception(*exceptionptr);
414                                                         }
415                                                 }
416                                         }
417                                 }
418                         }
419                 }
420         }
421
422
423         /******** If requested, compile a specific method ***************/
424
425         if (opt_method != NULL) {
426                 methodinfo *m;
427
428                 /* create, load and link the main class */
429
430                 if (!(mainclass = load_class_bootstrap(utf_new_char(mainstring))))
431                         throw_main_exception_exit();
432
433                 if (!link_class(mainclass))
434                         throw_main_exception_exit();
435
436                 if (opt_signature != NULL) {
437                         m = class_resolveclassmethod(mainclass,
438                                                                                  utf_new_char(opt_method),
439                                                                                  utf_new_char(opt_signature),
440                                                                                  mainclass,
441                                                                                  false);
442                 } else {
443                         m = class_resolveclassmethod(mainclass,
444                                                                                  utf_new_char(opt_method),
445                                                                                  NULL,
446                                                                                  mainclass,
447                                                                                  false);
448                 }
449
450                 if (!m) {
451                         char message[MAXLOGTEXT];
452                         sprintf(message, "%s%s", opt_method,
453                                         opt_signature ? opt_signature : "");
454
455                         *exceptionptr =
456                                 new_exception_message(string_java_lang_NoSuchMethodException,
457                                                                           message);
458                                                                                  
459                         throw_main_exception_exit();
460                 }
461                 
462                 jit_compile(m);
463         }
464
465         vm_shutdown(0);
466
467         /* keep compiler happy */
468
469         return 0;
470 }
471
472
473 /*
474  * These are local overrides for various environment variables in Emacs.
475  * Please do not remove this and leave it at the end of the file, where
476  * Emacs will automagically detect them.
477  * ---------------------------------------------------------------------
478  * Local variables:
479  * mode: c
480  * indent-tabs-mode: t
481  * c-basic-offset: 4
482  * tab-width: 4
483  * End:
484  */