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