Changed the makefile system to autoconf/automake.
[cacao.git] / headers.c
1 /* headers.c *******************************************************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Dieser Modul ersetzt f"ur den Headerfile-Betrieb den Modul 'main',
8         und 'f"alscht' einige Verweise auf externe Module (damit nicht schon 
9         alle Module des eigentlichen Programmes fertig sein m"ussen, was ja
10         unm"oglich w"are, da die Headerfile-Tabellen ja erst hier und jetzt
11         generiert werden).
12
13         Dieser Modul ist ein ziemlich schneller Hack und dementsprechend
14         schlecht (nicht) kommentiert.
15
16         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
17         Changes: Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
18                  Philipp Tomsich     EMAIL: cacao@complang.tuwien.ac.at
19
20         Last Change: $Id: headers.c 115 1999-01-20 01:52:45Z phil $
21
22 *******************************************************************************/
23
24 #include "config.h" /* phil */
25
26 #include "global.h"
27
28 #include "tables.h"
29 #include "loader.h"
30
31
32 /******* verschiedene externe Funktionen "faelschen" (=durch Dummys ersetzen), 
33   damit der Linker zufrieden ist *********/
34  
35 functionptr native_findfunction 
36   (unicode *cname, unicode *mname, unicode *desc, bool isstatic)
37 { return NULL; }
38
39 java_objectheader *literalstring_new (unicode *text)
40 { return NULL; }
41
42 java_objectheader *javastring_new (unicode *text)         /* schani */
43 { return NULL; }
44
45 void synchronize_caches() { }
46 void asm_call_jit_compiler () { }
47 void asm_calljavamethod () { }
48 void asm_dumpregistersandcall () { }
49
50 s4 asm_builtin_idiv (s4 a, s4 b) {return 0;}
51 s4 asm_builtin_irem (s4 a, s4 b) {return 0;}
52 s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;}
53 s8 asm_builtin_lrem (s8 a, s8 b) {return 0;}
54
55
56 void asm_builtin_monitorenter (java_objectheader *o) {}
57 void asm_builtin_monitorexit (java_objectheader *o) {}
58
59 s4 asm_builtin_checkarraycast
60         (java_objectheader *o, constant_arraydescriptor *d)
61         {return 0;}
62
63 void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
64
65 u1 *createcompilerstub (methodinfo *m) {return NULL;}
66 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
67 u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
68
69 void removecompilerstub (u1 *stub) {}
70 void removenativestub (u1 *stub) {}
71
72 void asm_perform_threadswitch (u1 **from, u1 **to) {}
73 u1* asm_initialize_thread_stack (void *func, u1 *stack) { return NULL; }
74 void asm_switchstackandcall () { }
75
76 java_objectheader *native_new_and_init (void *p) { return NULL; }
77
78 /************************ globale Variablen **********************/
79
80 java_objectheader *exceptionptr;                       /* schani */
81 int  newcompiler = true;
82 bool verbose =  false;
83
84 static chain *nativechain;
85 static FILE *file = NULL;
86
87 static void printIDpart (int c) 
88 {
89                 if (     (c>='a' && c<='z')
90                       || (c>='A' && c<='Z')
91                       || (c>='0' && c<='9')
92                       || (c=='_') )          
93                            putc (c,file);
94         else       putc ('_',file);
95
96 }
97
98 static void printID (unicode *name)
99 {
100         int i;
101         for (i=0; i<name->length; i++) {
102                 printIDpart (name->text[i]);
103         }
104 }
105
106
107 u4 outputsize;
108 bool dopadding;
109
110 static void addoutputsize (int len)
111 {
112         u4 newsize,i;
113         if (!dopadding) return;
114
115         newsize = ALIGN (outputsize, len);
116         
117         for (i=outputsize; i<newsize; i++) fprintf (file, "   u1 pad%d\n",(int) i);
118         outputsize = newsize;
119 }
120
121
122 static u2 *printtype (u2 *desc)
123 {
124         u2 c;
125
126         switch (*(desc++)) {
127                 case 'V': fprintf (file, "void");
128                           break;
129                 case 'I':
130                 case 'S':
131                 case 'B':
132                 case 'C':
133                 case 'Z': addoutputsize (4);
134                   fprintf (file, "s4");
135                   break;
136                 case 'J': addoutputsize (8);
137                   fprintf (file, "s8");
138                   break;
139                 case 'F': addoutputsize (4);
140                   fprintf (file, "float");
141                   break;
142                 case 'D': addoutputsize (8);
143                   fprintf (file, "double");
144                   break;
145                 case '[':
146                         addoutputsize ( sizeof(java_arrayheader*) ); 
147                         switch (*(desc++)) {
148                                 case 'I':  fprintf (file, "java_intarray*"); break;
149                                 case 'J':  fprintf (file, "java_longarray*"); break;
150                                 case 'Z':  fprintf (file, "java_booleanarray*"); break;
151                                 case 'B':  fprintf (file, "java_bytearray*"); break;
152                                 case 'S':  fprintf (file, "java_shortarray*"); break;
153                                 case 'C':  fprintf (file, "java_chararray*"); break;
154                                 case 'F':  fprintf (file, "java_floatarray*"); break;
155                                 case 'D':  fprintf (file, "java_doublearray*"); break;
156                                 
157                                 case '[':  fprintf (file, "java_arrayarray*");
158                                            while ((*desc) == '[') desc++;
159                                            if ((*desc)!='L') desc++;
160                                            else while (*(desc++) != ';');
161                            break;
162                            
163                                 case 'L':  fprintf (file, "java_objectarray*");
164                                            while ( *(desc++) != ';');
165                                            break;
166                                 default: panic ("invalid type descriptor");
167                                 }
168                         break;
169                 
170                 case 'L': 
171                         addoutputsize ( sizeof(java_objectheader*));
172             fprintf (file, "struct ");
173             while ( (c = *(desc++)) != ';' ) printIDpart (c);            
174             fprintf (file, "*");
175                         break;
176                                         
177                 default:  panic ("Unknown type in field descriptor");
178         }
179         
180         return (desc);
181 }
182
183
184
185 static void printfields (classinfo *c)
186 {
187         u4 i;
188         fieldinfo *f;
189         
190         if (!c) {
191                 addoutputsize ( sizeof(java_objectheader) );
192                 fprintf (file, "   java_objectheader header;\n");
193                 return;
194                 }
195                 
196         printfields (c->super);
197         
198         for (i=0; i<c->fieldscount; i++) {
199                 f = &(c->fields[i]);
200                 
201                 if (! (f->flags & ACC_STATIC) ) {
202                         fprintf (file,"   ");
203                         printtype (f->descriptor->text);
204                         fprintf (file, " ");
205                         unicode_fprint (file, f->name);
206                         fprintf (file, ";\n");
207                         }
208                 }
209 }
210
211
212
213
214 static void remembermethods (classinfo *c)
215 {
216         u2 i;
217         methodinfo *m;
218
219         for (i=0; i<c->methodscount; i++) {
220                 m = &(c->methods[i]);
221
222                 if (m->flags & ACC_NATIVE) {
223                         chain_addlast (nativechain, m);
224                         }
225                                         
226                 }
227 }
228
229
230
231
232 static void printmethod (methodinfo *m)
233 {
234         u2 *d;
235         u2 paramnum=1;
236         
237         d = m->descriptor->text;
238         while (*(d++) != ')');
239                                 
240         printtype (d);
241         fprintf (file," ");
242         printID (m->class->name);
243         fprintf (file,"_");
244         printID (m->name);
245         fprintf (file," (");
246                                         
247         d = m->descriptor->text+1;
248                         
249         if (! (m->flags & ACC_STATIC) ) {
250                 fprintf (file, "struct ");
251                 printID (m->class->name);
252                 fprintf (file, "* this");
253                 if ((*d)!=')') fprintf (file, ", ");
254                 }
255                         
256         while ((*d)!=')') {
257                 d = printtype (d);
258                 fprintf (file, " par%d", paramnum++);
259                 if ((*d)!=')') fprintf (file, ", ");
260                 }
261                         
262         fprintf (file, ");\n");
263 }
264
265
266 static void headers_generate (classinfo *c)
267 {
268         fprintf (file, "/* Structure information for class: ");
269         unicode_fprint (file, c->name);
270         fprintf (file, " */\n\n");
271
272         fprintf (file, "typedef struct ");
273         printID (c->name);
274         fprintf (file, " {\n");
275         
276         outputsize=0;
277         dopadding=true;
278         printfields (c);
279
280         fprintf (file, "} ");
281         printID (c->name);
282         fprintf (file, ";\n\n");
283
284         remembermethods (c);
285         
286
287         fprintf (file, "\n\n");
288 }
289
290
291
292 static void printnativetableentry (methodinfo *m)
293 {
294         fprintf (file, "   { \"");
295         unicode_fprint (file, m->class->name);
296         fprintf (file, "\",\n     \"");
297         unicode_fprint (file, m->name);
298         fprintf (file, "\",\n     \"");
299         unicode_fprint (file, m->descriptor);
300         fprintf (file, "\",\n     ");
301         if ( (m->flags & ACC_STATIC) !=0)  fprintf (file, "true");
302                                       else fprintf (file, "false");
303         fprintf (file, ",\n     ");
304         fprintf (file, "(functionptr) ");
305         printID (m->class->name);
306         fprintf (file,"_");
307         printID (m->name);
308         fprintf (file,"\n   },\n");
309 }
310
311
312
313
314
315 static void headers_start ()
316 {
317         file = fopen ("nativetypes.hh", "w");
318         if (!file) panic ("Can not open file 'native.h' to store header information");
319         
320         fprintf (file, "/* Headerfile for native methods: nativetypes.hh */\n");
321         fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); 
322
323         nativechain = chain_new ();
324 }
325
326
327 static void headers_finish ()
328 {
329         methodinfo *m;
330         
331         fprintf (file, "\n/* Prototypes for native methods */\n\n");
332         
333         m = chain_first (nativechain);
334         while (m) {
335                 dopadding=false;                
336                 printmethod (m);
337                 
338                 m = chain_next (nativechain);
339                 }
340
341
342         file = fopen ("nativetable.hh", "w");
343         if (!file) panic ("Can not open file 'nativetable' to store native-link-table");
344
345         fprintf (file, "/* Table of native methods: nativetables.hh */\n");
346         fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); 
347
348         while ( (m = chain_first (nativechain)) != NULL) {
349                 chain_remove (nativechain);
350                 
351                 printnativetableentry (m);
352                 
353                 }
354                 
355         chain_free (nativechain);
356         fclose (file);
357 }
358
359
360
361
362
363 /******************** interne Funktion: print_usage ************************
364
365 Gibt die richtige Aufrufsyntax des JAVA-Header-Generators auf stdout aus.
366
367 ***************************************************************************/
368
369 static void print_usage()
370 {
371         printf ("USAGE: jch class [class..]\n");
372 }   
373
374
375
376
377 /************************** Funktion: main *******************************
378
379    Das Hauptprogramm.
380    Wird vom System zu Programstart aufgerufen (eh klar).
381    
382 **************************************************************************/
383
384 int main(int argc, char **argv)
385 {
386         s4 i,a;
387         char *cp;
388         classinfo *topclass;
389         void *dummy;
390                 
391
392    /********** interne (nur fuer main relevante Optionen) **************/
393    
394         char classpath[500] = "";
395         char offsets_filename[1024] = ""; /* phil */
396         u4 heapsize = 100000;
397
398    /*********** Optionen, damit wirklich nur headers generiert werden ***/
399    
400    makeinitializations=false;
401    
402
403    /************ Infos aus der Environment lesen ************************/
404
405         cp = getenv ("CLASSPATH");
406         if (cp) {
407                 strcpy (classpath + strlen(classpath), ":");
408                 strcpy (classpath + strlen(classpath), cp);
409                 }
410
411         if (argc < 2) {
412                 print_usage ();
413                 exit(10);
414                 }
415
416
417    /**************************** Programmstart *****************************/
418
419         log_init (NULL);
420         log_text ("Java - header-generator started");
421         
422         sprintf(offsets_filename, "%s/offsets.h", SYSDEP_DIR); /* phil */
423         file = fopen(offsets_filename, "w");
424         if (file == NULL) {
425                 fprintf (stderr, "Can not open file '%s' for write", offsets_filename);
426                 exit(-1);
427         }
428         
429         fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); 
430
431         fprintf (file, "#define offobjvftbl    %3d\n", (int) OFFSET(java_objectheader, vftbl));
432         fprintf (file, "#define offarraysize   %3d\n", (int) OFFSET(java_arrayheader, size));
433         fprintf (file, "#define offobjarrdata  %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
434         fprintf (file, "#define offbaseval     %3d\n", (int) OFFSET(vftbl, baseval));
435         fprintf (file, "#define offdiffval     %3d\n", (int) OFFSET(vftbl, diffval));
436
437         fclose (file);
438         
439         suck_init (classpath);
440         
441         unicode_init ();
442         heap_init (heapsize, heapsize, &dummy);
443         loader_init ();
444
445
446    /*********************** JAVA-Klassen laden  ***************************/
447    
448         headers_start ();
449
450         
451         for (a=1; a<argc; a++) {   
452                 cp = argv[a];
453                 for (i=strlen(cp)-1; i>=0; i--) {     /* Punkte im Klassennamen */
454                         if (cp[i]=='.') cp[i]='/';        /* auf slashes umbauen */
455                         }
456
457                 topclass = loader_load ( unicode_new_char (cp) );
458                 
459                 headers_generate (topclass);
460                 }
461         
462
463         headers_finish ();
464
465
466    /************************ Freigeben aller Resourcen *******************/
467
468         loader_close ();
469         heap_close ();
470         unicode_close (NULL);
471         
472
473    /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */
474
475         log_text ("Java - header-generator stopped");
476         log_cputime ();
477         mem_usagelog(1);
478         
479         return 0;
480 }
481
482
483 /*
484  * These are local overrides for various environment variables in Emacs.
485  * Please do not remove this and leave it at the end of the file, where
486  * Emacs will automagically detect them.
487  * ---------------------------------------------------------------------
488  * Local variables:
489  * mode: c
490  * indent-tabs-mode: t
491  * c-basic-offset: 4
492  * tab-width: 4
493  * End:
494  */