GNU header update.
[cacao.git] / src / native / tools / gennativetable.c
1 /* gennativetable.c - generate nativetable.h for native.c
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    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., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Christian Thalinger
28
29    Changes:
30
31    $Id: gennativetable.c 1735 2004-12-07 14:33:27Z twisti $
32
33 */
34
35
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
40 #include "config.h"
41 #include "types.h"
42 #include "cacaoh/headers.h"
43 #include "mm/boehm.h"
44 #include "mm/memory.h"
45
46 #if defined(USE_THREADS)
47 # if defined(NATIVE_THREADS)
48 #  include "threads/native/threads.h"
49 # else
50 #  include "threads/green/threads.h"
51 # endif
52 #endif
53
54 #include "toolbox/chain.h"
55 #include "vm/exceptions.h"
56 #include "vm/global.h"
57 #include "vm/loader.h"
58 #include "vm/tables.h"
59
60
61 int main(int argc, char **argv)
62 {
63         s4 i, j, k;
64         char classpath[500] = "";
65         char *cp;
66         classinfo *c;
67         methodinfo *m;
68         methodinfo *m2;
69         bool nativelyoverloaded;
70         u4 heapmaxsize = 2 * 1024 * 1024;
71         u4 heapstartsize = 100 * 1024;
72         void *dummy;
73
74         /* XXX change me */
75         char classname[1024];
76
77         if (argc < 2) {
78                 printf("Usage: gennativetable class [class...]\n");
79                 exit(1);
80         }
81
82         cp = getenv("CLASSPATH");
83         if (cp) {
84                 strcpy(classpath + strlen(classpath), ":");
85                 strcpy(classpath + strlen(classpath), cp);
86         }
87
88         /* initialize the garbage collector */
89         gc_init(heapmaxsize, heapstartsize);
90
91         tables_init();
92
93         suck_init(classpath);
94    
95 #if defined(USE_THREADS)
96 #if defined(NATIVE_THREADS)
97         initThreadsEarly();
98 #endif
99         initLocks();
100 #endif
101
102         loader_init((u1 *) &dummy);
103
104
105         /*********************** Load JAVA classes  **************************/
106
107         nativeclass_chain = chain_new();
108         nativemethod_chain = chain_new();
109
110         for (i = 1; i < argc; i++) {
111                 cp = argv[i];
112
113                 /* convert classname */
114                 for (j = strlen(cp) - 1; j >= 0; j--) {
115                         switch (cp[j]) {
116                         case '.': cp[j] = '/';
117                                 break;
118                         case '_': cp[j] = '$';
119                         }
120                 }
121         
122                 c = class_new(utf_new_char(cp));
123
124                 /* exceptions are catched with new_exception call */
125                 class_load(c);
126                 class_link(c);
127
128                 chain_addlast(nativeclass_chain, c);
129
130                 /* find overloaded methods */
131                 for (j = 0; j < c->methodscount; j++) {
132                         m = &(c->methods[j]);
133
134                         if (!(m->flags & ACC_NATIVE))
135                                 continue;
136
137                         if (!m->nativelyoverloaded) {
138                                 nativelyoverloaded = false;
139                                 
140                                 for (k = j + 1; k < c->methodscount; k++) {
141                                         m2 = &(c->methods[k]);
142
143                                         if (!(m2->flags & ACC_NATIVE))
144                                                 continue;
145
146                                         if (m->name == m2->name) {
147                                                 m2->nativelyoverloaded = true;
148                                                 nativelyoverloaded = true;
149                                         }
150                                 }
151                                 m->nativelyoverloaded = nativelyoverloaded;
152                         }
153                 }
154
155                 for (j = 0; j < c->methodscount; j++) {
156                         m = &(c->methods[j]);
157
158                         if (m->flags & ACC_NATIVE) {
159                                 chain_addlast(nativemethod_chain, m);
160                         }
161                 }
162         }
163
164         /* create table of native-methods */
165
166         file = stdout;
167
168         fprintf(file, "/* Table of native methods: nativetables.inc */\n");
169         fprintf(file, "/* This file is machine generated, don't edit it! */\n\n"); 
170
171         fprintf(file, "#include \"config.h\"\n");
172
173         c = chain_first(nativeclass_chain);
174         while (c) {
175                 gen_header_filename(classname, c->name);
176                 fprintf(file, "#include \"native/include/%s.h\"\n", classname);
177                 c = chain_next(nativeclass_chain);
178         }
179         chain_free(nativeclass_chain);
180
181         fprintf(file, "\n\n#include \"native/native.h\"\n\n");
182         fprintf(file, "#if defined(STATIC_CLASSPATH)\n\n");
183         fprintf(file, "static nativeref nativetable[] = {\n");
184
185         m = chain_first(nativemethod_chain);
186         while (m) {
187                 printnativetableentry(m);
188                 m = chain_next(nativemethod_chain);
189         }
190         chain_free(nativemethod_chain);
191
192         fprintf(file, "};\n");
193         fprintf(file, "\n#else\n\n");
194         fprintf(file, "/* Ensure that symbols for functions implemented within cacao are used and    */\n");
195         fprintf(file, "/* exported to dlopen.                                                        */\n\n");
196         fprintf(file, "static functionptr dummynativetable[] = {\n");
197
198         {
199                 FILE *implData;
200
201                 implData = fopen("vm/implementednatives.data", "r");
202
203                 if (!implData) {
204                         fclose(file);
205                         throw_cacao_exception_exit(string_java_lang_InternalError,
206                                                                            "Could not find file");
207                 }
208
209                 while (!feof(implData)) {
210                         char functionLine[1024];
211                         functionLine[0] = '\0';
212                         fgets(functionLine, 1024, implData);
213
214                         if (strlen(functionLine) < 2)
215                                 continue;
216
217                         if (functionLine[strlen(functionLine) - 1] != '\n') {
218                                 fclose(implData);
219                                 fclose(file);
220                                 exit(4);
221                         }
222
223                         functionLine[strlen(functionLine) - 1] = ',';
224                         fprintf(file,"\t(functionptr) %s\n", functionLine);
225                 }
226
227                 fprintf(file, "\t(functionptr) 0\n");
228                 fclose(implData);
229         }
230
231         fprintf(file, "};\n");
232         fprintf(file, "\n#endif\n");
233         fclose(file);
234         
235         /* release all resources */
236
237         loader_close();
238         tables_close(literalstring_free);
239
240         /* everything is ok */
241
242         return 0;
243 }
244
245
246 /*
247  * These are local overrides for various environment variables in Emacs.
248  * Please do not remove this and leave it at the end of the file, where
249  * Emacs will automagically detect them.
250  * ---------------------------------------------------------------------
251  * Local variables:
252  * mode: c
253  * indent-tabs-mode: t
254  * c-basic-offset: 4
255  * tab-width: 4
256  * End:
257  */
258
259