* src/cacaoh/cacaoh.c (main): Added loader_preinit call.
[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                 assert(class_java_lang_Object);
995
996                 lc = class_resolveclassmethod(cl->vftbl->class,
997                                                                           utf_loadClass,
998                                                                           utf_java_lang_String__java_lang_Class,
999                                                                           class_java_lang_Object,
1000                                                                           true);
1001
1002                 if (!lc)
1003                         return false; /* exception */
1004
1005                 /* move return value into `o' and cast it afterwards to a classinfo* */
1006
1007                 string = javastring_new_slash_to_dot(name);
1008
1009                 RT_TIMING_GET_TIME(time_prepare);
1010
1011                 o = vm_call_method(lc, cl, string);
1012
1013                 RT_TIMING_GET_TIME(time_java);
1014
1015                 c = LLNI_classinfo_unwrap(o);
1016
1017                 if (c != NULL) {
1018                         /* Store this class in the loaded class cache. If another
1019                            class with the same (initloader,name) pair has been
1020                            stored earlier it will be returned by classcache_store
1021                            In this case classcache_store may not free the class
1022                            because it has already been exposed to Java code which
1023                            may have kept references to that class. */
1024
1025                     tmpc = classcache_store(cl, c, false);
1026
1027                         if (tmpc == NULL) {
1028                                 /* exception, free the loaded class */
1029                                 c->state &= ~CLASS_LOADING;
1030                                 class_free(c);
1031                         }
1032
1033                         c = tmpc;
1034                 }
1035
1036                 RT_TIMING_GET_TIME(time_cache);
1037
1038                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1039                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1040                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1041
1042                 /* SUN compatible -verbose:class output */
1043
1044                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1045                         printf("[Loaded ");
1046                         utf_display_printable_ascii_classname(name);
1047                         printf("]\n");
1048                 }
1049
1050 #if defined(ENABLE_JVMTI)
1051                 /* fire Class Load JVMTI event */
1052                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1053 #endif
1054
1055
1056                 return c;
1057         } 
1058
1059         c = load_class_bootstrap(name);
1060
1061         return c;
1062 }
1063
1064
1065 /* load_class_bootstrap ********************************************************
1066         
1067    Load the class with the given name using the bootstrap class loader.
1068
1069    IN:
1070        name.............the classname
1071
1072    RETURN VALUE:
1073        loaded classinfo, or
1074            NULL if an exception has been thrown
1075
1076    SYNCHRONIZATION:
1077        load_class_bootstrap is synchronized. It can be treated as an
1078            atomic operation.
1079
1080 *******************************************************************************/
1081
1082 classinfo *load_class_bootstrap(utf *name)
1083 {
1084         classbuffer *cb;
1085         classinfo   *c;
1086         classinfo   *r;
1087 #if defined(ENABLE_RT_TIMING)
1088         struct timespec time_start, time_lookup, time_array, time_suck, 
1089                                         time_load, time_cache;
1090 #endif
1091
1092         RT_TIMING_GET_TIME(time_start);
1093
1094         /* for debugging */
1095
1096         assert(name);
1097
1098         /* lookup if this class has already been loaded */
1099
1100         r = classcache_lookup(NULL, name);
1101
1102         if (r != NULL) {
1103                 RT_TIMING_GET_TIME(time_lookup);
1104                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1105                 
1106                 return r;
1107         }
1108
1109         RT_TIMING_GET_TIME(time_lookup);
1110         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1111                 
1112         /* create the classinfo */
1113
1114         c = class_create_classinfo(name);
1115
1116         /* handle array classes */
1117
1118         if (name->text[0] == '[') {
1119                 c = load_newly_created_array(c, NULL);
1120
1121                 if (c == NULL)
1122                         return NULL;
1123
1124                 assert(c->state & CLASS_LOADED);
1125
1126                 RT_TIMING_GET_TIME(time_array);
1127                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1128                 
1129                 return c;
1130         }
1131
1132 #if defined(ENABLE_STATISTICS)
1133         /* measure time */
1134
1135         if (opt_getcompilingtime)
1136                 compilingtime_stop();
1137
1138         if (opt_getloadingtime)
1139                 loadingtime_start();
1140 #endif
1141
1142         /* load classdata, throw exception on error */
1143
1144         cb = suck_start(c);
1145
1146         if (cb == NULL) {
1147                 /* this normally means, the classpath was not set properly */
1148
1149                 if (name == utf_java_lang_Object)
1150                         vm_abort("java/lang/NoClassDefFoundError: java/lang/Object");
1151
1152                 exceptions_throw_classnotfoundexception(name);
1153
1154                 return NULL;
1155         }
1156
1157         RT_TIMING_GET_TIME(time_suck);
1158         
1159         /* load the class from the buffer */
1160
1161         r = load_class_from_classbuffer(cb);
1162
1163         RT_TIMING_GET_TIME(time_load);
1164         
1165         if (!r) {
1166                 /* the class could not be loaded, free the classinfo struct */
1167
1168                 class_free(c);
1169
1170         } else {
1171                 /* Store this class in the loaded class cache this step also
1172                 checks the loading constraints. If the class has been loaded
1173                 before, the earlier loaded class is returned. */
1174
1175                 classinfo *res = classcache_store(NULL, c, true);
1176
1177                 if (!res) {
1178                         /* exception */
1179                         class_free(c);
1180                 }
1181
1182                 r = res;
1183         }
1184
1185         RT_TIMING_GET_TIME(time_cache);
1186         
1187         /* SUN compatible -verbose:class output */
1188
1189         if (opt_verboseclass && r) {
1190                 printf("[Loaded ");
1191                 utf_display_printable_ascii_classname(name);
1192                 printf(" from %s]\n", cb->path);
1193         }
1194
1195         /* free memory */
1196
1197         suck_stop(cb);
1198
1199 #if defined(ENABLE_STATISTICS)
1200         /* measure time */
1201
1202         if (opt_getloadingtime)
1203                 loadingtime_stop();
1204
1205         if (opt_getcompilingtime)
1206                 compilingtime_start();
1207 #endif
1208
1209         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1210         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1211         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1212         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1213
1214         return r;
1215 }
1216
1217
1218 /* load_class_from_classbuffer *************************************************
1219         
1220    Loads everything interesting about a class from the class file. The
1221    'classinfo' structure must have been allocated previously.
1222
1223    The super class and the interfaces implemented by this class need
1224    not be loaded. The link is set later by the function 'class_link'.
1225
1226    SYNCHRONIZATION:
1227        This function is NOT synchronized!
1228    
1229 *******************************************************************************/
1230
1231 classinfo *load_class_from_classbuffer(classbuffer *cb)
1232 {
1233         classinfo *c;
1234         utf *name;
1235         utf *supername;
1236         u4 i,j;
1237         u4 ma, mi;
1238         s4 dumpsize;
1239         descriptor_pool *descpool;
1240 #if defined(ENABLE_STATISTICS)
1241         u4 classrefsize;
1242         u4 descsize;
1243 #endif
1244 #if defined(ENABLE_RT_TIMING)
1245         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1246                                         time_setup, time_fields, time_methods, time_classrefs,
1247                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1248                                         time_parsecpool, time_verify, time_attrs;
1249 #endif
1250
1251         RT_TIMING_GET_TIME(time_start);
1252
1253         /* get the classbuffer's class */
1254
1255         c = cb->class;
1256
1257         /* the class is already loaded */
1258
1259         if (c->state & CLASS_LOADED)
1260                 return c;
1261
1262 #if defined(ENABLE_STATISTICS)
1263         if (opt_stat)
1264                 count_class_loads++;
1265 #endif
1266
1267 #if !defined(NDEBUG)
1268         /* output for debugging purposes */
1269
1270         if (loadverbose)
1271                 log_message_class("Loading class: ", c);
1272 #endif
1273
1274         /* mark start of dump memory area */
1275
1276         dumpsize = dump_size();
1277
1278         /* class is currently loading */
1279
1280         c->state |= CLASS_LOADING;
1281
1282         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1283                 goto return_exception;
1284
1285         /* check signature */
1286
1287         if (suck_u4(cb) != MAGIC) {
1288                 exceptions_throw_classformaterror(c, "Bad magic number");
1289
1290                 goto return_exception;
1291         }
1292
1293         /* check version */
1294
1295         mi = suck_u2(cb);
1296         ma = suck_u2(cb);
1297
1298         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1299                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1300                 goto return_exception;
1301         }
1302
1303         RT_TIMING_GET_TIME(time_checks);
1304
1305         /* create a new descriptor pool */
1306
1307         descpool = descriptor_pool_new(c);
1308
1309         RT_TIMING_GET_TIME(time_ndpool);
1310
1311         /* load the constant pool */
1312
1313         if (!load_constantpool(cb, descpool))
1314                 goto return_exception;
1315
1316         RT_TIMING_GET_TIME(time_cpool);
1317
1318         /* ACC flags */
1319
1320         if (!suck_check_classbuffer_size(cb, 2))
1321                 goto return_exception;
1322
1323         /* We OR the flags here, as we set already some flags in
1324            class_create_classinfo. */
1325
1326         c->flags |= suck_u2(cb);
1327
1328         /* check ACC flags consistency */
1329
1330         if (c->flags & ACC_INTERFACE) {
1331                 if (!(c->flags & ACC_ABSTRACT)) {
1332                         /* We work around this because interfaces in JDK 1.1 are
1333                          * not declared abstract. */
1334
1335                         c->flags |= ACC_ABSTRACT;
1336                 }
1337
1338                 if (c->flags & ACC_FINAL) {
1339                         exceptions_throw_classformaterror(c,
1340                                                                                           "Illegal class modifiers: 0x%X",
1341                                                                                           c->flags);
1342                         goto return_exception;
1343                 }
1344
1345                 if (c->flags & ACC_SUPER) {
1346                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1347                 }
1348         }
1349
1350         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1351                 exceptions_throw_classformaterror(c,
1352                                                                                   "Illegal class modifiers: 0x%X",
1353                                                                                   c->flags);
1354                 goto return_exception;
1355         }
1356
1357         if (!suck_check_classbuffer_size(cb, 2 + 2))
1358                 goto return_exception;
1359
1360         /* this class */
1361
1362         i = suck_u2(cb);
1363
1364         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1365                 goto return_exception;
1366
1367         if (c->name == utf_not_named_yet) {
1368                 /* we finally have a name for this class */
1369                 c->name = name;
1370                 class_set_packagename(c);
1371         }
1372         else if (name != c->name) {
1373                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1374                 goto return_exception;
1375         }
1376
1377         /* retrieve superclass */
1378
1379         c->super.any = NULL;
1380
1381         if ((i = suck_u2(cb))) {
1382                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1383                         goto return_exception;
1384
1385                 /* java.lang.Object may not have a super class. */
1386
1387                 if (c->name == utf_java_lang_Object) {
1388                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1389                         goto return_exception;
1390                 }
1391
1392                 /* Interfaces must have java.lang.Object as super class. */
1393
1394                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1395                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1396                         goto return_exception;
1397                 }
1398
1399         } else {
1400                 supername = NULL;
1401
1402                 /* This is only allowed for java.lang.Object. */
1403
1404                 if (c->name != utf_java_lang_Object) {
1405                         exceptions_throw_classformaterror(c, "Bad superclass index");
1406                         goto return_exception;
1407                 }
1408         }
1409
1410         /* retrieve interfaces */
1411
1412         if (!suck_check_classbuffer_size(cb, 2))
1413                 goto return_exception;
1414
1415         c->interfacescount = suck_u2(cb);
1416
1417         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1418                 goto return_exception;
1419
1420         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1421         for (i = 0; i < c->interfacescount; i++) {
1422                 /* the classrefs are created later */
1423                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1424                         goto return_exception;
1425         }
1426
1427         RT_TIMING_GET_TIME(time_setup);
1428
1429         /* load fields */
1430
1431         if (!suck_check_classbuffer_size(cb, 2))
1432                 goto return_exception;
1433
1434         c->fieldscount = suck_u2(cb);
1435         c->fields      = MNEW(fieldinfo, c->fieldscount);
1436
1437         MZERO(c->fields, fieldinfo, c->fieldscount);
1438
1439         for (i = 0; i < c->fieldscount; i++) {
1440                 if (!field_load(cb, &(c->fields[i]), descpool))
1441                         goto return_exception;
1442         }
1443
1444         RT_TIMING_GET_TIME(time_fields);
1445
1446         /* load methods */
1447
1448         if (!suck_check_classbuffer_size(cb, 2))
1449                 goto return_exception;
1450
1451         c->methodscount = suck_u2(cb);
1452         c->methods      = MNEW(methodinfo, c->methodscount);
1453
1454         MZERO(c->methods, methodinfo, c->methodscount);
1455         
1456         for (i = 0; i < c->methodscount; i++) {
1457                 if (!method_load(cb, &(c->methods[i]), descpool))
1458                         goto return_exception;
1459         }
1460
1461         RT_TIMING_GET_TIME(time_methods);
1462
1463         /* create the class reference table */
1464
1465         c->classrefs =
1466                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1467
1468         RT_TIMING_GET_TIME(time_classrefs);
1469
1470         /* allocate space for the parsed descriptors */
1471
1472         descriptor_pool_alloc_parsed_descriptors(descpool);
1473         c->parseddescs =
1474                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1475
1476 #if defined(ENABLE_STATISTICS)
1477         if (opt_stat) {
1478                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1479                 count_classref_len += classrefsize;
1480                 count_parsed_desc_len += descsize;
1481         }
1482 #endif
1483
1484         RT_TIMING_GET_TIME(time_descs);
1485
1486         /* put the classrefs in the constant pool */
1487         for (i = 0; i < c->cpcount; i++) {
1488                 if (c->cptags[i] == CONSTANT_Class) {
1489                         utf *name = (utf *) c->cpinfos[i];
1490                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1491                 }
1492         }
1493
1494         /* set the super class reference */
1495
1496         if (supername) {
1497                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1498                 if (!c->super.ref)
1499                         goto return_exception;
1500         }
1501
1502         /* set the super interfaces references */
1503
1504         for (i = 0; i < c->interfacescount; i++) {
1505                 c->interfaces[i].ref =
1506                         descriptor_pool_lookup_classref(descpool,
1507                                                                                         (utf *) c->interfaces[i].any);
1508                 if (!c->interfaces[i].ref)
1509                         goto return_exception;
1510         }
1511
1512         RT_TIMING_GET_TIME(time_setrefs);
1513
1514         /* parse field descriptors */
1515
1516         for (i = 0; i < c->fieldscount; i++) {
1517                 c->fields[i].parseddesc =
1518                         descriptor_pool_parse_field_descriptor(descpool,
1519                                                                                                    c->fields[i].descriptor);
1520                 if (!c->fields[i].parseddesc)
1521                         goto return_exception;
1522         }
1523
1524         RT_TIMING_GET_TIME(time_parsefds);
1525
1526         /* parse method descriptors */
1527
1528         for (i = 0; i < c->methodscount; i++) {
1529                 methodinfo *m = &c->methods[i];
1530                 m->parseddesc =
1531                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1532                                                                                                         m->flags, class_get_self_classref(m->class));
1533                 if (!m->parseddesc)
1534                         goto return_exception;
1535
1536                 for (j = 0; j < m->rawexceptiontablelength; j++) {
1537                         if (!m->rawexceptiontable[j].catchtype.any)
1538                                 continue;
1539                         if ((m->rawexceptiontable[j].catchtype.ref =
1540                                  descriptor_pool_lookup_classref(descpool,
1541                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1542                                 goto return_exception;
1543                 }
1544
1545                 for (j = 0; j < m->thrownexceptionscount; j++) {
1546                         if (!m->thrownexceptions[j].any)
1547                                 continue;
1548                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1549                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
1550                                 goto return_exception;
1551                 }
1552         }
1553
1554         RT_TIMING_GET_TIME(time_parsemds);
1555
1556         /* parse the loaded descriptors */
1557
1558         for (i = 0; i < c->cpcount; i++) {
1559                 constant_FMIref *fmi;
1560                 s4               index;
1561
1562                 switch (c->cptags[i]) {
1563                 case CONSTANT_Fieldref:
1564                         fmi = (constant_FMIref *) c->cpinfos[i];
1565                         fmi->parseddesc.fd =
1566                                 descriptor_pool_parse_field_descriptor(descpool,
1567                                                                                                            fmi->descriptor);
1568                         if (!fmi->parseddesc.fd)
1569                                 goto return_exception;
1570                         index = fmi->p.index;
1571                         fmi->p.classref =
1572                                 (constant_classref *) class_getconstant(c, index,
1573                                                                                                                 CONSTANT_Class);
1574                         if (!fmi->p.classref)
1575                                 goto return_exception;
1576                         break;
1577                 case CONSTANT_Methodref:
1578                 case CONSTANT_InterfaceMethodref:
1579                         fmi = (constant_FMIref *) c->cpinfos[i];
1580                         index = fmi->p.index;
1581                         fmi->p.classref =
1582                                 (constant_classref *) class_getconstant(c, index,
1583                                                                                                                 CONSTANT_Class);
1584                         if (!fmi->p.classref)
1585                                 goto return_exception;
1586                         fmi->parseddesc.md =
1587                                 descriptor_pool_parse_method_descriptor(descpool,
1588                                                                                                                 fmi->descriptor,
1589                                                                                                                 ACC_UNDEF,
1590                                                                                                                 fmi->p.classref);
1591                         if (!fmi->parseddesc.md)
1592                                 goto return_exception;
1593                         break;
1594                 }
1595         }
1596
1597         RT_TIMING_GET_TIME(time_parsecpool);
1598
1599 #ifdef ENABLE_VERIFIER
1600         /* Check if all fields and methods can be uniquely
1601          * identified by (name,descriptor). */
1602
1603         if (opt_verify) {
1604                 /* We use a hash table here to avoid making the
1605                  * average case quadratic in # of methods, fields.
1606                  */
1607                 static int shift = 0;
1608                 u2 *hashtab;
1609                 u2 *next; /* for chaining colliding hash entries */
1610                 size_t len;
1611                 size_t hashlen;
1612                 u2 index;
1613                 u2 old;
1614
1615                 /* Allocate hashtable */
1616                 len = c->methodscount;
1617                 if (len < c->fieldscount) len = c->fieldscount;
1618                 hashlen = 5 * len;
1619                 hashtab = MNEW(u2,(hashlen + len));
1620                 next = hashtab + hashlen;
1621
1622                 /* Determine bitshift (to get good hash values) */
1623                 if (!shift) {
1624                         len = sizeof(utf);
1625                         while (len) {
1626                                 len >>= 1;
1627                                 shift++;
1628                         }
1629                 }
1630
1631                 /* Check fields */
1632                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1633
1634                 for (i = 0; i < c->fieldscount; ++i) {
1635                         fieldinfo *fi = c->fields + i;
1636
1637                         /* It's ok if we lose bits here */
1638                         index = ((((size_t) fi->name) +
1639                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
1640
1641                         if ((old = hashtab[index])) {
1642                                 old--;
1643                                 next[i] = old;
1644                                 do {
1645                                         if (c->fields[old].name == fi->name &&
1646                                                 c->fields[old].descriptor == fi->descriptor) {
1647                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1648                                                 goto return_exception;
1649                                         }
1650                                 } while ((old = next[old]));
1651                         }
1652                         hashtab[index] = i + 1;
1653                 }
1654
1655                 /* Check methods */
1656                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1657
1658                 for (i = 0; i < c->methodscount; ++i) {
1659                         methodinfo *mi = c->methods + i;
1660
1661                         /* It's ok if we lose bits here */
1662                         index = ((((size_t) mi->name) +
1663                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
1664
1665                         /*{ JOWENN
1666                                 int dbg;
1667                                 for (dbg=0;dbg<hashlen+hashlen/5;++dbg){
1668                                         printf("Hash[%d]:%d\n",dbg,hashtab[dbg]);
1669                                 }
1670                         }*/
1671
1672                         if ((old = hashtab[index])) {
1673                                 old--;
1674                                 next[i] = old;
1675                                 do {
1676                                         if (c->methods[old].name == mi->name &&
1677                                                 c->methods[old].descriptor == mi->descriptor) {
1678                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1679                                                 goto return_exception;
1680                                         }
1681                                 } while ((old = next[old]));
1682                         }
1683                         hashtab[index] = i + 1;
1684                 }
1685
1686                 MFREE(hashtab, u2, (hashlen + len));
1687         }
1688 #endif /* ENABLE_VERIFIER */
1689
1690         RT_TIMING_GET_TIME(time_verify);
1691
1692 #if defined(ENABLE_STATISTICS)
1693         if (opt_stat) {
1694                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
1695                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
1696                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1697         }
1698 #endif
1699
1700         /* load attribute structures */
1701
1702         if (!class_load_attributes(cb))
1703                 goto return_exception;
1704
1705         /* Pre Java 1.5 version don't check this. This implementation is like
1706            Java 1.5 do it: for class file version 45.3 we don't check it, older
1707            versions are checked.
1708          */
1709
1710         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1711                 /* check if all data has been read */
1712                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1713
1714                 if (classdata_left > 0) {
1715                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1716                         goto return_exception;
1717                 }
1718         }
1719
1720         RT_TIMING_GET_TIME(time_attrs);
1721
1722         /* release dump area */
1723
1724         dump_release(dumpsize);
1725
1726         /* revert loading state and class is loaded */
1727
1728         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1729
1730 #if defined(ENABLE_JVMTI)
1731         /* fire Class Prepare JVMTI event */
1732
1733         if (jvmti)
1734                 jvmti_ClassLoadPrepare(true, c);
1735 #endif
1736
1737 #if !defined(NDEBUG)
1738         if (loadverbose)
1739                 log_message_class("Loading done class: ", c);
1740 #endif
1741
1742         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
1743         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
1744         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
1745         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
1746         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
1747         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
1748         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1749         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
1750         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
1751         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
1752         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
1753         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1754         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
1755         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
1756         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
1757
1758         return c;
1759
1760 return_exception:
1761         /* release dump area */
1762
1763         dump_release(dumpsize);
1764
1765         /* an exception has been thrown */
1766
1767         return NULL;
1768 }
1769
1770
1771 /* load_newly_created_array ****************************************************
1772
1773    Load a newly created array class.
1774
1775         RETURN VALUE:
1776             c....................the array class C has been loaded
1777                 other classinfo......the array class was found in the class cache, 
1778                                      C has been freed
1779             NULL.................an exception has been thrown
1780
1781         Note:
1782                 This is an internal function. Do not use it unless you know exactly
1783                 what you are doing!
1784
1785                 Use one of the load_class_... functions for general array class loading.
1786
1787 *******************************************************************************/
1788
1789 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1790 {
1791         classinfo         *comp = NULL;
1792         methodinfo        *clone;
1793         methoddesc        *clonedesc;
1794         constant_classref *classrefs;
1795         char              *text;
1796         s4                 namelen;
1797         utf               *u;
1798
1799         text    = c->name->text;
1800         namelen = c->name->blength;
1801
1802         /* Check array class name */
1803
1804         if ((namelen < 2) || (text[0] != '[')) {
1805                 exceptions_throw_classnotfoundexception(c->name);
1806                 return NULL;
1807         }
1808
1809         /* Check the element type */
1810
1811         switch (text[1]) {
1812         case '[':
1813                 /* c is an array of arrays. We have to create the component class. */
1814
1815                 u = utf_new(text + 1, namelen - 1);
1816
1817                 comp = load_class_from_classloader(u, loader);
1818
1819                 if (comp == NULL)
1820                         return NULL;
1821
1822                 assert(comp->state & CLASS_LOADED);
1823
1824                 /* the array's flags are that of the component class */
1825                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1826                 c->classloader = comp->classloader;
1827                 break;
1828
1829         case 'L':
1830                 /* c is an array of objects. */
1831
1832                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1833                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1834                         exceptions_throw_classnotfoundexception(c->name);
1835                         return NULL;
1836                 }
1837
1838                 u = utf_new(text + 2, namelen - 3);
1839
1840                 if (!(comp = load_class_from_classloader(u, loader)))
1841                         return NULL;
1842
1843                 assert(comp->state & CLASS_LOADED);
1844
1845                 /* the array's flags are that of the component class */
1846                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1847                 c->classloader = comp->classloader;
1848                 break;
1849
1850         default:
1851                 /* c is an array of a primitive type */
1852
1853                 /* check for cases like `[II' and whether the character is a
1854                    valid primitive type */
1855
1856                 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1857                         exceptions_throw_classnotfoundexception(c->name);
1858                         return NULL;
1859                 }
1860
1861                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1862                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1863                 c->classloader = NULL;
1864         }
1865
1866         assert(class_java_lang_Object);
1867 #if defined(ENABLE_JAVASE)
1868         assert(class_java_lang_Cloneable);
1869         assert(class_java_io_Serializable);
1870 #endif
1871
1872         /* setup the array class */
1873
1874         c->super.cls = class_java_lang_Object;
1875
1876 #if defined(ENABLE_JAVASE)
1877
1878         c->interfacescount   = 2;
1879     c->interfaces        = MNEW(classref_or_classinfo, 2);
1880         c->interfaces[0].cls = class_java_lang_Cloneable;
1881         c->interfaces[1].cls = class_java_io_Serializable;
1882
1883 #elif defined(ENABLE_JAVAME_CLDC1_1)
1884
1885         c->interfacescount   = 0;
1886         c->interfaces        = NULL;
1887
1888 #else
1889 # error unknow Java configuration
1890 #endif
1891
1892         c->methodscount = 1;
1893         c->methods = MNEW(methodinfo, c->methodscount);
1894         MZERO(c->methods, methodinfo, c->methodscount);
1895
1896         classrefs = MNEW(constant_classref, 2);
1897         CLASSREF_INIT(classrefs[0], c, c->name);
1898         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
1899
1900         /* create descriptor for clone method */
1901         /* we need one paramslot which is reserved for the 'this' parameter */
1902         clonedesc = NEW(methoddesc);
1903         clonedesc->returntype.type = TYPE_ADR;
1904         clonedesc->returntype.classref = classrefs + 1;
1905         clonedesc->returntype.arraydim = 0;
1906         /* initialize params to "empty", add real params below in
1907            descriptor_params_from_paramtypes */
1908         clonedesc->paramcount = 0;
1909         clonedesc->paramslots = 0;
1910         clonedesc->paramtypes[0].classref = classrefs + 0;
1911         clonedesc->params = NULL;
1912
1913         /* create methodinfo */
1914
1915         clone = c->methods;
1916         MSET(clone, 0, methodinfo, 1);
1917
1918 #if defined(ENABLE_THREADS)
1919         lock_init_object_lock(&clone->header);
1920 #endif
1921
1922         /* ATTENTION: if you delete the ACC_NATIVE below, set
1923            clone->maxlocals=1 (interpreter related) */
1924
1925         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
1926         clone->name       = utf_clone;
1927         clone->descriptor = utf_void__java_lang_Object;
1928         clone->parseddesc = clonedesc;
1929         clone->class      = c;
1930
1931         /* parse the descriptor to get the register allocation */
1932
1933         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
1934                 return false;
1935
1936         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
1937
1938         /* XXX: field: length? */
1939
1940         /* array classes are not loaded from class files */
1941
1942         c->state          |= CLASS_LOADED;
1943         c->parseddescs    = (u1 *) clonedesc;
1944         c->parseddescsize = sizeof(methodinfo);
1945         c->classrefs      = classrefs;
1946         c->classrefcount  = 1;
1947
1948         /* insert class into the loaded class cache */
1949         /* XXX free classinfo if NULL returned? */
1950
1951         return classcache_store(loader, c, true);
1952 }
1953
1954
1955 /* loader_close ****************************************************************
1956
1957    Frees all resources.
1958         
1959 *******************************************************************************/
1960
1961 void loader_close(void)
1962 {
1963         /* empty */
1964 }
1965
1966
1967 /*
1968  * These are local overrides for various environment variables in Emacs.
1969  * Please do not remove this and leave it at the end of the file, where
1970  * Emacs will automagically detect them.
1971  * ---------------------------------------------------------------------
1972  * Local variables:
1973  * mode: c
1974  * indent-tabs-mode: t
1975  * c-basic-offset: 4
1976  * tab-width: 4
1977  * End:
1978  * vim:noexpandtab:sw=4:ts=4:
1979  */