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