* Merged with default branch at rev 16f3633aaa5a.
[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 */
26
27
28 #include "config.h"
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <assert.h>
33
34 #include "vm/types.h"
35
36 #include "mm/memory.h"
37
38 #include "native/llni.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/primitive.h"
49 #include "vm/stringlocal.h"
50 #include "vm/vm.h"
51
52 #include "vm/jit_interface.h"
53
54 #if defined(ENABLE_JAVASE)
55 # include "vmcore/annotation.h"
56 # include "vmcore/stackmap.h"
57 #endif
58
59 #include "vmcore/classcache.h"
60 #include "vmcore/field.h"
61 #include "vmcore/linker.h"
62 #include "vmcore/loader.h"
63 #include "vmcore/method.h"
64 #include "vmcore/options.h"
65 #include "vmcore/rt-timing.h"
66
67 #if defined(ENABLE_STATISTICS)
68 # include "vmcore/statistics.h"
69 #endif
70
71 #include "vmcore/suck.h"
72
73 #if defined(ENABLE_ZLIB)
74 # include "vmcore/zip.h"
75 #endif
76
77 #if defined(ENABLE_JVMTI)
78 # include "native/jvmti/cacaodbg.h"
79 #endif
80
81
82 /* global variables ***********************************************************/
83
84 static hashtable *hashtable_classloader;
85
86
87 /* loader_preinit **************************************************************
88
89    Initializes the classpath list and loads classes required for the
90    primitive table.
91
92 *******************************************************************************/
93  
94 void loader_preinit(void)
95 {
96 #if defined(ENABLE_THREADS)
97         list_classpath_entry *lce;
98
99         /* Initialize the monitor pointer for zip/jar file locking. */
100
101         for (lce = list_first(list_classpath_entries); lce != NULL;
102                  lce = list_next(list_classpath_entries, lce)) {
103                 if (lce->type == CLASSPATH_ARCHIVE)
104                         LOCK_INIT_OBJECT_LOCK(lce);
105         }
106 #endif
107
108         /* initialize classloader hashtable, 10 entries should be enough */
109
110         hashtable_classloader = NEW(hashtable);
111         hashtable_create(hashtable_classloader, 10);
112
113         /* Load the most basic class. */
114
115         if (!(class_java_lang_Object = load_class_bootstrap(utf_java_lang_Object)))
116                 vm_abort("loader_preinit: loading java/lang/Object failed");
117
118 #if defined(ENABLE_JAVASE)
119         if (!(class_java_lang_Cloneable =
120                   load_class_bootstrap(utf_java_lang_Cloneable)))
121                 vm_abort("loader_preinit: loading java/lang/Cloneable failed");
122
123         if (!(class_java_io_Serializable =
124                   load_class_bootstrap(utf_java_io_Serializable)))
125                 vm_abort("loader_preinit: loading java/io/Serializable failed");
126 #endif
127 }
128
129
130 /* loader_init *****************************************************************
131
132    Loads all classes required in the VM.
133
134 *******************************************************************************/
135  
136 void loader_init(void)
137 {
138         /* Load primitive-type wrapping classes. */
139
140 #if defined(ENABLE_JAVASE)
141         if (!(class_java_lang_Void = load_class_bootstrap(utf_java_lang_Void)))
142                 vm_abort("loader_init: loading failed");
143 #endif
144
145         if (!(class_java_lang_Boolean =
146                   load_class_bootstrap(utf_java_lang_Boolean)))
147                 vm_abort("loader_init: loading failed");
148
149         if (!(class_java_lang_Byte = load_class_bootstrap(utf_java_lang_Byte)))
150                 vm_abort("loader_init: loading failed");
151
152         if (!(class_java_lang_Character =
153                   load_class_bootstrap(utf_java_lang_Character)))
154                 vm_abort("loader_init: loading failed");
155
156         if (!(class_java_lang_Short = load_class_bootstrap(utf_java_lang_Short)))
157                 vm_abort("loader_init: loading failed");
158
159         if (!(class_java_lang_Integer =
160                   load_class_bootstrap(utf_java_lang_Integer)))
161                 vm_abort("loader_init: loading failed");
162
163         if (!(class_java_lang_Long = load_class_bootstrap(utf_java_lang_Long)))
164                 vm_abort("loader_init: loading failed");
165
166         if (!(class_java_lang_Float = load_class_bootstrap(utf_java_lang_Float)))
167                 vm_abort("loader_init: loading failed");
168
169         if (!(class_java_lang_Double = load_class_bootstrap(utf_java_lang_Double)))
170                 vm_abort("loader_init: loading failed");
171
172         /* Load important system classes. */
173
174         if (!(class_java_lang_Class = load_class_bootstrap(utf_java_lang_Class)))
175                 vm_abort("loader_init: loading failed");
176
177         if (!(class_java_lang_String = load_class_bootstrap(utf_java_lang_String)))
178                 vm_abort("loader_init: loading failed");
179
180 #if defined(ENABLE_JAVASE)
181         if (!(class_java_lang_ClassLoader =
182                   load_class_bootstrap(utf_java_lang_ClassLoader)))
183                 vm_abort("loader_init: loading failed");
184
185         if (!(class_java_lang_SecurityManager =
186                   load_class_bootstrap(utf_java_lang_SecurityManager)))
187                 vm_abort("loader_init: loading failed");
188 #endif
189
190         if (!(class_java_lang_System = load_class_bootstrap(utf_java_lang_System)))
191                 vm_abort("loader_init: loading failed");
192
193         if (!(class_java_lang_Thread =
194                   load_class_bootstrap(utf_new_char("java/lang/Thread"))))
195                 vm_abort("loader_init: loading failed");
196
197 #if defined(ENABLE_JAVASE)
198         if (!(class_java_lang_ThreadGroup =
199                   load_class_bootstrap(utf_java_lang_ThreadGroup)))
200                 vm_abort("loader_init: loading failed");
201 #endif
202
203 #if defined(WITH_CLASSPATH_GNU)
204         if (!(class_java_lang_VMSystem =
205                   load_class_bootstrap(utf_new_char("java/lang/VMSystem"))))
206                 vm_abort("loader_init: loading failed");
207
208         if (!(class_java_lang_VMThread =
209                   load_class_bootstrap(utf_new_char("java/lang/VMThread"))))
210                 vm_abort("loader_init: loading failed");
211 #endif
212
213
214         /* some classes which may be used more often */
215
216 #if defined(ENABLE_JAVASE)
217         if (!(class_java_lang_StackTraceElement =
218                   load_class_bootstrap(utf_java_lang_StackTraceElement)))
219                 vm_abort("loader_init: loading failed");
220
221         if (!(class_java_lang_reflect_Constructor =
222                   load_class_bootstrap(utf_java_lang_reflect_Constructor)))
223                 vm_abort("loader_init: loading failed");
224
225         if (!(class_java_lang_reflect_Field =
226                   load_class_bootstrap(utf_java_lang_reflect_Field)))
227                 vm_abort("loader_init: loading failed");
228
229         if (!(class_java_lang_reflect_Method =
230                   load_class_bootstrap(utf_java_lang_reflect_Method)))
231                 vm_abort("loader_init: loading failed");
232
233         if (!(class_java_security_PrivilegedAction =
234                   load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"))))
235                 vm_abort("loader_init: loading failed");
236
237         if (!(class_java_util_Vector = load_class_bootstrap(utf_java_util_Vector)))
238                 vm_abort("loader_init: loading failed");
239
240 # if defined(WITH_CLASSPATH_SUN)
241         if (!(class_sun_reflect_MagicAccessorImpl =
242                   load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"))))
243                 vm_abort("loader_init: loading failed");
244 # endif
245
246         if (!(arrayclass_java_lang_Object =
247                   load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"))))
248                 return false;
249
250 # if defined(ENABLE_ANNOTATIONS)
251         /* needed by annotation support */
252         if (!(class_sun_reflect_ConstantPool = 
253                   load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"))))
254                 vm_abort("loader_init: loading failed");
255
256 #  if defined(WITH_CLASSPATH_GNU)
257         /* needed by GNU Classpaths annotation support */
258         if (!(class_sun_reflect_annotation_AnnotationParser = 
259                   load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"))))
260                 vm_abort("loader_init: loading failed");
261 #  endif
262 # endif
263 #endif
264
265
266         return true;
267 }
268
269
270 /* loader_hashtable_classloader_add ********************************************
271
272    Adds an entry to the classloader hashtable.
273
274    REMEMBER: Also use this to register native loaders!
275
276 *******************************************************************************/
277
278 classloader *loader_hashtable_classloader_add(java_handle_t *cl)
279 {
280         hashtable_classloader_entry *cle;
281         u4   key;
282         u4   slot;
283
284         if (cl == NULL)
285                 return NULL;
286
287         LOCK_MONITOR_ENTER(hashtable_classloader->header);
288
289         LLNI_CRITICAL_START;
290
291         /* key for entry is the hashcode of the classloader;
292            aligned to 16-byte boundaries */
293
294 #if defined(ENABLE_GC_CACAO)
295         key  = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
296 #else
297         key  = ((u4) (ptrint) cl) >> 4;
298 #endif
299
300         slot = key & (hashtable_classloader->size - 1);
301         cle  = hashtable_classloader->ptr[slot];
302
303         /* search hashchain for existing entry */
304
305         while (cle) {
306                 if (cle->object == LLNI_DIRECT(cl))
307                         break;
308
309                 cle = cle->hashlink;
310         }
311
312         LLNI_CRITICAL_END;
313
314         /* if no classloader was found, we create a new entry here */
315
316         if (cle == NULL) {
317                 cle = NEW(hashtable_classloader_entry);
318
319 #if defined(ENABLE_GC_CACAO)
320                 /* register the classloader object with the GC */
321
322                 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
323 #endif
324
325                 LLNI_CRITICAL_START;
326
327                 cle->object = LLNI_DIRECT(cl);
328
329                 LLNI_CRITICAL_END;
330
331                 /* insert entry into hashtable */
332
333                 cle->hashlink = hashtable_classloader->ptr[slot];
334                 hashtable_classloader->ptr[slot] = cle;
335
336                 /* update number of entries */
337
338                 hashtable_classloader->entries++;
339         }
340
341
342         LOCK_MONITOR_EXIT(hashtable_classloader->header);
343
344         return cle;
345 }
346
347
348 /* loader_hashtable_classloader_find *******************************************
349
350    Find an entry in the classloader hashtable.
351
352 *******************************************************************************/
353
354 classloader *loader_hashtable_classloader_find(java_handle_t *cl)
355 {
356         hashtable_classloader_entry *cle;
357         u4   key;
358         u4   slot;
359
360         if (cl == NULL)
361                 return NULL;
362
363         LLNI_CRITICAL_START;
364
365         /* key for entry is the hashcode of the classloader;
366            aligned to 16-byte boundaries */
367
368 #if defined(ENABLE_GC_CACAO)
369         key  = heap_get_hashcode(LLNI_DIRECT(cl)) >> 4;
370 #else
371         key  = ((u4) (ptrint) cl) >> 4;
372 #endif
373
374         slot = key & (hashtable_classloader->size - 1);
375         cle  = hashtable_classloader->ptr[slot];
376
377         /* search hashchain for existing entry */
378
379         while (cle) {
380                 if (cle->object == LLNI_DIRECT(cl))
381                         break;
382
383                 cle = cle->hashlink;
384         }
385
386         LLNI_CRITICAL_END;
387
388         return cle;
389 }
390
391
392 /* loader_load_all_classes *****************************************************
393
394    Loads all classes specified in the BOOTCLASSPATH.
395
396 *******************************************************************************/
397
398 void loader_load_all_classes(void)
399 {
400         list_classpath_entry    *lce;
401 #if defined(ENABLE_ZLIB)
402         hashtable               *ht;
403         s4                       slot;
404         hashtable_zipfile_entry *htzfe;
405         utf                     *u;
406 #endif
407
408         for (lce = list_first(list_classpath_entries); lce != NULL;
409                  lce = list_next(list_classpath_entries, lce)) {
410 #if defined(ENABLE_ZLIB)
411                 if (lce->type == CLASSPATH_ARCHIVE) {
412                         /* get the classes hashtable */
413
414                         ht = lce->htclasses;
415
416                         for (slot = 0; slot < ht->size; slot++) {
417                                 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
418
419                                 for (; htzfe; htzfe = htzfe->hashlink) {
420                                         u = htzfe->filename;
421
422                                         /* skip all entries in META-INF and .properties,
423                        .png files */
424
425                                         if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
426                                                 strstr(u->text, ".properties") ||
427                                                 strstr(u->text, ".png"))
428                                                 continue;
429
430                                         /* load class from bootstrap classloader */
431
432                                         if (!load_class_bootstrap(u)) {
433                                                 fprintf(stderr, "Error loading: ");
434                                                 utf_fprint_printable_ascii_classname(stderr, u);
435                                                 fprintf(stderr, "\n");
436
437 #if !defined(NDEBUG)
438                                                 /* print out exception and cause */
439
440                                                 exceptions_print_current_exception();
441 #endif
442                                         }
443                                 }
444                         }
445
446                 } else {
447 #endif
448 #if defined(ENABLE_ZLIB)
449                 }
450 #endif
451         }
452 }
453
454
455 /* loader_skip_attribute_body **************************************************
456
457    Skips an attribute the attribute_name_index has already been read.
458         
459    attribute_info {
460        u2 attribute_name_index;
461        u4 attribute_length;
462        u1 info[attribute_length];
463    }
464
465 *******************************************************************************/
466
467 bool loader_skip_attribute_body(classbuffer *cb)
468 {
469         u4 attribute_length;
470
471         if (!suck_check_classbuffer_size(cb, 4))
472                 return false;
473
474         attribute_length = suck_u4(cb);
475
476         if (!suck_check_classbuffer_size(cb, attribute_length))
477                 return false;
478
479         suck_skip_nbytes(cb, attribute_length);
480
481         return true;
482 }
483
484
485 /* load_constantpool ***********************************************************
486
487    Loads the constantpool of a class, the entries are transformed into
488    a simpler format by resolving references (a detailed overview of
489    the compact structures can be found in global.h).
490
491 *******************************************************************************/
492
493 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
494 {
495
496         /* The following structures are used to save information which cannot be 
497            processed during the first pass. After the complete constantpool has 
498            been traversed the references can be resolved. 
499            (only in specific order)                                                */
500         
501         /* CONSTANT_Class entries */
502         typedef struct forward_class {
503                 struct forward_class *next;
504                 u2 thisindex;
505                 u2 name_index;
506         } forward_class;
507
508         /* CONSTANT_String */
509         typedef struct forward_string {
510                 struct forward_string *next;
511                 u2 thisindex;
512                 u2 string_index;
513         } forward_string;
514
515         /* CONSTANT_NameAndType */
516         typedef struct forward_nameandtype {
517                 struct forward_nameandtype *next;
518                 u2 thisindex;
519                 u2 name_index;
520                 u2 sig_index;
521         } forward_nameandtype;
522
523         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
524         typedef struct forward_fieldmethint {
525                 struct forward_fieldmethint *next;
526                 u2 thisindex;
527                 u1 tag;
528                 u2 class_index;
529                 u2 nameandtype_index;
530         } forward_fieldmethint;
531
532
533         classinfo *c;
534         u4 idx;
535
536         forward_class *forward_classes = NULL;
537         forward_string *forward_strings = NULL;
538         forward_nameandtype *forward_nameandtypes = NULL;
539         forward_fieldmethint *forward_fieldmethints = NULL;
540
541         forward_class *nfc;
542         forward_string *nfs;
543         forward_nameandtype *nfn;
544         forward_fieldmethint *nff;
545
546         u4 cpcount;
547         u1 *cptags;
548         voidptr *cpinfos;
549
550         c = cb->class;
551
552         /* number of entries in the constant_pool table plus one */
553         if (!suck_check_classbuffer_size(cb, 2))
554                 return false;
555
556         cpcount = c->cpcount = suck_u2(cb);
557
558         /* allocate memory */
559         cptags  = c->cptags  = MNEW(u1, cpcount);
560         cpinfos = c->cpinfos = MNEW(voidptr, cpcount);
561
562         if (cpcount < 1) {
563                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
564                 return false;
565         }
566         
567 #if defined(ENABLE_STATISTICS)
568         if (opt_stat)
569                 count_const_pool_len += (sizeof(u1) + sizeof(voidptr)) * cpcount;
570 #endif
571         
572         /* initialize constantpool */
573         for (idx = 0; idx < cpcount; idx++) {
574                 cptags[idx] = CONSTANT_UNUSED;
575                 cpinfos[idx] = NULL;
576         }
577
578                         
579         /******* first pass *******/
580         /* entries which cannot be resolved now are written into 
581            temporary structures and traversed again later        */
582                    
583         idx = 1;
584         while (idx < cpcount) {
585                 u4 t;
586
587                 /* get constant type */
588                 if (!suck_check_classbuffer_size(cb, 1))
589                         return false;
590
591                 t = suck_u1(cb);
592
593                 switch (t) {
594                 case CONSTANT_Class:
595                         nfc = DNEW(forward_class);
596
597                         nfc->next = forward_classes;
598                         forward_classes = nfc;
599
600                         nfc->thisindex = idx;
601                         /* reference to CONSTANT_NameAndType */
602                         if (!suck_check_classbuffer_size(cb, 2))
603                                 return false;
604
605                         nfc->name_index = suck_u2(cb);
606
607                         idx++;
608                         break;
609                         
610                 case CONSTANT_String:
611                         nfs = DNEW(forward_string);
612                                 
613                         nfs->next = forward_strings;
614                         forward_strings = nfs;
615                                 
616                         nfs->thisindex = idx;
617
618                         /* reference to CONSTANT_Utf8_info with string characters */
619                         if (!suck_check_classbuffer_size(cb, 2))
620                                 return false;
621
622                         nfs->string_index = suck_u2(cb);
623                                 
624                         idx++;
625                         break;
626
627                 case CONSTANT_NameAndType:
628                         nfn = DNEW(forward_nameandtype);
629                                 
630                         nfn->next = forward_nameandtypes;
631                         forward_nameandtypes = nfn;
632                                 
633                         nfn->thisindex = idx;
634
635                         if (!suck_check_classbuffer_size(cb, 2 + 2))
636                                 return false;
637
638                         /* reference to CONSTANT_Utf8_info containing simple name */
639                         nfn->name_index = suck_u2(cb);
640
641                         /* reference to CONSTANT_Utf8_info containing field or method
642                            descriptor */
643                         nfn->sig_index = suck_u2(cb);
644                                 
645                         idx++;
646                         break;
647
648                 case CONSTANT_Fieldref:
649                 case CONSTANT_Methodref:
650                 case CONSTANT_InterfaceMethodref:
651                         nff = DNEW(forward_fieldmethint);
652                         
653                         nff->next = forward_fieldmethints;
654                         forward_fieldmethints = nff;
655
656                         nff->thisindex = idx;
657                         /* constant type */
658                         nff->tag = t;
659
660                         if (!suck_check_classbuffer_size(cb, 2 + 2))
661                                 return false;
662
663                         /* class or interface type that contains the declaration of the
664                            field or method */
665                         nff->class_index = suck_u2(cb);
666
667                         /* name and descriptor of the field or method */
668                         nff->nameandtype_index = suck_u2(cb);
669
670                         idx++;
671                         break;
672                                 
673                 case CONSTANT_Integer: {
674                         constant_integer *ci = NEW(constant_integer);
675
676 #if defined(ENABLE_STATISTICS)
677                         if (opt_stat)
678                                 count_const_pool_len += sizeof(constant_integer);
679 #endif
680
681                         if (!suck_check_classbuffer_size(cb, 4))
682                                 return false;
683
684                         ci->value = suck_s4(cb);
685                         cptags[idx] = CONSTANT_Integer;
686                         cpinfos[idx] = ci;
687
688                         idx++;
689                         break;
690                 }
691                                 
692                 case CONSTANT_Float: {
693                         constant_float *cf = NEW(constant_float);
694
695 #if defined(ENABLE_STATISTICS)
696                         if (opt_stat)
697                                 count_const_pool_len += sizeof(constant_float);
698 #endif
699
700                         if (!suck_check_classbuffer_size(cb, 4))
701                                 return false;
702
703                         cf->value = suck_float(cb);
704                         cptags[idx] = CONSTANT_Float;
705                         cpinfos[idx] = cf;
706
707                         idx++;
708                         break;
709                 }
710                                 
711                 case CONSTANT_Long: {
712                         constant_long *cl = NEW(constant_long);
713                                         
714 #if defined(ENABLE_STATISTICS)
715                         if (opt_stat)
716                                 count_const_pool_len += sizeof(constant_long);
717 #endif
718
719                         if (!suck_check_classbuffer_size(cb, 8))
720                                 return false;
721
722                         cl->value = suck_s8(cb);
723                         cptags[idx] = CONSTANT_Long;
724                         cpinfos[idx] = cl;
725                         idx += 2;
726                         if (idx > cpcount) {
727                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
728                                 return false;
729                         }
730                         break;
731                 }
732                         
733                 case CONSTANT_Double: {
734                         constant_double *cd = NEW(constant_double);
735                                 
736 #if defined(ENABLE_STATISTICS)
737                         if (opt_stat)
738                                 count_const_pool_len += sizeof(constant_double);
739 #endif
740
741                         if (!suck_check_classbuffer_size(cb, 8))
742                                 return false;
743
744                         cd->value = suck_double(cb);
745                         cptags[idx] = CONSTANT_Double;
746                         cpinfos[idx] = cd;
747                         idx += 2;
748                         if (idx > cpcount) {
749                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
750                                 return false;
751                         }
752                         break;
753                 }
754                                 
755                 case CONSTANT_Utf8: { 
756                         u4 length;
757
758                         /* number of bytes in the bytes array (not string-length) */
759                         if (!suck_check_classbuffer_size(cb, 2))
760                                 return false;
761
762                         length = suck_u2(cb);
763                         cptags[idx] = CONSTANT_Utf8;
764
765                         /* validate the string */
766                         if (!suck_check_classbuffer_size(cb, length))
767                                 return false;
768
769 #ifdef ENABLE_VERIFIER
770                         if (opt_verify &&
771                                 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
772                         {
773                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
774                                 return false;
775                         }
776 #endif /* ENABLE_VERIFIER */
777                         /* insert utf-string into the utf-symboltable */
778                         cpinfos[idx] = utf_new((char *) cb->pos, length);
779
780                         /* skip bytes of the string (buffer size check above) */
781                         suck_skip_nbytes(cb, length);
782                         idx++;
783                         break;
784                 }
785                                                                                 
786                 default:
787                         exceptions_throw_classformaterror(c, "Illegal constant pool type");
788                         return false;
789                 }  /* end switch */
790         } /* end while */
791
792
793         /* resolve entries in temporary structures */
794
795         while (forward_classes) {
796                 utf *name =
797                         class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
798                 if (!name)
799                         return false;
800
801 #ifdef ENABLE_VERIFIER
802                 if (opt_verify && !is_valid_name_utf(name)) {
803                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
804                         return false;
805                 }
806 #endif /* ENABLE_VERIFIER */
807
808                 /* add all class references to the descriptor_pool */
809
810                 if (!descriptor_pool_add_class(descpool, name))
811                         return false;
812
813                 cptags[forward_classes->thisindex] = CONSTANT_Class;
814
815                 /* the classref is created later */
816                 cpinfos[forward_classes->thisindex] = name;
817
818                 nfc = forward_classes;
819                 forward_classes = forward_classes->next;
820         }
821
822         while (forward_strings) {
823                 utf *text =
824                         class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
825                 if (!text)
826                         return false;
827
828                 /* resolve utf-string */
829                 cptags[forward_strings->thisindex] = CONSTANT_String;
830                 cpinfos[forward_strings->thisindex] = text;
831                 
832                 nfs = forward_strings;
833                 forward_strings = forward_strings->next;
834         }
835
836         while (forward_nameandtypes) {
837                 constant_nameandtype *cn = NEW(constant_nameandtype);   
838
839 #if defined(ENABLE_STATISTICS)
840                 if (opt_stat)
841                         count_const_pool_len += sizeof(constant_nameandtype);
842 #endif
843
844                 /* resolve simple name and descriptor */
845                 cn->name = class_getconstant(c,
846                                                                          forward_nameandtypes->name_index,
847                                                                          CONSTANT_Utf8);
848                 if (!cn->name)
849                         return false;
850
851                 cn->descriptor = class_getconstant(c,
852                                                                                    forward_nameandtypes->sig_index,
853                                                                                    CONSTANT_Utf8);
854                 if (!cn->descriptor)
855                         return false;
856
857 #ifdef ENABLE_VERIFIER
858                 if (opt_verify) {
859                         /* check name */
860                         if (!is_valid_name_utf(cn->name)) {
861                                 exceptions_throw_classformaterror(c,
862                                                                                                   "Illegal Field name \"%s\"",
863                                                                                                   cn->name->text);
864
865                                 return false;
866                         }
867
868                         /* disallow referencing <clinit> among others */
869                         if (cn->name->text[0] == '<' && cn->name != utf_init) {
870                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
871                                 return false;
872                         }
873                 }
874 #endif /* ENABLE_VERIFIER */
875
876                 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
877                 cpinfos[forward_nameandtypes->thisindex] = cn;
878
879                 nfn = forward_nameandtypes;
880                 forward_nameandtypes = forward_nameandtypes->next;
881         }
882
883         while (forward_fieldmethints) {
884                 constant_nameandtype *nat;
885                 constant_FMIref *fmi = NEW(constant_FMIref);
886
887 #if defined(ENABLE_STATISTICS)
888                 if (opt_stat)
889                         count_const_pool_len += sizeof(constant_FMIref);
890 #endif
891                 /* resolve simple name and descriptor */
892
893                 nat = class_getconstant(c,
894                                                                 forward_fieldmethints->nameandtype_index,
895                                                                 CONSTANT_NameAndType);
896                 if (!nat)
897                         return false;
898
899                 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
900
901                 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
902                         return false;
903
904                 /* the classref is created later */
905
906                 fmi->p.index = forward_fieldmethints->class_index;
907                 fmi->name = nat->name;
908                 fmi->descriptor = nat->descriptor;
909
910                 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
911                 cpinfos[forward_fieldmethints->thisindex] = fmi;
912         
913                 nff = forward_fieldmethints;
914                 forward_fieldmethints = forward_fieldmethints->next;
915         }
916
917         /* everything was ok */
918
919         return true;
920 }
921
922
923 /* loader_load_attribute_signature *********************************************
924
925    Signature_attribute {
926        u2 attribute_name_index;
927            u4 atrribute_length;
928            u2 signature_index;
929    }
930
931 *******************************************************************************/
932
933 #if defined(ENABLE_JAVASE)
934 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
935 {
936         classinfo *c;
937         u4         attribute_length;
938         u2         signature_index;
939
940         /* get classinfo */
941
942         c = cb->class;
943
944         /* check remaining bytecode */
945
946         if (!suck_check_classbuffer_size(cb, 4 + 2))
947                 return false;
948
949         /* check attribute length */
950
951         attribute_length = suck_u4(cb);
952
953         if (attribute_length != 2) {
954                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
955                 return false;
956         }
957
958         if (*signature != NULL) {
959                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
960                 return false;
961         }
962
963         /* get signature */
964
965         signature_index = suck_u2(cb);
966
967         if (!(*signature = class_getconstant(c, signature_index, CONSTANT_Utf8)))
968                 return false;
969
970         return true;
971 }
972 #endif /* defined(ENABLE_JAVASE) */
973
974
975 /* load_class_from_sysloader ***************************************************
976
977    Load the class with the given name using the system class loader
978
979    IN:
980        name.............the classname
981
982    RETURN VALUE:
983        the loaded class, or
984            NULL if an exception has been thrown
985
986 *******************************************************************************/
987
988 classinfo *load_class_from_sysloader(utf *name)
989 {
990         methodinfo    *m;
991         java_handle_t *clo;
992         classloader   *cl;
993         classinfo     *c;
994
995         assert(class_java_lang_Object);
996         assert(class_java_lang_ClassLoader);
997         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
998         
999         m = class_resolveclassmethod(class_java_lang_ClassLoader,
1000                                                                  utf_getSystemClassLoader,
1001                                                                  utf_void__java_lang_ClassLoader,
1002                                                                  class_java_lang_Object,
1003                                                                  false);
1004
1005         if (!m)
1006                 return false;
1007
1008         clo = vm_call_method(m, NULL);
1009
1010         if (!clo)
1011                 return false;
1012
1013         cl = loader_hashtable_classloader_add(clo);
1014
1015         c = load_class_from_classloader(name, cl);
1016
1017         return c;
1018 }
1019
1020
1021 /* load_class_from_classloader *************************************************
1022
1023    Load the class with the given name using the given user-defined class loader.
1024
1025    IN:
1026        name.............the classname
1027            cl...............user-defined class loader
1028            
1029    RETURN VALUE:
1030        the loaded class, or
1031            NULL if an exception has been thrown
1032
1033 *******************************************************************************/
1034
1035 classinfo *load_class_from_classloader(utf *name, classloader *cl)
1036 {
1037         java_handle_t *o;
1038         classinfo     *c;
1039         classinfo     *tmpc;
1040         java_handle_t *string;
1041 #if defined(ENABLE_RT_TIMING)
1042         struct timespec time_start, time_lookup, time_prepare, time_java, 
1043                                         time_cache;
1044 #endif
1045
1046         RT_TIMING_GET_TIME(time_start);
1047
1048         assert(name);
1049
1050         /* lookup if this class has already been loaded */
1051
1052         c = classcache_lookup(cl, name);
1053
1054         RT_TIMING_GET_TIME(time_lookup);
1055         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1056
1057         if (c != NULL)
1058                 return c;
1059
1060         /* if other class loader than bootstrap, call it */
1061
1062         if (cl != NULL) {
1063                 methodinfo *lc;
1064                 char       *text;
1065                 s4          namelen;
1066
1067                 text = name->text;
1068                 namelen = name->blength;
1069
1070                 /* handle array classes */
1071                 if (text[0] == '[') {
1072                         classinfo *comp;
1073                         utf       *u;
1074
1075                         switch (text[1]) {
1076                         case 'L':
1077                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1078                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1079                                         exceptions_throw_classnotfoundexception(name);
1080                                         return false;
1081                                 }
1082
1083                                 u = utf_new(text + 2, namelen - 3);
1084
1085                                 if (!(comp = load_class_from_classloader(u, cl)))
1086                                         return false;
1087
1088                                 /* create the array class */
1089
1090                                 c = class_array_of(comp, false);
1091
1092                                 tmpc = classcache_store(cl, c, true);
1093
1094                                 if (tmpc == NULL) {
1095                                         /* exception, free the loaded class */
1096                                         c->state &= ~CLASS_LOADING;
1097                                         class_free(c);
1098                                 }
1099
1100                                 return tmpc;
1101
1102                         case '[':
1103                                 /* load the component class */
1104
1105                                 u = utf_new(text + 1, namelen - 1);
1106
1107                                 if (!(comp = load_class_from_classloader(u, cl)))
1108                                         return false;
1109
1110                                 /* create the array class */
1111
1112                                 c = class_array_of(comp, false);
1113
1114                                 tmpc = classcache_store(cl, c, true);
1115
1116                                 if (tmpc == NULL) {
1117                                         /* exception, free the loaded class */
1118                                         c->state &= ~CLASS_LOADING;
1119                                         class_free(c);
1120                                 }
1121
1122                                 return tmpc;
1123
1124                         default:
1125                                 /* primitive array classes are loaded by the bootstrap loader */
1126
1127                                 c = load_class_bootstrap(name);
1128
1129                                 return c;
1130                         }
1131                 }
1132                 
1133 #if defined(WITH_CLASSPATH_SUN)
1134                 /* OpenJDK uses this internal function because it's
1135                    synchronized. */
1136
1137                 lc = class_resolveclassmethod(cl->object->vftbl->class,
1138                                                                           utf_loadClassInternal,
1139                                                                           utf_java_lang_String__java_lang_Class,
1140                                                                           NULL,
1141                                                                           true);
1142 #else
1143                 lc = class_resolveclassmethod(cl->vftbl->class,
1144                                                                           utf_loadClass,
1145                                                                           utf_java_lang_String__java_lang_Class,
1146                                                                           NULL,
1147                                                                           true);
1148 #endif
1149
1150                 if (lc == NULL)
1151                         return false; /* exception */
1152
1153                 /* move return value into `o' and cast it afterwards to a classinfo* */
1154
1155                 string = javastring_new_slash_to_dot(name);
1156
1157                 RT_TIMING_GET_TIME(time_prepare);
1158
1159 #if defined(ENABLE_HANDLES)
1160                 o = vm_call_method(lc, (java_handle_t *) cl, string);
1161 #else
1162                 o = vm_call_method(lc, cl->object, string);
1163 #endif
1164
1165                 RT_TIMING_GET_TIME(time_java);
1166
1167                 c = LLNI_classinfo_unwrap(o);
1168
1169                 if (c != NULL) {
1170                         /* Store this class in the loaded class cache. If another
1171                            class with the same (initloader,name) pair has been
1172                            stored earlier it will be returned by classcache_store
1173                            In this case classcache_store may not free the class
1174                            because it has already been exposed to Java code which
1175                            may have kept references to that class. */
1176
1177                     tmpc = classcache_store(cl, c, false);
1178
1179                         if (tmpc == NULL) {
1180                                 /* exception, free the loaded class */
1181                                 c->state &= ~CLASS_LOADING;
1182                                 class_free(c);
1183                         }
1184
1185                         c = tmpc;
1186                 }
1187
1188                 RT_TIMING_GET_TIME(time_cache);
1189
1190                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1191                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1192                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1193
1194                 /* SUN compatible -verbose:class output */
1195
1196                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1197                         printf("[Loaded ");
1198                         utf_display_printable_ascii_classname(name);
1199                         printf("]\n");
1200                 }
1201
1202 #if defined(ENABLE_JVMTI)
1203                 /* fire Class Load JVMTI event */
1204                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1205 #endif
1206
1207
1208                 return c;
1209         } 
1210
1211         c = load_class_bootstrap(name);
1212
1213         return c;
1214 }
1215
1216
1217 /* load_class_bootstrap ********************************************************
1218         
1219    Load the class with the given name using the bootstrap class loader.
1220
1221    IN:
1222        name.............the classname
1223
1224    RETURN VALUE:
1225        loaded classinfo, or
1226            NULL if an exception has been thrown
1227
1228    SYNCHRONIZATION:
1229        load_class_bootstrap is synchronized. It can be treated as an
1230            atomic operation.
1231
1232 *******************************************************************************/
1233
1234 classinfo *load_class_bootstrap(utf *name)
1235 {
1236         classbuffer *cb;
1237         classinfo   *c;
1238         classinfo   *r;
1239 #if defined(ENABLE_RT_TIMING)
1240         struct timespec time_start, time_lookup, time_array, time_suck, 
1241                                         time_load, time_cache;
1242 #endif
1243
1244         RT_TIMING_GET_TIME(time_start);
1245
1246         /* for debugging */
1247
1248         assert(name);
1249
1250         /* lookup if this class has already been loaded */
1251
1252         r = classcache_lookup(NULL, name);
1253
1254         if (r != NULL) {
1255                 RT_TIMING_GET_TIME(time_lookup);
1256                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1257                 
1258                 return r;
1259         }
1260
1261         RT_TIMING_GET_TIME(time_lookup);
1262         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1263                 
1264         /* create the classinfo */
1265
1266         c = class_create_classinfo(name);
1267
1268         /* handle array classes */
1269
1270         if (name->text[0] == '[') {
1271                 c = load_newly_created_array(c, NULL);
1272
1273                 if (c == NULL)
1274                         return NULL;
1275
1276                 assert(c->state & CLASS_LOADED);
1277
1278                 RT_TIMING_GET_TIME(time_array);
1279                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1280                 
1281                 return c;
1282         }
1283
1284 #if defined(ENABLE_STATISTICS)
1285         /* measure time */
1286
1287         if (opt_getcompilingtime)
1288                 compilingtime_stop();
1289
1290         if (opt_getloadingtime)
1291                 loadingtime_start();
1292 #endif
1293
1294         /* load classdata, throw exception on error */
1295
1296         cb = suck_start(c);
1297
1298         if (cb == NULL) {
1299                 /* this normally means, the classpath was not set properly */
1300
1301                 if (name == utf_java_lang_Object)
1302                         vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1303
1304                 exceptions_throw_classnotfoundexception(name);
1305
1306                 return NULL;
1307         }
1308
1309         RT_TIMING_GET_TIME(time_suck);
1310         
1311         /* load the class from the buffer */
1312
1313         r = load_class_from_classbuffer(cb);
1314
1315         RT_TIMING_GET_TIME(time_load);
1316         
1317         if (!r) {
1318                 /* the class could not be loaded, free the classinfo struct */
1319
1320                 class_free(c);
1321
1322         } else {
1323                 /* Store this class in the loaded class cache this step also
1324                 checks the loading constraints. If the class has been loaded
1325                 before, the earlier loaded class is returned. */
1326
1327                 classinfo *res = classcache_store(NULL, c, true);
1328
1329                 if (!res) {
1330                         /* exception */
1331                         class_free(c);
1332                 }
1333
1334                 r = res;
1335         }
1336
1337         RT_TIMING_GET_TIME(time_cache);
1338         
1339         /* SUN compatible -verbose:class output */
1340
1341         if (opt_verboseclass && r) {
1342                 printf("[Loaded ");
1343                 utf_display_printable_ascii_classname(name);
1344                 printf(" from %s]\n", cb->path);
1345         }
1346
1347         /* free memory */
1348
1349         suck_stop(cb);
1350
1351 #if defined(ENABLE_STATISTICS)
1352         /* measure time */
1353
1354         if (opt_getloadingtime)
1355                 loadingtime_stop();
1356
1357         if (opt_getcompilingtime)
1358                 compilingtime_start();
1359 #endif
1360
1361         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1362         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1363         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1364         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1365
1366         return r;
1367 }
1368
1369
1370 /* load_class_from_classbuffer_intern ******************************************
1371         
1372    Loads a class from a classbuffer into a given classinfo structure.
1373    Super-classes are also loaded at this point and some verfication
1374    checks are done.
1375
1376    SYNCHRONIZATION:
1377        This function is NOT synchronized!
1378    
1379 *******************************************************************************/
1380
1381 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1382 {
1383         classinfo *c;
1384         utf *name;
1385         utf *supername;
1386         u4 i,j;
1387         u4 ma, mi;
1388         descriptor_pool *descpool;
1389 #if defined(ENABLE_STATISTICS)
1390         u4 classrefsize;
1391         u4 descsize;
1392 #endif
1393 #if defined(ENABLE_RT_TIMING)
1394         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1395                                         time_setup, time_fields, time_methods, time_classrefs,
1396                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1397                                         time_parsecpool, time_verify, time_attrs;
1398 #endif
1399
1400         RT_TIMING_GET_TIME(time_start);
1401
1402         /* Get the classbuffer's class. */
1403
1404         c = cb->class;
1405
1406         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1407                 return false;
1408
1409         /* check signature */
1410
1411         if (suck_u4(cb) != MAGIC) {
1412                 exceptions_throw_classformaterror(c, "Bad magic number");
1413                 return false;
1414         }
1415
1416         /* check version */
1417
1418         mi = suck_u2(cb);
1419         ma = suck_u2(cb);
1420
1421         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1422                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1423                 return false;
1424         }
1425
1426         RT_TIMING_GET_TIME(time_checks);
1427
1428         /* create a new descriptor pool */
1429
1430         descpool = descriptor_pool_new(c);
1431
1432         RT_TIMING_GET_TIME(time_ndpool);
1433
1434         /* load the constant pool */
1435
1436         if (!load_constantpool(cb, descpool))
1437                 return false;
1438
1439         RT_TIMING_GET_TIME(time_cpool);
1440
1441         /* ACC flags */
1442
1443         if (!suck_check_classbuffer_size(cb, 2))
1444                 return false;
1445
1446         /* We OR the flags here, as we set already some flags in
1447            class_create_classinfo. */
1448
1449         c->flags |= suck_u2(cb);
1450
1451         /* check ACC flags consistency */
1452
1453         if (c->flags & ACC_INTERFACE) {
1454                 if (!(c->flags & ACC_ABSTRACT)) {
1455                         /* We work around this because interfaces in JDK 1.1 are
1456                          * not declared abstract. */
1457
1458                         c->flags |= ACC_ABSTRACT;
1459                 }
1460
1461                 if (c->flags & ACC_FINAL) {
1462                         exceptions_throw_classformaterror(c,
1463                                                                                           "Illegal class modifiers: 0x%X",
1464                                                                                           c->flags);
1465                         return false;
1466                 }
1467
1468                 if (c->flags & ACC_SUPER) {
1469                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1470                 }
1471         }
1472
1473         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1474                 exceptions_throw_classformaterror(c,
1475                                                                                   "Illegal class modifiers: 0x%X",
1476                                                                                   c->flags);
1477                 return false;
1478         }
1479
1480         if (!suck_check_classbuffer_size(cb, 2 + 2))
1481                 return false;
1482
1483         /* this class */
1484
1485         i = suck_u2(cb);
1486
1487         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1488                 return false;
1489
1490         if (c->name == utf_not_named_yet) {
1491                 /* we finally have a name for this class */
1492                 c->name = name;
1493                 class_set_packagename(c);
1494         }
1495         else if (name != c->name) {
1496                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1497                 return false;
1498         }
1499
1500         /* retrieve superclass */
1501
1502         c->super.any = NULL;
1503
1504         if ((i = suck_u2(cb))) {
1505                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1506                         return false;
1507
1508                 /* java.lang.Object may not have a super class. */
1509
1510                 if (c->name == utf_java_lang_Object) {
1511                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1512                         return false;
1513                 }
1514
1515                 /* Interfaces must have java.lang.Object as super class. */
1516
1517                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1518                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1519                         return false;
1520                 }
1521         }
1522         else {
1523                 supername = NULL;
1524
1525                 /* This is only allowed for java.lang.Object. */
1526
1527                 if (c->name != utf_java_lang_Object) {
1528                         exceptions_throw_classformaterror(c, "Bad superclass index");
1529                         return false;
1530                 }
1531         }
1532
1533         /* retrieve interfaces */
1534
1535         if (!suck_check_classbuffer_size(cb, 2))
1536                 return false;
1537
1538         c->interfacescount = suck_u2(cb);
1539
1540         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1541                 return false;
1542
1543         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1544
1545         for (i = 0; i < c->interfacescount; i++) {
1546                 /* the classrefs are created later */
1547                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1548                         return false;
1549         }
1550
1551         RT_TIMING_GET_TIME(time_setup);
1552
1553         /* load fields */
1554
1555         if (!suck_check_classbuffer_size(cb, 2))
1556                 return false;
1557
1558         c->fieldscount = suck_u2(cb);
1559         c->fields      = MNEW(fieldinfo, c->fieldscount);
1560
1561         MZERO(c->fields, fieldinfo, c->fieldscount);
1562
1563         for (i = 0; i < c->fieldscount; i++) {
1564                 if (!field_load(cb, &(c->fields[i]), descpool))
1565                         return false;
1566         }
1567
1568         RT_TIMING_GET_TIME(time_fields);
1569
1570         /* load methods */
1571
1572         if (!suck_check_classbuffer_size(cb, 2))
1573                 return false;
1574
1575         c->methodscount = suck_u2(cb);
1576         c->methods      = MNEW(methodinfo, c->methodscount);
1577
1578         MZERO(c->methods, methodinfo, c->methodscount);
1579         
1580         for (i = 0; i < c->methodscount; i++) {
1581                 if (!method_load(cb, &(c->methods[i]), descpool))
1582                         return false;
1583         }
1584
1585         RT_TIMING_GET_TIME(time_methods);
1586
1587         /* create the class reference table */
1588
1589         c->classrefs =
1590                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1591
1592         RT_TIMING_GET_TIME(time_classrefs);
1593
1594         /* allocate space for the parsed descriptors */
1595
1596         descriptor_pool_alloc_parsed_descriptors(descpool);
1597         c->parseddescs =
1598                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1599
1600 #if defined(ENABLE_STATISTICS)
1601         if (opt_stat) {
1602                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1603                 count_classref_len += classrefsize;
1604                 count_parsed_desc_len += descsize;
1605         }
1606 #endif
1607
1608         RT_TIMING_GET_TIME(time_descs);
1609
1610         /* put the classrefs in the constant pool */
1611         for (i = 0; i < c->cpcount; i++) {
1612                 if (c->cptags[i] == CONSTANT_Class) {
1613                         utf *name = (utf *) c->cpinfos[i];
1614                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1615                 }
1616         }
1617
1618         /* set the super class reference */
1619
1620         if (supername) {
1621                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1622                 if (!c->super.ref)
1623                         return false;
1624         }
1625
1626         /* set the super interfaces references */
1627
1628         for (i = 0; i < c->interfacescount; i++) {
1629                 c->interfaces[i].ref =
1630                         descriptor_pool_lookup_classref(descpool,
1631                                                                                         (utf *) c->interfaces[i].any);
1632                 if (!c->interfaces[i].ref)
1633                         return false;
1634         }
1635
1636         RT_TIMING_GET_TIME(time_setrefs);
1637
1638         /* parse field descriptors */
1639
1640         for (i = 0; i < c->fieldscount; i++) {
1641                 c->fields[i].parseddesc =
1642                         descriptor_pool_parse_field_descriptor(descpool,
1643                                                                                                    c->fields[i].descriptor);
1644                 if (!c->fields[i].parseddesc)
1645                         return false;
1646         }
1647
1648         RT_TIMING_GET_TIME(time_parsefds);
1649
1650         /* parse method descriptors */
1651
1652         for (i = 0; i < c->methodscount; i++) {
1653                 methodinfo *m = &c->methods[i];
1654                 m->parseddesc =
1655                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1656                                                                                                         m->flags, class_get_self_classref(m->class));
1657                 if (!m->parseddesc)
1658                         return false;
1659
1660                 for (j = 0; j < m->rawexceptiontablelength; j++) {
1661                         if (!m->rawexceptiontable[j].catchtype.any)
1662                                 continue;
1663
1664                         if ((m->rawexceptiontable[j].catchtype.ref =
1665                                  descriptor_pool_lookup_classref(descpool,
1666                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1667                                 return false;
1668                 }
1669
1670                 for (j = 0; j < m->thrownexceptionscount; j++) {
1671                         if (!m->thrownexceptions[j].any)
1672                                 continue;
1673
1674                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1675                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
1676                                 return false;
1677                 }
1678         }
1679
1680         RT_TIMING_GET_TIME(time_parsemds);
1681
1682         /* parse the loaded descriptors */
1683
1684         for (i = 0; i < c->cpcount; i++) {
1685                 constant_FMIref *fmi;
1686                 s4               index;
1687
1688                 switch (c->cptags[i]) {
1689                 case CONSTANT_Fieldref:
1690                         fmi = (constant_FMIref *) c->cpinfos[i];
1691                         fmi->parseddesc.fd =
1692                                 descriptor_pool_parse_field_descriptor(descpool,
1693                                                                                                            fmi->descriptor);
1694                         if (!fmi->parseddesc.fd)
1695                                 return false;
1696
1697                         index = fmi->p.index;
1698                         fmi->p.classref =
1699                                 (constant_classref *) class_getconstant(c, index,
1700                                                                                                                 CONSTANT_Class);
1701                         if (!fmi->p.classref)
1702                                 return false;
1703                         break;
1704                 case CONSTANT_Methodref:
1705                 case CONSTANT_InterfaceMethodref:
1706                         fmi = (constant_FMIref *) c->cpinfos[i];
1707                         index = fmi->p.index;
1708                         fmi->p.classref =
1709                                 (constant_classref *) class_getconstant(c, index,
1710                                                                                                                 CONSTANT_Class);
1711                         if (!fmi->p.classref)
1712                                 return false;
1713                         fmi->parseddesc.md =
1714                                 descriptor_pool_parse_method_descriptor(descpool,
1715                                                                                                                 fmi->descriptor,
1716                                                                                                                 ACC_UNDEF,
1717                                                                                                                 fmi->p.classref);
1718                         if (!fmi->parseddesc.md)
1719                                 return false;
1720                         break;
1721                 }
1722         }
1723
1724         RT_TIMING_GET_TIME(time_parsecpool);
1725
1726 #ifdef ENABLE_VERIFIER
1727         /* Check if all fields and methods can be uniquely
1728          * identified by (name,descriptor). */
1729
1730         if (opt_verify) {
1731                 /* We use a hash table here to avoid making the
1732                  * average case quadratic in # of methods, fields.
1733                  */
1734                 static int shift = 0;
1735                 u2 *hashtab;
1736                 u2 *next; /* for chaining colliding hash entries */
1737                 size_t len;
1738                 size_t hashlen;
1739                 u2 index;
1740                 u2 old;
1741
1742                 /* Allocate hashtable */
1743                 len = c->methodscount;
1744                 if (len < c->fieldscount) len = c->fieldscount;
1745                 hashlen = 5 * len;
1746                 hashtab = MNEW(u2,(hashlen + len));
1747                 next = hashtab + hashlen;
1748
1749                 /* Determine bitshift (to get good hash values) */
1750                 if (!shift) {
1751                         len = sizeof(utf);
1752                         while (len) {
1753                                 len >>= 1;
1754                                 shift++;
1755                         }
1756                 }
1757
1758                 /* Check fields */
1759                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1760
1761                 for (i = 0; i < c->fieldscount; ++i) {
1762                         fieldinfo *fi = c->fields + i;
1763
1764                         /* It's ok if we lose bits here */
1765                         index = ((((size_t) fi->name) +
1766                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
1767
1768                         if ((old = hashtab[index])) {
1769                                 old--;
1770                                 next[i] = old;
1771                                 do {
1772                                         if (c->fields[old].name == fi->name &&
1773                                                 c->fields[old].descriptor == fi->descriptor) {
1774                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1775                                                 return false;
1776                                         }
1777                                 } while ((old = next[old]));
1778                         }
1779                         hashtab[index] = i + 1;
1780                 }
1781
1782                 /* Check methods */
1783                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1784
1785                 for (i = 0; i < c->methodscount; ++i) {
1786                         methodinfo *mi = c->methods + i;
1787
1788                         /* It's ok if we lose bits here */
1789                         index = ((((size_t) mi->name) +
1790                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
1791
1792                         if ((old = hashtab[index])) {
1793                                 old--;
1794                                 next[i] = old;
1795                                 do {
1796                                         if (c->methods[old].name == mi->name &&
1797                                                 c->methods[old].descriptor == mi->descriptor) {
1798                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1799                                                 return false;
1800                                         }
1801                                 } while ((old = next[old]));
1802                         }
1803                         hashtab[index] = i + 1;
1804                 }
1805
1806                 MFREE(hashtab, u2, (hashlen + len));
1807         }
1808 #endif /* ENABLE_VERIFIER */
1809
1810         RT_TIMING_GET_TIME(time_verify);
1811
1812 #if defined(ENABLE_STATISTICS)
1813         if (opt_stat) {
1814                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
1815                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
1816                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1817         }
1818 #endif
1819
1820         /* load attribute structures */
1821
1822         if (!class_load_attributes(cb))
1823                 return false;
1824
1825         /* Pre Java 1.5 version don't check this. This implementation is
1826            like Java 1.5 do it: for class file version 45.3 we don't check
1827            it, older versions are checked. */
1828
1829         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1830                 /* check if all data has been read */
1831                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1832
1833                 if (classdata_left > 0) {
1834                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1835                         return false;
1836                 }
1837         }
1838
1839         RT_TIMING_GET_TIME(time_attrs);
1840
1841         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
1842         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
1843         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
1844         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
1845         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
1846         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
1847         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1848         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
1849         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
1850         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
1851         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
1852         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1853         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
1854         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
1855         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
1856
1857         return true;
1858 }
1859
1860
1861 /* load_class_from_classbuffer *************************************************
1862
1863    Convenience wrapper for load_class_from_classbuffer.
1864
1865    SYNCHRONIZATION:
1866        This function is NOT synchronized!
1867    
1868 *******************************************************************************/
1869
1870 classinfo *load_class_from_classbuffer(classbuffer *cb)
1871 {
1872         classinfo *c;
1873         int32_t    dumpsize;
1874         bool       result;
1875
1876         /* Get the classbuffer's class. */
1877
1878         c = cb->class;
1879
1880         /* Check if the class is already loaded. */
1881
1882         if (c->state & CLASS_LOADED)
1883                 return c;
1884
1885 #if defined(ENABLE_STATISTICS)
1886         if (opt_stat)
1887                 count_class_loads++;
1888 #endif
1889
1890 #if !defined(NDEBUG)
1891         if (loadverbose)
1892                 log_message_class("Loading class: ", c);
1893 #endif
1894
1895         /* Mark start of dump memory area. */
1896
1897         dumpsize = dump_size();
1898
1899         /* Class is currently loading. */
1900
1901         c->state |= CLASS_LOADING;
1902
1903         /* Parse the classbuffer. */
1904
1905         result = load_class_from_classbuffer_intern(cb);
1906
1907         /* Release dump area. */
1908
1909         dump_release(dumpsize);
1910
1911         /* An error occurred. */
1912
1913         if (result == false) {
1914                 /* Revert loading state. */
1915
1916                 c->state = (c->state & ~CLASS_LOADING);
1917
1918                 return NULL;
1919         }
1920
1921         /* Revert loading state and set loaded. */
1922
1923         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1924
1925 #if defined(ENABLE_JVMTI)
1926         /* fire Class Prepare JVMTI event */
1927
1928         if (jvmti)
1929                 jvmti_ClassLoadPrepare(true, c);
1930 #endif
1931
1932 #if !defined(NDEBUG)
1933         if (loadverbose)
1934                 log_message_class("Loading done class: ", c);
1935 #endif
1936
1937         return c;
1938 }
1939
1940
1941 /* load_newly_created_array ****************************************************
1942
1943    Load a newly created array class.
1944
1945         RETURN VALUE:
1946             c....................the array class C has been loaded
1947                 other classinfo......the array class was found in the class cache, 
1948                                      C has been freed
1949             NULL.................an exception has been thrown
1950
1951         Note:
1952                 This is an internal function. Do not use it unless you know exactly
1953                 what you are doing!
1954
1955                 Use one of the load_class_... functions for general array class loading.
1956
1957 *******************************************************************************/
1958
1959 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1960 {
1961         classinfo         *comp = NULL;
1962         methodinfo        *clone;
1963         methoddesc        *clonedesc;
1964         constant_classref *classrefs;
1965         char              *text;
1966         s4                 namelen;
1967         utf               *u;
1968
1969         text    = c->name->text;
1970         namelen = c->name->blength;
1971
1972         /* Check array class name */
1973
1974         if ((namelen < 2) || (text[0] != '[')) {
1975                 exceptions_throw_classnotfoundexception(c->name);
1976                 return NULL;
1977         }
1978
1979         /* Check the element type */
1980
1981         switch (text[1]) {
1982         case '[':
1983                 /* c is an array of arrays. We have to create the component class. */
1984
1985                 u = utf_new(text + 1, namelen - 1);
1986
1987                 comp = load_class_from_classloader(u, loader);
1988
1989                 if (comp == NULL)
1990                         return NULL;
1991
1992                 assert(comp->state & CLASS_LOADED);
1993
1994                 /* the array's flags are that of the component class */
1995                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1996                 c->classloader = comp->classloader;
1997                 break;
1998
1999         case 'L':
2000                 /* c is an array of objects. */
2001
2002                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2003                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2004                         exceptions_throw_classnotfoundexception(c->name);
2005                         return NULL;
2006                 }
2007
2008                 u = utf_new(text + 2, namelen - 3);
2009
2010                 if (!(comp = load_class_from_classloader(u, loader)))
2011                         return NULL;
2012
2013                 assert(comp->state & CLASS_LOADED);
2014
2015                 /* the array's flags are that of the component class */
2016                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2017                 c->classloader = comp->classloader;
2018                 break;
2019
2020         default:
2021                 /* c is an array of a primitive type */
2022
2023                 /* check for cases like `[II' and whether the character is a
2024                    valid primitive type */
2025
2026                 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
2027                         exceptions_throw_classnotfoundexception(c->name);
2028                         return NULL;
2029                 }
2030
2031                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2032                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2033                 c->classloader = NULL;
2034         }
2035
2036         assert(class_java_lang_Object);
2037 #if defined(ENABLE_JAVASE)
2038         assert(class_java_lang_Cloneable);
2039         assert(class_java_io_Serializable);
2040 #endif
2041
2042         /* setup the array class */
2043
2044         c->super.cls = class_java_lang_Object;
2045
2046 #if defined(ENABLE_JAVASE)
2047
2048         c->interfacescount   = 2;
2049     c->interfaces        = MNEW(classref_or_classinfo, 2);
2050         c->interfaces[0].cls = class_java_lang_Cloneable;
2051         c->interfaces[1].cls = class_java_io_Serializable;
2052
2053 #elif defined(ENABLE_JAVAME_CLDC1_1)
2054
2055         c->interfacescount   = 0;
2056         c->interfaces        = NULL;
2057
2058 #else
2059 # error unknow Java configuration
2060 #endif
2061
2062         c->methodscount = 1;
2063         c->methods = MNEW(methodinfo, c->methodscount);
2064         MZERO(c->methods, methodinfo, c->methodscount);
2065
2066         classrefs = MNEW(constant_classref, 2);
2067         CLASSREF_INIT(classrefs[0], c, c->name);
2068         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2069
2070         /* create descriptor for clone method */
2071         /* we need one paramslot which is reserved for the 'this' parameter */
2072         clonedesc = NEW(methoddesc);
2073         clonedesc->returntype.type = TYPE_ADR;
2074         clonedesc->returntype.classref = classrefs + 1;
2075         clonedesc->returntype.arraydim = 0;
2076         /* initialize params to "empty", add real params below in
2077            descriptor_params_from_paramtypes */
2078         clonedesc->paramcount = 0;
2079         clonedesc->paramslots = 0;
2080         clonedesc->paramtypes[0].classref = classrefs + 0;
2081         clonedesc->params = NULL;
2082
2083         /* create methodinfo */
2084
2085         clone = c->methods;
2086         MSET(clone, 0, methodinfo, 1);
2087
2088 #if defined(ENABLE_THREADS)
2089         lock_init_object_lock(&clone->header);
2090 #endif
2091
2092         /* ATTENTION: if you delete the ACC_NATIVE below, set
2093            clone->maxlocals=1 (interpreter related) */
2094
2095         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2096         clone->name       = utf_clone;
2097         clone->descriptor = utf_void__java_lang_Object;
2098         clone->parseddesc = clonedesc;
2099         clone->class      = c;
2100
2101         /* parse the descriptor to get the register allocation */
2102
2103         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2104                 return false;
2105
2106         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
2107
2108         /* XXX: field: length? */
2109
2110         /* array classes are not loaded from class files */
2111
2112         c->state          |= CLASS_LOADED;
2113         c->parseddescs    = (u1 *) clonedesc;
2114         c->parseddescsize = sizeof(methodinfo);
2115         c->classrefs      = classrefs;
2116         c->classrefcount  = 1;
2117
2118         /* insert class into the loaded class cache */
2119         /* XXX free classinfo if NULL returned? */
2120
2121         return classcache_store(loader, c, true);
2122 }
2123
2124
2125 /* loader_close ****************************************************************
2126
2127    Frees all resources.
2128         
2129 *******************************************************************************/
2130
2131 void loader_close(void)
2132 {
2133         /* empty */
2134 }
2135
2136
2137 /*
2138  * These are local overrides for various environment variables in Emacs.
2139  * Please do not remove this and leave it at the end of the file, where
2140  * Emacs will automagically detect them.
2141  * ---------------------------------------------------------------------
2142  * Local variables:
2143  * mode: c
2144  * indent-tabs-mode: t
2145  * c-basic-offset: 4
2146  * tab-width: 4
2147  * End:
2148  * vim:noexpandtab:sw=4:ts=4:
2149  */