Merged revisions 7797-7917 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 7918 2007-05-20 20:42:18Z 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 #include "threads/lock-common.h"
41
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.h"
44
45 #include "vm/builtin.h"
46 #include "vm/exceptions.h"
47 #include "vm/global.h"
48 #include "vm/stringlocal.h"
49 #include "vm/vm.h"
50
51 #include "vm/jit_interface.h"
52
53 #if defined(ENABLE_JAVASE)
54 # include "vmcore/annotation.h"
55 # include "vmcore/stackmap.h"
56 #endif
57
58 #include "vmcore/classcache.h"
59 #include "vmcore/linker.h"
60 #include "vmcore/loader.h"
61 #include "vmcore/options.h"
62 #include "vmcore/rt-timing.h"
63
64 #if defined(ENABLE_STATISTICS)
65 # include "vmcore/statistics.h"
66 #endif
67
68 #include "vmcore/suck.h"
69
70 #if defined(ENABLE_ZLIB)
71 # include "vmcore/zip.h"
72 #endif
73
74 #if defined(ENABLE_JVMTI)
75 # include "native/jvmti/cacaodbg.h"
76 #endif
77
78
79 /* global variables ***********************************************************/
80
81 hashtable *hashtable_classloader;
82
83
84 /* loader_init *****************************************************************
85
86    Initializes all lists and loads all classes required for the system
87    or the compiler.
88
89 *******************************************************************************/
90  
91 bool loader_init(void)
92 {
93 #if defined(ENABLE_THREADS)
94         list_classpath_entry *lce;
95
96         /* Initialize the monitor pointer for zip/jar file locking. */
97
98         for (lce = list_first(list_classpath_entries); lce != NULL;
99                  lce = list_next(list_classpath_entries, lce))
100                 if (lce->type == CLASSPATH_ARCHIVE)
101                         LOCK_INIT_OBJECT_LOCK(lce);
102 #endif
103
104         /* initialize classloader hashtable, 10 entries should be enough */
105
106         hashtable_classloader = NEW(hashtable);
107         hashtable_create(hashtable_classloader, 10);
108
109         /* load some important classes */
110
111         if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
112                 return false;
113
114         if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
115                 return false;
116
117 #if defined(ENABLE_JAVASE)
118         if (!(class_java_lang_Cloneable =
119                   load_class_bootstrap(utf_java_lang_Cloneable)))
120                 return false;
121
122         if (!(class_java_io_Serializable =
123                   load_class_bootstrap(utf_java_io_Serializable)))
124                 return false;
125 #endif
126
127         /* load classes for wrapping primitive types */
128
129 #if defined(ENABLE_JAVASE)
130         if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
131                 return false;
132 #endif
133
134         if (!(class_java_lang_Boolean =
135                   load_class_bootstrap(utf_java_lang_Boolean)))
136                 return false;
137
138         if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
139                 return false;
140
141         if (!(class_java_lang_Character =
142                   load_class_bootstrap(utf_java_lang_Character)))
143                 return false;
144
145         if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
146                 return false;
147
148         if (!(class_java_lang_Integer =
149                   load_class_bootstrap(utf_java_lang_Integer)))
150                 return false;
151
152         if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
153                 return false;
154
155         if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
156                 return false;
157
158         if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
159                 return false;
160
161
162         /* load some other important classes */
163
164         if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
165                 return false;
166
167 #if defined(ENABLE_JAVASE)
168         if (!(class_java_lang_ClassLoader =
169                   load_class_bootstrap(utf_java_lang_ClassLoader)))
170                 return false;
171
172         if (!(class_java_lang_SecurityManager =
173                   load_class_bootstrap(utf_java_lang_SecurityManager)))
174                 return false;
175 #endif
176
177         if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
178                 return false;
179
180         if (!(class_java_lang_Thread =
181                   load_class_bootstrap(utf_new_char("java/lang/Thread"))))
182                 return false;
183
184 #if defined(ENABLE_JAVASE)
185         if (!(class_java_lang_ThreadGroup =
186                   load_class_bootstrap(utf_java_lang_ThreadGroup)))
187                 return false;
188 #endif
189
190 #if defined(WITH_CLASSPATH_GNU)
191         if (!(class_java_lang_VMSystem =
192                   load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
193
194                 return false;
195
196         if (!(class_java_lang_VMThread =
197                   load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
198                 return false;
199 #endif
200
201
202         /* some classes which may be used more often */
203
204 #if defined(ENABLE_JAVASE)
205         if (!(class_java_lang_StackTraceElement =
206                   load_class_bootstrap(utf_java_lang_StackTraceElement)))
207                 return false;
208
209         if (!(class_java_lang_reflect_Constructor =
210                   load_class_bootstrap(utf_java_lang_reflect_Constructor)))
211                 return false;
212
213         if (!(class_java_lang_reflect_Field =
214                   load_class_bootstrap(utf_java_lang_reflect_Field)))
215                 return false;
216
217         if (!(class_java_lang_reflect_Method =
218                   load_class_bootstrap(utf_java_lang_reflect_Method)))
219                 return false;
220
221         if (!(class_java_security_PrivilegedAction =
222                   load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
223                 return false;
224
225         if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
226                 return false;
227
228         if (!(arrayclass_java_lang_Object =
229                   load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
230                 return false;
231 #endif
232
233         return true;
234 }
235
236
237 /* loader_hashtable_classloader_add ********************************************
238
239    Adds an entry to the classloader hashtable.
240
241    REMEMBER: Also use this to register native loaders!
242
243 *******************************************************************************/
244
245 classloader *loader_hashtable_classloader_add(java_objectheader *cl)
246 {
247         hashtable_classloader_entry *cle;
248         u4   key;
249         u4   slot;
250
251         if (cl == NULL)
252                 return NULL;
253
254         LOCK_MONITOR_ENTER(hashtable_classloader->header);
255
256         /* key for entry is the hashcode of the classloader;
257            aligned to 16-byte boundaries */
258
259 #if defined(ENABLE_GC_CACAO)
260         key  = heap_get_hashcode(cl) >> 4;
261 #else
262         key  = ((u4) (ptrint) cl) >> 4;
263 #endif
264
265         slot = key & (hashtable_classloader->size - 1);
266         cle  = hashtable_classloader->ptr[slot];
267
268         /* search hashchain for existing entry */
269         /* XXX no GC collection is allowed here, make this a critical section */
270
271         while (cle) {
272                 if (cle->object == cl)
273                         break;
274
275                 cle = cle->hashlink;
276         }
277
278         /* if no classloader was found, we create a new entry here */
279
280         if (cle == NULL) {
281                 cle = NEW(hashtable_classloader_entry);
282
283                 cle->object = cl;
284
285                 /* insert entry into hashtable */
286
287                 cle->hashlink = hashtable_classloader->ptr[slot];
288                 hashtable_classloader->ptr[slot] = cle;
289
290                 /* update number of entries */
291
292                 hashtable_classloader->entries++;
293         }
294
295
296         LOCK_MONITOR_EXIT(hashtable_classloader->header);
297
298         return cle;
299 }
300
301
302 /* loader_hashtable_classloader_find *******************************************
303
304    Find an entry in the classloader hashtable.
305
306 *******************************************************************************/
307
308 classloader *loader_hashtable_classloader_find(java_objectheader *cl)
309 {
310         hashtable_classloader_entry *cle;
311         u4   key;
312         u4   slot;
313
314         if (cl == NULL)
315                 return NULL;
316
317         /* key for entry is the hashcode of the classloader;
318            aligned to 16-byte boundaries */
319
320 #if defined(ENABLE_GC_CACAO)
321         key  = heap_get_hashcode(cl) >> 4;
322 #else
323         key  = ((u4) (ptrint) cl) >> 4;
324 #endif
325
326         slot = key & (hashtable_classloader->size - 1);
327         cle  = hashtable_classloader->ptr[slot];
328
329         /* search hashchain for existing entry */
330         /* XXX no GC collection is allowed here, make this a critical section */
331
332         while (cle) {
333                 if (cle->object == cl)
334                         break;
335
336                 cle = cle->hashlink;
337         }
338
339         return cle;
340 }
341
342
343 /* loader_load_all_classes *****************************************************
344
345    Loads all classes specified in the BOOTCLASSPATH.
346
347 *******************************************************************************/
348
349 void loader_load_all_classes(void)
350 {
351         list_classpath_entry    *lce;
352 #if defined(ENABLE_ZLIB)
353         hashtable               *ht;
354         s4                       slot;
355         hashtable_zipfile_entry *htzfe;
356         utf                     *u;
357 #endif
358
359         for (lce = list_first(list_classpath_entries); lce != NULL;
360                  lce = list_next(list_classpath_entries, lce)) {
361 #if defined(ENABLE_ZLIB)
362                 if (lce->type == CLASSPATH_ARCHIVE) {
363                         /* get the classes hashtable */
364
365                         ht = lce->htclasses;
366
367                         for (slot = 0; slot < ht->size; slot++) {
368                                 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
369
370                                 for (; htzfe; htzfe = htzfe->hashlink) {
371                                         u = htzfe->filename;
372
373                                         /* skip all entries in META-INF and .properties,
374                        .png files */
375
376                                         if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
377                                                 strstr(u->text, ".properties") ||
378                                                 strstr(u->text, ".png"))
379                                                 continue;
380
381                                         /* load class from bootstrap classloader */
382
383                                         if (!load_class_bootstrap(u)) {
384                                                 fprintf(stderr, "Error loading: ");
385                                                 utf_fprint_printable_ascii_classname(stderr, u);
386                                                 fprintf(stderr, "\n");
387
388 #if !defined(NDEBUG)
389                                                 /* print out exception and cause */
390
391                                                 exceptions_print_current_exception();
392 #endif
393                                         }
394                                 }
395                         }
396
397                 } else {
398 #endif
399 #if defined(ENABLE_ZLIB)
400                 }
401 #endif
402         }
403 }
404
405
406 /* loader_skip_attribute_body **************************************************
407
408    Skips an attribute the attribute_name_index has already been read.
409         
410    attribute_info {
411        u2 attribute_name_index;
412        u4 attribute_length;
413        u1 info[attribute_length];
414    }
415
416 *******************************************************************************/
417
418 bool loader_skip_attribute_body(classbuffer *cb)
419 {
420         u4 attribute_length;
421
422         if (!suck_check_classbuffer_size(cb, 4))
423                 return false;
424
425         attribute_length = suck_u4(cb);
426
427         if (!suck_check_classbuffer_size(cb, attribute_length))
428                 return false;
429
430         suck_skip_nbytes(cb, attribute_length);
431
432         return true;
433 }
434
435
436 /* load_constantpool ***********************************************************
437
438    Loads the constantpool of a class, the entries are transformed into
439    a simpler format by resolving references (a detailed overview of
440    the compact structures can be found in global.h).
441
442 *******************************************************************************/
443
444 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
445 {
446
447         /* The following structures are used to save information which cannot be 
448            processed during the first pass. After the complete constantpool has 
449            been traversed the references can be resolved. 
450            (only in specific order)                                                */
451         
452         /* CONSTANT_Class entries */
453         typedef struct forward_class {
454                 struct forward_class *next;
455                 u2 thisindex;
456                 u2 name_index;
457         } forward_class;
458
459         /* CONSTANT_String */
460         typedef struct forward_string {
461                 struct forward_string *next;
462                 u2 thisindex;
463                 u2 string_index;
464         } forward_string;
465
466         /* CONSTANT_NameAndType */
467         typedef struct forward_nameandtype {
468                 struct forward_nameandtype *next;
469                 u2 thisindex;
470                 u2 name_index;
471                 u2 sig_index;
472         } forward_nameandtype;
473
474         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
475         typedef struct forward_fieldmethint {
476                 struct forward_fieldmethint *next;
477                 u2 thisindex;
478                 u1 tag;
479                 u2 class_index;
480                 u2 nameandtype_index;
481         } forward_fieldmethint;
482
483
484         classinfo *c;
485         u4 idx;
486
487         forward_class *forward_classes = NULL;
488         forward_string *forward_strings = NULL;
489         forward_nameandtype *forward_nameandtypes = NULL;
490         forward_fieldmethint *forward_fieldmethints = NULL;
491
492         forward_class *nfc;
493         forward_string *nfs;
494         forward_nameandtype *nfn;
495         forward_fieldmethint *nff;
496
497         u4 cpcount;
498         u1 *cptags;
499         voidptr *cpinfos;
500
501         c = cb->class;
502
503         /* number of entries in the constant_pool table plus one */
504         if (!suck_check_classbuffer_size(cb, 2))
505                 return false;
506
507         cpcount = c->cpcount = suck_u2(cb);
508
509         /* allocate memory */
510         cptags  = c->cptags  = MNEW(u1, cpcount);
511         cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
512
513         if (cpcount < 1) {
514                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
515                 return false;
516         }
517         
518 #if defined(ENABLE_STATISTICS)
519         if (opt_stat)
520                 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
521 #endif
522         
523         /* initialize constantpool */
524         for (idx = 0; idx < cpcount; idx++) {
525                 cptags[idx] = CONSTANT_UNUSED;
526                 cpinfos[idx] = NULL;
527         }
528
529                         
530         /******* first pass *******/
531         /* entries which cannot be resolved now are written into 
532            temporary structures and traversed again later        */
533                    
534         idx = 1;
535         while (idx < cpcount) {
536                 u4 t;
537
538                 /* get constant type */
539                 if (!suck_check_classbuffer_size(cb, 1))
540                         return false;
541
542                 t = suck_u1(cb);
543
544                 switch (t) {
545                 case CONSTANT_Class:
546                         nfc = DNEW(forward_class);
547
548                         nfc->next = forward_classes;
549                         forward_classes = nfc;
550
551                         nfc->thisindex = idx;
552                         /* reference to CONSTANT_NameAndType */
553                         if (!suck_check_classbuffer_size(cb, 2))
554                                 return false;
555
556                         nfc->name_index = suck_u2(cb);
557
558                         idx++;
559                         break;
560                         
561                 case CONSTANT_String:
562                         nfs = DNEW(forward_string);
563                                 
564                         nfs->next = forward_strings;
565                         forward_strings = nfs;
566                                 
567                         nfs->thisindex = idx;
568
569                         /* reference to CONSTANT_Utf8_info with string characters */
570                         if (!suck_check_classbuffer_size(cb, 2))
571                                 return false;
572
573                         nfs->string_index = suck_u2(cb);
574                                 
575                         idx++;
576                         break;
577
578                 case CONSTANT_NameAndType:
579                         nfn = DNEW(forward_nameandtype);
580                                 
581                         nfn->next = forward_nameandtypes;
582                         forward_nameandtypes = nfn;
583                                 
584                         nfn->thisindex = idx;
585
586                         if (!suck_check_classbuffer_size(cb, 2 + 2))
587                                 return false;
588
589                         /* reference to CONSTANT_Utf8_info containing simple name */
590                         nfn->name_index = suck_u2(cb);
591
592                         /* reference to CONSTANT_Utf8_info containing field or method
593                            descriptor */
594                         nfn->sig_index = suck_u2(cb);
595                                 
596                         idx++;
597                         break;
598
599                 case CONSTANT_Fieldref:
600                 case CONSTANT_Methodref:
601                 case CONSTANT_InterfaceMethodref:
602                         nff = DNEW(forward_fieldmethint);
603                         
604                         nff->next = forward_fieldmethints;
605                         forward_fieldmethints = nff;
606
607                         nff->thisindex = idx;
608                         /* constant type */
609                         nff->tag = t;
610
611                         if (!suck_check_classbuffer_size(cb, 2 + 2))
612                                 return false;
613
614                         /* class or interface type that contains the declaration of the
615                            field or method */
616                         nff->class_index = suck_u2(cb);
617
618                         /* name and descriptor of the field or method */
619                         nff->nameandtype_index = suck_u2(cb);
620
621                         idx++;
622                         break;
623                                 
624                 case CONSTANT_Integer: {
625                         constant_integer *ci = NEW(constant_integer);
626
627 #if defined(ENABLE_STATISTICS)
628                         if (opt_stat)
629                                 count_const_pool_len += sizeof(constant_integer);
630 #endif
631
632                         if (!suck_check_classbuffer_size(cb, 4))
633                                 return false;
634
635                         ci->value = suck_s4(cb);
636                         cptags[idx] = CONSTANT_Integer;
637                         cpinfos[idx] = ci;
638
639                         idx++;
640                         break;
641                 }
642                                 
643                 case CONSTANT_Float: {
644                         constant_float *cf = NEW(constant_float);
645
646 #if defined(ENABLE_STATISTICS)
647                         if (opt_stat)
648                                 count_const_pool_len += sizeof(constant_float);
649 #endif
650
651                         if (!suck_check_classbuffer_size(cb, 4))
652                                 return false;
653
654                         cf->value = suck_float(cb);
655                         cptags[idx] = CONSTANT_Float;
656                         cpinfos[idx] = cf;
657
658                         idx++;
659                         break;
660                 }
661                                 
662                 case CONSTANT_Long: {
663                         constant_long *cl = NEW(constant_long);
664                                         
665 #if defined(ENABLE_STATISTICS)
666                         if (opt_stat)
667                                 count_const_pool_len += sizeof(constant_long);
668 #endif
669
670                         if (!suck_check_classbuffer_size(cb, 8))
671                                 return false;
672
673                         cl->value = suck_s8(cb);
674                         cptags[idx] = CONSTANT_Long;
675                         cpinfos[idx] = cl;
676                         idx += 2;
677                         if (idx > cpcount) {
678                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
679                                 return false;
680                         }
681                         break;
682                 }
683                         
684                 case CONSTANT_Double: {
685                         constant_double *cd = NEW(constant_double);
686                                 
687 #if defined(ENABLE_STATISTICS)
688                         if (opt_stat)
689                                 count_const_pool_len += sizeof(constant_double);
690 #endif
691
692                         if (!suck_check_classbuffer_size(cb, 8))
693                                 return false;
694
695                         cd->value = suck_double(cb);
696                         cptags[idx] = CONSTANT_Double;
697                         cpinfos[idx] = cd;
698                         idx += 2;
699                         if (idx > cpcount) {
700                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
701                                 return false;
702                         }
703                         break;
704                 }
705                                 
706                 case CONSTANT_Utf8: { 
707                         u4 length;
708
709                         /* number of bytes in the bytes array (not string-length) */
710                         if (!suck_check_classbuffer_size(cb, 2))
711                                 return false;
712
713                         length = suck_u2(cb);
714                         cptags[idx] = CONSTANT_Utf8;
715
716                         /* validate the string */
717                         if (!suck_check_classbuffer_size(cb, length))
718                                 return false;
719
720 #ifdef ENABLE_VERIFIER
721                         if (opt_verify &&
722                                 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
723                         {
724                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
725                                 return false;
726                         }
727 #endif /* ENABLE_VERIFIER */
728                         /* insert utf-string into the utf-symboltable */
729                         cpinfos[idx] = utf_new((char *) cb->pos, length);
730
731                         /* skip bytes of the string (buffer size check above) */
732                         suck_skip_nbytes(cb, length);
733                         idx++;
734                         break;
735                 }
736                                                                                 
737                 default:
738                         exceptions_throw_classformaterror(c, "Illegal constant pool type");
739                         return false;
740                 }  /* end switch */
741         } /* end while */
742
743
744         /* resolve entries in temporary structures */
745
746         while (forward_classes) {
747                 utf *name =
748                         class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
749                 if (!name)
750                         return false;
751
752 #ifdef ENABLE_VERIFIER
753                 if (opt_verify && !is_valid_name_utf(name)) {
754                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
755                         return false;
756                 }
757 #endif /* ENABLE_VERIFIER */
758
759                 /* add all class references to the descriptor_pool */
760
761                 if (!descriptor_pool_add_class(descpool, name))
762                         return false;
763
764                 cptags[forward_classes->thisindex] = CONSTANT_Class;
765
766                 if (opt_eager) {
767                         classinfo *tc;
768
769                         if (!(tc = load_class_bootstrap(name)))
770                                 return false;
771
772                         /* link the class later, because we cannot link the class currently
773                            loading */
774                         list_add_first(&unlinkedclasses, tc);
775                 }
776
777                 /* the classref is created later */
778                 cpinfos[forward_classes->thisindex] = name;
779
780                 nfc = forward_classes;
781                 forward_classes = forward_classes->next;
782         }
783
784         while (forward_strings) {
785                 utf *text =
786                         class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
787                 if (!text)
788                         return false;
789
790                 /* resolve utf-string */
791                 cptags[forward_strings->thisindex] = CONSTANT_String;
792                 cpinfos[forward_strings->thisindex] = text;
793                 
794                 nfs = forward_strings;
795                 forward_strings = forward_strings->next;
796         }
797
798         while (forward_nameandtypes) {
799                 constant_nameandtype *cn = NEW(constant_nameandtype);   
800
801 #if defined(ENABLE_STATISTICS)
802                 if (opt_stat)
803                         count_const_pool_len += sizeof(constant_nameandtype);
804 #endif
805
806                 /* resolve simple name and descriptor */
807                 cn->name = class_getconstant(c,
808                                                                          forward_nameandtypes->name_index,
809                                                                          CONSTANT_Utf8);
810                 if (!cn->name)
811                         return false;
812
813                 cn->descriptor = class_getconstant(c,
814                                                                                    forward_nameandtypes->sig_index,
815                                                                                    CONSTANT_Utf8);
816                 if (!cn->descriptor)
817                         return false;
818
819 #ifdef ENABLE_VERIFIER
820                 if (opt_verify) {
821                         /* check name */
822                         if (!is_valid_name_utf(cn->name)) {
823                                 exceptions_throw_classformaterror(c,
824                                                                                                   "Illegal Field name \"%s\"",
825                                                                                                   cn->name->text);
826
827                                 return false;
828                         }
829
830                         /* disallow referencing <clinit> among others */
831                         if (cn->name->text[0] == '<' && cn->name != utf_init) {
832                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
833                                 return false;
834                         }
835                 }
836 #endif /* ENABLE_VERIFIER */
837
838                 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
839                 cpinfos[forward_nameandtypes->thisindex] = cn;
840
841                 nfn = forward_nameandtypes;
842                 forward_nameandtypes = forward_nameandtypes->next;
843         }
844
845         while (forward_fieldmethints) {
846                 constant_nameandtype *nat;
847                 constant_FMIref *fmi = NEW(constant_FMIref);
848
849 #if defined(ENABLE_STATISTICS)
850                 if (opt_stat)
851                         count_const_pool_len += sizeof(constant_FMIref);
852 #endif
853                 /* resolve simple name and descriptor */
854
855                 nat = class_getconstant(c,
856                                                                 forward_fieldmethints->nameandtype_index,
857                                                                 CONSTANT_NameAndType);
858                 if (!nat)
859                         return false;
860
861                 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
862
863                 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
864                         return false;
865
866                 /* the classref is created later */
867
868                 fmi->p.index = forward_fieldmethints->class_index;
869                 fmi->name = nat->name;
870                 fmi->descriptor = nat->descriptor;
871
872                 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
873                 cpinfos[forward_fieldmethints->thisindex] = fmi;
874         
875                 nff = forward_fieldmethints;
876                 forward_fieldmethints = forward_fieldmethints->next;
877         }
878
879         /* everything was ok */
880
881         return true;
882 }
883
884
885 /* loader_load_attribute_signature *********************************************
886
887    Signature_attribute {
888        u2 attribute_name_index;
889            u4 atrribute_length;
890            u2 signature_index;
891    }
892
893 *******************************************************************************/
894
895 #if defined(ENABLE_JAVASE)
896 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
897 {
898         classinfo *c;
899         u4         attribute_length;
900         u2         signature_index;
901
902         /* get classinfo */
903
904         c = cb->class;
905
906         /* check remaining bytecode */
907
908         if (!suck_check_classbuffer_size(cb, 4 + 2))
909                 return false;
910
911         /* check attribute length */
912
913         attribute_length = suck_u4(cb);
914
915         if (attribute_length != 2) {
916                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
917                 return false;
918         }
919
920         if (*signature != NULL) {
921                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
922                 return false;
923         }
924
925         /* get signature */
926
927         signature_index = suck_u2(cb);
928
929         if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
930                 return false;
931
932         return true;
933 }
934 #endif /* defined(ENABLE_JAVASE) */
935
936
937 /* load_field ******************************************************************
938
939    Load everything about a class field from the class file and fill a
940    'fieldinfo' structure. For static fields, space in the data segment
941    is allocated.
942
943 *******************************************************************************/
944
945 #define field_load_NOVALUE  0xffffffff /* must be bigger than any u2 value! */
946
947 static bool load_field(classbuffer *cb, fieldinfo *f, descriptor_pool *descpool)
948 {
949         classinfo *c;
950         u4 attrnum, i;
951         u4 jtype;
952         u4 pindex = field_load_NOVALUE;     /* constantvalue_index */
953         utf *u;
954
955         c = cb->class;
956
957         if (!suck_check_classbuffer_size(cb, 2 + 2 + 2))
958                 return false;
959
960         f->flags = suck_u2(cb);
961
962         if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
963                 return false;
964
965         f->name = u;
966
967         if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
968                 return false;
969
970         f->descriptor = u;
971         f->parseddesc = NULL;
972
973         if (!descriptor_pool_add(descpool, u, NULL))
974                 return false;
975
976         /* descriptor_pool_add accepts method descriptors, so we have to check  */
977         /* against them here before the call of descriptor_to_basic_type below. */
978         if (u->text[0] == '(') {
979                 exceptions_throw_classformaterror(c, "Method descriptor used for field");
980                 return false;
981         }
982
983 #ifdef ENABLE_VERIFIER
984         if (opt_verify) {
985                 /* check name */
986                 if (!is_valid_name_utf(f->name) || f->name->text[0] == '<') {
987                         exceptions_throw_classformaterror(c,
988                                                                                           "Illegal Field name \"%s\"",
989                                                                                           f->name->text);
990                         return false;
991                 }
992
993                 /* check flag consistency */
994                 i = f->flags & (ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED);
995
996                 if ((i != 0 && i != ACC_PUBLIC && i != ACC_PRIVATE && i != ACC_PROTECTED) ||
997                         ((f->flags & (ACC_FINAL | ACC_VOLATILE)) == (ACC_FINAL | ACC_VOLATILE))) {
998                         exceptions_throw_classformaterror(c,
999                                                                                           "Illegal field modifiers: 0x%X",
1000                                                                                           f->flags);
1001                         return false;
1002                 }
1003
1004                 if (c->flags & ACC_INTERFACE) {
1005                         if (((f->flags & (ACC_STATIC | ACC_PUBLIC | ACC_FINAL))
1006                                 != (ACC_STATIC | ACC_PUBLIC | ACC_FINAL)) ||
1007                                 f->flags & ACC_TRANSIENT) {
1008                                 exceptions_throw_classformaterror(c,
1009                                                                                                   "Illegal field modifiers: 0x%X",
1010                                                                                                   f->flags);
1011                                 return false;
1012                         }
1013                 }
1014         }
1015 #endif /* ENABLE_VERIFIER */
1016
1017         f->type   = jtype = descriptor_to_basic_type(f->descriptor); /* data type */
1018         f->offset = 0;                             /* offset from start of object */
1019         f->class  = c;
1020
1021         switch (f->type) {
1022         case TYPE_INT:
1023                 f->value.i = 0;
1024                 break;
1025
1026         case TYPE_FLT:
1027                 f->value.f = 0.0;
1028                 break;
1029
1030         case TYPE_DBL:
1031                 f->value.d = 0.0;
1032                 break;
1033
1034         case TYPE_ADR:
1035                 f->value.a = NULL;
1036                 if (!(f->flags & ACC_STATIC))
1037                         c->flags |= ACC_CLASS_HAS_POINTERS;
1038                 break;
1039
1040         case TYPE_LNG:
1041 #if U8_AVAILABLE
1042                 f->value.l = 0;
1043 #else
1044                 f->value.l.low  = 0;
1045                 f->value.l.high = 0;
1046 #endif
1047                 break;
1048         }
1049
1050         /* read attributes */
1051         if (!suck_check_classbuffer_size(cb, 2))
1052                 return false;
1053
1054         attrnum = suck_u2(cb);
1055         for (i = 0; i < attrnum; i++) {
1056                 if (!suck_check_classbuffer_size(cb, 2))
1057                         return false;
1058
1059                 if (!(u = class_getconstant(c, suck_u2(cb), CONSTANT_Utf8)))
1060                         return false;
1061
1062                 if (u == utf_ConstantValue) {
1063                         if (!suck_check_classbuffer_size(cb, 4 + 2))
1064                                 return false;
1065
1066                         /* check attribute length */
1067
1068                         if (suck_u4(cb) != 2) {
1069                                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
1070                                 return false;
1071                         }
1072                         
1073                         /* constant value attribute */
1074
1075                         if (pindex != field_load_NOVALUE) {
1076                                 exceptions_throw_classformaterror(c, "Multiple ConstantValue attributes");
1077                                 return false;
1078                         }
1079                         
1080                         /* index of value in constantpool */
1081
1082                         pindex = suck_u2(cb);
1083                 
1084                         /* initialize field with value from constantpool */             
1085                         switch (jtype) {
1086                         case TYPE_INT: {
1087                                 constant_integer *ci; 
1088
1089                                 if (!(ci = class_getconstant(c, pindex, CONSTANT_Integer)))
1090                                         return false;
1091
1092                                 f->value.i = ci->value;
1093                         }
1094                         break;
1095                                         
1096                         case TYPE_LNG: {
1097                                 constant_long *cl; 
1098
1099                                 if (!(cl = class_getconstant(c, pindex, CONSTANT_Long)))
1100                                         return false;
1101
1102                                 f->value.l = cl->value;
1103                         }
1104                         break;
1105
1106                         case TYPE_FLT: {
1107                                 constant_float *cf;
1108
1109                                 if (!(cf = class_getconstant(c, pindex, CONSTANT_Float)))
1110                                         return false;
1111
1112                                 f->value.f = cf->value;
1113                         }
1114                         break;
1115                                                                                         
1116                         case TYPE_DBL: {
1117                                 constant_double *cd;
1118
1119                                 if (!(cd = class_getconstant(c, pindex, CONSTANT_Double)))
1120                                         return false;
1121
1122                                 f->value.d = cd->value;
1123                         }
1124                         break;
1125                                                 
1126                         case TYPE_ADR:
1127                                 if (!(u = class_getconstant(c, pindex, CONSTANT_String)))
1128                                         return false;
1129
1130                                 /* create javastring from compressed utf8-string */
1131                                 f->value.a = literalstring_new(u);
1132                                 break;
1133         
1134                         default: 
1135                                 log_text("Invalid Constant - Type");
1136                         }
1137                 }
1138 #if defined(ENABLE_JAVASE)
1139                 else if (u == utf_Signature) {
1140                         /* Signature */
1141
1142                         if (!loader_load_attribute_signature(cb, &(f->signature)))
1143                                 return false;
1144                 }
1145 #endif
1146                 else {
1147                         /* unknown attribute */
1148
1149                         if (!loader_skip_attribute_body(cb))
1150                                 return false;
1151                 }
1152         }
1153
1154         /* everything was ok */
1155
1156         return true;
1157 }
1158
1159
1160 /* loader_load_method **********************************************************
1161
1162    Loads a method from the class file and fills an existing
1163    'methodinfo' structure. For native methods, the function pointer
1164    field is set to the real function pointer, for JavaVM methods a
1165    pointer to the compiler is used preliminarily.
1166
1167    method_info {
1168        u2 access_flags;
1169            u2 name_index;
1170            u2 descriptor_index;
1171            u2 attributes_count;
1172            attribute_info attributes[attribute_count];
1173    }
1174
1175    attribute_info {
1176        u2 attribute_name_index;
1177            u4 attribute_length;
1178            u1 info[attribute_length];
1179    }
1180
1181    LineNumberTable_attribute {
1182        u2 attribute_name_index;
1183            u4 attribute_length;
1184            u2 line_number_table_length;
1185            {
1186                u2 start_pc;
1187                    u2 line_number;
1188            } line_number_table[line_number_table_length];
1189    }
1190
1191 *******************************************************************************/
1192
1193 static bool loader_load_method(classbuffer *cb, methodinfo *m,
1194                                                            descriptor_pool *descpool)
1195 {
1196         classinfo *c;
1197         int argcount;
1198         s4         i, j, k, l;
1199         utf       *u;
1200         u2         name_index;
1201         u2         descriptor_index;
1202         u2         attributes_count;
1203         u2         attribute_name_index;
1204         utf       *attribute_name;
1205         u2         code_attributes_count;
1206         u2         code_attribute_name_index;
1207         utf       *code_attribute_name;
1208
1209         /* get classinfo */
1210
1211         c = cb->class;
1212
1213 #if defined(ENABLE_THREADS)
1214         lock_init_object_lock(&m->header);
1215 #endif
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
2094         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2095                 goto return_exception;
2096
2097         if (c->name == utf_not_named_yet) {
2098                 /* we finally have a name for this class */
2099                 c->name = name;
2100                 class_set_packagename(c);
2101         }
2102         else if (name != c->name) {
2103                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
2104                 goto return_exception;
2105         }
2106
2107         /* retrieve superclass */
2108
2109         c->super.any = NULL;
2110
2111         if ((i = suck_u2(cb))) {
2112                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
2113                         goto return_exception;
2114
2115                 /* java.lang.Object may not have a super class. */
2116
2117                 if (c->name == utf_java_lang_Object) {
2118                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
2119                         goto return_exception;
2120                 }
2121
2122                 /* Interfaces must have java.lang.Object as super class. */
2123
2124                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
2125                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
2126                         goto return_exception;
2127                 }
2128
2129         } else {
2130                 supername = NULL;
2131
2132                 /* This is only allowed for java.lang.Object. */
2133
2134                 if (c->name != utf_java_lang_Object) {
2135                         exceptions_throw_classformaterror(c, "Bad superclass index");
2136                         goto return_exception;
2137                 }
2138         }
2139
2140         /* retrieve interfaces */
2141
2142         if (!suck_check_classbuffer_size(cb, 2))
2143                 goto return_exception;
2144
2145         c->interfacescount = suck_u2(cb);
2146
2147         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
2148                 goto return_exception;
2149
2150         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
2151         for (i = 0; i < c->interfacescount; i++) {
2152                 /* the classrefs are created later */
2153                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
2154                         goto return_exception;
2155         }
2156
2157         RT_TIMING_GET_TIME(time_setup);
2158
2159         /* load fields */
2160         if (!suck_check_classbuffer_size(cb, 2))
2161                 goto return_exception;
2162
2163         c->fieldscount = suck_u2(cb);
2164 #if defined(ENABLE_GC_CACAO)
2165         c->fields = MNEW(fieldinfo, c->fieldscount);
2166         MZERO(c->fields, fieldinfo, c->fieldscount);
2167 #else
2168         c->fields = GCNEW_UNCOLLECTABLE(fieldinfo, c->fieldscount);
2169 #endif
2170
2171         for (i = 0; i < c->fieldscount; i++) {
2172                 if (!load_field(cb, &(c->fields[i]),descpool))
2173                         goto return_exception;
2174         }
2175
2176         RT_TIMING_GET_TIME(time_fields);
2177
2178         /* load methods */
2179         if (!suck_check_classbuffer_size(cb, 2))
2180                 goto return_exception;
2181
2182         c->methodscount = suck_u2(cb);
2183         c->methods = MNEW(methodinfo, c->methodscount);
2184
2185         MZERO(c->methods, methodinfo, c->methodscount);
2186         
2187         for (i = 0; i < c->methodscount; i++) {
2188                 if (!loader_load_method(cb, &(c->methods[i]), descpool))
2189                         goto return_exception;
2190         }
2191
2192         RT_TIMING_GET_TIME(time_methods);
2193
2194         /* create the class reference table */
2195
2196         c->classrefs =
2197                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
2198
2199         RT_TIMING_GET_TIME(time_classrefs);
2200
2201         /* allocate space for the parsed descriptors */
2202
2203         descriptor_pool_alloc_parsed_descriptors(descpool);
2204         c->parseddescs =
2205                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
2206
2207 #if defined(ENABLE_STATISTICS)
2208         if (opt_stat) {
2209                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
2210                 count_classref_len += classrefsize;
2211                 count_parsed_desc_len += descsize;
2212         }
2213 #endif
2214
2215         RT_TIMING_GET_TIME(time_descs);
2216
2217         /* put the classrefs in the constant pool */
2218         for (i = 0; i < c->cpcount; i++) {
2219                 if (c->cptags[i] == CONSTANT_Class) {
2220                         utf *name = (utf *) c->cpinfos[i];
2221                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
2222                 }
2223         }
2224
2225         /* set the super class reference */
2226
2227         if (supername) {
2228                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
2229                 if (!c->super.ref)
2230                         goto return_exception;
2231         }
2232
2233         /* set the super interfaces references */
2234
2235         for (i = 0; i < c->interfacescount; i++) {
2236                 c->interfaces[i].ref =
2237                         descriptor_pool_lookup_classref(descpool,
2238                                                                                         (utf *) c->interfaces[i].any);
2239                 if (!c->interfaces[i].ref)
2240                         goto return_exception;
2241         }
2242
2243         RT_TIMING_GET_TIME(time_setrefs);
2244
2245         /* parse field descriptors */
2246
2247         for (i = 0; i < c->fieldscount; i++) {
2248                 c->fields[i].parseddesc =
2249                         descriptor_pool_parse_field_descriptor(descpool,
2250                                                                                                    c->fields[i].descriptor);
2251                 if (!c->fields[i].parseddesc)
2252                         goto return_exception;
2253         }
2254
2255         RT_TIMING_GET_TIME(time_parsefds);
2256
2257         /* parse method descriptors */
2258
2259         for (i = 0; i < c->methodscount; i++) {
2260                 methodinfo *m = &c->methods[i];
2261                 m->parseddesc =
2262                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
2263                                                                                                         m->flags, class_get_self_classref(m->class));
2264                 if (!m->parseddesc)
2265                         goto return_exception;
2266
2267                 for (j = 0; j < m->rawexceptiontablelength; j++) {
2268                         if (!m->rawexceptiontable[j].catchtype.any)
2269                                 continue;
2270                         if ((m->rawexceptiontable[j].catchtype.ref =
2271                                  descriptor_pool_lookup_classref(descpool,
2272                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
2273                                 goto return_exception;
2274                 }
2275
2276                 for (j = 0; j < m->thrownexceptionscount; j++) {
2277                         if (!m->thrownexceptions[j].any)
2278                                 continue;
2279                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
2280                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
2281                                 goto return_exception;
2282                 }
2283         }
2284
2285         RT_TIMING_GET_TIME(time_parsemds);
2286
2287         /* parse the loaded descriptors */
2288
2289         for (i = 0; i < c->cpcount; i++) {
2290                 constant_FMIref *fmi;
2291                 s4               index;
2292
2293                 switch (c->cptags[i]) {
2294                 case CONSTANT_Fieldref:
2295                         fmi = (constant_FMIref *) c->cpinfos[i];
2296                         fmi->parseddesc.fd =
2297                                 descriptor_pool_parse_field_descriptor(descpool,
2298                                                                                                            fmi->descriptor);
2299                         if (!fmi->parseddesc.fd)
2300                                 goto return_exception;
2301                         index = fmi->p.index;
2302                         fmi->p.classref =
2303                                 (constant_classref *) class_getconstant(c, index,
2304                                                                                                                 CONSTANT_Class);
2305                         if (!fmi->p.classref)
2306                                 goto return_exception;
2307                         break;
2308                 case CONSTANT_Methodref:
2309                 case CONSTANT_InterfaceMethodref:
2310                         fmi = (constant_FMIref *) c->cpinfos[i];
2311                         index = fmi->p.index;
2312                         fmi->p.classref =
2313                                 (constant_classref *) class_getconstant(c, index,
2314                                                                                                                 CONSTANT_Class);
2315                         if (!fmi->p.classref)
2316                                 goto return_exception;
2317                         fmi->parseddesc.md =
2318                                 descriptor_pool_parse_method_descriptor(descpool,
2319                                                                                                                 fmi->descriptor,
2320                                                                                                                 ACC_UNDEF,
2321                                                                                                                 fmi->p.classref);
2322                         if (!fmi->parseddesc.md)
2323                                 goto return_exception;
2324                         break;
2325                 }
2326         }
2327
2328         RT_TIMING_GET_TIME(time_parsecpool);
2329
2330 #ifdef ENABLE_VERIFIER
2331         /* Check if all fields and methods can be uniquely
2332          * identified by (name,descriptor). */
2333
2334         if (opt_verify) {
2335                 /* We use a hash table here to avoid making the
2336                  * average case quadratic in # of methods, fields.
2337                  */
2338                 static int shift = 0;
2339                 u2 *hashtab;
2340                 u2 *next; /* for chaining colliding hash entries */
2341                 size_t len;
2342                 size_t hashlen;
2343                 u2 index;
2344                 u2 old;
2345
2346                 /* Allocate hashtable */
2347                 len = c->methodscount;
2348                 if (len < c->fieldscount) len = c->fieldscount;
2349                 hashlen = 5 * len;
2350                 hashtab = MNEW(u2,(hashlen + len));
2351                 next = hashtab + hashlen;
2352
2353                 /* Determine bitshift (to get good hash values) */
2354                 if (!shift) {
2355                         len = sizeof(utf);
2356                         while (len) {
2357                                 len >>= 1;
2358                                 shift++;
2359                         }
2360                 }
2361
2362                 /* Check fields */
2363                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
2364
2365                 for (i = 0; i < c->fieldscount; ++i) {
2366                         fieldinfo *fi = c->fields + i;
2367
2368                         /* It's ok if we lose bits here */
2369                         index = ((((size_t) fi->name) +
2370                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
2371
2372                         if ((old = hashtab[index])) {
2373                                 old--;
2374                                 next[i] = old;
2375                                 do {
2376                                         if (c->fields[old].name == fi->name &&
2377                                                 c->fields[old].descriptor == fi->descriptor) {
2378                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
2379                                                 goto return_exception;
2380                                         }
2381                                 } while ((old = next[old]));
2382                         }
2383                         hashtab[index] = i + 1;
2384                 }
2385
2386                 /* Check methods */
2387                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
2388
2389                 for (i = 0; i < c->methodscount; ++i) {
2390                         methodinfo *mi = c->methods + i;
2391
2392                         /* It's ok if we lose bits here */
2393                         index = ((((size_t) mi->name) +
2394                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
2395
2396                         /*{ JOWENN
2397                                 int dbg;
2398                                 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
2399                                         printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
2400                                 }
2401                         }*/
2402
2403                         if ((old = hashtab[index])) {
2404                                 old--;
2405                                 next[i] = old;
2406                                 do {
2407                                         if (c->methods[old].name == mi->name &&
2408                                                 c->methods[old].descriptor == mi->descriptor) {
2409                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
2410                                                 goto return_exception;
2411                                         }
2412                                 } while ((old = next[old]));
2413                         }
2414                         hashtab[index] = i + 1;
2415                 }
2416
2417                 MFREE(hashtab, u2, (hashlen + len));
2418         }
2419 #endif /* ENABLE_VERIFIER */
2420
2421         RT_TIMING_GET_TIME(time_verify);
2422
2423 #if defined(ENABLE_STATISTICS)
2424         if (opt_stat) {
2425                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
2426                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
2427                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
2428         }
2429 #endif
2430
2431         /* load attribute structures */
2432
2433         if (!class_load_attributes(cb))
2434                 goto return_exception;
2435
2436         /* Pre Java 1.5 version don't check this. This implementation is like
2437            Java 1.5 do it: for class file version 45.3 we don't check it, older
2438            versions are checked.
2439          */
2440
2441         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
2442                 /* check if all data has been read */
2443                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
2444
2445                 if (classdata_left > 0) {
2446                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
2447                         goto return_exception;
2448                 }
2449         }
2450
2451         RT_TIMING_GET_TIME(time_attrs);
2452
2453         /* release dump area */
2454
2455         dump_release(dumpsize);
2456
2457         /* revert loading state and class is loaded */
2458
2459         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2460
2461 #if defined(ENABLE_JVMTI)
2462         /* fire Class Prepare JVMTI event */
2463
2464         if (jvmti)
2465                 jvmti_ClassLoadPrepare(true, c);
2466 #endif
2467
2468 #if !defined(NDEBUG)
2469         if (loadverbose)
2470                 log_message_class("Loading done class: ", c);
2471 #endif
2472
2473         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
2474         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
2475         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
2476         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
2477         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
2478         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
2479         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
2480         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
2481         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
2482         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
2483         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
2484         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
2485         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
2486         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
2487         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
2488
2489         return c;
2490
2491 return_exception:
2492         /* release dump area */
2493
2494         dump_release(dumpsize);
2495
2496         /* an exception has been thrown */
2497
2498         return NULL;
2499 }
2500
2501
2502 /* load_newly_created_array ****************************************************
2503
2504    Load a newly created array class.
2505
2506         RETURN VALUE:
2507             c....................the array class C has been loaded
2508                 other classinfo......the array class was found in the class cache, 
2509                                      C has been freed
2510             NULL.................an exception has been thrown
2511
2512         Note:
2513                 This is an internal function. Do not use it unless you know exactly
2514                 what you are doing!
2515
2516                 Use one of the load_class_... functions for general array class loading.
2517
2518 *******************************************************************************/
2519
2520 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
2521 {
2522         classinfo         *comp = NULL;
2523         methodinfo        *clone;
2524         methoddesc        *clonedesc;
2525         constant_classref *classrefs;
2526         char              *text;
2527         s4                 namelen;
2528         utf               *u;
2529
2530         text = c->name->text;
2531         namelen = c->name->blength;
2532
2533         /* Check array class name */
2534
2535         if ((namelen < 2) || (text[0] != '[')) {
2536                 exceptions_throw_noclassdeffounderror(c->name);
2537                 return NULL;
2538         }
2539
2540         /* Check the element type */
2541
2542         switch (text[1]) {
2543         case '[':
2544                 /* c is an array of arrays. We have to create the component class. */
2545
2546                 u = utf_new(text + 1, namelen - 1);
2547                 if (!(comp = load_class_from_classloader(u, loader)))
2548                         return NULL;
2549
2550                 assert(comp->state & CLASS_LOADED);
2551
2552                 if (opt_eager)
2553                         if (!link_class(c))
2554                                 return NULL;
2555
2556                 /* the array's flags are that of the component class */
2557                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2558                 c->classloader = comp->classloader;
2559                 break;
2560
2561         case 'L':
2562                 /* c is an array of objects. */
2563
2564                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2565                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2566                         exceptions_throw_noclassdeffounderror(c->name);
2567                         return NULL;
2568                 }
2569
2570                 u = utf_new(text + 2, namelen - 3);
2571
2572                 if (!(comp = load_class_from_classloader(u, loader)))
2573                         return NULL;
2574
2575                 assert(comp->state & CLASS_LOADED);
2576
2577                 if (opt_eager)
2578                         if (!link_class(c))
2579                                 return NULL;
2580
2581                 /* the array's flags are that of the component class */
2582                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2583                 c->classloader = comp->classloader;
2584                 break;
2585
2586         default:
2587                 /* c is an array of a primitive type */
2588
2589                 /* check for cases like `[II' */
2590                 if (namelen > 2) {
2591                         exceptions_throw_noclassdeffounderror(c->name);
2592                         return NULL;
2593                 }
2594
2595                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2596                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2597                 c->classloader = NULL;
2598         }
2599
2600         assert(class_java_lang_Object);
2601 #if defined(ENABLE_JAVASE)
2602         assert(class_java_lang_Cloneable);
2603         assert(class_java_io_Serializable);
2604 #endif
2605
2606         /* setup the array class */
2607
2608         c->super.cls = class_java_lang_Object;
2609
2610 #if defined(ENABLE_JAVASE)
2611         c->interfacescount = 2;
2612     c->interfaces      = MNEW(classref_or_classinfo, 2);
2613
2614         if (opt_eager) {
2615                 classinfo *tc;
2616
2617                 tc = class_java_lang_Cloneable;
2618                 assert(tc->state & CLASS_LOADED);
2619                 list_add_first(&unlinkedclasses, tc);
2620                 c->interfaces[0].cls = tc;
2621
2622                 tc = class_java_io_Serializable;
2623                 assert(tc->state & CLASS_LOADED);
2624                 list_add_first(&unlinkedclasses, tc);
2625                 c->interfaces[1].cls = tc;
2626         }
2627         else {
2628                 c->interfaces[0].cls = class_java_lang_Cloneable;
2629                 c->interfaces[1].cls = class_java_io_Serializable;
2630         }
2631 #elif defined(ENABLE_JAVAME_CLDC1_1)
2632         c->interfacescount = 0;
2633         c->interfaces      = NULL;
2634 #else
2635 #error unknow Java configuration
2636 #endif
2637
2638         c->methodscount = 1;
2639         c->methods = MNEW(methodinfo, c->methodscount);
2640         MZERO(c->methods, methodinfo, c->methodscount);
2641
2642         classrefs = MNEW(constant_classref, 2);
2643         CLASSREF_INIT(classrefs[0], c, c->name);
2644         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2645
2646         /* create descriptor for clone method */
2647         /* we need one paramslot which is reserved for the 'this' parameter */
2648         clonedesc = NEW(methoddesc);
2649         clonedesc->returntype.type = TYPE_ADR;
2650         clonedesc->returntype.classref = classrefs + 1;
2651         clonedesc->returntype.arraydim = 0;
2652         /* initialize params to "empty", add real params below in
2653            descriptor_params_from_paramtypes */
2654         clonedesc->paramcount = 0;
2655         clonedesc->paramslots = 0;
2656         clonedesc->paramtypes[0].classref = classrefs + 0;
2657         clonedesc->params = NULL;
2658
2659         /* create methodinfo */
2660
2661         clone = c->methods;
2662         MSET(clone, 0, methodinfo, 1);
2663
2664 #if defined(ENABLE_THREADS)
2665         lock_init_object_lock(&clone->header);
2666 #endif
2667
2668         /* ATTENTION: if you delete the ACC_NATIVE below, set
2669            clone->maxlocals=1 (interpreter related) */
2670
2671         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2672         clone->name       = utf_clone;
2673         clone->descriptor = utf_void__java_lang_Object;
2674         clone->parseddesc = clonedesc;
2675         clone->class      = c;
2676
2677         /* parse the descriptor to get the register allocation */
2678
2679         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2680                 return false;
2681
2682         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2683
2684         /* XXX: field: length? */
2685
2686         /* array classes are not loaded from class files */
2687
2688         c->state          |= CLASS_LOADED;
2689         c->parseddescs    = (u1 *) clonedesc;
2690         c->parseddescsize = sizeof(methodinfo);
2691         c->classrefs      = classrefs;
2692         c->classrefcount  = 1;
2693
2694         /* insert class into the loaded class cache */
2695         /* XXX free classinfo if NULL returned? */
2696
2697         return classcache_store(loader, c, true);
2698 }
2699
2700
2701 /* loader_close ****************************************************************
2702
2703    Frees all resources.
2704         
2705 *******************************************************************************/
2706
2707 void loader_close(void)
2708 {
2709         /* empty */
2710 }
2711
2712
2713 /*
2714  * These are local overrides for various environment variables in Emacs.
2715  * Please do not remove this and leave it at the end of the file, where
2716  * Emacs will automagically detect them.
2717  * ---------------------------------------------------------------------
2718  * Local variables:
2719  * mode: c
2720  * indent-tabs-mode: t
2721  * c-basic-offset: 4
2722  * tab-width: 4
2723  * End:
2724  * vim:noexpandtab:sw=4:ts=4:
2725  */