* src/threads/native/threads.c: The Big Thread Cleanup. No functional changes,
[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 4908 2006-05-12 16:49:50Z edwin $
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/boehm.h"
47 #include "mm/memory.h"
48
49 #if defined(USE_THREADS)
50 # if defined(NATIVE_THREADS)
51 #  include "threads/native/threads.h"
52 # else
53 #  include "threads/green/threads.h"
54 # endif
55 #endif
56
57 #include "toolbox/chain.h"
58 #include "vm/classcache.h"
59 #include "vm/exceptions.h"
60 #include "vm/global.h"
61 #include "vm/loader.h"
62 #include "vm/options.h"
63 #include "vm/suck.h"
64
65
66 /* define heap sizes **********************************************************/
67
68 #define HEAP_MAXSIZE      4 * 1024 * 1024   /* default 4MB                    */
69 #define HEAP_STARTSIZE    100 * 1024        /* default 100kB                  */
70
71
72 /* define cacaoh options ******************************************************/
73
74 enum {
75         OPT_HELP,
76         OPT_VERSION,
77         OPT_VERBOSE,
78         OPT_BOOTCLASSPATH,
79
80         DUMMY
81 };
82
83
84 opt_struct opts[] = {
85         { "help",             false, OPT_HELP          },
86         { "version",          false, OPT_VERSION       },
87         { "verbose",          false, OPT_VERBOSE       },
88         { "bootclasspath",    true,  OPT_BOOTCLASSPATH },
89         { NULL,               false, 0                 }
90 };
91
92
93 int main(int argc, char **argv)
94 {
95         char *bootclasspath;
96
97         chain *nativemethod_chain;
98         classcache_name_entry *nmen;
99         classcache_class_entry *clsen;
100         classinfo *c;
101         s4 i;
102         s4 j;
103         u4 slot;
104         methodinfo *m;
105         methodinfo *m2;
106         bool nativelyoverloaded;
107
108         void *dummy;
109
110 #if defined(DISABLE_GC)
111         nogc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
112 #endif
113
114         while ((i = get_opt(argc, argv, opts)) != OPT_DONE) {
115                 switch (i) {
116                 case OPT_IGNORE:
117                         break;
118
119                 case OPT_HELP:
120 /*                      usage(); */
121                         break;
122
123                 case OPT_BOOTCLASSPATH:
124                         bootclasspath = MNEW(char, strlen(opt_arg) + strlen("0"));
125                         strcpy(bootclasspath, opt_arg);
126                         break;
127
128                 case OPT_VERSION:
129 /*                      version(); */
130                         break;
131
132                 case OPT_VERBOSE:
133                         opt_verbose = true;
134                         loadverbose = true;
135                         linkverbose = true;
136                         break;
137
138                 default:
139 /*                      usage(); */
140                         ;
141                 }
142         }
143
144         /* initialize the garbage collector */
145
146         gc_init(HEAP_MAXSIZE, HEAP_STARTSIZE);
147
148 #if defined(USE_THREADS)
149 #if defined(NATIVE_THREADS)
150         threads_preinit();
151 #endif
152         lock_init();
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((u1 *) &dummy))
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)
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                                         /* ATTENTION: We use the methodinfo's isleafmethod
220                                            variable as nativelyoverloaded, so we can save
221                                            some space during runtime. */
222
223                                         if (!m->isleafmethod) {
224                                                 nativelyoverloaded = false;
225                                 
226                                                 for (j = i + 1; j < c->methodscount; j++) {
227                                                         m2 = &(c->methods[j]);
228
229                                                         if (!(m2->flags & ACC_NATIVE))
230                                                                 continue;
231
232                                                         if (m->name == m2->name) {
233                                                                 m2->isleafmethod = true;
234                                                                 nativelyoverloaded = true;
235                                                         }
236                                                 }
237
238                                                 m->isleafmethod = nativelyoverloaded;
239                                         }
240                                 }
241
242                                 for (j = 0; j < c->methodscount; j++) {
243                                         m = &(c->methods[j]);
244
245                                         if (m->flags & ACC_NATIVE) {
246                                                 chain_addlast(nativemethod_chain, m);
247                                         }
248                                 }
249                         }
250                 }
251         }
252
253         /* create table of native-methods */
254
255         file = stdout;
256
257         fprintf(file, "/* This file is machine generated, don't edit it! */\n\n"); 
258
259         m = chain_first(nativemethod_chain);
260
261         while (m) {
262                 printmethod(m);
263                 m = chain_next(nativemethod_chain);
264         }
265
266         fprintf(file, "static nativeref nativetable[] = {\n");
267
268         m = chain_first(nativemethod_chain);
269
270         while (m) {
271         fprintf(file, "   { \"");
272
273                 print_classname(m->class);
274                 fprintf(file, "\",\n     \"");
275                 utf_fprint_printable_ascii(file, m->name);
276                 fprintf(file, "\",\n     \"");
277                 utf_fprint_printable_ascii(file, m->descriptor);
278                 fprintf(file, "\",\n     ");
279
280                 if (m->flags & ACC_STATIC)
281                         fprintf(file, "true");
282                 else
283                         fprintf(file, "false");
284
285                 fprintf(file, ",\n     ");
286                 fprintf(file, "(functionptr) Java_");
287                 printID(m->class->name);
288                 fprintf(file, "_");
289                 printID(m->name);
290          
291                 /* ATTENTION: We use the methodinfo's isleafmethod variable as
292                    nativelyoverloaded, so we can save some space during
293                    runtime. */
294
295                 if (m->isleafmethod)
296                         printOverloadPart(m->descriptor);
297
298                 fprintf(file,"\n   },\n");
299
300                 m = chain_next(nativemethod_chain);
301         }
302
303         chain_free(nativemethod_chain);
304
305         fprintf(file, "};\n");
306
307         fclose(file);
308         
309         /* release all resources */
310
311         loader_close();
312
313         /* everything is ok */
314
315         return 0;
316 }
317
318
319 /*
320  * These are local overrides for various environment variables in Emacs.
321  * Please do not remove this and leave it at the end of the file, where
322  * Emacs will automagically detect them.
323  * ---------------------------------------------------------------------
324  * Local variables:
325  * mode: c
326  * indent-tabs-mode: t
327  * c-basic-offset: 4
328  * tab-width: 4
329  * End:
330  */