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