Initial revision
[cacao.git] / headers.c
1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /****************************** headers.c **************************************
3
4         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5
6         See file COPYRIGHT for information on usage and disclaimer of warranties
7
8         Dieser Modul ersetzt f"ur den Headerfile-Betrieb den Modul 'main',
9         und 'f"alscht' einige Verweise auf externe Module (damit nicht schon 
10         alle Module des eigentlichen Programmes fertig sein m"ussen, was ja
11         unm"oglich w"are, da die Headerfile-Tabellen ja erst hier und jetzt
12         generiert werden).
13
14         Dieser Modul ist ein ziemlich schneller Hack und dementsprechend
15         schlecht (nicht) kommentiert.
16
17         Authors: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
18         Changes: Mark Probst         EMAIL: cacao@complang.tuwien.ac.at
19
20         Last Change: 1997/05/23
21
22 *******************************************************************************/
23
24 #include "global.h"
25
26 #include "tables.h"
27 #include "loader.h"
28
29
30 /******* verschiedene externe Funktionen "faelschen" (=durch Dummys ersetzen), 
31   damit der Linker zufrieden ist *********/
32  
33 functionptr native_findfunction 
34   (unicode *cname, unicode *mname, unicode *desc, bool isstatic)
35 { return NULL; }
36
37 java_objectheader *literalstring_new (unicode *text)
38 { return NULL; }
39
40 java_objectheader *javastring_new (unicode *text)         /* schani */
41 { return NULL; }
42
43 void synchronize_caches() { }
44 void asm_call_jit_compiler () { }
45 void asm_calljavamethod () { }
46 void asm_dumpregistersandcall () { }
47
48 s4 new_builtin_idiv (s4 a, s4 b) {return 0;}
49 s4 new_builtin_irem (s4 a, s4 b) {return 0;}
50 s8 new_builtin_ldiv (s8 a, s8 b) {return 0;}
51 s8 new_builtin_lrem (s8 a, s8 b) {return 0;}
52
53
54 void new_builtin_monitorenter (java_objectheader *o) {}
55 void new_builtin_monitorexit (java_objectheader *o) {}
56
57 s4 new_builtin_checkcast(java_objectheader *o, classinfo *c)
58                         {return 0;}
59 s4 new_builtin_checkarraycast
60         (java_objectheader *o, constant_arraydescriptor *d)
61         {return 0;}
62
63 void new_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 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
68
69 void removecompilerstub (u1 *stub) {}
70 void removenativestub (u1 *stub) {}
71
72 void perform_alpha_threadswitch (u1 **from, u1 **to) {}
73 u1* initialize_thread_stack (void *func, u1 *stack) { return NULL; }
74 u1* used_stack_top (void) { return NULL; }
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         u4 heapsize = 100000;
396
397    /*********** Optionen, damit wirklich nur headers generiert werden ***/
398    
399    makeinitializations=false;
400    
401
402    /************ Infos aus der Environment lesen ************************/
403
404         cp = getenv ("CLASSPATH");
405         if (cp) {
406                 strcpy (classpath + strlen(classpath), ":");
407                 strcpy (classpath + strlen(classpath), cp);
408                 }
409
410         if (argc < 2) {
411                 print_usage ();
412                 exit(10);
413                 }
414
415
416    /**************************** Programmstart *****************************/
417
418         log_init (NULL);
419         log_text ("Java - header-generator started");
420         
421         
422         suck_init (classpath);
423         
424         unicode_init ();
425         heap_init (heapsize, heapsize, &dummy);
426         loader_init ();
427
428
429    /*********************** JAVA-Klassen laden  ***************************/
430    
431         headers_start ();
432
433         
434         for (a=1; a<argc; a++) {   
435                 cp = argv[a];
436                 for (i=strlen(cp)-1; i>=0; i--) {     /* Punkte im Klassennamen */
437                         if (cp[i]=='.') cp[i]='/';        /* auf slashes umbauen */
438                         }
439
440                 topclass = loader_load ( unicode_new_char (cp) );
441                 
442                 headers_generate (topclass);
443                 }
444         
445
446         headers_finish ();
447
448
449    /************************ Freigeben aller Resourcen *******************/
450
451         loader_close ();
452         heap_close ();
453         unicode_close (NULL);
454         
455
456    /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */
457
458         log_text ("Java - header-generator stopped");
459         log_cputime ();
460         mem_usagelog(1);
461         
462         return 0;
463 }
464
465