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