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