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