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