1 /* loader.c ********************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the functions of the class loader.
9 Author: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
10 Changes: Mark Probst EMAIL: cacao@complang.tuwien.ac.at
12 Last Change: 1997/06/03
14 *******************************************************************************/
28 #include "threads/thread.h" /* schani */
31 /* global variables ***********************************************************/
33 extern bool newcompiler; /* true if new compiler is used */
35 int count_class_infos = 0; /* variables for measurements */
36 int count_const_pool_len = 0;
37 int count_vftbl_len = 0;
38 int count_all_methods = 0;
39 int count_vmcode_len = 0;
40 int count_extable_len = 0;
42 bool loadverbose = false; /* switches for debug messages */
43 bool linkverbose = false;
44 bool initverbose = false;
46 bool makeinitializations = true;
48 bool getloadingtime = false;
49 long int loadingtime = 0;
52 static s4 interfaceindex; /* sequential numbering of interfaces */
54 static list unloadedclasses; /* list of all referenced but not loaded classes */
55 static list unlinkedclasses; /* list of all loaded but not linked classes */
56 list linkedclasses; /* list of all completely linked classes */
60 /* important system classes ***************************************************/
62 classinfo *class_java_lang_Object;
63 classinfo *class_java_lang_String;
64 classinfo *class_java_lang_ClassCastException;
65 classinfo *class_java_lang_NullPointerException;
66 classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
67 classinfo *class_java_lang_NegativeArraySizeException;
68 classinfo *class_java_lang_OutOfMemoryError;
69 classinfo *class_java_lang_ArithmeticException;
70 classinfo *class_java_lang_ArrayStoreException;
71 classinfo *class_java_lang_ThreadDeath; /* schani */
73 classinfo *class_array;
76 /* instances of important system classes **************************************/
78 java_objectheader *proto_java_lang_ClassCastException;
79 java_objectheader *proto_java_lang_NullPointerException;
80 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
81 java_objectheader *proto_java_lang_NegativeArraySizeException;
82 java_objectheader *proto_java_lang_OutOfMemoryError;
83 java_objectheader *proto_java_lang_ArithmeticException;
84 java_objectheader *proto_java_lang_ArrayStoreException;
85 java_objectheader *proto_java_lang_ThreadDeath; /* schani */
90 /******************************************************************************/
91 /******************* Einige Support-Funkionen *********************************/
92 /******************************************************************************/
95 /********** interne Funktion: printflags (nur zu Debug-Zwecken) **************/
97 static void printflags (u2 f)
99 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
100 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
101 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
102 if ( f & ACC_STATIC ) printf (" STATIC");
103 if ( f & ACC_FINAL ) printf (" FINAL");
104 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
105 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
106 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
107 if ( f & ACC_NATIVE ) printf (" NATIVE");
108 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
109 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
113 /************************* Funktion: skipattribute *****************************
115 "uberliest im ClassFile eine (1) 'attribute'-Struktur
117 *******************************************************************************/
119 static void skipattribute ()
122 skip_nbytes(suck_u4());
125 /********************** Funktion: skipattributebody ****************************
127 "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name -
128 Referenz schon gelesen worden ist.
130 *******************************************************************************/
132 static void skipattributebody ()
134 skip_nbytes(suck_u4());
138 /************************* Funktion: skipattributes ****************************
140 "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
142 *******************************************************************************/
144 static void skipattributes (u4 num)
147 for (i = 0; i < num; i++)
153 /************************** Funktion: loadUtf8 *********************************
155 liest aus dem ClassFile einen Utf8-String (=komprimierter unicode-text)
156 und legt daf"ur ein unicode-Symbol an.
157 Return: Zeiger auf das Symbol
159 *******************************************************************************/
161 #define MAXUNICODELEN 5000
162 static u2 unicodebuffer[MAXUNICODELEN];
164 static unicode *loadUtf8 ()
178 if (b1<0x80) letter = b1;
182 if (b1<0xe0) letter = ((b1 & 0x1f) << 6) | (b2 & 0x3f);
186 letter = ((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
191 if (unicodelen >= MAXUNICODELEN) {
192 panic ("String constant too long");
195 unicodebuffer[unicodelen++] = letter;
199 return unicode_new_u2 (unicodebuffer, unicodelen);
204 /******************** interne Funktion: checkfieldtype ************************/
206 static void checkfieldtype (u2 *text, u4 *count, u4 length)
210 if (*count >= length) panic ("Type-descriptor exceeds unicode length");
212 l = text[(*count)++];
215 default: panic ("Invalid symbol in type descriptor");
226 case '[': checkfieldtype (text, count, length);
231 u4 tlen,tstart = *count;
233 if (*count >= length)
234 panic ("Objecttype descriptor of length zero");
236 while ( text[*count] != ';' ) {
238 if (*count >= length)
239 panic ("Missing ';' in objecttype-descriptor");
242 tlen = (*count) - tstart;
245 if (tlen == 0) panic ("Objecttype descriptor with empty name");
247 class_get ( unicode_new_u2 (text+tstart, tlen) );
253 /******************* Funktion: checkfielddescriptor ****************************
255 "uberpr"uft, ob ein Field-Descriptor ein g"ultiges Format hat.
256 Wenn nicht, dann wird das System angehalten.
257 Au"serdem werden alle Klassen, die hier referenziert werden,
258 in die Liste zu ladender Klassen eingetragen.
260 *******************************************************************************/
262 void checkfielddescriptor (unicode *d)
265 checkfieldtype (d->text, &count, d->length);
266 if (count != d->length) panic ("Invalid type-descritor encountered");
270 /******************* Funktion: checkmethoddescriptor ***************************
272 "uberpr"uft, ob ein Method-Descriptor ein g"ultiges Format hat.
273 Wenn nicht, dann wird das System angehalten.
274 Au"serdem werden alle Klassen, die hier referenziert werden,
275 in die Liste zu ladender Klassen eingetragen.
277 *******************************************************************************/
279 void checkmethoddescriptor (unicode *d)
285 if (length<2) panic ("Method descriptor too short");
286 if (text[0] != '(') panic ("Missing '(' in method descriptor");
289 while (text[count] != ')') {
290 checkfieldtype (text,&count,length);
291 if ( count > length-2 ) panic ("Unexpected end of descriptor");
295 if (text[count] == 'V') count++;
296 else checkfieldtype (text, &count,length);
298 if (count != length) panic ("Method-descriptor has exceeding chars");
302 /******************** Funktion: buildarraydescriptor ***************************
304 erzeugt zu einem namentlich als u2-String vorliegenden Arraytyp eine
305 entsprechende constant_arraydescriptor - Struktur
307 *******************************************************************************/
309 static constant_arraydescriptor * buildarraydescriptor(u2 *name, u4 namelen)
311 constant_arraydescriptor *d;
313 if (name[0]!='[') panic ("Attempt to build arraydescriptor for non-array");
314 d = NEW (constant_arraydescriptor);
315 d -> objectclass = NULL;
316 d -> elementdescriptor = NULL;
319 count_const_pool_len += sizeof(constant_arraydescriptor);
323 case 'Z': d -> arraytype = ARRAYTYPE_BOOLEAN; break;
324 case 'B': d -> arraytype = ARRAYTYPE_BYTE; break;
325 case 'C': d -> arraytype = ARRAYTYPE_CHAR; break;
326 case 'D': d -> arraytype = ARRAYTYPE_DOUBLE; break;
327 case 'F': d -> arraytype = ARRAYTYPE_FLOAT; break;
328 case 'I': d -> arraytype = ARRAYTYPE_INT; break;
329 case 'J': d -> arraytype = ARRAYTYPE_LONG; break;
330 case 'S': d -> arraytype = ARRAYTYPE_SHORT; break;
333 d -> arraytype = ARRAYTYPE_ARRAY;
334 d -> elementdescriptor = buildarraydescriptor (name+1, namelen-1);
338 d -> arraytype = ARRAYTYPE_OBJECT;
339 d -> objectclass = class_get ( unicode_new_u2 (name+2, namelen-3) );
346 /******************* Funktion: freearraydescriptor *****************************
348 entfernt eine mit buildarraydescriptor erzeugte Struktur wieder
351 *******************************************************************************/
353 static void freearraydescriptor (constant_arraydescriptor *d)
356 constant_arraydescriptor *n = d->elementdescriptor;
357 FREE (d, constant_arraydescriptor);
362 /*********************** Funktion: displayarraydescriptor *********************/
364 static void displayarraydescriptor (constant_arraydescriptor *d)
366 switch (d->arraytype) {
367 case ARRAYTYPE_BOOLEAN: printf ("boolean[]"); break;
368 case ARRAYTYPE_BYTE: printf ("byte[]"); break;
369 case ARRAYTYPE_CHAR: printf ("char[]"); break;
370 case ARRAYTYPE_DOUBLE: printf ("double[]"); break;
371 case ARRAYTYPE_FLOAT: printf ("float[]"); break;
372 case ARRAYTYPE_INT: printf ("int[]"); break;
373 case ARRAYTYPE_LONG: printf ("long[]"); break;
374 case ARRAYTYPE_SHORT: printf ("short[]"); break;
375 case ARRAYTYPE_ARRAY: displayarraydescriptor(d->elementdescriptor); printf("[]"); break;
376 case ARRAYTYPE_OBJECT: unicode_display(d->objectclass->name); printf("[]"); break;
382 /******************************************************************************/
383 /******************** Funktionen fuer Fields **********************************/
384 /******************************************************************************/
387 /************************ Funktion: field_load *********************************
389 l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
390 und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
391 Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
394 *******************************************************************************/
396 static void field_load (fieldinfo *f, classinfo *c)
401 f -> flags = suck_u2 ();
402 f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
403 f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
404 f -> type = jtype = desc_to_type (f->descriptor);
408 case TYPE_INT: f->value.i = 0; break;
409 case TYPE_FLOAT: f->value.f = 0.0; break;
410 case TYPE_DOUBLE: f->value.d = 0.0; break;
411 case TYPE_ADDRESS: f->value.a = NULL;
412 heap_addreference (&(f->value.a));
416 f->value.l = 0; break;
418 f->value.l.low = 0; f->value.l.high = 0; break;
423 for (i=0; i<attrnum; i++) {
427 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
429 if ( aname != unicode_new_char ("ConstantValue") ) {
430 skipattributebody ();
438 constant_integer *ci =
439 class_getconstant(c, pindex, CONSTANT_Integer);
440 f->value.i = ci -> value;
446 class_getconstant(c, pindex, CONSTANT_Long);
448 f->value.l = cl -> value;
454 class_getconstant(c, pindex, CONSTANT_Float);
456 f->value.f = cf->value;
461 constant_double *cd =
462 class_getconstant(c, pindex, CONSTANT_Double);
464 f->value.d = cd->value;
470 class_getconstant(c, pindex, CONSTANT_String);
471 f->value.a = literalstring_new(u);
476 log_text ("Invalid Constant - Type");
486 /********************** Funktion: field_free **********************************/
488 static void field_free (fieldinfo *f)
493 /************** Funktion: field_display (nur zu Debug-Zwecken) ****************/
495 static void field_display (fieldinfo *f)
498 printflags (f -> flags);
500 unicode_display (f -> name);
502 unicode_display (f -> descriptor);
503 printf (" offset: %ld\n", (long int) (f -> offset) );
509 /******************************************************************************/
510 /************************* Funktionen f"ur Methods ****************************/
511 /******************************************************************************/
514 /*********************** Funktion: method_load *********************************
516 l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit
517 eine schon existierende 'methodinfo'-Struktur aus.
518 Bei allen native-Methoden wird au"serdem gleich der richtige
519 Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
520 Zeiger auf den Compiler
522 *******************************************************************************/
524 static void method_load (methodinfo *m, classinfo *c)
534 m -> flags = suck_u2 ();
535 m -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
536 m -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
539 m -> exceptiontable = NULL;
540 m -> entrypoint = NULL;
542 m -> stubroutine = NULL;
544 if (! (m->flags & ACC_NATIVE) ) {
545 m -> stubroutine = createcompilerstub (m);
548 functionptr f = native_findfunction
549 (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
552 m -> stubroutine = ncreatenativestub (f, m);
554 m -> stubroutine = createnativestub (f, m);
560 for (i=0; i<attrnum; i++) {
563 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
565 if ( aname != unicode_new_char("Code")) {
566 skipattributebody ();
569 if (m -> jcode) panic ("Two code-attributes for one method!");
572 m -> maxstack = suck_u2();
573 m -> maxlocals = suck_u2();
574 m -> jcodelength = suck_u4();
575 m -> jcode = MNEW (u1, m->jcodelength);
576 suck_nbytes (m->jcode, m->jcodelength);
577 m -> exceptiontablelength = suck_u2 ();
578 m -> exceptiontable =
579 MNEW (exceptiontable, m->exceptiontablelength);
582 count_vmcode_len += m->jcodelength + 18;
583 count_extable_len += 8 * m->exceptiontablelength;
586 for (e=0; e < m->exceptiontablelength; e++) {
588 m -> exceptiontable[e].startpc = suck_u2();
589 m -> exceptiontable[e].endpc = suck_u2();
590 m -> exceptiontable[e].handlerpc = suck_u2();
593 if (!idx) m -> exceptiontable[e].catchtype = NULL;
595 m -> exceptiontable[e].catchtype =
596 class_getconstant (c, idx, CONSTANT_Class);
600 skipattributes ( suck_u2() );
609 /********************* Funktion: method_free ***********************************
611 gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
614 *******************************************************************************/
616 static void method_free (methodinfo *m)
618 if (m->jcode) MFREE (m->jcode, u1, m->jcodelength);
619 if (m->exceptiontable)
620 MFREE (m->exceptiontable, exceptiontable, m->exceptiontablelength);
621 if (m->mcode) CFREE (m->mcode, m->mcodelength);
622 if (m->stubroutine) {
623 if (m->flags & ACC_NATIVE) removenativestub (m->stubroutine);
624 else removecompilerstub (m->stubroutine);
629 /************** Funktion: method_display (nur zu Debug-Zwecken) **************/
631 void method_display (methodinfo *m)
634 printflags (m -> flags);
636 unicode_display (m -> name);
638 unicode_display (m -> descriptor);
643 /******************** Funktion: method_canoverwrite ****************************
645 "uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch
646 ist (also mit einer Methodendefinition eine andere "uberschrieben
649 *******************************************************************************/
651 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
653 if (m->name != old->name) return false;
654 if (m->descriptor != old->descriptor) return false;
655 if (m->flags & ACC_STATIC) return false;
662 /******************************************************************************/
663 /************************ Funktionen fuer Class *******************************/
664 /******************************************************************************/
667 /******************** Funktion: class_get **************************************
669 Sucht im System die Klasse mit dem gew"unschten Namen, oder erzeugt
670 eine neue 'classinfo'-Struktur (und h"angt sie in die Liste der zu
671 ladenen Klassen ein).
673 *******************************************************************************/
675 classinfo *class_get (unicode *u)
679 if (u->class) return u->class;
682 count_class_infos += sizeof(classinfo);
694 c -> interfacescount = 0;
695 c -> interfaces = NULL;
696 c -> fieldscount = 0;
698 c -> methodscount = 0;
702 c -> instancesize = 0;
703 c -> header.vftbl = NULL;
705 c -> initialized = false;
707 unicode_setclasslink (u,c);
708 list_addlast (&unloadedclasses, c);
715 /******************** Funktion: class_getconstant ******************************
717 holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
718 Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
720 *******************************************************************************/
722 voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
724 if (pos >= c->cpcount)
725 panic ("Attempt to access constant outside range");
726 if (c->cptags[pos] != ctype) {
727 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
728 (int) ctype, (int) c->cptags[pos] );
732 return c->cpinfos[pos];
736 /********************* Funktion: class_constanttype ****************************
738 Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
741 *******************************************************************************/
743 u4 class_constanttype (classinfo *c, u4 pos)
745 if (pos >= c->cpcount)
746 panic ("Attempt to access constant outside range");
747 return c->cptags[pos];
751 /******************** Funktion: class_loadcpool ********************************
753 l"adt den gesammten ConstantPool einer Klasse.
755 Dabei werden die einzelnen Eintr"age in ein wesentlich einfachers
756 Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
757 F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
759 *******************************************************************************/
761 static void class_loadcpool (classinfo *c)
764 typedef struct forward_class { /* Diese Strukturen dienen dazu, */
765 struct forward_class *next; /* die Infos, die beim ersten */
766 u2 thisindex; /* Durchgang durch den ConstantPool */
767 u2 name_index; /* gelesen werden, aufzunehmen. */
768 } forward_class; /* Erst nachdem der ganze Pool */
769 /* gelesen wurde, k"onnen alle */
770 typedef struct forward_string { /* Felder kompletiert werden */
771 struct forward_string *next; /* (und das auch nur in der richtigen */
772 u2 thisindex; /* Reihenfolge) */
776 typedef struct forward_nameandtype {
777 struct forward_nameandtype *next;
781 } forward_nameandtype;
783 typedef struct forward_fieldmethint {
784 struct forward_fieldmethint *next;
788 u2 nameandtype_index;
789 } forward_fieldmethint;
794 long int dumpsize = dump_size ();
796 forward_class *forward_classes = NULL;
797 forward_string *forward_strings = NULL;
798 forward_nameandtype *forward_nameandtypes = NULL;
799 forward_fieldmethint *forward_fieldmethints = NULL;
801 u4 cpcount = c -> cpcount = suck_u2();
802 u1 *cptags = c -> cptags = MNEW (u1, cpcount);
803 voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
806 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
810 for (idx=0; idx<cpcount; idx++) {
811 cptags[idx] = CONSTANT_UNUSED;
816 /******* Erster Durchgang *******/
817 /* Alle Eintr"age, die nicht unmittelbar aufgel"ost werden k"onnen,
818 werden einmal `auf Vorrat' in tempor"are Strukturen eingelesen,
819 und dann am Ende nocheinmal durchgegangen */
822 while (idx < cpcount) {
826 case CONSTANT_Class: {
827 forward_class *nfc = DNEW(forward_class);
829 nfc -> next = forward_classes;
830 forward_classes = nfc;
832 nfc -> thisindex = idx;
833 nfc -> name_index = suck_u2 ();
839 case CONSTANT_Fieldref:
840 case CONSTANT_Methodref:
841 case CONSTANT_InterfaceMethodref: {
842 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
844 nff -> next = forward_fieldmethints;
845 forward_fieldmethints = nff;
847 nff -> thisindex = idx;
849 nff -> class_index = suck_u2 ();
850 nff -> nameandtype_index = suck_u2 ();
856 case CONSTANT_String: {
857 forward_string *nfs = DNEW (forward_string);
859 nfs -> next = forward_strings;
860 forward_strings = nfs;
862 nfs -> thisindex = idx;
863 nfs -> string_index = suck_u2 ();
869 case CONSTANT_NameAndType: {
870 forward_nameandtype *nfn = DNEW (forward_nameandtype);
872 nfn -> next = forward_nameandtypes;
873 forward_nameandtypes = nfn;
875 nfn -> thisindex = idx;
876 nfn -> name_index = suck_u2 ();
877 nfn -> sig_index = suck_u2 ();
883 case CONSTANT_Integer: {
884 constant_integer *ci = NEW (constant_integer);
887 count_const_pool_len += sizeof(constant_integer);
890 ci -> value = suck_s4 ();
891 cptags [idx] = CONSTANT_Integer;
898 case CONSTANT_Float: {
899 constant_float *cf = NEW (constant_float);
902 count_const_pool_len += sizeof(constant_float);
905 cf -> value = suck_float ();
906 cptags [idx] = CONSTANT_Float;
912 case CONSTANT_Long: {
913 constant_long *cl = NEW(constant_long);
916 count_const_pool_len += sizeof(constant_long);
919 cl -> value = suck_s8 ();
920 cptags [idx] = CONSTANT_Long;
926 case CONSTANT_Double: {
927 constant_double *cd = NEW(constant_double);
930 count_const_pool_len += sizeof(constant_double);
933 cd -> value = suck_double ();
934 cptags [idx] = CONSTANT_Double;
940 case CONSTANT_Utf8: {
945 cptags [idx] = CONSTANT_Utf8;
952 sprintf (logtext, "Unkown constant type: %d",(int) t);
961 /* Aufl"osen der noch unfertigen Eintr"age */
963 while (forward_classes) {
965 class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
967 if ( (name->length>0) && (name->text[0]=='[') ) {
968 checkfielddescriptor (name);
970 cptags [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
971 cpinfos [forward_classes -> thisindex] =
972 buildarraydescriptor(name->text, name->length);
976 cptags [forward_classes -> thisindex] = CONSTANT_Class;
977 cpinfos [forward_classes -> thisindex] = class_get (name);
979 forward_classes = forward_classes -> next;
983 while (forward_strings) {
985 class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
987 cptags [forward_strings -> thisindex] = CONSTANT_String;
988 cpinfos [forward_strings -> thisindex] = text;
990 forward_strings = forward_strings -> next;
993 while (forward_nameandtypes) {
994 constant_nameandtype *cn = NEW (constant_nameandtype);
997 count_const_pool_len += sizeof(constant_nameandtype);
1000 cn -> name = class_getconstant
1001 (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1002 cn -> descriptor = class_getconstant
1003 (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1005 cptags [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1006 cpinfos [forward_nameandtypes -> thisindex] = cn;
1008 forward_nameandtypes = forward_nameandtypes -> next;
1012 while (forward_fieldmethints) {
1013 constant_nameandtype *nat;
1014 constant_FMIref *fmi = NEW (constant_FMIref);
1017 count_const_pool_len += sizeof(constant_FMIref);
1020 nat = class_getconstant
1021 (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1023 fmi -> class = class_getconstant
1024 (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1025 fmi -> name = nat -> name;
1026 fmi -> descriptor = nat -> descriptor;
1028 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1029 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1031 switch (forward_fieldmethints -> tag) {
1032 case CONSTANT_Fieldref: checkfielddescriptor (fmi->descriptor);
1034 case CONSTANT_InterfaceMethodref:
1035 case CONSTANT_Methodref: checkmethoddescriptor (fmi->descriptor);
1039 forward_fieldmethints = forward_fieldmethints -> next;
1044 dump_release (dumpsize);
1048 /********************** Funktion: class_load ***********************************
1050 l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
1051 'classinfo'-Struktur mu"s bereits angelegt worden sein.
1053 Die Superklasse und die Interfaces, die diese Klasse implementiert,
1054 m"ussen zu diesem Zeitpunkt noch nicht geladen sein, die
1055 Verbindung dazu wird sp"ater in der Funktion 'class_link' hergestellt.
1057 Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
1058 und in die Liste 'unlinkedclasses' eingh"angt.
1060 *******************************************************************************/
1062 static void class_load (classinfo *c)
1069 sprintf (logtext, "Loading class: ");
1070 unicode_sprint (logtext+strlen(logtext), c->name );
1075 suck_start (c->name);
1077 if (suck_u4() != MAGIC) panic("Can not find class-file signature");
1080 if (ma != MAJOR_VERSION) {
1081 sprintf (logtext, "Can only support major version %d, but not %d",
1082 MAJOR_VERSION, (int) ma);
1085 if (mi > MINOR_VERSION) {
1086 sprintf (logtext, "Minor version %d is not yet supported.", (int) mi);
1091 class_loadcpool (c);
1093 c -> flags = suck_u2 ();
1094 suck_u2 (); /* this */
1096 if ( (i = suck_u2 () ) ) {
1097 c -> super = class_getconstant (c, i, CONSTANT_Class);
1103 c -> interfacescount = suck_u2 ();
1104 c -> interfaces = MNEW (classinfo*, c -> interfacescount);
1105 for (i=0; i < c -> interfacescount; i++) {
1106 c -> interfaces [i] =
1107 class_getconstant (c, suck_u2(), CONSTANT_Class);
1110 c -> fieldscount = suck_u2 ();
1111 c -> fields = MNEW (fieldinfo, c -> fieldscount);
1112 for (i=0; i < c -> fieldscount; i++) {
1113 field_load (&(c->fields[i]), c);
1116 c -> methodscount = suck_u2 ();
1117 c -> methods = MNEW (methodinfo, c -> methodscount);
1118 for (i=0; i < c -> methodscount; i++) {
1119 method_load (&(c -> methods [i]), c);
1123 count_class_infos += sizeof(classinfo*) * c -> interfacescount;
1124 count_class_infos += sizeof(fieldinfo) * c -> fieldscount;
1125 count_class_infos += sizeof(methodinfo) * c -> methodscount;
1129 skipattributes ( suck_u2() );
1134 list_remove (&unloadedclasses, c);
1135 list_addlast (&unlinkedclasses, c);
1140 /************** interne Funktion: class_highestinterface ***********************
1142 wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
1143 die Interfacetable einer Klasse sein mu"s.
1145 *******************************************************************************/
1147 static s4 class_highestinterface (classinfo *c)
1152 if ( ! (c->flags & ACC_INTERFACE) ) {
1153 sprintf (logtext, "Interface-methods count requested for non-interface: ");
1154 unicode_sprint (logtext+strlen(logtext), c->name);
1159 for (i=0; i<c->interfacescount; i++) {
1160 s4 h2 = class_highestinterface (c->interfaces[i]);
1167 /* class_addinterface **********************************************************
1169 wird von der Funktion class_link ben"otigt, um eine Virtual Function
1170 Table f"ur ein Interface (und alle weiteren von diesem Interface
1171 implementierten Interfaces) in eine Klasse einzutragen.
1173 *******************************************************************************/
1175 static void class_addinterface (classinfo *c, classinfo *ic)
1179 vftbl *vftbl = c->vftbl;
1181 if (i >= vftbl->interfacetablelength)
1182 panic ("Inernal error: interfacetable overflow");
1183 if (vftbl->interfacetable[-i])
1186 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1187 vftbl->interfacevftbllength[i] = 1;
1188 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
1189 vftbl->interfacetable[-i][0] = NULL;
1192 vftbl->interfacevftbllength[i] = ic->methodscount;
1193 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1196 count_vftbl_len += sizeof(methodptr) *
1197 (ic->methodscount + (ic->methodscount == 0));
1200 for (j=0; j<ic->methodscount; j++) {
1203 for (m = 0; m < sc->methodscount; m++) {
1204 methodinfo *mi = &(sc->methods[m]);
1205 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1206 vftbl->interfacetable[-i][j] =
1207 vftbl->table[mi->vftblindex];
1217 for (j = 0; j < ic->interfacescount; j++)
1218 class_addinterface(c, ic->interfaces[j]);
1222 /********************** Funktion: class_link ***********************************
1224 versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
1225 m"ussen sowol die Superklasse, als auch alle implementierten
1226 Interfaces schon gelinkt sein.
1227 Diese Funktion berechnet sowohl die L"ange (in Bytes) einer Instanz
1228 dieser Klasse, als auch die Virtual Function Tables f"ur normale
1229 Methoden als auch Interface-Methoden.
1231 Wenn die Klasse erfolgreich gelinkt werden kann, dann wird sie aus
1232 der Liste 'unlinkedclasses' ausgeh"angt, und in die Klasse 'linkedclasses'
1234 Wenn nicht, dann wird sie ans Ende der Liste 'unlinkedclasses' gestellt.
1236 Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
1237 eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
1239 *******************************************************************************/
1241 static void class_link (classinfo *c)
1243 s4 supervftbllength; /* vftbllegnth of super class */
1244 s4 vftbllength; /* vftbllength of current class */
1245 s4 interfacetablelength; /* interface table length */
1246 classinfo *super = c->super; /* super class */
1247 classinfo *ic, *c2; /* intermediate class variables */
1248 vftbl *v; /* vftbl of current class */
1249 s4 i; /* interface/method/field counter */
1252 /* check if all superclasses are already linked, if not put c at end of
1253 unlinked list and return. Additionally initialize class fields. */
1255 /* check interfaces */
1257 for (i = 0; i < c->interfacescount; i++) {
1258 ic = c->interfaces[i];
1260 list_remove(&unlinkedclasses, c);
1261 list_addlast(&unlinkedclasses, c);
1266 /* check super class */
1268 if (super == NULL) { /* class java.long.Object */
1270 c->instancesize = sizeof(java_objectheader);
1272 vftbllength = supervftbllength = 0;
1274 c->finalizer = NULL;
1277 if (!super->linked) {
1278 list_remove(&unlinkedclasses, c);
1279 list_addlast(&unlinkedclasses, c);
1283 if (c->flags & ACC_INTERFACE)
1284 c->index = interfaceindex++;
1286 c->index = super->index + 1;
1288 c->instancesize = super->instancesize;
1290 vftbllength = supervftbllength = super->vftbl->vftbllength;
1292 c->finalizer = super->finalizer;
1297 sprintf (logtext, "Linking Class: ");
1298 unicode_sprint (logtext+strlen(logtext), c->name );
1302 /* compute vftbl length */
1304 for (i = 0; i < c->methodscount; i++) {
1305 methodinfo *m = &(c->methods[i]);
1307 if (!(m->flags & ACC_STATIC)) { /* is instance method */
1308 classinfo *sc = super;
1311 for (j = 0; j < sc->methodscount; j++) {
1312 if (method_canoverwrite(m, &(sc->methods[j]))) {
1313 m->vftblindex = sc->methods[j].vftblindex;
1314 goto foundvftblindex;
1319 m->vftblindex = (vftbllength++);
1325 count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
1328 /* compute interfacetable length */
1330 interfacetablelength = 0;
1333 for (i = 0; i < c2->interfacescount; i++) {
1334 s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1335 if (h > interfacetablelength)
1336 interfacetablelength = h;
1341 /* allocate virtual function table */
1343 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
1344 (vftbllength - 1) + sizeof(methodptr*) *
1345 (interfacetablelength - (interfacetablelength > 0)));
1346 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
1347 (interfacetablelength > 1));
1348 c->header.vftbl = c->vftbl = v;
1350 v->vftbllength = vftbllength;
1351 v->interfacetablelength = interfacetablelength;
1353 /* copy virtual function table of super class */
1355 for (i = 0; i < supervftbllength; i++)
1356 v->table[i] = super->vftbl->table[i];
1358 /* add method stubs into virtual function table */
1360 for (i = 0; i < c->methodscount; i++) {
1361 methodinfo *m = &(c->methods[i]);
1362 if (!(m->flags & ACC_STATIC)) {
1363 v->table[m->vftblindex] = m->stubroutine;
1367 /* compute instance size and offset of each field */
1369 for (i = 0; i < c->fieldscount; i++) {
1371 fieldinfo *f = &(c->fields[i]);
1373 if (!(f->flags & ACC_STATIC) ) {
1374 dsize = desc_typesize (f->descriptor);
1375 c->instancesize = ALIGN (c->instancesize, dsize);
1376 f->offset = c->instancesize;
1377 c->instancesize += dsize;
1381 /* initialize interfacetable and interfacevftbllength */
1383 v->interfacevftbllength = MNEW (s4, interfacetablelength);
1386 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
1389 for (i = 0; i < interfacetablelength; i++) {
1390 v->interfacevftbllength[i] = 0;
1391 v->interfacetable[-i] = NULL;
1394 /* add interfaces */
1396 for (c2 = c; c2 != NULL; c2 = c2->super)
1397 for (i = 0; i < c2->interfacescount; i++) {
1398 class_addinterface (c, c2->interfaces[i]);
1401 /* add finalizer method (not for java.lang.Object) */
1403 if (super != NULL) {
1405 static unicode *finame = NULL;
1406 static unicode *fidesc = NULL;
1409 finame = unicode_new_char("finalize");
1411 fidesc = unicode_new_char("()V");
1413 fi = class_findmethod (c, finame, fidesc);
1415 if (!(fi->flags & ACC_STATIC)) {
1425 list_remove (&unlinkedclasses, c);
1426 list_addlast (&linkedclasses, c);
1430 /******************* Funktion: class_freepool **********************************
1432 Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
1435 *******************************************************************************/
1437 static void class_freecpool (classinfo *c)
1443 for (idx=0; idx < c->cpcount; idx++) {
1444 tag = c->cptags[idx];
1445 info = c->cpinfos[idx];
1449 case CONSTANT_Fieldref:
1450 case CONSTANT_Methodref:
1451 case CONSTANT_InterfaceMethodref:
1452 FREE (info, constant_FMIref);
1454 case CONSTANT_Integer:
1455 FREE (info, constant_integer);
1457 case CONSTANT_Float:
1458 FREE (info, constant_float);
1461 FREE (info, constant_long);
1463 case CONSTANT_Double:
1464 FREE (info, constant_double);
1466 case CONSTANT_NameAndType:
1467 FREE (info, constant_nameandtype);
1469 case CONSTANT_Arraydescriptor:
1470 freearraydescriptor (info);
1476 MFREE (c -> cptags, u1, c -> cpcount);
1477 MFREE (c -> cpinfos, voidptr, c -> cpcount);
1481 /*********************** Funktion: class_free **********************************
1483 Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
1485 *******************************************************************************/
1487 static void class_free (classinfo *c)
1492 unicode_unlinkclass (c->name);
1494 class_freecpool (c);
1496 MFREE (c->interfaces, classinfo*, c->interfacescount);
1498 for (i = 0; i < c->fieldscount; i++)
1499 field_free(&(c->fields[i]));
1500 MFREE (c->fields, fieldinfo, c->fieldscount);
1502 for (i = 0; i < c->methodscount; i++)
1503 method_free(&(c->methods[i]));
1504 MFREE (c->methods, methodinfo, c->methodscount);
1506 if ((v = c->vftbl) != NULL) {
1507 for (i = 0; i < v->interfacetablelength; i++) {
1508 MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
1510 MFREE (v->interfacevftbllength, s4, v->interfacetablelength);
1512 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
1513 sizeof(methodptr*) * (v->interfacetablelength -
1514 (v->interfacetablelength > 0));
1515 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
1516 (v->interfacetablelength > 1));
1520 FREE (c, classinfo);
1524 /************************* Funktion: class_findfield ***************************
1526 sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
1529 *******************************************************************************/
1531 fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
1534 for (i = 0; i < c->fieldscount; i++) {
1535 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1536 return &(c->fields[i]);
1538 panic ("Can not find field given in CONSTANT_Fieldref");
1543 /************************* Funktion: class_findmethod **************************
1545 sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
1547 Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
1549 *******************************************************************************/
1551 methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
1554 for (i = 0; i < c->methodscount; i++) {
1555 if ((c->methods[i].name == name) && ((desc == NULL) ||
1556 (c->methods[i].descriptor == desc)))
1557 return &(c->methods[i]);
1563 /************************* Funktion: class_resolvemethod ***********************
1565 sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
1567 *******************************************************************************/
1570 methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
1573 methodinfo *m = class_findmethod (c, name, desc);
1582 /************************* Funktion: class_issubclass **************************
1584 "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
1586 *******************************************************************************/
1588 bool class_issubclass (classinfo *sub, classinfo *super)
1591 if (!sub) return false;
1592 if (sub==super) return true;
1599 /****************** Initialisierungsfunktion f"ur eine Klasse ******************
1601 In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
1602 Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
1603 Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
1606 *******************************************************************************/
1609 extern int blockInts;
1612 void class_init (classinfo *c)
1615 java_objectheader *exceptionptr;
1619 if (!makeinitializations) return;
1620 if (c->initialized) return;
1621 c -> initialized = true;
1623 if (c->super) class_init (c->super);
1624 for (i=0; i < c->interfacescount; i++) class_init(c->interfaces[i]);
1626 m = class_findmethod (c,
1627 unicode_new_char ("<clinit>"),
1628 unicode_new_char ("()V"));
1631 sprintf (logtext, "Class ");
1632 unicode_sprint (logtext+strlen(logtext), c->name);
1633 sprintf (logtext+strlen(logtext), " has no initializer");
1639 if (! (m->flags & ACC_STATIC)) panic ("Class initializer is not static!");
1642 sprintf (logtext, "Starting initializer for class: ");
1643 unicode_sprint (logtext+strlen(logtext), c->name);
1652 exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
1655 assert(blockInts == 0);
1660 printf ("#### Initializer has thrown: ");
1661 unicode_display (exceptionptr->vftbl->class->name);
1667 sprintf (logtext, "Finished initializer for class: ");
1668 unicode_sprint (logtext+strlen(logtext), c->name);
1677 /********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/
1679 void class_showconstantpool (classinfo *c)
1684 printf ("---- dump of constant pool ----\n");
1686 for (i=0; i<c->cpcount; i++) {
1687 printf ("#%d: ", (int) i);
1689 e = c -> cpinfos [i];
1692 switch (c -> cptags [i]) {
1693 case CONSTANT_Class:
1694 printf ("Classreference -> ");
1695 unicode_display ( ((classinfo*)e) -> name );
1698 case CONSTANT_Fieldref:
1699 printf ("Fieldref -> "); goto displayFMI;
1700 case CONSTANT_Methodref:
1701 printf ("Methodref -> "); goto displayFMI;
1702 case CONSTANT_InterfaceMethodref:
1703 printf ("InterfaceMethod -> "); goto displayFMI;
1706 constant_FMIref *fmi = e;
1707 unicode_display ( fmi->class->name );
1709 unicode_display ( fmi->name);
1711 unicode_display ( fmi->descriptor );
1715 case CONSTANT_String:
1716 printf ("String -> ");
1717 unicode_display (e);
1719 case CONSTANT_Integer:
1720 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1722 case CONSTANT_Float:
1723 printf ("Float -> %f", ((constant_float*)e) -> value);
1725 case CONSTANT_Double:
1726 printf ("Double -> %f", ((constant_double*)e) -> value);
1730 u8 v = ((constant_long*)e) -> value;
1732 printf ("Long -> %ld", (long int) v);
1734 printf ("Long -> HI: %ld, LO: %ld\n",
1735 (long int) v.high, (long int) v.low);
1739 case CONSTANT_NameAndType:
1740 { constant_nameandtype *cnt = e;
1741 printf ("NameAndType: ");
1742 unicode_display (cnt->name);
1744 unicode_display (cnt->descriptor);
1748 printf ("Utf8 -> ");
1749 unicode_display (e);
1751 case CONSTANT_Arraydescriptor: {
1752 printf ("Arraydescriptor: ");
1753 displayarraydescriptor (e);
1757 panic ("Invalid type of ConstantPool-Entry");
1769 /********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/
1771 void class_showmethods (classinfo *c)
1775 printf ("--------- Fields and Methods ----------------\n");
1776 printf ("Flags: "); printflags (c->flags); printf ("\n");
1778 printf ("This: "); unicode_display (c->name); printf ("\n");
1780 printf ("Super: "); unicode_display (c->super->name); printf ("\n");
1782 printf ("Index: %d\n", c->index);
1784 printf ("interfaces:\n");
1785 for (i=0; i < c-> interfacescount; i++) {
1787 unicode_display (c -> interfaces[i] -> name);
1788 printf (" (%d)\n", c->interfaces[i] -> index);
1791 printf ("fields:\n");
1792 for (i=0; i < c -> fieldscount; i++) {
1793 field_display (&(c -> fields[i]));
1796 printf ("methods:\n");
1797 for (i=0; i < c -> methodscount; i++) {
1798 methodinfo *m = &(c->methods[i]);
1799 if ( !(m->flags & ACC_STATIC))
1800 printf ("vftblindex: %d ", m->vftblindex);
1802 method_display ( m );
1806 printf ("Virtual function table:\n");
1807 for (i=0; i<c->vftbl->vftbllength; i++) {
1808 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1815 /******************************************************************************/
1816 /******************* Funktionen fuer den Class-loader generell ****************/
1817 /******************************************************************************/
1820 /********************* Funktion: loader_load ***********************************
1822 l"adt und linkt die ge"unschte Klasse und alle davon
1823 referenzierten Klassen und Interfaces
1824 Return: Einen Zeiger auf diese Klasse
1826 *******************************************************************************/
1828 classinfo *loader_load (unicode *topname)
1832 long int starttime=0,stoptime=0;
1834 intsDisable(); /* schani */
1836 if (getloadingtime) starttime = getcputime();
1838 top = class_get (topname);
1840 while ( (c = list_first(&unloadedclasses)) ) {
1844 while ( (c = list_first(&unlinkedclasses)) ) {
1848 if (getloadingtime) {
1849 stoptime = getcputime();
1850 loadingtime += (stoptime-starttime);
1853 intsRestore(); /* schani */
1859 /******************* interne Funktion: loader_createarrayclass *****************
1861 Erzeugt (und linkt) eine Klasse f"ur die Arrays.
1863 *******************************************************************************/
1865 static classinfo *loader_createarrayclass ()
1868 c = class_get ( unicode_new_char ("The_Array_Class") );
1870 list_remove (&unloadedclasses, c);
1871 list_addlast (&unlinkedclasses, c);
1872 c -> super = class_java_lang_Object;
1880 /********************** Funktion: loader_init **********************************
1882 Initialisiert alle Listen und l"adt alle Klassen, die vom System
1883 und vom Compiler direkt ben"otigt werden.
1885 *******************************************************************************/
1891 list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
1892 list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
1893 list_init (&linkedclasses, OFFSET(classinfo, listnode) );
1896 class_java_lang_Object =
1897 loader_load ( unicode_new_char ("java/lang/Object") );
1898 class_java_lang_String =
1899 loader_load ( unicode_new_char ("java/lang/String") );
1900 class_java_lang_ClassCastException =
1901 loader_load ( unicode_new_char ("java/lang/ClassCastException") );
1902 class_java_lang_NullPointerException =
1903 loader_load ( unicode_new_char ("java/lang/NullPointerException") );
1904 class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
1905 unicode_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
1906 class_java_lang_NegativeArraySizeException = loader_load (
1907 unicode_new_char ("java/lang/NegativeArraySizeException") );
1908 class_java_lang_OutOfMemoryError = loader_load (
1909 unicode_new_char ("java/lang/OutOfMemoryError") );
1910 class_java_lang_ArrayStoreException =
1911 loader_load ( unicode_new_char ("java/lang/ArrayStoreException") );
1912 class_java_lang_ArithmeticException =
1913 loader_load ( unicode_new_char ("java/lang/ArithmeticException") );
1914 class_java_lang_ThreadDeath = /* schani */
1915 loader_load ( unicode_new_char ("java/lang/ThreadDeath") );
1917 class_array = loader_createarrayclass ();
1920 proto_java_lang_ClassCastException =
1921 builtin_new(class_java_lang_ClassCastException);
1922 heap_addreference ( (void**) &proto_java_lang_ClassCastException);
1924 proto_java_lang_NullPointerException =
1925 builtin_new(class_java_lang_NullPointerException);
1926 heap_addreference ( (void**) &proto_java_lang_NullPointerException);
1928 proto_java_lang_ArrayIndexOutOfBoundsException =
1929 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
1930 heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
1932 proto_java_lang_NegativeArraySizeException =
1933 builtin_new(class_java_lang_NegativeArraySizeException);
1934 heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
1936 proto_java_lang_OutOfMemoryError =
1937 builtin_new(class_java_lang_OutOfMemoryError);
1938 heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
1940 proto_java_lang_ArithmeticException =
1941 builtin_new(class_java_lang_ArithmeticException);
1942 heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
1944 proto_java_lang_ArrayStoreException =
1945 builtin_new(class_java_lang_ArrayStoreException);
1946 heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
1948 proto_java_lang_ThreadDeath = /* schani */
1949 builtin_new(class_java_lang_ThreadDeath);
1950 heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
1956 /********************* Funktion: loader_initclasses ****************************
1958 initialisiert alle geladenen aber noch nicht initialisierten Klassen
1960 *******************************************************************************/
1962 void loader_initclasses ()
1966 intsDisable(); /* schani */
1968 if (makeinitializations) {
1969 c = list_first (&linkedclasses);
1972 c = list_next (&linkedclasses, c);
1976 intsRestore(); /* schani */
1979 static s4 classvalue = 0;
1981 static void loader_compute_class_values (classinfo *c)
1985 c->vftbl->baseval = ++classvalue;
1987 while (subs != NULL) {
1988 loader_compute_class_values(subs);
1989 subs = subs->nextsub;
1991 c->vftbl->diffval = classvalue - c->vftbl->baseval;
1995 for (i = 0; i < c->index; i++)
1997 printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval);
1998 unicode_display(c->name);
2005 void loader_compute_subclasses ()
2009 intsDisable(); /* schani */
2011 c = list_first (&linkedclasses);
2013 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
2014 c->nextsub = c->super->sub;
2017 c = list_next (&linkedclasses, c);
2020 loader_compute_class_values(class_java_lang_Object);
2022 intsRestore(); /* schani */
2027 /******************** Funktion: loader_close ***********************************
2029 gibt alle Resourcen wieder frei
2031 *******************************************************************************/
2033 void loader_close ()
2037 while ( (c=list_first(&unloadedclasses)) ) {
2038 list_remove (&unloadedclasses,c);
2041 while ( (c=list_first(&unlinkedclasses)) ) {
2042 list_remove (&unlinkedclasses,c);
2045 while ( (c=list_first(&linkedclasses)) ) {
2046 list_remove (&linkedclasses,c);
2053 * These are local overrides for various environment variables in Emacs.
2054 * Please do not remove this and leave it at the end of the file, where
2055 * Emacs will automagically detect them.
2056 * ---------------------------------------------------------------------
2059 * indent-tabs-mode: t