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