1 /* -*- mode: c; tab-width: 4; c-basic-offset: 4 -*- */
2 /****************************** loader.c ***************************************
4 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
6 See file COPYRIGHT for information on usage and disclaimer of warranties
8 Contains the functions of the class loader.
10 Author: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
11 Changes: Mark Probst EMAIL: cacao@complang.tuwien.ac.at
13 Last Change: 1997/06/03
15 *******************************************************************************/
29 #include "threads/thread.h" /* schani */
32 /*************************** globale Variablen *******************************/
34 extern bool newcompiler;
36 int count_class_infos = 0;
37 int count_const_pool_len = 0;
38 int count_vftbl_len = 0;
39 int count_all_methods = 0;
40 int count_vmcode_len = 0;
41 int count_extable_len = 0;
43 bool loadverbose = false; /* Switches f"ur mehr Debug-Meldungen */
44 bool linkverbose = false;
45 bool initverbose = false;
47 bool makeinitializations = true;
49 bool getloadingtime = false;
50 long int loadingtime = 0;
53 static u4 interfaceindex; /* fortlaufende Nummer f"ur Interfaces */
55 static list unloadedclasses; /* Liste alle referenzierten, aber noch nicht
57 static list unlinkedclasses; /* Liste aller geladenen, aber noch nicht
59 list linkedclasses; /* Liste aller fertig gelinkten Klassen */
63 /***************** die Referenzen auf die wichtigen Systemklassen ************/
65 classinfo *class_java_lang_Object;
66 classinfo *class_java_lang_String;
67 classinfo *class_java_lang_ClassCastException;
68 classinfo *class_java_lang_NullPointerException;
69 classinfo *class_java_lang_ArrayIndexOutOfBoundsException;
70 classinfo *class_java_lang_NegativeArraySizeException;
71 classinfo *class_java_lang_OutOfMemoryError;
72 classinfo *class_java_lang_ArithmeticException;
73 classinfo *class_java_lang_ArrayStoreException;
74 classinfo *class_java_lang_ThreadDeath; /* schani */
76 classinfo *class_array;
79 /************ einige vorgefertigte Instanzen wichtiger Systemklassen *********/
81 java_objectheader *proto_java_lang_ClassCastException;
82 java_objectheader *proto_java_lang_NullPointerException;
83 java_objectheader *proto_java_lang_ArrayIndexOutOfBoundsException;
84 java_objectheader *proto_java_lang_NegativeArraySizeException;
85 java_objectheader *proto_java_lang_OutOfMemoryError;
86 java_objectheader *proto_java_lang_ArithmeticException;
87 java_objectheader *proto_java_lang_ArrayStoreException;
88 java_objectheader *proto_java_lang_ThreadDeath; /* schani */
93 /****************************************************************************/
94 /******************* Einige Support-Funkionen *******************************/
95 /****************************************************************************/
98 /********** interne Funktion: printflags (nur zu Debug-Zwecken) ************/
100 static void printflags (u2 f)
102 if ( f & ACC_PUBLIC ) printf (" PUBLIC");
103 if ( f & ACC_PRIVATE ) printf (" PRIVATE");
104 if ( f & ACC_PROTECTED ) printf (" PROTECTED");
105 if ( f & ACC_STATIC ) printf (" STATIC");
106 if ( f & ACC_FINAL ) printf (" FINAL");
107 if ( f & ACC_SYNCHRONIZED ) printf (" SYNCHRONIZED");
108 if ( f & ACC_VOLATILE ) printf (" VOLATILE");
109 if ( f & ACC_TRANSIENT ) printf (" TRANSIENT");
110 if ( f & ACC_NATIVE ) printf (" NATIVE");
111 if ( f & ACC_INTERFACE ) printf (" INTERFACE");
112 if ( f & ACC_ABSTRACT ) printf (" ABSTRACT");
116 /************************* Funktion: skipattribute ****************************
118 "uberliest im ClassFile eine (1) 'attribute'-Struktur
120 ******************************************************************************/
122 static void skipattribute ()
131 /********************** Funktion: skipattributebody ***************************
133 "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name -
134 Referenz schon gelesen worden ist.
136 ******************************************************************************/
138 static void skipattributebody ()
145 /************************* Funktion: skipattributes ***************************
147 "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
149 ******************************************************************************/
151 static void skipattributes (u4 num)
154 for (i=0; i<num; i++) skipattribute();
159 /************************** Funktion: loadUtf8 ********************************
161 liest aus dem ClassFile einen Utf8-String (=komprimierter unicode-text)
162 und legt daf"ur ein unicode-Symbol an.
163 Return: Zeiger auf das Symbol
165 ******************************************************************************/
167 #define MAXUNICODELEN 5000
168 static u2 unicodebuffer[MAXUNICODELEN];
170 static unicode *loadUtf8 ()
184 if (b1<0x80) letter = b1;
188 if (b1<0xe0) letter = ((b1 & 0x1f) << 6) | (b2 & 0x3f);
192 letter = ((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
197 if (unicodelen >= MAXUNICODELEN) {
198 panic ("String constant too long");
201 unicodebuffer[unicodelen++] = letter;
205 return unicode_new_u2 (unicodebuffer, unicodelen);
210 /******************** interne Funktion: checkfieldtype ***********************/
212 static void checkfieldtype (u2 *text, u4 *count, u4 length)
216 if (*count >= length) panic ("Type-descriptor exceeds unicode length");
218 l = text[(*count)++];
221 default: panic ("Invalid symbol in type descriptor");
232 case '[': checkfieldtype (text, count, length);
237 u4 tlen,tstart = *count;
239 if (*count >= length)
240 panic ("Objecttype descriptor of length zero");
242 while ( text[*count] != ';' ) {
244 if (*count >= length)
245 panic ("Missing ';' in objecttype-descriptor");
248 tlen = (*count) - tstart;
251 if (tlen == 0) panic ("Objecttype descriptor with empty name");
253 class_get ( unicode_new_u2 (text+tstart, tlen) );
259 /******************* Funktion: checkfielddescriptor ***************************
261 "uberpr"uft, ob ein Field-Descriptor ein g"ultiges Format hat.
262 Wenn nicht, dann wird das System angehalten.
263 Au"serdem werden alle Klassen, die hier referenziert werden,
264 in die Liste zu ladender Klassen eingetragen.
266 ******************************************************************************/
268 void checkfielddescriptor (unicode *d)
271 checkfieldtype (d->text, &count, d->length);
272 if (count != d->length) panic ("Invalid type-descritor encountered");
276 /******************* Funktion: checkmethoddescriptor **************************
278 "uberpr"uft, ob ein Method-Descriptor ein g"ultiges Format hat.
279 Wenn nicht, dann wird das System angehalten.
280 Au"serdem werden alle Klassen, die hier referenziert werden,
281 in die Liste zu ladender Klassen eingetragen.
283 ******************************************************************************/
285 void checkmethoddescriptor (unicode *d)
291 if (length<2) panic ("Method descriptor too short");
292 if (text[0] != '(') panic ("Missing '(' in method descriptor");
295 while (text[count] != ')') {
296 checkfieldtype (text,&count,length);
297 if ( count > length-2 ) panic ("Unexpected end of descriptor");
301 if (text[count] == 'V') count++;
302 else checkfieldtype (text, &count,length);
304 if (count != length) panic ("Method-descriptor has exceeding chars");
308 /******************** Funktion: buildarraydescriptor ****************************
310 erzeugt zu einem namentlich als u2-String vorliegenden Arraytyp eine
311 entsprechende constant_arraydescriptor - Struktur
313 ********************************************************************************/
315 static constant_arraydescriptor * buildarraydescriptor(u2 *name, u4 namelen)
317 constant_arraydescriptor *d;
319 if (name[0]!='[') panic ("Attempt to build arraydescriptor for non-array");
320 d = NEW (constant_arraydescriptor);
321 d -> objectclass = NULL;
322 d -> elementdescriptor = NULL;
325 count_const_pool_len += sizeof(constant_arraydescriptor);
329 case 'Z': d -> arraytype = ARRAYTYPE_BOOLEAN; break;
330 case 'B': d -> arraytype = ARRAYTYPE_BYTE; break;
331 case 'C': d -> arraytype = ARRAYTYPE_CHAR; break;
332 case 'D': d -> arraytype = ARRAYTYPE_DOUBLE; break;
333 case 'F': d -> arraytype = ARRAYTYPE_FLOAT; break;
334 case 'I': d -> arraytype = ARRAYTYPE_INT; break;
335 case 'J': d -> arraytype = ARRAYTYPE_LONG; break;
336 case 'S': d -> arraytype = ARRAYTYPE_SHORT; break;
339 d -> arraytype = ARRAYTYPE_ARRAY;
340 d -> elementdescriptor = buildarraydescriptor (name+1, namelen-1);
344 d -> arraytype = ARRAYTYPE_OBJECT;
345 d -> objectclass = class_get ( unicode_new_u2 (name+2, namelen-3) );
352 /******************* Funktion: freearraydescriptor ****************************
354 entfernt eine mit buildarraydescriptor erzeugte Struktur wieder
357 *******************************************************************************/
359 static void freearraydescriptor (constant_arraydescriptor *d)
362 constant_arraydescriptor *n = d->elementdescriptor;
363 FREE (d, constant_arraydescriptor);
368 /*********************** Funktion: displayarraydescriptor *********************/
370 static void displayarraydescriptor (constant_arraydescriptor *d)
372 switch (d->arraytype) {
373 case ARRAYTYPE_BOOLEAN: printf ("boolean[]"); break;
374 case ARRAYTYPE_BYTE: printf ("byte[]"); break;
375 case ARRAYTYPE_CHAR: printf ("char[]"); break;
376 case ARRAYTYPE_DOUBLE: printf ("double[]"); break;
377 case ARRAYTYPE_FLOAT: printf ("float[]"); break;
378 case ARRAYTYPE_INT: printf ("int[]"); break;
379 case ARRAYTYPE_LONG: printf ("long[]"); break;
380 case ARRAYTYPE_SHORT: printf ("short[]"); break;
381 case ARRAYTYPE_ARRAY: displayarraydescriptor(d->elementdescriptor); printf("[]"); break;
382 case ARRAYTYPE_OBJECT: unicode_display(d->objectclass->name); printf("[]"); break;
388 /*****************************************************************************/
389 /******************** Funktionen fuer Fields *********************************/
390 /*****************************************************************************/
393 /************************ Funktion: field_load ********************************
395 l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
396 und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
397 Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
400 ******************************************************************************/
402 static void field_load (fieldinfo *f, classinfo *c)
407 f -> flags = suck_u2 ();
408 f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
409 f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
410 f -> type = jtype = desc_to_type (f->descriptor);
414 case TYPE_INT: f->value.i = 0; break;
415 case TYPE_FLOAT: f->value.f = 0.0; break;
416 case TYPE_DOUBLE: f->value.d = 0.0; break;
417 case TYPE_ADDRESS: f->value.a = NULL;
418 heap_addreference (&(f->value.a));
422 f->value.l = 0; break;
424 f->value.l.low = 0; f->value.l.high = 0; break;
429 for (i=0; i<attrnum; i++) {
433 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
435 if ( aname != unicode_new_char ("ConstantValue") ) {
436 skipattributebody ();
444 constant_integer *ci =
445 class_getconstant(c, pindex, CONSTANT_Integer);
446 f->value.i = ci -> value;
452 class_getconstant(c, pindex, CONSTANT_Long);
454 f->value.l = cl -> value;
460 class_getconstant(c, pindex, CONSTANT_Float);
462 f->value.f = cf->value;
467 constant_double *cd =
468 class_getconstant(c, pindex, CONSTANT_Double);
470 f->value.d = cd->value;
476 class_getconstant(c, pindex, CONSTANT_String);
477 f->value.a = literalstring_new(u);
482 log_text ("Invalid Constant - Type");
492 /********************** Funktion: field_free *********************************/
494 static void field_free (fieldinfo *f)
499 /************** Funktion: field_display (nur zu Debug-Zwecken) ***************/
501 static void field_display (fieldinfo *f)
504 printflags (f -> flags);
506 unicode_display (f -> name);
508 unicode_display (f -> descriptor);
509 printf (" offset: %ld\n", (long int) (f -> offset) );
515 /*****************************************************************************/
516 /************************* Funktionen f"ur Methods ***************************/
517 /*****************************************************************************/
520 /*********************** Funktion: method_load ********************************
522 l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit
523 eine schon existierende 'methodinfo'-Struktur aus.
524 Bei allen native-Methoden wird au"serdem gleich der richtige
525 Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
526 Zeiger auf den Compiler
528 ******************************************************************************/
530 static void method_load (methodinfo *m, classinfo *c)
540 m -> flags = suck_u2 ();
541 m -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
542 m -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
545 m -> exceptiontable = NULL;
546 m -> entrypoint = NULL;
548 m -> stubroutine = NULL;
550 if (! (m->flags & ACC_NATIVE) ) {
551 m -> stubroutine = createcompilerstub (m);
554 functionptr f = native_findfunction
555 (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
558 m -> stubroutine = ncreatenativestub (f, m);
560 m -> stubroutine = createnativestub (f, m);
566 for (i=0; i<attrnum; i++) {
569 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
571 if ( aname != unicode_new_char("Code")) {
572 skipattributebody ();
575 if (m -> jcode) panic ("Two code-attributes for one method!");
578 m -> maxstack = suck_u2();
579 m -> maxlocals = suck_u2();
580 m -> jcodelength = suck_u4();
581 m -> jcode = MNEW (u1, m->jcodelength);
582 suck_nbytes (m->jcode, m->jcodelength);
583 m -> exceptiontablelength = suck_u2 ();
584 m -> exceptiontable =
585 MNEW (exceptiontable, m->exceptiontablelength);
588 count_vmcode_len += m->jcodelength + 18;
589 count_extable_len += 8 * m->exceptiontablelength;
592 for (e=0; e < m->exceptiontablelength; e++) {
594 m -> exceptiontable[e].startpc = suck_u2();
595 m -> exceptiontable[e].endpc = suck_u2();
596 m -> exceptiontable[e].handlerpc = suck_u2();
599 if (!idx) m -> exceptiontable[e].catchtype = NULL;
601 m -> exceptiontable[e].catchtype =
602 class_getconstant (c, idx, CONSTANT_Class);
606 skipattributes ( suck_u2() );
615 /********************* Funktion: method_free **********************************
617 gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
620 ******************************************************************************/
622 static void method_free (methodinfo *m)
624 if (m->jcode) MFREE (m->jcode, u1, m->jcodelength);
625 if (m->exceptiontable)
626 MFREE (m->exceptiontable, exceptiontable, m->exceptiontablelength);
627 if (m->mcode) CFREE (m->mcode, m->mcodelength);
628 if (m->stubroutine) {
629 if (m->flags & ACC_NATIVE) removenativestub (m->stubroutine);
630 else removecompilerstub (m->stubroutine);
635 /************** Funktion: method_display (nur zu Debug-Zwecken) *************/
637 void method_display (methodinfo *m)
640 printflags (m -> flags);
642 unicode_display (m -> name);
644 unicode_display (m -> descriptor);
649 /******************** Funktion: method_canoverwrite ***************************
651 "uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch
652 ist (also mit einer Methodendefinition eine andere "uberschrieben
655 ******************************************************************************/
657 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
659 if (m->name != old->name) return false;
660 if (m->descriptor != old->descriptor) return false;
661 if (m->flags & ACC_STATIC) return false;
668 /*****************************************************************************/
669 /************************ Funktionen fuer Class ******************************/
670 /*****************************************************************************/
673 /******************** Funktion: class_get *************************************
675 Sucht im System die Klasse mit dem gew"unschten Namen, oder erzeugt
676 eine neue 'classinfo'-Struktur (und h"angt sie in die Liste der zu
677 ladenen Klassen ein).
679 ******************************************************************************/
681 classinfo *class_get (unicode *u)
685 if (u->class) return u->class;
688 count_class_infos += sizeof(classinfo);
700 c -> interfacescount = 0;
701 c -> interfaces = NULL;
702 c -> fieldscount = 0;
704 c -> methodscount = 0;
708 c -> instancesize = 0;
710 c -> initialized = false;
712 unicode_setclasslink (u,c);
713 list_addlast (&unloadedclasses, c);
720 /******************** Funktion: class_getconstant *****************************
722 holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
723 Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
725 ******************************************************************************/
727 voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
729 if (pos >= c->cpcount)
730 panic ("Attempt to access constant outside range");
731 if (c->cptags[pos] != ctype) {
732 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
733 (int) ctype, (int) c->cptags[pos] );
737 return c->cpinfos[pos];
741 /********************* Funktion: class_constanttype ***************************
743 Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
746 ******************************************************************************/
748 u4 class_constanttype (classinfo *c, u4 pos)
750 if (pos >= c->cpcount)
751 panic ("Attempt to access constant outside range");
752 return c->cptags[pos];
756 /******************** Funktion: class_loadcpool *******************************
758 l"adt den gesammten ConstantPool einer Klasse.
760 Dabei werden die einzelnen Eintr"age in ein wesentlich einfachers
761 Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
762 F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
764 ******************************************************************************/
766 static void class_loadcpool (classinfo *c)
769 typedef struct forward_class { /* Diese Strukturen dienen dazu, */
770 struct forward_class *next; /* die Infos, die beim ersten */
771 u2 thisindex; /* Durchgang durch den ConstantPool */
772 u2 name_index; /* gelesen werden, aufzunehmen. */
773 } forward_class; /* Erst nachdem der ganze Pool */
774 /* gelesen wurde, k"onnen alle */
775 typedef struct forward_string { /* Felder kompletiert werden */
776 struct forward_string *next; /* (und das auch nur in der richtigen */
777 u2 thisindex; /* Reihenfolge) */
781 typedef struct forward_nameandtype {
782 struct forward_nameandtype *next;
786 } forward_nameandtype;
788 typedef struct forward_fieldmethint {
789 struct forward_fieldmethint *next;
793 u2 nameandtype_index;
794 } forward_fieldmethint;
799 long int dumpsize = dump_size ();
801 forward_class *forward_classes = NULL;
802 forward_string *forward_strings = NULL;
803 forward_nameandtype *forward_nameandtypes = NULL;
804 forward_fieldmethint *forward_fieldmethints = NULL;
806 u4 cpcount = c -> cpcount = suck_u2();
807 u1 *cptags = c -> cptags = MNEW (u1, cpcount);
808 voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
811 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
815 for (idx=0; idx<cpcount; idx++) {
816 cptags[idx] = CONSTANT_UNUSED;
821 /******* Erster Durchgang *******/
822 /* Alle Eintr"age, die nicht unmittelbar aufgel"ost werden k"onnen,
823 werden einmal `auf Vorrat' in tempor"are Strukturen eingelesen,
824 und dann am Ende nocheinmal durchgegangen */
827 while (idx < cpcount) {
831 case CONSTANT_Class: {
832 forward_class *nfc = DNEW(forward_class);
834 nfc -> next = forward_classes;
835 forward_classes = nfc;
837 nfc -> thisindex = idx;
838 nfc -> name_index = suck_u2 ();
844 case CONSTANT_Fieldref:
845 case CONSTANT_Methodref:
846 case CONSTANT_InterfaceMethodref: {
847 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
849 nff -> next = forward_fieldmethints;
850 forward_fieldmethints = nff;
852 nff -> thisindex = idx;
854 nff -> class_index = suck_u2 ();
855 nff -> nameandtype_index = suck_u2 ();
861 case CONSTANT_String: {
862 forward_string *nfs = DNEW (forward_string);
864 nfs -> next = forward_strings;
865 forward_strings = nfs;
867 nfs -> thisindex = idx;
868 nfs -> string_index = suck_u2 ();
874 case CONSTANT_NameAndType: {
875 forward_nameandtype *nfn = DNEW (forward_nameandtype);
877 nfn -> next = forward_nameandtypes;
878 forward_nameandtypes = nfn;
880 nfn -> thisindex = idx;
881 nfn -> name_index = suck_u2 ();
882 nfn -> sig_index = suck_u2 ();
888 case CONSTANT_Integer: {
889 constant_integer *ci = NEW (constant_integer);
892 count_const_pool_len += sizeof(constant_integer);
895 ci -> value = suck_s4 ();
896 cptags [idx] = CONSTANT_Integer;
903 case CONSTANT_Float: {
904 constant_float *cf = NEW (constant_float);
907 count_const_pool_len += sizeof(constant_float);
910 cf -> value = suck_float ();
911 cptags [idx] = CONSTANT_Float;
917 case CONSTANT_Long: {
918 constant_long *cl = NEW(constant_long);
921 count_const_pool_len += sizeof(constant_long);
924 cl -> value = suck_s8 ();
925 cptags [idx] = CONSTANT_Long;
931 case CONSTANT_Double: {
932 constant_double *cd = NEW(constant_double);
935 count_const_pool_len += sizeof(constant_double);
938 cd -> value = suck_double ();
939 cptags [idx] = CONSTANT_Double;
945 case CONSTANT_Utf8: {
950 cptags [idx] = CONSTANT_Utf8;
957 sprintf (logtext, "Unkown constant type: %d",(int) t);
966 /* Aufl"osen der noch unfertigen Eintr"age */
968 while (forward_classes) {
970 class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
972 if ( (name->length>0) && (name->text[0]=='[') ) {
973 checkfielddescriptor (name);
975 cptags [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
976 cpinfos [forward_classes -> thisindex] =
977 buildarraydescriptor(name->text, name->length);
981 cptags [forward_classes -> thisindex] = CONSTANT_Class;
982 cpinfos [forward_classes -> thisindex] = class_get (name);
984 forward_classes = forward_classes -> next;
988 while (forward_strings) {
990 class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
992 cptags [forward_strings -> thisindex] = CONSTANT_String;
993 cpinfos [forward_strings -> thisindex] = text;
995 forward_strings = forward_strings -> next;
998 while (forward_nameandtypes) {
999 constant_nameandtype *cn = NEW (constant_nameandtype);
1002 count_const_pool_len += sizeof(constant_nameandtype);
1005 cn -> name = class_getconstant
1006 (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1007 cn -> descriptor = class_getconstant
1008 (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1010 cptags [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1011 cpinfos [forward_nameandtypes -> thisindex] = cn;
1013 forward_nameandtypes = forward_nameandtypes -> next;
1017 while (forward_fieldmethints) {
1018 constant_nameandtype *nat;
1019 constant_FMIref *fmi = NEW (constant_FMIref);
1022 count_const_pool_len += sizeof(constant_FMIref);
1025 nat = class_getconstant
1026 (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1028 fmi -> class = class_getconstant
1029 (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1030 fmi -> name = nat -> name;
1031 fmi -> descriptor = nat -> descriptor;
1033 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1034 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1036 switch (forward_fieldmethints -> tag) {
1037 case CONSTANT_Fieldref: checkfielddescriptor (fmi->descriptor);
1039 case CONSTANT_InterfaceMethodref:
1040 case CONSTANT_Methodref: checkmethoddescriptor (fmi->descriptor);
1044 forward_fieldmethints = forward_fieldmethints -> next;
1049 dump_release (dumpsize);
1053 /********************** Funktion: class_load **********************************
1055 l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
1056 'classinfo'-Struktur mu"s bereits angelegt worden sein.
1058 Die Superklasse und die Interfaces, die diese Klasse implementiert,
1059 m"ussen zu diesem Zeitpunkt noch nicht geladen sein, die
1060 Verbindung dazu wird sp"ater in der Funktion 'class_link' hergestellt.
1062 Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
1063 und in die Liste 'unlinkedclasses' eingh"angt.
1065 ******************************************************************************/
1067 static void class_load (classinfo *c)
1074 sprintf (logtext, "Loading class: ");
1075 unicode_sprint (logtext+strlen(logtext), c->name );
1080 suck_start (c->name);
1082 if (suck_u4() != MAGIC) panic("Can not find class-file signature");
1085 if (ma != MAJOR_VERSION) {
1086 sprintf (logtext, "Can only support major version %d, but not %d",
1087 MAJOR_VERSION, (int) ma);
1090 if (mi > MINOR_VERSION) {
1091 sprintf (logtext, "Minor version %d is not yet supported.", (int) mi);
1096 class_loadcpool (c);
1098 c -> flags = suck_u2 ();
1099 suck_u2 (); /* this */
1101 if ( (i = suck_u2 () ) ) {
1102 c -> super = class_getconstant (c, i, CONSTANT_Class);
1108 c -> interfacescount = suck_u2 ();
1109 c -> interfaces = MNEW (classinfo*, c -> interfacescount);
1110 for (i=0; i < c -> interfacescount; i++) {
1111 c -> interfaces [i] =
1112 class_getconstant (c, suck_u2(), CONSTANT_Class);
1115 c -> fieldscount = suck_u2 ();
1116 c -> fields = MNEW (fieldinfo, c -> fieldscount);
1117 for (i=0; i < c -> fieldscount; i++) {
1118 field_load (&(c->fields[i]), c);
1121 c -> methodscount = suck_u2 ();
1122 c -> methods = MNEW (methodinfo, c -> methodscount);
1123 for (i=0; i < c -> methodscount; i++) {
1124 method_load (&(c -> methods [i]), c);
1128 count_class_infos += sizeof(classinfo*) * c -> interfacescount;
1129 count_class_infos += sizeof(fieldinfo) * c -> fieldscount;
1130 count_class_infos += sizeof(methodinfo) * c -> methodscount;
1134 skipattributes ( suck_u2() );
1139 list_remove (&unloadedclasses, c);
1140 list_addlast (&unlinkedclasses, c);
1145 /************** interne Funktion: class_highestinterface **********************
1147 wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
1148 die Interfacetable einer Klasse sein mu"s.
1150 ******************************************************************************/
1152 static s4 class_highestinterface (classinfo *c)
1157 if ( ! (c->flags & ACC_INTERFACE) ) {
1158 sprintf (logtext, "Interface-methods count requested for non-interface: ");
1159 unicode_sprint (logtext+strlen(logtext), c->name);
1164 for (i=0; i<c->interfacescount; i++) {
1165 s4 h2 = class_highestinterface (c->interfaces[i]);
1172 /**************** Funktion: class_addinterface ********************************
1174 wird von der Funktion class_link ben"otigt, um eine Virtual Function
1175 Table f"ur ein Interface (und alle weiteren von diesem Interface
1176 implementierten Interfaces) in eine Klasse einzutragen.
1178 ******************************************************************************/
1180 static void class_addinterface (classinfo *c, classinfo *ic)
1184 vftbl *vftbl = c->vftbl;
1186 if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow");
1187 if (vftbl->interfacevftbl[i]) return;
1189 if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann
1190 trotzdem eine Tabelle mit L"ange 1 anlegen,
1191 wegen Subclass-Tests */
1192 vftbl -> interfacevftbllength[i] = 1;
1193 vftbl -> interfacevftbl[i] = MNEW(methodptr, 1);
1194 vftbl -> interfacevftbl[i][0] = NULL;
1197 vftbl -> interfacevftbllength[i] = ic -> methodscount;
1198 vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount);
1201 count_vftbl_len += sizeof(methodptr) * ic -> methodscount;
1204 for (j=0; j<ic->methodscount; j++) {
1207 for (m=0; m<sc->methodscount; m++) {
1208 methodinfo *mi = &(sc->methods[m]);
1209 if (method_canoverwrite (mi, &(ic->methods[j])) ) {
1210 vftbl->interfacevftbl[i][j] =
1211 vftbl->table[mi->vftblindex];
1221 for (j=0; j<ic->interfacescount; j++)
1222 class_addinterface(c, ic->interfaces[j]);
1226 /********************** Funktion: class_link **********************************
1228 versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
1229 m"ussen sowol die Superklasse, als auch alle implementierten
1230 Interfaces schon gelinkt sein.
1231 Diese Funktion berechnet sowohl die L"ange (in Bytes) einer Instanz
1232 dieser Klasse, als auch die Virtual Function Tables f"ur normale
1233 Methoden als auch Interface-Methoden.
1235 Wenn die Klasse erfolgreich gelinkt werden kann, dann wird sie aus
1236 der Liste 'unlinkedclasses' ausgeh"angt, und in die Klasse 'linkedclasses'
1238 Wenn nicht, dann wird sie ans Ende der Liste 'unlinkedclasses' gestellt.
1240 Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
1241 eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
1243 ******************************************************************************/
1245 static void class_link (classinfo *c)
1247 u4 supervftbllength; /* L"ange der VFTBL der Superklasse */
1248 u4 vftbllength; /* L"ange der VFTBL dieser Klasse */
1249 classinfo *super = c->super;
1250 classinfo *ic,*c2; /* Hilfsvariablen */
1255 /* schauen, ob alle "ubergeordneten Klassen schon fertig sind,
1256 und richtiges Initialisieren der lokalen Variablen */
1258 for ( i=0; i<c->interfacescount; i++) {
1259 ic = c->interfaces[i];
1260 if ( !ic -> linked) {
1261 list_remove (&unlinkedclasses,c );
1262 list_addlast (&unlinkedclasses,c );
1269 c -> instancesize = sizeof (java_objectheader);
1271 vftbllength = supervftbllength = 0;
1273 c -> finalizer = NULL;
1276 if ( !super -> linked ) {
1277 list_remove (&unlinkedclasses,c );
1278 list_addlast (&unlinkedclasses,c );
1282 if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++;
1283 else c -> index = super -> index + 1;
1285 c -> instancesize = super -> instancesize;
1287 vftbllength = supervftbllength = super -> vftbl -> vftbllength;
1289 c -> finalizer = super -> finalizer;
1294 sprintf (logtext, "Linking Class: ");
1295 unicode_sprint (logtext+strlen(logtext), c->name );
1299 /* Erstellen der Virtual Function Table */
1301 for (i=0; i < c->methodscount; i++) {
1302 methodinfo *m = &(c->methods[i]);
1304 if (! (m->flags & ACC_STATIC) ) {
1305 classinfo *sc = super;
1308 for (j=0; j < sc->methodscount; j++) {
1309 if ( method_canoverwrite (m, &(sc->methods[j])) ) {
1310 m -> vftblindex = sc->methods[j].vftblindex;
1311 goto foundvftblindex;
1316 m -> vftblindex = (vftbllength++);
1322 count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
1325 c -> vftbl = v = (vftbl*)
1326 mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1));
1328 v -> vftbllength = vftbllength;
1329 v -> interfacetablelength = 0;
1331 for (i=0; i < supervftbllength; i++)
1332 v -> table[i] = super -> vftbl -> table[i];
1334 for (i=0; i < c->methodscount; i++) {
1335 methodinfo *m = &(c->methods[i]);
1336 if ( ! (m->flags & ACC_STATIC) ) {
1337 v -> table[m->vftblindex] = m -> stubroutine;
1342 /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen
1345 for (i=0; i < c->fieldscount; i++) {
1347 fieldinfo *f = &(c -> fields[i]);
1349 if ( ! (f->flags & ACC_STATIC) ) {
1350 dsize = desc_typesize (f->descriptor);
1351 c -> instancesize = ALIGN ( c->instancesize, dsize);
1352 f -> offset = c -> instancesize;
1353 c -> instancesize += dsize;
1359 /* Berechnen der Virtual Function Tables f"ur alle Interfaces */
1363 for (i=0; i<c2->interfacescount; i++) {
1364 s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1365 if ( h > v->interfacetablelength) v->interfacetablelength = h;
1369 v -> interfacevftbllength = MNEW (u4, v->interfacetablelength);
1370 v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength);
1373 count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength;
1376 for (i=0; i < v->interfacetablelength; i++) {
1377 v -> interfacevftbllength[i] = 0;
1378 v -> interfacevftbl[i] = NULL;
1383 for (i=0; i<c2->interfacescount; i++) {
1384 class_addinterface (c, c2->interfaces[i]);
1391 /* Die finalizer-Methode suchen und eintragen (wenn vorhanden),
1392 aber nur bei Objekten ausser java.lang.Object */
1396 static unicode *finame=NULL,*fidesc=NULL;
1398 if (!finame) finame = unicode_new_char ("finalize");
1399 if (!fidesc) fidesc = unicode_new_char ("()V");
1401 fi = class_findmethod (c, finame, fidesc);
1403 if (! (fi->flags & ACC_STATIC) ) {
1404 c -> finalizer = fi;
1410 /* Abschlie"sende Aktionen */
1414 list_remove (&unlinkedclasses, c);
1415 list_addlast (&linkedclasses, c);
1419 /******************* Funktion: class_freepool *********************************
1421 Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
1424 ******************************************************************************/
1426 static void class_freecpool (classinfo *c)
1432 for (idx=0; idx < c->cpcount; idx++) {
1433 tag = c->cptags[idx];
1434 info = c->cpinfos[idx];
1438 case CONSTANT_Fieldref:
1439 case CONSTANT_Methodref:
1440 case CONSTANT_InterfaceMethodref:
1441 FREE (info, constant_FMIref);
1443 case CONSTANT_Integer:
1444 FREE (info, constant_integer);
1446 case CONSTANT_Float:
1447 FREE (info, constant_float);
1450 FREE (info, constant_long);
1452 case CONSTANT_Double:
1453 FREE (info, constant_double);
1455 case CONSTANT_NameAndType:
1456 FREE (info, constant_nameandtype);
1458 case CONSTANT_Arraydescriptor:
1459 freearraydescriptor (info);
1465 MFREE (c -> cptags, u1, c -> cpcount);
1466 MFREE (c -> cpinfos, voidptr, c -> cpcount);
1470 /*********************** Funktion: class_free *********************************
1472 Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
1474 ******************************************************************************/
1476 static void class_free (classinfo *c)
1481 unicode_unlinkclass (c->name);
1483 class_freecpool (c);
1485 MFREE (c->interfaces, classinfo*, c->interfacescount);
1487 for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) );
1488 MFREE (c->fields, fieldinfo, c->fieldscount);
1490 for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) );
1491 MFREE (c->methods, methodinfo, c->methodscount);
1493 if ( (v = c->vftbl) ) {
1494 for (i=0; i<v->interfacetablelength; i++) {
1495 MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]);
1497 MFREE (v->interfacevftbllength, u4, v->interfacetablelength);
1498 MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength);
1500 mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1));
1503 FREE (c, classinfo);
1507 /************************* Funktion: class_findfield *************************
1509 sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
1512 *****************************************************************************/
1514 fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
1517 for (i=0; i < c->fieldscount; i++) {
1518 if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) )
1519 return &(c->fields[i]);
1521 panic ("Can not find field given in CONSTANT_Fieldref");
1526 /************************* Funktion: class_findmethod *************************
1528 sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
1530 Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
1532 *****************************************************************************/
1534 methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
1537 for (i=0; i < c->methodscount; i++) {
1538 if ( (c->methods[i].name == name)
1540 || (c->methods[i].descriptor == desc)
1543 return &(c->methods[i]);
1549 /************************* Funktion: class_resolvemethod *************************
1551 sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
1553 *****************************************************************************/
1556 methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
1559 methodinfo *m = class_findmethod (c, name, desc);
1568 /************************* Funktion: class_issubclass ************************
1570 "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
1572 *****************************************************************************/
1574 bool class_issubclass (classinfo *sub, classinfo *super)
1577 if (!sub) return false;
1578 if (sub==super) return true;
1585 /****************** Initialisierungsfunktion f"ur eine Klasse ****************
1587 In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
1588 Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
1589 Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
1592 ******************************************************************************/
1595 extern int blockInts;
1598 void class_init (classinfo *c)
1601 java_objectheader *exceptionptr;
1605 if (!makeinitializations) return;
1606 if (c->initialized) return;
1607 c -> initialized = true;
1609 if (c->super) class_init (c->super);
1610 for (i=0; i < c->interfacescount; i++) class_init(c->interfaces[i]);
1612 m = class_findmethod (c,
1613 unicode_new_char ("<clinit>"),
1614 unicode_new_char ("()V"));
1617 sprintf (logtext, "Class ");
1618 unicode_sprint (logtext+strlen(logtext), c->name);
1619 sprintf (logtext+strlen(logtext), " has no initializer");
1625 if (! (m->flags & ACC_STATIC)) panic ("Class initializer is not static!");
1628 sprintf (logtext, "Starting initializer for class: ");
1629 unicode_sprint (logtext+strlen(logtext), c->name);
1638 exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
1641 assert(blockInts == 0);
1646 printf ("#### Initializer has thrown: ");
1647 unicode_display (exceptionptr->vftbl->class->name);
1653 sprintf (logtext, "Finished initializer for class: ");
1654 unicode_sprint (logtext+strlen(logtext), c->name);
1663 /********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/
1665 void class_showconstantpool (classinfo *c)
1670 printf ("---- dump of constant pool ----\n");
1672 for (i=0; i<c->cpcount; i++) {
1673 printf ("#%d: ", (int) i);
1675 e = c -> cpinfos [i];
1678 switch (c -> cptags [i]) {
1679 case CONSTANT_Class:
1680 printf ("Classreference -> ");
1681 unicode_display ( ((classinfo*)e) -> name );
1684 case CONSTANT_Fieldref:
1685 printf ("Fieldref -> "); goto displayFMI;
1686 case CONSTANT_Methodref:
1687 printf ("Methodref -> "); goto displayFMI;
1688 case CONSTANT_InterfaceMethodref:
1689 printf ("InterfaceMethod -> "); goto displayFMI;
1692 constant_FMIref *fmi = e;
1693 unicode_display ( fmi->class->name );
1695 unicode_display ( fmi->name);
1697 unicode_display ( fmi->descriptor );
1701 case CONSTANT_String:
1702 printf ("String -> ");
1703 unicode_display (e);
1705 case CONSTANT_Integer:
1706 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1708 case CONSTANT_Float:
1709 printf ("Float -> %f", ((constant_float*)e) -> value);
1711 case CONSTANT_Double:
1712 printf ("Double -> %f", ((constant_double*)e) -> value);
1716 u8 v = ((constant_long*)e) -> value;
1718 printf ("Long -> %ld", (long int) v);
1720 printf ("Long -> HI: %ld, LO: %ld\n",
1721 (long int) v.high, (long int) v.low);
1725 case CONSTANT_NameAndType:
1726 { constant_nameandtype *cnt = e;
1727 printf ("NameAndType: ");
1728 unicode_display (cnt->name);
1730 unicode_display (cnt->descriptor);
1734 printf ("Utf8 -> ");
1735 unicode_display (e);
1737 case CONSTANT_Arraydescriptor: {
1738 printf ("Arraydescriptor: ");
1739 displayarraydescriptor (e);
1743 panic ("Invalid type of ConstantPool-Entry");
1755 /********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/
1757 void class_showmethods (classinfo *c)
1761 printf ("--------- Fields and Methods ----------------\n");
1762 printf ("Flags: "); printflags (c->flags); printf ("\n");
1764 printf ("This: "); unicode_display (c->name); printf ("\n");
1766 printf ("Super: "); unicode_display (c->super->name); printf ("\n");
1768 printf ("Index: %d\n", c->index);
1770 printf ("interfaces:\n");
1771 for (i=0; i < c-> interfacescount; i++) {
1773 unicode_display (c -> interfaces[i] -> name);
1774 printf (" (%d)\n", c->interfaces[i] -> index);
1777 printf ("fields:\n");
1778 for (i=0; i < c -> fieldscount; i++) {
1779 field_display (&(c -> fields[i]));
1782 printf ("methods:\n");
1783 for (i=0; i < c -> methodscount; i++) {
1784 methodinfo *m = &(c->methods[i]);
1785 if ( !(m->flags & ACC_STATIC))
1786 printf ("vftblindex: %d ", m->vftblindex);
1788 method_display ( m );
1792 printf ("Virtual function table:\n");
1793 for (i=0; i<c->vftbl->vftbllength; i++) {
1794 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1801 /*****************************************************************************/
1802 /******************* Funktionen fuer den Class-loader generell ***************/
1803 /*****************************************************************************/
1806 /********************* Funktion: loader_load **********************************
1808 l"adt und linkt die ge"unschte Klasse und alle davon
1809 referenzierten Klassen und Interfaces
1810 Return: Einen Zeiger auf diese Klasse
1812 ******************************************************************************/
1814 classinfo *loader_load (unicode *topname)
1818 long int starttime=0,stoptime=0;
1820 intsDisable(); /* schani */
1822 if (getloadingtime) starttime = getcputime();
1824 top = class_get (topname);
1826 while ( (c = list_first(&unloadedclasses)) ) {
1830 while ( (c = list_first(&unlinkedclasses)) ) {
1834 if (getloadingtime) {
1835 stoptime = getcputime();
1836 loadingtime += (stoptime-starttime);
1839 intsRestore(); /* schani */
1845 /******************* interne Funktion: loader_createarrayclass ****************
1847 Erzeugt (und linkt) eine Klasse f"ur die Arrays.
1849 ******************************************************************************/
1851 static classinfo *loader_createarrayclass ()
1854 c = class_get ( unicode_new_char ("The_Array_Class") );
1856 list_remove (&unloadedclasses, c);
1857 list_addlast (&unlinkedclasses, c);
1858 c -> super = class_java_lang_Object;
1866 /********************** Funktion: loader_init *********************************
1868 Initialisiert alle Listen und l"adt alle Klassen, die vom System
1869 und vom Compiler direkt ben"otigt werden.
1871 ******************************************************************************/
1877 list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
1878 list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
1879 list_init (&linkedclasses, OFFSET(classinfo, listnode) );
1882 class_java_lang_Object =
1883 loader_load ( unicode_new_char ("java/lang/Object") );
1884 class_java_lang_String =
1885 loader_load ( unicode_new_char ("java/lang/String") );
1886 class_java_lang_ClassCastException =
1887 loader_load ( unicode_new_char ("java/lang/ClassCastException") );
1888 class_java_lang_NullPointerException =
1889 loader_load ( unicode_new_char ("java/lang/NullPointerException") );
1890 class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
1891 unicode_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
1892 class_java_lang_NegativeArraySizeException = loader_load (
1893 unicode_new_char ("java/lang/NegativeArraySizeException") );
1894 class_java_lang_OutOfMemoryError = loader_load (
1895 unicode_new_char ("java/lang/OutOfMemoryError") );
1896 class_java_lang_ArrayStoreException =
1897 loader_load ( unicode_new_char ("java/lang/ArrayStoreException") );
1898 class_java_lang_ArithmeticException =
1899 loader_load ( unicode_new_char ("java/lang/ArithmeticException") );
1900 class_java_lang_ThreadDeath = /* schani */
1901 loader_load ( unicode_new_char ("java/lang/ThreadDeath") );
1903 class_array = loader_createarrayclass ();
1906 proto_java_lang_ClassCastException =
1907 builtin_new(class_java_lang_ClassCastException);
1908 heap_addreference ( (void**) &proto_java_lang_ClassCastException);
1910 proto_java_lang_NullPointerException =
1911 builtin_new(class_java_lang_NullPointerException);
1912 heap_addreference ( (void**) &proto_java_lang_NullPointerException);
1914 proto_java_lang_ArrayIndexOutOfBoundsException =
1915 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
1916 heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
1918 proto_java_lang_NegativeArraySizeException =
1919 builtin_new(class_java_lang_NegativeArraySizeException);
1920 heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
1922 proto_java_lang_OutOfMemoryError =
1923 builtin_new(class_java_lang_OutOfMemoryError);
1924 heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
1926 proto_java_lang_ArithmeticException =
1927 builtin_new(class_java_lang_ArithmeticException);
1928 heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
1930 proto_java_lang_ArrayStoreException =
1931 builtin_new(class_java_lang_ArrayStoreException);
1932 heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
1934 proto_java_lang_ThreadDeath = /* schani */
1935 builtin_new(class_java_lang_ThreadDeath);
1936 heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
1942 /********************* Funktion: loader_initclasses ****************************
1944 initialisiert alle geladenen aber noch nicht initialisierten Klassen
1946 ******************************************************************************/
1948 void loader_initclasses ()
1952 intsDisable(); /* schani */
1954 if (makeinitializations) {
1955 c = list_first (&linkedclasses);
1958 c = list_next (&linkedclasses, c);
1962 intsRestore(); /* schani */
1965 static s4 classvalue = 0;
1967 static void loader_compute_class_values (classinfo *c)
1971 c->vftbl->lowclassval = classvalue++;
1973 while (subs != NULL) {
1974 loader_compute_class_values(subs);
1975 subs = subs->nextsub;
1977 c->vftbl->highclassval = classvalue++;
1981 for (i = 0; i < c->index; i++)
1983 printf("%3d %3d ", (int) c->vftbl->lowclassval, (int) c->vftbl->highclassval);
1984 unicode_display(c->name);
1991 void loader_compute_subclasses ()
1995 intsDisable(); /* schani */
1997 c = list_first (&linkedclasses);
1999 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
2000 c->nextsub = c->super->sub;
2003 c = list_next (&linkedclasses, c);
2006 loader_compute_class_values(class_java_lang_Object);
2008 intsRestore(); /* schani */
2013 /******************** Funktion: loader_close **********************************
2015 gibt alle Resourcen wieder frei
2017 ******************************************************************************/
2019 void loader_close ()
2023 while ( (c=list_first(&unloadedclasses)) ) {
2024 list_remove (&unloadedclasses,c);
2027 while ( (c=list_first(&unlinkedclasses)) ) {
2028 list_remove (&unlinkedclasses,c);
2031 while ( (c=list_first(&linkedclasses)) ) {
2032 list_remove (&linkedclasses,c);