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