Fixes PR126.
[cacao.git] / src / vm / loader.cpp
1 /* src/vm/loader.cpp - class loader functions
2
3    Copyright (C) 1996-2005, 2006, 2007, 2008
4    CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
5    Copyright (C) 2009 Theobroma Systems Ltd.
6
7    This file is part of CACAO.
8
9    This program is free software; you can redistribute it and/or
10    modify it under the terms of the GNU General Public License as
11    published by the Free Software Foundation; either version 2, or (at
12    your option) any later version.
13
14    This program is distributed in the hope that it will be useful, but
15    WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    General Public License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22    02110-1301, USA.
23
24 */
25
26
27 #include "config.h"
28
29 #include <stdlib.h>
30 #include <string.h>
31 #include <assert.h>
32
33 #include "vm/types.h"
34
35 #include "mm/dumpmemory.hpp"
36 #include "mm/memory.hpp"
37
38 #include "native/llni.h"
39
40 #include "threads/mutex.hpp"
41
42 #include "toolbox/hashtable.h"
43 #include "toolbox/logging.hpp"
44
45 #include "vm/jit/builtin.hpp"
46 #include "vm/classcache.hpp"
47 #include "vm/exceptions.hpp"
48 #include "vm/field.hpp"
49 #include "vm/global.h"
50 #include "vm/globals.hpp"
51 #include "vm/linker.hpp"
52 #include "vm/loader.hpp"
53 #include "vm/method.hpp"
54 #include "vm/options.h"
55 #include "vm/package.hpp"
56 #include "vm/primitive.hpp"
57 #include "vm/resolve.hpp"
58 #include "vm/rt-timing.h"
59 #include "vm/string.hpp"
60 #include "vm/suck.hpp"
61 #include "vm/vm.hpp"
62
63
64 #if defined(ENABLE_JAVASE)
65 # include "vm/annotation.hpp"
66 # include "vm/stackmap.h"
67 #endif
68
69 #if defined(ENABLE_STATISTICS)
70 # include "vm/statistics.h"
71 #endif
72
73 #if defined(ENABLE_ZLIB)
74 # include "vm/zip.hpp"
75 #endif
76
77 #include "vm/jit/stubs.hpp"
78
79 #if defined(ENABLE_JVMTI)
80 # include "native/jvmti/cacaodbg.h"
81 #endif
82
83
84 /* global variables ***********************************************************/
85
86 static hashtable *hashtable_classloader;
87
88
89 /* loader_preinit **************************************************************
90
91    Initializes the classpath list and loads classes required for the
92    primitive table.
93
94    NOTE: Exceptions thrown during VM initialization are caught in the
95          exception functions themselves.
96
97 *******************************************************************************/
98  
99 void loader_preinit(void)
100 {
101         TRACESUBSYSTEMINITIALIZATION("loader_preinit");
102
103 #if defined(ENABLE_THREADS)
104         // Get current list of classpath entries.
105         SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
106
107         /* Initialize the monitor pointer for zip/jar file locking. */
108
109         for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
110                 list_classpath_entry* lce = *it;
111
112                 if (lce->type == CLASSPATH_ARCHIVE)
113                         lce->mutex = new Mutex();
114         }
115 #endif
116
117         /* initialize classloader hashtable, 10 entries should be enough */
118
119         hashtable_classloader = NEW(hashtable);
120         hashtable_create(hashtable_classloader, 10);
121
122         /* Load the most basic classes. */
123
124         assert(VM::get_current()->is_initializing() == true);
125
126         class_java_lang_Object     = load_class_bootstrap(utf_java_lang_Object);
127
128 #if defined(ENABLE_JAVASE)
129         class_java_lang_Cloneable  = load_class_bootstrap(utf_java_lang_Cloneable);
130         class_java_io_Serializable = load_class_bootstrap(utf_java_io_Serializable);
131 #endif
132 }
133
134
135 /* loader_init *****************************************************************
136
137    Loads all classes required in the VM.
138
139    NOTE: Exceptions thrown during VM initialization are caught in the
140          exception functions themselves.
141
142 *******************************************************************************/
143  
144 void loader_init(void)
145 {
146         TRACESUBSYSTEMINITIALIZATION("loader_init");
147
148         /* Load primitive-type wrapping classes. */
149
150         assert(VM::get_current()->is_initializing() == true);
151
152 #if defined(ENABLE_JAVASE)
153         class_java_lang_Void       = load_class_bootstrap(utf_java_lang_Void);
154 #endif
155
156         class_java_lang_Boolean    = load_class_bootstrap(utf_java_lang_Boolean);
157         class_java_lang_Byte       = load_class_bootstrap(utf_java_lang_Byte);
158         class_java_lang_Character  = load_class_bootstrap(utf_java_lang_Character);
159         class_java_lang_Short      = load_class_bootstrap(utf_java_lang_Short);
160         class_java_lang_Integer    = load_class_bootstrap(utf_java_lang_Integer);
161         class_java_lang_Long       = load_class_bootstrap(utf_java_lang_Long);
162         class_java_lang_Float      = load_class_bootstrap(utf_java_lang_Float);
163         class_java_lang_Double     = load_class_bootstrap(utf_java_lang_Double);
164
165         /* Load important system classes. */
166
167         class_java_lang_Class      = load_class_bootstrap(utf_java_lang_Class);
168         class_java_lang_String     = load_class_bootstrap(utf_java_lang_String);
169
170 #if defined(ENABLE_JAVASE)
171         class_java_lang_ClassLoader =
172                 load_class_bootstrap(utf_java_lang_ClassLoader);
173
174         class_java_lang_SecurityManager =
175                 load_class_bootstrap(utf_java_lang_SecurityManager);
176 #endif
177
178         class_java_lang_System     =
179                 load_class_bootstrap(utf_new_char("java/lang/System"));
180
181         class_java_lang_Thread     =
182                 load_class_bootstrap(utf_new_char("java/lang/Thread"));
183
184 #if defined(ENABLE_JAVASE)
185         class_java_lang_ThreadGroup =
186                 load_class_bootstrap(utf_java_lang_ThreadGroup);
187 #endif
188
189         class_java_lang_Throwable  = load_class_bootstrap(utf_java_lang_Throwable);
190
191 #if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
192         class_java_lang_VMSystem   =
193                 load_class_bootstrap(utf_new_char("java/lang/VMSystem"));
194
195         class_java_lang_VMThread   =
196                 load_class_bootstrap(utf_new_char("java/lang/VMThread"));
197
198         class_java_lang_VMThrowable =
199                 load_class_bootstrap(utf_new_char("java/lang/VMThrowable"));
200 #endif
201
202         /* Important system exceptions. */
203
204         class_java_lang_Exception  = load_class_bootstrap(utf_java_lang_Exception);
205
206         class_java_lang_ClassNotFoundException =
207                 load_class_bootstrap(utf_java_lang_ClassNotFoundException);
208
209         class_java_lang_RuntimeException =
210                 load_class_bootstrap(utf_java_lang_RuntimeException);
211
212         /* Some classes which may be used often. */
213
214 #if defined(ENABLE_JAVASE)
215         class_java_lang_StackTraceElement      = load_class_bootstrap(utf_java_lang_StackTraceElement);
216
217         class_java_lang_reflect_Constructor    = load_class_bootstrap(utf_java_lang_reflect_Constructor);
218         class_java_lang_reflect_Field          = load_class_bootstrap(utf_java_lang_reflect_Field);
219         class_java_lang_reflect_Method         = load_class_bootstrap(utf_java_lang_reflect_Method);
220
221 # if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
222         class_java_lang_reflect_VMConstructor  = load_class_bootstrap(utf_java_lang_reflect_VMConstructor);
223         class_java_lang_reflect_VMField        = load_class_bootstrap(utf_java_lang_reflect_VMField);
224         class_java_lang_reflect_VMMethod       = load_class_bootstrap(utf_java_lang_reflect_VMMethod);
225 # endif
226
227         class_java_security_PrivilegedAction   = load_class_bootstrap(utf_new_char("java/security/PrivilegedAction"));
228
229         class_java_util_HashMap                = load_class_bootstrap(utf_new_char("java/util/HashMap"));
230         class_java_util_Vector                 = load_class_bootstrap(utf_java_util_Vector);
231
232 # if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
233         class_sun_misc_Signal                  = load_class_bootstrap(utf_new_char("sun/misc/Signal"));
234         class_sun_reflect_MagicAccessorImpl    = load_class_bootstrap(utf_new_char("sun/reflect/MagicAccessorImpl"));
235 # endif
236
237         arrayclass_java_lang_Object =
238                 load_class_bootstrap(utf_new_char("[Ljava/lang/Object;"));
239
240 # if defined(ENABLE_ANNOTATIONS)
241         /* needed by annotation support */
242         class_sun_reflect_ConstantPool =
243                 load_class_bootstrap(utf_new_char("sun/reflect/ConstantPool"));
244
245 #  if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
246         /* needed by GNU Classpaths annotation support */
247         class_sun_reflect_annotation_AnnotationParser =
248                 load_class_bootstrap(utf_new_char("sun/reflect/annotation/AnnotationParser"));
249 #  endif
250 # endif
251 #endif
252 }
253
254
255 /* loader_hashtable_classloader_add ********************************************
256
257    Adds an entry to the classloader hashtable.
258
259    REMEMBER: Also use this to register native loaders!
260
261 *******************************************************************************/
262
263 classloader_t *loader_hashtable_classloader_add(java_handle_t *cl)
264 {
265         hashtable_classloader_entry *cle;
266         u4   key;
267         u4   slot;
268
269         if (cl == NULL)
270                 return NULL;
271
272         hashtable_classloader->mutex->lock();
273
274         LLNI_CRITICAL_START;
275
276         /* key for entry is the hashcode of the classloader;
277            aligned to 16-byte boundaries */
278
279         key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
280         slot = key & (hashtable_classloader->size - 1);
281         cle  = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
282
283         /* search hashchain for existing entry */
284
285         while (cle) {
286                 if (cle->object == LLNI_DIRECT(cl))
287                         break;
288
289                 cle = cle->hashlink;
290         }
291
292         LLNI_CRITICAL_END;
293
294         /* if no classloader was found, we create a new entry here */
295
296         if (cle == NULL) {
297                 cle = NEW(hashtable_classloader_entry);
298
299 #if defined(ENABLE_GC_CACAO)
300                 /* register the classloader object with the GC */
301
302                 gc_reference_register(&(cle->object), GC_REFTYPE_CLASSLOADER);
303 #endif
304
305                 LLNI_CRITICAL_START;
306
307                 cle->object = LLNI_DIRECT(cl);
308
309                 LLNI_CRITICAL_END;
310
311 /*#define LOADER_DEBUG_CLASSLOADER*/
312 #ifdef LOADER_DEBUG_CLASSLOADER
313                 printf("CLASSLOADER: adding new classloader entry %p for %p: ", cle, cl);
314                 class_print(LLNI_vftbl_direct(cl)->class);
315                 printf("\n");
316                 fflush(stdout);
317 #endif
318
319                 /* insert entry into hashtable */
320
321                 cle->hashlink = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
322                 hashtable_classloader->ptr[slot] = cle;
323
324                 /* update number of entries */
325
326                 hashtable_classloader->entries++;
327         }
328
329         hashtable_classloader->mutex->unlock();
330
331 #if defined(ENABLE_HANDLES)
332         return cle;
333 #else
334         return cl;
335 #endif
336 }
337
338
339 /* loader_hashtable_classloader_find *******************************************
340
341    Find an entry in the classloader hashtable.
342
343 *******************************************************************************/
344
345 classloader_t *loader_hashtable_classloader_find(java_handle_t *cl)
346 {
347         hashtable_classloader_entry *cle;
348         u4   key;
349         u4   slot;
350
351         if (cl == NULL)
352                 return NULL;
353
354         LLNI_CRITICAL_START;
355
356         /* key for entry is the hashcode of the classloader;
357            aligned to 16-byte boundaries */
358
359         key  = heap_hashcode(LLNI_DIRECT(cl)) >> 4;
360         slot = key & (hashtable_classloader->size - 1);
361         cle  = (hashtable_classloader_entry*) hashtable_classloader->ptr[slot];
362
363         /* search hashchain for existing entry */
364
365         while (cle) {
366                 if (cle->object == LLNI_DIRECT(cl))
367                         break;
368
369                 cle = cle->hashlink;
370         }
371
372 #ifdef LOADER_DEBUG_CLASSLOADER
373         if (cle == NULL) {
374                 printf("CLASSLOADER: unable to find classloader entry for %p: ", cl);
375                 class_print(LLNI_vftbl_direct(cl)->class);
376                 printf("\n");
377                 fflush(stdout);
378         }
379 #endif
380
381         LLNI_CRITICAL_END;
382
383 #if defined(ENABLE_HANDLES)
384         return cle;
385 #else
386         return cl;
387 #endif
388 }
389
390
391 /* loader_load_all_classes *****************************************************
392
393    Loads all classes specified in the BOOTCLASSPATH.
394
395 *******************************************************************************/
396
397 void loader_load_all_classes(void)
398 {
399 #if defined(ENABLE_ZLIB)
400         hashtable               *ht;
401         hashtable_zipfile_entry *htzfe;
402         utf                     *u;
403 #endif
404
405         // Get current list of classpath entries.
406         SuckClasspath& suckclasspath = VM::get_current()->get_suckclasspath();
407
408         for (SuckClasspath::iterator it = suckclasspath.begin(); it != suckclasspath.end(); it++) {
409                 list_classpath_entry* lce = *it;
410
411 #if defined(ENABLE_ZLIB)
412                 if (lce->type == CLASSPATH_ARCHIVE) {
413                         /* get the classes hashtable */
414
415                         ht = lce->htclasses;
416
417                         for (uint32_t slot = 0; slot < ht->size; slot++) {
418                                 htzfe = (hashtable_zipfile_entry *) ht->ptr[slot];
419
420                                 for (; htzfe; htzfe = htzfe->hashlink) {
421                                         u = htzfe->filename;
422
423                                         /* skip all entries in META-INF and .properties,
424                        .png files */
425
426                                         if (!strncmp(u->text, "META-INF", strlen("META-INF")) ||
427                                                 strstr(u->text, ".properties") ||
428                                                 strstr(u->text, ".png"))
429                                                 continue;
430
431                                         /* load class from bootstrap classloader */
432
433                                         if (!load_class_bootstrap(u)) {
434                                                 fprintf(stderr, "Error loading: ");
435                                                 utf_fprint_printable_ascii_classname(stderr, u);
436                                                 fprintf(stderr, "\n");
437
438 #if !defined(NDEBUG)
439                                                 /* print out exception and cause */
440
441                                                 exceptions_print_current_exception();
442 #endif
443                                         }
444                                 }
445                         }
446
447                 } else {
448 #endif
449 #if defined(ENABLE_ZLIB)
450                 }
451 #endif
452         }
453 }
454
455
456 /* loader_skip_attribute_body **************************************************
457
458    Skips an attribute the attribute_name_index has already been read.
459         
460    attribute_info {
461        u2 attribute_name_index;
462        u4 attribute_length;
463        u1 info[attribute_length];
464    }
465
466 *******************************************************************************/
467
468 bool loader_skip_attribute_body(classbuffer *cb)
469 {
470         u4 attribute_length;
471
472         if (!suck_check_classbuffer_size(cb, 4))
473                 return false;
474
475         attribute_length = suck_u4(cb);
476
477         if (!suck_check_classbuffer_size(cb, attribute_length))
478                 return false;
479
480         suck_skip_nbytes(cb, attribute_length);
481
482         return true;
483 }
484
485
486 /* load_constantpool ***********************************************************
487
488    Loads the constantpool of a class, the entries are transformed into
489    a simpler format by resolving references (a detailed overview of
490    the compact structures can be found in global.h).
491
492 *******************************************************************************/
493
494 static bool load_constantpool(classbuffer *cb, descriptor_pool *descpool)
495 {
496
497         /* The following structures are used to save information which cannot be 
498            processed during the first pass. After the complete constantpool has 
499            been traversed the references can be resolved. 
500            (only in specific order)                                                */
501         
502         /* CONSTANT_Class entries */
503         typedef struct forward_class {
504                 struct forward_class *next;
505                 u2 thisindex;
506                 u2 name_index;
507         } forward_class;
508
509         /* CONSTANT_String */
510         typedef struct forward_string {
511                 struct forward_string *next;
512                 u2 thisindex;
513                 u2 string_index;
514         } forward_string;
515
516         /* CONSTANT_NameAndType */
517         typedef struct forward_nameandtype {
518                 struct forward_nameandtype *next;
519                 u2 thisindex;
520                 u2 name_index;
521                 u2 sig_index;
522         } forward_nameandtype;
523
524         /* CONSTANT_Fieldref, CONSTANT_Methodref or CONSTANT_InterfaceMethodref */
525         typedef struct forward_fieldmethint {
526                 struct forward_fieldmethint *next;
527                 u2 thisindex;
528                 u1 tag;
529                 u2 class_index;
530                 u2 nameandtype_index;
531         } forward_fieldmethint;
532
533
534         classinfo *c;
535         u4 idx;
536
537         forward_class *forward_classes = NULL;
538         forward_string *forward_strings = NULL;
539         forward_nameandtype *forward_nameandtypes = NULL;
540         forward_fieldmethint *forward_fieldmethints = NULL;
541
542         forward_class *nfc;
543         forward_string *nfs;
544         forward_nameandtype *nfn;
545         forward_fieldmethint *nff;
546
547         u4 cpcount;
548         u1 *cptags;
549         void** cpinfos;
550
551         c = cb->clazz;
552
553         /* number of entries in the constant_pool table plus one */
554         if (!suck_check_classbuffer_size(cb, 2))
555                 return false;
556
557         cpcount = c->cpcount = suck_u2(cb);
558
559         /* allocate memory */
560         cptags  = c->cptags  = MNEW(u1, cpcount);
561         cpinfos = c->cpinfos = MNEW(void*, cpcount);
562
563         if (cpcount < 1) {
564                 exceptions_throw_classformaterror(c, "Illegal constant pool size");
565                 return false;
566         }
567         
568 #if defined(ENABLE_STATISTICS)
569         if (opt_stat)
570                 count_const_pool_len += (sizeof(u1) + sizeof(void*)) * cpcount;
571 #endif
572         
573         /* initialize constantpool */
574         for (idx = 0; idx < cpcount; idx++) {
575                 cptags[idx] = CONSTANT_UNUSED;
576                 cpinfos[idx] = NULL;
577         }
578
579                         
580         /******* first pass *******/
581         /* entries which cannot be resolved now are written into 
582            temporary structures and traversed again later        */
583                    
584         idx = 1;
585         while (idx < cpcount) {
586                 u4 t;
587
588                 /* get constant type */
589                 if (!suck_check_classbuffer_size(cb, 1))
590                         return false;
591
592                 t = suck_u1(cb);
593
594                 switch (t) {
595                 case CONSTANT_Class:
596 #warning Use list.
597                         nfc = (forward_class*) DumpMemory::allocate(sizeof(forward_class));
598
599                         nfc->next = forward_classes;
600                         forward_classes = nfc;
601
602                         nfc->thisindex = idx;
603                         /* reference to CONSTANT_NameAndType */
604                         if (!suck_check_classbuffer_size(cb, 2))
605                                 return false;
606
607                         nfc->name_index = suck_u2(cb);
608
609                         idx++;
610                         break;
611                         
612                 case CONSTANT_String:
613 #warning Use list.
614                         nfs = (forward_string*) DumpMemory::allocate(sizeof(forward_string));
615                                 
616                         nfs->next = forward_strings;
617                         forward_strings = nfs;
618                                 
619                         nfs->thisindex = idx;
620
621                         /* reference to CONSTANT_Utf8_info with string characters */
622                         if (!suck_check_classbuffer_size(cb, 2))
623                                 return false;
624
625                         nfs->string_index = suck_u2(cb);
626                                 
627                         idx++;
628                         break;
629
630                 case CONSTANT_NameAndType:
631 #warning Use list.
632                         nfn = (forward_nameandtype*) DumpMemory::allocate(sizeof(forward_nameandtype));
633                                 
634                         nfn->next = forward_nameandtypes;
635                         forward_nameandtypes = nfn;
636                                 
637                         nfn->thisindex = idx;
638
639                         if (!suck_check_classbuffer_size(cb, 2 + 2))
640                                 return false;
641
642                         /* reference to CONSTANT_Utf8_info containing simple name */
643                         nfn->name_index = suck_u2(cb);
644
645                         /* reference to CONSTANT_Utf8_info containing field or method
646                            descriptor */
647                         nfn->sig_index = suck_u2(cb);
648                                 
649                         idx++;
650                         break;
651
652                 case CONSTANT_Fieldref:
653                 case CONSTANT_Methodref:
654                 case CONSTANT_InterfaceMethodref:
655 #warning Use list.
656                         nff = (forward_fieldmethint*) DumpMemory::allocate(sizeof(forward_fieldmethint));
657                         
658                         nff->next = forward_fieldmethints;
659                         forward_fieldmethints = nff;
660
661                         nff->thisindex = idx;
662                         /* constant type */
663                         nff->tag = t;
664
665                         if (!suck_check_classbuffer_size(cb, 2 + 2))
666                                 return false;
667
668                         /* class or interface type that contains the declaration of the
669                            field or method */
670                         nff->class_index = suck_u2(cb);
671
672                         /* name and descriptor of the field or method */
673                         nff->nameandtype_index = suck_u2(cb);
674
675                         idx++;
676                         break;
677                                 
678                 case CONSTANT_Integer: {
679                         constant_integer *ci = NEW(constant_integer);
680
681 #if defined(ENABLE_STATISTICS)
682                         if (opt_stat)
683                                 count_const_pool_len += sizeof(constant_integer);
684 #endif
685
686                         if (!suck_check_classbuffer_size(cb, 4))
687                                 return false;
688
689                         ci->value = suck_s4(cb);
690                         cptags[idx] = CONSTANT_Integer;
691                         cpinfos[idx] = ci;
692
693                         idx++;
694                         break;
695                 }
696                                 
697                 case CONSTANT_Float: {
698                         constant_float *cf = NEW(constant_float);
699
700 #if defined(ENABLE_STATISTICS)
701                         if (opt_stat)
702                                 count_const_pool_len += sizeof(constant_float);
703 #endif
704
705                         if (!suck_check_classbuffer_size(cb, 4))
706                                 return false;
707
708                         cf->value = suck_float(cb);
709                         cptags[idx] = CONSTANT_Float;
710                         cpinfos[idx] = cf;
711
712                         idx++;
713                         break;
714                 }
715                                 
716                 case CONSTANT_Long: {
717                         constant_long *cl = NEW(constant_long);
718                                         
719 #if defined(ENABLE_STATISTICS)
720                         if (opt_stat)
721                                 count_const_pool_len += sizeof(constant_long);
722 #endif
723
724                         if (!suck_check_classbuffer_size(cb, 8))
725                                 return false;
726
727                         cl->value = suck_s8(cb);
728                         cptags[idx] = CONSTANT_Long;
729                         cpinfos[idx] = cl;
730                         idx += 2;
731                         if (idx > cpcount) {
732                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
733                                 return false;
734                         }
735                         break;
736                 }
737                         
738                 case CONSTANT_Double: {
739                         constant_double *cd = NEW(constant_double);
740                                 
741 #if defined(ENABLE_STATISTICS)
742                         if (opt_stat)
743                                 count_const_pool_len += sizeof(constant_double);
744 #endif
745
746                         if (!suck_check_classbuffer_size(cb, 8))
747                                 return false;
748
749                         cd->value = suck_double(cb);
750                         cptags[idx] = CONSTANT_Double;
751                         cpinfos[idx] = cd;
752                         idx += 2;
753                         if (idx > cpcount) {
754                                 exceptions_throw_classformaterror(c, "Invalid constant pool entry");
755                                 return false;
756                         }
757                         break;
758                 }
759                                 
760                 case CONSTANT_Utf8: { 
761                         u4 length;
762
763                         /* number of bytes in the bytes array (not string-length) */
764                         if (!suck_check_classbuffer_size(cb, 2))
765                                 return false;
766
767                         length = suck_u2(cb);
768                         cptags[idx] = CONSTANT_Utf8;
769
770                         /* validate the string */
771                         if (!suck_check_classbuffer_size(cb, length))
772                                 return false;
773
774 #ifdef ENABLE_VERIFIER
775                         if (opt_verify &&
776                                 !is_valid_utf((char *) cb->pos, (char *) (cb->pos + length))) 
777                         {
778                                 exceptions_throw_classformaterror(c, "Invalid UTF-8 string");
779                                 return false;
780                         }
781 #endif /* ENABLE_VERIFIER */
782                         /* insert utf-string into the utf-symboltable */
783                         cpinfos[idx] = utf_new((char *) cb->pos, length);
784
785                         /* skip bytes of the string (buffer size check above) */
786                         suck_skip_nbytes(cb, length);
787                         idx++;
788                         break;
789                 }
790                                                                                 
791                 default:
792                         exceptions_throw_classformaterror(c, "Illegal constant pool type");
793                         return false;
794                 }  /* end switch */
795         } /* end while */
796
797
798         /* resolve entries in temporary structures */
799
800         while (forward_classes) {
801                 utf *name = (utf*) class_getconstant(c, forward_classes->name_index, CONSTANT_Utf8);
802                 if (!name)
803                         return false;
804
805 #ifdef ENABLE_VERIFIER
806                 if (opt_verify && !is_valid_name_utf(name)) {
807                         exceptions_throw_classformaterror(c, "Class reference with invalid name");
808                         return false;
809                 }
810 #endif /* ENABLE_VERIFIER */
811
812                 /* add all class references to the descriptor_pool */
813
814                 if (!descriptor_pool_add_class(descpool, name))
815                         return false;
816
817                 cptags[forward_classes->thisindex] = CONSTANT_Class;
818
819                 /* the classref is created later */
820                 cpinfos[forward_classes->thisindex] = name;
821
822                 nfc = forward_classes;
823                 forward_classes = forward_classes->next;
824         }
825
826         while (forward_strings) {
827                 utf *text = (utf*) class_getconstant(c, forward_strings->string_index, CONSTANT_Utf8);
828
829                 if (!text)
830                         return false;
831
832                 /* resolve utf-string */
833                 cptags[forward_strings->thisindex] = CONSTANT_String;
834                 cpinfos[forward_strings->thisindex] = text;
835                 
836                 nfs = forward_strings;
837                 forward_strings = forward_strings->next;
838         }
839
840         while (forward_nameandtypes) {
841                 constant_nameandtype *cn = NEW(constant_nameandtype);   
842
843 #if defined(ENABLE_STATISTICS)
844                 if (opt_stat)
845                         count_const_pool_len += sizeof(constant_nameandtype);
846 #endif
847
848                 /* resolve simple name and descriptor */
849                 cn->name = (utf*) class_getconstant(c,
850                                                                                         forward_nameandtypes->name_index,
851                                                                                         CONSTANT_Utf8);
852                 if (!cn->name)
853                         return false;
854
855                 cn->descriptor = (utf*) class_getconstant(c,
856                                                                                                   forward_nameandtypes->sig_index,
857                                                                                                   CONSTANT_Utf8);
858                 if (!cn->descriptor)
859                         return false;
860
861 #ifdef ENABLE_VERIFIER
862                 if (opt_verify) {
863                         /* check name */
864                         if (!is_valid_name_utf(cn->name)) {
865                                 exceptions_throw_classformaterror(c,
866                                                                                                   "Illegal Field name \"%s\"",
867                                                                                                   cn->name->text);
868
869                                 return false;
870                         }
871
872                         /* disallow referencing <clinit> among others */
873                         if (cn->name->text[0] == '<' && cn->name != utf_init) {
874                                 exceptions_throw_classformaterror(c, "Illegal reference to special method");
875                                 return false;
876                         }
877                 }
878 #endif /* ENABLE_VERIFIER */
879
880                 cptags[forward_nameandtypes->thisindex] = CONSTANT_NameAndType;
881                 cpinfos[forward_nameandtypes->thisindex] = cn;
882
883                 nfn = forward_nameandtypes;
884                 forward_nameandtypes = forward_nameandtypes->next;
885         }
886
887         while (forward_fieldmethints) {
888                 constant_nameandtype *nat;
889                 constant_FMIref *fmi = NEW(constant_FMIref);
890
891 #if defined(ENABLE_STATISTICS)
892                 if (opt_stat)
893                         count_const_pool_len += sizeof(constant_FMIref);
894 #endif
895                 /* resolve simple name and descriptor */
896
897                 nat = (constant_nameandtype*) class_getconstant(c,
898                                                                                                                 forward_fieldmethints->nameandtype_index,
899                                                                                                                 CONSTANT_NameAndType);
900
901                 if (!nat)
902                         return false;
903
904                 /* add all descriptors in {Field,Method}ref to the descriptor_pool */
905
906                 if (!descriptor_pool_add(descpool, nat->descriptor, NULL))
907                         return false;
908
909                 /* the classref is created later */
910
911                 fmi->p.index = forward_fieldmethints->class_index;
912                 fmi->name = nat->name;
913                 fmi->descriptor = nat->descriptor;
914
915                 cptags[forward_fieldmethints->thisindex] = forward_fieldmethints->tag;
916                 cpinfos[forward_fieldmethints->thisindex] = fmi;
917         
918                 nff = forward_fieldmethints;
919                 forward_fieldmethints = forward_fieldmethints->next;
920         }
921
922         /* everything was ok */
923
924         return true;
925 }
926
927
928 /* loader_load_attribute_signature *********************************************
929
930    Signature_attribute {
931        u2 attribute_name_index;
932            u4 atrribute_length;
933            u2 signature_index;
934    }
935
936 *******************************************************************************/
937
938 #if defined(ENABLE_JAVASE)
939 bool loader_load_attribute_signature(classbuffer *cb, utf **signature)
940 {
941         classinfo *c;
942         u4         attribute_length;
943         u2         signature_index;
944
945         /* get classinfo */
946
947         c = cb->clazz;
948
949         /* check remaining bytecode */
950
951         if (!suck_check_classbuffer_size(cb, 4 + 2))
952                 return false;
953
954         /* check attribute length */
955
956         attribute_length = suck_u4(cb);
957
958         if (attribute_length != 2) {
959                 exceptions_throw_classformaterror(c, "Wrong size for VALUE attribute");
960                 return false;
961         }
962
963         if (*signature != NULL) {
964                 exceptions_throw_classformaterror(c, "Multiple Signature attributes");
965                 return false;
966         }
967
968         /* get signature */
969
970         signature_index = suck_u2(cb);
971
972         *signature = (utf*) class_getconstant(c, signature_index, CONSTANT_Utf8);
973
974         if (*signature == NULL)
975                 return false;
976
977         return true;
978 }
979 #endif /* defined(ENABLE_JAVASE) */
980
981
982 /* load_class_from_sysloader ***************************************************
983
984    Load the class with the given name using the system class loader
985
986    IN:
987        name.............the classname
988
989    RETURN VALUE:
990        the loaded class, or
991            NULL if an exception has been thrown
992
993 *******************************************************************************/
994
995 classinfo *load_class_from_sysloader(utf *name)
996 {
997         methodinfo    *m;
998         java_handle_t *clo;
999         classloader_t *cl;
1000         classinfo     *c;
1001
1002         assert(class_java_lang_Object);
1003         assert(class_java_lang_ClassLoader);
1004         assert(class_java_lang_ClassLoader->state & CLASS_LINKED);
1005         
1006         m = class_resolveclassmethod(class_java_lang_ClassLoader,
1007                                                                  utf_getSystemClassLoader,
1008                                                                  utf_void__java_lang_ClassLoader,
1009                                                                  class_java_lang_Object,
1010                                                                  false);
1011
1012         if (!m)
1013                 return false;
1014
1015         clo = vm_call_method(m, NULL);
1016
1017         if (!clo)
1018                 return false;
1019
1020         cl = loader_hashtable_classloader_add(clo);
1021
1022         c = load_class_from_classloader(name, cl);
1023
1024         return c;
1025 }
1026
1027
1028 /* load_class_from_classloader *************************************************
1029
1030    Load the class with the given name using the given user-defined class loader.
1031
1032    IN:
1033        name.............the classname
1034            cl...............user-defined class loader
1035            
1036    RETURN VALUE:
1037        the loaded class, or
1038            NULL if an exception has been thrown
1039
1040 *******************************************************************************/
1041
1042 classinfo *load_class_from_classloader(utf *name, classloader_t *cl)
1043 {
1044         java_handle_t *o;
1045         classinfo     *c;
1046         classinfo     *tmpc;
1047         java_handle_t *string;
1048 #if defined(ENABLE_RT_TIMING)
1049         struct timespec time_start, time_lookup, time_prepare, time_java, 
1050                                         time_cache;
1051 #endif
1052
1053         RT_TIMING_GET_TIME(time_start);
1054
1055         assert(name);
1056
1057         /* lookup if this class has already been loaded */
1058
1059         c = classcache_lookup(cl, name);
1060
1061         RT_TIMING_GET_TIME(time_lookup);
1062         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_CL_LOOKUP);
1063
1064         if (c != NULL)
1065                 return c;
1066
1067         /* if other class loader than bootstrap, call it */
1068
1069         if (cl != NULL) {
1070                 methodinfo *lc;
1071                 char       *text;
1072                 s4          namelen;
1073
1074                 text = name->text;
1075                 namelen = name->blength;
1076
1077                 /* handle array classes */
1078                 if (text[0] == '[') {
1079                         classinfo *comp;
1080                         utf       *u;
1081
1082                         switch (text[1]) {
1083                         case 'L':
1084                                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
1085                                 if (namelen < 4 || text[2] == '[' || text[namelen - 1] != ';') {
1086                                         exceptions_throw_classnotfoundexception(name);
1087                                         return false;
1088                                 }
1089
1090                                 u = utf_new(text + 2, namelen - 3);
1091
1092                                 if (!(comp = load_class_from_classloader(u, cl)))
1093                                         return false;
1094
1095                                 /* create the array class */
1096
1097                                 c = class_array_of(comp, false);
1098
1099                                 tmpc = classcache_store(cl, c, true);
1100
1101                                 if (tmpc == NULL) {
1102                                         /* exception, free the loaded class */
1103                                         c->state &= ~CLASS_LOADING;
1104                                         class_free(c);
1105                                 }
1106
1107                                 return tmpc;
1108
1109                         case '[':
1110                                 /* load the component class */
1111
1112                                 u = utf_new(text + 1, namelen - 1);
1113
1114                                 if (!(comp = load_class_from_classloader(u, cl)))
1115                                         return false;
1116
1117                                 /* create the array class */
1118
1119                                 c = class_array_of(comp, false);
1120
1121                                 tmpc = classcache_store(cl, c, true);
1122
1123                                 if (tmpc == NULL) {
1124                                         /* exception, free the loaded class */
1125                                         c->state &= ~CLASS_LOADING;
1126                                         class_free(c);
1127                                 }
1128
1129                                 return tmpc;
1130
1131                         default:
1132                                 /* primitive array classes are loaded by the bootstrap loader */
1133
1134                                 c = load_class_bootstrap(name);
1135
1136                                 return c;
1137                         }
1138                 }
1139
1140                 LLNI_class_get(cl, c);
1141
1142 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
1143                 /* OpenJDK uses this internal function because it's
1144                    synchronized. */
1145
1146                 lc = class_resolveclassmethod(c,
1147                                                                           utf_loadClassInternal,
1148                                                                           utf_java_lang_String__java_lang_Class,
1149                                                                           NULL,
1150                                                                           true);
1151 #else
1152                 lc = class_resolveclassmethod(c,
1153                                                                           utf_loadClass,
1154                                                                           utf_java_lang_String__java_lang_Class,
1155                                                                           NULL,
1156                                                                           true);
1157 #endif
1158
1159                 if (lc == NULL)
1160                         return false; /* exception */
1161
1162                 /* move return value into `o' and cast it afterwards to a classinfo* */
1163
1164                 string = javastring_new_slash_to_dot(name);
1165
1166                 RT_TIMING_GET_TIME(time_prepare);
1167
1168                 o = vm_call_method(lc, (java_handle_t *) cl, string);
1169
1170                 RT_TIMING_GET_TIME(time_java);
1171
1172                 c = LLNI_classinfo_unwrap(o);
1173
1174                 if (c != NULL) {
1175                         /* Store this class in the loaded class cache. If another
1176                            class with the same (initloader,name) pair has been
1177                            stored earlier it will be returned by classcache_store
1178                            In this case classcache_store may not free the class
1179                            because it has already been exposed to Java code which
1180                            may have kept references to that class. */
1181
1182                     tmpc = classcache_store(cl, c, false);
1183
1184                         if (tmpc == NULL) {
1185                                 /* exception, free the loaded class */
1186                                 c->state &= ~CLASS_LOADING;
1187                                 class_free(c);
1188                         }
1189
1190                         c = tmpc;
1191                 }
1192                 else {
1193                         // Expected behavior for the classloader is to throw an exception
1194                         // and never return NULL. If the classloader shows a different
1195                         // behavior, we are correcting it here (see PR126).
1196                         if (exceptions_get_exception() == NULL) {
1197 #if !defined(NDEBUG)
1198                                 if (opt_PrintWarnings)
1199                                         log_message_utf("load_class_from_classloader: Correcting faulty classloader behavior (PR126) for ", name);
1200 #endif
1201                                 exceptions_throw_classnotfoundexception(name);
1202                         }
1203                 }
1204
1205                 RT_TIMING_GET_TIME(time_cache);
1206
1207                 RT_TIMING_TIME_DIFF(time_lookup , time_prepare, RT_TIMING_LOAD_CL_PREPARE);
1208                 RT_TIMING_TIME_DIFF(time_prepare, time_java   , RT_TIMING_LOAD_CL_JAVA);
1209                 RT_TIMING_TIME_DIFF(time_java   , time_cache  , RT_TIMING_LOAD_CL_CACHE);
1210
1211                 /* SUN compatible -verbose:class output */
1212
1213                 if (opt_verboseclass && (c != NULL) && (c->classloader == cl)) {
1214                         printf("[Loaded ");
1215                         utf_display_printable_ascii_classname(name);
1216                         printf("]\n");
1217                 }
1218
1219 #if defined(ENABLE_JVMTI)
1220                 /* fire Class Load JVMTI event */
1221                 if (jvmti) jvmti_ClassLoadPrepare(false, c);
1222 #endif
1223
1224
1225                 return c;
1226         } 
1227
1228         c = load_class_bootstrap(name);
1229
1230         return c;
1231 }
1232
1233
1234 /* load_class_bootstrap ********************************************************
1235         
1236    Load the class with the given name using the bootstrap class loader.
1237
1238    IN:
1239        name.............the classname
1240
1241    RETURN VALUE:
1242        loaded classinfo, or
1243            NULL if an exception has been thrown
1244
1245    SYNCHRONIZATION:
1246        load_class_bootstrap is synchronized. It can be treated as an
1247            atomic operation.
1248
1249 *******************************************************************************/
1250
1251 classinfo *load_class_bootstrap(utf *name)
1252 {
1253         classbuffer *cb;
1254         classinfo   *c;
1255         classinfo   *r;
1256 #if defined(ENABLE_RT_TIMING)
1257         struct timespec time_start, time_lookup, time_array, time_suck, 
1258                                         time_load, time_cache;
1259 #endif
1260
1261         RT_TIMING_GET_TIME(time_start);
1262
1263         /* for debugging */
1264
1265         assert(name);
1266
1267         /* lookup if this class has already been loaded */
1268
1269         r = classcache_lookup(NULL, name);
1270
1271         if (r != NULL) {
1272                 RT_TIMING_GET_TIME(time_lookup);
1273                 RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1274                 
1275                 return r;
1276         }
1277
1278         RT_TIMING_GET_TIME(time_lookup);
1279         RT_TIMING_TIME_DIFF(time_start,time_lookup,RT_TIMING_LOAD_BOOT_LOOKUP);
1280                 
1281         /* create the classinfo */
1282
1283         c = class_create_classinfo(name);
1284
1285         /* handle array classes */
1286
1287         if (name->text[0] == '[') {
1288                 c = load_newly_created_array(c, NULL);
1289
1290                 if (c == NULL)
1291                         return NULL;
1292
1293                 assert(c->state & CLASS_LOADED);
1294
1295                 RT_TIMING_GET_TIME(time_array);
1296                 RT_TIMING_TIME_DIFF(time_start,time_array,RT_TIMING_LOAD_BOOT_ARRAY);
1297                 
1298                 return c;
1299         }
1300
1301 #if defined(ENABLE_STATISTICS)
1302         /* measure time */
1303
1304         if (opt_getcompilingtime)
1305                 compilingtime_stop();
1306
1307         if (opt_getloadingtime)
1308                 loadingtime_start();
1309 #endif
1310
1311         /* load classdata, throw exception on error */
1312
1313         cb = suck_start(c);
1314
1315         if (cb == NULL) {
1316                 exceptions_throw_classnotfoundexception(name);
1317                 return NULL;
1318         }
1319
1320         RT_TIMING_GET_TIME(time_suck);
1321         
1322         /* load the class from the buffer */
1323
1324         r = load_class_from_classbuffer(cb);
1325
1326         RT_TIMING_GET_TIME(time_load);
1327         
1328         if (r == NULL) {
1329                 /* the class could not be loaded, free the classinfo struct */
1330
1331                 class_free(c);
1332         }
1333         else {
1334                 /* Store this class in the loaded class cache this step also
1335                    checks the loading constraints. If the class has been
1336                    loaded before, the earlier loaded class is returned. */
1337
1338                 classinfo *res = classcache_store(NULL, c, true);
1339
1340                 if (res == NULL) {
1341                         /* exception */
1342                         class_free(c);
1343                 }
1344                 else {
1345                         // Add the package name to the boot packages.
1346                         Package::add(c->packagename);
1347                 }
1348
1349                 r = res;
1350         }
1351
1352         RT_TIMING_GET_TIME(time_cache);
1353         
1354         /* SUN compatible -verbose:class output */
1355
1356         if (opt_verboseclass && r) {
1357                 printf("[Loaded ");
1358                 utf_display_printable_ascii_classname(name);
1359                 printf(" from %s]\n", cb->path);
1360         }
1361
1362         /* free memory */
1363
1364         suck_stop(cb);
1365
1366 #if defined(ENABLE_STATISTICS)
1367         /* measure time */
1368
1369         if (opt_getloadingtime)
1370                 loadingtime_stop();
1371
1372         if (opt_getcompilingtime)
1373                 compilingtime_start();
1374 #endif
1375
1376         RT_TIMING_TIME_DIFF(time_lookup, time_suck , RT_TIMING_LOAD_BOOT_SUCK);
1377         RT_TIMING_TIME_DIFF(time_suck  , time_load , RT_TIMING_LOAD_BOOT_LOAD);
1378         RT_TIMING_TIME_DIFF(time_load  , time_cache, RT_TIMING_LOAD_BOOT_CACHE);
1379         RT_TIMING_TIME_DIFF(time_lookup, time_cache, RT_TIMING_LOAD_BOOT_TOTAL);
1380
1381         return r;
1382 }
1383
1384
1385 /* load_class_from_classbuffer_intern ******************************************
1386         
1387    Loads a class from a classbuffer into a given classinfo structure.
1388    Super-classes are also loaded at this point and some verfication
1389    checks are done.
1390
1391    SYNCHRONIZATION:
1392        This function is NOT synchronized!
1393    
1394 *******************************************************************************/
1395
1396 static bool load_class_from_classbuffer_intern(classbuffer *cb)
1397 {
1398         classinfo          *c;
1399         classinfo          *tc;
1400         utf                *name;
1401         utf                *supername;
1402         utf               **interfacesnames;
1403         utf                *u;
1404         constant_classref  *cr;
1405         int16_t             index;
1406
1407         u4 ma, mi;
1408         descriptor_pool *descpool;
1409 #if defined(ENABLE_STATISTICS)
1410         u4 classrefsize;
1411         u4 descsize;
1412 #endif
1413 #if defined(ENABLE_RT_TIMING)
1414         struct timespec time_start, time_checks, time_ndpool, time_cpool,
1415                                         time_setup, time_fields, time_methods, time_classrefs,
1416                                         time_descs,     time_setrefs, time_parsefds, time_parsemds,
1417                                         time_parsecpool, time_verify, time_attrs;
1418 #endif
1419
1420         // Create new dump memory area.
1421         DumpMemoryArea dma;
1422
1423         RT_TIMING_GET_TIME(time_start);
1424
1425         /* Get the classbuffer's class. */
1426
1427         c = cb->clazz;
1428
1429         if (!suck_check_classbuffer_size(cb, 4 + 2 + 2))
1430                 return false;
1431
1432         /* check signature */
1433
1434         if (suck_u4(cb) != MAGIC) {
1435                 exceptions_throw_classformaterror(c, "Bad magic number");
1436                 return false;
1437         }
1438
1439         /* check version */
1440
1441         mi = suck_u2(cb);
1442         ma = suck_u2(cb);
1443
1444         if (!(ma < MAJOR_VERSION || (ma == MAJOR_VERSION && mi <= MINOR_VERSION))) {
1445                 exceptions_throw_unsupportedclassversionerror(c, ma, mi);
1446                 return false;
1447         }
1448
1449         RT_TIMING_GET_TIME(time_checks);
1450
1451         /* create a new descriptor pool */
1452
1453         descpool = descriptor_pool_new(c);
1454
1455         RT_TIMING_GET_TIME(time_ndpool);
1456
1457         /* load the constant pool */
1458
1459         if (!load_constantpool(cb, descpool))
1460                 return false;
1461
1462         RT_TIMING_GET_TIME(time_cpool);
1463
1464         /* ACC flags */
1465
1466         if (!suck_check_classbuffer_size(cb, 2))
1467                 return false;
1468
1469         /* We OR the flags here, as we set already some flags in
1470            class_create_classinfo. */
1471
1472         c->flags |= suck_u2(cb);
1473
1474         /* check ACC flags consistency */
1475
1476         if (c->flags & ACC_INTERFACE) {
1477                 if (!(c->flags & ACC_ABSTRACT)) {
1478                         /* We work around this because interfaces in JDK 1.1 are
1479                          * not declared abstract. */
1480
1481                         c->flags |= ACC_ABSTRACT;
1482                 }
1483
1484                 if (c->flags & ACC_FINAL) {
1485                         exceptions_throw_classformaterror(c,
1486                                                                                           "Illegal class modifiers: 0x%X",
1487                                                                                           c->flags);
1488                         return false;
1489                 }
1490
1491                 if (c->flags & ACC_SUPER) {
1492                         c->flags &= ~ACC_SUPER; /* kjc seems to set this on interfaces */
1493                 }
1494         }
1495
1496         if ((c->flags & (ACC_ABSTRACT | ACC_FINAL)) == (ACC_ABSTRACT | ACC_FINAL)) {
1497                 exceptions_throw_classformaterror(c,
1498                                                                                   "Illegal class modifiers: 0x%X",
1499                                                                                   c->flags);
1500                 return false;
1501         }
1502
1503         if (!suck_check_classbuffer_size(cb, 2 + 2))
1504                 return false;
1505
1506         /* This class. */
1507
1508         index = suck_u2(cb);
1509
1510         name = (utf *) class_getconstant(c, index, CONSTANT_Class);
1511
1512         if (name == NULL)
1513                 return false;
1514
1515         if (c->name == utf_not_named_yet) {
1516                 /* we finally have a name for this class */
1517                 c->name = name;
1518                 class_set_packagename(c);
1519         }
1520         else if (name != c->name) {
1521                 exceptions_throw_noclassdeffounderror_wrong_name(c, name);
1522                 return false;
1523         }
1524
1525         /* Retrieve superclass. */
1526
1527         c->super = NULL;
1528
1529         index = suck_u2(cb);
1530
1531         if (index == 0) {
1532                 supername = NULL;
1533
1534                 /* This is only allowed for java.lang.Object. */
1535
1536                 if (c->name != utf_java_lang_Object) {
1537                         exceptions_throw_classformaterror(c, "Bad superclass index");
1538                         return false;
1539                 }
1540         }
1541         else {
1542                 supername = (utf *) class_getconstant(c, index, CONSTANT_Class);
1543
1544                 if (supername == NULL)
1545                         return false;
1546
1547                 /* java.lang.Object may not have a super class. */
1548
1549                 if (c->name == utf_java_lang_Object) {
1550                         exceptions_throw_classformaterror(NULL, "java.lang.Object with superclass");
1551                         return false;
1552                 }
1553
1554                 /* Detect circularity. */
1555
1556                 if (supername == c->name) {
1557                         exceptions_throw_classcircularityerror(c);
1558                         return false;
1559                 }
1560
1561                 /* Interfaces must have java.lang.Object as super class. */
1562
1563                 if ((c->flags & ACC_INTERFACE) && (supername != utf_java_lang_Object)) {
1564                         exceptions_throw_classformaterror(c, "Interfaces must have java.lang.Object as superclass");
1565                         return false;
1566                 }
1567         }
1568
1569         /* Parse the super interfaces. */
1570
1571         if (!suck_check_classbuffer_size(cb, 2))
1572                 return false;
1573
1574         c->interfacescount = suck_u2(cb);
1575
1576         if (!suck_check_classbuffer_size(cb, 2 * c->interfacescount))
1577                 return false;
1578
1579         c->interfaces = MNEW(classinfo*, c->interfacescount);
1580
1581         /* Get the names of the super interfaces. */
1582
1583         interfacesnames = (utf**) DumpMemory::allocate(sizeof(utf*) * c->interfacescount);
1584
1585         for (int32_t i = 0; i < c->interfacescount; i++) {
1586                 index = suck_u2(cb);
1587
1588                 u = (utf *) class_getconstant(c, index, CONSTANT_Class);
1589
1590                 if (u == NULL)
1591                         return false;
1592
1593                 interfacesnames[i] = u;
1594         }
1595
1596         RT_TIMING_GET_TIME(time_setup);
1597
1598         /* Parse fields. */
1599
1600         if (!suck_check_classbuffer_size(cb, 2))
1601                 return false;
1602
1603         c->fieldscount = suck_u2(cb);
1604         c->fields      = MNEW(fieldinfo, c->fieldscount);
1605
1606         MZERO(c->fields, fieldinfo, c->fieldscount);
1607
1608         for (int32_t i = 0; i < c->fieldscount; i++) {
1609                 if (!field_load(cb, &(c->fields[i]), descpool))
1610                         return false;
1611         }
1612
1613         RT_TIMING_GET_TIME(time_fields);
1614
1615         /* Parse methods. */
1616
1617         if (!suck_check_classbuffer_size(cb, 2))
1618                 return false;
1619
1620         c->methodscount = suck_u2(cb);
1621         c->methods      = MNEW(methodinfo, c->methodscount);
1622
1623         MZERO(c->methods, methodinfo, c->methodscount);
1624         
1625         for (int32_t i = 0; i < c->methodscount; i++) {
1626                 if (!method_load(cb, &(c->methods[i]), descpool))
1627                         return false;
1628         }
1629
1630         RT_TIMING_GET_TIME(time_methods);
1631
1632         /* create the class reference table */
1633
1634         c->classrefs =
1635                 descriptor_pool_create_classrefs(descpool, &(c->classrefcount));
1636
1637         RT_TIMING_GET_TIME(time_classrefs);
1638
1639         /* allocate space for the parsed descriptors */
1640
1641         descriptor_pool_alloc_parsed_descriptors(descpool);
1642         c->parseddescs = (u1*) descriptor_pool_get_parsed_descriptors(descpool, &(c->parseddescsize));
1643
1644 #if defined(ENABLE_STATISTICS)
1645         if (opt_stat) {
1646                 descriptor_pool_get_sizes(descpool, &classrefsize, &descsize);
1647                 count_classref_len += classrefsize;
1648                 count_parsed_desc_len += descsize;
1649         }
1650 #endif
1651
1652         RT_TIMING_GET_TIME(time_descs);
1653
1654         /* put the classrefs in the constant pool */
1655
1656         for (int32_t i = 0; i < c->cpcount; i++) {
1657                 if (c->cptags[i] == CONSTANT_Class) {
1658                         utf *name = (utf *) c->cpinfos[i];
1659                         c->cpinfos[i] = descriptor_pool_lookup_classref(descpool, name);
1660                 }
1661         }
1662
1663         /* Resolve the super class. */
1664
1665         if (supername != NULL) {
1666                 cr = descriptor_pool_lookup_classref(descpool, supername);
1667
1668                 if (cr == NULL)
1669                         return false;
1670
1671                 /* XXX This should be done better. */
1672                 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1673
1674                 if (tc == NULL) {
1675                         resolve_handle_pending_exception(true);
1676                         return false;
1677                 }
1678
1679                 /* Interfaces are not allowed as super classes. */
1680
1681                 if (tc->flags & ACC_INTERFACE) {
1682                         exceptions_throw_incompatibleclasschangeerror(c, "class %s has interface %s as super class");
1683                         return false;
1684                 }
1685
1686                 /* Don't allow extending final classes */
1687
1688                 if (tc->flags & ACC_FINAL) {
1689                         exceptions_throw_verifyerror(NULL,
1690                                                                                  "Cannot inherit from final class");
1691                         return false;
1692                 }
1693
1694                 /* Store the super class. */
1695
1696                 c->super = tc;
1697         }
1698
1699         /* Resolve the super interfaces. */
1700
1701         for (int32_t i = 0; i < c->interfacescount; i++) {
1702                 u  = interfacesnames[i];
1703                 cr = descriptor_pool_lookup_classref(descpool, u);
1704
1705                 if (cr == NULL)
1706                         return false;
1707
1708                 /* XXX This should be done better. */
1709                 tc = resolve_classref_or_classinfo_eager(CLASSREF_OR_CLASSINFO(cr), false);
1710
1711                 if (tc == NULL) {
1712                         resolve_handle_pending_exception(true);
1713                         return false;
1714                 }
1715
1716                 /* Detect circularity. */
1717
1718                 if (tc == c) {
1719                         exceptions_throw_classcircularityerror(c);
1720                         return false;
1721                 }
1722
1723                 if (!(tc->flags & ACC_INTERFACE)) {
1724                         exceptions_throw_incompatibleclasschangeerror(tc,
1725                                                                                                                   "Implementing class");
1726                         return false;
1727                 }
1728
1729                 /* Store the super interface. */
1730
1731                 c->interfaces[i] = tc;
1732         }
1733
1734         RT_TIMING_GET_TIME(time_setrefs);
1735
1736         /* Parse the field descriptors. */
1737
1738         for (int32_t i = 0; i < c->fieldscount; i++) {
1739                 c->fields[i].parseddesc =
1740                         descriptor_pool_parse_field_descriptor(descpool,
1741                                                                                                    c->fields[i].descriptor);
1742                 if (!c->fields[i].parseddesc)
1743                         return false;
1744         }
1745
1746         RT_TIMING_GET_TIME(time_parsefds);
1747
1748         /* parse method descriptors */
1749
1750         for (int32_t i = 0; i < c->methodscount; i++) {
1751                 methodinfo *m = &c->methods[i];
1752                 m->parseddesc =
1753                         descriptor_pool_parse_method_descriptor(descpool, m->descriptor,
1754                                                                                                         m->flags, class_get_self_classref(m->clazz));
1755                 if (!m->parseddesc)
1756                         return false;
1757
1758                 for (int32_t j = 0; j < m->rawexceptiontablelength; j++) {
1759                         if (!m->rawexceptiontable[j].catchtype.any)
1760                                 continue;
1761
1762                         if ((m->rawexceptiontable[j].catchtype.ref =
1763                                  descriptor_pool_lookup_classref(descpool,
1764                                                 (utf *) m->rawexceptiontable[j].catchtype.any)) == NULL)
1765                                 return false;
1766                 }
1767
1768                 for (int32_t j = 0; j < m->thrownexceptionscount; j++) {
1769                         if (!m->thrownexceptions[j].any)
1770                                 continue;
1771
1772                         if ((m->thrownexceptions[j].ref = descriptor_pool_lookup_classref(descpool,
1773                                                 (utf *) m->thrownexceptions[j].any)) == NULL)
1774                                 return false;
1775                 }
1776         }
1777
1778         RT_TIMING_GET_TIME(time_parsemds);
1779
1780         /* parse the loaded descriptors */
1781
1782         for (int32_t i = 0; i < c->cpcount; i++) {
1783                 constant_FMIref *fmi;
1784                 s4               index;
1785
1786                 switch (c->cptags[i]) {
1787                 case CONSTANT_Fieldref:
1788                         fmi = (constant_FMIref *) c->cpinfos[i];
1789                         fmi->parseddesc.fd =
1790                                 descriptor_pool_parse_field_descriptor(descpool,
1791                                                                                                            fmi->descriptor);
1792                         if (!fmi->parseddesc.fd)
1793                                 return false;
1794
1795                         index = fmi->p.index;
1796                         fmi->p.classref =
1797                                 (constant_classref *) class_getconstant(c, index,
1798                                                                                                                 CONSTANT_Class);
1799                         if (!fmi->p.classref)
1800                                 return false;
1801                         break;
1802                 case CONSTANT_Methodref:
1803                 case CONSTANT_InterfaceMethodref:
1804                         fmi = (constant_FMIref *) c->cpinfos[i];
1805                         index = fmi->p.index;
1806                         fmi->p.classref =
1807                                 (constant_classref *) class_getconstant(c, index,
1808                                                                                                                 CONSTANT_Class);
1809                         if (!fmi->p.classref)
1810                                 return false;
1811                         fmi->parseddesc.md =
1812                                 descriptor_pool_parse_method_descriptor(descpool,
1813                                                                                                                 fmi->descriptor,
1814                                                                                                                 ACC_UNDEF,
1815                                                                                                                 fmi->p.classref);
1816                         if (!fmi->parseddesc.md)
1817                                 return false;
1818                         break;
1819                 }
1820         }
1821
1822         RT_TIMING_GET_TIME(time_parsecpool);
1823
1824 #ifdef ENABLE_VERIFIER
1825         /* Check if all fields and methods can be uniquely
1826          * identified by (name,descriptor). */
1827
1828         if (opt_verify) {
1829                 /* We use a hash table here to avoid making the
1830                  * average case quadratic in # of methods, fields.
1831                  */
1832                 static int shift = 0;
1833                 u2 *hashtab;
1834                 u2 *next; /* for chaining colliding hash entries */
1835                 int32_t len;
1836                 int32_t hashlen;
1837                 u2 index;
1838                 u2 old;
1839
1840                 /* Allocate hashtable */
1841                 len = c->methodscount;
1842                 if (len < c->fieldscount) len = c->fieldscount;
1843                 hashlen = 5 * len;
1844                 hashtab = MNEW(u2,(hashlen + len));
1845                 next = hashtab + hashlen;
1846
1847                 /* Determine bitshift (to get good hash values) */
1848                 if (!shift) {
1849                         len = sizeof(utf);
1850                         while (len) {
1851                                 len >>= 1;
1852                                 shift++;
1853                         }
1854                 }
1855
1856                 /* Check fields */
1857                 memset(hashtab, 0, sizeof(u2) * (hashlen + len));
1858
1859                 for (int32_t i = 0; i < c->fieldscount; ++i) {
1860                         fieldinfo *fi = c->fields + i;
1861
1862                         /* It's ok if we lose bits here */
1863                         index = ((((size_t) fi->name) +
1864                                           ((size_t) fi->descriptor)) >> shift) % hashlen;
1865
1866                         if ((old = hashtab[index])) {
1867                                 old--;
1868                                 next[i] = old;
1869                                 do {
1870                                         if (c->fields[old].name == fi->name &&
1871                                                 c->fields[old].descriptor == fi->descriptor) {
1872                                                 exceptions_throw_classformaterror(c, "Repetitive field name/signature");
1873                                                 return false;
1874                                         }
1875                                 } while ((old = next[old]));
1876                         }
1877                         hashtab[index] = i + 1;
1878                 }
1879
1880                 /* Check methods */
1881                 memset(hashtab, 0, sizeof(u2) * (hashlen + hashlen/5));
1882
1883                 for (int32_t i = 0; i < c->methodscount; ++i) {
1884                         methodinfo *mi = c->methods + i;
1885
1886                         /* It's ok if we lose bits here */
1887                         index = ((((size_t) mi->name) +
1888                                           ((size_t) mi->descriptor)) >> shift) % hashlen;
1889
1890                         if ((old = hashtab[index])) {
1891                                 old--;
1892                                 next[i] = old;
1893                                 do {
1894                                         if (c->methods[old].name == mi->name &&
1895                                                 c->methods[old].descriptor == mi->descriptor) {
1896                                                 exceptions_throw_classformaterror(c, "Repetitive method name/signature");
1897                                                 return false;
1898                                         }
1899                                 } while ((old = next[old]));
1900                         }
1901                         hashtab[index] = i + 1;
1902                 }
1903
1904                 MFREE(hashtab, u2, (hashlen + len));
1905         }
1906 #endif /* ENABLE_VERIFIER */
1907
1908         RT_TIMING_GET_TIME(time_verify);
1909
1910 #if defined(ENABLE_STATISTICS)
1911         if (opt_stat) {
1912                 size_classinfo  += sizeof(classinfo*) * c->interfacescount;
1913                 size_fieldinfo  += sizeof(fieldinfo)  * c->fieldscount;
1914                 size_methodinfo += sizeof(methodinfo) * c->methodscount;
1915         }
1916 #endif
1917
1918         /* load attribute structures */
1919
1920         if (!class_load_attributes(cb))
1921                 return false;
1922
1923         /* Pre Java 1.5 version don't check this. This implementation is
1924            like Java 1.5 do it: for class file version 45.3 we don't check
1925            it, older versions are checked. */
1926
1927         if (((ma == 45) && (mi > 3)) || (ma > 45)) {
1928                 /* check if all data has been read */
1929                 s4 classdata_left = ((cb->data + cb->size) - cb->pos);
1930
1931                 if (classdata_left > 0) {
1932                         exceptions_throw_classformaterror(c, "Extra bytes at the end of class file");
1933                         return false;
1934                 }
1935         }
1936
1937         RT_TIMING_GET_TIME(time_attrs);
1938
1939         RT_TIMING_TIME_DIFF(time_start     , time_checks    , RT_TIMING_LOAD_CHECKS);
1940         RT_TIMING_TIME_DIFF(time_checks    , time_ndpool    , RT_TIMING_LOAD_NDPOOL);
1941         RT_TIMING_TIME_DIFF(time_ndpool    , time_cpool     , RT_TIMING_LOAD_CPOOL);
1942         RT_TIMING_TIME_DIFF(time_cpool     , time_setup     , RT_TIMING_LOAD_SETUP);
1943         RT_TIMING_TIME_DIFF(time_setup     , time_fields    , RT_TIMING_LOAD_FIELDS);
1944         RT_TIMING_TIME_DIFF(time_fields    , time_methods   , RT_TIMING_LOAD_METHODS);
1945         RT_TIMING_TIME_DIFF(time_methods   , time_classrefs , RT_TIMING_LOAD_CLASSREFS);
1946         RT_TIMING_TIME_DIFF(time_classrefs , time_descs     , RT_TIMING_LOAD_DESCS);
1947         RT_TIMING_TIME_DIFF(time_descs     , time_setrefs   , RT_TIMING_LOAD_SETREFS);
1948         RT_TIMING_TIME_DIFF(time_setrefs   , time_parsefds  , RT_TIMING_LOAD_PARSEFDS);
1949         RT_TIMING_TIME_DIFF(time_parsefds  , time_parsemds  , RT_TIMING_LOAD_PARSEMDS);
1950         RT_TIMING_TIME_DIFF(time_parsemds  , time_parsecpool, RT_TIMING_LOAD_PARSECP);
1951         RT_TIMING_TIME_DIFF(time_parsecpool, time_verify    , RT_TIMING_LOAD_VERIFY);
1952         RT_TIMING_TIME_DIFF(time_verify    , time_attrs     , RT_TIMING_LOAD_ATTRS);
1953         RT_TIMING_TIME_DIFF(time_start     , time_attrs     , RT_TIMING_LOAD_TOTAL);
1954
1955         return true;
1956 }
1957
1958
1959 /* load_class_from_classbuffer *************************************************
1960
1961    Convenience wrapper for load_class_from_classbuffer.
1962
1963    SYNCHRONIZATION:
1964        This function is NOT synchronized!
1965    
1966 *******************************************************************************/
1967
1968 classinfo *load_class_from_classbuffer(classbuffer *cb)
1969 {
1970         classinfo *c;
1971         bool       result;
1972
1973         /* Get the classbuffer's class. */
1974
1975         c = cb->clazz;
1976
1977         /* Check if the class is already loaded. */
1978
1979         if (c->state & CLASS_LOADED)
1980                 return c;
1981
1982 #if defined(ENABLE_STATISTICS)
1983         if (opt_stat)
1984                 count_class_loads++;
1985 #endif
1986
1987 #if !defined(NDEBUG)
1988         if (loadverbose)
1989                 log_message_class("Loading class: ", c);
1990 #endif
1991
1992         /* Class is currently loading. */
1993
1994         c->state |= CLASS_LOADING;
1995
1996         /* Parse the classbuffer. */
1997
1998         result = load_class_from_classbuffer_intern(cb);
1999
2000         /* An error occurred. */
2001
2002         if (result == false) {
2003                 /* Revert loading state. */
2004
2005                 c->state = (c->state & ~CLASS_LOADING);
2006
2007                 return NULL;
2008         }
2009
2010         /* Revert loading state and set loaded. */
2011
2012         c->state = (c->state & ~CLASS_LOADING) | CLASS_LOADED;
2013
2014 #if defined(ENABLE_JVMTI)
2015         /* fire Class Prepare JVMTI event */
2016
2017         if (jvmti)
2018                 jvmti_ClassLoadPrepare(true, c);
2019 #endif
2020
2021 #if !defined(NDEBUG)
2022         if (loadverbose)
2023                 log_message_class("Loading done class: ", c);
2024 #endif
2025
2026         return c;
2027 }
2028
2029
2030 /* load_newly_created_array ****************************************************
2031
2032    Load a newly created array class.
2033
2034         RETURN VALUE:
2035             c....................the array class C has been loaded
2036                 other classinfo......the array class was found in the class cache, 
2037                                      C has been freed
2038             NULL.................an exception has been thrown
2039
2040         Note:
2041                 This is an internal function. Do not use it unless you know exactly
2042                 what you are doing!
2043
2044                 Use one of the load_class_... functions for general array class loading.
2045
2046 *******************************************************************************/
2047
2048 classinfo *load_newly_created_array(classinfo *c, classloader_t *loader)
2049 {
2050         classinfo         *comp = NULL;
2051         methodinfo        *clone;
2052         methoddesc        *clonedesc;
2053         constant_classref *classrefs;
2054         char              *text;
2055         s4                 namelen;
2056         utf               *u;
2057
2058         text    = c->name->text;
2059         namelen = c->name->blength;
2060
2061         /* Check array class name */
2062
2063         if ((namelen < 2) || (text[0] != '[')) {
2064                 exceptions_throw_classnotfoundexception(c->name);
2065                 return NULL;
2066         }
2067
2068         /* Check the element type */
2069
2070         switch (text[1]) {
2071         case '[':
2072                 /* c is an array of arrays. We have to create the component class. */
2073
2074                 u = utf_new(text + 1, namelen - 1);
2075
2076                 comp = load_class_from_classloader(u, loader);
2077
2078                 if (comp == NULL)
2079                         return NULL;
2080
2081                 assert(comp->state & CLASS_LOADED);
2082
2083                 /* the array's flags are that of the component class */
2084                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2085                 c->classloader = comp->classloader;
2086                 break;
2087
2088         case 'L':
2089                 /* c is an array of objects. */
2090
2091                 /* check for cases like `[L;' or `[L[I;' or `[Ljava.lang.Object' */
2092                 if ((namelen < 4) || (text[2] == '[') || (text[namelen - 1] != ';')) {
2093                         exceptions_throw_classnotfoundexception(c->name);
2094                         return NULL;
2095                 }
2096
2097                 u = utf_new(text + 2, namelen - 3);
2098
2099                 if (!(comp = load_class_from_classloader(u, loader)))
2100                         return NULL;
2101
2102                 assert(comp->state & CLASS_LOADED);
2103
2104                 /* the array's flags are that of the component class */
2105                 c->flags = (comp->flags & ~ACC_INTERFACE) | ACC_FINAL | ACC_ABSTRACT;
2106                 c->classloader = comp->classloader;
2107                 break;
2108
2109         default:
2110                 /* c is an array of a primitive type */
2111
2112                 /* check for cases like `[II' and whether the character is a
2113                    valid primitive type */
2114
2115                 if ((namelen > 2) || (Primitive::get_class_by_char(text[1]) == NULL)) {
2116                         exceptions_throw_classnotfoundexception(c->name);
2117                         return NULL;
2118                 }
2119
2120                 /* the accessibility of the array class is public (VM Spec 5.3.3) */
2121                 c->flags = ACC_PUBLIC | ACC_FINAL | ACC_ABSTRACT;
2122                 c->classloader = NULL;
2123         }
2124
2125         assert(class_java_lang_Object);
2126 #if defined(ENABLE_JAVASE)
2127         assert(class_java_lang_Cloneable);
2128         assert(class_java_io_Serializable);
2129 #endif
2130
2131         /* Setup the array class. */
2132
2133         c->super = class_java_lang_Object;
2134
2135 #if defined(ENABLE_JAVASE)
2136
2137         c->interfacescount = 2;
2138     c->interfaces      = MNEW(classinfo*, 2);
2139         c->interfaces[0]   = class_java_lang_Cloneable;
2140         c->interfaces[1]   = class_java_io_Serializable;
2141
2142 #elif defined(ENABLE_JAVAME_CLDC1_1)
2143
2144         c->interfacescount = 0;
2145         c->interfaces      = NULL;
2146
2147 #else
2148 # error unknow Java configuration
2149 #endif
2150
2151         c->methodscount = 1;
2152         c->methods      = MNEW(methodinfo, c->methodscount);
2153
2154         MZERO(c->methods, methodinfo, c->methodscount);
2155
2156         classrefs = MNEW(constant_classref, 2);
2157
2158         CLASSREF_INIT(classrefs[0], c, c->name);
2159         CLASSREF_INIT(classrefs[1], c, utf_java_lang_Object);
2160
2161         /* create descriptor for clone method */
2162         /* we need one paramslot which is reserved for the 'this' parameter */
2163         clonedesc = NEW(methoddesc);
2164         clonedesc->returntype.type = TYPE_ADR;
2165         clonedesc->returntype.classref = classrefs + 1;
2166         clonedesc->returntype.arraydim = 0;
2167         /* initialize params to "empty", add real params below in
2168            descriptor_params_from_paramtypes */
2169         clonedesc->paramcount = 0;
2170         clonedesc->paramslots = 0;
2171         clonedesc->paramtypes[0].classref = classrefs + 0;
2172         clonedesc->params = NULL;
2173
2174         /* create methodinfo */
2175
2176         clone = c->methods;
2177         MSET(clone, 0, methodinfo, 1);
2178
2179         /* ATTENTION: if you delete the ACC_NATIVE below, set
2180            clone->maxlocals=1 (interpreter related) */
2181
2182         clone->mutex      = new Mutex();
2183         clone->flags      = ACC_PUBLIC | ACC_NATIVE;
2184         clone->name       = utf_clone;
2185         clone->descriptor = utf_void__java_lang_Object;
2186         clone->parseddesc = clonedesc;
2187         clone->clazz      = c;
2188
2189         /* parse the descriptor to get the register allocation */
2190
2191         if (!descriptor_params_from_paramtypes(clonedesc, clone->flags))
2192                 return false;
2193
2194         clone->code = NativeStub::generate(clone, BUILTIN_clone);
2195
2196         /* XXX: field: length? */
2197
2198         /* array classes are not loaded from class files */
2199
2200         c->state          |= CLASS_LOADED;
2201         c->parseddescs    = (u1 *) clonedesc;
2202         c->parseddescsize = sizeof(methodinfo);
2203         c->classrefs      = classrefs;
2204         c->classrefcount  = 1;
2205
2206         /* insert class into the loaded class cache */
2207         /* XXX free classinfo if NULL returned? */
2208
2209         return classcache_store(loader, c, true);
2210 }
2211
2212
2213 /* loader_close ****************************************************************
2214
2215    Frees all resources.
2216         
2217 *******************************************************************************/
2218
2219 void loader_close(void)
2220 {
2221         /* empty */
2222 }
2223
2224
2225 /*
2226  * These are local overrides for various environment variables in Emacs.
2227  * Please do not remove this and leave it at the end of the file, where
2228  * Emacs will automagically detect them.
2229  * ---------------------------------------------------------------------
2230  * Local variables:
2231  * mode: c++
2232  * indent-tabs-mode: t
2233  * c-basic-offset: 4
2234  * tab-width: 4
2235  * End:
2236  * vim:noexpandtab:sw=4:ts=4:
2237  */