* src/cacaoh/dummy.c (gc_reference_register): Added.
[cacao.git] / src / vmcore / loader.c
1 /* src/vmcore/loader.c - class loader functions
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: loader.c 7921 2007-05-20 23:14:11Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35
36 #include "vm/types.h"
37
38 #include "mm/memory.h"
39
40 #include "threads/lock-common.h"
41
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
44
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/stringlocal.h"
49 #include "vm/vm.h"
50
51 #include "vm/jit_interface.h"
52
53 #if defined(ENABLE_JAVASE)
54 # include "vmcore/annotation.h"
55 # include "vmcore/stackmap.h"
56 #endif
57
58 #include "vmcore/classcache.h"
59 #include "vmcore/linker.h"
60 #include "vmcore/loader.h"
61 #include "vmcore/options.h"
62 #include "vmcore/rt-timing.h"
63
64 #if defined(ENABLE_STATISTICS)
65 # include "vmcore/statistics.h"
66 #endif
67
68 #include "vmcore/suck.h"
69
70 #if defined(ENABLE_ZLIB)
71 # include "vmcore/zip.h"
72 #endif
73
74 #if defined(ENABLE_JVMTI)
75 # include "native/jvmti/cacaodbg.h"
76 #endif
77
78
79 /* global variables ***********************************************************/
80
81 static hashtable *hashtable_classloader;
82
83
84 /* loader_init *****************************************************************
85
86    Initializes all lists and loads all classes required for the system
87    or the compiler.
88
89 *******************************************************************************/
90  
91 bool loader_init(void)
92 {
93 #if defined(ENABLE_THREADS)
94         list_classpath_entry *lce;
95
96         /* Initialize the monitor pointer for zip/jar file locking. */
97
98         for (lce = list_first(list_classpath_entries); lce != NULL;
99                  lce = list_next(list_classpath_entries, lce))
100                 if (lce->type == CLASSPATH_ARCHIVE)
101                         LOCK_INIT_OBJECT_LOCK(lce);
102 #endif
103
104         /* initialize classloader hashtable, 10 entries should be enough */
105
106         hashtable_classloader = NEW(hashtable);
107         hashtable_create(hashtable_classloader, 10);
108
109         /* load some important classes */
110
111         if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
112                 return false;
113
114         if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
115                 return false;
116
117 #if defined(ENABLE_JAVASE)
118         if (!(class_java_lang_Cloneable =
119                   load_class_bootstrap(utf_java_lang_Cloneable)))
120                 return false;
121
122         if (!(class_java_io_Serializable =
123                   load_class_bootstrap(utf_java_io_Serializable)))
124                 return false;
125 #endif
126
127         /* load classes for wrapping primitive types */
128
129 #if defined(ENABLE_JAVASE)
130         if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
131                 return false;
132 #endif
133
134         if (!(class_java_lang_Boolean =
135                   load_class_bootstrap(utf_java_lang_Boolean)))
136                 return false;
137
138         if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
139                 return false;
140
141         if (!(class_java_lang_Character =
142                   load_class_bootstrap(utf_java_lang_Character)))
143                 return false;
144
145         if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
146                 return false;
147
148         if (!(class_java_lang_Integer =
149                   load_class_bootstrap(utf_java_lang_Integer)))
150                 return false;
151
152         if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
153                 return false;
154
155         if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
156                 return false;
157
158         if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
159                 return false;
160
161
162         /* load some other important classes */
163
164         if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
165                 return false;
166
167 #if defined(ENABLE_JAVASE)
168         if (!(class_java_lang_ClassLoader =
169                   load_class_bootstrap(utf_java_lang_ClassLoader)))
170                 return false;
171
172         if (!(class_java_lang_SecurityManager =
173                   load_class_bootstrap(utf_java_lang_SecurityManager)))
174                 return false;
175 #endif
176
177         if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
178                 return false;
179
180         if (!(class_java_lang_Thread =
181                   load_class_bootstrap(utf_new_char("java/lang/Thread"))))
182                 return false;
183
184 #if defined(ENABLE_JAVASE)
185         if (!(class_java_lang_ThreadGroup =
186                   load_class_bootstrap(utf_java_lang_ThreadGroup)))
187                 return false;
188 #endif
189
190 #if defined(WITH_CLASSPATH_GNU)
191         if (!(class_java_lang_VMSystem =
192                   load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
193
194                 return false;
195
196         if (!(class_java_lang_VMThread =
197                   load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
198                 return false;
199 #endif
200
201
202         /* some classes which may be used more often */
203
204 #if defined(ENABLE_JAVASE)
205         if (!(class_java_lang_StackTraceElement =
206                   load_class_bootstrap(utf_java_lang_StackTraceElement)))
207                 return false;
208
209         if (!(class_java_lang_reflect_Constructor =
210                   load_class_bootstrap(utf_java_lang_reflect_Constructor)))
211                 return false;
212
213         if (!(class_java_lang_reflect_Field =
214                   load_class_bootstrap(utf_java_lang_reflect_Field)))
215                 return false;
216
217         if (!(class_java_lang_reflect_Method =
218                   load_class_bootstrap(utf_java_lang_reflect_Method)))
219                 return false;
220
221         if (!(class_java_security_PrivilegedAction =
222                   load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
223                 return false;
224
225         if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
226                 return false;
227
228         if (!(arrayclass_java_lang_Object =
229                   load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
230                 return false;
231 #endif
232
233         return true;
234 }
235
236
237 /* loader_hashtable_classloader_add ********************************************
238
239    Adds an entry to the classloader hashtable.
240
241    REMEMBER: Also use this to register native loaders!
242
243 *******************************************************************************/
244
245 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
246 {
247         hashtable_classloader_entry *cle;
248         u4   key;
249         u4   slot;
250
251         if (cl == NULL)
252                 return NULL;
253
254         LOCK_MONITOR_ENTER(hashtable_classloader->header);
255
256         /* key for entry is the hashcode of the classloader;
257            aligned to 16-byte boundaries */
258
259 #if defined(ENABLE_GC_CACAO)
260         key  = heap_get_hashcode(cl) >> 4;
261 #else
262         key  = ((u4) (ptrint) cl) >> 4;
263 #endif
264
265         slot = key & (hashtable_classloader->size - 1);
266         cle  = hashtable_classloader->ptr[slot];
267
268         /* search hashchain for existing entry */
269         /* XXX no GC collection is allowed here, make this a critical section */
270
271         while (cle) {
272                 if (cle->object == cl)
273                         break;
274
275                 cle = cle->hashlink;
276         }
277
278         /* if no classloader was found, we create a new entry here */
279
280         if (cle == NULL) {
281                 cle = NEW(hashtable_classloader_entry);
282
283 #if defined(ENABLE_GC_CACAO)
284                 /* register the classloader object with the GC */
285
286                 gc_reference_register(&(cle->object));
287 #endif
288
289                 cle->object = cl;
290
291                 /* insert entry into hashtable */
292
293                 cle->hashlink = hashtable_classloader->ptr[slot];
294                 hashtable_classloader->ptr[slot] = cle;
295
296                 /* update number of entries */
297
298                 hashtable_classloader->entries++;
299         }
300
301
302         LOCK_MONITOR_EXIT(hashtable_classloader->header);
303
304         return cle;
305 }
306
307
308 /* loader_hashtable_classloader_find *******************************************
309
310    Find an entry in the classloader hashtable.
311
312 *******************************************************************************/
313
314 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
315 {
316         hashtable_classloader_entry *cle;
317         u4   key;
318         u4   slot;
319
320         if (cl == NULL)
321                 return NULL;
322
323         /* key for entry is the hashcode of the classloader;
324            aligned to 16-byte boundaries */
325
326 #if defined(ENABLE_GC_CACAO)
327         key  = heap_get_hashcode(cl) >> 4;
328 #else
329         key  = ((u4) (ptrint) cl) >> 4;
330 #endif
331
332         slot = key & (hashtable_classloader->size - 1);
333         cle  = hashtable_classloader->ptr[slot];
334
335         /* search hashchain for existing entry */
336         /* XXX no GC collection is allowed here, make this a critical section */
337
338         while (cle) {
339                 if (cle->object == cl)
340                         break;
341
342                 cle = cle->hashlink;
343         }
344
345         return cle;
346 }
347
348
349 /* loader_load_all_classes *****************************************************
350
351    Loads all classes specified in the BOOTCLASSPATH.
352
353 *******************************************************************************/
354
355 void loader_load_all_classes(void)
356 {
357         list_classpath_entry    *lce;
358 #if defined(ENABLE_ZLIB)
359         hashtable               *ht;
360         s4                       slot;
361         hashtable_zipfile_entry *htzfe;
362         utf                     *u;
363 #endif
364
365         for (lce = list_first(list_classpath_entries); lce != NULL;
366                  lce = list_next(list_classpath_entries, lce)) {
367 #if defined(ENABLE_ZLIB)
368                 if (lce->type == CLASSPATH_ARCHIVE) {
369                         /* get the classes hashtable */
370
371                         ht = lce->htclasses;
372
373                         for (slot = 0; slot < ht->size; slot++) {
374                                 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
375
376                                 for (; htzfe; htzfe = htzfe->hashlink) {
377                                         u = htzfe->filename;
378
379                                         /* skip all entries in META-INF and .properties,
380                        .png files */
381
382                                         if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
383                                                 strstr(u->text, ".properties") ||
384                                                 strstr(u->text, ".png"))
385                                                 continue;
386
387                                         /* load class from bootstrap classloader */
388
389                                         if (!load_class_bootstrap(u)) {
390                                                 fprintf(stderr, "Error loading: ");
391                                                 utf_fprint_printable_ascii_classname(stderr, u);
392                                                 fprintf(stderr, "\n");
393
394 #if !defined(NDEBUG)
395                                                 /* print out exception and cause */
396
397                                                 exceptions_print_current_exception();
398 #endif
399                                         }
400                                 }
401                         }
402
403                 } else {
404 #endif
405 #if defined(ENABLE_ZLIB)
406                 }
407 #endif
408         }
409 }
410
411
412 /* loader_skip_attribute_body **************************************************
413
414    Skips an attribute the attribute_name_index has already been read.
415         
416    attribute_info {
417        u2 attribute_name_index;
418        u4 attribute_length;
419        u1 info[attribute_length];
420    }
421
422 *******************************************************************************/
423
424 bool loader_skip_attribute_body(classbuffer *cb)
425 {
426         u4 attribute_length;
427
428         if (!suck_check_classbuffer_size(cb, 4))
429                 return false;
430
431         attribute_length = suck_u4(cb);
432
433         if (!suck_check_classbuffer_size(cb, attribute_length))
434                 return false;
435
436         suck_skip_nbytes(cb, attribute_length);
437
438         return true;
439 }
440
441
442 /* load_constantpool ***********************************************************
443
444    Loads the constantpool of a class, the entries are transformed into
445    a simpler format by resolving references (a detailed overview of
446    the compact structures can be found in global.h).
447
448 *******************************************************************************/
449
450 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
451 {
452
453         /* The following structures are used to save information which cannot be 
454            processed during the first pass. After the complete constantpool has 
455            been traversed the references can be resolved. 
456            (only in specific order)                                                */
457         
458         /* CONSTANT_Class entries */
459         typedef struct forward_class {
460                 struct forward_class *next;
461                 u2 thisindex;
462                 u2 name_index;
463         } forward_class;
464
465         /* CONSTANT_String */
466         typedef struct forward_string {
467                 struct forward_string *next;
468                 u2 thisindex;
469                 u2 string_index;
470         } forward_string;
471
472         /* CONSTANT_NameAndType */
473         typedef struct forward_nameandtype {
474                 struct forward_nameandtype *next;
475                 u2 thisindex;
476                 u2 name_index;
477                 u2 sig_index;
478         } forward_nameandtype;
479
480         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
481         typedef struct forward_fieldmethint {
482                 struct forward_fieldmethint *next;
483                 u2 thisindex;
484                 u1 tag;
485                 u2 class_index;
486                 u2 nameandtype_index;
487         } forward_fieldmethint;
488
489
490         classinfo *c;
491         u4 idx;
492
493         forward_class *forward_classes = NULL;
494         forward_string *forward_strings = NULL;
495         forward_nameandtype *forward_nameandtypes = NULL;
496         forward_fieldmethint *forward_fieldmethints = NULL;
497
498         forward_class *nfc;
499         forward_string *nfs;
500         forward_nameandtype *nfn;
501         forward_fieldmethint *nff;
502
503         u4 cpcount;
504         u1 *cptags;
505         voidptr *cpinfos;
506
507         c = cb->class;
508
509         /* number of entries in the constant_pool table plus one */
510         if (!suck_check_classbuffer_size(cb, 2))
511                 return false;
512
513         cpcount = c->cpcount = suck_u2(cb);
514
515         /* allocate memory */
516         cptags  = c->cptags  = MNEW(u1, cpcount);
517         cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
518
519         if (cpcount < 1) {
520                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
521                 return false;
522         }
523         
524 #if defined(ENABLE_STATISTICS)
525         if (opt_stat)
526                 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
527 #endif
528         
529         /* initialize constantpool */
530         for (idx = 0; idx < cpcount; idx++) {
531                 cptags[idx] = CONSTANT_UNUSED;
532                 cpinfos[idx] = NULL;
533         }
534
535                         
536         /******* first pass *******/
537         /* entries which cannot be resolved now are written into 
538            temporary structures and traversed again later        */
539                    
540         idx = 1;
541         while (idx < cpcount) {
542                 u4 t;
543
544                 /* get constant type */
545                 if (!suck_check_classbuffer_size(cb, 1))
546                         return false;
547
548                 t = suck_u1(cb);
549
550                 switch (t) {
551                 case CONSTANT_Class:
552                         nfc = DNEW(forward_class);
553
554                         nfc->next = forward_classes;
555                         forward_classes = nfc;
556
557                         nfc->thisindex = idx;
558                         /* reference to CONSTANT_NameAndType */
559                         if (!suck_check_classbuffer_size(cb, 2))
560                                 return false;
561
562                         nfc->name_index = suck_u2(cb);
563
564                         idx++;
565                         break;
566                         
567                 case CONSTANT_String:
568                         nfs = DNEW(forward_string);
569                                 
570                         nfs->next = forward_strings;
571                         forward_strings = nfs;
572                                 
573                         nfs->thisindex = idx;
574
575                         /* reference to CONSTANT_Utf8_info with string characters */
576                         if (!suck_check_classbuffer_size(cb, 2))
577                                 return false;
578
579                         nfs->string_index = suck_u2(cb);
580                                 
581                         idx++;
582                         break;
583
584                 case CONSTANT_NameAndType:
585                         nfn = DNEW(forward_nameandtype);
586                                 
587                         nfn->next = forward_nameandtypes;
588                         forward_nameandtypes = nfn;
589                                 
590                         nfn->thisindex = idx;
591
592                         if (!suck_check_classbuffer_size(cb, 2 + 2))
593                                 return false;
594
595                         /* reference to CONSTANT_Utf8_info containing simple name */
596                         nfn->name_index = suck_u2(cb);
597
598                         /* reference to CONSTANT_Utf8_info containing field or method
599                            descriptor */
600                         nfn->sig_index = suck_u2(cb);
601                                 
602                         idx++;
603                         break;
604
605                 case CONSTANT_Fieldref:
606                 case CONSTANT_Methodref:
607                 case CONSTANT_InterfaceMethodref:
608                         nff = DNEW(forward_fieldmethint);
609                         
610                         nff->next = forward_fieldmethints;
611                         forward_fieldmethints = nff;
612
613                         nff->thisindex = idx;
614                         /* constant type */
615                         nff->tag = t;
616
617                         if (!suck_check_classbuffer_size(cb, 2 + 2))
618                                 return false;
619
620                         /* class or interface type that contains the declaration of the
621                            field or method */
622                         nff->class_index = suck_u2(cb);
623
624                         /* name and descriptor of the field or method */
625                         nff->nameandtype_index = suck_u2(cb);
626
627                         idx++;
628                         break;
629                                 
630                 case CONSTANT_Integer: {
631                         constant_integer *ci = NEW(constant_integer);
632
633 #if defined(ENABLE_STATISTICS)
634                         if (opt_stat)
635                                 count_const_pool_len += sizeof(constant_integer);
636 #endif
637
638                         if (!suck_check_classbuffer_size(cb, 4))
639                                 return false;
640
641                         ci->value = suck_s4(cb);
642                         cptags[idx] = CONSTANT_Integer;
643                         cpinfos[idx] = ci;
644
645                         idx++;
646                         break;
647                 }
648                                 
649                 case CONSTANT_Float: {
650                         constant_float *cf = NEW(constant_float);
651
652 #if defined(ENABLE_STATISTICS)
653                         if (opt_stat)
654                                 count_const_pool_len += sizeof(constant_float);
655 #endif
656
657                         if (!suck_check_classbuffer_size(cb, 4))
658                                 return false;
659
660                         cf->value = suck_float(cb);
661                         cptags[idx] = CONSTANT_Float;
662                         cpinfos[idx] = cf;
663
664                         idx++;
665                         break;
666                 }
667                                 
668                 case CONSTANT_Long: {
669                         constant_long *cl = NEW(constant_long);
670                                         
671 #if defined(ENABLE_STATISTICS)
672                         if (opt_stat)
673                                 count_const_pool_len += sizeof(constant_long);
674 #endif
675
676                         if (!suck_check_classbuffer_size(cb, 8))
677                                 return false;
678
679                         cl->value = suck_s8(cb);
680                         cptags[idx] = CONSTANT_Long;
681                         cpinfos[idx] = cl;
682                         idx += 2;
683                         if (idx > cpcount) {
684                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
685                                 return false;
686                         }
687                         break;
688                 }
689                         
690                 case CONSTANT_Double: {
691                         constant_double *cd = NEW(constant_double);
692                                 
693 #if defined(ENABLE_STATISTICS)
694                         if (opt_stat)
695                                 count_const_pool_len += sizeof(constant_double);
696 #endif
697
698                         if (!suck_check_classbuffer_size(cb, 8))
699                                 return false;
700
701                         cd->value = suck_double(cb);
702                         cptags[idx] = CONSTANT_Double;
703                         cpinfos[idx] = cd;
704                         idx += 2;
705                         if (idx > cpcount) {
706                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
707                                 return false;
708                         }
709                         break;
710                 }
711                                 
712                 case CONSTANT_Utf8: { 
713                         u4 length;
714
715                         /* number of bytes in the bytes array (not string-length) */
716                         if (!suck_check_classbuffer_size(cb, 2))
717                                 return false;
718
719                         length = suck_u2(cb);
720                         cptags[idx] = CONSTANT_Utf8;
721
722                         /* validate the string */
723                         if (!suck_check_classbuffer_size(cb, length))
724                                 return false;
725
726 #ifdef ENABLE_VERIFIER
727                         if (opt_verify &&
728                                 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
729                         {
730                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
731                                 return false;
732                         }
733 #endif /* ENABLE_VERIFIER */
734                         /* insert utf-string into the utf-symboltable */
735                         cpinfos[idx] = utf_new((char *) cb->pos, length);
736
737                         /* skip bytes of the string (buffer size check above) */
738                         suck_skip_nbytes(cb, length);
739                         idx++;
740                         break;
741                 }
742                                                                                 
743                 default:
744                         exceptions_throw_classformaterror(c, "Illegal constant pool type");
745                         return false;
746                 }  /* end switch */
747         } /* end while */
748
749
750         /* resolve entries in temporary structures */
751
752         while (forward_classes) {
753                 utf *name =
754                         class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
755                 if (!name)
756                         return false;
757
758 #ifdef ENABLE_VERIFIER
759                 if (opt_verify && !is_valid_name_utf(name)) {
760                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
761                         return false;
762                 }
763 #endif /* ENABLE_VERIFIER */
764
765                 /* add all class references to the descriptor_pool */
766
767                 if (!descriptor_pool_add_class(descpool, name))
768                         return false;
769
770                 cptags[forward_classes->thisindex] = CONSTANT_Class;
771
772                 if (opt_eager) {
773                         classinfo *tc;
774
775                         if (!(tc = load_class_bootstrap(name)))
776                                 return false;
777
778                         /* link the class later, because we cannot link the class currently
779                            loading */
780                         list_add_first(&unlinkedclasses, tc);
781                 }
782
783                 /* the classref is created later */
784                 cpinfos[forward_classes->thisindex] = name;
785
786                 nfc = forward_classes;
787                 forward_classes = forward_classes->next;
788         }
789
790         while (forward_strings) {
791                 utf *text =
792                         class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
793                 if (!text)
794                         return false;
795
796                 /* resolve utf-string */
797                 cptags[forward_strings->thisindex] = CONSTANT_String;
798                 cpinfos[forward_strings->thisindex] = text;
799                 
800                 nfs = forward_strings;
801                 forward_strings = forward_strings->next;
802         }
803
804         while (forward_nameandtypes) {
805                 constant_nameandtype *cn = NEW(constant_nameandtype);   
806
807 #if defined(ENABLE_STATISTICS)
808                 if (opt_stat)
809                         count_const_pool_len += sizeof(constant_nameandtype);
810 #endif
811
812                 /* resolve simple name and descriptor */
813                 cn->name = class_getconstant(c,
814                                                                          forward_nameandtypes->name_index,
815                                                                          CONSTANT_Utf8);
816                 if (!cn->name)
817                         return false;
818
819                 cn->descriptor = class_getconstant(c,
820                                                                                    forward_nameandtypes->sig_index,
821                                                                                    CONSTANT_Utf8);
822                 if (!cn->descriptor)
823                         return false;
824
825 #ifdef ENABLE_VERIFIER
826                 if (opt_verify) {
827                         /* check name */
828                         if (!is_valid_name_utf(cn->name)) {
829                                 exceptions_throw_classformaterror(c,
830                                                                                                   "Illegal Field name \"%s\"",
831                                                                                                   cn->name->text);
832
833                                 return false;
834                         }
835
836                         /* disallow referencing <clinit> among others */
837                         if (cn->name->text[0] == '<' && cn->name != utf_init) {
838                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
839                                 return false;
840                         }
841                 }
842 #endif /* ENABLE_VERIFIER */
843
844                 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
845                 cpinfos[forward_nameandtypes->thisindex] = cn;
846
847                 nfn = forward_nameandtypes;
848                 forward_nameandtypes = forward_nameandtypes->next;
849         }
850
851         while (forward_fieldmethints) {
852                 constant_nameandtype *nat;
853                 constant_FMIref *fmi = NEW(constant_FMIref);
854
855 #if defined(ENABLE_STATISTICS)
856                 if (opt_stat)
857                         count_const_pool_len += sizeof(constant_FMIref);
858 #endif
859                 /* resolve simple name and descriptor */
860
861                 nat = class_getconstant(c,
862                                                                 forward_fieldmethints->nameandtype_index,
863                                                                 CONSTANT_NameAndType);
864                 if (!nat)
865                         return false;
866
867                 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
868
869                 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
870                         return false;
871
872                 /* the classref is created later */
873
874                 fmi->p.index = forward_fieldmethints->class_index;
875                 fmi->name = nat->name;
876                 fmi->descriptor = nat->descriptor;
877
878                 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
879                 cpinfos[forward_fieldmethints->thisindex] = fmi;
880         
881                 nff = forward_fieldmethints;
882                 forward_fieldmethints = forward_fieldmethints->next;
883         }
884
885         /* everything was ok */
886
887         return true;
888 }
889
890
891 /* loader_load_attribute_signature *********************************************
892
893    Signature_attribute {
894        u2 attribute_name_index;
895            u4 atrribute_length;
896            u2 signature_index;
897    }
898
899 *******************************************************************************/
900
901 #if defined(ENABLE_JAVASE)
902 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
903 {
904         classinfo *c;
905         u4         attribute_length;
906         u2         signature_index;
907
908         /* get classinfo */
909
910         c = cb->class;
911
912         /* check remaining bytecode */
913
914         if (!suck_check_classbuffer_size(cb, 4 + 2))
915                 return false;
916
917         /* check attribute length */
918
919         attribute_length = suck_u4(cb);
920
921         if (attribute_length != 2) {
922                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
923                 return false;
924         }
925
926         if (*signature != NULL) {
927                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
928                 return false;
929         }
930
931         /* get signature */
932
933         signature_index = suck_u2(cb);
934
935         if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
936                 return false;
937
938         return true;
939 }
940 #endif /* defined(ENABLE_JAVASE) */
941
942
943 /* load_field ******************************************************************
944
945    Load everything about a class field from the class file and fill a
946    'fieldinfo' structure. For static fields, space in the data segment
947    is allocated.
948
949 *******************************************************************************/
950
951 #define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
952
953 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
954 {
955         classinfo *c;
956         u4 attrnum, i;
957         u4 jtype;
958         u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
959         utf *u;
960
961         c = cb->class;
962
963         if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
964                 return false;
965
966         f->flags = suck_u2(cb);
967
968         if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
969                 return false;
970
971         f->name = u;
972
973         if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
974                 return false;
975
976         f->descriptor = u;
977         f->parseddesc = NULL;
978
979         if (!descriptor_pool_add(descpool, u, NULL))
980                 return false;
981
982         /* descriptor_pool_add accepts method descriptors, so we have to check  */
983         /* against them here before the call of descriptor_to_basic_type below. */
984         if (u->text[0] == '(') {
985                 exceptions_throw_classformaterror(c, "Method descriptor used for field");
986                 return false;
987         }
988
989 #ifdef ENABLE_VERIFIER
990         if (opt_verify) {
991                 /* check name */
992                 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
993                         exceptions_throw_classformaterror(c,
994                                                                                           "Illegal Field name \"%s\"",
995                                                                                           f->name->text);
996                         return false;
997                 }
998
999                 /* check flag consistency */
1000                 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
1001
1002                 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
1003                         ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
1004                         exceptions_throw_classformaterror(c,
1005                                                                                           "Illegal field modifiers: 0x%X",
1006                                                                                           f->flags);
1007                         return false;
1008                 }
1009
1010                 if (c->flags & ACC_INTERFACE) {
1011                         if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1012                                 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1013                                 f->flags & ACC_TRANSIENT) {
1014                                 exceptions_throw_classformaterror(c,
1015                                                                                                   "Illegal field modifiers: 0x%X",
1016                                                                                                   f->flags);
1017                                 return false;
1018                         }
1019                 }
1020         }
1021 #endif /* ENABLE_VERIFIER */
1022
1023         f->type   = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1024         f->offset = 0;                             /* offset from start of object */
1025         f->class  = c;
1026
1027         switch (f->type) {
1028         case TYPE_INT:
1029                 f->value.i = 0;
1030                 break;
1031
1032         case TYPE_FLT:
1033                 f->value.f = 0.0;
1034                 break;
1035
1036         case TYPE_DBL:
1037                 f->value.d = 0.0;
1038                 break;
1039
1040         case TYPE_ADR:
1041                 f->value.a = NULL;
1042                 if (!(f->flags & ACC_STATIC))
1043                         c->flags |= ACC_CLASS_HAS_POINTERS;
1044                 break;
1045
1046         case TYPE_LNG:
1047 #if U8_AVAILABLE
1048                 f->value.l = 0;
1049 #else
1050                 f->value.l.low  = 0;
1051                 f->value.l.high = 0;
1052 #endif
1053                 break;
1054         }
1055
1056         /* read attributes */
1057         if (!suck_check_classbuffer_size(cb, 2))
1058                 return false;
1059
1060         attrnum = suck_u2(cb);
1061         for (i = 0; i < attrnum; i++) {
1062                 if (!suck_check_classbuffer_size(cb, 2))
1063                         return false;
1064
1065                 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1066                         return false;
1067
1068                 if (u == utf_ConstantValue) {
1069                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1070                                 return false;
1071
1072                         /* check attribute length */
1073
1074                         if (suck_u4(cb) != 2) {
1075                                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1076                                 return false;
1077                         }
1078                         
1079                         /* constant value attribute */
1080
1081                         if (pindex != field_load_NOVALUE) {
1082                                 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1083                                 return false;
1084                         }
1085                         
1086                         /* index of value in constantpool */
1087
1088                         pindex = suck_u2(cb);
1089                 
1090                         /* initialize field with value from constantpool */             
1091                         switch (jtype) {
1092                         case TYPE_INT: {
1093                                 constant_integer *ci; 
1094
1095                                 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1096                                         return false;
1097
1098                                 f->value.i = ci->value;
1099                         }
1100                         break;
1101                                         
1102                         case TYPE_LNG: {
1103                                 constant_long *cl; 
1104
1105                                 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1106                                         return false;
1107
1108                                 f->value.l = cl->value;
1109                         }
1110                         break;
1111
1112                         case TYPE_FLT: {
1113                                 constant_float *cf;
1114
1115                                 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1116                                         return false;
1117
1118                                 f->value.f = cf->value;
1119                         }
1120                         break;
1121                                                                                         
1122                         case TYPE_DBL: {
1123                                 constant_double *cd;
1124
1125                                 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1126                                         return false;
1127
1128                                 f->value.d = cd->value;
1129                         }
1130                         break;
1131                                                 
1132                         case TYPE_ADR:
1133                                 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1134                                         return false;
1135
1136                                 /* create javastring from compressed utf8-string */
1137                                 f->value.a = literalstring_new(u);
1138                                 break;
1139         
1140                         default: 
1141                                 log_text("Invalid Constant - Type");
1142                         }
1143                 }
1144 #if defined(ENABLE_JAVASE)
1145                 else if (u == utf_Signature) {
1146                         /* Signature */
1147
1148                         if (!loader_load_attribute_signature(cb, &(f->signature)))
1149                                 return false;
1150                 }
1151 #endif
1152                 else {
1153                         /* unknown attribute */
1154
1155                         if (!loader_skip_attribute_body(cb))
1156                                 return false;
1157                 }
1158         }
1159
1160         /* everything was ok */
1161
1162         return true;
1163 }
1164
1165
1166 /* loader_load_method **********************************************************
1167
1168    Loads a method from the class file and fills an existing
1169    'methodinfo' structure. For native methods, the function pointer
1170    field is set to the real function pointer, for JavaVM methods a
1171    pointer to the compiler is used preliminarily.
1172
1173    method_info {
1174        u2 access_flags;
1175            u2 name_index;
1176            u2 descriptor_index;
1177            u2 attributes_count;
1178            attribute_info attributes[attribute_count];
1179    }
1180
1181    attribute_info {
1182        u2 attribute_name_index;
1183            u4 attribute_length;
1184            u1 info[attribute_length];
1185    }
1186
1187    LineNumberTable_attribute {
1188        u2 attribute_name_index;
1189            u4 attribute_length;
1190            u2 line_number_table_length;
1191            {
1192                u2 start_pc;
1193                    u2 line_number;
1194            } line_number_table[line_number_table_length];
1195    }
1196
1197 *******************************************************************************/
1198
1199 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1200                                                            descriptor_pool *descpool)
1201 {
1202         classinfo *c;
1203         int argcount;
1204         s4         i, j, k, l;
1205         utf       *u;
1206         u2         name_index;
1207         u2         descriptor_index;
1208         u2         attributes_count;
1209         u2         attribute_name_index;
1210         utf       *attribute_name;
1211         u2         code_attributes_count;
1212         u2         code_attribute_name_index;
1213         utf       *code_attribute_name;
1214
1215         /* get classinfo */
1216
1217         c = cb->class;
1218
1219 #if defined(ENABLE_THREADS)
1220         lock_init_object_lock(&m->header);
1221 #endif
1222
1223 #if defined(ENABLE_STATISTICS)
1224         if (opt_stat)
1225                 count_all_methods++;
1226 #endif
1227
1228         /* all fields of m have been zeroed in load_class_from_classbuffer */
1229
1230         m->class = c;
1231         
1232         if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
1233                 return false;
1234
1235         /* access flags */
1236
1237         m->flags = suck_u2(cb);
1238
1239         /* name */
1240
1241         name_index = suck_u2(cb);
1242
1243         if (!(u = class_getconstant(c, name_index, CONSTANT_Utf8)))
1244                 return false;
1245
1246         m->name = u;
1247
1248         /* descriptor */
1249
1250         descriptor_index = suck_u2(cb);
1251
1252         if (!(u = class_getconstant(c, descriptor_index, CONSTANT_Utf8)))
1253                 return false;
1254
1255         m->descriptor = u;
1256
1257         if (!descriptor_pool_add(descpool, u, &argcount))
1258                 return false;
1259
1260 #ifdef ENABLE_VERIFIER
1261         if (opt_verify) {
1262                 if (!is_valid_name_utf(m->name)) {
1263                         exceptions_throw_classformaterror(c, "Method with invalid name");
1264                         return false;
1265                 }
1266
1267                 if (m->name->text[0] == '<' &&
1268                         m->name != utf_init && m->name != utf_clinit) {
1269                         exceptions_throw_classformaterror(c, "Method with invalid special name");
1270                         return false;
1271                 }
1272         }
1273 #endif /* ENABLE_VERIFIER */
1274         
1275         if (!(m->flags & ACC_STATIC))
1276                 argcount++; /* count the 'this' argument */
1277
1278 #ifdef ENABLE_VERIFIER
1279         if (opt_verify) {
1280                 if (argcount > 255) {
1281                         exceptions_throw_classformaterror(c, "Too many arguments in signature");
1282                         return false;
1283                 }
1284
1285                 /* check flag consistency */
1286                 if (m->name != utf_clinit) {
1287                         i = (m->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED));
1288
1289                         if (i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) {
1290                                 exceptions_throw_classformaterror(c,
1291                                                                                                   "Illegal method modifiers: 0x%X",
1292                                                                                                   m->flags);
1293                                 return false;
1294                         }
1295
1296                         if (m->flags & ACC_ABSTRACT) {
1297                                 if ((m->flags & (ACC_FINAL | ACC_NATIVE | ACC_PRIVATE |
1298                                                                  ACC_STATIC | ACC_STRICT | ACC_SYNCHRONIZED))) {
1299                                         exceptions_throw_classformaterror(c,
1300                                                                                                           "Illegal method modifiers: 0x%X",
1301                                                                                                           m->flags);
1302                                         return false;
1303                                 }
1304                         }
1305
1306                         if (c->flags & ACC_INTERFACE) {
1307                                 if ((m->flags & (ACC_ABSTRACT | ACC_PUBLIC)) != (ACC_ABSTRACT | ACC_PUBLIC)) {
1308                                         exceptions_throw_classformaterror(c,
1309                                                                                                           "Illegal method modifiers: 0x%X",
1310                                                                                                           m->flags);
1311                                         return false;
1312                                 }
1313                         }
1314
1315                         if (m->name == utf_init) {
1316                                 if (m->flags & (ACC_STATIC | ACC_FINAL | ACC_SYNCHRONIZED |
1317                                                                 ACC_NATIVE | ACC_ABSTRACT)) {
1318                                         exceptions_throw_classformaterror(c, "Instance initialization method has invalid flags set");
1319                                         return false;
1320                                 }
1321                         }
1322                 }
1323         }
1324 #endif /* ENABLE_VERIFIER */
1325
1326         /* mark the method as monomorphic until further notice */
1327
1328         m->flags |= ACC_METHOD_MONOMORPHIC;
1329
1330         /* non-abstract methods have an implementation in this class */
1331
1332         if (!(m->flags & ACC_ABSTRACT))
1333                 m->flags |= ACC_METHOD_IMPLEMENTED;
1334                 
1335         if (!suck_check_classbuffer_size(cb, 2))
1336                 return false;
1337
1338         /* attributes count */
1339
1340         attributes_count = suck_u2(cb);
1341
1342         for (i = 0; i < attributes_count; i++) {
1343                 if (!suck_check_classbuffer_size(cb, 2))
1344                         return false;
1345
1346                 /* attribute name index */
1347
1348                 attribute_name_index = suck_u2(cb);
1349
1350                 if (!(attribute_name = class_getconstant(c, attribute_name_index, CONSTANT_Utf8)))
1351                         return false;
1352
1353                 if (attribute_name == utf_Code) {
1354                         /* Code */
1355                         if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1356                                 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1357                                 return false;
1358                         }
1359                         
1360                         if (m->jcode) {
1361                                 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1362                                 return false;
1363                         }
1364
1365                         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1366                                 return false;
1367
1368                         suck_u4(cb);
1369                         m->maxstack = suck_u2(cb);
1370                         m->maxlocals = suck_u2(cb);
1371
1372                         if (m->maxlocals < argcount) {
1373                                 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1374                                 return false;
1375                         }
1376                         
1377                         if (!suck_check_classbuffer_size(cb, 4))
1378                                 return false;
1379
1380                         m->jcodelength = suck_u4(cb);
1381
1382                         if (m->jcodelength == 0) {
1383                                 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1384                                 return false;
1385                         }
1386                         
1387                         if (m->jcodelength > 65535) {
1388                                 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1389                                 return false;
1390                         }
1391
1392                         if (!suck_check_classbuffer_size(cb, m->jcodelength))
1393                                 return false;
1394
1395                         m->jcode = MNEW(u1, m->jcodelength);
1396                         suck_nbytes(m->jcode, cb, m->jcodelength);
1397
1398                         if (!suck_check_classbuffer_size(cb, 2))
1399                                 return false;
1400
1401                         m->rawexceptiontablelength = suck_u2(cb);
1402                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1403                                 return false;
1404
1405                         m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1406
1407 #if defined(ENABLE_STATISTICS)
1408                         if (opt_stat) {
1409                                 count_vmcode_len += m->jcodelength + 18;
1410                                 count_extable_len +=
1411                                         m->rawexceptiontablelength * sizeof(raw_exception_entry);
1412                         }
1413 #endif
1414
1415                         for (j = 0; j < m->rawexceptiontablelength; j++) {
1416                                 u4 idx;
1417                                 m->rawexceptiontable[j].startpc = suck_u2(cb);
1418                                 m->rawexceptiontable[j].endpc = suck_u2(cb);
1419                                 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1420
1421                                 idx = suck_u2(cb);
1422                                 if (!idx) {
1423                                         m->rawexceptiontable[j].catchtype.any = NULL;
1424
1425                                 } else {
1426                                         /* the classref is created later */
1427                                         if (!(m->rawexceptiontable[j].catchtype.any =
1428                                                   (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1429                                                 return false;
1430                                 }
1431                         }
1432
1433                         if (!suck_check_classbuffer_size(cb, 2))
1434                                 return false;
1435
1436                         /* code attributes count */
1437
1438                         code_attributes_count = suck_u2(cb);
1439
1440                         for (k = 0; k < code_attributes_count; k++) {
1441                                 if (!suck_check_classbuffer_size(cb, 2))
1442                                         return false;
1443
1444                                 /* code attribute name index */
1445
1446                                 code_attribute_name_index = suck_u2(cb);
1447
1448                                 if (!(code_attribute_name = class_getconstant(c, code_attribute_name_index, CONSTANT_Utf8)))
1449                                         return false;
1450
1451                                 /* check which code attribute */
1452
1453                                 if (code_attribute_name == utf_LineNumberTable) {
1454                                         /* LineNumberTable */
1455                                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1456                                                 return false;
1457
1458                                         /* attribute length */
1459
1460                                         (void) suck_u4(cb);
1461
1462                                         /* line number table length */
1463
1464                                         m->linenumbercount = suck_u2(cb);
1465
1466                                         if (!suck_check_classbuffer_size(cb,
1467                                                                                                 (2 + 2) * m->linenumbercount))
1468                                                 return false;
1469
1470                                         m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1471
1472 #if defined(ENABLE_STATISTICS)
1473                                         if (opt_stat)
1474                                                 size_lineinfo += sizeof(lineinfo) * m->linenumbercount;
1475 #endif
1476                                         
1477                                         for (l = 0; l < m->linenumbercount; l++) {
1478                                                 m->linenumbers[l].start_pc    = suck_u2(cb);
1479                                                 m->linenumbers[l].line_number = suck_u2(cb);
1480                                         }
1481                                 }
1482 #if defined(ENABLE_JAVASE)
1483                                 else if (code_attribute_name == utf_StackMapTable) {
1484                                         /* StackTableMap */
1485
1486                                         if (!stackmap_load_attribute_stackmaptable(cb, m))
1487                                                 return false;
1488                                 }
1489 #endif
1490                                 else {
1491                                         /* unknown code attribute */
1492
1493                                         if (!loader_skip_attribute_body(cb))
1494                                                 return false;
1495                                 }
1496                         }
1497                 }
1498                 else if (attribute_name == utf_Exceptions) {
1499                         /* Exceptions */
1500
1501                         if (m->thrownexceptions != NULL) {
1502                                 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1503                                 return false;
1504                         }
1505
1506                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1507                                 return false;
1508
1509                         /* attribute length */
1510
1511                         (void) suck_u4(cb);
1512
1513                         m->thrownexceptionscount = suck_u2(cb);
1514
1515                         if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1516                                 return false;
1517
1518                         m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1519
1520                         for (j = 0; j < m->thrownexceptionscount; j++) {
1521                                 /* the classref is created later */
1522                                 if (!((m->thrownexceptions)[j].any =
1523                                           (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1524                                         return false;
1525                         }
1526                 }
1527 #if defined(ENABLE_JAVASE)
1528                 else if (attribute_name == utf_Signature) {
1529                         /* Signature */
1530
1531                         if (!loader_load_attribute_signature(cb, &(m->signature)))
1532                                 return false;
1533                 }
1534 #endif
1535                 else {
1536                         /* unknown attribute */
1537
1538                         if (!loader_skip_attribute_body(cb))
1539                                 return false;
1540                 }
1541         }
1542
1543         if ((m->jcode == NULL) && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1544                 exceptions_throw_classformaterror(c, "Missing Code attribute");
1545                 return false;
1546         }
1547
1548         /* initialize the hit countdown field */
1549
1550 #if defined(ENABLE_REPLACEMENT)
1551         m->hitcountdown = METHOD_INITIAL_HIT_COUNTDOWN;
1552 #endif
1553
1554         /* everything was ok */
1555
1556         return true;
1557 }
1558
1559
1560 /* load_class_from_sysloader ***************************************************
1561
1562    Load the class with the given name using the system class loader
1563
1564    IN:
1565        name.............the classname
1566
1567    RETURN VALUE:
1568        the loaded class, or
1569            NULL if an exception has been thrown
1570
1571 *******************************************************************************/
1572
1573 classinfo *load_class_from_sysloader(utf *name)
1574 {
1575         methodinfo        *m;
1576         java_objectheader *clo;
1577         classloader       *cl;
1578         classinfo         *c;
1579
1580         assert(class_java_lang_Object);
1581         assert(class_java_lang_ClassLoader);
1582         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1583         
1584         m = class_resolveclassmethod(class_java_lang_ClassLoader,
1585                                                                  utf_getSystemClassLoader,
1586                                                                  utf_void__java_lang_ClassLoader,
1587                                                                  class_java_lang_Object,
1588                                                                  false);
1589
1590         if (!m)
1591                 return false;
1592
1593         clo = vm_call_method(m, NULL);
1594
1595         if (!clo)
1596                 return false;
1597
1598         cl = loader_hashtable_classloader_add(clo);
1599
1600         c = load_class_from_classloader(name, cl);
1601
1602         return c;
1603 }
1604
1605
1606 /* load_class_from_classloader *************************************************
1607
1608    Load the class with the given name using the given user-defined class loader.
1609
1610    IN:
1611        name.............the classname
1612            cl...............user-defined class loader
1613            
1614    RETURN VALUE:
1615        the loaded class, or
1616            NULL if an exception has been thrown
1617
1618 *******************************************************************************/
1619
1620 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1621 {
1622         java_objectheader *o;
1623         classinfo         *c;
1624         classinfo         *tmpc;
1625         java_objectheader *string;
1626 #if defined(ENABLE_RT_TIMING)
1627         struct timespec time_start, time_lookup, time_prepare, time_java, 
1628                                         time_cache;
1629 #endif
1630
1631         RT_TIMING_GET_TIME(time_start);
1632
1633         assert(name);
1634
1635         /* lookup if this class has already been loaded */
1636
1637         c = classcache_lookup(cl, name);
1638
1639         RT_TIMING_GET_TIME(time_lookup);
1640         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1641
1642         if (c != NULL)
1643                 return c;
1644
1645         /* if other class loader than bootstrap, call it */
1646
1647         if (cl != NULL) {
1648                 methodinfo *lc;
1649                 char       *text;
1650                 s4          namelen;
1651
1652                 text = name->text;
1653                 namelen = name->blength;
1654
1655                 /* handle array classes */
1656                 if (text[0] == '[') {
1657                         classinfo *comp;
1658                         utf       *u;
1659
1660                         switch (text[1]) {
1661                         case 'L':
1662                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1663                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1664                                         exceptions_throw_noclassdeffounderror(name);
1665                                         return false;
1666                                 }
1667
1668                                 u = utf_new(text + 2, namelen - 3);
1669
1670                                 if (!(comp = load_class_from_classloader(u, cl)))
1671                                         return false;
1672
1673                                 /* create the array class */
1674
1675                                 c = class_array_of(comp, false);
1676
1677                                 tmpc = classcache_store(cl, c, true);
1678
1679                                 if (tmpc == NULL) {
1680                                         /* exception, free the loaded class */
1681                                         c->state &= ~CLASS_LOADING;
1682                                         class_free(c);
1683                                 }
1684
1685                                 return tmpc;
1686
1687                         case '[':
1688                                 /* load the component class */
1689
1690                                 u = utf_new(text + 1, namelen - 1);
1691
1692                                 if (!(comp = load_class_from_classloader(u, cl)))
1693                                         return false;
1694
1695                                 /* create the array class */
1696
1697                                 c = class_array_of(comp, false);
1698
1699                                 tmpc = classcache_store(cl, c, true);
1700
1701                                 if (tmpc == NULL) {
1702                                         /* exception, free the loaded class */
1703                                         c->state &= ~CLASS_LOADING;
1704                                         class_free(c);
1705                                 }
1706
1707                                 return tmpc;
1708
1709                         default:
1710                                 /* primitive array classes are loaded by the bootstrap loader */
1711
1712                                 c = load_class_bootstrap(name);
1713
1714                                 return c;
1715                         }
1716                 }
1717                 
1718                 assert(class_java_lang_Object);
1719
1720                 lc = class_resolveclassmethod(cl->object->vftbl->class,
1721                                                                           utf_loadClass,
1722                                                                           utf_java_lang_String__java_lang_Class,
1723                                                                           class_java_lang_Object,
1724                                                                           true);
1725
1726                 if (!lc)
1727                         return false; /* exception */
1728
1729                 /* move return value into `o' and cast it afterwards to a classinfo* */
1730
1731                 string = javastring_new_slash_to_dot(name);
1732
1733                 RT_TIMING_GET_TIME(time_prepare);
1734
1735                 o = vm_call_method(lc, cl->object, string);
1736
1737                 RT_TIMING_GET_TIME(time_java);
1738
1739                 c = (classinfo *) o;
1740
1741                 if (c != NULL) {
1742                         /* Store this class in the loaded class cache. If another
1743                            class with the same (initloader,name) pair has been
1744                            stored earlier it will be returned by classcache_store
1745                            In this case classcache_store may not free the class
1746                            because it has already been exposed to Java code which
1747                            may have kept references to that class. */
1748
1749                     tmpc = classcache_store(cl, c, false);
1750
1751                         if (tmpc == NULL) {
1752                                 /* exception, free the loaded class */
1753                                 c->state &= ~CLASS_LOADING;
1754                                 class_free(c);
1755                         }
1756
1757                         c = tmpc;
1758
1759                 } else {
1760                         /* loadClass has thrown an exception.  We must convert
1761                            ClassNotFoundException into
1762                            NoClassDefFoundException. */
1763
1764                         /* XXX Maybe we should have a flag that avoids this
1765                            conversion for calling load_class_from_classloader from
1766                            Class.forName.  Currently we do a double conversion in
1767                            these cases.  */
1768
1769                         classnotfoundexception_to_noclassdeffounderror();
1770                 }
1771
1772                 RT_TIMING_GET_TIME(time_cache);
1773
1774                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1775                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1776                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1777
1778                 /* SUN compatible -verbose:class output */
1779
1780                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1781                         printf("[Loaded ");
1782                         utf_display_printable_ascii_classname(name);
1783                         printf("]\n");
1784                 }
1785
1786 #if defined(ENABLE_JVMTI)
1787                 /* fire Class Load JVMTI event */
1788                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1789 #endif
1790
1791
1792                 return c;
1793         } 
1794
1795         c = load_class_bootstrap(name);
1796
1797         return c;
1798 }
1799
1800
1801 /* load_class_bootstrap ********************************************************
1802         
1803    Load the class with the given name using the bootstrap class loader.
1804
1805    IN:
1806        name.............the classname
1807
1808    RETURN VALUE:
1809        loaded classinfo, or
1810            NULL if an exception has been thrown
1811
1812    SYNCHRONIZATION:
1813        load_class_bootstrap is synchronized. It can be treated as an
1814            atomic operation.
1815
1816 *******************************************************************************/
1817
1818 classinfo *load_class_bootstrap(utf *name)
1819 {
1820         classbuffer *cb;
1821         classinfo   *c;
1822         classinfo   *r;
1823 #if defined(ENABLE_RT_TIMING)
1824         struct timespec time_start, time_lookup, time_array, time_suck, 
1825                                         time_load, time_cache;
1826 #endif
1827
1828         RT_TIMING_GET_TIME(time_start);
1829
1830         /* for debugging */
1831
1832         assert(name);
1833
1834         /* lookup if this class has already been loaded */
1835
1836         if ((r = classcache_lookup(NULL, name))) {
1837
1838                 RT_TIMING_GET_TIME(time_lookup);
1839                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1840                 
1841                 return r;
1842         }
1843
1844         RT_TIMING_GET_TIME(time_lookup);
1845         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1846                 
1847         /* create the classinfo */
1848
1849         c = class_create_classinfo(name);
1850
1851         /* handle array classes */
1852
1853         if (name->text[0] == '[') {
1854                 c = load_newly_created_array(c, NULL);
1855                 if (c == NULL)
1856                         return NULL;
1857                 assert(c->state & CLASS_LOADED);
1858
1859                 RT_TIMING_GET_TIME(time_array);
1860                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1861                 
1862                 return c;
1863         }
1864
1865 #if defined(ENABLE_STATISTICS)
1866         /* measure time */
1867
1868         if (opt_getcompilingtime)
1869                 compilingtime_stop();
1870
1871         if (opt_getloadingtime)
1872                 loadingtime_start();
1873 #endif
1874
1875         /* load classdata, throw exception on error */
1876
1877         cb = suck_start(c);
1878
1879         if (cb == NULL) {
1880                 /* this normally means, the classpath was not set properly */
1881
1882                 if (name == utf_java_lang_Object)
1883                         vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1884
1885                 exceptions_throw_noclassdeffounderror(name);
1886
1887                 return NULL;
1888         }
1889
1890         RT_TIMING_GET_TIME(time_suck);
1891         
1892         /* load the class from the buffer */
1893
1894         r = load_class_from_classbuffer(cb);
1895
1896         RT_TIMING_GET_TIME(time_load);
1897         
1898         if (!r) {
1899                 /* the class could not be loaded, free the classinfo struct */
1900
1901                 class_free(c);
1902
1903         } else {
1904                 /* Store this class in the loaded class cache this step also
1905                 checks the loading constraints. If the class has been loaded
1906                 before, the earlier loaded class is returned. */
1907
1908                 classinfo *res = classcache_store(NULL, c, true);
1909
1910                 if (!res) {
1911                         /* exception */
1912                         class_free(c);
1913                 }
1914
1915                 r = res;
1916         }
1917
1918         RT_TIMING_GET_TIME(time_cache);
1919         
1920         /* SUN compatible -verbose:class output */
1921
1922         if (opt_verboseclass && r) {
1923                 printf("[Loaded ");
1924                 utf_display_printable_ascii_classname(name);
1925                 printf(" from %s]\n", cb->path);
1926         }
1927
1928         /* free memory */
1929
1930         suck_stop(cb);
1931
1932 #if defined(ENABLE_STATISTICS)
1933         /* measure time */
1934
1935         if (opt_getloadingtime)
1936                 loadingtime_stop();
1937
1938         if (opt_getcompilingtime)
1939                 compilingtime_start();
1940 #endif
1941
1942         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1943         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1944         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1945         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1946
1947         return r;
1948 }
1949
1950
1951 /* load_class_from_classbuffer *************************************************
1952         
1953    Loads everything interesting about a class from the class file. The
1954    'classinfo' structure must have been allocated previously.
1955
1956    The super class and the interfaces implemented by this class need
1957    not be loaded. The link is set later by the function 'class_link'.
1958
1959    The loaded class is removed from the list 'unloadedclasses' and
1960    added to the list 'unlinkedclasses'.
1961         
1962    SYNCHRONIZATION:
1963        This function is NOT synchronized!
1964    
1965 *******************************************************************************/
1966
1967 classinfo *load_class_from_classbuffer(classbuffer *cb)
1968 {
1969         classinfo *c;
1970         utf *name;
1971         utf *supername;
1972         u4 i,j;
1973         u4 ma, mi;
1974         s4 dumpsize;
1975         descriptor_pool *descpool;
1976 #if defined(ENABLE_STATISTICS)
1977         u4 classrefsize;
1978         u4 descsize;
1979 #endif
1980 #if defined(ENABLE_RT_TIMING)
1981         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1982                                         time_setup, time_fields, time_methods, time_classrefs,
1983                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1984                                         time_parsecpool, time_verify, time_attrs;
1985 #endif
1986
1987         RT_TIMING_GET_TIME(time_start);
1988
1989         /* get the classbuffer's class */
1990
1991         c = cb->class;
1992
1993         /* the class is already loaded */
1994
1995         if (c->state & CLASS_LOADED)
1996                 return c;
1997
1998 #if defined(ENABLE_STATISTICS)
1999         if (opt_stat)
2000                 count_class_loads++;
2001 #endif
2002
2003 #if !defined(NDEBUG)
2004         /* output for debugging purposes */
2005
2006         if (loadverbose)
2007                 log_message_class("Loading class: ", c);
2008 #endif
2009
2010         /* mark start of dump memory area */
2011
2012         dumpsize = dump_size();
2013
2014         /* class is currently loading */
2015
2016         c->state |= CLASS_LOADING;
2017
2018         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
2019                 goto return_exception;
2020
2021         /* check signature */
2022
2023         if (suck_u4(cb) != MAGIC) {
2024                 exceptions_throw_classformaterror(c, "Bad magic number");
2025
2026                 goto return_exception;
2027         }
2028
2029         /* check version */
2030
2031         mi = suck_u2(cb);
2032         ma = suck_u2(cb);
2033
2034         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
2035                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
2036                 goto return_exception;
2037         }
2038
2039         RT_TIMING_GET_TIME(time_checks);
2040
2041         /* create a new descriptor pool */
2042
2043         descpool = descriptor_pool_new(c);
2044
2045         RT_TIMING_GET_TIME(time_ndpool);
2046
2047         /* load the constant pool */
2048
2049         if (!load_constantpool(cb, descpool))
2050                 goto return_exception;
2051
2052         RT_TIMING_GET_TIME(time_cpool);
2053
2054         /* ACC flags */
2055
2056         if (!suck_check_classbuffer_size(cb, 2))
2057                 goto return_exception;
2058
2059         /* We OR the flags here, as we set already some flags in
2060            class_create_classinfo. */
2061
2062         c->flags |= suck_u2(cb);
2063
2064         /* check ACC flags consistency */
2065
2066         if (c->flags & ACC_INTERFACE) {
2067                 if (!(c->flags & ACC_ABSTRACT)) {
2068                         /* We work around this because interfaces in JDK 1.1 are
2069                          * not declared abstract. */
2070
2071                         c->flags |= ACC_ABSTRACT;
2072                 }
2073
2074                 if (c->flags & ACC_FINAL) {
2075                         exceptions_throw_classformaterror(c,
2076                                                                                           "Illegal class modifiers: 0x%X",
2077                                                                                           c->flags);
2078                         goto return_exception;
2079                 }
2080
2081                 if (c->flags & ACC_SUPER) {
2082                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
2083                 }
2084         }
2085
2086         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
2087                 exceptions_throw_classformaterror(c,
2088                                                                                   "Illegal class modifiers: 0x%X",
2089                                                                                   c->flags);
2090                 goto return_exception;
2091         }
2092
2093         if (!suck_check_classbuffer_size(cb, 2 + 2))
2094                 goto return_exception;
2095
2096         /* this class */
2097
2098         i = suck_u2(cb);
2099
2100         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2101                 goto return_exception;
2102
2103         if (c->name == utf_not_named_yet) {
2104                 /* we finally have a name for this class */
2105                 c->name = name;
2106                 class_set_packagename(c);
2107         }
2108         else if (name != c->name) {
2109                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
2110                 goto return_exception;
2111         }
2112
2113         /* retrieve superclass */
2114
2115         c->super.any = NULL;
2116
2117         if ((i = suck_u2(cb))) {
2118                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2119                         goto return_exception;
2120
2121                 /* java.lang.Object may not have a super class. */
2122
2123                 if (c->name == utf_java_lang_Object) {
2124                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2125                         goto return_exception;
2126                 }
2127
2128                 /* Interfaces must have java.lang.Object as super class. */
2129
2130                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2131                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2132                         goto return_exception;
2133                 }
2134
2135         } else {
2136                 supername = NULL;
2137
2138                 /* This is only allowed for java.lang.Object. */
2139
2140                 if (c->name != utf_java_lang_Object) {
2141                         exceptions_throw_classformaterror(c, "Bad superclass index");
2142                         goto return_exception;
2143                 }
2144         }
2145
2146         /* retrieve interfaces */
2147
2148         if (!suck_check_classbuffer_size(cb, 2))
2149                 goto return_exception;
2150
2151         c->interfacescount = suck_u2(cb);
2152
2153         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2154                 goto return_exception;
2155
2156         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2157         for (i = 0; i < c->interfacescount; i++) {
2158                 /* the classrefs are created later */
2159                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2160                         goto return_exception;
2161         }
2162
2163         RT_TIMING_GET_TIME(time_setup);
2164
2165         /* load fields */
2166         if (!suck_check_classbuffer_size(cb, 2))
2167                 goto return_exception;
2168
2169         c->fieldscount = suck_u2(cb);
2170 #if defined(ENABLE_GC_CACAO)
2171         c->fields = MNEW(fieldinfo, c->fieldscount);
2172         MZERO(c->fields, fieldinfo, c->fieldscount);
2173 #else
2174         c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2175 #endif
2176
2177         for (i = 0; i < c->fieldscount; i++) {
2178                 if (!load_field(cb, &(c->fields[i]),descpool))
2179                         goto return_exception;
2180         }
2181
2182         RT_TIMING_GET_TIME(time_fields);
2183
2184         /* load methods */
2185         if (!suck_check_classbuffer_size(cb, 2))
2186                 goto return_exception;
2187
2188         c->methodscount = suck_u2(cb);
2189         c->methods = MNEW(methodinfo, c->methodscount);
2190
2191         MZERO(c->methods, methodinfo, c->methodscount);
2192         
2193         for (i = 0; i < c->methodscount; i++) {
2194                 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2195                         goto return_exception;
2196         }
2197
2198         RT_TIMING_GET_TIME(time_methods);
2199
2200         /* create the class reference table */
2201
2202         c->classrefs =
2203                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2204
2205         RT_TIMING_GET_TIME(time_classrefs);
2206
2207         /* allocate space for the parsed descriptors */
2208
2209         descriptor_pool_alloc_parsed_descriptors(descpool);
2210         c->parseddescs =
2211                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2212
2213 #if defined(ENABLE_STATISTICS)
2214         if (opt_stat) {
2215                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2216                 count_classref_len += classrefsize;
2217                 count_parsed_desc_len += descsize;
2218         }
2219 #endif
2220
2221         RT_TIMING_GET_TIME(time_descs);
2222
2223         /* put the classrefs in the constant pool */
2224         for (i = 0; i < c->cpcount; i++) {
2225                 if (c->cptags[i] == CONSTANT_Class) {
2226                         utf *name = (utf *) c->cpinfos[i];
2227                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2228                 }
2229         }
2230
2231         /* set the super class reference */
2232
2233         if (supername) {
2234                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2235                 if (!c->super.ref)
2236                         goto return_exception;
2237         }
2238
2239         /* set the super interfaces references */
2240
2241         for (i = 0; i < c->interfacescount; i++) {
2242                 c->interfaces[i].ref =
2243                         descriptor_pool_lookup_classref(descpool,
2244                                                                                         (utf *) c->interfaces[i].any);
2245                 if (!c->interfaces[i].ref)
2246                         goto return_exception;
2247         }
2248
2249         RT_TIMING_GET_TIME(time_setrefs);
2250
2251         /* parse field descriptors */
2252
2253         for (i = 0; i < c->fieldscount; i++) {
2254                 c->fields[i].parseddesc =
2255                         descriptor_pool_parse_field_descriptor(descpool,
2256                                                                                                    c->fields[i].descriptor);
2257                 if (!c->fields[i].parseddesc)
2258                         goto return_exception;
2259         }
2260
2261         RT_TIMING_GET_TIME(time_parsefds);
2262
2263         /* parse method descriptors */
2264
2265         for (i = 0; i < c->methodscount; i++) {
2266                 methodinfo *m = &c->methods[i];
2267                 m->parseddesc =
2268                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2269                                                                                                         m->flags, class_get_self_classref(m->class));
2270                 if (!m->parseddesc)
2271                         goto return_exception;
2272
2273                 for (j = 0; j < m->rawexceptiontablelength; j++) {
2274                         if (!m->rawexceptiontable[j].catchtype.any)
2275                                 continue;
2276                         if ((m->rawexceptiontable[j].catchtype.ref =
2277                                  descriptor_pool_lookup_classref(descpool,
2278                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2279                                 goto return_exception;
2280                 }
2281
2282                 for (j = 0; j < m->thrownexceptionscount; j++) {
2283                         if (!m->thrownexceptions[j].any)
2284                                 continue;
2285                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2286                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
2287                                 goto return_exception;
2288                 }
2289         }
2290
2291         RT_TIMING_GET_TIME(time_parsemds);
2292
2293         /* parse the loaded descriptors */
2294
2295         for (i = 0; i < c->cpcount; i++) {
2296                 constant_FMIref *fmi;
2297                 s4               index;
2298
2299                 switch (c->cptags[i]) {
2300                 case CONSTANT_Fieldref:
2301                         fmi = (constant_FMIref *) c->cpinfos[i];
2302                         fmi->parseddesc.fd =
2303                                 descriptor_pool_parse_field_descriptor(descpool,
2304                                                                                                            fmi->descriptor);
2305                         if (!fmi->parseddesc.fd)
2306                                 goto return_exception;
2307                         index = fmi->p.index;
2308                         fmi->p.classref =
2309                                 (constant_classref *) class_getconstant(c, index,
2310                                                                                                                 CONSTANT_Class);
2311                         if (!fmi->p.classref)
2312                                 goto return_exception;
2313                         break;
2314                 case CONSTANT_Methodref:
2315                 case CONSTANT_InterfaceMethodref:
2316                         fmi = (constant_FMIref *) c->cpinfos[i];
2317                         index = fmi->p.index;
2318                         fmi->p.classref =
2319                                 (constant_classref *) class_getconstant(c, index,
2320                                                                                                                 CONSTANT_Class);
2321                         if (!fmi->p.classref)
2322                                 goto return_exception;
2323                         fmi->parseddesc.md =
2324                                 descriptor_pool_parse_method_descriptor(descpool,
2325                                                                                                                 fmi->descriptor,
2326                                                                                                                 ACC_UNDEF,
2327                                                                                                                 fmi->p.classref);
2328                         if (!fmi->parseddesc.md)
2329                                 goto return_exception;
2330                         break;
2331                 }
2332         }
2333
2334         RT_TIMING_GET_TIME(time_parsecpool);
2335
2336 #ifdef ENABLE_VERIFIER
2337         /* Check if all fields and methods can be uniquely
2338          * identified by (name,descriptor). */
2339
2340         if (opt_verify) {
2341                 /* We use a hash table here to avoid making the
2342                  * average case quadratic in # of methods, fields.
2343                  */
2344                 static int shift = 0;
2345                 u2 *hashtab;
2346                 u2 *next; /* for chaining colliding hash entries */
2347                 size_t len;
2348                 size_t hashlen;
2349                 u2 index;
2350                 u2 old;
2351
2352                 /* Allocate hashtable */
2353                 len = c->methodscount;
2354                 if (len < c->fieldscount) len = c->fieldscount;
2355                 hashlen = 5 * len;
2356                 hashtab = MNEW(u2,(hashlen + len));
2357                 next = hashtab + hashlen;
2358
2359                 /* Determine bitshift (to get good hash values) */
2360                 if (!shift) {
2361                         len = sizeof(utf);
2362                         while (len) {
2363                                 len >>= 1;
2364                                 shift++;
2365                         }
2366                 }
2367
2368                 /* Check fields */
2369                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2370
2371                 for (i = 0; i < c->fieldscount; ++i) {
2372                         fieldinfo *fi = c->fields + i;
2373
2374                         /* It's ok if we lose bits here */
2375                         index = ((((size_t) fi->name) +
2376                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
2377
2378                         if ((old = hashtab[index])) {
2379                                 old--;
2380                                 next[i] = old;
2381                                 do {
2382                                         if (c->fields[old].name == fi->name &&
2383                                                 c->fields[old].descriptor == fi->descriptor) {
2384                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2385                                                 goto return_exception;
2386                                         }
2387                                 } while ((old = next[old]));
2388                         }
2389                         hashtab[index] = i + 1;
2390                 }
2391
2392                 /* Check methods */
2393                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2394
2395                 for (i = 0; i < c->methodscount; ++i) {
2396                         methodinfo *mi = c->methods + i;
2397
2398                         /* It's ok if we lose bits here */
2399                         index = ((((size_t) mi->name) +
2400                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
2401
2402                         /*{ JOWENN
2403                                 int dbg;
2404                                 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2405                                         printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2406                                 }
2407                         }*/
2408
2409                         if ((old = hashtab[index])) {
2410                                 old--;
2411                                 next[i] = old;
2412                                 do {
2413                                         if (c->methods[old].name == mi->name &&
2414                                                 c->methods[old].descriptor == mi->descriptor) {
2415                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2416                                                 goto return_exception;
2417                                         }
2418                                 } while ((old = next[old]));
2419                         }
2420                         hashtab[index] = i + 1;
2421                 }
2422
2423                 MFREE(hashtab, u2, (hashlen + len));
2424         }
2425 #endif /* ENABLE_VERIFIER */
2426
2427         RT_TIMING_GET_TIME(time_verify);
2428
2429 #if defined(ENABLE_STATISTICS)
2430         if (opt_stat) {
2431                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
2432                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
2433                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2434         }
2435 #endif
2436
2437         /* load attribute structures */
2438
2439         if (!class_load_attributes(cb))
2440                 goto return_exception;
2441
2442         /* Pre Java 1.5 version don't check this. This implementation is like
2443            Java 1.5 do it: for class file version 45.3 we don't check it, older
2444            versions are checked.
2445          */
2446
2447         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2448                 /* check if all data has been read */
2449                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2450
2451                 if (classdata_left > 0) {
2452                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2453                         goto return_exception;
2454                 }
2455         }
2456
2457         RT_TIMING_GET_TIME(time_attrs);
2458
2459         /* release dump area */
2460
2461         dump_release(dumpsize);
2462
2463         /* revert loading state and class is loaded */
2464
2465         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2466
2467 #if defined(ENABLE_JVMTI)
2468         /* fire Class Prepare JVMTI event */
2469
2470         if (jvmti)
2471                 jvmti_ClassLoadPrepare(true, c);
2472 #endif
2473
2474 #if !defined(NDEBUG)
2475         if (loadverbose)
2476                 log_message_class("Loading done class: ", c);
2477 #endif
2478
2479         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
2480         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
2481         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
2482         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
2483         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
2484         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
2485         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2486         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
2487         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
2488         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
2489         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
2490         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2491         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
2492         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
2493         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
2494
2495         return c;
2496
2497 return_exception:
2498         /* release dump area */
2499
2500         dump_release(dumpsize);
2501
2502         /* an exception has been thrown */
2503
2504         return NULL;
2505 }
2506
2507
2508 /* load_newly_created_array ****************************************************
2509
2510    Load a newly created array class.
2511
2512         RETURN VALUE:
2513             c....................the array class C has been loaded
2514                 other classinfo......the array class was found in the class cache, 
2515                                      C has been freed
2516             NULL.................an exception has been thrown
2517
2518         Note:
2519                 This is an internal function. Do not use it unless you know exactly
2520                 what you are doing!
2521
2522                 Use one of the load_class_... functions for general array class loading.
2523
2524 *******************************************************************************/
2525
2526 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2527 {
2528         classinfo         *comp = NULL;
2529         methodinfo        *clone;
2530         methoddesc        *clonedesc;
2531         constant_classref *classrefs;
2532         char              *text;
2533         s4                 namelen;
2534         utf               *u;
2535
2536         text = c->name->text;
2537         namelen = c->name->blength;
2538
2539         /* Check array class name */
2540
2541         if ((namelen < 2) || (text[0] != '[')) {
2542                 exceptions_throw_noclassdeffounderror(c->name);
2543                 return NULL;
2544         }
2545
2546         /* Check the element type */
2547
2548         switch (text[1]) {
2549         case '[':
2550                 /* c is an array of arrays. We have to create the component class. */
2551
2552                 u = utf_new(text + 1, namelen - 1);
2553                 if (!(comp = load_class_from_classloader(u, loader)))
2554                         return NULL;
2555
2556                 assert(comp->state & CLASS_LOADED);
2557
2558                 if (opt_eager)
2559                         if (!link_class(c))
2560                                 return NULL;
2561
2562                 /* the array's flags are that of the component class */
2563                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2564                 c->classloader = comp->classloader;
2565                 break;
2566
2567         case 'L':
2568                 /* c is an array of objects. */
2569
2570                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2571                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2572                         exceptions_throw_noclassdeffounderror(c->name);
2573                         return NULL;
2574                 }
2575
2576                 u = utf_new(text + 2, namelen - 3);
2577
2578                 if (!(comp = load_class_from_classloader(u, loader)))
2579                         return NULL;
2580
2581                 assert(comp->state & CLASS_LOADED);
2582
2583                 if (opt_eager)
2584                         if (!link_class(c))
2585                                 return NULL;
2586
2587                 /* the array's flags are that of the component class */
2588                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2589                 c->classloader = comp->classloader;
2590                 break;
2591
2592         default:
2593                 /* c is an array of a primitive type */
2594
2595                 /* check for cases like `[II' */
2596                 if (namelen > 2) {
2597                         exceptions_throw_noclassdeffounderror(c->name);
2598                         return NULL;
2599                 }
2600
2601                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2602                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2603                 c->classloader = NULL;
2604         }
2605
2606         assert(class_java_lang_Object);
2607 #if defined(ENABLE_JAVASE)
2608         assert(class_java_lang_Cloneable);
2609         assert(class_java_io_Serializable);
2610 #endif
2611
2612         /* setup the array class */
2613
2614         c->super.cls = class_java_lang_Object;
2615
2616 #if defined(ENABLE_JAVASE)
2617         c->interfacescount = 2;
2618     c->interfaces      = MNEW(classref_or_classinfo, 2);
2619
2620         if (opt_eager) {
2621                 classinfo *tc;
2622
2623                 tc = class_java_lang_Cloneable;
2624                 assert(tc->state & CLASS_LOADED);
2625                 list_add_first(&unlinkedclasses, tc);
2626                 c->interfaces[0].cls = tc;
2627
2628                 tc = class_java_io_Serializable;
2629                 assert(tc->state & CLASS_LOADED);
2630                 list_add_first(&unlinkedclasses, tc);
2631                 c->interfaces[1].cls = tc;
2632         }
2633         else {
2634                 c->interfaces[0].cls = class_java_lang_Cloneable;
2635                 c->interfaces[1].cls = class_java_io_Serializable;
2636         }
2637 #elif defined(ENABLE_JAVAME_CLDC1_1)
2638         c->interfacescount = 0;
2639         c->interfaces      = NULL;
2640 #else
2641 #error unknow Java configuration
2642 #endif
2643
2644         c->methodscount = 1;
2645         c->methods = MNEW(methodinfo, c->methodscount);
2646         MZERO(c->methods, methodinfo, c->methodscount);
2647
2648         classrefs = MNEW(constant_classref, 2);
2649         CLASSREF_INIT(classrefs[0], c, c->name);
2650         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2651
2652         /* create descriptor for clone method */
2653         /* we need one paramslot which is reserved for the 'this' parameter */
2654         clonedesc = NEW(methoddesc);
2655         clonedesc->returntype.type = TYPE_ADR;
2656         clonedesc->returntype.classref = classrefs + 1;
2657         clonedesc->returntype.arraydim = 0;
2658         /* initialize params to "empty", add real params below in
2659            descriptor_params_from_paramtypes */
2660         clonedesc->paramcount = 0;
2661         clonedesc->paramslots = 0;
2662         clonedesc->paramtypes[0].classref = classrefs + 0;
2663         clonedesc->params = NULL;
2664
2665         /* create methodinfo */
2666
2667         clone = c->methods;
2668         MSET(clone, 0, methodinfo, 1);
2669
2670 #if defined(ENABLE_THREADS)
2671         lock_init_object_lock(&clone->header);
2672 #endif
2673
2674         /* ATTENTION: if you delete the ACC_NATIVE below, set
2675            clone->maxlocals=1 (interpreter related) */
2676
2677         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2678         clone->name       = utf_clone;
2679         clone->descriptor = utf_void__java_lang_Object;
2680         clone->parseddesc = clonedesc;
2681         clone->class      = c;
2682
2683         /* parse the descriptor to get the register allocation */
2684
2685         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2686                 return false;
2687
2688         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2689
2690         /* XXX: field: length? */
2691
2692         /* array classes are not loaded from class files */
2693
2694         c->state          |= CLASS_LOADED;
2695         c->parseddescs    = (u1 *) clonedesc;
2696         c->parseddescsize = sizeof(methodinfo);
2697         c->classrefs      = classrefs;
2698         c->classrefcount  = 1;
2699
2700         /* insert class into the loaded class cache */
2701         /* XXX free classinfo if NULL returned? */
2702
2703         return classcache_store(loader, c, true);
2704 }
2705
2706
2707 /* loader_close ****************************************************************
2708
2709    Frees all resources.
2710         
2711 *******************************************************************************/
2712
2713 void loader_close(void)
2714 {
2715         /* empty */
2716 }
2717
2718
2719 /*
2720  * These are local overrides for various environment variables in Emacs.
2721  * Please do not remove this and leave it at the end of the file, where
2722  * Emacs will automagically detect them.
2723  * ---------------------------------------------------------------------
2724  * Local variables:
2725  * mode: c
2726  * indent-tabs-mode: t
2727  * c-basic-offset: 4
2728  * tab-width: 4
2729  * End:
2730  * vim:noexpandtab:sw=4:ts=4:
2731  */