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