* src/vmcore/loader.c (load_class_from_classbuffer): Renamed to
[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_intern ******************************************
1228         
1229    Loads a class from a classbuffer into a given classinfo structure.
1230    Super-classes are also loaded at this point and some verfication
1231    checks are done.
1232
1233    SYNCHRONIZATION:
1234        This function is NOT synchronized!
1235    
1236 *******************************************************************************/
1237
1238 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1239 {
1240         classinfo *c;
1241         utf *name;
1242         utf *supername;
1243         u4 i,j;
1244         u4 ma, mi;
1245         descriptor_pool *descpool;
1246 #if defined(ENABLE_STATISTICS)
1247         u4 classrefsize;
1248         u4 descsize;
1249 #endif
1250 #if defined(ENABLE_RT_TIMING)
1251         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1252                                         time_setup, time_fields, time_methods, time_classrefs,
1253                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1254                                         time_parsecpool, time_verify, time_attrs;
1255 #endif
1256
1257         RT_TIMING_GET_TIME(time_start);
1258
1259         /* Get the classbuffer's class. */
1260
1261         c = cb->class;
1262
1263         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1264                 return false;
1265
1266         /* check signature */
1267
1268         if (suck_u4(cb) != MAGIC) {
1269                 exceptions_throw_classformaterror(c, "Bad magic number");
1270                 return false;
1271         }
1272
1273         /* check version */
1274
1275         mi = suck_u2(cb);
1276         ma = suck_u2(cb);
1277
1278         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1279                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1280                 return false;
1281         }
1282
1283         RT_TIMING_GET_TIME(time_checks);
1284
1285         /* create a new descriptor pool */
1286
1287         descpool = descriptor_pool_new(c);
1288
1289         RT_TIMING_GET_TIME(time_ndpool);
1290
1291         /* load the constant pool */
1292
1293         if (!load_constantpool(cb, descpool))
1294                 return false;
1295
1296         RT_TIMING_GET_TIME(time_cpool);
1297
1298         /* ACC flags */
1299
1300         if (!suck_check_classbuffer_size(cb, 2))
1301                 return false;
1302
1303         /* We OR the flags here, as we set already some flags in
1304            class_create_classinfo. */
1305
1306         c->flags |= suck_u2(cb);
1307
1308         /* check ACC flags consistency */
1309
1310         if (c->flags & ACC_INTERFACE) {
1311                 if (!(c->flags & ACC_ABSTRACT)) {
1312                         /* We work around this because interfaces in JDK 1.1 are
1313                          * not declared abstract. */
1314
1315                         c->flags |= ACC_ABSTRACT;
1316                 }
1317
1318                 if (c->flags & ACC_FINAL) {
1319                         exceptions_throw_classformaterror(c,
1320                                                                                           "Illegal class modifiers: 0x%X",
1321                                                                                           c->flags);
1322                         return false;
1323                 }
1324
1325                 if (c->flags & ACC_SUPER) {
1326                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1327                 }
1328         }
1329
1330         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1331                 exceptions_throw_classformaterror(c,
1332                                                                                   "Illegal class modifiers: 0x%X",
1333                                                                                   c->flags);
1334                 return false;
1335         }
1336
1337         if (!suck_check_classbuffer_size(cb, 2 + 2))
1338                 return false;
1339
1340         /* this class */
1341
1342         i = suck_u2(cb);
1343
1344         if (!(name = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1345                 return false;
1346
1347         if (c->name == utf_not_named_yet) {
1348                 /* we finally have a name for this class */
1349                 c->name = name;
1350                 class_set_packagename(c);
1351         }
1352         else if (name != c->name) {
1353                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1354                 return false;
1355         }
1356
1357         /* retrieve superclass */
1358
1359         c->super.any = NULL;
1360
1361         if ((i = suck_u2(cb))) {
1362                 if (!(supername = (utf *) class_getconstant(c, i, CONSTANT_Class)))
1363                         return false;
1364
1365                 /* java.lang.Object may not have a super class. */
1366
1367                 if (c->name == utf_java_lang_Object) {
1368                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1369                         return false;
1370                 }
1371
1372                 /* Interfaces must have java.lang.Object as super class. */
1373
1374                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1375                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1376                         return false;
1377                 }
1378         }
1379         else {
1380                 supername = NULL;
1381
1382                 /* This is only allowed for java.lang.Object. */
1383
1384                 if (c->name != utf_java_lang_Object) {
1385                         exceptions_throw_classformaterror(c, "Bad superclass index");
1386                         return false;
1387                 }
1388         }
1389
1390         /* retrieve interfaces */
1391
1392         if (!suck_check_classbuffer_size(cb, 2))
1393                 return false;
1394
1395         c->interfacescount = suck_u2(cb);
1396
1397         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1398                 return false;
1399
1400         c->interfaces = MNEW(classref_or_classinfo, c->interfacescount);
1401
1402         for (i = 0; i < c->interfacescount; i++) {
1403                 /* the classrefs are created later */
1404                 if (!(c->interfaces[i].any = (utf *) class_getconstant(c, suck_u2(cb), CONSTANT_Class)))
1405                         return false;
1406         }
1407
1408         RT_TIMING_GET_TIME(time_setup);
1409
1410         /* load fields */
1411
1412         if (!suck_check_classbuffer_size(cb, 2))
1413                 return false;
1414
1415         c->fieldscount = suck_u2(cb);
1416         c->fields      = MNEW(fieldinfo, c->fieldscount);
1417
1418         MZERO(c->fields, fieldinfo, c->fieldscount);
1419
1420         for (i = 0; i < c->fieldscount; i++) {
1421                 if (!field_load(cb, &(c->fields[i]), descpool))
1422                         return false;
1423         }
1424
1425         RT_TIMING_GET_TIME(time_fields);
1426
1427         /* load methods */
1428
1429         if (!suck_check_classbuffer_size(cb, 2))
1430                 return false;
1431
1432         c->methodscount = suck_u2(cb);
1433         c->methods      = MNEW(methodinfo, c->methodscount);
1434
1435         MZERO(c->methods, methodinfo, c->methodscount);
1436         
1437         for (i = 0; i < c->methodscount; i++) {
1438                 if (!method_load(cb, &(c->methods[i]), descpool))
1439                         return false;
1440         }
1441
1442         RT_TIMING_GET_TIME(time_methods);
1443
1444         /* create the class reference table */
1445
1446         c->classrefs =
1447                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1448
1449         RT_TIMING_GET_TIME(time_classrefs);
1450
1451         /* allocate space for the parsed descriptors */
1452
1453         descriptor_pool_alloc_parsed_descriptors(descpool);
1454         c->parseddescs =
1455                 descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1456
1457 #if defined(ENABLE_STATISTICS)
1458         if (opt_stat) {
1459                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1460                 count_classref_len += classrefsize;
1461                 count_parsed_desc_len += descsize;
1462         }
1463 #endif
1464
1465         RT_TIMING_GET_TIME(time_descs);
1466
1467         /* put the classrefs in the constant pool */
1468         for (i = 0; i < c->cpcount; i++) {
1469                 if (c->cptags[i] == CONSTANT_Class) {
1470                         utf *name = (utf *) c->cpinfos[i];
1471                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1472                 }
1473         }
1474
1475         /* set the super class reference */
1476
1477         if (supername) {
1478                 c->super.ref = descriptor_pool_lookup_classref(descpool, supername);
1479                 if (!c->super.ref)
1480                         return false;
1481         }
1482
1483         /* set the super interfaces references */
1484
1485         for (i = 0; i < c->interfacescount; i++) {
1486                 c->interfaces[i].ref =
1487                         descriptor_pool_lookup_classref(descpool,
1488                                                                                         (utf *) c->interfaces[i].any);
1489                 if (!c->interfaces[i].ref)
1490                         return false;
1491         }
1492
1493         RT_TIMING_GET_TIME(time_setrefs);
1494
1495         /* parse field descriptors */
1496
1497         for (i = 0; i < c->fieldscount; i++) {
1498                 c->fields[i].parseddesc =
1499                         descriptor_pool_parse_field_descriptor(descpool,
1500                                                                                                    c->fields[i].descriptor);
1501                 if (!c->fields[i].parseddesc)
1502                         return false;
1503         }
1504
1505         RT_TIMING_GET_TIME(time_parsefds);
1506
1507         /* parse method descriptors */
1508
1509         for (i = 0; i < c->methodscount; i++) {
1510                 methodinfo *m = &c->methods[i];
1511                 m->parseddesc =
1512                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1513                                                                                                         m->flags, class_get_self_classref(m->class));
1514                 if (!m->parseddesc)
1515                         return false;
1516
1517                 for (j = 0; j < m->rawexceptiontablelength; j++) {
1518                         if (!m->rawexceptiontable[j].catchtype.any)
1519                                 continue;
1520
1521                         if ((m->rawexceptiontable[j].catchtype.ref =
1522                                  descriptor_pool_lookup_classref(descpool,
1523                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1524                                 return false;
1525                 }
1526
1527                 for (j = 0; j < m->thrownexceptionscount; j++) {
1528                         if (!m->thrownexceptions[j].any)
1529                                 continue;
1530
1531                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1532                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
1533                                 return false;
1534                 }
1535         }
1536
1537         RT_TIMING_GET_TIME(time_parsemds);
1538
1539         /* parse the loaded descriptors */
1540
1541         for (i = 0; i < c->cpcount; i++) {
1542                 constant_FMIref *fmi;
1543                 s4               index;
1544
1545                 switch (c->cptags[i]) {
1546                 case CONSTANT_Fieldref:
1547                         fmi = (constant_FMIref *) c->cpinfos[i];
1548                         fmi->parseddesc.fd =
1549                                 descriptor_pool_parse_field_descriptor(descpool,
1550                                                                                                            fmi->descriptor);
1551                         if (!fmi->parseddesc.fd)
1552                                 return false;
1553
1554                         index = fmi->p.index;
1555                         fmi->p.classref =
1556                                 (constant_classref *) class_getconstant(c, index,
1557                                                                                                                 CONSTANT_Class);
1558                         if (!fmi->p.classref)
1559                                 return false;
1560                         break;
1561                 case CONSTANT_Methodref:
1562                 case CONSTANT_InterfaceMethodref:
1563                         fmi = (constant_FMIref *) c->cpinfos[i];
1564                         index = fmi->p.index;
1565                         fmi->p.classref =
1566                                 (constant_classref *) class_getconstant(c, index,
1567                                                                                                                 CONSTANT_Class);
1568                         if (!fmi->p.classref)
1569                                 return false;
1570                         fmi->parseddesc.md =
1571                                 descriptor_pool_parse_method_descriptor(descpool,
1572                                                                                                                 fmi->descriptor,
1573                                                                                                                 ACC_UNDEF,
1574                                                                                                                 fmi->p.classref);
1575                         if (!fmi->parseddesc.md)
1576                                 return false;
1577                         break;
1578                 }
1579         }
1580
1581         RT_TIMING_GET_TIME(time_parsecpool);
1582
1583 #ifdef ENABLE_VERIFIER
1584         /* Check if all fields and methods can be uniquely
1585          * identified by (name,descriptor). */
1586
1587         if (opt_verify) {
1588                 /* We use a hash table here to avoid making the
1589                  * average case quadratic in # of methods, fields.
1590                  */
1591                 static int shift = 0;
1592                 u2 *hashtab;
1593                 u2 *next; /* for chaining colliding hash entries */
1594                 size_t len;
1595                 size_t hashlen;
1596                 u2 index;
1597                 u2 old;
1598
1599                 /* Allocate hashtable */
1600                 len = c->methodscount;
1601                 if (len < c->fieldscount) len = c->fieldscount;
1602                 hashlen = 5 * len;
1603                 hashtab = MNEW(u2,(hashlen + len));
1604                 next = hashtab + hashlen;
1605
1606                 /* Determine bitshift (to get good hash values) */
1607                 if (!shift) {
1608                         len = sizeof(utf);
1609                         while (len) {
1610                                 len >>= 1;
1611                                 shift++;
1612                         }
1613                 }
1614
1615                 /* Check fields */
1616                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1617
1618                 for (i = 0; i < c->fieldscount; ++i) {
1619                         fieldinfo *fi = c->fields + i;
1620
1621                         /* It's ok if we lose bits here */
1622                         index = ((((size_t) fi->name) +
1623                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
1624
1625                         if ((old = hashtab[index])) {
1626                                 old--;
1627                                 next[i] = old;
1628                                 do {
1629                                         if (c->fields[old].name == fi->name &&
1630                                                 c->fields[old].descriptor == fi->descriptor) {
1631                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1632                                                 return false;
1633                                         }
1634                                 } while ((old = next[old]));
1635                         }
1636                         hashtab[index] = i + 1;
1637                 }
1638
1639                 /* Check methods */
1640                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1641
1642                 for (i = 0; i < c->methodscount; ++i) {
1643                         methodinfo *mi = c->methods + i;
1644
1645                         /* It's ok if we lose bits here */
1646                         index = ((((size_t) mi->name) +
1647                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
1648
1649                         if ((old = hashtab[index])) {
1650                                 old--;
1651                                 next[i] = old;
1652                                 do {
1653                                         if (c->methods[old].name == mi->name &&
1654                                                 c->methods[old].descriptor == mi->descriptor) {
1655                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1656                                                 return false;
1657                                         }
1658                                 } while ((old = next[old]));
1659                         }
1660                         hashtab[index] = i + 1;
1661                 }
1662
1663                 MFREE(hashtab, u2, (hashlen + len));
1664         }
1665 #endif /* ENABLE_VERIFIER */
1666
1667         RT_TIMING_GET_TIME(time_verify);
1668
1669 #if defined(ENABLE_STATISTICS)
1670         if (opt_stat) {
1671                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
1672                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
1673                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1674         }
1675 #endif
1676
1677         /* load attribute structures */
1678
1679         if (!class_load_attributes(cb))
1680                 return false;
1681
1682         /* Pre Java 1.5 version don't check this. This implementation is
1683            like Java 1.5 do it: for class file version 45.3 we don't check
1684            it, older versions are checked. */
1685
1686         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1687                 /* check if all data has been read */
1688                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1689
1690                 if (classdata_left > 0) {
1691                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1692                         return false;
1693                 }
1694         }
1695
1696         RT_TIMING_GET_TIME(time_attrs);
1697
1698         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
1699         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
1700         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
1701         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
1702         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
1703         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
1704         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1705         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
1706         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
1707         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
1708         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
1709         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1710         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
1711         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
1712         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
1713
1714         return true;
1715 }
1716
1717
1718 /* load_class_from_classbuffer *************************************************
1719
1720    Convenience wrapper for load_class_from_classbuffer.
1721
1722    SYNCHRONIZATION:
1723        This function is NOT synchronized!
1724    
1725 *******************************************************************************/
1726
1727 classinfo *load_class_from_classbuffer(classbuffer *cb)
1728 {
1729         classinfo *c;
1730         int32_t    dumpsize;
1731         bool       result;
1732
1733         /* Get the classbuffer's class. */
1734
1735         c = cb->class;
1736
1737         /* Check if the class is already loaded. */
1738
1739         if (c->state & CLASS_LOADED)
1740                 return c;
1741
1742 #if defined(ENABLE_STATISTICS)
1743         if (opt_stat)
1744                 count_class_loads++;
1745 #endif
1746
1747 #if !defined(NDEBUG)
1748         if (loadverbose)
1749                 log_message_class("Loading class: ", c);
1750 #endif
1751
1752         /* Mark start of dump memory area. */
1753
1754         dumpsize = dump_size();
1755
1756         /* Class is currently loading. */
1757
1758         c->state |= CLASS_LOADING;
1759
1760         /* Parse the classbuffer. */
1761
1762         result = load_class_from_classbuffer_intern(cb);
1763
1764         /* Release dump area. */
1765
1766         dump_release(dumpsize);
1767
1768         /* An error occurred. */
1769
1770         if (result == false) {
1771                 /* Revert loading state. */
1772
1773                 c->state = (c->state & ~CLASS_LOADING);
1774
1775                 return NULL;
1776         }
1777
1778         /* Revert loading state and set loaded. */
1779
1780         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
1781
1782 #if defined(ENABLE_JVMTI)
1783         /* fire Class Prepare JVMTI event */
1784
1785         if (jvmti)
1786                 jvmti_ClassLoadPrepare(true, c);
1787 #endif
1788
1789 #if !defined(NDEBUG)
1790         if (loadverbose)
1791                 log_message_class("Loading done class: ", c);
1792 #endif
1793
1794         return c;
1795 }
1796
1797
1798 /* load_newly_created_array ****************************************************
1799
1800    Load a newly created array class.
1801
1802         RETURN VALUE:
1803             c....................the array class C has been loaded
1804                 other classinfo......the array class was found in the class cache, 
1805                                      C has been freed
1806             NULL.................an exception has been thrown
1807
1808         Note:
1809                 This is an internal function. Do not use it unless you know exactly
1810                 what you are doing!
1811
1812                 Use one of the load_class_... functions for general array class loading.
1813
1814 *******************************************************************************/
1815
1816 classinfo *load_newly_created_array(classinfo *c, classloader *loader)
1817 {
1818         classinfo         *comp = NULL;
1819         methodinfo        *clone;
1820         methoddesc        *clonedesc;
1821         constant_classref *classrefs;
1822         char              *text;
1823         s4                 namelen;
1824         utf               *u;
1825
1826         text    = c->name->text;
1827         namelen = c->name->blength;
1828
1829         /* Check array class name */
1830
1831         if ((namelen < 2) || (text[0] != '[')) {
1832                 exceptions_throw_classnotfoundexception(c->name);
1833                 return NULL;
1834         }
1835
1836         /* Check the element type */
1837
1838         switch (text[1]) {
1839         case '[':
1840                 /* c is an array of arrays. We have to create the component class. */
1841
1842                 u = utf_new(text + 1, namelen - 1);
1843
1844                 comp = load_class_from_classloader(u, loader);
1845
1846                 if (comp == NULL)
1847                         return NULL;
1848
1849                 assert(comp->state & CLASS_LOADED);
1850
1851                 /* the array's flags are that of the component class */
1852                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1853                 c->classloader = comp->classloader;
1854                 break;
1855
1856         case 'L':
1857                 /* c is an array of objects. */
1858
1859                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1860                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
1861                         exceptions_throw_classnotfoundexception(c->name);
1862                         return NULL;
1863                 }
1864
1865                 u = utf_new(text + 2, namelen - 3);
1866
1867                 if (!(comp = load_class_from_classloader(u, loader)))
1868                         return NULL;
1869
1870                 assert(comp->state & CLASS_LOADED);
1871
1872                 /* the array's flags are that of the component class */
1873                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
1874                 c->classloader = comp->classloader;
1875                 break;
1876
1877         default:
1878                 /* c is an array of a primitive type */
1879
1880                 /* check for cases like `[II' and whether the character is a
1881                    valid primitive type */
1882
1883                 if ((namelen > 2) || (primitive_class_get_by_char(text[1]) == NULL)) {
1884                         exceptions_throw_classnotfoundexception(c->name);
1885                         return NULL;
1886                 }
1887
1888                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
1889                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
1890                 c->classloader = NULL;
1891         }
1892
1893         assert(class_java_lang_Object);
1894 #if defined(ENABLE_JAVASE)
1895         assert(class_java_lang_Cloneable);
1896         assert(class_java_io_Serializable);
1897 #endif
1898
1899         /* setup the array class */
1900
1901         c->super.cls = class_java_lang_Object;
1902
1903 #if defined(ENABLE_JAVASE)
1904
1905         c->interfacescount   = 2;
1906     c->interfaces        = MNEW(classref_or_classinfo, 2);
1907         c->interfaces[0].cls = class_java_lang_Cloneable;
1908         c->interfaces[1].cls = class_java_io_Serializable;
1909
1910 #elif defined(ENABLE_JAVAME_CLDC1_1)
1911
1912         c->interfacescount   = 0;
1913         c->interfaces        = NULL;
1914
1915 #else
1916 # error unknow Java configuration
1917 #endif
1918
1919         c->methodscount = 1;
1920         c->methods = MNEW(methodinfo, c->methodscount);
1921         MZERO(c->methods, methodinfo, c->methodscount);
1922
1923         classrefs = MNEW(constant_classref, 2);
1924         CLASSREF_INIT(classrefs[0], c, c->name);
1925         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
1926
1927         /* create descriptor for clone method */
1928         /* we need one paramslot which is reserved for the 'this' parameter */
1929         clonedesc = NEW(methoddesc);
1930         clonedesc->returntype.type = TYPE_ADR;
1931         clonedesc->returntype.classref = classrefs + 1;
1932         clonedesc->returntype.arraydim = 0;
1933         /* initialize params to "empty", add real params below in
1934            descriptor_params_from_paramtypes */
1935         clonedesc->paramcount = 0;
1936         clonedesc->paramslots = 0;
1937         clonedesc->paramtypes[0].classref = classrefs + 0;
1938         clonedesc->params = NULL;
1939
1940         /* create methodinfo */
1941
1942         clone = c->methods;
1943         MSET(clone, 0, methodinfo, 1);
1944
1945 #if defined(ENABLE_THREADS)
1946         lock_init_object_lock(&clone->header);
1947 #endif
1948
1949         /* ATTENTION: if you delete the ACC_NATIVE below, set
1950            clone->maxlocals=1 (interpreter related) */
1951
1952         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
1953         clone->name       = utf_clone;
1954         clone->descriptor = utf_void__java_lang_Object;
1955         clone->parseddesc = clonedesc;
1956         clone->class      = c;
1957
1958         /* parse the descriptor to get the register allocation */
1959
1960         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
1961                 return false;
1962
1963         clone->code = codegen_generate_stub_native(clone, BUILTIN_clone);
1964
1965         /* XXX: field: length? */
1966
1967         /* array classes are not loaded from class files */
1968
1969         c->state          |= CLASS_LOADED;
1970         c->parseddescs    = (u1 *) clonedesc;
1971         c->parseddescsize = sizeof(methodinfo);
1972         c->classrefs      = classrefs;
1973         c->classrefcount  = 1;
1974
1975         /* insert class into the loaded class cache */
1976         /* XXX free classinfo if NULL returned? */
1977
1978         return classcache_store(loader, c, true);
1979 }
1980
1981
1982 /* loader_close ****************************************************************
1983
1984    Frees all resources.
1985         
1986 *******************************************************************************/
1987
1988 void loader_close(void)
1989 {
1990         /* empty */
1991 }
1992
1993
1994 /*
1995  * These are local overrides for various environment variables in Emacs.
1996  * Please do not remove this and leave it at the end of the file, where
1997  * Emacs will automagically detect them.
1998  * ---------------------------------------------------------------------
1999  * Local variables:
2000  * mode: c
2001  * indent-tabs-mode: t
2002  * c-basic-offset: 4
2003  * tab-width: 4
2004  * End:
2005  * vim:noexpandtab:sw=4:ts=4:
2006  */