1 /* headers.c *******************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
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
13 Dieser Modul ist ein ziemlich schneller Hack und dementsprechend
14 schlecht (nicht) kommentiert.
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
20 Last Change: $Id: headers.c 136 1999-11-09 11:33:46Z schani $
22 *******************************************************************************/
26 #include "config.h" /* phil */
32 /******* replace some external functions *********/
34 functionptr native_findfunction (utf *cname, utf *mname, utf *desc, bool isstatic)
37 java_objectheader *javastring_new (utf *text) /* schani */
40 void throw_classnotfoundexception()
42 panic("class not found");
45 java_objectheader *literalstring_new (utf *u)
48 void literalstring_free (java_objectheader *o) { }
49 void stringtable_update () { }
50 void synchronize_caches() { }
51 void asm_call_jit_compiler () { }
52 void asm_calljavamethod () { }
53 void asm_dumpregistersandcall () { }
54 s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class) { return 0; }
56 s4 asm_builtin_idiv (s4 a, s4 b) {return 0;}
57 s4 asm_builtin_irem (s4 a, s4 b) {return 0;}
58 s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;}
59 s8 asm_builtin_lrem (s8 a, s8 b) {return 0;}
62 void asm_builtin_monitorenter (java_objectheader *o) {}
63 void asm_builtin_monitorexit (java_objectheader *o) {}
65 s4 asm_builtin_checkarraycast
66 (java_objectheader *o, constant_arraydescriptor *d)
69 void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
71 u1 *createcompilerstub (methodinfo *m) {return NULL;}
72 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
73 u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
75 void removecompilerstub (u1 *stub) {}
76 void removenativestub (u1 *stub) {}
78 void asm_perform_threadswitch (u1 **from, u1 **to) {}
79 u1* asm_initialize_thread_stack (void *func, u1 *stack) { return NULL; }
80 void asm_switchstackandcall () { }
82 java_objectheader *native_new_and_init (void *p) { return NULL; }
84 /************************ global variables **********************/
86 java_objectheader *exceptionptr; /* schani */
87 int newcompiler = true;
90 static chain *nativemethod_chain; /* chain with native methods */
91 static chain *nativeclass_chain; /* chain with processed classes */
92 static chain *ident_chain; /* chain with method and field names in current class */
93 static FILE *file = NULL;
95 static bool dopadding;
97 static void printIDpart (int c)
99 if ( (c>='a' && c<='z')
100 || (c>='A' && c<='Z')
101 || (c>='0' && c<='9')
104 else putc ('_',file);
108 static void printID (utf *u)
110 char *utf_ptr = u->text;
113 for (i=0; i<utf_strlen(u); i++)
114 printIDpart (utf_nextu2(&utf_ptr));
117 static void addoutputsize (int len)
120 if (!dopadding) return;
122 newsize = ALIGN (outputsize, len);
124 for (i=outputsize; i<newsize; i++) fprintf (file, " u1 pad%d\n",(int) i);
125 outputsize = newsize;
129 static char *printtype (char *utf_ptr)
133 switch (utf_nextu2(&utf_ptr)) {
134 case 'V': fprintf (file, "void");
140 case 'Z': addoutputsize (4);
141 fprintf (file, "s4");
143 case 'J': addoutputsize (8);
144 fprintf (file, "s8");
146 case 'F': addoutputsize (4);
147 fprintf (file, "float");
149 case 'D': addoutputsize (8);
150 fprintf (file, "double");
153 addoutputsize ( sizeof(java_arrayheader*) );
154 switch (utf_nextu2(&utf_ptr)) {
155 case 'I': fprintf (file, "java_intarray*"); break;
156 case 'J': fprintf (file, "java_longarray*"); break;
157 case 'Z': fprintf (file, "java_booleanarray*"); break;
158 case 'B': fprintf (file, "java_bytearray*"); break;
159 case 'S': fprintf (file, "java_shortarray*"); break;
160 case 'C': fprintf (file, "java_chararray*"); break;
161 case 'F': fprintf (file, "java_floatarray*"); break;
162 case 'D': fprintf (file, "java_doublearray*"); break;
164 case '[': fprintf (file, "java_arrayarray*");
165 while ((c = utf_nextu2(&utf_ptr)) == '[') ;
167 while (utf_nextu2(&utf_ptr) != ';');
170 case 'L': fprintf (file, "java_objectarray*");
171 while ( utf_nextu2(&utf_ptr) != ';');
173 default: panic ("invalid type descriptor");
178 addoutputsize ( sizeof(java_objectheader*));
179 fprintf (file, "struct ");
180 while ( (c = utf_nextu2(&utf_ptr)) != ';' ) printIDpart (c);
184 default: panic ("Unknown type in field descriptor");
190 /******* determine the number of entries of a utf string in the ident chain *****/
192 static int searchidentchain_utf(utf *ident)
194 utf *u = chain_first(ident_chain); /* first element of list */
198 if (u==ident) count++; /* string found */
199 u = chain_next(ident_chain); /* next element in list */
205 /**************** print structure for direct access to objects ******************/
207 static void printfields (classinfo *c)
214 addoutputsize ( sizeof(java_objectheader) );
215 fprintf (file, " java_objectheader header;\n");
219 printfields (c->super);
221 for (i=0; i<c->fieldscount; i++) {
224 if (! (f->flags & ACC_STATIC) ) {
226 printtype (f->descriptor->text);
228 utf_fprint (file, f->name);
230 /* rename multiple fieldnames */
231 if (ident_count = searchidentchain_utf(f->name))
232 fprintf(file,"%d",ident_count - 1);
233 chain_addlast(ident_chain,f->name);
235 fprintf (file, ";\n");
240 /***************** store prototype for native method in file ******************/
242 static void printmethod (methodinfo *m)
248 /* search for return-type in descriptor */
249 utf_ptr = m->descriptor->text;
250 while (utf_nextu2(&utf_ptr) != ')');
253 fprintf (file,"/*\n * Class: ");
254 utf_fprint (file, m->class->name);
255 fprintf (file,"\n * Method: ");
256 utf_fprint (file, m->name);
257 fprintf (file,"\n * Signature: ");
258 utf_fprint (file, m->descriptor);
259 fprintf (file,"\n */\n");
261 /* create prototype */
262 fprintf (file,"JNIEXPORT ");
264 fprintf (file," JNICALL Java_");
265 printID (m->class->name);
267 /* rename overloaded method */
268 if (ident_count = searchidentchain_utf(m->name))
269 fprintf(file,"%d",ident_count - 1);
270 chain_addlast(ident_chain,m->name);
274 fprintf (file," (JNIEnv *env ");
276 utf_ptr = m->descriptor->text+1;
278 if (! (m->flags & ACC_STATIC) ) {
280 fprintf (file, ", struct ");
281 printID (m->class->name);
282 fprintf (file, "* this ");
286 if ((*utf_ptr)!=')') fprintf (file, ", ");
288 while ((*utf_ptr)!=')') {
289 utf_ptr = printtype (utf_ptr);
290 fprintf (file, " par%d", paramnum++);
291 if ((*utf_ptr)!=')') fprintf (file, ", ");
294 fprintf (file, ");\n");
298 /****************** remove package-name in fully-qualified classname *********************/
300 static void simple_classname(char *buffer, utf *u)
302 u2 i, simplename_start;
304 for (i=utf_strlen(u); i>0; i--) {
306 if (u->text[i] == '$') u->text[i] = '_'; else /* convert '$' to '_' */
307 if (u->text[i] == '/') {
308 /* beginning of simple name */
309 simplename_start = i+1;
314 for (i=simplename_start; i < utf_strlen(u); i++)
315 buffer[i-simplename_start] = u->text[i];
317 buffer[i-simplename_start] = '\0';
320 /*********** create headerfile for classes and store native methods in chain ************/
322 static void headerfile_generate (classinfo *c)
324 char header_filename[1024] = "";
325 char classname[1024];
329 /* store class in chain */
330 chain_addlast (nativeclass_chain, c);
332 /* open headerfile for class */
333 simple_classname(classname,c->name);
335 /* create chain for renaming fields */
336 ident_chain = chain_new ();
338 sprintf(header_filename, "nat/%s.h", classname);
339 file = fopen (header_filename, "w");
340 if (!file) panic ("Can not open file to store header information");
341 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
343 /* create structure for direct access to objects */
344 fprintf (file, "/* Structure information for class: ");
345 utf_fprint (file, c->name);
346 fprintf (file, " */\n\n");
347 fprintf (file, "typedef struct ");
349 fprintf (file, " {\n");
353 fprintf (file, "} ");
355 fprintf (file, ";\n\n");
357 /* create chain for renaming overloaded methods */
358 chain_free(ident_chain);
359 ident_chain = chain_new ();
361 /* create method-prototypes */
363 for (i=0; i<c->methodscount; i++) {
365 m = &(c->methods[i]);
367 if (m->flags & ACC_NATIVE) {
368 chain_addlast (nativemethod_chain, m);
374 chain_free(ident_chain);
378 /******** print classname, '$' used to seperate inner-class name ***********/
380 void print_classname (classinfo *clazz)
382 utf *u = clazz->name;
383 char *endpos = u->text + u->blength;
384 char *utf_ptr = u->text;
387 while (utf_ptr<endpos) {
388 if ((c=utf_nextu2(&utf_ptr)) == '_')
396 /*************** create table for locating native functions ****************/
398 static void printnativetableentry (methodinfo *m)
400 fprintf (file, " { \"");
401 print_classname(m->class);
402 fprintf (file, "\",\n \"");
403 utf_fprint (file, m->name);
404 fprintf (file, "\",\n \"");
405 utf_fprint (file, m->descriptor);
406 fprintf (file, "\",\n ");
407 if ( (m->flags & ACC_STATIC) !=0) fprintf (file, "true");
408 else fprintf (file, "false");
409 fprintf (file, ",\n ");
410 fprintf (file, "(functionptr) Java_");
411 printID (m->class->name);
414 fprintf (file,"\n },\n");
418 /***************************************************************************
420 create the nativetypes-headerfile which includes
421 the headerfiles of the classes stored in the classes-chain
423 ****************************************************************************/
425 static void headers_finish ()
429 char classname[1024];
431 file = fopen ("nativetypes.hh", "w");
432 if (!file) panic ("Can not open file 'native.h' to store header information");
434 fprintf (file, "/* Headerfile for native methods: nativetypes.hh */\n");
435 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
436 fprintf (file, "\n/* include native-Headerfiles */\n\n");
438 c = chain_first (nativeclass_chain);
442 simple_classname(classname,c->name);
443 fprintf(file,"#include \"nat/%s.h\"\n",classname);
444 c = chain_next (nativeclass_chain);
448 chain_free (nativeclass_chain);
450 /* create table of native-methods */
452 file = fopen ("nativetable.hh", "w");
453 if (!file) panic ("Can not open file 'nativetable' to store native-link-table");
455 fprintf (file, "/* Table of native methods: nativetables.hh */\n");
456 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
458 while ( (m = chain_first (nativemethod_chain)) != NULL) {
459 chain_remove (nativemethod_chain);
460 printnativetableentry (m);
463 chain_free (nativemethod_chain);
469 /******************** interne Funktion: print_usage ************************
471 Gibt die richtige Aufrufsyntax des JAVA-Header-Generators auf stdout aus.
473 ***************************************************************************/
475 static void print_usage()
477 printf ("USAGE: jch class [class..]\n");
482 /************************** Funktion: main *******************************
485 Wird vom System zu Programstart aufgerufen (eh klar).
487 **************************************************************************/
489 int main(int argc, char **argv)
497 /********** interne (nur fuer main relevante Optionen) **************/
499 char classpath[500] = "";
500 char offsets_filename[1024] = ""; /* phil */
501 u4 heapsize = 100000;
503 /*********** Optionen, damit wirklich nur headers generiert werden ***/
505 makeinitializations=false;
508 /************ Infos aus der Environment lesen ************************/
510 cp = getenv ("CLASSPATH");
512 strcpy (classpath + strlen(classpath), ":");
513 strcpy (classpath + strlen(classpath), cp);
522 /**************************** Programmstart *****************************/
525 log_text ("Java - header-generator started");
527 sprintf(offsets_filename, "%s/offsets.h", SYSDEP_DIR); /* phil */
528 file = fopen(offsets_filename, "w");
530 fprintf (stderr, "Can not open file '%s' for write", offsets_filename);
534 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
536 fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl));
537 fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size));
538 fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
539 fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval));
540 fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval));
544 suck_init (classpath);
547 heap_init (heapsize, heapsize, &dummy);
551 /*********************** JAVA-Klassen laden ***************************/
553 nativemethod_chain = chain_new ();
554 nativeclass_chain = chain_new ();
556 for (a=1; a<argc; a++) {
560 /* convert classname */
561 for (i=strlen(cp)-1; i>=0; i--)
568 topclass = loader_load ( utf_new_char (cp) );
570 headerfile_generate (topclass);
575 /************************ Freigeben aller Resourcen *******************/
579 tables_close ( literalstring_free );
582 /* Endemeldung ausgeben und mit entsprechendem exit-Status terminieren */
584 log_text ("Java - header-generator stopped");
593 * These are local overrides for various environment variables in Emacs.
594 * Please do not remove this and leave it at the end of the file, where
595 * Emacs will automagically detect them.
596 * ---------------------------------------------------------------------
599 * indent-tabs-mode: t