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