e0618c786caafde65ce36f0604a40b8d8bd64686
[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 8299 2007-08-13 08:41:18Z michi $
26
27 */
28
29
30 #include "config.h"
31
32 #include <stdlib.h>
33 #include <string.h>
34 #include <assert.h>
35
36 #include "vm/types.h"
37
38 #include "mm/memory.h"
39
40 #include "threads/lock-common.h"
41
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
44
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/primitive.h"
49 #include "vm/stringlocal.h"
50 #include "vm/vm.h"
51
52 #include "vm/jit_interface.h"
53
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
57 #endif
58
59 #include "vmcore/classcache.h"
60 #include "vmcore/field.h"
61 #include "vmcore/linker.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/method.h"
64 #include "vmcore/options.h"
65 #include "vmcore/rt-timing.h"
66
67 #if defined(ENABLE_STATISTICS)
68 # include "vmcore/statistics.h"
69 #endif
70
71 #include "vmcore/suck.h"
72
73 #if defined(ENABLE_ZLIB)
74 # include "vmcore/zip.h"
75 #endif
76
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/cacaodbg.h"
79 #endif
80
81
82 /* global variables ***********************************************************/
83
84 static hashtable *hashtable_classloader;
85
86
87 /* loader_init *****************************************************************
88
89    Initializes all lists and loads all classes required for the system
90    or the compiler.
91
92 *******************************************************************************/
93  
94 bool loader_init(void)
95 {
96 #if defined(ENABLE_THREADS)
97         list_classpath_entry *lce;
98
99         /* Initialize the monitor pointer for zip/jar file locking. */
100
101         for (lce = list_first(list_classpath_entries); lce != NULL;
102                  lce = list_next(list_classpath_entries, lce))
103                 if (lce->type == CLASSPATH_ARCHIVE)
104                         LOCK_INIT_OBJECT_LOCK(lce);
105 #endif
106
107         /* initialize classloader hashtable, 10 entries should be enough */
108
109         hashtable_classloader = NEW(hashtable);
110         hashtable_create(hashtable_classloader, 10);
111
112         /* load some important classes */
113
114         if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
115                 return false;
116
117         if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
118                 return false;
119
120 #if defined(ENABLE_JAVASE)
121         if (!(class_java_lang_Cloneable =
122                   load_class_bootstrap(utf_java_lang_Cloneable)))
123                 return false;
124
125         if (!(class_java_io_Serializable =
126                   load_class_bootstrap(utf_java_io_Serializable)))
127                 return false;
128 #endif
129
130         /* load classes for wrapping primitive types */
131
132 #if defined(ENABLE_JAVASE)
133         if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
134                 return false;
135 #endif
136
137         if (!(class_java_lang_Boolean =
138                   load_class_bootstrap(utf_java_lang_Boolean)))
139                 return false;
140
141         if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
142                 return false;
143
144         if (!(class_java_lang_Character =
145                   load_class_bootstrap(utf_java_lang_Character)))
146                 return false;
147
148         if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
149                 return false;
150
151         if (!(class_java_lang_Integer =
152                   load_class_bootstrap(utf_java_lang_Integer)))
153                 return false;
154
155         if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
156                 return false;
157
158         if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
159                 return false;
160
161         if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
162                 return false;
163
164
165         /* load some other important classes */
166
167         if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
168                 return false;
169
170 #if defined(ENABLE_JAVASE)
171         if (!(class_java_lang_ClassLoader =
172                   load_class_bootstrap(utf_java_lang_ClassLoader)))
173                 return false;
174
175         if (!(class_java_lang_SecurityManager =
176                   load_class_bootstrap(utf_java_lang_SecurityManager)))
177                 return false;
178 #endif
179
180         if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
181                 return false;
182
183         if (!(class_java_lang_Thread =
184                   load_class_bootstrap(utf_new_char("java/lang/Thread"))))
185                 return false;
186
187 #if defined(ENABLE_JAVASE)
188         if (!(class_java_lang_ThreadGroup =
189                   load_class_bootstrap(utf_java_lang_ThreadGroup)))
190                 return false;
191 #endif
192
193 #if defined(WITH_CLASSPATH_GNU)
194         if (!(class_java_lang_VMSystem =
195                   load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
196
197                 return false;
198
199         if (!(class_java_lang_VMThread =
200                   load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
201                 return false;
202 #endif
203
204
205         /* some classes which may be used more often */
206
207 #if defined(ENABLE_JAVASE)
208         if (!(class_java_lang_StackTraceElement =
209                   load_class_bootstrap(utf_java_lang_StackTraceElement)))
210                 return false;
211
212         if (!(class_java_lang_reflect_Constructor =
213                   load_class_bootstrap(utf_java_lang_reflect_Constructor)))
214                 return false;
215
216         if (!(class_java_lang_reflect_Field =
217                   load_class_bootstrap(utf_java_lang_reflect_Field)))
218                 return false;
219
220         if (!(class_java_lang_reflect_Method =
221                   load_class_bootstrap(utf_java_lang_reflect_Method)))
222                 return false;
223
224         if (!(class_java_security_PrivilegedAction =
225                   load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
226                 return false;
227
228         if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
229                 return false;
230
231 # if defined(WITH_CLASSPATH_SUN)
232         if (!(class_sun_reflect_MagicAccessorImpl =
233                   load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
234                 return false;
235 # endif
236
237         if (!(arrayclass_java_lang_Object =
238                   load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
239                 return false;
240
241 #if defined(ENABLE_ANNOTATIONS)
242         /* needed by annotation support */
243         if (!(class_sun_reflect_ConstantPool = 
244                   load_class_bootstrap(utf_sun_reflect_ConstantPool)))
245                 return false;
246
247 #if defined(WITH_CLASSPATH_GNU)
248         /* needed by GNU Classpaths annotation support */
249         if (!(class_sun_reflect_annotation_AnnotationParser = 
250                   load_class_bootstrap(utf_sun_reflect_annotation_AnnotationParser)))
251                 return false;
252 #endif
253 #endif
254 #endif
255
256
257         return true;
258 }
259
260
261 /* loader_hashtable_classloader_add ********************************************
262
263    Adds an entry to the classloader hashtable.
264
265    REMEMBER: Also use this to register native loaders!
266
267 *******************************************************************************/
268
269 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
270 {
271         hashtable_classloader_entry *cle;
272         u4   key;
273         u4   slot;
274
275         if (cl == NULL)
276                 return NULL;
277
278         LOCK_MONITOR_ENTER(hashtable_classloader->header);
279
280         /* key for entry is the hashcode of the classloader;
281            aligned to 16-byte boundaries */
282
283 #if defined(ENABLE_GC_CACAO)
284         key  = heap_get_hashcode(cl) >> 4;
285 #else
286         key  = ((u4) (ptrint) cl) >> 4;
287 #endif
288
289         slot = key & (hashtable_classloader->size - 1);
290         cle  = hashtable_classloader->ptr[slot];
291
292         /* search hashchain for existing entry */
293         /* XXX no GC collection is allowed here, make this a critical section */
294
295         while (cle) {
296                 if (cle->object == cl)
297                         break;
298
299                 cle = cle->hashlink;
300         }
301
302         /* if no classloader was found, we create a new entry here */
303
304         if (cle == NULL) {
305                 cle = NEW(hashtable_classloader_entry);
306
307 #if defined(ENABLE_GC_CACAO)
308                 /* register the classloader object with the GC */
309
310                 gc_reference_register(&(cle->object));
311 #endif
312
313                 cle->object = cl;
314
315                 /* insert entry into hashtable */
316
317                 cle->hashlink = hashtable_classloader->ptr[slot];
318                 hashtable_classloader->ptr[slot] = cle;
319
320                 /* update number of entries */
321
322                 hashtable_classloader->entries++;
323         }
324
325
326         LOCK_MONITOR_EXIT(hashtable_classloader->header);
327
328         return cle;
329 }
330
331
332 /* loader_hashtable_classloader_find *******************************************
333
334    Find an entry in the classloader hashtable.
335
336 *******************************************************************************/
337
338 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
339 {
340         hashtable_classloader_entry *cle;
341         u4   key;
342         u4   slot;
343
344         if (cl == NULL)
345                 return NULL;
346
347         /* key for entry is the hashcode of the classloader;
348            aligned to 16-byte boundaries */
349
350 #if defined(ENABLE_GC_CACAO)
351         key  = heap_get_hashcode(cl) >> 4;
352 #else
353         key  = ((u4) (ptrint) cl) >> 4;
354 #endif
355
356         slot = key & (hashtable_classloader->size - 1);
357         cle  = hashtable_classloader->ptr[slot];
358
359         /* search hashchain for existing entry */
360         /* XXX no GC collection is allowed here, make this a critical section */
361
362         while (cle) {
363                 if (cle->object == cl)
364                         break;
365
366                 cle = cle->hashlink;
367         }
368
369         return cle;
370 }
371
372
373 /* loader_load_all_classes *****************************************************
374
375    Loads all classes specified in the BOOTCLASSPATH.
376
377 *******************************************************************************/
378
379 void loader_load_all_classes(void)
380 {
381         list_classpath_entry    *lce;
382 #if defined(ENABLE_ZLIB)
383         hashtable               *ht;
384         s4                       slot;
385         hashtable_zipfile_entry *htzfe;
386         utf                     *u;
387 #endif
388
389         for (lce = list_first(list_classpath_entries); lce != NULL;
390                  lce = list_next(list_classpath_entries, lce)) {
391 #if defined(ENABLE_ZLIB)
392                 if (lce->type == CLASSPATH_ARCHIVE) {
393                         /* get the classes hashtable */
394
395                         ht = lce->htclasses;
396
397                         for (slot = 0; slot < ht->size; slot++) {
398                                 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
399
400                                 for (; htzfe; htzfe = htzfe->hashlink) {
401                                         u = htzfe->filename;
402
403                                         /* skip all entries in META-INF and .properties,
404                        .png files */
405
406                                         if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
407                                                 strstr(u->text, ".properties") ||
408                                                 strstr(u->text, ".png"))
409                                                 continue;
410
411                                         /* load class from bootstrap classloader */
412
413                                         if (!load_class_bootstrap(u)) {
414                                                 fprintf(stderr, "Error loading: ");
415                                                 utf_fprint_printable_ascii_classname(stderr, u);
416                                                 fprintf(stderr, "\n");
417
418 #if !defined(NDEBUG)
419                                                 /* print out exception and cause */
420
421                                                 exceptions_print_current_exception();
422 #endif
423                                         }
424                                 }
425                         }
426
427                 } else {
428 #endif
429 #if defined(ENABLE_ZLIB)
430                 }
431 #endif
432         }
433 }
434
435
436 /* loader_skip_attribute_body **************************************************
437
438    Skips an attribute the attribute_name_index has already been read.
439         
440    attribute_info {
441        u2 attribute_name_index;
442        u4 attribute_length;
443        u1 info[attribute_length];
444    }
445
446 *******************************************************************************/
447
448 bool loader_skip_attribute_body(classbuffer *cb)
449 {
450         u4 attribute_length;
451
452         if (!suck_check_classbuffer_size(cb, 4))
453                 return false;
454
455         attribute_length = suck_u4(cb);
456
457         if (!suck_check_classbuffer_size(cb, attribute_length))
458                 return false;
459
460         suck_skip_nbytes(cb, attribute_length);
461
462         return true;
463 }
464
465
466 /* load_constantpool ***********************************************************
467
468    Loads the constantpool of a class, the entries are transformed into
469    a simpler format by resolving references (a detailed overview of
470    the compact structures can be found in global.h).
471
472 *******************************************************************************/
473
474 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
475 {
476
477         /* The following structures are used to save information which cannot be 
478            processed during the first pass. After the complete constantpool has 
479            been traversed the references can be resolved. 
480            (only in specific order)                                                */
481         
482         /* CONSTANT_Class entries */
483         typedef struct forward_class {
484                 struct forward_class *next;
485                 u2 thisindex;
486                 u2 name_index;
487         } forward_class;
488
489         /* CONSTANT_String */
490         typedef struct forward_string {
491                 struct forward_string *next;
492                 u2 thisindex;
493                 u2 string_index;
494         } forward_string;
495
496         /* CONSTANT_NameAndType */
497         typedef struct forward_nameandtype {
498                 struct forward_nameandtype *next;
499                 u2 thisindex;
500                 u2 name_index;
501                 u2 sig_index;
502         } forward_nameandtype;
503
504         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
505         typedef struct forward_fieldmethint {
506                 struct forward_fieldmethint *next;
507                 u2 thisindex;
508                 u1 tag;
509                 u2 class_index;
510                 u2 nameandtype_index;
511         } forward_fieldmethint;
512
513
514         classinfo *c;
515         u4 idx;
516
517         forward_class *forward_classes = NULL;
518         forward_string *forward_strings = NULL;
519         forward_nameandtype *forward_nameandtypes = NULL;
520         forward_fieldmethint *forward_fieldmethints = NULL;
521
522         forward_class *nfc;
523         forward_string *nfs;
524         forward_nameandtype *nfn;
525         forward_fieldmethint *nff;
526
527         u4 cpcount;
528         u1 *cptags;
529         voidptr *cpinfos;
530
531         c = cb->class;
532
533         /* number of entries in the constant_pool table plus one */
534         if (!suck_check_classbuffer_size(cb, 2))
535                 return false;
536
537         cpcount = c->cpcount = suck_u2(cb);
538
539         /* allocate memory */
540         cptags  = c->cptags  = MNEW(u1, cpcount);
541         cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
542
543         if (cpcount < 1) {
544                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
545                 return false;
546         }
547         
548 #if defined(ENABLE_STATISTICS)
549         if (opt_stat)
550                 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
551 #endif
552         
553         /* initialize constantpool */
554         for (idx = 0; idx < cpcount; idx++) {
555                 cptags[idx] = CONSTANT_UNUSED;
556                 cpinfos[idx] = NULL;
557         }
558
559                         
560         /******* first pass *******/
561         /* entries which cannot be resolved now are written into 
562            temporary structures and traversed again later        */
563                    
564         idx = 1;
565         while (idx < cpcount) {
566                 u4 t;
567
568                 /* get constant type */
569                 if (!suck_check_classbuffer_size(cb, 1))
570                         return false;
571
572                 t = suck_u1(cb);
573
574                 switch (t) {
575                 case CONSTANT_Class:
576                         nfc = DNEW(forward_class);
577
578                         nfc->next = forward_classes;
579                         forward_classes = nfc;
580
581                         nfc->thisindex = idx;
582                         /* reference to CONSTANT_NameAndType */
583                         if (!suck_check_classbuffer_size(cb, 2))
584                                 return false;
585
586                         nfc->name_index = suck_u2(cb);
587
588                         idx++;
589                         break;
590                         
591                 case CONSTANT_String:
592                         nfs = DNEW(forward_string);
593                                 
594                         nfs->next = forward_strings;
595                         forward_strings = nfs;
596                                 
597                         nfs->thisindex = idx;
598
599                         /* reference to CONSTANT_Utf8_info with string characters */
600                         if (!suck_check_classbuffer_size(cb, 2))
601                                 return false;
602
603                         nfs->string_index = suck_u2(cb);
604                                 
605                         idx++;
606                         break;
607
608                 case CONSTANT_NameAndType:
609                         nfn = DNEW(forward_nameandtype);
610                                 
611                         nfn->next = forward_nameandtypes;
612                         forward_nameandtypes = nfn;
613                                 
614                         nfn->thisindex = idx;
615
616                         if (!suck_check_classbuffer_size(cb, 2 + 2))
617                                 return false;
618
619                         /* reference to CONSTANT_Utf8_info containing simple name */
620                         nfn->name_index = suck_u2(cb);
621
622                         /* reference to CONSTANT_Utf8_info containing field or method
623                            descriptor */
624                         nfn->sig_index = suck_u2(cb);
625                                 
626                         idx++;
627                         break;
628
629                 case CONSTANT_Fieldref:
630                 case CONSTANT_Methodref:
631                 case CONSTANT_InterfaceMethodref:
632                         nff = DNEW(forward_fieldmethint);
633                         
634                         nff->next = forward_fieldmethints;
635                         forward_fieldmethints = nff;
636
637                         nff->thisindex = idx;
638                         /* constant type */
639                         nff->tag = t;
640
641                         if (!suck_check_classbuffer_size(cb, 2 + 2))
642                                 return false;
643
644                         /* class or interface type that contains the declaration of the
645                            field or method */
646                         nff->class_index = suck_u2(cb);
647
648                         /* name and descriptor of the field or method */
649                         nff->nameandtype_index = suck_u2(cb);
650
651                         idx++;
652                         break;
653                                 
654                 case CONSTANT_Integer: {
655                         constant_integer *ci = NEW(constant_integer);
656
657 #if defined(ENABLE_STATISTICS)
658                         if (opt_stat)
659                                 count_const_pool_len += sizeof(constant_integer);
660 #endif
661
662                         if (!suck_check_classbuffer_size(cb, 4))
663                                 return false;
664
665                         ci->value = suck_s4(cb);
666                         cptags[idx] = CONSTANT_Integer;
667                         cpinfos[idx] = ci;
668
669                         idx++;
670                         break;
671                 }
672                                 
673                 case CONSTANT_Float: {
674                         constant_float *cf = NEW(constant_float);
675
676 #if defined(ENABLE_STATISTICS)
677                         if (opt_stat)
678                                 count_const_pool_len += sizeof(constant_float);
679 #endif
680
681                         if (!suck_check_classbuffer_size(cb, 4))
682                                 return false;
683
684                         cf->value = suck_float(cb);
685                         cptags[idx] = CONSTANT_Float;
686                         cpinfos[idx] = cf;
687
688                         idx++;
689                         break;
690                 }
691                                 
692                 case CONSTANT_Long: {
693                         constant_long *cl = NEW(constant_long);
694                                         
695 #if defined(ENABLE_STATISTICS)
696                         if (opt_stat)
697                                 count_const_pool_len += sizeof(constant_long);
698 #endif
699
700                         if (!suck_check_classbuffer_size(cb, 8))
701                                 return false;
702
703                         cl->value = suck_s8(cb);
704                         cptags[idx] = CONSTANT_Long;
705                         cpinfos[idx] = cl;
706                         idx += 2;
707                         if (idx > cpcount) {
708                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
709                                 return false;
710                         }
711                         break;
712                 }
713                         
714                 case CONSTANT_Double: {
715                         constant_double *cd = NEW(constant_double);
716                                 
717 #if defined(ENABLE_STATISTICS)
718                         if (opt_stat)
719                                 count_const_pool_len += sizeof(constant_double);
720 #endif
721
722                         if (!suck_check_classbuffer_size(cb, 8))
723                                 return false;
724
725                         cd->value = suck_double(cb);
726                         cptags[idx] = CONSTANT_Double;
727                         cpinfos[idx] = cd;
728                         idx += 2;
729                         if (idx > cpcount) {
730                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
731                                 return false;
732                         }
733                         break;
734                 }
735                                 
736                 case CONSTANT_Utf8: { 
737                         u4 length;
738
739                         /* number of bytes in the bytes array (not string-length) */
740                         if (!suck_check_classbuffer_size(cb, 2))
741                                 return false;
742
743                         length = suck_u2(cb);
744                         cptags[idx] = CONSTANT_Utf8;
745
746                         /* validate the string */
747                         if (!suck_check_classbuffer_size(cb, length))
748                                 return false;
749
750 #ifdef ENABLE_VERIFIER
751                         if (opt_verify &&
752                                 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
753                         {
754                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
755                                 return false;
756                         }
757 #endif /* ENABLE_VERIFIER */
758                         /* insert utf-string into the utf-symboltable */
759                         cpinfos[idx] = utf_new((char *) cb->pos, length);
760
761                         /* skip bytes of the string (buffer size check above) */
762                         suck_skip_nbytes(cb, length);
763                         idx++;
764                         break;
765                 }
766                                                                                 
767                 default:
768                         exceptions_throw_classformaterror(c, "Illegal constant pool type");
769                         return false;
770                 }  /* end switch */
771         } /* end while */
772
773
774         /* resolve entries in temporary structures */
775
776         while (forward_classes) {
777                 utf *name =
778                         class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
779                 if (!name)
780                         return false;
781
782 #ifdef ENABLE_VERIFIER
783                 if (opt_verify && !is_valid_name_utf(name)) {
784                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
785                         return false;
786                 }
787 #endif /* ENABLE_VERIFIER */
788
789                 /* add all class references to the descriptor_pool */
790
791                 if (!descriptor_pool_add_class(descpool, name))
792                         return false;
793
794                 cptags[forward_classes->thisindex] = CONSTANT_Class;
795
796                 /* the classref is created later */
797                 cpinfos[forward_classes->thisindex] = name;
798
799                 nfc = forward_classes;
800                 forward_classes = forward_classes->next;
801         }
802
803         while (forward_strings) {
804                 utf *text =
805                         class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
806                 if (!text)
807                         return false;
808
809                 /* resolve utf-string */
810                 cptags[forward_strings->thisindex] = CONSTANT_String;
811                 cpinfos[forward_strings->thisindex] = text;
812                 
813                 nfs = forward_strings;
814                 forward_strings = forward_strings->next;
815         }
816
817         while (forward_nameandtypes) {
818                 constant_nameandtype *cn = NEW(constant_nameandtype);   
819
820 #if defined(ENABLE_STATISTICS)
821                 if (opt_stat)
822                         count_const_pool_len += sizeof(constant_nameandtype);
823 #endif
824
825                 /* resolve simple name and descriptor */
826                 cn->name = class_getconstant(c,
827                                                                          forward_nameandtypes->name_index,
828                                                                          CONSTANT_Utf8);
829                 if (!cn->name)
830                         return false;
831
832                 cn->descriptor = class_getconstant(c,
833                                                                                    forward_nameandtypes->sig_index,
834                                                                                    CONSTANT_Utf8);
835                 if (!cn->descriptor)
836                         return false;
837
838 #ifdef ENABLE_VERIFIER
839                 if (opt_verify) {
840                         /* check name */
841                         if (!is_valid_name_utf(cn->name)) {
842                                 exceptions_throw_classformaterror(c,
843                                                                                                   "Illegal Field name \"%s\"",
844                                                                                                   cn->name->text);
845
846                                 return false;
847                         }
848
849                         /* disallow referencing <clinit> among others */
850                         if (cn->name->text[0] == '<' && cn->name != utf_init) {
851                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
852                                 return false;
853                         }
854                 }
855 #endif /* ENABLE_VERIFIER */
856
857                 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
858                 cpinfos[forward_nameandtypes->thisindex] = cn;
859
860                 nfn = forward_nameandtypes;
861                 forward_nameandtypes = forward_nameandtypes->next;
862         }
863
864         while (forward_fieldmethints) {
865                 constant_nameandtype *nat;
866                 constant_FMIref *fmi = NEW(constant_FMIref);
867
868 #if defined(ENABLE_STATISTICS)
869                 if (opt_stat)
870                         count_const_pool_len += sizeof(constant_FMIref);
871 #endif
872                 /* resolve simple name and descriptor */
873
874                 nat = class_getconstant(c,
875                                                                 forward_fieldmethints->nameandtype_index,
876                                                                 CONSTANT_NameAndType);
877                 if (!nat)
878                         return false;
879
880                 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
881
882                 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
883                         return false;
884
885                 /* the classref is created later */
886
887                 fmi->p.index = forward_fieldmethints->class_index;
888                 fmi->name = nat->name;
889                 fmi->descriptor = nat->descriptor;
890
891                 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
892                 cpinfos[forward_fieldmethints->thisindex] = fmi;
893         
894                 nff = forward_fieldmethints;
895                 forward_fieldmethints = forward_fieldmethints->next;
896         }
897
898         /* everything was ok */
899
900         return true;
901 }
902
903
904 /* loader_load_attribute_signature *********************************************
905
906    Signature_attribute {
907        u2 attribute_name_index;
908            u4 atrribute_length;
909            u2 signature_index;
910    }
911
912 *******************************************************************************/
913
914 #if defined(ENABLE_JAVASE)
915 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
916 {
917         classinfo *c;
918         u4         attribute_length;
919         u2         signature_index;
920
921         /* get classinfo */
922
923         c = cb->class;
924
925         /* check remaining bytecode */
926
927         if (!suck_check_classbuffer_size(cb, 4 + 2))
928                 return false;
929
930         /* check attribute length */
931
932         attribute_length = suck_u4(cb);
933
934         if (attribute_length != 2) {
935                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
936                 return false;
937         }
938
939         if (*signature != NULL) {
940                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
941                 return false;
942         }
943
944         /* get signature */
945
946         signature_index = suck_u2(cb);
947
948         if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
949                 return false;
950
951         return true;
952 }
953 #endif /* defined(ENABLE_JAVASE) */
954
955
956 /* load_class_from_sysloader ***************************************************
957
958    Load the class with the given name using the system class loader
959
960    IN:
961        name.............the classname
962
963    RETURN VALUE:
964        the loaded class, or
965            NULL if an exception has been thrown
966
967 *******************************************************************************/
968
969 classinfo *load_class_from_sysloader(utf *name)
970 {
971         methodinfo    *m;
972         java_handle_t *clo;
973         classloader   *cl;
974         classinfo     *c;
975
976         assert(class_java_lang_Object);
977         assert(class_java_lang_ClassLoader);
978         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
979         
980         m = class_resolveclassmethod(class_java_lang_ClassLoader,
981                                                                  utf_getSystemClassLoader,
982                                                                  utf_void__java_lang_ClassLoader,
983                                                                  class_java_lang_Object,
984                                                                  false);
985
986         if (!m)
987                 return false;
988
989         clo = vm_call_method(m, NULL);
990
991         if (!clo)
992                 return false;
993
994         cl = loader_hashtable_classloader_add(clo);
995
996         c = load_class_from_classloader(name, cl);
997
998         return c;
999 }
1000
1001
1002 /* load_class_from_classloader *************************************************
1003
1004    Load the class with the given name using the given user-defined class loader.
1005
1006    IN:
1007        name.............the classname
1008            cl...............user-defined class loader
1009            
1010    RETURN VALUE:
1011        the loaded class, or
1012            NULL if an exception has been thrown
1013
1014 *******************************************************************************/
1015
1016 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1017 {
1018         java_handle_t *o;
1019         classinfo     *c;
1020         classinfo     *tmpc;
1021         java_handle_t *string;
1022 #if defined(ENABLE_RT_TIMING)
1023         struct timespec time_start, time_lookup, time_prepare, time_java, 
1024                                         time_cache;
1025 #endif
1026
1027         RT_TIMING_GET_TIME(time_start);
1028
1029         assert(name);
1030
1031         /* lookup if this class has already been loaded */
1032
1033         c = classcache_lookup(cl, name);
1034
1035         RT_TIMING_GET_TIME(time_lookup);
1036         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1037
1038         if (c != NULL)
1039                 return c;
1040
1041         /* if other class loader than bootstrap, call it */
1042
1043         if (cl != NULL) {
1044                 methodinfo *lc;
1045                 char       *text;
1046                 s4          namelen;
1047
1048                 text = name->text;
1049                 namelen = name->blength;
1050
1051                 /* handle array classes */
1052                 if (text[0] == '[') {
1053                         classinfo *comp;
1054                         utf       *u;
1055
1056                         switch (text[1]) {
1057                         case 'L':
1058                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1059                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1060                                         exceptions_throw_classnotfoundexception(name);
1061                                         return false;
1062                                 }
1063
1064                                 u = utf_new(text + 2, namelen - 3);
1065
1066                                 if (!(comp = load_class_from_classloader(u, cl)))
1067                                         return false;
1068
1069                                 /* create the array class */
1070
1071                                 c = class_array_of(comp, false);
1072
1073                                 tmpc = classcache_store(cl, c, true);
1074
1075                                 if (tmpc == NULL) {
1076                                         /* exception, free the loaded class */
1077                                         c->state &= ~CLASS_LOADING;
1078                                         class_free(c);
1079                                 }
1080
1081                                 return tmpc;
1082
1083                         case '[':
1084                                 /* load the component class */
1085
1086                                 u = utf_new(text + 1, namelen - 1);
1087
1088                                 if (!(comp = load_class_from_classloader(u, cl)))
1089                                         return false;
1090
1091                                 /* create the array class */
1092
1093                                 c = class_array_of(comp, false);
1094
1095                                 tmpc = classcache_store(cl, c, true);
1096
1097                                 if (tmpc == NULL) {
1098                                         /* exception, free the loaded class */
1099                                         c->state &= ~CLASS_LOADING;
1100                                         class_free(c);
1101                                 }
1102
1103                                 return tmpc;
1104
1105                         default:
1106                                 /* primitive array classes are loaded by the bootstrap loader */
1107
1108                                 c = load_class_bootstrap(name);
1109
1110                                 return c;
1111                         }
1112                 }
1113                 
1114                 assert(class_java_lang_Object);
1115
1116                 lc = class_resolveclassmethod(cl->object->vftbl->class,
1117                                                                           utf_loadClass,
1118                                                                           utf_java_lang_String__java_lang_Class,
1119                                                                           class_java_lang_Object,
1120                                                                           true);
1121
1122                 if (!lc)
1123                         return false; /* exception */
1124
1125                 /* move return value into `o' and cast it afterwards to a classinfo* */
1126
1127                 string = javastring_new_slash_to_dot(name);
1128
1129                 RT_TIMING_GET_TIME(time_prepare);
1130
1131                 o = vm_call_method(lc, cl->object, string);
1132
1133                 RT_TIMING_GET_TIME(time_java);
1134
1135                 c = (classinfo *) o;
1136
1137                 if (c != NULL) {
1138                         /* Store this class in the loaded class cache. If another
1139                            class with the same (initloader,name) pair has been
1140                            stored earlier it will be returned by classcache_store
1141                            In this case classcache_store may not free the class
1142                            because it has already been exposed to Java code which
1143                            may have kept references to that class. */
1144
1145                     tmpc = classcache_store(cl, c, false);
1146
1147                         if (tmpc == NULL) {
1148                                 /* exception, free the loaded class */
1149                                 c->state &= ~CLASS_LOADING;
1150                                 class_free(c);
1151                         }
1152
1153                         c = tmpc;
1154                 }
1155
1156                 RT_TIMING_GET_TIME(time_cache);
1157
1158                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1159                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1160                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1161
1162                 /* SUN compatible -verbose:class output */
1163
1164                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1165                         printf("[Loaded ");
1166                         utf_display_printable_ascii_classname(name);
1167                         printf("]\n");
1168                 }
1169
1170 #if defined(ENABLE_JVMTI)
1171                 /* fire Class Load JVMTI event */
1172                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1173 #endif
1174
1175
1176                 return c;
1177         } 
1178
1179         c = load_class_bootstrap(name);
1180
1181         return c;
1182 }
1183
1184
1185 /* load_class_bootstrap ********************************************************
1186         
1187    Load the class with the given name using the bootstrap class loader.
1188
1189    IN:
1190        name.............the classname
1191
1192    RETURN VALUE:
1193        loaded classinfo, or
1194            NULL if an exception has been thrown
1195
1196    SYNCHRONIZATION:
1197        load_class_bootstrap is synchronized. It can be treated as an
1198            atomic operation.
1199
1200 *******************************************************************************/
1201
1202 classinfo *load_class_bootstrap(utf *name)
1203 {
1204         classbuffer *cb;
1205         classinfo   *c;
1206         classinfo   *r;
1207 #if defined(ENABLE_RT_TIMING)
1208         struct timespec time_start, time_lookup, time_array, time_suck, 
1209                                         time_load, time_cache;
1210 #endif
1211
1212         RT_TIMING_GET_TIME(time_start);
1213
1214         /* for debugging */
1215
1216         assert(name);
1217
1218         /* lookup if this class has already been loaded */
1219
1220         r = classcache_lookup(NULL, name);
1221
1222         if (r != NULL) {
1223                 RT_TIMING_GET_TIME(time_lookup);
1224                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1225                 
1226                 return r;
1227         }
1228
1229         RT_TIMING_GET_TIME(time_lookup);
1230         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1231                 
1232         /* create the classinfo */
1233
1234         c = class_create_classinfo(name);
1235
1236         /* handle array classes */
1237
1238         if (name->text[0] == '[') {
1239                 c = load_newly_created_array(c, NULL);
1240
1241                 if (c == NULL)
1242                         return NULL;
1243
1244                 assert(c->state & CLASS_LOADED);
1245
1246                 RT_TIMING_GET_TIME(time_array);
1247                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1248                 
1249                 return c;
1250         }
1251
1252 #if defined(ENABLE_STATISTICS)
1253         /* measure time */
1254
1255         if (opt_getcompilingtime)
1256                 compilingtime_stop();
1257
1258         if (opt_getloadingtime)
1259                 loadingtime_start();
1260 #endif
1261
1262         /* load classdata, throw exception on error */
1263
1264         cb = suck_start(c);
1265
1266         if (cb == NULL) {
1267                 /* this normally means, the classpath was not set properly */
1268
1269                 if (name == utf_java_lang_Object)
1270                         vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1271
1272                 exceptions_throw_classnotfoundexception(name);
1273
1274                 return NULL;
1275         }
1276
1277         RT_TIMING_GET_TIME(time_suck);
1278         
1279         /* load the class from the buffer */
1280
1281         r = load_class_from_classbuffer(cb);
1282
1283         RT_TIMING_GET_TIME(time_load);
1284         
1285         if (!r) {
1286                 /* the class could not be loaded, free the classinfo struct */
1287
1288                 class_free(c);
1289
1290         } else {
1291                 /* Store this class in the loaded class cache this step also
1292                 checks the loading constraints. If the class has been loaded
1293                 before, the earlier loaded class is returned. */
1294
1295                 classinfo *res = classcache_store(NULL, c, true);
1296
1297                 if (!res) {
1298                         /* exception */
1299                         class_free(c);
1300                 }
1301
1302                 r = res;
1303         }
1304
1305         RT_TIMING_GET_TIME(time_cache);
1306         
1307         /* SUN compatible -verbose:class output */
1308
1309         if (opt_verboseclass && r) {
1310                 printf("[Loaded ");
1311                 utf_display_printable_ascii_classname(name);
1312                 printf(" from %s]\n", cb->path);
1313         }
1314
1315         /* free memory */
1316
1317         suck_stop(cb);
1318
1319 #if defined(ENABLE_STATISTICS)
1320         /* measure time */
1321
1322         if (opt_getloadingtime)
1323                 loadingtime_stop();
1324
1325         if (opt_getcompilingtime)
1326                 compilingtime_start();
1327 #endif
1328
1329         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1330         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1331         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1332         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1333
1334         return r;
1335 }
1336
1337
1338 /* load_class_from_classbuffer *************************************************
1339         
1340    Loads everything interesting about a class from the class file. The
1341    'classinfo' structure must have been allocated previously.
1342
1343    The super class and the interfaces implemented by this class need
1344    not be loaded. The link is set later by the function 'class_link'.
1345
1346    SYNCHRONIZATION:
1347        This function is NOT synchronized!
1348    
1349 *******************************************************************************/
1350
1351 classinfo *load_class_from_classbuffer(classbuffer *cb)
1352 {
1353         classinfo *c;
1354         utf *name;
1355         utf *supername;
1356         u4 i,j;
1357         u4 ma, mi;
1358         s4 dumpsize;
1359         descriptor_pool *descpool;
1360 #if defined(ENABLE_STATISTICS)
1361         u4 classrefsize;
1362         u4 descsize;
1363 #endif
1364 #if defined(ENABLE_RT_TIMING)
1365         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1366                                         time_setup, time_fields, time_methods, time_classrefs,
1367                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1368                                         time_parsecpool, time_verify, time_attrs;
1369 #endif
1370
1371         RT_TIMING_GET_TIME(time_start);
1372
1373         /* get the classbuffer's class */
1374
1375         c = cb->class;
1376
1377         /* the class is already loaded */
1378
1379         if (c->state & CLASS_LOADED)
1380                 return c;
1381
1382 #if defined(ENABLE_STATISTICS)
1383         if (opt_stat)
1384                 count_class_loads++;
1385 #endif
1386
1387 #if !defined(NDEBUG)
1388         /* output for debugging purposes */
1389
1390         if (loadverbose)
1391                 log_message_class("Loading class: ", c);
1392 #endif
1393
1394         /* mark start of dump memory area */
1395
1396         dumpsize = dump_size();
1397
1398         /* class is currently loading */
1399
1400         c->state |= CLASS_LOADING;
1401
1402         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1403                 goto return_exception;
1404
1405         /* check signature */
1406
1407         if (suck_u4(cb) != MAGIC) {
1408                 exceptions_throw_classformaterror(c, "Bad magic number");
1409
1410                 goto return_exception;
1411         }
1412
1413         /* check version */
1414
1415         mi = suck_u2(cb);
1416         ma = suck_u2(cb);
1417
1418         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1419                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1420                 goto return_exception;
1421         }
1422
1423         RT_TIMING_GET_TIME(time_checks);
1424
1425         /* create a new descriptor pool */
1426
1427         descpool = descriptor_pool_new(c);
1428
1429         RT_TIMING_GET_TIME(time_ndpool);
1430
1431         /* load the constant pool */
1432
1433         if (!load_constantpool(cb, descpool))
1434                 goto return_exception;
1435
1436         RT_TIMING_GET_TIME(time_cpool);
1437
1438         /* ACC flags */
1439
1440         if (!suck_check_classbuffer_size(cb, 2))
1441                 goto return_exception;
1442
1443         /* We OR the flags here, as we set already some flags in
1444            class_create_classinfo. */
1445
1446         c->flags |= suck_u2(cb);
1447
1448         /* check ACC flags consistency */
1449
1450         if (c->flags & ACC_INTERFACE) {
1451                 if (!(c->flags & ACC_ABSTRACT)) {
1452                         /* We work around this because interfaces in JDK 1.1 are
1453                          * not declared abstract. */
1454
1455                         c->flags |= ACC_ABSTRACT;
1456                 }
1457
1458                 if (c->flags & ACC_FINAL) {
1459                         exceptions_throw_classformaterror(c,
1460                                                                                           "Illegal class modifiers: 0x%X",
1461                                                                                           c->flags);
1462                         goto return_exception;
1463                 }
1464
1465                 if (c->flags & ACC_SUPER) {
1466                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1467                 }
1468         }
1469
1470         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1471                 exceptions_throw_classformaterror(c,
1472                                                                                   "Illegal class modifiers: 0x%X",
1473                                                                                   c->flags);
1474                 goto return_exception;
1475         }
1476
1477         if (!suck_check_classbuffer_size(cb, 2 + 2))
1478                 goto return_exception;
1479
1480         /* this class */
1481
1482         i = suck_u2(cb);
1483
1484         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1485                 goto return_exception;
1486
1487         if (c->name == utf_not_named_yet) {
1488                 /* we finally have a name for this class */
1489                 c->name = name;
1490                 class_set_packagename(c);
1491         }
1492         else if (name != c->name) {
1493                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1494                 goto return_exception;
1495         }
1496
1497         /* retrieve superclass */
1498
1499         c->super.any = NULL;
1500
1501         if ((i = suck_u2(cb))) {
1502                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1503                         goto return_exception;
1504
1505                 /* java.lang.Object may not have a super class. */
1506
1507                 if (c->name == utf_java_lang_Object) {
1508                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1509                         goto return_exception;
1510                 }
1511
1512                 /* Interfaces must have java.lang.Object as super class. */
1513
1514                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1515                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1516                         goto return_exception;
1517                 }
1518
1519         } else {
1520                 supername = NULL;
1521
1522                 /* This is only allowed for java.lang.Object. */
1523
1524                 if (c->name != utf_java_lang_Object) {
1525                         exceptions_throw_classformaterror(c, "Bad superclass index");
1526                         goto return_exception;
1527                 }
1528         }
1529
1530         /* retrieve interfaces */
1531
1532         if (!suck_check_classbuffer_size(cb, 2))
1533                 goto return_exception;
1534
1535         c->interfacescount = suck_u2(cb);
1536
1537         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1538                 goto return_exception;
1539
1540         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1541         for (i = 0; i < c->interfacescount; i++) {
1542                 /* the classrefs are created later */
1543                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1544                         goto return_exception;
1545         }
1546
1547         RT_TIMING_GET_TIME(time_setup);
1548
1549         /* load fields */
1550
1551         if (!suck_check_classbuffer_size(cb, 2))
1552                 goto return_exception;
1553
1554         c->fieldscount = suck_u2(cb);
1555         c->fields      = MNEW(fieldinfo, c->fieldscount);
1556
1557         MZERO(c->fields, fieldinfo, c->fieldscount);
1558
1559         for (i = 0; i < c->fieldscount; i++) {
1560                 if (!field_load(cb, &(c->fields[i]), descpool))
1561                         goto return_exception;
1562         }
1563
1564         RT_TIMING_GET_TIME(time_fields);
1565
1566         /* load methods */
1567
1568         if (!suck_check_classbuffer_size(cb, 2))
1569                 goto return_exception;
1570
1571         c->methodscount = suck_u2(cb);
1572         c->methods      = MNEW(methodinfo, c->methodscount);
1573
1574         MZERO(c->methods, methodinfo, c->methodscount);
1575         
1576         for (i = 0; i < c->methodscount; i++) {
1577                 if (!method_load(cb, &(c->methods[i]), descpool))
1578                         goto return_exception;
1579         }
1580
1581         RT_TIMING_GET_TIME(time_methods);
1582
1583         /* create the class reference table */
1584
1585         c->classrefs =
1586                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1587
1588         RT_TIMING_GET_TIME(time_classrefs);
1589
1590         /* allocate space for the parsed descriptors */
1591
1592         descriptor_pool_alloc_parsed_descriptors(descpool);
1593         c->parseddescs =
1594                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1595
1596 #if defined(ENABLE_STATISTICS)
1597         if (opt_stat) {
1598                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1599                 count_classref_len += classrefsize;
1600                 count_parsed_desc_len += descsize;
1601         }
1602 #endif
1603
1604         RT_TIMING_GET_TIME(time_descs);
1605
1606         /* put the classrefs in the constant pool */
1607         for (i = 0; i < c->cpcount; i++) {
1608                 if (c->cptags[i] == CONSTANT_Class) {
1609                         utf *name = (utf *) c->cpinfos[i];
1610                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1611                 }
1612         }
1613
1614         /* set the super class reference */
1615
1616         if (supername) {
1617                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1618                 if (!c->super.ref)
1619                         goto return_exception;
1620         }
1621
1622         /* set the super interfaces references */
1623
1624         for (i = 0; i < c->interfacescount; i++) {
1625                 c->interfaces[i].ref =
1626                         descriptor_pool_lookup_classref(descpool,
1627                                                                                         (utf *) c->interfaces[i].any);
1628                 if (!c->interfaces[i].ref)
1629                         goto return_exception;
1630         }
1631
1632         RT_TIMING_GET_TIME(time_setrefs);
1633
1634         /* parse field descriptors */
1635
1636         for (i = 0; i < c->fieldscount; i++) {
1637                 c->fields[i].parseddesc =
1638                         descriptor_pool_parse_field_descriptor(descpool,
1639                                                                                                    c->fields[i].descriptor);
1640                 if (!c->fields[i].parseddesc)
1641                         goto return_exception;
1642         }
1643
1644         RT_TIMING_GET_TIME(time_parsefds);
1645
1646         /* parse method descriptors */
1647
1648         for (i = 0; i < c->methodscount; i++) {
1649                 methodinfo *m = &c->methods[i];
1650                 m->parseddesc =
1651                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1652                                                                                                         m->flags, class_get_self_classref(m->class));
1653                 if (!m->parseddesc)
1654                         goto return_exception;
1655
1656                 for (j = 0; j < m->rawexceptiontablelength; j++) {
1657                         if (!m->rawexceptiontable[j].catchtype.any)
1658                                 continue;
1659                         if ((m->rawexceptiontable[j].catchtype.ref =
1660                                  descriptor_pool_lookup_classref(descpool,
1661                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1662                                 goto return_exception;
1663                 }
1664
1665                 for (j = 0; j < m->thrownexceptionscount; j++) {
1666                         if (!m->thrownexceptions[j].any)
1667                                 continue;
1668                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1669                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
1670                                 goto return_exception;
1671                 }
1672         }
1673
1674         RT_TIMING_GET_TIME(time_parsemds);
1675
1676         /* parse the loaded descriptors */
1677
1678         for (i = 0; i < c->cpcount; i++) {
1679                 constant_FMIref *fmi;
1680                 s4               index;
1681
1682                 switch (c->cptags[i]) {
1683                 case CONSTANT_Fieldref:
1684                         fmi = (constant_FMIref *) c->cpinfos[i];
1685                         fmi->parseddesc.fd =
1686                                 descriptor_pool_parse_field_descriptor(descpool,
1687                                                                                                            fmi->descriptor);
1688                         if (!fmi->parseddesc.fd)
1689                                 goto return_exception;
1690                         index = fmi->p.index;
1691                         fmi->p.classref =
1692                                 (constant_classref *) class_getconstant(c, index,
1693                                                                                                                 CONSTANT_Class);
1694                         if (!fmi->p.classref)
1695                                 goto return_exception;
1696                         break;
1697                 case CONSTANT_Methodref:
1698                 case CONSTANT_InterfaceMethodref:
1699                         fmi = (constant_FMIref *) c->cpinfos[i];
1700                         index = fmi->p.index;
1701                         fmi->p.classref =
1702                                 (constant_classref *) class_getconstant(c, index,
1703                                                                                                                 CONSTANT_Class);
1704                         if (!fmi->p.classref)
1705                                 goto return_exception;
1706                         fmi->parseddesc.md =
1707                                 descriptor_pool_parse_method_descriptor(descpool,
1708                                                                                                                 fmi->descriptor,
1709                                                                                                                 ACC_UNDEF,
1710                                                                                                                 fmi->p.classref);
1711                         if (!fmi->parseddesc.md)
1712                                 goto return_exception;
1713                         break;
1714                 }
1715         }
1716
1717         RT_TIMING_GET_TIME(time_parsecpool);
1718
1719 #ifdef ENABLE_VERIFIER
1720         /* Check if all fields and methods can be uniquely
1721          * identified by (name,descriptor). */
1722
1723         if (opt_verify) {
1724                 /* We use a hash table here to avoid making the
1725                  * average case quadratic in # of methods, fields.
1726                  */
1727                 static int shift = 0;
1728                 u2 *hashtab;
1729                 u2 *next; /* for chaining colliding hash entries */
1730                 size_t len;
1731                 size_t hashlen;
1732                 u2 index;
1733                 u2 old;
1734
1735                 /* Allocate hashtable */
1736                 len = c->methodscount;
1737                 if (len < c->fieldscount) len = c->fieldscount;
1738                 hashlen = 5 * len;
1739                 hashtab = MNEW(u2,(hashlen + len));
1740                 next = hashtab + hashlen;
1741
1742                 /* Determine bitshift (to get good hash values) */
1743                 if (!shift) {
1744                         len = sizeof(utf);
1745                         while (len) {
1746                                 len >>= 1;
1747                                 shift++;
1748                         }
1749                 }
1750
1751                 /* Check fields */
1752                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1753
1754                 for (i = 0; i < c->fieldscount; ++i) {
1755                         fieldinfo *fi = c->fields + i;
1756
1757                         /* It's ok if we lose bits here */
1758                         index = ((((size_t) fi->name) +
1759                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
1760
1761                         if ((old = hashtab[index])) {
1762                                 old--;
1763                                 next[i] = old;
1764                                 do {
1765                                         if (c->fields[old].name == fi->name &&
1766                                                 c->fields[old].descriptor == fi->descriptor) {
1767                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1768                                                 goto return_exception;
1769                                         }
1770                                 } while ((old = next[old]));
1771                         }
1772                         hashtab[index] = i + 1;
1773                 }
1774
1775                 /* Check methods */
1776                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1777
1778                 for (i = 0; i < c->methodscount; ++i) {
1779                         methodinfo *mi = c->methods + i;
1780
1781                         /* It's ok if we lose bits here */
1782                         index = ((((size_t) mi->name) +
1783                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
1784
1785                         /*{ JOWENN
1786                                 int dbg;
1787                                 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1788                                         printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
1789                                 }
1790                         }*/
1791
1792                         if ((old = hashtab[index])) {
1793                                 old--;
1794                                 next[i] = old;
1795                                 do {
1796                                         if (c->methods[old].name == mi->name &&
1797                                                 c->methods[old].descriptor == mi->descriptor) {
1798                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1799                                                 goto return_exception;
1800                                         }
1801                                 } while ((old = next[old]));
1802                         }
1803                         hashtab[index] = i + 1;
1804                 }
1805
1806                 MFREE(hashtab, u2, (hashlen + len));
1807         }
1808 #endif /* ENABLE_VERIFIER */
1809
1810         RT_TIMING_GET_TIME(time_verify);
1811
1812 #if defined(ENABLE_STATISTICS)
1813         if (opt_stat) {
1814                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
1815                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
1816                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1817         }
1818 #endif
1819
1820         /* load attribute structures */
1821
1822         if (!class_load_attributes(cb))
1823                 goto return_exception;
1824
1825         /* Pre Java 1.5 version don't check this. This implementation is like
1826            Java 1.5 do it: for class file version 45.3 we don't check it, older
1827            versions are checked.
1828          */
1829
1830         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1831                 /* check if all data has been read */
1832                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1833
1834                 if (classdata_left > 0) {
1835                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1836                         goto return_exception;
1837                 }
1838         }
1839
1840         RT_TIMING_GET_TIME(time_attrs);
1841
1842         /* release dump area */
1843
1844         dump_release(dumpsize);
1845
1846         /* revert loading state and class is loaded */
1847
1848         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1849
1850 #if defined(ENABLE_JVMTI)
1851         /* fire Class Prepare JVMTI event */
1852
1853         if (jvmti)
1854                 jvmti_ClassLoadPrepare(true, c);
1855 #endif
1856
1857 #if !defined(NDEBUG)
1858         if (loadverbose)
1859                 log_message_class("Loading done class: ", c);
1860 #endif
1861
1862         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
1863         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
1864         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
1865         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
1866         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
1867         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
1868         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1869         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
1870         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
1871         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
1872         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
1873         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1874         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
1875         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
1876         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
1877
1878         return c;
1879
1880 return_exception:
1881         /* release dump area */
1882
1883         dump_release(dumpsize);
1884
1885         /* an exception has been thrown */
1886
1887         return NULL;
1888 }
1889
1890
1891 /* load_newly_created_array ****************************************************
1892
1893    Load a newly created array class.
1894
1895         RETURN VALUE:
1896             c....................the array class C has been loaded
1897                 other classinfo......the array class was found in the class cache, 
1898                                      C has been freed
1899             NULL.................an exception has been thrown
1900
1901         Note:
1902                 This is an internal function. Do not use it unless you know exactly
1903                 what you are doing!
1904
1905                 Use one of the load_class_... functions for general array class loading.
1906
1907 *******************************************************************************/
1908
1909 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1910 {
1911         classinfo         *comp = NULL;
1912         methodinfo        *clone;
1913         methoddesc        *clonedesc;
1914         constant_classref *classrefs;
1915         char              *text;
1916         s4                 namelen;
1917         utf               *u;
1918
1919         text    = c->name->text;
1920         namelen = c->name->blength;
1921
1922         /* Check array class name */
1923
1924         if ((namelen < 2) || (text[0] != '[')) {
1925                 exceptions_throw_classnotfoundexception(c->name);
1926                 return NULL;
1927         }
1928
1929         /* Check the element type */
1930
1931         switch (text[1]) {
1932         case '[':
1933                 /* c is an array of arrays. We have to create the component class. */
1934
1935                 u = utf_new(text + 1, namelen - 1);
1936
1937                 comp = load_class_from_classloader(u, loader);
1938
1939                 if (comp == NULL)
1940                         return NULL;
1941
1942                 assert(comp->state & CLASS_LOADED);
1943
1944                 /* the array's flags are that of the component class */
1945                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1946                 c->classloader = comp->classloader;
1947                 break;
1948
1949         case 'L':
1950                 /* c is an array of objects. */
1951
1952                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1953                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1954                         exceptions_throw_classnotfoundexception(c->name);
1955                         return NULL;
1956                 }
1957
1958                 u = utf_new(text + 2, namelen - 3);
1959
1960                 if (!(comp = load_class_from_classloader(u, loader)))
1961                         return NULL;
1962
1963                 assert(comp->state & CLASS_LOADED);
1964
1965                 /* the array's flags are that of the component class */
1966                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1967                 c->classloader = comp->classloader;
1968                 break;
1969
1970         default:
1971                 /* c is an array of a primitive type */
1972
1973                 /* check for cases like `[II' and whether the character is a
1974                    valid primitive type */
1975
1976                 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1977                         exceptions_throw_classnotfoundexception(c->name);
1978                         return NULL;
1979                 }
1980
1981                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1982                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1983                 c->classloader = NULL;
1984         }
1985
1986         assert(class_java_lang_Object);
1987 #if defined(ENABLE_JAVASE)
1988         assert(class_java_lang_Cloneable);
1989         assert(class_java_io_Serializable);
1990 #endif
1991
1992         /* setup the array class */
1993
1994         c->super.cls = class_java_lang_Object;
1995
1996 #if defined(ENABLE_JAVASE)
1997
1998         c->interfacescount   = 2;
1999     c->interfaces        = MNEW(classref_or_classinfo, 2);
2000         c->interfaces[0].cls = class_java_lang_Cloneable;
2001         c->interfaces[1].cls = class_java_io_Serializable;
2002
2003 #elif defined(ENABLE_JAVAME_CLDC1_1)
2004
2005         c->interfacescount   = 0;
2006         c->interfaces        = NULL;
2007
2008 #else
2009 # error unknow Java configuration
2010 #endif
2011
2012         c->methodscount = 1;
2013         c->methods = MNEW(methodinfo, c->methodscount);
2014         MZERO(c->methods, methodinfo, c->methodscount);
2015
2016         classrefs = MNEW(constant_classref, 2);
2017         CLASSREF_INIT(classrefs[0], c, c->name);
2018         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2019
2020         /* create descriptor for clone method */
2021         /* we need one paramslot which is reserved for the 'this' parameter */
2022         clonedesc = NEW(methoddesc);
2023         clonedesc->returntype.type = TYPE_ADR;
2024         clonedesc->returntype.classref = classrefs + 1;
2025         clonedesc->returntype.arraydim = 0;
2026         /* initialize params to "empty", add real params below in
2027            descriptor_params_from_paramtypes */
2028         clonedesc->paramcount = 0;
2029         clonedesc->paramslots = 0;
2030         clonedesc->paramtypes[0].classref = classrefs + 0;
2031         clonedesc->params = NULL;
2032
2033         /* create methodinfo */
2034
2035         clone = c->methods;
2036         MSET(clone, 0, methodinfo, 1);
2037
2038 #if defined(ENABLE_THREADS)
2039         lock_init_object_lock(&clone->header);
2040 #endif
2041
2042         /* ATTENTION: if you delete the ACC_NATIVE below, set
2043            clone->maxlocals=1 (interpreter related) */
2044
2045         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2046         clone->name       = utf_clone;
2047         clone->descriptor = utf_void__java_lang_Object;
2048         clone->parseddesc = clonedesc;
2049         clone->class      = c;
2050
2051         /* parse the descriptor to get the register allocation */
2052
2053         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2054                 return false;
2055
2056         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2057
2058         /* XXX: field: length? */
2059
2060         /* array classes are not loaded from class files */
2061
2062         c->state          |= CLASS_LOADED;
2063         c->parseddescs    = (u1 *) clonedesc;
2064         c->parseddescsize = sizeof(methodinfo);
2065         c->classrefs      = classrefs;
2066         c->classrefcount  = 1;
2067
2068         /* insert class into the loaded class cache */
2069         /* XXX free classinfo if NULL returned? */
2070
2071         return classcache_store(loader, c, true);
2072 }
2073
2074
2075 /* loader_close ****************************************************************
2076
2077    Frees all resources.
2078         
2079 *******************************************************************************/
2080
2081 void loader_close(void)
2082 {
2083         /* empty */
2084 }
2085
2086
2087 /*
2088  * These are local overrides for various environment variables in Emacs.
2089  * Please do not remove this and leave it at the end of the file, where
2090  * Emacs will automagically detect them.
2091  * ---------------------------------------------------------------------
2092  * Local variables:
2093  * mode: c
2094  * indent-tabs-mode: t
2095  * c-basic-offset: 4
2096  * tab-width: 4
2097  * End:
2098  * vim:noexpandtab:sw=4:ts=4:
2099  */