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