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