* src/vm/options.h, src/vm/method.c, src/vm/jit/inline/inline.c,
[cacao.git] / src / cacaoh / headers.c
1 /* src/cacaoh/headers.c - functions for header generation
2
3    Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
4    C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
5    E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
6    J. Wenninger, Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23    02110-1301, USA.
24
25    $Id: headers.c 7228 2007-01-19 01:13:48Z edwin $
26
27 */
28
29
30 #include "config.h"
31
32 #include <assert.h>
33 #include <ctype.h>
34 #include <stdarg.h>
35 #include <stdlib.h>
36 #include <string.h>
37
38 #include "vm/types.h"
39
40 #if defined(ENABLE_THREADS)
41 # if defined(__DARWIN__)
42 #  include <signal.h>
43 # endif
44 # include <ucontext.h>
45 #endif
46
47 #include "mm/gc-common.h"
48 #include "mm/memory.h"
49 #include "native/include/java_lang_String.h"
50 #include "native/include/java_lang_Throwable.h"
51 #include "toolbox/chain.h"
52 #include "toolbox/logging.h"
53 #include "vm/builtin.h"
54 #include "vm/class.h"
55 #include "vm/global.h"
56 #include "vm/method.h"
57 #include "vm/loader.h"
58 #include "vm/options.h"
59 #include "vm/stringlocal.h"
60 #include "vm/jit/asmpart.h"
61
62
63 /* Invocation API variables ***************************************************/
64
65 _Jv_JavaVM *_Jv_jvm;                    /* denotes a Java VM                  */
66 char       *_Jv_bootclasspath;
67
68 char       *cacao_prefix;
69 char       *classpath_libdir;
70
71 char       *_Jv_classpath;
72 char       *_Jv_java_library_path;
73
74 #if defined(ENABLE_INTRP)
75 /* dummy interpreter stack to keep the compiler happy */
76
77 u1 *intrp_main_stack;
78 #endif
79
80
81 /* for raising exceptions from native methods *********************************/
82
83 #if !defined(ENABLE_THREADS)
84 java_objectheader *_no_threads_exceptionptr = NULL;
85 #endif
86
87
88 /* replace some non-vmcore functions ******************************************/
89
90 functionptr native_findfunction(utf *cname, utf *mname, utf *desc,
91                                                                 bool isstatic)
92 {
93         /* return something different than NULL, otherwise we get an exception */
94
95         return (functionptr) 1;
96 }
97
98 java_objectheader *native_new_and_init(classinfo *c) { return NULL; }
99 java_objectheader *native_new_and_init_string(classinfo *c, java_lang_String *s) { return NULL; }
100 java_objectheader *native_new_and_init_int(classinfo *c, s4 i) { return NULL; }
101 java_objectheader *native_new_and_init_throwable(classinfo *c, java_lang_Throwable *t) { return NULL; }
102
103
104 java_objectheader *vm_call_method(methodinfo *m, java_objectheader *o, ...)
105 { return NULL; }
106
107 void vm_abort(const char *text, ...)
108 {
109         va_list ap;
110
111         /* print the log message */
112
113         va_start(ap, text);
114         vfprintf(stderr, text, ap);
115         va_end(ap);
116
117         /* now abort the VM */
118
119         abort();
120 }
121
122 /* code patching functions */
123 void patcher_builtin_arraycheckcast(u1 *sp) {}
124
125
126 long compare_and_swap(volatile long *p, long oldval, long newval)
127 {
128         if (*p == oldval) {
129         *p = newval;
130         return oldval;
131         }
132         else
133         return *p;
134
135         return oldval;
136 }
137
138 long asm_compare_and_swap(volatile long *p, long oldval, long newval)
139 {
140         if (*p == oldval) {
141         *p = newval;
142         return oldval;
143         }
144         else
145         return *p;
146
147         return oldval;
148 }
149
150 void asm_memory_barrier(void)
151 {
152 }
153
154
155 u1 *createcompilerstub(methodinfo *m) { return NULL; }
156 #if defined(ENABLE_INTRP)
157 u1 *intrp_createcompilerstub(methodinfo *m) { return NULL; }
158 #endif
159
160 codeinfo *codegen_createnativestub(functionptr f, methodinfo *m) { return NULL; }
161
162 void removecompilerstub(u1 *stub) {}
163 void removenativestub(u1 *stub) {}
164
165 void asm_perform_threadswitch(u1 **from, u1 **to, u1 **stackTop) {}
166 u1* asm_initialize_thread_stack(void *func, u1 *stack) { return NULL; }
167
168 void *asm_switchstackandcall(void *stack, void *func, void **stacktopsave, void * p) { return NULL; }
169
170 void asm_handle_builtin_exception(classinfo *c) {}
171
172 #if defined(ENABLE_JIT)
173 void asm_abstractmethoderror(void) {}
174 void asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
175 #endif
176
177 #if defined(ENABLE_INTRP)
178 void intrp_asm_abstractmethoderror(void) {}
179 void intrp_asm_getclassvalues_atomic(vftbl_t *super, vftbl_t *sub, castinfo *out) {}
180 #endif
181
182 u8 asm_get_cycle_count(void)
183 {
184         return 0;
185 }
186
187
188 void *Java_java_lang_VMObject_clone(void *env, void *clazz, void * this)
189 {
190         return NULL;
191 }
192
193 typecheck_result typeinfo_is_assignable_to_class(typeinfo *value,classref_or_classinfo dest)
194 {
195         return typecheck_TRUE;
196 }
197
198 void typeinfo_init_classinfo(typeinfo *info,classinfo *c)
199 {
200 }
201
202 bool typeinfo_init_class(typeinfo *info,classref_or_classinfo c)
203 {
204         return true;
205 }
206
207 void typeinfo_print(FILE *file,typeinfo *info,int indent) {}
208 void typeinfo_print_short(FILE *file,typeinfo *info) {}
209
210 void exceptions_print_exception(java_objectheader *xptr) {}
211 void stacktrace_dump_trace(threadobject *thread) {}
212 void stacktrace_print_trace(java_objectheader *xptr) {}
213 java_objectarray *stacktrace_getClassContext() { return NULL; }
214 void code_free_code_of_method(methodinfo *m) {}
215
216 void jit_invalidate_code(methodinfo *m) {}
217
218
219 /* exception functions ********************************************************/
220
221 /* these should not be called */
222
223 void throw_main_exception_exit(void) { assert(0); }
224 void throw_exception(void) { assert(0); }
225 void throw_exception_exit(void) { assert(0); }
226
227 void exceptions_throw_verifyerror(methodinfo *m, const char *message)
228 {
229         assert(0);
230 }
231
232 java_objectheader *new_exception_throwable(const char *classname, java_lang_Throwable *throwable)
233 {
234         assert(0);
235
236         /* keep compiler happy */
237
238         return NULL;
239 }
240
241
242 java_objectheader *new_exception(const char *classname)
243 {
244         fprintf(stderr, "%s\n", classname);
245         exit(1);
246
247         /* keep compiler happy */
248
249         return NULL;
250 }
251
252
253 java_objectheader *new_exception_message(const char *classname, const char *message)
254 {
255         fprintf(stderr, "%s: %s\n", classname, message);
256         exit(1);
257
258         /* keep compiler happy */
259
260         return NULL;
261 }
262
263
264 java_objectheader *new_exception_utfmessage(const char *classname, utf *message)
265 {
266         fprintf(stderr, "%s: ", classname);
267         utf_display_printable_ascii(message);
268         fputc('\n', stderr);
269
270         exit(1);
271
272         /* keep compiler happy */
273
274         return NULL;
275 }
276
277
278 java_objectheader *new_exception_javastring(const char *classname,
279                                                                                         java_lang_String *message)
280 {
281         fprintf(stderr, "%s: ", classname);
282         /* TODO print message */
283         fputc('\n', stderr);
284
285         exit(1);
286
287         /* keep compiler happy */
288
289         return NULL;
290 }
291
292
293 void exceptions_throw_abstractmethoderror(void)
294 {
295         fprintf(stderr, "java.lang.AbstractMethodError\n");
296
297         exit(1);
298 }
299
300
301 java_objectheader *new_classformaterror(classinfo *c, const char *message, ...)
302 {
303         va_list ap;
304
305         utf_display_printable_ascii(c->name);
306         fprintf(stderr, ": ");
307
308         va_start(ap, message);
309         vfprintf(stderr, message, ap);
310         va_end(ap);
311
312         fputc('\n', stderr);
313
314         exit(1);
315
316         /* keep compiler happy */
317
318         return NULL;
319 }
320
321
322 void exceptions_throw_classformaterror(classinfo *c, const char *message, ...)
323 {
324         va_list ap;
325
326         va_start(ap, message);
327         (void) new_classformaterror(c, message, ap);
328         va_end(ap);
329 }
330
331
332 java_objectheader *new_classnotfoundexception(utf *name)
333 {
334         fprintf(stderr, "java.lang.ClassNotFoundException: ");
335         utf_fprint_printable_ascii(stderr, name);
336         fputc('\n', stderr);
337
338         exit(1);
339
340         /* keep compiler happy */
341
342         return NULL;
343 }
344
345
346 java_objectheader *new_noclassdeffounderror(utf *name)
347 {
348         fprintf(stderr, "java.lang.NoClassDefFoundError: ");
349         utf_fprint_printable_ascii(stderr, name);
350         fputc('\n', stderr);
351
352         exit(1);
353
354         /* keep compiler happy */
355
356         return NULL;
357 }
358
359
360 java_objectheader *exceptions_new_linkageerror(const char *message,
361                                                                                            classinfo *c)
362 {
363         fprintf(stderr, "java.lang.LinkageError: %s",message);
364         if (c) {
365                 utf_fprint_printable_ascii_classname(stderr, c->name);
366         }
367         fputc('\n', stderr);
368
369         exit(1);
370
371         /* keep compiler happy */
372
373         return NULL;
374 }
375
376 java_objectheader *exceptions_new_nosuchmethoderror(classinfo *c,
377                                                                                                         utf *name, utf *desc)
378 {
379         fprintf(stderr, "java.lang.NoSuchMethodError: ");
380         utf_fprint_printable_ascii(stderr, c->name);
381         fprintf(stderr, ".");
382         utf_fprint_printable_ascii(stderr, name);
383         utf_fprint_printable_ascii(stderr, desc);
384         fputc('\n', stderr);
385
386         exit(1);
387
388         /* keep compiler happy */
389
390         return NULL;
391 }
392
393
394 void exceptions_throw_nosuchmethoderror(classinfo *c, utf *name, utf *desc)
395 {
396         (void) exceptions_new_nosuchmethoderror(c, name, desc);
397 }
398
399
400 void exceptions_throw_internalerror(const char *message, ...)
401 {
402         va_list ap;
403
404         fprintf(stderr, "%s: ", string_java_lang_InternalError);
405
406         va_start(ap, message);
407         vfprintf(stderr, message, ap);
408         va_end(ap);
409
410         exit(1);
411 }
412
413
414 void exceptions_throw_outofmemoryerror(void)
415 {
416         fprintf(stderr, "%s", string_java_lang_OutOfMemoryError);
417         exit(1);
418 }
419
420
421 java_objectheader *new_unsupportedclassversionerror(classinfo *c, const char *message, ...)
422 {
423         va_list ap;
424
425         fprintf(stderr, "%s: ", string_java_lang_UnsupportedClassVersionError);
426
427         utf_display_printable_ascii(c->name);
428         fprintf(stderr, ": ");
429
430         va_start(ap, message);
431         vfprintf(stderr, message, ap);
432         va_end(ap);
433
434         exit(1);
435
436         /* keep compiler happy */
437
438         return NULL;
439 }
440
441
442 void exceptions_throw_virtualmachineerror(void)
443 {
444         fprintf(stderr, "%s", string_java_lang_VirtualMachineError);
445         exit(1);
446 }
447
448
449 void exceptions_throw_arrayindexoutofboundsexception(void)
450 {
451         fprintf(stderr, "%s", string_java_lang_ArrayIndexOutOfBoundsException);
452         exit(1);
453 }
454
455
456 java_objectheader *exceptions_new_arraystoreexception(void)
457 {
458         fprintf(stderr, "%s", string_java_lang_ArrayStoreException);
459         exit(1);
460
461         /* keep compiler happy */
462
463         return NULL;
464 }
465
466
467 void exceptions_throw_arraystoreexception(void)
468 {
469         (void) exceptions_new_arraystoreexception();
470 }
471
472
473 java_objectheader *exceptions_throw_illegalmonitorstateexception(void)
474 {
475         fprintf(stderr, "%s", string_java_lang_IllegalMonitorStateException);
476         exit(1);
477
478         /* keep compiler happy */
479
480         return NULL;
481 }
482
483
484 java_objectheader *new_negativearraysizeexception(void)
485 {
486         fprintf(stderr, "%s", string_java_lang_NegativeArraySizeException);
487         exit(1);
488
489         /* keep compiler happy */
490
491         return NULL;
492 }
493
494
495 void exceptions_throw_negativearraysizeexception(void)
496 {
497         (void) new_negativearraysizeexception();
498 }
499
500
501 java_objectheader *exceptions_new_nullpointerexception(void)
502 {
503         fprintf(stderr, "%s", string_java_lang_NullPointerException);
504         exit(1);
505
506         /* keep compiler happy */
507
508         return NULL;
509 }
510
511
512 void exceptions_throw_nullpointerexception(void)
513 {
514         (void) exceptions_new_nullpointerexception();
515 }
516
517
518 void classnotfoundexception_to_noclassdeffounderror(void)
519 {
520 }
521
522 /* machine dependent stuff ****************************************************/
523
524 #if defined(ENABLE_THREADS)
525 critical_section_node_t asm_criticalsections;
526 void thread_restartcriticalsection(ucontext_t *uc) {}
527 #endif
528
529 void md_param_alloc(methoddesc *md) {}
530
531
532 #if defined(ENABLE_INTRP)
533 void print_dynamic_super_statistics(void) {}
534 #endif
535
536
537 /************************ global variables **********************/
538
539 #define ACC_NATIVELY_OVERLOADED    0x10000000
540
541 chain *ident_chain;     /* chain with method and field names in current class */
542 FILE *file = NULL;
543 static u4 outputsize;
544 static bool dopadding;
545
546
547 static void printIDpart(int c)
548 {
549         if ((c >= 'a' && c <= 'z') ||
550                 (c >= 'A' && c <= 'Z') ||
551                 (c >= '0' && c <= '9') ||
552                 (c == '_'))
553                 putc(c, file);
554         else
555                 putc('_', file);
556 }
557
558
559 void printID(utf *u)
560 {
561         char *utf_ptr = u->text;
562         int i;
563
564         for (i = 0; i < utf_get_number_of_u2s(u); i++) 
565                 printIDpart(utf_nextu2(&utf_ptr));
566 }
567
568
569 static void addoutputsize (int len)
570 {
571         u4 newsize,i;
572         if (!dopadding) return;
573
574         newsize = MEMORY_ALIGN(outputsize, len);
575         
576         for (i = outputsize; i < newsize; i++) fprintf(file, "   u1 pad%d\n", (int) i);
577         outputsize = newsize;
578 }
579
580
581 void printOverloadPart(utf *desc)
582 {
583         char *utf_ptr=desc->text;
584         u2 c;
585
586         fprintf(file, "__");
587
588         while ((c = utf_nextu2(&utf_ptr)) != ')') {
589                 switch (c) {
590                 case 'I':
591                 case 'S':
592                 case 'B':
593                 case 'C':
594                 case 'Z':
595                 case 'J':
596                 case 'F':
597                 case 'D': 
598                         fprintf(file, "%c", (char) c);
599                         break;
600                 case '[':
601                         fprintf(file, "_3");
602                         break;
603                 case 'L':
604                         putc('L', file);
605                         while ((c = utf_nextu2(&utf_ptr)) != ';')
606                                 printIDpart(c);
607                         fprintf(file, "_2");
608                         break;
609                 case '(':
610                         break;
611                 default: 
612                         log_text("invalid method descriptor");
613                         assert(0);
614                 }
615         }
616 }
617
618 static char *printtype(char *utf_ptr)
619 {
620         u2 c;
621
622         switch (utf_nextu2(&utf_ptr)) {
623         case 'V': fprintf (file, "void");
624                 break;
625         case 'I':
626         case 'S':
627         case 'B':
628         case 'C':
629         case 'Z': addoutputsize (4);
630                 fprintf (file, "s4");
631                 break;
632         case 'J': addoutputsize (8);
633                 fprintf (file, "s8");
634                 break;
635         case 'F': addoutputsize (4);
636                 fprintf (file, "float");
637                 break;
638         case 'D': addoutputsize (8);
639                 fprintf (file, "double");
640                 break;
641         case '[':
642                 addoutputsize ( sizeof(java_arrayheader*) ); 
643                 switch (utf_nextu2(&utf_ptr)) {
644                 case 'I':  fprintf (file, "java_intarray*"); break;
645                 case 'J':  fprintf (file, "java_longarray*"); break;
646                 case 'Z':  fprintf (file, "java_booleanarray*"); break;
647                 case 'B':  fprintf (file, "java_bytearray*"); break;
648                 case 'S':  fprintf (file, "java_shortarray*"); break;
649                 case 'C':  fprintf (file, "java_chararray*"); break;
650                 case 'F':  fprintf (file, "java_floatarray*"); break;
651                 case 'D':  fprintf (file, "java_doublearray*"); break;
652                                 
653                 case '[': fprintf(file, "java_objectarray*");
654                         while ((c = utf_nextu2(&utf_ptr)) == '[');
655                         if (c == 'L')
656                                 while (utf_nextu2(&utf_ptr) != ';');
657                         break;
658                            
659                 case 'L':  fprintf(file, "java_objectarray*");
660                         while (utf_nextu2(&utf_ptr) != ';');
661                         break;
662                 default:
663                         log_text("invalid type descriptor");
664                         assert(0);
665                 }
666                 break;
667                 
668         case 'L': 
669                 addoutputsize ( sizeof(java_objectheader*));
670                 fprintf (file, "struct ");
671                 while ( (c = utf_nextu2(&utf_ptr)) != ';' ) printIDpart (c);     
672                 fprintf (file, "*");
673                 break;
674                                         
675         default:
676                 log_text("Unknown type in field descriptor");
677                 assert(0);
678         }
679         
680         return utf_ptr;
681 }
682
683
684 /***** determine the number of entries of a utf string in the ident chain *****/
685
686 static int searchidentchain_utf(utf *ident) 
687 {
688         utf *u = chain_first(ident_chain);     /* first element of list */
689         int count = 0;
690
691         while (u) {
692                 if (u==ident) count++;         /* string found */
693                 u = chain_next(ident_chain);   /* next element in list */ 
694         }
695
696         return count;
697 }
698
699
700 /************** print structure for direct access to objects ******************/
701
702 static void printfields(classinfo *c)
703 {
704         u4 i;
705         fieldinfo *f;
706         int ident_count;
707         
708         if (!c) {
709                 addoutputsize(sizeof(java_objectheader));
710                 fprintf(file, "   java_objectheader header;\n");
711                 return;
712         }
713                 
714         printfields(c->super.cls);
715         
716         for (i = 0; i < c->fieldscount; i++) {
717                 f = &(c->fields[i]);
718                 
719                 if (!(f->flags & ACC_STATIC)) {
720                         fprintf(file, "   ");
721                         printtype(f->descriptor->text);
722                         fprintf(file, " ");
723                         utf_fprint_printable_ascii(file, f->name);
724
725                         /* rename multiple fieldnames */
726                         if ((ident_count = searchidentchain_utf(f->name)))
727                                 fprintf(file, "%d", ident_count - 1);
728                         chain_addlast(ident_chain, f->name);    
729
730                         fprintf(file, ";\n");
731                 }
732         }
733 }
734
735
736 /***************** store prototype for native method in file ******************/
737
738 void printmethod(methodinfo *m)
739 {
740         char *utf_ptr;
741         u2 paramnum = 1;
742
743         /* search for return-type in descriptor */      
744         utf_ptr = m->descriptor->text;
745         while (utf_nextu2(&utf_ptr) != ')');
746
747         /* create remarks */
748         fprintf(file, "\n/*\n * Class:     ");
749         utf_fprint_printable_ascii(file, m->class->name);
750         fprintf(file, "\n * Method:    ");
751         utf_fprint_printable_ascii(file, m->name);
752         fprintf(file, "\n * Signature: ");
753         utf_fprint_printable_ascii(file, m->descriptor);
754         fprintf(file, "\n */\n");
755
756         /* create prototype */                  
757         fprintf(file, "JNIEXPORT ");
758         printtype(utf_ptr);
759         fprintf(file, " JNICALL Java_");
760         printID(m->class->name);
761
762         chain_addlast(ident_chain, m->name);
763
764         fprintf(file, "_");
765         printID(m->name);
766
767         /* ATTENTION: We use a dummy flag here. */
768
769         if (m->flags & ACC_NATIVELY_OVERLOADED)
770                 printOverloadPart(m->descriptor);
771
772         fprintf(file, "(JNIEnv *env");
773         
774         utf_ptr = m->descriptor->text + 1;
775                         
776         if (!(m->flags & ACC_STATIC)) {
777                 fprintf(file, ", struct ");
778                 printID(m->class->name);
779                 fprintf(file, "* this");
780
781         } else {
782                 fprintf(file, ", jclass clazz");
783         }
784
785         if ((*utf_ptr) != ')') fprintf(file, ", ");
786                         
787         while ((*utf_ptr) != ')') {
788                 utf_ptr = printtype(utf_ptr);
789                 fprintf(file, " par%d", paramnum++);
790                 if ((*utf_ptr)!=')') fprintf(file, ", ");
791         }
792                         
793         fprintf(file, ");\n\n");
794 }
795
796
797 /******* remove package-name in fully-qualified classname *********************/
798
799 void gen_header_filename(char *buffer, utf *u)
800 {
801         s4 i;
802   
803         for (i = 0; i < utf_get_number_of_u2s(u); i++) {
804                 if ((u->text[i] == '/') || (u->text[i] == '$')) {
805                         buffer[i] = '_';  /* convert '$' and '/' to '_' */
806
807                 } else {
808                         buffer[i] = u->text[i];
809                 }
810         }
811         buffer[utf_get_number_of_u2s(u)] = '\0';
812 }
813
814
815 /* create headerfile for classes and store native methods in chain ************/
816
817 void headerfile_generate(classinfo *c, char *opt_directory)
818 {
819         char header_filename[1024] = "";
820         char classname[1024]; 
821         char uclassname[1024];
822         u2 i;
823         methodinfo *m;                  
824         u2 j;
825         methodinfo *m2;
826         bool nativelyoverloaded;
827
828         /* prevent compiler warnings */
829
830         nativelyoverloaded = false;
831
832         /* open headerfile for class */
833         gen_header_filename(classname, c->name);
834
835         /* create chain for renaming fields */
836         ident_chain = chain_new();
837         
838         if (opt_directory) {
839                 sprintf(header_filename, "%s/%s.h", opt_directory, classname);
840
841         } else {
842                 sprintf(header_filename, "%s.h", classname);
843         }
844
845         file = fopen(header_filename, "w");
846         if (!file) {
847                 log_text("Can not open file to store header information");
848                 assert(0);
849         }
850
851         fprintf(file, "/* This file is machine generated, don't edit it! */\n\n");
852
853         /* convert to uppercase */
854         for (i = 0; classname[i]; i++) {
855                 uclassname[i] = toupper(classname[i]);
856         }
857         uclassname[i] = '\0';
858
859         fprintf(file, "#ifndef _%s_H\n#define _%s_H\n\n", uclassname, uclassname);
860
861         /* create structure for direct access to objects */     
862         fprintf(file, "/* Structure information for class: ");
863         utf_fprint_printable_ascii(file, c->name);
864         fprintf(file, " */\n\n");
865         fprintf(file, "typedef struct ");
866         printID(c->name);                                                       
867         fprintf(file, " {\n");
868         outputsize = 0;
869         dopadding = true;
870
871         printfields(c);
872
873         fprintf(file, "} ");
874         printID(c->name);
875         fprintf(file, ";\n\n");
876
877         /* create chain for renaming overloaded methods */
878         chain_free(ident_chain);
879         ident_chain = chain_new();
880
881         /* create method-prototypes */
882                                 
883         /* find overloaded methods */
884
885         for (i = 0; i < c->methodscount; i++) {
886                 m = &(c->methods[i]);
887
888                 if (!(m->flags & ACC_NATIVE))
889                         continue;
890
891                 /* We use a dummy flag here. */
892
893                 if (!(m->flags & ACC_NATIVELY_OVERLOADED)) {
894                         nativelyoverloaded = false;
895
896                         for (j = i + 1; j < c->methodscount; j++) {
897                                 m2 = &(c->methods[j]);
898
899                                 if (!(m2->flags & ACC_NATIVE))
900                                         continue;
901
902                                 if (m->name == m2->name) {
903                                         m2->flags          |= ACC_NATIVELY_OVERLOADED;
904                                         nativelyoverloaded  = true;
905                                 }
906                         }
907                 }
908
909                 if (nativelyoverloaded == true)
910                         m->flags |= ACC_NATIVELY_OVERLOADED;
911         }
912
913         for (i = 0; i < c->methodscount; i++) {
914                 m = &(c->methods[i]);
915
916                 if (m->flags & ACC_NATIVE)
917                         printmethod(m);
918         }
919
920         chain_free(ident_chain);
921
922         fprintf(file, "#endif\n\n");
923
924         fclose(file);
925 }
926
927
928 /******** print classname, '$' used to seperate inner-class name ***********/
929
930 void print_classname(classinfo *clazz)
931 {
932         utf *u = clazz->name;
933     char *endpos  = u->text + u->blength;
934     char *utf_ptr = u->text; 
935         u2 c;
936
937     while (utf_ptr < endpos) {
938                 if ((c = utf_nextu2(&utf_ptr)) == '_')
939                         putc('$', file);
940                 else
941                         putc(c, file);
942         }
943
944
945 /* jvmti releated functions ************************************************/
946
947 #if defined(ENABLE_JVMTI)
948 void jvmti_ThreadStartEnd(int ev) {;}
949 void jvmti_ClassLoadPrepare(bool prepared, classinfo *c) {;}
950 void jvmti_MonitorContendedEntering(bool entered, jobject obj) {;}
951 #endif
952
953
954
955 /*
956  * These are local overrides for various environment variables in Emacs.
957  * Please do not remove this and leave it at the end of the file, where
958  * Emacs will automagically detect them.
959  * ---------------------------------------------------------------------
960  * Local variables:
961  * mode: c
962  * indent-tabs-mode: t
963  * c-basic-offset: 4
964  * tab-width: 4
965  * End:
966  * vim:noexpandtab:sw=4:ts=4:
967  */