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