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