* Removed all Id tags.
[cacao.git] / src / native / tools / gennativetable.c
1 /* src/native/tools/gennativetable.c - generate nativetable.h for native.c
2
3    Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    Contact: cacao@cacaojvm.org
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31 */
32
33
34 #include "config.h"
35
36 #include <assert.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40
41 #include "vm/types.h"
42
43 #include "cacaoh/headers.h"
44 #include "mm/gc-common.h"
45 #include "mm/memory.h"
46
47 #if defined(ENABLE_THREADS)
48 # include "threads/native/threads.h"
49 #endif
50
51 #include "toolbox/chain.h"
52 #include "vm/classcache.h"
53 #include "vm/exceptions.h"
54 #include "vm/global.h"
55 #include "vm/loader.h"
56 #include "vm/options.h"
57 #include "vm/stringlocal.h"
58 #include "vm/suck.h"
59
60
61 /* define heap sizes **********************************************************/
62
63 #define HEAP_MAXSIZE      4 * 1024 * 1024   /* default 4MB                    */
64 #define HEAP_STARTSIZE    100 * 1024        /* default 100kB                  */
65
66 #define ACC_NATIVELY_OVERLOADED    0x10000000
67
68
69 /* define cacaoh options ******************************************************/
70
71 enum {
72         OPT_HELP,
73         OPT_VERSION,
74         OPT_VERBOSE,
75         OPT_BOOTCLASSPATH,
76
77         DUMMY
78 };
79
80
81 opt_struct opts[] = {
82         { "help",             false, OPT_HELP          },
83         { "version",          false, OPT_VERSION       },
84         { "verbose",          false, OPT_VERBOSE       },
85         { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
86         { NULL,               false, 0                 }
87 };
88
89
90 static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv);
91
92
93 int main(int argc, char **argv)
94 {
95         JavaVMInitArgs *vm_args;
96         char *bootclasspath;
97
98         chain *nativemethod_chain;
99         classcache_name_entry *nmen;
100         classcache_class_entry *clsen;
101         classinfo *c;
102         s4 i;
103         s4 j;
104         u4 slot;
105         methodinfo *m;
106         methodinfo *m2;
107         bool nativelyoverloaded;
108
109 #if defined(DISABLE_GC)
110         gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
111 #endif
112
113         vm_args = gennativetable_options_prepare(argc, argv);
114
115         while ((i = options_get(opts, vm_args)) != OPT_DONE) {
116                 switch (i) {
117                 case OPT_IGNORE:
118                         break;
119
120                 case OPT_HELP:
121 /*                      usage(); */
122                         break;
123
124                 case OPT_BOOTCLASSPATH:
125                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
126                         strcpy(bootclasspath, opt_arg);
127                         break;
128
129                 case OPT_VERSION:
130 /*                      version(); */
131                         break;
132
133                 case OPT_VERBOSE:
134                         opt_verbose = true;
135                         loadverbose = true;
136                         linkverbose = true;
137                         break;
138
139                 default:
140 /*                      usage(); */
141                         ;
142                 }
143         }
144
145         /* initialize the garbage collector */
146
147         gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
148
149 #if defined(ENABLE_THREADS)
150         threads_preinit();
151 #endif
152
153         /* initialize the string hashtable stuff: lock (must be done
154            _after_ threads_preinit) */
155
156         if (!string_init())
157                 throw_main_exception_exit();
158
159         /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
160            (must be done _after_ threads_preinit) */
161
162         if (!utf8_init())
163                 throw_main_exception_exit();
164
165         /* initialize the classcache hashtable stuff: lock, hashtable
166            (must be done _after_ threads_preinit) */
167
168         if (!classcache_init())
169                 throw_main_exception_exit();
170
171         /* initialize the loader with bootclasspath (must be done _after_
172            thread_preinit) */
173
174         if (!suck_init())
175                 throw_main_exception_exit();
176
177         suck_add(bootclasspath);
178
179         /* initialize the loader subsystems (must be done _after_
180        classcache_init) */
181
182         if (!loader_init())
183                 throw_main_exception_exit();
184
185
186         /*********************** Load JAVA classes  **************************/
187
188         nativemethod_chain = chain_new();
189         ident_chain = chain_new();
190
191         /* load all classes from bootclasspath */
192
193         loader_load_all_classes();
194
195         /* link all classes */
196
197         for (slot = 0; slot < hashtable_classcache.size; slot++) {
198                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
199
200                 for (; nmen; nmen = nmen->hashlink) {
201                         /* iterate over all class entries */
202
203                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
204                                 c = clsen->classobj;
205
206                                 if (c == NULL)
207                                         continue;
208
209                                 /* find overloaded methods */
210
211                                 for (i = 0; i < c->methodscount; i++) {
212                                         m = &(c->methods[i]);
213
214                                         if (!(m->flags & ACC_NATIVE))
215                                                 continue;
216
217                                         if (!(m->flags & ACC_NATIVELY_OVERLOADED)) {
218                                                 nativelyoverloaded = false;
219                                 
220                                                 for (j = i + 1; j < c->methodscount; j++) {
221                                                         m2 = &(c->methods[j]);
222
223                                                         if (!(m2->flags & ACC_NATIVE))
224                                                                 continue;
225
226                                                         if (m->name == m2->name) {
227                                                                 m2->flags          |= ACC_NATIVELY_OVERLOADED;
228                                                                 nativelyoverloaded  = true;
229                                                         }
230                                                 }
231
232                                                 if (nativelyoverloaded == true)
233                                                         m->flags |= ACC_NATIVELY_OVERLOADED;
234                                         }
235                                 }
236
237                                 for (j = 0; j < c->methodscount; j++) {
238                                         m = &(c->methods[j]);
239
240                                         if (m->flags & ACC_NATIVE) {
241                                                 chain_addlast(nativemethod_chain, m);
242                                         }
243                                 }
244                         }
245                 }
246         }
247
248         /* create table of native-methods */
249
250         file = stdout;
251
252         fprintf(file, "/* This file is machine generated, don't edit it! */\n\n"); 
253
254         m = chain_first(nativemethod_chain);
255
256         while (m) {
257                 printmethod(m);
258                 m = chain_next(nativemethod_chain);
259         }
260
261         fprintf(file, "static nativeref nativetable[] = {\n");
262
263         m = chain_first(nativemethod_chain);
264
265         while (m) {
266         fprintf(file, "   { \"");
267
268                 print_classname(m->class);
269                 fprintf(file, "\",\n     \"");
270                 utf_fprint_printable_ascii(file, m->name);
271                 fprintf(file, "\",\n     \"");
272                 utf_fprint_printable_ascii(file, m->descriptor);
273                 fprintf(file, "\",\n     ");
274
275                 if (m->flags & ACC_STATIC)
276                         fprintf(file, "true");
277                 else
278                         fprintf(file, "false");
279
280                 fprintf(file, ",\n     ");
281                 fprintf(file, "(functionptr) Java_");
282                 printID(m->class->name);
283                 fprintf(file, "_");
284                 printID(m->name);
285          
286                 if (m->flags & ACC_NATIVELY_OVERLOADED)
287                         printOverloadPart(m->descriptor);
288
289                 fprintf(file,"\n   },\n");
290
291                 m = chain_next(nativemethod_chain);
292         }
293
294         chain_free(nativemethod_chain);
295
296         fprintf(file, "};\n");
297
298         fclose(file);
299         
300         /* release all resources */
301
302         loader_close();
303
304         /* everything is ok */
305
306         return 0;
307 }
308
309
310 /* gennativetable_options_prepare **********************************************
311
312    Prepare the JavaVMInitArgs.
313
314 *******************************************************************************/
315
316 static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv)
317 {
318         JavaVMInitArgs *vm_args;
319         s4              i;
320
321         vm_args = NEW(JavaVMInitArgs);
322
323         vm_args->nOptions = argc - 1;
324         vm_args->options  = MNEW(JavaVMOption, argc);
325
326         for (i = 1; i < argc; i++)
327                 vm_args->options[i - 1].optionString = argv[i];
328
329         return vm_args;
330 }
331
332
333 /*
334  * These are local overrides for various environment variables in Emacs.
335  * Please do not remove this and leave it at the end of the file, where
336  * Emacs will automagically detect them.
337  * ---------------------------------------------------------------------
338  * Local variables:
339  * mode: c
340  * indent-tabs-mode: t
341  * c-basic-offset: 4
342  * tab-width: 4
343  * End:
344  */