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