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