33e3bab9e8c2203e0eb95e18fe3b79d7c2b80d23
[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    $Id: gennativetable.c 6104 2006-12-02 14:54:27Z tbfg $
32
33 */
34
35
36 #include "config.h"
37
38 #include <assert.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <string.h>
42
43 #include "vm/types.h"
44
45 #include "cacaoh/headers.h"
46 #include "mm/gc-common.h"
47 #include "mm/memory.h"
48
49 #if defined(ENABLE_THREADS)
50 # include "threads/native/threads.h"
51 #endif
52
53 #include "toolbox/chain.h"
54 #include "vm/classcache.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/options.h"
59 #include "vm/stringlocal.h"
60 #include "vm/suck.h"
61
62
63 /* define heap sizes **********************************************************/
64
65 #define HEAP_MAXSIZE      4 * 1024 * 1024   /* default 4MB                    */
66 #define HEAP_STARTSIZE    100 * 1024        /* default 100kB                  */
67
68 #define ACC_NATIVELY_OVERLOADED    0x10000000
69
70
71 /* define cacaoh options ******************************************************/
72
73 enum {
74         OPT_HELP,
75         OPT_VERSION,
76         OPT_VERBOSE,
77         OPT_BOOTCLASSPATH,
78
79         DUMMY
80 };
81
82
83 opt_struct opts[] = {
84         { "help",             false, OPT_HELP          },
85         { "version",          false, OPT_VERSION       },
86         { "verbose",          false, OPT_VERBOSE       },
87         { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
88         { NULL,               false, 0                 }
89 };
90
91
92 static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv);
93
94
95 int main(int argc, char **argv)
96 {
97         JavaVMInitArgs *vm_args;
98         char *bootclasspath;
99
100         chain *nativemethod_chain;
101         classcache_name_entry *nmen;
102         classcache_class_entry *clsen;
103         classinfo *c;
104         s4 i;
105         s4 j;
106         u4 slot;
107         methodinfo *m;
108         methodinfo *m2;
109         bool nativelyoverloaded;
110
111 #if defined(DISABLE_GC)
112         gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
113 #endif
114
115         vm_args = gennativetable_options_prepare(argc, argv);
116
117         while ((i = options_get(opts, vm_args)) != OPT_DONE) {
118                 switch (i) {
119                 case OPT_IGNORE:
120                         break;
121
122                 case OPT_HELP:
123 /*                      usage(); */
124                         break;
125
126                 case OPT_BOOTCLASSPATH:
127                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
128                         strcpy(bootclasspath, opt_arg);
129                         break;
130
131                 case OPT_VERSION:
132 /*                      version(); */
133                         break;
134
135                 case OPT_VERBOSE:
136                         opt_verbose = true;
137                         loadverbose = true;
138                         linkverbose = true;
139                         break;
140
141                 default:
142 /*                      usage(); */
143                         ;
144                 }
145         }
146
147         /* initialize the garbage collector */
148
149         gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
150
151 #if defined(ENABLE_THREADS)
152         threads_preinit();
153 #endif
154
155         /* initialize the string hashtable stuff: lock (must be done
156            _after_ threads_preinit) */
157
158         if (!string_init())
159                 throw_main_exception_exit();
160
161         /* initialize the utf8 hashtable stuff: lock, often used utf8 strings
162            (must be done _after_ threads_preinit) */
163
164         if (!utf8_init())
165                 throw_main_exception_exit();
166
167         /* initialize the classcache hashtable stuff: lock, hashtable
168            (must be done _after_ threads_preinit) */
169
170         if (!classcache_init())
171                 throw_main_exception_exit();
172
173         /* initialize the loader with bootclasspath (must be done _after_
174            thread_preinit) */
175
176         if (!suck_init())
177                 throw_main_exception_exit();
178
179         suck_add(bootclasspath);
180
181         /* initialize the loader subsystems (must be done _after_
182        classcache_init) */
183
184         if (!loader_init())
185                 throw_main_exception_exit();
186
187
188         /*********************** Load JAVA classes  **************************/
189
190         nativemethod_chain = chain_new();
191         ident_chain = chain_new();
192
193         /* load all classes from bootclasspath */
194
195         loader_load_all_classes();
196
197         /* link all classes */
198
199         for (slot = 0; slot < hashtable_classcache.size; slot++) {
200                 nmen = (classcache_name_entry *) hashtable_classcache.ptr[slot];
201
202                 for (; nmen; nmen = nmen->hashlink) {
203                         /* iterate over all class entries */
204
205                         for (clsen = nmen->classes; clsen; clsen = clsen->next) {
206                                 c = clsen->classobj;
207
208                                 if (c == NULL)
209                                         continue;
210
211                                 /* find overloaded methods */
212
213                                 for (i = 0; i < c->methodscount; i++) {
214                                         m = &(c->methods[i]);
215
216                                         if (!(m->flags & ACC_NATIVE))
217                                                 continue;
218
219                                         if (!(m->flags & ACC_NATIVELY_OVERLOADED)) {
220                                                 nativelyoverloaded = false;
221                                 
222                                                 for (j = i + 1; j < c->methodscount; j++) {
223                                                         m2 = &(c->methods[j]);
224
225                                                         if (!(m2->flags & ACC_NATIVE))
226                                                                 continue;
227
228                                                         if (m->name == m2->name) {
229                                                                 m2->flags          |= ACC_NATIVELY_OVERLOADED;
230                                                                 nativelyoverloaded  = true;
231                                                         }
232                                                 }
233
234                                                 if (nativelyoverloaded == true)
235                                                         m->flags |= ACC_NATIVELY_OVERLOADED;
236                                         }
237                                 }
238
239                                 for (j = 0; j < c->methodscount; j++) {
240                                         m = &(c->methods[j]);
241
242                                         if (m->flags & ACC_NATIVE) {
243                                                 chain_addlast(nativemethod_chain, m);
244                                         }
245                                 }
246                         }
247                 }
248         }
249
250         /* create table of native-methods */
251
252         file = stdout;
253
254         fprintf(file, "/* This file is machine generated, don't edit it! */\n\n"); 
255
256         m = chain_first(nativemethod_chain);
257
258         while (m) {
259                 printmethod(m);
260                 m = chain_next(nativemethod_chain);
261         }
262
263         fprintf(file, "static nativeref nativetable[] = {\n");
264
265         m = chain_first(nativemethod_chain);
266
267         while (m) {
268         fprintf(file, "   { \"");
269
270                 print_classname(m->class);
271                 fprintf(file, "\",\n     \"");
272                 utf_fprint_printable_ascii(file, m->name);
273                 fprintf(file, "\",\n     \"");
274                 utf_fprint_printable_ascii(file, m->descriptor);
275                 fprintf(file, "\",\n     ");
276
277                 if (m->flags & ACC_STATIC)
278                         fprintf(file, "true");
279                 else
280                         fprintf(file, "false");
281
282                 fprintf(file, ",\n     ");
283                 fprintf(file, "(functionptr) Java_");
284                 printID(m->class->name);
285                 fprintf(file, "_");
286                 printID(m->name);
287          
288                 if (m->flags & ACC_NATIVELY_OVERLOADED)
289                         printOverloadPart(m->descriptor);
290
291                 fprintf(file,"\n   },\n");
292
293                 m = chain_next(nativemethod_chain);
294         }
295
296         chain_free(nativemethod_chain);
297
298         fprintf(file, "};\n");
299
300         fclose(file);
301         
302         /* release all resources */
303
304         loader_close();
305
306         /* everything is ok */
307
308         return 0;
309 }
310
311
312 /* gennativetable_options_prepare **********************************************
313
314    Prepare the JavaVMInitArgs.
315
316 *******************************************************************************/
317
318 static JavaVMInitArgs *gennativetable_options_prepare(int argc, char **argv)
319 {
320         JavaVMInitArgs *vm_args;
321         s4              i;
322
323         vm_args = NEW(JavaVMInitArgs);
324
325         vm_args->nOptions = argc - 1;
326         vm_args->options  = MNEW(JavaVMOption, argc);
327
328         for (i = 1; i < argc; i++)
329                 vm_args->options[i - 1].optionString = argv[i];
330
331         return vm_args;
332 }
333
334
335 /*
336  * These are local overrides for various environment variables in Emacs.
337  * Please do not remove this and leave it at the end of the file, where
338  * Emacs will automagically detect them.
339  * ---------------------------------------------------------------------
340  * Local variables:
341  * mode: c
342  * indent-tabs-mode: t
343  * c-basic-offset: 4
344  * tab-width: 4
345  * End:
346  */