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