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