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