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