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);
698 c -> interfacescount = 0;
699 c -> interfaces = NULL;
700 c -> fieldscount = 0;
702 c -> methodscount = 0;
706 c -> instancesize = 0;
708 c -> initialized = false;
710 unicode_setclasslink (u,c);
711 list_addlast (&unloadedclasses, c);
718 /******************** Funktion: class_getconstant *****************************
720 holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
721 Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
723 ******************************************************************************/
725 voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
727 if (pos >= c->cpcount)
728 panic ("Attempt to access constant outside range");
729 if (c->cptags[pos] != ctype) {
730 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
731 (int) ctype, (int) c->cptags[pos] );
735 return c->cpinfos[pos];
739 /********************* Funktion: class_constanttype ***************************
741 Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
744 ******************************************************************************/
746 u4 class_constanttype (classinfo *c, u4 pos)
748 if (pos >= c->cpcount)
749 panic ("Attempt to access constant outside range");
750 return c->cptags[pos];
754 /******************** Funktion: class_loadcpool *******************************
756 l"adt den gesammten ConstantPool einer Klasse.
758 Dabei werden die einzelnen Eintr"age in ein wesentlich einfachers
759 Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
760 F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
762 ******************************************************************************/
764 static void class_loadcpool (classinfo *c)
767 typedef struct forward_class { /* Diese Strukturen dienen dazu, */
768 struct forward_class *next; /* die Infos, die beim ersten */
769 u2 thisindex; /* Durchgang durch den ConstantPool */
770 u2 name_index; /* gelesen werden, aufzunehmen. */
771 } forward_class; /* Erst nachdem der ganze Pool */
772 /* gelesen wurde, k"onnen alle */
773 typedef struct forward_string { /* Felder kompletiert werden */
774 struct forward_string *next; /* (und das auch nur in der richtigen */
775 u2 thisindex; /* Reihenfolge) */
779 typedef struct forward_nameandtype {
780 struct forward_nameandtype *next;
784 } forward_nameandtype;
786 typedef struct forward_fieldmethint {
787 struct forward_fieldmethint *next;
791 u2 nameandtype_index;
792 } forward_fieldmethint;
797 long int dumpsize = dump_size ();
799 forward_class *forward_classes = NULL;
800 forward_string *forward_strings = NULL;
801 forward_nameandtype *forward_nameandtypes = NULL;
802 forward_fieldmethint *forward_fieldmethints = NULL;
804 u4 cpcount = c -> cpcount = suck_u2();
805 u1 *cptags = c -> cptags = MNEW (u1, cpcount);
806 voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
809 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
813 for (idx=0; idx<cpcount; idx++) {
814 cptags[idx] = CONSTANT_UNUSED;
819 /******* Erster Durchgang *******/
820 /* Alle Eintr"age, die nicht unmittelbar aufgel"ost werden k"onnen,
821 werden einmal `auf Vorrat' in tempor"are Strukturen eingelesen,
822 und dann am Ende nocheinmal durchgegangen */
825 while (idx < cpcount) {
829 case CONSTANT_Class: {
830 forward_class *nfc = DNEW(forward_class);
832 nfc -> next = forward_classes;
833 forward_classes = nfc;
835 nfc -> thisindex = idx;
836 nfc -> name_index = suck_u2 ();
842 case CONSTANT_Fieldref:
843 case CONSTANT_Methodref:
844 case CONSTANT_InterfaceMethodref: {
845 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
847 nff -> next = forward_fieldmethints;
848 forward_fieldmethints = nff;
850 nff -> thisindex = idx;
852 nff -> class_index = suck_u2 ();
853 nff -> nameandtype_index = suck_u2 ();
859 case CONSTANT_String: {
860 forward_string *nfs = DNEW (forward_string);
862 nfs -> next = forward_strings;
863 forward_strings = nfs;
865 nfs -> thisindex = idx;
866 nfs -> string_index = suck_u2 ();
872 case CONSTANT_NameAndType: {
873 forward_nameandtype *nfn = DNEW (forward_nameandtype);
875 nfn -> next = forward_nameandtypes;
876 forward_nameandtypes = nfn;
878 nfn -> thisindex = idx;
879 nfn -> name_index = suck_u2 ();
880 nfn -> sig_index = suck_u2 ();
886 case CONSTANT_Integer: {
887 constant_integer *ci = NEW (constant_integer);
890 count_const_pool_len += sizeof(constant_integer);
893 ci -> value = suck_s4 ();
894 cptags [idx] = CONSTANT_Integer;
901 case CONSTANT_Float: {
902 constant_float *cf = NEW (constant_float);
905 count_const_pool_len += sizeof(constant_float);
908 cf -> value = suck_float ();
909 cptags [idx] = CONSTANT_Float;
915 case CONSTANT_Long: {
916 constant_long *cl = NEW(constant_long);
919 count_const_pool_len += sizeof(constant_long);
922 cl -> value = suck_s8 ();
923 cptags [idx] = CONSTANT_Long;
929 case CONSTANT_Double: {
930 constant_double *cd = NEW(constant_double);
933 count_const_pool_len += sizeof(constant_double);
936 cd -> value = suck_double ();
937 cptags [idx] = CONSTANT_Double;
943 case CONSTANT_Utf8: {
948 cptags [idx] = CONSTANT_Utf8;
955 sprintf (logtext, "Unkown constant type: %d",(int) t);
964 /* Aufl"osen der noch unfertigen Eintr"age */
966 while (forward_classes) {
968 class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
970 if ( (name->length>0) && (name->text[0]=='[') ) {
971 checkfielddescriptor (name);
973 cptags [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
974 cpinfos [forward_classes -> thisindex] =
975 buildarraydescriptor(name->text, name->length);
979 cptags [forward_classes -> thisindex] = CONSTANT_Class;
980 cpinfos [forward_classes -> thisindex] = class_get (name);
982 forward_classes = forward_classes -> next;
986 while (forward_strings) {
988 class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
990 cptags [forward_strings -> thisindex] = CONSTANT_String;
991 cpinfos [forward_strings -> thisindex] = text;
993 forward_strings = forward_strings -> next;
996 while (forward_nameandtypes) {
997 constant_nameandtype *cn = NEW (constant_nameandtype);
1000 count_const_pool_len += sizeof(constant_nameandtype);
1003 cn -> name = class_getconstant
1004 (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1005 cn -> descriptor = class_getconstant
1006 (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1008 cptags [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1009 cpinfos [forward_nameandtypes -> thisindex] = cn;
1011 forward_nameandtypes = forward_nameandtypes -> next;
1015 while (forward_fieldmethints) {
1016 constant_nameandtype *nat;
1017 constant_FMIref *fmi = NEW (constant_FMIref);
1020 count_const_pool_len += sizeof(constant_FMIref);
1023 nat = class_getconstant
1024 (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1026 fmi -> class = class_getconstant
1027 (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1028 fmi -> name = nat -> name;
1029 fmi -> descriptor = nat -> descriptor;
1031 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1032 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1034 switch (forward_fieldmethints -> tag) {
1035 case CONSTANT_Fieldref: checkfielddescriptor (fmi->descriptor);
1037 case CONSTANT_InterfaceMethodref:
1038 case CONSTANT_Methodref: checkmethoddescriptor (fmi->descriptor);
1042 forward_fieldmethints = forward_fieldmethints -> next;
1047 dump_release (dumpsize);
1051 /********************** Funktion: class_load **********************************
1053 l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
1054 'classinfo'-Struktur mu"s bereits angelegt worden sein.
1056 Die Superklasse und die Interfaces, die diese Klasse implementiert,
1057 m"ussen zu diesem Zeitpunkt noch nicht geladen sein, die
1058 Verbindung dazu wird sp"ater in der Funktion 'class_link' hergestellt.
1060 Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
1061 und in die Liste 'unlinkedclasses' eingh"angt.
1063 ******************************************************************************/
1065 static void class_load (classinfo *c)
1072 sprintf (logtext, "Loading class: ");
1073 unicode_sprint (logtext+strlen(logtext), c->name );
1078 suck_start (c->name);
1080 if (suck_u4() != MAGIC) panic("Can not find class-file signature");
1083 if (ma != MAJOR_VERSION) {
1084 sprintf (logtext, "Can only support major version %d, but not %d",
1085 MAJOR_VERSION, (int) ma);
1088 if (mi > MINOR_VERSION) {
1089 sprintf (logtext, "Minor version %d is not yet supported.", (int) mi);
1094 class_loadcpool (c);
1096 c -> flags = suck_u2 ();
1097 suck_u2 (); /* this */
1099 if ( (i = suck_u2 () ) ) {
1100 c -> super = class_getconstant (c, i, CONSTANT_Class);
1106 c -> interfacescount = suck_u2 ();
1107 c -> interfaces = MNEW (classinfo*, c -> interfacescount);
1108 for (i=0; i < c -> interfacescount; i++) {
1109 c -> interfaces [i] =
1110 class_getconstant (c, suck_u2(), CONSTANT_Class);
1113 c -> fieldscount = suck_u2 ();
1114 c -> fields = MNEW (fieldinfo, c -> fieldscount);
1115 for (i=0; i < c -> fieldscount; i++) {
1116 field_load (&(c->fields[i]), c);
1119 c -> methodscount = suck_u2 ();
1120 c -> methods = MNEW (methodinfo, c -> methodscount);
1121 for (i=0; i < c -> methodscount; i++) {
1122 method_load (&(c -> methods [i]), c);
1126 count_class_infos += sizeof(classinfo*) * c -> interfacescount;
1127 count_class_infos += sizeof(fieldinfo) * c -> fieldscount;
1128 count_class_infos += sizeof(methodinfo) * c -> methodscount;
1132 skipattributes ( suck_u2() );
1137 list_remove (&unloadedclasses, c);
1138 list_addlast (&unlinkedclasses, c);
1143 /************** interne Funktion: class_highestinterface **********************
1145 wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
1146 die Interfacetable einer Klasse sein mu"s.
1148 ******************************************************************************/
1150 static s4 class_highestinterface (classinfo *c)
1155 if ( ! (c->flags & ACC_INTERFACE) ) {
1156 sprintf (logtext, "Interface-methods count requested for non-interface: ");
1157 unicode_sprint (logtext+strlen(logtext), c->name);
1162 for (i=0; i<c->interfacescount; i++) {
1163 s4 h2 = class_highestinterface (c->interfaces[i]);
1170 /**************** Funktion: class_addinterface ********************************
1172 wird von der Funktion class_link ben"otigt, um eine Virtual Function
1173 Table f"ur ein Interface (und alle weiteren von diesem Interface
1174 implementierten Interfaces) in eine Klasse einzutragen.
1176 ******************************************************************************/
1178 static void class_addinterface (classinfo *c, classinfo *ic)
1182 vftbl *vftbl = c->vftbl;
1184 if (i>=vftbl->interfacetablelength) panic ("Interfacetable-Overflow");
1185 if (vftbl->interfacevftbl[i]) return;
1187 if (ic->methodscount==0) { /* wenn interface keine Methoden hat, dann
1188 trotzdem eine Tabelle mit L"ange 1 anlegen,
1189 wegen Subclass-Tests */
1190 vftbl -> interfacevftbllength[i] = 1;
1191 vftbl -> interfacevftbl[i] = MNEW(methodptr, 1);
1192 vftbl -> interfacevftbl[i][0] = NULL;
1195 vftbl -> interfacevftbllength[i] = ic -> methodscount;
1196 vftbl -> interfacevftbl[i] = MNEW(methodptr, ic -> methodscount);
1199 count_vftbl_len += sizeof(methodptr) * ic -> methodscount;
1202 for (j=0; j<ic->methodscount; j++) {
1205 for (m=0; m<sc->methodscount; m++) {
1206 methodinfo *mi = &(sc->methods[m]);
1207 if (method_canoverwrite (mi, &(ic->methods[j])) ) {
1208 vftbl->interfacevftbl[i][j] =
1209 vftbl->table[mi->vftblindex];
1219 for (j=0; j<ic->interfacescount; j++)
1220 class_addinterface(c, ic->interfaces[j]);
1224 /********************** Funktion: class_link **********************************
1226 versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
1227 m"ussen sowol die Superklasse, als auch alle implementierten
1228 Interfaces schon gelinkt sein.
1229 Diese Funktion berechnet sowohl die L"ange (in Bytes) einer Instanz
1230 dieser Klasse, als auch die Virtual Function Tables f"ur normale
1231 Methoden als auch Interface-Methoden.
1233 Wenn die Klasse erfolgreich gelinkt werden kann, dann wird sie aus
1234 der Liste 'unlinkedclasses' ausgeh"angt, und in die Klasse 'linkedclasses'
1236 Wenn nicht, dann wird sie ans Ende der Liste 'unlinkedclasses' gestellt.
1238 Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
1239 eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
1241 ******************************************************************************/
1243 static void class_link (classinfo *c)
1245 u4 supervftbllength; /* L"ange der VFTBL der Superklasse */
1246 u4 vftbllength; /* L"ange der VFTBL dieser Klasse */
1247 classinfo *super = c->super;
1248 classinfo *ic,*c2; /* Hilfsvariablen */
1253 /* schauen, ob alle "ubergeordneten Klassen schon fertig sind,
1254 und richtiges Initialisieren der lokalen Variablen */
1256 for ( i=0; i<c->interfacescount; i++) {
1257 ic = c->interfaces[i];
1258 if ( !ic -> linked) {
1259 list_remove (&unlinkedclasses,c );
1260 list_addlast (&unlinkedclasses,c );
1267 c -> instancesize = sizeof (java_objectheader);
1269 vftbllength = supervftbllength = 0;
1271 c -> finalizer = NULL;
1274 if ( !super -> linked ) {
1275 list_remove (&unlinkedclasses,c );
1276 list_addlast (&unlinkedclasses,c );
1280 if ( c->flags & ACC_INTERFACE) c -> index = interfaceindex++;
1281 else c -> index = super -> index + 1;
1283 c -> instancesize = super -> instancesize;
1285 vftbllength = supervftbllength = super -> vftbl -> vftbllength;
1287 c -> finalizer = super -> finalizer;
1292 sprintf (logtext, "Linking Class: ");
1293 unicode_sprint (logtext+strlen(logtext), c->name );
1297 /* Erstellen der Virtual Function Table */
1299 for (i=0; i < c->methodscount; i++) {
1300 methodinfo *m = &(c->methods[i]);
1302 if (! (m->flags & ACC_STATIC) ) {
1303 classinfo *sc = super;
1306 for (j=0; j < sc->methodscount; j++) {
1307 if ( method_canoverwrite (m, &(sc->methods[j])) ) {
1308 m -> vftblindex = sc->methods[j].vftblindex;
1309 goto foundvftblindex;
1314 m -> vftblindex = (vftbllength++);
1320 count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
1323 c -> vftbl = v = (vftbl*)
1324 mem_alloc (sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1));
1326 v -> vftbllength = vftbllength;
1327 v -> interfacetablelength = 0;
1329 for (i=0; i < supervftbllength; i++)
1330 v -> table[i] = super -> vftbl -> table[i];
1332 for (i=0; i < c->methodscount; i++) {
1333 methodinfo *m = &(c->methods[i]);
1334 if ( ! (m->flags & ACC_STATIC) ) {
1335 v -> table[m->vftblindex] = m -> stubroutine;
1340 /* Berechnen der Instanzengr"o"se und der Offsets der einzelnen
1343 for (i=0; i < c->fieldscount; i++) {
1345 fieldinfo *f = &(c -> fields[i]);
1347 if ( ! (f->flags & ACC_STATIC) ) {
1348 dsize = desc_typesize (f->descriptor);
1349 c -> instancesize = ALIGN ( c->instancesize, dsize);
1350 f -> offset = c -> instancesize;
1351 c -> instancesize += dsize;
1357 /* Berechnen der Virtual Function Tables f"ur alle Interfaces */
1361 for (i=0; i<c2->interfacescount; i++) {
1362 s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1363 if ( h > v->interfacetablelength) v->interfacetablelength = h;
1367 v -> interfacevftbllength = MNEW (u4, v->interfacetablelength);
1368 v -> interfacevftbl = MNEW (methodptr *, v->interfacetablelength);
1371 count_vftbl_len += (4 + sizeof(methodptr*)) * v->interfacetablelength;
1374 for (i=0; i < v->interfacetablelength; i++) {
1375 v -> interfacevftbllength[i] = 0;
1376 v -> interfacevftbl[i] = NULL;
1381 for (i=0; i<c2->interfacescount; i++) {
1382 class_addinterface (c, c2->interfaces[i]);
1389 /* Die finalizer-Methode suchen und eintragen (wenn vorhanden),
1390 aber nur bei Objekten ausser java.lang.Object */
1394 static unicode *finame=NULL,*fidesc=NULL;
1396 if (!finame) finame = unicode_new_char ("finalize");
1397 if (!fidesc) fidesc = unicode_new_char ("()V");
1399 fi = class_findmethod (c, finame, fidesc);
1401 if (! (fi->flags & ACC_STATIC) ) {
1402 c -> finalizer = fi;
1408 /* Abschlie"sende Aktionen */
1412 list_remove (&unlinkedclasses, c);
1413 list_addlast (&linkedclasses, c);
1417 /******************* Funktion: class_freepool *********************************
1419 Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
1422 ******************************************************************************/
1424 static void class_freecpool (classinfo *c)
1430 for (idx=0; idx < c->cpcount; idx++) {
1431 tag = c->cptags[idx];
1432 info = c->cpinfos[idx];
1436 case CONSTANT_Fieldref:
1437 case CONSTANT_Methodref:
1438 case CONSTANT_InterfaceMethodref:
1439 FREE (info, constant_FMIref);
1441 case CONSTANT_Integer:
1442 FREE (info, constant_integer);
1444 case CONSTANT_Float:
1445 FREE (info, constant_float);
1448 FREE (info, constant_long);
1450 case CONSTANT_Double:
1451 FREE (info, constant_double);
1453 case CONSTANT_NameAndType:
1454 FREE (info, constant_nameandtype);
1456 case CONSTANT_Arraydescriptor:
1457 freearraydescriptor (info);
1463 MFREE (c -> cptags, u1, c -> cpcount);
1464 MFREE (c -> cpinfos, voidptr, c -> cpcount);
1468 /*********************** Funktion: class_free *********************************
1470 Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
1472 ******************************************************************************/
1474 static void class_free (classinfo *c)
1479 unicode_unlinkclass (c->name);
1481 class_freecpool (c);
1483 MFREE (c->interfaces, classinfo*, c->interfacescount);
1485 for (i=0; i < c->fieldscount; i++) field_free ( &(c->fields[i]) );
1486 MFREE (c->fields, fieldinfo, c->fieldscount);
1488 for (i=0; i < c->methodscount; i++) method_free ( &(c->methods[i]) );
1489 MFREE (c->methods, methodinfo, c->methodscount);
1491 if ( (v = c->vftbl) ) {
1492 for (i=0; i<v->interfacetablelength; i++) {
1493 MFREE (v->interfacevftbl[i], methodptr, v->interfacevftbllength[i]);
1495 MFREE (v->interfacevftbllength, u4, v->interfacetablelength);
1496 MFREE (v->interfacevftbl, methodptr*, v->interfacetablelength);
1498 mem_free (v, sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1));
1501 FREE (c, classinfo);
1505 /************************* Funktion: class_findfield *************************
1507 sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
1510 *****************************************************************************/
1512 fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
1515 for (i=0; i < c->fieldscount; i++) {
1516 if ( (c->fields[i].name == name) && (c->fields[i].descriptor == desc) )
1517 return &(c->fields[i]);
1519 panic ("Can not find field given in CONSTANT_Fieldref");
1524 /************************* Funktion: class_findmethod *************************
1526 sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
1528 Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
1530 *****************************************************************************/
1532 methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
1535 for (i=0; i < c->methodscount; i++) {
1536 if ( (c->methods[i].name == name)
1538 || (c->methods[i].descriptor == desc)
1541 return &(c->methods[i]);
1547 /************************* Funktion: class_resolvemethod *************************
1549 sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
1551 *****************************************************************************/
1554 methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
1557 methodinfo *m = class_findmethod (c, name, desc);
1566 /************************* Funktion: class_issubclass ************************
1568 "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
1570 *****************************************************************************/
1572 bool class_issubclass (classinfo *sub, classinfo *super)
1575 if (!sub) return false;
1576 if (sub==super) return true;
1583 /****************** Initialisierungsfunktion f"ur eine Klasse ****************
1585 In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
1586 Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
1587 Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
1590 ******************************************************************************/
1593 extern int blockInts;
1596 void class_init (classinfo *c)
1599 java_objectheader *exceptionptr;
1603 if (!makeinitializations) return;
1604 if (c->initialized) return;
1605 c -> initialized = true;
1607 if (c->super) class_init (c->super);
1608 for (i=0; i < c->interfacescount; i++) class_init(c->interfaces[i]);
1610 m = class_findmethod (c,
1611 unicode_new_char ("<clinit>"),
1612 unicode_new_char ("()V"));
1615 sprintf (logtext, "Class ");
1616 unicode_sprint (logtext+strlen(logtext), c->name);
1617 sprintf (logtext+strlen(logtext), " has no initializer");
1623 if (! (m->flags & ACC_STATIC)) panic ("Class initializer is not static!");
1626 sprintf (logtext, "Starting initializer for class: ");
1627 unicode_sprint (logtext+strlen(logtext), c->name);
1636 exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
1639 assert(blockInts == 0);
1644 printf ("#### Initializer has thrown: ");
1645 unicode_display (exceptionptr->vftbl->class->name);
1651 sprintf (logtext, "Finished initializer for class: ");
1652 unicode_sprint (logtext+strlen(logtext), c->name);
1661 /********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) ********/
1663 void class_showconstantpool (classinfo *c)
1668 printf ("---- dump of constant pool ----\n");
1670 for (i=0; i<c->cpcount; i++) {
1671 printf ("#%d: ", (int) i);
1673 e = c -> cpinfos [i];
1676 switch (c -> cptags [i]) {
1677 case CONSTANT_Class:
1678 printf ("Classreference -> ");
1679 unicode_display ( ((classinfo*)e) -> name );
1682 case CONSTANT_Fieldref:
1683 printf ("Fieldref -> "); goto displayFMI;
1684 case CONSTANT_Methodref:
1685 printf ("Methodref -> "); goto displayFMI;
1686 case CONSTANT_InterfaceMethodref:
1687 printf ("InterfaceMethod -> "); goto displayFMI;
1690 constant_FMIref *fmi = e;
1691 unicode_display ( fmi->class->name );
1693 unicode_display ( fmi->name);
1695 unicode_display ( fmi->descriptor );
1699 case CONSTANT_String:
1700 printf ("String -> ");
1701 unicode_display (e);
1703 case CONSTANT_Integer:
1704 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1706 case CONSTANT_Float:
1707 printf ("Float -> %f", ((constant_float*)e) -> value);
1709 case CONSTANT_Double:
1710 printf ("Double -> %f", ((constant_double*)e) -> value);
1714 u8 v = ((constant_long*)e) -> value;
1716 printf ("Long -> %ld", (long int) v);
1718 printf ("Long -> HI: %ld, LO: %ld\n",
1719 (long int) v.high, (long int) v.low);
1723 case CONSTANT_NameAndType:
1724 { constant_nameandtype *cnt = e;
1725 printf ("NameAndType: ");
1726 unicode_display (cnt->name);
1728 unicode_display (cnt->descriptor);
1732 printf ("Utf8 -> ");
1733 unicode_display (e);
1735 case CONSTANT_Arraydescriptor: {
1736 printf ("Arraydescriptor: ");
1737 displayarraydescriptor (e);
1741 panic ("Invalid type of ConstantPool-Entry");
1753 /********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) ************/
1755 void class_showmethods (classinfo *c)
1759 printf ("--------- Fields and Methods ----------------\n");
1760 printf ("Flags: "); printflags (c->flags); printf ("\n");
1762 printf ("This: "); unicode_display (c->name); printf ("\n");
1764 printf ("Super: "); unicode_display (c->super->name); printf ("\n");
1766 printf ("Index: %d\n", c->index);
1768 printf ("interfaces:\n");
1769 for (i=0; i < c-> interfacescount; i++) {
1771 unicode_display (c -> interfaces[i] -> name);
1772 printf (" (%d)\n", c->interfaces[i] -> index);
1775 printf ("fields:\n");
1776 for (i=0; i < c -> fieldscount; i++) {
1777 field_display (&(c -> fields[i]));
1780 printf ("methods:\n");
1781 for (i=0; i < c -> methodscount; i++) {
1782 methodinfo *m = &(c->methods[i]);
1783 if ( !(m->flags & ACC_STATIC))
1784 printf ("vftblindex: %d ", m->vftblindex);
1786 method_display ( m );
1790 printf ("Virtual function table:\n");
1791 for (i=0; i<c->vftbl->vftbllength; i++) {
1792 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1799 /*****************************************************************************/
1800 /******************* Funktionen fuer den Class-loader generell ***************/
1801 /*****************************************************************************/
1804 /********************* Funktion: loader_load **********************************
1806 l"adt und linkt die ge"unschte Klasse und alle davon
1807 referenzierten Klassen und Interfaces
1808 Return: Einen Zeiger auf diese Klasse
1810 ******************************************************************************/
1812 classinfo *loader_load (unicode *topname)
1816 long int starttime=0,stoptime=0;
1818 intsDisable(); /* schani */
1820 if (getloadingtime) starttime = getcputime();
1823 top = class_get (topname);
1825 while ( (c = list_first(&unloadedclasses)) ) {
1829 while ( (c = list_first(&unlinkedclasses)) ) {
1834 synchronize_caches ();
1838 if (getloadingtime) {
1839 stoptime = getcputime();
1840 loadingtime += (stoptime-starttime);
1843 intsRestore(); /* schani */
1849 /******************* interne Funktion: loader_createarrayclass ****************
1851 Erzeugt (und linkt) eine Klasse f"ur die Arrays.
1853 ******************************************************************************/
1855 static classinfo *loader_createarrayclass ()
1858 c = class_get ( unicode_new_char ("The_Array_Class") );
1860 list_remove (&unloadedclasses, c);
1861 list_addlast (&unlinkedclasses, c);
1862 c -> super = class_java_lang_Object;
1870 /********************** Funktion: loader_init *********************************
1872 Initialisiert alle Listen und l"adt alle Klassen, die vom System
1873 und vom Compiler direkt ben"otigt werden.
1875 ******************************************************************************/
1881 list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
1882 list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
1883 list_init (&linkedclasses, OFFSET(classinfo, listnode) );
1886 class_java_lang_Object =
1887 loader_load ( unicode_new_char ("java/lang/Object") );
1888 class_java_lang_String =
1889 loader_load ( unicode_new_char ("java/lang/String") );
1890 class_java_lang_ClassCastException =
1891 loader_load ( unicode_new_char ("java/lang/ClassCastException") );
1892 class_java_lang_NullPointerException =
1893 loader_load ( unicode_new_char ("java/lang/NullPointerException") );
1894 class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
1895 unicode_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
1896 class_java_lang_NegativeArraySizeException = loader_load (
1897 unicode_new_char ("java/lang/NegativeArraySizeException") );
1898 class_java_lang_OutOfMemoryError = loader_load (
1899 unicode_new_char ("java/lang/OutOfMemoryError") );
1900 class_java_lang_ArrayStoreException =
1901 loader_load ( unicode_new_char ("java/lang/ArrayStoreException") );
1902 class_java_lang_ArithmeticException =
1903 loader_load ( unicode_new_char ("java/lang/ArithmeticException") );
1904 class_java_lang_ThreadDeath = /* schani */
1905 loader_load ( unicode_new_char ("java/lang/ThreadDeath") );
1907 class_array = loader_createarrayclass ();
1910 proto_java_lang_ClassCastException =
1911 builtin_new(class_java_lang_ClassCastException);
1912 heap_addreference ( (void**) &proto_java_lang_ClassCastException);
1914 proto_java_lang_NullPointerException =
1915 builtin_new(class_java_lang_NullPointerException);
1916 heap_addreference ( (void**) &proto_java_lang_NullPointerException);
1918 proto_java_lang_ArrayIndexOutOfBoundsException =
1919 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
1920 heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
1922 proto_java_lang_NegativeArraySizeException =
1923 builtin_new(class_java_lang_NegativeArraySizeException);
1924 heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
1926 proto_java_lang_OutOfMemoryError =
1927 builtin_new(class_java_lang_OutOfMemoryError);
1928 heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
1930 proto_java_lang_ArithmeticException =
1931 builtin_new(class_java_lang_ArithmeticException);
1932 heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
1934 proto_java_lang_ArrayStoreException =
1935 builtin_new(class_java_lang_ArrayStoreException);
1936 heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
1938 proto_java_lang_ThreadDeath = /* schani */
1939 builtin_new(class_java_lang_ThreadDeath);
1940 heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
1946 /********************* Funktion: loader_initclasses ****************************
1948 initialisiert alle geladenen aber noch nicht initialisierten Klassen
1950 ******************************************************************************/
1952 void loader_initclasses ()
1956 intsDisable(); /* schani */
1958 if (makeinitializations) {
1959 c = list_first (&linkedclasses);
1962 c = list_next (&linkedclasses, c);
1966 intsRestore(); /* schani */
1971 /******************** Funktion: loader_close **********************************
1973 gibt alle Resourcen wieder frei
1975 ******************************************************************************/
1977 void loader_close ()
1981 while ( (c=list_first(&unloadedclasses)) ) {
1982 list_remove (&unloadedclasses,c);
1985 while ( (c=list_first(&unlinkedclasses)) ) {
1986 list_remove (&unlinkedclasses,c);
1989 while ( (c=list_first(&linkedclasses)) ) {
1990 list_remove (&linkedclasses,c);