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