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 This module replaces 'main' for header file generation. It also fakes some
8 references to external modules which would otherwise depend on the header
9 files generated by this very program.
11 This module is quite a quick hack and not documented very well as a
14 Authors: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
15 Changes: Mark Probst EMAIL: cacao@complang.tuwien.ac.at
16 Philipp Tomsich EMAIL: cacao@complang.tuwien.ac.at
18 Last Change: $Id: headers.c 303 2003-05-14 13:14:46Z stefan $
20 *******************************************************************************/
24 #include "config.h" /* phil */
30 /******* replace some external functions *********/
32 functionptr native_findfunction (utf *cname, utf *mname, utf *desc, bool isstatic)
35 java_objectheader *javastring_new (utf *text) /* schani */
38 void throw_classnotfoundexception()
40 panic("class not found");
43 java_objectheader *literalstring_new (utf *u)
46 void literalstring_free (java_objectheader *o) { }
47 void stringtable_update () { }
48 void synchronize_caches() { }
49 void asm_call_jit_compiler () { }
50 void asm_calljavamethod () { }
51 void asm_dumpregistersandcall () { }
52 s4 asm_builtin_checkcast(java_objectheader *obj, classinfo *class) { return 0; }
54 s4 asm_builtin_idiv (s4 a, s4 b) {return 0;}
55 s4 asm_builtin_irem (s4 a, s4 b) {return 0;}
56 s8 asm_builtin_ldiv (s8 a, s8 b) {return 0;}
57 s8 asm_builtin_lrem (s8 a, s8 b) {return 0;}
58 float asm_builtin_frem (float a, float b) {}
61 void asm_builtin_monitorenter (java_objectheader *o) {}
62 void asm_builtin_monitorexit (java_objectheader *o) {}
64 s4 asm_builtin_checkarraycast
65 (java_objectheader *o, constant_arraydescriptor *d)
69 void asm_builtin_anewarray (s4 size, classinfo *elementtype) {}
70 void asm_builtin_newarray_array (s4 size, constant_arraydescriptor *elementdesc) {}
72 void asm_builtin_aastore (java_objectarray *a, s4 index, java_objectheader *o) {}
74 u1 *createcompilerstub (methodinfo *m) {return NULL;}
75 u1 *createnativestub (functionptr f, methodinfo *m) {return NULL;}
76 u1 *oldcreatenativestub (functionptr f, methodinfo *m) {return NULL;}
78 void removecompilerstub (u1 *stub) {}
79 void removenativestub (u1 *stub) {}
81 void asm_perform_threadswitch (u1 **from, u1 **to) {}
82 u1* asm_initialize_thread_stack (void *func, u1 *stack) { return NULL; }
83 void asm_switchstackandcall () { }
85 java_objectheader *native_new_and_init (void *p) { return NULL; }
87 /************************ global variables **********************/
89 java_objectheader *exceptionptr; /* schani */
90 int newcompiler = true;
93 static chain *nativemethod_chain; /* chain with native methods */
94 static chain *nativeclass_chain; /* chain with processed classes */
95 static chain *ident_chain; /* chain with method and field names in current class */
96 static FILE *file = NULL;
98 static bool dopadding;
100 static void printIDpart (int c)
102 if ( (c>='a' && c<='z')
103 || (c>='A' && c<='Z')
104 || (c>='0' && c<='9')
107 else putc ('_',file);
111 static void printID (utf *u)
113 char *utf_ptr = u->text;
116 for (i=0; i<utf_strlen(u); i++)
117 printIDpart (utf_nextu2(&utf_ptr));
120 static void addoutputsize (int len)
123 if (!dopadding) return;
125 newsize = ALIGN (outputsize, len);
127 for (i=outputsize; i<newsize; i++) fprintf (file, " u1 pad%d\n",(int) i);
128 outputsize = newsize;
132 static char *printtype (char *utf_ptr)
136 switch (utf_nextu2(&utf_ptr)) {
137 case 'V': fprintf (file, "void");
143 case 'Z': addoutputsize (4);
144 fprintf (file, "s4");
146 case 'J': addoutputsize (8);
147 fprintf (file, "s8");
149 case 'F': addoutputsize (4);
150 fprintf (file, "float");
152 case 'D': addoutputsize (8);
153 fprintf (file, "double");
156 addoutputsize ( sizeof(java_arrayheader*) );
157 switch (utf_nextu2(&utf_ptr)) {
158 case 'I': fprintf (file, "java_intarray*"); break;
159 case 'J': fprintf (file, "java_longarray*"); break;
160 case 'Z': fprintf (file, "java_booleanarray*"); break;
161 case 'B': fprintf (file, "java_bytearray*"); break;
162 case 'S': fprintf (file, "java_shortarray*"); break;
163 case 'C': fprintf (file, "java_chararray*"); break;
164 case 'F': fprintf (file, "java_floatarray*"); break;
165 case 'D': fprintf (file, "java_doublearray*"); break;
167 case '[': fprintf (file, "java_arrayarray*");
168 while ((c = utf_nextu2(&utf_ptr)) == '[') ;
170 while (utf_nextu2(&utf_ptr) != ';');
173 case 'L': fprintf (file, "java_objectarray*");
174 while ( utf_nextu2(&utf_ptr) != ';');
176 default: panic ("invalid type descriptor");
181 addoutputsize ( sizeof(java_objectheader*));
182 fprintf (file, "struct ");
183 while ( (c = utf_nextu2(&utf_ptr)) != ';' ) printIDpart (c);
187 default: panic ("Unknown type in field descriptor");
193 /******* determine the number of entries of a utf string in the ident chain *****/
195 static int searchidentchain_utf(utf *ident)
197 utf *u = chain_first(ident_chain); /* first element of list */
201 if (u==ident) count++; /* string found */
202 u = chain_next(ident_chain); /* next element in list */
208 /**************** print structure for direct access to objects ******************/
210 static void printfields (classinfo *c)
217 addoutputsize ( sizeof(java_objectheader) );
218 fprintf (file, " java_objectheader header;\n");
222 printfields (c->super);
224 for (i=0; i<c->fieldscount; i++) {
227 if (! (f->flags & ACC_STATIC) ) {
229 printtype (f->descriptor->text);
231 utf_fprint (file, f->name);
233 /* rename multiple fieldnames */
234 if (ident_count = searchidentchain_utf(f->name))
235 fprintf(file,"%d",ident_count - 1);
236 chain_addlast(ident_chain,f->name);
238 fprintf (file, ";\n");
243 /***************** store prototype for native method in file ******************/
245 static void printmethod (methodinfo *m)
251 /* search for return-type in descriptor */
252 utf_ptr = m->descriptor->text;
253 while (utf_nextu2(&utf_ptr) != ')');
256 fprintf (file,"/*\n * Class: ");
257 utf_fprint (file, m->class->name);
258 fprintf (file,"\n * Method: ");
259 utf_fprint (file, m->name);
260 fprintf (file,"\n * Signature: ");
261 utf_fprint (file, m->descriptor);
262 fprintf (file,"\n */\n");
264 /* create prototype */
265 fprintf (file,"JNIEXPORT ");
267 fprintf (file," JNICALL Java_");
268 printID (m->class->name);
270 /* rename overloaded method */
271 if (ident_count = searchidentchain_utf(m->name))
272 fprintf(file,"%d",ident_count - 1);
273 chain_addlast(ident_chain,m->name);
277 fprintf (file," (JNIEnv *env ");
279 utf_ptr = m->descriptor->text+1;
281 if (! (m->flags & ACC_STATIC) ) {
283 fprintf (file, ", struct ");
284 printID (m->class->name);
285 fprintf (file, "* this ");
289 if ((*utf_ptr)!=')') fprintf (file, ", ");
291 while ((*utf_ptr)!=')') {
292 utf_ptr = printtype (utf_ptr);
293 fprintf (file, " par%d", paramnum++);
294 if ((*utf_ptr)!=')') fprintf (file, ", ");
297 fprintf (file, ");\n");
301 /****************** remove package-name in fully-qualified classname *********************/
303 static void simple_classname(char *buffer, utf *u)
305 int i, simplename_start;
307 for (i=utf_strlen(u)-1; i>=0; i--) {
309 if (u->text[i] == '$') u->text[i] = '_'; else /* convert '$' to '_' */
310 if (u->text[i] == '/') {
311 /* beginning of simple name */
312 simplename_start = i+1;
317 for (i=simplename_start; i < utf_strlen(u); i++)
318 buffer[i-simplename_start] = u->text[i];
320 buffer[i-simplename_start] = '\0';
323 /*********** create headerfile for classes and store native methods in chain ************/
325 static void headerfile_generate (classinfo *c)
327 char header_filename[1024] = "";
328 char classname[1024];
332 /* store class in chain */
333 chain_addlast (nativeclass_chain, c);
335 /* open headerfile for class */
336 simple_classname(classname,c->name);
338 /* create chain for renaming fields */
339 ident_chain = chain_new ();
341 sprintf(header_filename, "nat/%s.h", classname);
342 file = fopen (header_filename, "w");
343 if (!file) panic ("Can not open file to store header information");
344 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
346 /* create structure for direct access to objects */
347 fprintf (file, "/* Structure information for class: ");
348 utf_fprint (file, c->name);
349 fprintf (file, " */\n\n");
350 fprintf (file, "typedef struct ");
352 fprintf (file, " {\n");
356 fprintf (file, "} ");
358 fprintf (file, ";\n\n");
360 /* create chain for renaming overloaded methods */
361 chain_free(ident_chain);
362 ident_chain = chain_new ();
364 /* create method-prototypes */
366 for (i=0; i<c->methodscount; i++) {
368 m = &(c->methods[i]);
370 if (m->flags & ACC_NATIVE) {
371 chain_addlast (nativemethod_chain, m);
377 chain_free(ident_chain);
381 /******** print classname, '$' used to seperate inner-class name ***********/
383 void print_classname (classinfo *clazz)
385 utf *u = clazz->name;
386 char *endpos = u->text + u->blength;
387 char *utf_ptr = u->text;
390 while (utf_ptr<endpos) {
391 if ((c=utf_nextu2(&utf_ptr)) == '_')
399 /*************** create table for locating native functions ****************/
401 static void printnativetableentry (methodinfo *m)
403 fprintf (file, " { \"");
404 print_classname(m->class);
405 fprintf (file, "\",\n \"");
406 utf_fprint (file, m->name);
407 fprintf (file, "\",\n \"");
408 utf_fprint (file, m->descriptor);
409 fprintf (file, "\",\n ");
410 if ( (m->flags & ACC_STATIC) !=0) fprintf (file, "true");
411 else fprintf (file, "false");
412 fprintf (file, ",\n ");
413 fprintf (file, "(functionptr) Java_");
414 printID (m->class->name);
417 fprintf (file,"\n },\n");
421 /***************************************************************************
423 create the nativetypes-headerfile which includes
424 the headerfiles of the classes stored in the classes-chain
426 ****************************************************************************/
428 static void headers_finish ()
432 char classname[1024];
434 file = fopen ("nativetypes.hh", "w");
435 if (!file) panic ("Can not open file 'native.h' to store header information");
437 fprintf (file, "/* Headerfile for native methods: nativetypes.hh */\n");
438 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
439 fprintf (file, "\n/* include native-Headerfiles */\n\n");
441 c = chain_first (nativeclass_chain);
445 simple_classname(classname,c->name);
446 fprintf(file,"#include \"nat/%s.h\"\n",classname);
447 c = chain_next (nativeclass_chain);
451 chain_free (nativeclass_chain);
453 /* create table of native-methods */
455 file = fopen ("nativetable.hh", "w");
456 if (!file) panic ("Can not open file 'nativetable' to store native-link-table");
458 fprintf (file, "/* Table of native methods: nativetables.hh */\n");
459 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
461 while ( (m = chain_first (nativemethod_chain)) != NULL) {
462 chain_remove (nativemethod_chain);
463 printnativetableentry (m);
466 chain_free (nativemethod_chain);
472 /******************** internal function: print_usage ************************
474 Prints usage information for the JAVA header generator to stdout.
476 ***************************************************************************/
478 static void print_usage()
480 printf ("USAGE: jch class [class..]\n");
485 /************************** Function: main *******************************
489 **************************************************************************/
491 int main(int argc, char **argv)
499 /********** internal (only used by main) *****************************/
501 char classpath[500] = "";
502 char offsets_filename[1024] = ""; /* phil */
503 u4 heapsize = 100000;
505 /*********** options so only headers are generated *******************/
507 makeinitializations=false;
510 /************ Collect some info from the environment *****************/
512 cp = getenv ("CLASSPATH");
514 strcpy (classpath + strlen(classpath), ":");
515 strcpy (classpath + strlen(classpath), cp);
524 /**************************** Program start **************************/
527 log_text ("Java - header-generator started");
529 sprintf(offsets_filename, "%s/offsets.h", SYSDEP_DIR); /* phil */
530 file = fopen(offsets_filename, "w");
532 fprintf (stderr, "Can not open file '%s' for write", offsets_filename);
536 fprintf (file, "/* This file is machine generated, don't edit it !*/\n\n");
538 fprintf (file, "#define offobjvftbl %3d\n", (int) OFFSET(java_objectheader, vftbl));
539 fprintf (file, "#define offarraysize %3d\n", (int) OFFSET(java_arrayheader, size));
540 fprintf (file, "#define offobjarrdata %3d\n\n", (int) OFFSET(java_objectarray, data[0]));
541 fprintf (file, "#define offbaseval %3d\n", (int) OFFSET(vftbl, baseval));
542 fprintf (file, "#define offdiffval %3d\n", (int) OFFSET(vftbl, diffval));
546 suck_init (classpath);
549 heap_init (heapsize, heapsize, &dummy);
553 /*********************** Load JAVA classes **************************/
555 nativemethod_chain = chain_new ();
556 nativeclass_chain = chain_new ();
558 for (a=1; a<argc; a++) {
562 /* convert classname */
563 for (i=strlen(cp)-1; i>=0; i--)
570 topclass = loader_load ( utf_new_char (cp) );
572 headerfile_generate (topclass);
577 /************************ Release all resources **********************/
581 tables_close ( literalstring_free );
584 /* Print "finished" message */
586 log_text ("Java - header-generator stopped");
595 * These are local overrides for various environment variables in Emacs.
596 * Please do not remove this and leave it at the end of the file, where
597 * Emacs will automagically detect them.
598 * ---------------------------------------------------------------------
601 * indent-tabs-mode: t