92ae368980688a997af9bbb3e99e7e7421b795e6
[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_checkclasscast(java_objectheader *o, classinfo *c)
60                         {return 0;}
61 s4 new_builtin_checkintercast(java_objectheader *o, classinfo *c)
62                         {return 0;}
63 s4 new_builtin_checkarraycast
64         (java_objectheader *o, constant_arraydescriptor *d)
65         {return 0;}
66
67 void new_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
68
69 u1 *createcompilerstub (methodinfo *m) {return NULL;}
70 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
71 u1 *ncreatenativestub (functionptr f, methodinfo *m) {return NULL;}
72
73 void removecompilerstub (u1 *stub) {}
74 void removenativestub (u1 *stub) {}
75
76 void perform_alpha_threadswitch (u1 **from, u1 **to) {}
77 u1* initialize_thread_stack (void *func, u1 *stack) { return NULL; }
78 void asm_switchstackandcall () { }
79
80 java_objectheader *native_new_and_init (void *p) { return NULL; }
81
82 /************************ globale Variablen **********************/
83
84 java_objectheader *exceptionptr;                       /* schani */
85 int  newcompiler = true;
86 bool verbose =  false;
87
88 static chain *nativechain;
89 static FILE *file = NULL;
90
91 static void printIDpart (int c) 
92 {
93                 if (     (c>='a' && c<='z')
94                       || (c>='A' && c<='Z')
95                       || (c>='0' && c<='9')
96                       || (c=='_') )          
97                            putc (c,file);
98         else       putc ('_',file);
99
100 }
101
102 static void printID (unicode *name)
103 {
104         int i;
105         for (i=0; i<name->length; i++) {
106                 printIDpart (name->text[i]);
107         }
108 }
109
110
111 u4 outputsize;
112 bool dopadding;
113
114 static void addoutputsize (int len)
115 {
116         u4 newsize,i;
117         if (!dopadding) return;
118
119         newsize = ALIGN (outputsize, len);
120         
121         for (i=outputsize; i<newsize; i++) fprintf (file, "   u1 pad%d\n",(int) i);
122         outputsize = newsize;
123 }
124
125
126 static u2 *printtype (u2 *desc)
127 {
128         u2 c;
129
130         switch (*(desc++)) {
131                 case 'V': fprintf (file, "void");
132                           break;
133                 case 'I':
134                 case 'S':
135                 case 'B':
136                 case 'C':
137                 case 'Z': addoutputsize (4);
138                   fprintf (file, "s4");
139                   break;
140                 case 'J': addoutputsize (8);
141                   fprintf (file, "s8");
142                   break;
143                 case 'F': addoutputsize (4);
144                   fprintf (file, "float");
145                   break;
146                 case 'D': addoutputsize (8);
147                   fprintf (file, "double");
148                   break;
149                 case '[':
150                         addoutputsize ( sizeof(java_arrayheader*) ); 
151                         switch (*(desc++)) {
152                                 case 'I':  fprintf (file, "java_intarray*"); break;
153                                 case 'J':  fprintf (file, "java_longarray*"); break;
154                                 case 'Z':  fprintf (file, "java_booleanarray*"); break;
155                                 case 'B':  fprintf (file, "java_bytearray*"); break;
156                                 case 'S':  fprintf (file, "java_shortarray*"); break;
157                                 case 'C':  fprintf (file, "java_chararray*"); break;
158                                 case 'F':  fprintf (file, "java_floatarray*"); break;
159                                 case 'D':  fprintf (file, "java_doublearray*"); break;
160                                 
161                                 case '[':  fprintf (file, "java_arrayarray*");
162                                            while ((*desc) == '[') desc++;
163                                            if ((*desc)!='L') desc++;
164                                            else while (*(desc++) != ';');
165                            break;
166                            
167                                 case 'L':  fprintf (file, "java_objectarray*");
168                                            while ( *(desc++) != ';');
169                                            break;
170                                 default: panic ("invalid type descriptor");
171                                 }
172                         break;
173                 
174                 case 'L': 
175                         addoutputsize ( sizeof(java_objectheader*));
176             fprintf (file, "struct ");
177             while ( (c = *(desc++)) != ';' ) printIDpart (c);            
178             fprintf (file, "*");
179                         break;
180                                         
181                 default:  panic ("Unknown type in field descriptor");
182         }
183         
184         return (desc);
185 }
186
187
188
189 static void printfields (classinfo *c)
190 {
191         u4 i;
192         fieldinfo *f;
193         
194         if (!c) {
195                 addoutputsize ( sizeof(java_objectheader) );
196                 fprintf (file, "   java_objectheader header;\n");
197                 return;
198                 }
199                 
200         printfields (c->super);
201         
202         for (i=0; i<c->fieldscount; i++) {
203                 f = &(c->fields[i]);
204                 
205                 if (! (f->flags & ACC_STATIC) ) {
206                         fprintf (file,"   ");
207                         printtype (f->descriptor->text);
208                         fprintf (file, " ");
209                         unicode_fprint (file, f->name);
210                         fprintf (file, ";\n");
211                         }
212                 }
213 }
214
215
216
217
218 static void remembermethods (classinfo *c)
219 {
220         u2 i;
221         methodinfo *m;
222
223         for (i=0; i<c->methodscount; i++) {
224                 m = &(c->methods[i]);
225
226                 if (m->flags & ACC_NATIVE) {
227                         chain_addlast (nativechain, m);
228                         }
229                                         
230                 }
231 }
232
233
234
235
236 static void printmethod (methodinfo *m)
237 {
238         u2 *d;
239         u2 paramnum=1;
240         
241         d = m->descriptor->text;
242         while (*(d++) != ')');
243                                 
244         printtype (d);
245         fprintf (file," ");
246         printID (m->class->name);
247         fprintf (file,"_");
248         printID (m->name);
249         fprintf (file," (");
250                                         
251         d = m->descriptor->text+1;
252                         
253         if (! (m->flags & ACC_STATIC) ) {
254                 fprintf (file, "struct ");
255                 printID (m->class->name);
256                 fprintf (file, "* this");
257                 if ((*d)!=')') fprintf (file, ", ");
258                 }
259                         
260         while ((*d)!=')') {
261                 d = printtype (d);
262                 fprintf (file, " par%d", paramnum++);
263                 if ((*d)!=')') fprintf (file, ", ");
264                 }
265                         
266         fprintf (file, ");\n");
267 }
268
269
270 static void headers_generate (classinfo *c)
271 {
272         fprintf (file, "/* Structure information for class: ");
273         unicode_fprint (file, c->name);
274         fprintf (file, " */\n\n");
275
276         fprintf (file, "typedef struct ");
277         printID (c->name);
278         fprintf (file, " {\n");
279         
280         outputsize=0;
281         dopadding=true;
282         printfields (c);
283
284         fprintf (file, "} ");
285         printID (c->name);
286         fprintf (file, ";\n\n");
287
288         remembermethods (c);
289         
290
291         fprintf (file, "\n\n");
292 }
293
294
295
296 static void printnativetableentry (methodinfo *m)
297 {
298         fprintf (file, "   { \"");
299         unicode_fprint (file, m->class->name);
300         fprintf (file, "\",\n     \"");
301         unicode_fprint (file, m->name);
302         fprintf (file, "\",\n     \"");
303         unicode_fprint (file, m->descriptor);
304         fprintf (file, "\",\n     ");
305         if ( (m->flags & ACC_STATIC) !=0)  fprintf (file, "true");
306                                       else fprintf (file, "false");
307         fprintf (file, ",\n     ");
308         fprintf (file, "(functionptr) ");
309         printID (m->class->name);
310         fprintf (file,"_");
311         printID (m->name);
312         fprintf (file,"\n   },\n");
313 }
314
315
316
317
318
319 static void headers_start ()
320 {
321         file = fopen ("nativetypes.hh", "w");
322         if (!file) panic ("Can not open file 'native.h' to store header information");
323         
324         fprintf (file, "/* Headerfile for native methods: nativetypes.hh */\n");
325         fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); 
326
327         nativechain = chain_new ();
328 }
329
330
331 static void headers_finish ()
332 {
333         methodinfo *m;
334         
335         fprintf (file, "\n/* Prototypes for native methods */\n\n");
336         
337         m = chain_first (nativechain);
338         while (m) {
339                 dopadding=false;                
340                 printmethod (m);
341                 
342                 m = chain_next (nativechain);
343                 }
344
345
346         file = fopen ("nativetable.hh", "w");
347         if (!file) panic ("Can not open file 'nativetable' to store native-link-table");
348
349         fprintf (file, "/* Table of native methods: nativetables.hh */\n");
350         fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n"); 
351
352         while ( (m = chain_first (nativechain)) != NULL) {
353                 chain_remove (nativechain);
354                 
355                 printnativetableentry (m);
356                 
357                 }
358                 
359         chain_free (nativechain);
360         fclose (file);
361 }
362
363
364
365
366
367 /******************** interne Funktion: print_usage ************************
368
369 Gibt die richtige Aufrufsyntax des JAVA-Header-Generators auf stdout aus.
370
371 ***************************************************************************/
372
373 static void print_usage()
374 {
375         printf ("USAGE: jch class [class..]\n");
376 }   
377
378
379
380
381 /************************** Funktion: main *******************************
382
383    Das Hauptprogramm.
384    Wird vom System zu Programstart aufgerufen (eh klar).
385    
386 **************************************************************************/
387
388 int main(int argc, char **argv)
389 {
390         s4 i,a;
391         char *cp;
392         classinfo *topclass;
393         void *dummy;
394                 
395
396    /********** interne (nur fuer main relevante Optionen) **************/
397    
398         char classpath[500] = "";
399         u4 heapsize = 100000;
400
401    /*********** Optionen, damit wirklich nur headers generiert werden ***/
402    
403    makeinitializations=false;
404    
405
406    /************ Infos aus der Environment lesen ************************/
407
408         cp = getenv ("CLASSPATH");
409         if (cp) {
410                 strcpy (classpath + strlen(classpath), ":");
411                 strcpy (classpath + strlen(classpath), cp);
412                 }
413
414         if (argc < 2) {
415                 print_usage ();
416                 exit(10);
417                 }
418
419
420    /**************************** Programmstart *****************************/
421
422         log_init (NULL);
423         log_text ("Java - header-generator started");
424         
425         
426         suck_init (classpath);
427         
428         unicode_init ();
429         heap_init (heapsize, heapsize, &dummy);
430         loader_init ();
431
432
433    /*********************** JAVA-Klassen laden  ***************************/
434    
435         headers_start ();
436
437         
438         for (a=1; a<argc; a++) {   
439                 cp = argv[a];
440                 for (i=strlen(cp)-1; i>=0; i--) {     /* Punkte im Klassennamen */
441                         if (cp[i]=='.') cp[i]='/';        /* auf slashes umbauen */
442                         }
443
444                 topclass = loader_load ( unicode_new_char (cp) );
445                 
446                 headers_generate (topclass);
447                 }
448         
449
450         headers_finish ();
451
452
453    /************************ Freigeben aller Resourcen *******************/
454
455         loader_close ();
456         heap_close ();
457         unicode_close (NULL);
458         
459
460    /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */
461
462         log_text ("Java - header-generator stopped");
463         log_cputime ();
464         mem_usagelog(1);
465         
466         return 0;
467 }
468
469