* src/vm/jit/parse.c, src/vm/jit/parse.h (Changes): Merged with
[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 5937 2006-11-08 22:00:57Z 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         if (!suck_check_classbuffer_size(cb, 2))
1133                 return false;
1134         
1135         attrnum = suck_u2(cb);
1136         for (i = 0; i < attrnum; i++) {
1137                 utf *aname;
1138
1139                 if (!suck_check_classbuffer_size(cb, 2))
1140                         return false;
1141
1142                 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1143                         return false;
1144
1145                 if (aname == utf_Code) {
1146                         if (m->flags & (ACC_ABSTRACT | ACC_NATIVE)) {
1147                                 exceptions_throw_classformaterror(c, "Code attribute in native or abstract methods");
1148                                 return false;
1149                         }
1150                         
1151                         if (m->jcode) {
1152                                 exceptions_throw_classformaterror(c, "Multiple Code attributes");
1153                                 return false;
1154                         }
1155
1156                         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1157                                 return false;
1158
1159                         suck_u4(cb);
1160                         m->maxstack = suck_u2(cb);
1161                         m->maxlocals = suck_u2(cb);
1162
1163                         if (m->maxlocals < argcount) {
1164                                 exceptions_throw_classformaterror(c, "Arguments can't fit into locals");
1165                                 return false;
1166                         }
1167                         
1168                         if (!suck_check_classbuffer_size(cb, 4))
1169                                 return false;
1170
1171                         m->jcodelength = suck_u4(cb);
1172
1173                         if (m->jcodelength == 0) {
1174                                 exceptions_throw_classformaterror(c, "Code of a method has length 0");
1175                                 return false;
1176                         }
1177                         
1178                         if (m->jcodelength > 65535) {
1179                                 exceptions_throw_classformaterror(c, "Code of a method longer than 65535 bytes");
1180                                 return false;
1181                         }
1182
1183                         if (!suck_check_classbuffer_size(cb, m->jcodelength))
1184                                 return false;
1185
1186                         m->jcode = MNEW(u1, m->jcodelength);
1187                         suck_nbytes(m->jcode, cb, m->jcodelength);
1188
1189                         if (!suck_check_classbuffer_size(cb, 2))
1190                                 return false;
1191
1192                         m->rawexceptiontablelength = suck_u2(cb);
1193                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * m->rawexceptiontablelength))
1194                                 return false;
1195
1196                         m->rawexceptiontable = MNEW(raw_exception_entry, m->rawexceptiontablelength);
1197
1198 #if defined(ENABLE_STATISTICS)
1199                         if (opt_stat) {
1200                                 count_vmcode_len += m->jcodelength + 18;
1201                                 count_extable_len +=
1202                                         m->rawexceptiontablelength * sizeof(raw_exception_entry);
1203                         }
1204 #endif
1205
1206                         for (j = 0; j < m->rawexceptiontablelength; j++) {
1207                                 u4 idx;
1208                                 m->rawexceptiontable[j].startpc = suck_u2(cb);
1209                                 m->rawexceptiontable[j].endpc = suck_u2(cb);
1210                                 m->rawexceptiontable[j].handlerpc = suck_u2(cb);
1211
1212                                 idx = suck_u2(cb);
1213                                 if (!idx) {
1214                                         m->rawexceptiontable[j].catchtype.any = NULL;
1215
1216                                 } else {
1217                                         /* the classref is created later */
1218                                         if (!(m->rawexceptiontable[j].catchtype.any =
1219                                                   (utf*)class_getconstant(c, idx, CONSTANT_Class)))
1220                                                 return false;
1221                                 }
1222                         }
1223
1224                         if (!suck_check_classbuffer_size(cb, 2))
1225                                 return false;
1226
1227                         codeattrnum = suck_u2(cb);
1228
1229                         for (; codeattrnum > 0; codeattrnum--) {
1230                                 utf *caname;
1231
1232                                 if (!suck_check_classbuffer_size(cb, 2))
1233                                         return false;
1234
1235                                 if (!(caname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1236                                         return false;
1237
1238                                 if (caname == utf_LineNumberTable) {
1239                                         u2 lncid;
1240
1241                                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1242                                                 return false;
1243
1244                                         suck_u4(cb);
1245                                         m->linenumbercount = suck_u2(cb);
1246
1247                                         if (!suck_check_classbuffer_size(cb,
1248                                                                                                 (2 + 2) * m->linenumbercount))
1249                                                 return false;
1250
1251                                         m->linenumbers = MNEW(lineinfo, m->linenumbercount);
1252                                         
1253                                         for (lncid = 0; lncid < m->linenumbercount; lncid++) {
1254                                                 m->linenumbers[lncid].start_pc = suck_u2(cb);
1255                                                 m->linenumbers[lncid].line_number = suck_u2(cb);
1256                                         }
1257                                         codeattrnum--;
1258
1259                                         if (!skipattributes(cb, codeattrnum))
1260                                                 return false;
1261                                         
1262                                         break;
1263
1264                                 } else {
1265                                         if (!skipattributebody(cb))
1266                                                 return false;
1267                                 }
1268                         }
1269                 }
1270                 else if (aname == utf_Exceptions) {
1271                         s4 j;
1272
1273                         if (m->thrownexceptions) {
1274                                 exceptions_throw_classformaterror(c, "Multiple Exceptions attributes");
1275                                 return false;
1276                         }
1277
1278                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1279                                 return false;
1280
1281                         suck_u4(cb); /* length */
1282                         m->thrownexceptionscount = suck_u2(cb);
1283
1284                         if (!suck_check_classbuffer_size(cb, 2 * m->thrownexceptionscount))
1285                                 return false;
1286
1287                         m->thrownexceptions = MNEW(classref_or_classinfo, m->thrownexceptionscount);
1288
1289                         for (j = 0; j < m->thrownexceptionscount; j++) {
1290                                 /* the classref is created later */
1291                                 if (!((m->thrownexceptions)[j].any =
1292                                           (utf*) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1293                                         return false;
1294                         }
1295                 }
1296                 else if (aname == utf_Signature) {
1297                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1298                                 return false;
1299
1300                         /* check attribute length */
1301
1302                         if (suck_u4(cb) != 2) {
1303                                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1304                                 return false;
1305                         }
1306
1307                         if (m->signature != NULL) {
1308                                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
1309                                 return false;
1310                         }
1311
1312                         if (!(m->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1313                                 return false;
1314                 }
1315                 else {
1316                         if (!skipattributebody(cb))
1317                                 return false;
1318                 }
1319         }
1320
1321         if (!m->jcode && !(m->flags & (ACC_ABSTRACT | ACC_NATIVE))) {
1322                 exceptions_throw_classformaterror(c, "Missing Code attribute");
1323                 return false;
1324         }
1325
1326         /* everything was ok */
1327
1328         return true;
1329 }
1330
1331
1332 /* load_attribute **************************************************************
1333
1334    Read attributes from classfile.
1335         
1336 *******************************************************************************/
1337
1338 static bool load_attributes(classbuffer *cb, u4 num)
1339 {
1340         classinfo *c;
1341         utf       *aname;
1342         u4 i, j;
1343
1344         c = cb->class;
1345
1346         for (i = 0; i < num; i++) {
1347                 /* retrieve attribute name */
1348
1349                 if (!suck_check_classbuffer_size(cb, 2))
1350                         return false;
1351
1352                 if (!(aname = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1353                         return false;
1354
1355                 if (aname == utf_InnerClasses) {
1356                         /* InnerClasses attribute */
1357
1358                         if (c->innerclass != NULL) {
1359                                 exceptions_throw_classformaterror(c, "Multiple InnerClasses attributes");
1360                                 return false;
1361                         }
1362                                 
1363                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1364                                 return false;
1365
1366                         /* skip attribute length */
1367                         suck_u4(cb);
1368
1369                         /* number of records */
1370                         c->innerclasscount = suck_u2(cb);
1371
1372                         if (!suck_check_classbuffer_size(cb, (2 + 2 + 2 + 2) * c->innerclasscount))
1373                                 return false;
1374
1375                         /* allocate memory for innerclass structure */
1376                         c->innerclass = MNEW(innerclassinfo, c->innerclasscount);
1377
1378                         for (j = 0; j < c->innerclasscount; j++) {
1379                                 /* The innerclass structure contains a class with an encoded
1380                                    name, its defining scope, its simple name and a bitmask of
1381                                    the access flags. If an inner class is not a member, its
1382                                    outer_class is NULL, if a class is anonymous, its name is
1383                                    NULL. */
1384                                                                 
1385                                 innerclassinfo *info = c->innerclass + j;
1386
1387                                 info->inner_class.ref =
1388                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1389                                 info->outer_class.ref =
1390                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Class);
1391                                 info->name =
1392                                         innerclass_getconstant(c, suck_u2(cb), CONSTANT_Utf8);
1393                                 info->flags = suck_u2(cb);
1394                         }
1395                 }
1396                 else if (aname == utf_SourceFile) {
1397                         /* SourceFile attribute */
1398
1399                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1400                                 return false;
1401
1402                         if (suck_u4(cb) != 2) {
1403                                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1404                                 return false;
1405                         }
1406
1407                         if (c->sourcefile != NULL) {
1408                                 exceptions_throw_classformaterror(c, "Multiple SourceFile attributes");
1409                                 return false;
1410                         }
1411
1412                         if (!(c->sourcefile = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1413                                 return false;
1414                 }
1415                 else if (aname == utf_Signature) {
1416                         /* Signature attribute */
1417
1418                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1419                                 return false;
1420
1421                         if (suck_u4(cb) != 2) {
1422                                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1423                                 return false;
1424                         }
1425
1426                         if (c->signature != NULL) {
1427                                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
1428                                 return false;
1429                         }
1430
1431                         if (!(c->signature = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1432                                 return false;
1433                 }
1434                 else {
1435                         /* unknown attribute */
1436
1437                         if (!skipattributebody(cb))
1438                                 return false;
1439                 }
1440         }
1441
1442         return true;
1443 }
1444
1445
1446 /* load_class_from_sysloader ***************************************************
1447
1448    Load the class with the given name using the system class loader
1449
1450    IN:
1451        name.............the classname
1452
1453    RETURN VALUE:
1454        the loaded class, or
1455            NULL if an exception has been thrown
1456
1457 *******************************************************************************/
1458
1459 classinfo *load_class_from_sysloader(utf *name)
1460 {
1461         methodinfo        *m;
1462         java_objectheader *cl;
1463         classinfo         *c;
1464
1465         assert(class_java_lang_Object);
1466         assert(class_java_lang_ClassLoader);
1467         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1468         
1469         m = class_resolveclassmethod(class_java_lang_ClassLoader,
1470                                                                  utf_getSystemClassLoader,
1471                                                                  utf_void__java_lang_ClassLoader,
1472                                                                  class_java_lang_Object,
1473                                                                  false);
1474
1475         if (!m)
1476                 return false;
1477
1478         cl = vm_call_method(m, NULL);
1479
1480         if (!cl)
1481                 return false;
1482
1483         c = load_class_from_classloader(name, cl);
1484
1485         return c;
1486 }
1487
1488
1489 /* load_class_from_classloader *************************************************
1490
1491    Load the class with the given name using the given user-defined class loader.
1492
1493    IN:
1494        name.............the classname
1495            cl...............user-defined class loader
1496            
1497    RETURN VALUE:
1498        the loaded class, or
1499            NULL if an exception has been thrown
1500
1501 *******************************************************************************/
1502
1503 classinfo *load_class_from_classloader(utf *name, java_objectheader *cl)
1504 {
1505         java_objectheader *o;
1506         classinfo         *c;
1507         classinfo         *tmpc;
1508         java_lang_String  *s;
1509 #if defined(ENABLE_RT_TIMING)
1510         struct timespec time_start, time_lookup, time_prepare, time_java, 
1511                                         time_cache;
1512 #endif
1513
1514         RT_TIMING_GET_TIME(time_start);
1515
1516         assert(name);
1517
1518         /* lookup if this class has already been loaded */
1519
1520         c = classcache_lookup(cl, name);
1521
1522         RT_TIMING_GET_TIME(time_lookup);
1523         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1524
1525         if (c)
1526                 return c;
1527
1528         /* if other class loader than bootstrap, call it */
1529
1530         if (cl) {
1531                 methodinfo *lc;
1532                 char       *text;
1533                 s4          namelen;
1534
1535                 text = name->text;
1536                 namelen = name->blength;
1537
1538                 /* handle array classes */
1539                 if (text[0] == '[') {
1540                         classinfo *comp;
1541                         utf       *u;
1542
1543                         switch (text[1]) {
1544                         case 'L':
1545                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1546                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1547                                         *exceptionptr = new_noclassdeffounderror(name);
1548                                         return false;
1549                                 }
1550
1551                                 u = utf_new(text + 2, namelen - 3);
1552
1553                                 if (!(comp = load_class_from_classloader(u, cl)))
1554                                         return false;
1555
1556                                 /* create the array class */
1557
1558                                 c = class_array_of(comp, false);
1559
1560                                 tmpc = classcache_store(cl, c, true);
1561
1562                                 if (tmpc == NULL) {
1563                                         /* exception, free the loaded class */
1564                                         c->state &= ~CLASS_LOADING;
1565                                         class_free(c);
1566                                 }
1567
1568                                 return tmpc;
1569
1570                         case '[':
1571                                 /* load the component class */
1572
1573                                 u = utf_new(text + 1, namelen - 1);
1574
1575                                 if (!(comp = load_class_from_classloader(u, cl)))
1576                                         return false;
1577
1578                                 /* create the array class */
1579
1580                                 c = class_array_of(comp, false);
1581
1582                                 tmpc = classcache_store(cl, c, true);
1583
1584                                 if (tmpc == NULL) {
1585                                         /* exception, free the loaded class */
1586                                         c->state &= ~CLASS_LOADING;
1587                                         class_free(c);
1588                                 }
1589
1590                                 return tmpc;
1591
1592                         default:
1593                                 /* primitive array classes are loaded by the bootstrap loader */
1594
1595                                 c = load_class_bootstrap(name);
1596
1597                                 return c;
1598                         }
1599                 }
1600                 
1601                 assert(class_java_lang_Object);
1602
1603                 lc = class_resolveclassmethod(cl->vftbl->class,
1604                                                                           utf_loadClass,
1605                                                                           utf_java_lang_String__java_lang_Class,
1606                                                                           class_java_lang_Object,
1607                                                                           true);
1608
1609                 if (!lc)
1610                         return false; /* exception */
1611
1612                 /* move return value into `o' and cast it afterwards to a classinfo* */
1613
1614                 s = javastring_new_slash_to_dot(name);
1615
1616                 RT_TIMING_GET_TIME(time_prepare);
1617
1618                 o = vm_call_method(lc, cl, s);
1619
1620                 RT_TIMING_GET_TIME(time_java);
1621
1622                 c = (classinfo *) o;
1623
1624                 if (c) {
1625                         /* Store this class in the loaded class cache. If another
1626                            class with the same (initloader,name) pair has been
1627                            stored earlier it will be returned by classcache_store
1628                            In this case classcache_store may not free the class
1629                            because it has already been exposed to Java code which
1630                            may have kept references to that class. */
1631
1632                     tmpc = classcache_store(cl, c, false);
1633
1634                         if (tmpc == NULL) {
1635                                 /* exception, free the loaded class */
1636                                 c->state &= ~CLASS_LOADING;
1637                                 class_free(c);
1638                         }
1639
1640                         c = tmpc;
1641
1642                 } else {
1643                         /* loadClass has thrown an exception.  We must convert
1644                            ClassNotFoundException into
1645                            NoClassDefFoundException. */
1646
1647                         /* XXX Maybe we should have a flag that avoids this
1648                            conversion for calling load_class_from_classloader from
1649                            Class.forName.  Currently we do a double conversion in
1650                            these cases.  */
1651
1652                         classnotfoundexception_to_noclassdeffounderror();
1653                 }
1654
1655                 RT_TIMING_GET_TIME(time_cache);
1656
1657                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1658                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1659                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1660
1661                 /* SUN compatible -verbose:class output */
1662
1663                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1664                         printf("[Loaded ");
1665                         utf_display_printable_ascii_classname(name);
1666                         printf("]\n");
1667                 }
1668
1669 #if defined(ENABLE_JVMTI)
1670                 /* fire Class Load JVMTI event */
1671                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1672 #endif
1673
1674
1675                 return c;
1676         } 
1677
1678         c = load_class_bootstrap(name);
1679
1680         return c;
1681 }
1682
1683
1684 /* load_class_bootstrap ********************************************************
1685         
1686    Load the class with the given name using the bootstrap class loader.
1687
1688    IN:
1689        name.............the classname
1690
1691    RETURN VALUE:
1692        loaded classinfo, or
1693            NULL if an exception has been thrown
1694
1695    SYNCHRONIZATION:
1696        load_class_bootstrap is synchronized. It can be treated as an
1697            atomic operation.
1698
1699 *******************************************************************************/
1700
1701 classinfo *load_class_bootstrap(utf *name)
1702 {
1703         classbuffer *cb;
1704         classinfo   *c;
1705         classinfo   *r;
1706 #if defined(ENABLE_RT_TIMING)
1707         struct timespec time_start, time_lookup, time_array, time_suck, 
1708                                         time_load, time_cache;
1709 #endif
1710
1711         RT_TIMING_GET_TIME(time_start);
1712
1713         /* for debugging */
1714
1715         assert(name);
1716
1717         /* lookup if this class has already been loaded */
1718
1719         if ((r = classcache_lookup(NULL, name))) {
1720
1721                 RT_TIMING_GET_TIME(time_lookup);
1722                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1723                 
1724                 return r;
1725         }
1726
1727         RT_TIMING_GET_TIME(time_lookup);
1728         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1729                 
1730         /* create the classinfo */
1731
1732         c = class_create_classinfo(name);
1733
1734         /* handle array classes */
1735
1736         if (name->text[0] == '[') {
1737                 c = load_newly_created_array(c, NULL);
1738                 if (c == NULL)
1739                         return NULL;
1740                 assert(c->state & CLASS_LOADED);
1741
1742                 RT_TIMING_GET_TIME(time_array);
1743                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1744                 
1745                 return c;
1746         }
1747
1748 #if defined(ENABLE_STATISTICS)
1749         /* measure time */
1750
1751         if (opt_getcompilingtime)
1752                 compilingtime_stop();
1753
1754         if (opt_getloadingtime)
1755                 loadingtime_start();
1756 #endif
1757
1758         /* load classdata, throw exception on error */
1759
1760         if ((cb = suck_start(c)) == NULL) {
1761                 /* this normally means, the classpath was not set properly */
1762
1763                 if (name == utf_java_lang_Object)
1764                         throw_cacao_exception_exit(string_java_lang_NoClassDefFoundError,
1765                                                                            "java/lang/Object");
1766
1767                 *exceptionptr = new_noclassdeffounderror(name);
1768
1769                 return NULL;
1770         }
1771
1772         RT_TIMING_GET_TIME(time_suck);
1773         
1774         /* load the class from the buffer */
1775
1776         r = load_class_from_classbuffer(cb);
1777
1778         RT_TIMING_GET_TIME(time_load);
1779         
1780         if (!r) {
1781                 /* the class could not be loaded, free the classinfo struct */
1782
1783                 class_free(c);
1784
1785         } else {
1786                 /* Store this class in the loaded class cache this step also
1787                 checks the loading constraints. If the class has been loaded
1788                 before, the earlier loaded class is returned. */
1789
1790                 classinfo *res = classcache_store(NULL, c, true);
1791
1792                 if (!res) {
1793                         /* exception */
1794                         class_free(c);
1795                 }
1796
1797                 r = res;
1798         }
1799
1800         RT_TIMING_GET_TIME(time_cache);
1801         
1802         /* SUN compatible -verbose:class output */
1803
1804         if (opt_verboseclass && r) {
1805                 printf("[Loaded ");
1806                 utf_display_printable_ascii_classname(name);
1807                 printf(" from %s]\n", cb->path);
1808         }
1809
1810         /* free memory */
1811
1812         suck_stop(cb);
1813
1814 #if defined(ENABLE_STATISTICS)
1815         /* measure time */
1816
1817         if (opt_getloadingtime)
1818                 loadingtime_stop();
1819
1820         if (opt_getcompilingtime)
1821                 compilingtime_start();
1822 #endif
1823
1824         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1825         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1826         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1827         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1828
1829         return r;
1830 }
1831
1832
1833 /* load_class_from_classbuffer *************************************************
1834         
1835    Loads everything interesting about a class from the class file. The
1836    'classinfo' structure must have been allocated previously.
1837
1838    The super class and the interfaces implemented by this class need
1839    not be loaded. The link is set later by the function 'class_link'.
1840
1841    The loaded class is removed from the list 'unloadedclasses' and
1842    added to the list 'unlinkedclasses'.
1843         
1844    SYNCHRONIZATION:
1845        This function is NOT synchronized!
1846    
1847 *******************************************************************************/
1848
1849 classinfo *load_class_from_classbuffer(classbuffer *cb)
1850 {
1851         classinfo *c;
1852         utf *name;
1853         utf *supername;
1854         u4 i,j;
1855         u4 ma, mi;
1856         s4 dumpsize;
1857         descriptor_pool *descpool;
1858 #if defined(ENABLE_STATISTICS)
1859         u4 classrefsize;
1860         u4 descsize;
1861 #endif
1862 #if defined(ENABLE_RT_TIMING)
1863         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1864                                         time_setup, time_fields, time_methods, time_classrefs,
1865                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1866                                         time_parsecpool, time_verify, time_attrs;
1867 #endif
1868
1869         RT_TIMING_GET_TIME(time_start);
1870
1871         /* get the classbuffer's class */
1872
1873         c = cb->class;
1874
1875         /* the class is already loaded */
1876
1877         if (c->state & CLASS_LOADED)
1878                 return c;
1879
1880 #if defined(ENABLE_STATISTICS)
1881         if (opt_stat)
1882                 count_class_loads++;
1883 #endif
1884
1885 #if !defined(NDEBUG)
1886         /* output for debugging purposes */
1887
1888         if (loadverbose)
1889                 log_message_class("Loading class: ", c);
1890 #endif
1891
1892         /* mark start of dump memory area */
1893
1894         dumpsize = dump_size();
1895
1896         /* class is currently loading */
1897
1898         c->state |= CLASS_LOADING;
1899
1900         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1901                 goto return_exception;
1902
1903         /* check signature */
1904
1905         if (suck_u4(cb) != MAGIC) {
1906                 exceptions_throw_classformaterror(c, "Bad magic number");
1907
1908                 goto return_exception;
1909         }
1910
1911         /* check version */
1912
1913         mi = suck_u2(cb);
1914         ma = suck_u2(cb);
1915
1916         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1917                 *exceptionptr =
1918                         new_unsupportedclassversionerror(c,
1919                                                                                          "Unsupported major.minor version %d.%d",
1920                                                                                          ma, mi);
1921
1922                 goto return_exception;
1923         }
1924         RT_TIMING_GET_TIME(time_checks);
1925
1926         /* create a new descriptor pool */
1927
1928         descpool = descriptor_pool_new(c);
1929
1930         RT_TIMING_GET_TIME(time_ndpool);
1931
1932         /* load the constant pool */
1933
1934         if (!load_constantpool(cb, descpool))
1935                 goto return_exception;
1936
1937         RT_TIMING_GET_TIME(time_cpool);
1938
1939         /* ACC flags */
1940
1941         if (!suck_check_classbuffer_size(cb, 2))
1942                 goto return_exception;
1943
1944         c->flags = suck_u2(cb);
1945
1946         /* check ACC flags consistency */
1947
1948         if (c->flags & ACC_INTERFACE) {
1949                 if (!(c->flags & ACC_ABSTRACT)) {
1950                         /* We work around this because interfaces in JDK 1.1 are
1951                          * not declared abstract. */
1952
1953                         c->flags |= ACC_ABSTRACT;
1954                 }
1955
1956                 if (c->flags & ACC_FINAL) {
1957                         exceptions_throw_classformaterror(c,
1958                                                                                           "Illegal class modifiers: 0x%X",
1959                                                                                           c->flags);
1960                         goto return_exception;
1961                 }
1962
1963                 if (c->flags & ACC_SUPER) {
1964                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1965                 }
1966         }
1967
1968         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1969                 exceptions_throw_classformaterror(c,
1970                                                                                   "Illegal class modifiers: 0x%X",
1971                                                                                   c->flags);
1972                 goto return_exception;
1973         }
1974
1975         if (!suck_check_classbuffer_size(cb, 2 + 2))
1976                 goto return_exception;
1977
1978         /* this class */
1979
1980         i = suck_u2(cb);
1981         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1982                 goto return_exception;
1983
1984         if (c->name == utf_not_named_yet) {
1985                 /* we finally have a name for this class */
1986                 c->name = name;
1987                 class_set_packagename(c);
1988
1989         } else if (name != c->name) {
1990                 char *msg;
1991                 s4    msglen;
1992
1993                 msglen = utf_bytes(c->name) + strlen(" (wrong name: ") +
1994                         utf_bytes(name) + strlen(")") + strlen("0");
1995
1996                 msg = MNEW(char, msglen);
1997
1998                 utf_copy_classname(msg, c->name);
1999                 strcat(msg, " (wrong name: ");
2000                 utf_cat_classname(msg, name);
2001                 strcat(msg, ")");
2002
2003                 *exceptionptr =
2004                         new_exception_message(string_java_lang_NoClassDefFoundError, msg);
2005
2006                 MFREE(msg, char, msglen);
2007
2008                 goto return_exception;
2009         }
2010
2011         /* retrieve superclass */
2012
2013         c->super.any = NULL;
2014         if ((i = suck_u2(cb))) {
2015                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2016                         goto return_exception;
2017
2018                 /* java.lang.Object may not have a super class. */
2019
2020                 if (c->name == utf_java_lang_Object) {
2021                         *exceptionptr =
2022                                 new_exception_message(string_java_lang_ClassFormatError,
2023                                                                           "java.lang.Object with superclass");
2024
2025                         goto return_exception;
2026                 }
2027
2028                 /* Interfaces must have java.lang.Object as super class. */
2029
2030                 if ((c->flags & ACC_INTERFACE) &&
2031                         supername != utf_java_lang_Object) {
2032                         *exceptionptr =
2033                                 new_exception_message(string_java_lang_ClassFormatError,
2034                                                                           "Interfaces must have java.lang.Object as superclass");
2035
2036                         goto return_exception;
2037                 }
2038
2039         } else {
2040                 supername = NULL;
2041
2042                 /* This is only allowed for java.lang.Object. */
2043
2044                 if (c->name != utf_java_lang_Object) {
2045                         exceptions_throw_classformaterror(c, "Bad superclass index");
2046                         goto return_exception;
2047                 }
2048         }
2049
2050         /* retrieve interfaces */
2051
2052         if (!suck_check_classbuffer_size(cb, 2))
2053                 goto return_exception;
2054
2055         c->interfacescount = suck_u2(cb);
2056
2057         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2058                 goto return_exception;
2059
2060         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2061         for (i = 0; i < c->interfacescount; i++) {
2062                 /* the classrefs are created later */
2063                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2064                         goto return_exception;
2065         }
2066
2067         RT_TIMING_GET_TIME(time_setup);
2068
2069         /* load fields */
2070         if (!suck_check_classbuffer_size(cb, 2))
2071                 goto return_exception;
2072
2073         c->fieldscount = suck_u2(cb);
2074         c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2075 /*      c->fields = MNEW(fieldinfo, c->fieldscount); */
2076         for (i = 0; i < c->fieldscount; i++) {
2077                 if (!load_field(cb, &(c->fields[i]),descpool))
2078                         goto return_exception;
2079         }
2080
2081         RT_TIMING_GET_TIME(time_fields);
2082
2083         /* load methods */
2084         if (!suck_check_classbuffer_size(cb, 2))
2085                 goto return_exception;
2086
2087         c->methodscount = suck_u2(cb);
2088         c->methods = MNEW(methodinfo, c->methodscount);
2089
2090         MZERO(c->methods, methodinfo, c->methodscount);
2091         
2092         for (i = 0; i < c->methodscount; i++) {
2093                 if (!load_method(cb, &(c->methods[i]),descpool))
2094                         goto return_exception;
2095         }
2096
2097         RT_TIMING_GET_TIME(time_methods);
2098
2099         /* create the class reference table */
2100
2101         c->classrefs =
2102                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2103
2104         RT_TIMING_GET_TIME(time_classrefs);
2105
2106         /* allocate space for the parsed descriptors */
2107
2108         descriptor_pool_alloc_parsed_descriptors(descpool);
2109         c->parseddescs =
2110                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2111
2112 #if defined(ENABLE_STATISTICS)
2113         if (opt_stat) {
2114                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2115                 count_classref_len += classrefsize;
2116                 count_parsed_desc_len += descsize;
2117         }
2118 #endif
2119
2120         RT_TIMING_GET_TIME(time_descs);
2121
2122         /* put the classrefs in the constant pool */
2123         for (i = 0; i < c->cpcount; i++) {
2124                 if (c->cptags[i] == CONSTANT_Class) {
2125                         utf *name = (utf *) c->cpinfos[i];
2126                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2127                 }
2128         }
2129
2130         /* set the super class reference */
2131
2132         if (supername) {
2133                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2134                 if (!c->super.ref)
2135                         goto return_exception;
2136         }
2137
2138         /* set the super interfaces references */
2139
2140         for (i = 0; i < c->interfacescount; i++) {
2141                 c->interfaces[i].ref =
2142                         descriptor_pool_lookup_classref(descpool,
2143                                                                                         (utf *) c->interfaces[i].any);
2144                 if (!c->interfaces[i].ref)
2145                         goto return_exception;
2146         }
2147
2148         RT_TIMING_GET_TIME(time_setrefs);
2149
2150         /* parse field descriptors */
2151
2152         for (i = 0; i < c->fieldscount; i++) {
2153                 c->fields[i].parseddesc =
2154                         descriptor_pool_parse_field_descriptor(descpool,
2155                                                                                                    c->fields[i].descriptor);
2156                 if (!c->fields[i].parseddesc)
2157                         goto return_exception;
2158         }
2159
2160         RT_TIMING_GET_TIME(time_parsefds);
2161
2162         /* parse method descriptors */
2163
2164         for (i = 0; i < c->methodscount; i++) {
2165                 methodinfo *m = &c->methods[i];
2166                 m->parseddesc =
2167                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2168                                                                                                         m->flags, class_get_self_classref(m->class));
2169                 if (!m->parseddesc)
2170                         goto return_exception;
2171
2172                 for (j = 0; j < m->rawexceptiontablelength; j++) {
2173                         if (!m->rawexceptiontable[j].catchtype.any)
2174                                 continue;
2175                         if ((m->rawexceptiontable[j].catchtype.ref =
2176                                  descriptor_pool_lookup_classref(descpool,
2177                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2178                                 goto return_exception;
2179                 }
2180
2181                 for (j = 0; j < m->thrownexceptionscount; j++) {
2182                         if (!m->thrownexceptions[j].any)
2183                                 continue;
2184                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2185                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
2186                                 goto return_exception;
2187                 }
2188         }
2189
2190         RT_TIMING_GET_TIME(time_parsemds);
2191
2192         /* parse the loaded descriptors */
2193
2194         for (i = 0; i < c->cpcount; i++) {
2195                 constant_FMIref *fmi;
2196                 s4               index;
2197
2198                 switch (c->cptags[i]) {
2199                 case CONSTANT_Fieldref:
2200                         fmi = (constant_FMIref *) c->cpinfos[i];
2201                         fmi->parseddesc.fd =
2202                                 descriptor_pool_parse_field_descriptor(descpool,
2203                                                                                                            fmi->descriptor);
2204                         if (!fmi->parseddesc.fd)
2205                                 goto return_exception;
2206                         index = fmi->p.index;
2207                         fmi->p.classref =
2208                                 (constant_classref *) class_getconstant(c, index,
2209                                                                                                                 CONSTANT_Class);
2210                         if (!fmi->p.classref)
2211                                 goto return_exception;
2212                         break;
2213                 case CONSTANT_Methodref:
2214                 case CONSTANT_InterfaceMethodref:
2215                         fmi = (constant_FMIref *) c->cpinfos[i];
2216                         index = fmi->p.index;
2217                         fmi->p.classref =
2218                                 (constant_classref *) class_getconstant(c, index,
2219                                                                                                                 CONSTANT_Class);
2220                         if (!fmi->p.classref)
2221                                 goto return_exception;
2222                         fmi->parseddesc.md =
2223                                 descriptor_pool_parse_method_descriptor(descpool,
2224                                                                                                                 fmi->descriptor,
2225                                                                                                                 ACC_UNDEF,
2226                                                                                                                 fmi->p.classref);
2227                         if (!fmi->parseddesc.md)
2228                                 goto return_exception;
2229                         break;
2230                 }
2231         }
2232
2233         RT_TIMING_GET_TIME(time_parsecpool);
2234
2235 #ifdef ENABLE_VERIFIER
2236         /* Check if all fields and methods can be uniquely
2237          * identified by (name,descriptor). */
2238
2239         if (opt_verify) {
2240                 /* We use a hash table here to avoid making the
2241                  * average case quadratic in # of methods, fields.
2242                  */
2243                 static int shift = 0;
2244                 u2 *hashtab;
2245                 u2 *next; /* for chaining colliding hash entries */
2246                 size_t len;
2247                 size_t hashlen;
2248                 u2 index;
2249                 u2 old;
2250
2251                 /* Allocate hashtable */
2252                 len = c->methodscount;
2253                 if (len < c->fieldscount) len = c->fieldscount;
2254                 hashlen = 5 * len;
2255                 hashtab = MNEW(u2,(hashlen + len));
2256                 next = hashtab + hashlen;
2257
2258                 /* Determine bitshift (to get good hash values) */
2259                 if (!shift) {
2260                         len = sizeof(utf);
2261                         while (len) {
2262                                 len >>= 1;
2263                                 shift++;
2264                         }
2265                 }
2266
2267                 /* Check fields */
2268                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2269
2270                 for (i = 0; i < c->fieldscount; ++i) {
2271                         fieldinfo *fi = c->fields + i;
2272
2273                         /* It's ok if we lose bits here */
2274                         index = ((((size_t) fi->name) +
2275                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
2276
2277                         if ((old = hashtab[index])) {
2278                                 old--;
2279                                 next[i] = old;
2280                                 do {
2281                                         if (c->fields[old].name == fi->name &&
2282                                                 c->fields[old].descriptor == fi->descriptor) {
2283                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2284                                                 goto return_exception;
2285                                         }
2286                                 } while ((old = next[old]));
2287                         }
2288                         hashtab[index] = i + 1;
2289                 }
2290
2291                 /* Check methods */
2292                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2293
2294                 for (i = 0; i < c->methodscount; ++i) {
2295                         methodinfo *mi = c->methods + i;
2296
2297                         /* It's ok if we lose bits here */
2298                         index = ((((size_t) mi->name) +
2299                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
2300
2301                         /*{ JOWENN
2302                                 int dbg;
2303                                 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2304                                         printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2305                                 }
2306                         }*/
2307
2308                         if ((old = hashtab[index])) {
2309                                 old--;
2310                                 next[i] = old;
2311                                 do {
2312                                         if (c->methods[old].name == mi->name &&
2313                                                 c->methods[old].descriptor == mi->descriptor) {
2314                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2315                                                 goto return_exception;
2316                                         }
2317                                 } while ((old = next[old]));
2318                         }
2319                         hashtab[index] = i + 1;
2320                 }
2321
2322                 MFREE(hashtab, u2, (hashlen + len));
2323         }
2324 #endif /* ENABLE_VERIFIER */
2325
2326         RT_TIMING_GET_TIME(time_verify);
2327
2328 #if defined(ENABLE_STATISTICS)
2329         if (opt_stat) {
2330                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
2331                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
2332                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2333         }
2334 #endif
2335
2336         /* load attribute structures */
2337
2338         if (!suck_check_classbuffer_size(cb, 2))
2339                 goto return_exception;
2340
2341         if (!load_attributes(cb, suck_u2(cb)))
2342                 goto return_exception;
2343
2344         /* Pre Java 1.5 version don't check this. This implementation is like
2345            Java 1.5 do it: for class file version 45.3 we don't check it, older
2346            versions are checked.
2347          */
2348
2349         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2350                 /* check if all data has been read */
2351                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2352
2353                 if (classdata_left > 0) {
2354                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2355                         goto return_exception;
2356                 }
2357         }
2358
2359         RT_TIMING_GET_TIME(time_attrs);
2360
2361         /* release dump area */
2362
2363         dump_release(dumpsize);
2364
2365         /* revert loading state and class is loaded */
2366
2367         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2368
2369 #if defined(ENABLE_JVMTI)
2370         /* fire Class Prepare JVMTI event */
2371
2372         if (jvmti)
2373                 jvmti_ClassLoadPrepare(true, c);
2374 #endif
2375
2376 #if !defined(NDEBUG)
2377         if (loadverbose)
2378                 log_message_class("Loading done class: ", c);
2379 #endif
2380
2381         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
2382         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
2383         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
2384         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
2385         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
2386         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
2387         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2388         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
2389         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
2390         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
2391         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
2392         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2393         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
2394         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
2395         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
2396
2397         return c;
2398
2399 return_exception:
2400         /* release dump area */
2401
2402         dump_release(dumpsize);
2403
2404         /* an exception has been thrown */
2405
2406         return NULL;
2407 }
2408
2409
2410 /* load_newly_created_array ****************************************************
2411
2412    Load a newly created array class.
2413
2414         RETURN VALUE:
2415             c....................the array class C has been loaded
2416                 other classinfo......the array class was found in the class cache, 
2417                                      C has been freed
2418             NULL.................an exception has been thrown
2419
2420         Note:
2421                 This is an internal function. Do not use it unless you know exactly
2422                 what you are doing!
2423
2424                 Use one of the load_class_... functions for general array class loading.
2425
2426 *******************************************************************************/
2427
2428 classinfo *load_newly_created_array(classinfo *c, java_objectheader *loader)
2429 {
2430         classinfo         *comp = NULL;
2431         methodinfo        *clone;
2432         methoddesc        *clonedesc;
2433         constant_classref *classrefs;
2434         char              *text;
2435         s4                 namelen;
2436         utf               *u;
2437
2438         text = c->name->text;
2439         namelen = c->name->blength;
2440
2441         /* Check array class name */
2442
2443         if (namelen < 2 || text[0] != '[') {
2444                 *exceptionptr = new_noclassdeffounderror(c->name);
2445                 return NULL;
2446         }
2447
2448         /* Check the element type */
2449
2450         switch (text[1]) {
2451         case '[':
2452                 /* c is an array of arrays. We have to create the component class. */
2453
2454                 u = utf_new(text + 1, namelen - 1);
2455                 if (!(comp = load_class_from_classloader(u, loader)))
2456                         return NULL;
2457
2458                 assert(comp->state & CLASS_LOADED);
2459
2460                 if (opt_eager)
2461                         if (!link_class(c))
2462                                 return NULL;
2463
2464                 /* the array's flags are that of the component class */
2465                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2466                 c->classloader = comp->classloader;
2467                 break;
2468
2469         case 'L':
2470                 /* c is an array of objects. */
2471
2472                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2473                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
2474                         *exceptionptr = new_noclassdeffounderror(c->name);
2475                         return NULL;
2476                 }
2477
2478                 u = utf_new(text + 2, namelen - 3);
2479
2480                 if (!(comp = load_class_from_classloader(u, loader)))
2481                         return NULL;
2482
2483                 assert(comp->state & CLASS_LOADED);
2484
2485                 if (opt_eager)
2486                         if (!link_class(c))
2487                                 return NULL;
2488
2489                 /* the array's flags are that of the component class */
2490                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2491                 c->classloader = comp->classloader;
2492                 break;
2493
2494         default:
2495                 /* c is an array of a primitive type */
2496
2497                 /* check for cases like `[II' */
2498                 if (namelen > 2) {
2499                         *exceptionptr = new_noclassdeffounderror(c->name);
2500                         return NULL;
2501                 }
2502
2503                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2504                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2505                 c->classloader = NULL;
2506         }
2507
2508         assert(class_java_lang_Object);
2509         assert(class_java_lang_Cloneable);
2510         assert(class_java_io_Serializable);
2511
2512         /* setup the array class */
2513
2514         c->super.cls = class_java_lang_Object;
2515
2516     c->interfacescount = 2;
2517     c->interfaces = MNEW(classref_or_classinfo, 2);
2518
2519         if (opt_eager) {
2520                 classinfo *tc;
2521
2522                 tc = class_java_lang_Cloneable;
2523                 assert(tc->state & CLASS_LOADED);
2524                 list_add_first(&unlinkedclasses, tc);
2525                 c->interfaces[0].cls = tc;
2526
2527                 tc = class_java_io_Serializable;
2528                 assert(tc->state & CLASS_LOADED);
2529                 list_add_first(&unlinkedclasses, tc);
2530                 c->interfaces[1].cls = tc;
2531
2532         } else {
2533                 c->interfaces[0].cls = class_java_lang_Cloneable;
2534                 c->interfaces[1].cls = class_java_io_Serializable;
2535         }
2536
2537         c->methodscount = 1;
2538         c->methods = MNEW(methodinfo, c->methodscount);
2539         MZERO(c->methods, methodinfo, c->methodscount);
2540
2541         classrefs = MNEW(constant_classref, 2);
2542         CLASSREF_INIT(classrefs[0], c, c->name);
2543         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2544
2545         /* create descriptor for clone method */
2546         /* we need one paramslot which is reserved for the 'this' parameter */
2547         clonedesc = NEW(methoddesc);
2548         clonedesc->returntype.type = TYPE_ADR;
2549         clonedesc->returntype.classref = classrefs + 1;
2550         clonedesc->returntype.arraydim = 0;
2551         /* initialize params to "empty", add real params below in
2552            descriptor_params_from_paramtypes */
2553         clonedesc->paramcount = 0;
2554         clonedesc->paramslots = 0;
2555         clonedesc->paramtypes[0].classref = classrefs + 0;
2556         clonedesc->params = NULL;
2557
2558         /* create methodinfo */
2559
2560         clone = c->methods;
2561         MSET(clone, 0, methodinfo, 1);
2562
2563 #if defined(ENABLE_THREADS)
2564         lock_init_object_lock(&clone->header);
2565 #endif
2566
2567         /* ATTENTION: if you delete the ACC_NATIVE below, set
2568            clone->maxlocals=1 (interpreter related) */
2569
2570         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2571         clone->name       = utf_clone;
2572         clone->descriptor = utf_void__java_lang_Object;
2573         clone->parseddesc = clonedesc;
2574         clone->class      = c;
2575
2576         /* parse the descriptor to get the register allocation */
2577
2578         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2579                 return false;
2580
2581         clone->code =
2582                 codegen_createnativestub((functionptr) &builtin_clone_array, clone);
2583
2584         /* XXX: field: length? */
2585
2586         /* array classes are not loaded from class files */
2587
2588         c->state          |= CLASS_LOADED;
2589         c->parseddescs    = (u1 *) clonedesc;
2590         c->parseddescsize = sizeof(methodinfo);
2591         c->classrefs      = classrefs;
2592         c->classrefcount  = 1;
2593
2594         /* insert class into the loaded class cache */
2595         /* XXX free classinfo if NULL returned? */
2596
2597         return classcache_store(loader, c, true);
2598 }
2599
2600
2601 /* loader_close ****************************************************************
2602
2603    Frees all resources.
2604         
2605 *******************************************************************************/
2606
2607 void loader_close(void)
2608 {
2609         /* empty */
2610 }
2611
2612
2613 /*
2614  * These are local overrides for various environment variables in Emacs.
2615  * Please do not remove this and leave it at the end of the file, where
2616  * Emacs will automagically detect them.
2617  * ---------------------------------------------------------------------
2618  * Local variables:
2619  * mode: c
2620  * indent-tabs-mode: t
2621  * c-basic-offset: 4
2622  * tab-width: 4
2623  * End:
2624  * vim:noexpandtab:sw=4:ts=4:
2625  */