1 /* loader.c ********************************************************************
3 Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
5 See file COPYRIGHT for information on usage and disclaimer of warranties
7 Contains the functions of the class loader.
9 Author: Reinhard Grafl EMAIL: cacao@complang.tuwien.ac.at
10 Changes: Mark Probst EMAIL: cacao@complang.tuwien.ac.at
12 Last Change: 1997/06/03
14 *******************************************************************************/
31 #include "threads/thread.h" /* schani */
34 /* global variables ***********************************************************/
36 extern bool newcompiler; /* true if new compiler is used */
38 int count_class_infos = 0; /* variables for measurements */
39 int count_const_pool_len = 0;
40 int count_vftbl_len = 0;
41 int count_all_methods = 0;
42 int count_vmcode_len = 0;
43 int count_extable_len = 0;
45 bool loadverbose = false; /* switches for debug messages */
46 bool linkverbose = false;
47 bool initverbose = false;
49 bool makeinitializations = true;
51 bool getloadingtime = false;
52 long int loadingtime = 0;
55 static s4 interfaceindex; /* sequential numbering of interfaces */
57 static list unloadedclasses; /* list of all referenced but not loaded classes */
58 static list unlinkedclasses; /* list of all loaded but not linked classes */
59 list linkedclasses; /* list of all completely linked classes */
63 /* important system classes ***************************************************/
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 /* instances of important system classes **************************************/
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 ()
125 skip_nbytes(suck_u4());
128 /********************** Funktion: skipattributebody ****************************
130 "uberliest im Classfile ein attribut, wobei die 16-bit - attribute_name -
131 Referenz schon gelesen worden ist.
133 *******************************************************************************/
135 static void skipattributebody ()
137 skip_nbytes(suck_u4());
141 /************************* Funktion: skipattributes ****************************
143 "uberliest im ClassFile eine gew"unschte Anzahl von attribute-Strukturen
145 *******************************************************************************/
147 static void skipattributes (u4 num)
150 for (i = 0; i < num; i++)
156 /************************** Funktion: loadUtf8 *********************************
158 liest aus dem ClassFile einen Utf8-String (=komprimierter unicode-text)
159 und legt daf"ur ein unicode-Symbol an.
160 Return: Zeiger auf das Symbol
162 *******************************************************************************/
164 #define MAXUNICODELEN 5000
165 static u2 unicodebuffer[MAXUNICODELEN];
167 static unicode *loadUtf8 ()
181 if (b1<0x80) letter = b1;
185 if (b1<0xe0) letter = ((b1 & 0x1f) << 6) | (b2 & 0x3f);
189 letter = ((b1 & 0x0f) << 12) | ((b2 & 0x3f) << 6) | (b3 & 0x3f);
194 if (unicodelen >= MAXUNICODELEN) {
195 panic ("String constant too long");
198 unicodebuffer[unicodelen++] = letter;
202 return unicode_new_u2 (unicodebuffer, unicodelen);
207 /******************** interne Funktion: checkfieldtype ************************/
209 static void checkfieldtype (u2 *text, u4 *count, u4 length)
213 if (*count >= length) panic ("Type-descriptor exceeds unicode length");
215 l = text[(*count)++];
218 default: panic ("Invalid symbol in type descriptor");
229 case '[': checkfieldtype (text, count, length);
234 u4 tlen,tstart = *count;
236 if (*count >= length)
237 panic ("Objecttype descriptor of length zero");
239 while ( text[*count] != ';' ) {
241 if (*count >= length)
242 panic ("Missing ';' in objecttype-descriptor");
245 tlen = (*count) - tstart;
248 if (tlen == 0) panic ("Objecttype descriptor with empty name");
250 class_get ( unicode_new_u2 (text+tstart, tlen) );
256 /******************* Funktion: checkfielddescriptor ****************************
258 "uberpr"uft, ob ein Field-Descriptor ein g"ultiges Format hat.
259 Wenn nicht, dann wird das System angehalten.
260 Au"serdem werden alle Klassen, die hier referenziert werden,
261 in die Liste zu ladender Klassen eingetragen.
263 *******************************************************************************/
265 void checkfielddescriptor (unicode *d)
268 checkfieldtype (d->text, &count, d->length);
269 if (count != d->length) panic ("Invalid type-descritor encountered");
273 /******************* Funktion: checkmethoddescriptor ***************************
275 "uberpr"uft, ob ein Method-Descriptor ein g"ultiges Format hat.
276 Wenn nicht, dann wird das System angehalten.
277 Au"serdem werden alle Klassen, die hier referenziert werden,
278 in die Liste zu ladender Klassen eingetragen.
280 *******************************************************************************/
282 void checkmethoddescriptor (unicode *d)
288 if (length<2) panic ("Method descriptor too short");
289 if (text[0] != '(') panic ("Missing '(' in method descriptor");
292 while (text[count] != ')') {
293 checkfieldtype (text,&count,length);
294 if ( count > length-2 ) panic ("Unexpected end of descriptor");
298 if (text[count] == 'V') count++;
299 else checkfieldtype (text, &count,length);
301 if (count != length) panic ("Method-descriptor has exceeding chars");
305 /******************** Funktion: buildarraydescriptor ***************************
307 erzeugt zu einem namentlich als u2-String vorliegenden Arraytyp eine
308 entsprechende constant_arraydescriptor - Struktur
310 *******************************************************************************/
312 static constant_arraydescriptor * buildarraydescriptor(u2 *name, u4 namelen)
314 constant_arraydescriptor *d;
316 if (name[0]!='[') panic ("Attempt to build arraydescriptor for non-array");
317 d = NEW (constant_arraydescriptor);
318 d -> objectclass = NULL;
319 d -> elementdescriptor = NULL;
322 count_const_pool_len += sizeof(constant_arraydescriptor);
326 case 'Z': d -> arraytype = ARRAYTYPE_BOOLEAN; break;
327 case 'B': d -> arraytype = ARRAYTYPE_BYTE; break;
328 case 'C': d -> arraytype = ARRAYTYPE_CHAR; break;
329 case 'D': d -> arraytype = ARRAYTYPE_DOUBLE; break;
330 case 'F': d -> arraytype = ARRAYTYPE_FLOAT; break;
331 case 'I': d -> arraytype = ARRAYTYPE_INT; break;
332 case 'J': d -> arraytype = ARRAYTYPE_LONG; break;
333 case 'S': d -> arraytype = ARRAYTYPE_SHORT; break;
336 d -> arraytype = ARRAYTYPE_ARRAY;
337 d -> elementdescriptor = buildarraydescriptor (name+1, namelen-1);
341 d -> arraytype = ARRAYTYPE_OBJECT;
342 d -> objectclass = class_get ( unicode_new_u2 (name+2, namelen-3) );
349 /******************* Funktion: freearraydescriptor *****************************
351 entfernt eine mit buildarraydescriptor erzeugte Struktur wieder
354 *******************************************************************************/
356 static void freearraydescriptor (constant_arraydescriptor *d)
359 constant_arraydescriptor *n = d->elementdescriptor;
360 FREE (d, constant_arraydescriptor);
365 /*********************** Funktion: displayarraydescriptor *********************/
367 static void displayarraydescriptor (constant_arraydescriptor *d)
369 switch (d->arraytype) {
370 case ARRAYTYPE_BOOLEAN: printf ("boolean[]"); break;
371 case ARRAYTYPE_BYTE: printf ("byte[]"); break;
372 case ARRAYTYPE_CHAR: printf ("char[]"); break;
373 case ARRAYTYPE_DOUBLE: printf ("double[]"); break;
374 case ARRAYTYPE_FLOAT: printf ("float[]"); break;
375 case ARRAYTYPE_INT: printf ("int[]"); break;
376 case ARRAYTYPE_LONG: printf ("long[]"); break;
377 case ARRAYTYPE_SHORT: printf ("short[]"); break;
378 case ARRAYTYPE_ARRAY: displayarraydescriptor(d->elementdescriptor); printf("[]"); break;
379 case ARRAYTYPE_OBJECT: unicode_display(d->objectclass->name); printf("[]"); break;
385 /******************************************************************************/
386 /******************** Funktionen fuer Fields **********************************/
387 /******************************************************************************/
390 /************************ Funktion: field_load *********************************
392 l"adt alle Informationen f"ur eine Feld einer Methode aus dem ClassFile,
393 und f"ullt mit diesen Infos eine schon existierende 'fieldinfo'-Struktur.
394 Bei 'static'-Fields wird auch noch ein Platz auf dem Datensegment
397 *******************************************************************************/
399 static void field_load (fieldinfo *f, classinfo *c)
404 f -> flags = suck_u2 ();
405 f -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
406 f -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
407 f -> type = jtype = desc_to_type (f->descriptor);
411 case TYPE_INT: f->value.i = 0; break;
412 case TYPE_FLOAT: f->value.f = 0.0; break;
413 case TYPE_DOUBLE: f->value.d = 0.0; break;
414 case TYPE_ADDRESS: f->value.a = NULL;
415 heap_addreference (&(f->value.a));
419 f->value.l = 0; break;
421 f->value.l.low = 0; f->value.l.high = 0; break;
426 for (i=0; i<attrnum; i++) {
430 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
432 if ( aname != unicode_new_char ("ConstantValue") ) {
433 skipattributebody ();
441 constant_integer *ci =
442 class_getconstant(c, pindex, CONSTANT_Integer);
443 f->value.i = ci -> value;
449 class_getconstant(c, pindex, CONSTANT_Long);
451 f->value.l = cl -> value;
457 class_getconstant(c, pindex, CONSTANT_Float);
459 f->value.f = cf->value;
464 constant_double *cd =
465 class_getconstant(c, pindex, CONSTANT_Double);
467 f->value.d = cd->value;
473 class_getconstant(c, pindex, CONSTANT_String);
474 f->value.a = literalstring_new(u);
479 log_text ("Invalid Constant - Type");
489 /********************** Funktion: field_free **********************************/
491 static void field_free (fieldinfo *f)
496 /************** Funktion: field_display (nur zu Debug-Zwecken) ****************/
498 static void field_display (fieldinfo *f)
501 printflags (f -> flags);
503 unicode_display (f -> name);
505 unicode_display (f -> descriptor);
506 printf (" offset: %ld\n", (long int) (f -> offset) );
512 /******************************************************************************/
513 /************************* Funktionen f"ur Methods ****************************/
514 /******************************************************************************/
517 /*********************** Funktion: method_load *********************************
519 l"adt die Infos f"ur eine Methode aus dem ClassFile und f"ullt damit
520 eine schon existierende 'methodinfo'-Struktur aus.
521 Bei allen native-Methoden wird au"serdem gleich der richtige
522 Funktionszeiger eingetragen, bei JavaVM-Methoden einstweilen ein
523 Zeiger auf den Compiler
525 *******************************************************************************/
527 static void method_load (methodinfo *m, classinfo *c)
537 m -> flags = suck_u2 ();
538 m -> name = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
539 m -> descriptor = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
542 m -> exceptiontable = NULL;
543 m -> entrypoint = NULL;
545 m -> stubroutine = NULL;
547 if (! (m->flags & ACC_NATIVE) ) {
548 m -> stubroutine = createcompilerstub (m);
551 functionptr f = native_findfunction
552 (c->name, m->name, m->descriptor, (m->flags & ACC_STATIC) != 0);
557 m -> stubroutine = createnativestub (f, m);
560 m -> stubroutine = oldcreatenativestub (f, m);
567 for (i=0; i<attrnum; i++) {
570 aname = class_getconstant (c, suck_u2(), CONSTANT_Utf8);
572 if ( aname != unicode_new_char("Code")) {
573 skipattributebody ();
576 if (m -> jcode) panic ("Two code-attributes for one method!");
579 m -> maxstack = suck_u2();
580 m -> maxlocals = suck_u2();
581 m -> jcodelength = suck_u4();
582 m -> jcode = MNEW (u1, m->jcodelength);
583 suck_nbytes (m->jcode, m->jcodelength);
584 m -> exceptiontablelength = suck_u2 ();
585 m -> exceptiontable =
586 MNEW (exceptiontable, m->exceptiontablelength);
589 count_vmcode_len += m->jcodelength + 18;
590 count_extable_len += 8 * m->exceptiontablelength;
593 for (e=0; e < m->exceptiontablelength; e++) {
595 m -> exceptiontable[e].startpc = suck_u2();
596 m -> exceptiontable[e].endpc = suck_u2();
597 m -> exceptiontable[e].handlerpc = suck_u2();
600 if (!idx) m -> exceptiontable[e].catchtype = NULL;
602 m -> exceptiontable[e].catchtype =
603 class_getconstant (c, idx, CONSTANT_Class);
607 skipattributes ( suck_u2() );
616 /********************* Funktion: method_free ***********************************
618 gibt allen Speicher, der extra f"ur eine Methode angefordert wurde,
621 *******************************************************************************/
623 static void method_free (methodinfo *m)
625 if (m->jcode) MFREE (m->jcode, u1, m->jcodelength);
626 if (m->exceptiontable)
627 MFREE (m->exceptiontable, exceptiontable, m->exceptiontablelength);
628 if (m->mcode) CFREE (m->mcode, m->mcodelength);
629 if (m->stubroutine) {
630 if (m->flags & ACC_NATIVE) removenativestub (m->stubroutine);
631 else removecompilerstub (m->stubroutine);
636 /************** Funktion: method_display (nur zu Debug-Zwecken) **************/
638 void method_display (methodinfo *m)
641 printflags (m -> flags);
643 unicode_display (m -> name);
645 unicode_display (m -> descriptor);
650 /******************** Funktion: method_canoverwrite ****************************
652 "uberpr"ft, ob eine Methode mit einer anderen typ- und namensidentisch
653 ist (also mit einer Methodendefinition eine andere "uberschrieben
656 *******************************************************************************/
658 static bool method_canoverwrite (methodinfo *m, methodinfo *old)
660 if (m->name != old->name) return false;
661 if (m->descriptor != old->descriptor) return false;
662 if (m->flags & ACC_STATIC) return false;
669 /******************************************************************************/
670 /************************ Funktionen fuer Class *******************************/
671 /******************************************************************************/
674 /******************** Funktion: class_get **************************************
676 Sucht im System die Klasse mit dem gew"unschten Namen, oder erzeugt
677 eine neue 'classinfo'-Struktur (und h"angt sie in die Liste der zu
678 ladenen Klassen ein).
680 *******************************************************************************/
682 classinfo *class_get (unicode *u)
686 if (u->class) return u->class;
689 count_class_infos += sizeof(classinfo);
701 c -> interfacescount = 0;
702 c -> interfaces = NULL;
703 c -> fieldscount = 0;
705 c -> methodscount = 0;
709 c -> instancesize = 0;
710 c -> header.vftbl = NULL;
712 c -> initialized = false;
714 unicode_setclasslink (u,c);
715 list_addlast (&unloadedclasses, c);
722 /******************** Funktion: class_getconstant ******************************
724 holt aus dem ConstantPool einer Klasse den Wert an der Stelle 'pos'.
725 Der Wert mu"s vom Typ 'ctype' sein, sonst wird das System angehalten.
727 *******************************************************************************/
729 voidptr class_getconstant (classinfo *c, u4 pos, u4 ctype)
731 if (pos >= c->cpcount)
732 panic ("Attempt to access constant outside range");
733 if (c->cptags[pos] != ctype) {
734 sprintf (logtext, "Type mismatch on constant: %d requested, %d here",
735 (int) ctype, (int) c->cptags[pos] );
739 return c->cpinfos[pos];
743 /********************* Funktion: class_constanttype ****************************
745 Findet heraus, welchen Typ ein Eintrag in den ConstantPool einer
748 *******************************************************************************/
750 u4 class_constanttype (classinfo *c, u4 pos)
752 if (pos >= c->cpcount)
753 panic ("Attempt to access constant outside range");
754 return c->cptags[pos];
758 /******************** Funktion: class_loadcpool ********************************
760 l"adt den gesammten ConstantPool einer Klasse.
762 Dabei werden die einzelnen Eintr"age in ein wesentlich einfachers
763 Format gebracht (Klassenreferenzen werden aufgel"ost, ...)
764 F"ur eine genaue "Ubersicht "uber das kompakte Format siehe: 'global.h'
766 *******************************************************************************/
768 static void class_loadcpool (classinfo *c)
771 typedef struct forward_class { /* Diese Strukturen dienen dazu, */
772 struct forward_class *next; /* die Infos, die beim ersten */
773 u2 thisindex; /* Durchgang durch den ConstantPool */
774 u2 name_index; /* gelesen werden, aufzunehmen. */
775 } forward_class; /* Erst nachdem der ganze Pool */
776 /* gelesen wurde, k"onnen alle */
777 typedef struct forward_string { /* Felder kompletiert werden */
778 struct forward_string *next; /* (und das auch nur in der richtigen */
779 u2 thisindex; /* Reihenfolge) */
783 typedef struct forward_nameandtype {
784 struct forward_nameandtype *next;
788 } forward_nameandtype;
790 typedef struct forward_fieldmethint {
791 struct forward_fieldmethint *next;
795 u2 nameandtype_index;
796 } forward_fieldmethint;
801 long int dumpsize = dump_size ();
803 forward_class *forward_classes = NULL;
804 forward_string *forward_strings = NULL;
805 forward_nameandtype *forward_nameandtypes = NULL;
806 forward_fieldmethint *forward_fieldmethints = NULL;
808 u4 cpcount = c -> cpcount = suck_u2();
809 u1 *cptags = c -> cptags = MNEW (u1, cpcount);
810 voidptr *cpinfos = c -> cpinfos = MNEW (voidptr, cpcount);
813 count_const_pool_len += (sizeof(voidptr) + 1) * cpcount;
817 for (idx=0; idx<cpcount; idx++) {
818 cptags[idx] = CONSTANT_UNUSED;
823 /******* Erster Durchgang *******/
824 /* Alle Eintr"age, die nicht unmittelbar aufgel"ost werden k"onnen,
825 werden einmal `auf Vorrat' in tempor"are Strukturen eingelesen,
826 und dann am Ende nocheinmal durchgegangen */
829 while (idx < cpcount) {
833 case CONSTANT_Class: {
834 forward_class *nfc = DNEW(forward_class);
836 nfc -> next = forward_classes;
837 forward_classes = nfc;
839 nfc -> thisindex = idx;
840 nfc -> name_index = suck_u2 ();
846 case CONSTANT_Fieldref:
847 case CONSTANT_Methodref:
848 case CONSTANT_InterfaceMethodref: {
849 forward_fieldmethint *nff = DNEW (forward_fieldmethint);
851 nff -> next = forward_fieldmethints;
852 forward_fieldmethints = nff;
854 nff -> thisindex = idx;
856 nff -> class_index = suck_u2 ();
857 nff -> nameandtype_index = suck_u2 ();
863 case CONSTANT_String: {
864 forward_string *nfs = DNEW (forward_string);
866 nfs -> next = forward_strings;
867 forward_strings = nfs;
869 nfs -> thisindex = idx;
870 nfs -> string_index = suck_u2 ();
876 case CONSTANT_NameAndType: {
877 forward_nameandtype *nfn = DNEW (forward_nameandtype);
879 nfn -> next = forward_nameandtypes;
880 forward_nameandtypes = nfn;
882 nfn -> thisindex = idx;
883 nfn -> name_index = suck_u2 ();
884 nfn -> sig_index = suck_u2 ();
890 case CONSTANT_Integer: {
891 constant_integer *ci = NEW (constant_integer);
894 count_const_pool_len += sizeof(constant_integer);
897 ci -> value = suck_s4 ();
898 cptags [idx] = CONSTANT_Integer;
905 case CONSTANT_Float: {
906 constant_float *cf = NEW (constant_float);
909 count_const_pool_len += sizeof(constant_float);
912 cf -> value = suck_float ();
913 cptags [idx] = CONSTANT_Float;
919 case CONSTANT_Long: {
920 constant_long *cl = NEW(constant_long);
923 count_const_pool_len += sizeof(constant_long);
926 cl -> value = suck_s8 ();
927 cptags [idx] = CONSTANT_Long;
933 case CONSTANT_Double: {
934 constant_double *cd = NEW(constant_double);
937 count_const_pool_len += sizeof(constant_double);
940 cd -> value = suck_double ();
941 cptags [idx] = CONSTANT_Double;
947 case CONSTANT_Utf8: {
952 cptags [idx] = CONSTANT_Utf8;
959 sprintf (logtext, "Unkown constant type: %d",(int) t);
968 /* Aufl"osen der noch unfertigen Eintr"age */
970 while (forward_classes) {
972 class_getconstant (c, forward_classes -> name_index, CONSTANT_Utf8);
974 if ( (name->length>0) && (name->text[0]=='[') ) {
975 checkfielddescriptor (name);
977 cptags [forward_classes -> thisindex] = CONSTANT_Arraydescriptor;
978 cpinfos [forward_classes -> thisindex] =
979 buildarraydescriptor(name->text, name->length);
983 cptags [forward_classes -> thisindex] = CONSTANT_Class;
984 cpinfos [forward_classes -> thisindex] = class_get (name);
986 forward_classes = forward_classes -> next;
990 while (forward_strings) {
992 class_getconstant (c, forward_strings -> string_index, CONSTANT_Utf8);
994 cptags [forward_strings -> thisindex] = CONSTANT_String;
995 cpinfos [forward_strings -> thisindex] = text;
997 forward_strings = forward_strings -> next;
1000 while (forward_nameandtypes) {
1001 constant_nameandtype *cn = NEW (constant_nameandtype);
1004 count_const_pool_len += sizeof(constant_nameandtype);
1007 cn -> name = class_getconstant
1008 (c, forward_nameandtypes -> name_index, CONSTANT_Utf8);
1009 cn -> descriptor = class_getconstant
1010 (c, forward_nameandtypes -> sig_index, CONSTANT_Utf8);
1012 cptags [forward_nameandtypes -> thisindex] = CONSTANT_NameAndType;
1013 cpinfos [forward_nameandtypes -> thisindex] = cn;
1015 forward_nameandtypes = forward_nameandtypes -> next;
1019 while (forward_fieldmethints) {
1020 constant_nameandtype *nat;
1021 constant_FMIref *fmi = NEW (constant_FMIref);
1024 count_const_pool_len += sizeof(constant_FMIref);
1027 nat = class_getconstant
1028 (c, forward_fieldmethints -> nameandtype_index, CONSTANT_NameAndType);
1030 fmi -> class = class_getconstant
1031 (c, forward_fieldmethints -> class_index, CONSTANT_Class);
1032 fmi -> name = nat -> name;
1033 fmi -> descriptor = nat -> descriptor;
1035 cptags [forward_fieldmethints -> thisindex] = forward_fieldmethints -> tag;
1036 cpinfos [forward_fieldmethints -> thisindex] = fmi;
1038 switch (forward_fieldmethints -> tag) {
1039 case CONSTANT_Fieldref: checkfielddescriptor (fmi->descriptor);
1041 case CONSTANT_InterfaceMethodref:
1042 case CONSTANT_Methodref: checkmethoddescriptor (fmi->descriptor);
1046 forward_fieldmethints = forward_fieldmethints -> next;
1051 dump_release (dumpsize);
1055 /********************** Funktion: class_load ***********************************
1057 l"adt alle Infos f"ur eine ganze Klasse aus einem ClassFile. Die
1058 'classinfo'-Struktur mu"s bereits angelegt worden sein.
1060 Die Superklasse und die Interfaces, die diese Klasse implementiert,
1061 m"ussen zu diesem Zeitpunkt noch nicht geladen sein, die
1062 Verbindung dazu wird sp"ater in der Funktion 'class_link' hergestellt.
1064 Die gelesene Klasse wird dann aus der Liste 'unloadedclasses' ausgetragen
1065 und in die Liste 'unlinkedclasses' eingh"angt.
1067 *******************************************************************************/
1069 static void class_load (classinfo *c)
1076 sprintf (logtext, "Loading class: ");
1077 unicode_sprint (logtext+strlen(logtext), c->name );
1082 suck_start (c->name);
1084 if (suck_u4() != MAGIC) panic("Can not find class-file signature");
1087 if (ma != MAJOR_VERSION) {
1088 sprintf (logtext, "Can only support major version %d, but not %d",
1089 MAJOR_VERSION, (int) ma);
1092 if (mi > MINOR_VERSION) {
1093 sprintf (logtext, "Minor version %d is not yet supported.", (int) mi);
1098 class_loadcpool (c);
1100 c -> flags = suck_u2 ();
1101 suck_u2 (); /* this */
1103 if ( (i = suck_u2 () ) ) {
1104 c -> super = class_getconstant (c, i, CONSTANT_Class);
1110 c -> interfacescount = suck_u2 ();
1111 c -> interfaces = MNEW (classinfo*, c -> interfacescount);
1112 for (i=0; i < c -> interfacescount; i++) {
1113 c -> interfaces [i] =
1114 class_getconstant (c, suck_u2(), CONSTANT_Class);
1117 c -> fieldscount = suck_u2 ();
1118 c -> fields = MNEW (fieldinfo, c -> fieldscount);
1119 for (i=0; i < c -> fieldscount; i++) {
1120 field_load (&(c->fields[i]), c);
1123 c -> methodscount = suck_u2 ();
1124 c -> methods = MNEW (methodinfo, c -> methodscount);
1125 for (i=0; i < c -> methodscount; i++) {
1126 method_load (&(c -> methods [i]), c);
1130 count_class_infos += sizeof(classinfo*) * c -> interfacescount;
1131 count_class_infos += sizeof(fieldinfo) * c -> fieldscount;
1132 count_class_infos += sizeof(methodinfo) * c -> methodscount;
1136 skipattributes ( suck_u2() );
1141 list_remove (&unloadedclasses, c);
1142 list_addlast (&unlinkedclasses, c);
1147 /************** interne Funktion: class_highestinterface ***********************
1149 wird von der Funktion class_link ben"otigt, um festzustellen, wie gro"s
1150 die Interfacetable einer Klasse sein mu"s.
1152 *******************************************************************************/
1154 static s4 class_highestinterface (classinfo *c)
1159 if ( ! (c->flags & ACC_INTERFACE) ) {
1160 sprintf (logtext, "Interface-methods count requested for non-interface: ");
1161 unicode_sprint (logtext+strlen(logtext), c->name);
1166 for (i=0; i<c->interfacescount; i++) {
1167 s4 h2 = class_highestinterface (c->interfaces[i]);
1174 /* class_addinterface **********************************************************
1176 wird von der Funktion class_link ben"otigt, um eine Virtual Function
1177 Table f"ur ein Interface (und alle weiteren von diesem Interface
1178 implementierten Interfaces) in eine Klasse einzutragen.
1180 *******************************************************************************/
1182 static void class_addinterface (classinfo *c, classinfo *ic)
1186 vftbl *vftbl = c->vftbl;
1188 if (i >= vftbl->interfacetablelength)
1189 panic ("Inernal error: interfacetable overflow");
1190 if (vftbl->interfacetable[-i])
1193 if (ic->methodscount == 0) { /* fake entry needed for subtype test */
1194 vftbl->interfacevftbllength[i] = 1;
1195 vftbl->interfacetable[-i] = MNEW(methodptr, 1);
1196 vftbl->interfacetable[-i][0] = NULL;
1199 vftbl->interfacevftbllength[i] = ic->methodscount;
1200 vftbl->interfacetable[-i] = MNEW(methodptr, ic->methodscount);
1203 count_vftbl_len += sizeof(methodptr) *
1204 (ic->methodscount + (ic->methodscount == 0));
1207 for (j=0; j<ic->methodscount; j++) {
1210 for (m = 0; m < sc->methodscount; m++) {
1211 methodinfo *mi = &(sc->methods[m]);
1212 if (method_canoverwrite(mi, &(ic->methods[j]))) {
1213 vftbl->interfacetable[-i][j] =
1214 vftbl->table[mi->vftblindex];
1224 for (j = 0; j < ic->interfacescount; j++)
1225 class_addinterface(c, ic->interfaces[j]);
1229 /********************** Funktion: class_link ***********************************
1231 versucht, eine Klasse in das System voll zu integrieren (linken). Dazu
1232 m"ussen sowol die Superklasse, als auch alle implementierten
1233 Interfaces schon gelinkt sein.
1234 Diese Funktion berechnet sowohl die L"ange (in Bytes) einer Instanz
1235 dieser Klasse, als auch die Virtual Function Tables f"ur normale
1236 Methoden als auch Interface-Methoden.
1238 Wenn die Klasse erfolgreich gelinkt werden kann, dann wird sie aus
1239 der Liste 'unlinkedclasses' ausgeh"angt, und in die Klasse 'linkedclasses'
1241 Wenn nicht, dann wird sie ans Ende der Liste 'unlinkedclasses' gestellt.
1243 Achtung: Bei zyklischen Klassendefinitionen ger"at das Programm hier in
1244 eine Endlosschleife!! (Da muss ich mir noch was einfallen lassen)
1246 *******************************************************************************/
1248 static void class_link (classinfo *c)
1250 s4 supervftbllength; /* vftbllegnth of super class */
1251 s4 vftbllength; /* vftbllength of current class */
1252 s4 interfacetablelength; /* interface table length */
1253 classinfo *super = c->super; /* super class */
1254 classinfo *ic, *c2; /* intermediate class variables */
1255 vftbl *v; /* vftbl of current class */
1256 s4 i; /* interface/method/field counter */
1259 /* check if all superclasses are already linked, if not put c at end of
1260 unlinked list and return. Additionally initialize class fields. */
1262 /* check interfaces */
1264 for (i = 0; i < c->interfacescount; i++) {
1265 ic = c->interfaces[i];
1267 list_remove(&unlinkedclasses, c);
1268 list_addlast(&unlinkedclasses, c);
1273 /* check super class */
1275 if (super == NULL) { /* class java.long.Object */
1277 c->instancesize = sizeof(java_objectheader);
1279 vftbllength = supervftbllength = 0;
1281 c->finalizer = NULL;
1284 if (!super->linked) {
1285 list_remove(&unlinkedclasses, c);
1286 list_addlast(&unlinkedclasses, c);
1290 if (c->flags & ACC_INTERFACE)
1291 c->index = interfaceindex++;
1293 c->index = super->index + 1;
1295 c->instancesize = super->instancesize;
1297 vftbllength = supervftbllength = super->vftbl->vftbllength;
1299 c->finalizer = super->finalizer;
1304 sprintf (logtext, "Linking Class: ");
1305 unicode_sprint (logtext+strlen(logtext), c->name );
1309 /* compute vftbl length */
1311 for (i = 0; i < c->methodscount; i++) {
1312 methodinfo *m = &(c->methods[i]);
1314 if (!(m->flags & ACC_STATIC)) { /* is instance method */
1315 classinfo *sc = super;
1318 for (j = 0; j < sc->methodscount; j++) {
1319 if (method_canoverwrite(m, &(sc->methods[j]))) {
1320 m->vftblindex = sc->methods[j].vftblindex;
1321 goto foundvftblindex;
1326 m->vftblindex = (vftbllength++);
1332 count_vftbl_len += sizeof(vftbl) + sizeof(methodptr)*(vftbllength-1);
1335 /* compute interfacetable length */
1337 interfacetablelength = 0;
1340 for (i = 0; i < c2->interfacescount; i++) {
1341 s4 h = class_highestinterface (c2->interfaces[i]) + 1;
1342 if (h > interfacetablelength)
1343 interfacetablelength = h;
1348 /* allocate virtual function table */
1350 v = (vftbl*) mem_alloc(sizeof(vftbl) + sizeof(methodptr) *
1351 (vftbllength - 1) + sizeof(methodptr*) *
1352 (interfacetablelength - (interfacetablelength > 0)));
1353 v = (vftbl*) (((methodptr*) v) + (interfacetablelength - 1) *
1354 (interfacetablelength > 1));
1355 c->header.vftbl = c->vftbl = v;
1357 v->vftbllength = vftbllength;
1358 v->interfacetablelength = interfacetablelength;
1360 /* copy virtual function table of super class */
1362 for (i = 0; i < supervftbllength; i++)
1363 v->table[i] = super->vftbl->table[i];
1365 /* add method stubs into virtual function table */
1367 for (i = 0; i < c->methodscount; i++) {
1368 methodinfo *m = &(c->methods[i]);
1369 if (!(m->flags & ACC_STATIC)) {
1370 v->table[m->vftblindex] = m->stubroutine;
1374 /* compute instance size and offset of each field */
1376 for (i = 0; i < c->fieldscount; i++) {
1378 fieldinfo *f = &(c->fields[i]);
1380 if (!(f->flags & ACC_STATIC) ) {
1381 dsize = desc_typesize (f->descriptor);
1382 c->instancesize = ALIGN (c->instancesize, dsize);
1383 f->offset = c->instancesize;
1384 c->instancesize += dsize;
1388 /* initialize interfacetable and interfacevftbllength */
1390 v->interfacevftbllength = MNEW (s4, interfacetablelength);
1393 count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
1396 for (i = 0; i < interfacetablelength; i++) {
1397 v->interfacevftbllength[i] = 0;
1398 v->interfacetable[-i] = NULL;
1401 /* add interfaces */
1403 for (c2 = c; c2 != NULL; c2 = c2->super)
1404 for (i = 0; i < c2->interfacescount; i++) {
1405 class_addinterface (c, c2->interfaces[i]);
1408 /* add finalizer method (not for java.lang.Object) */
1410 if (super != NULL) {
1412 static unicode *finame = NULL;
1413 static unicode *fidesc = NULL;
1416 finame = unicode_new_char("finalize");
1418 fidesc = unicode_new_char("()V");
1420 fi = class_findmethod (c, finame, fidesc);
1422 if (!(fi->flags & ACC_STATIC)) {
1432 list_remove (&unlinkedclasses, c);
1433 list_addlast (&linkedclasses, c);
1437 /******************* Funktion: class_freepool **********************************
1439 Gibt alle Resourcen, die der ConstantPool einer Klasse ben"otigt,
1442 *******************************************************************************/
1444 static void class_freecpool (classinfo *c)
1450 for (idx=0; idx < c->cpcount; idx++) {
1451 tag = c->cptags[idx];
1452 info = c->cpinfos[idx];
1456 case CONSTANT_Fieldref:
1457 case CONSTANT_Methodref:
1458 case CONSTANT_InterfaceMethodref:
1459 FREE (info, constant_FMIref);
1461 case CONSTANT_Integer:
1462 FREE (info, constant_integer);
1464 case CONSTANT_Float:
1465 FREE (info, constant_float);
1468 FREE (info, constant_long);
1470 case CONSTANT_Double:
1471 FREE (info, constant_double);
1473 case CONSTANT_NameAndType:
1474 FREE (info, constant_nameandtype);
1476 case CONSTANT_Arraydescriptor:
1477 freearraydescriptor (info);
1483 MFREE (c -> cptags, u1, c -> cpcount);
1484 MFREE (c -> cpinfos, voidptr, c -> cpcount);
1488 /*********************** Funktion: class_free **********************************
1490 Gibt alle Resourcen, die eine ganze Klasse ben"otigt, frei
1492 *******************************************************************************/
1494 static void class_free (classinfo *c)
1499 unicode_unlinkclass (c->name);
1501 class_freecpool (c);
1503 MFREE (c->interfaces, classinfo*, c->interfacescount);
1505 for (i = 0; i < c->fieldscount; i++)
1506 field_free(&(c->fields[i]));
1507 MFREE (c->fields, fieldinfo, c->fieldscount);
1509 for (i = 0; i < c->methodscount; i++)
1510 method_free(&(c->methods[i]));
1511 MFREE (c->methods, methodinfo, c->methodscount);
1513 if ((v = c->vftbl) != NULL) {
1514 for (i = 0; i < v->interfacetablelength; i++) {
1515 MFREE (v->interfacetable[-i], methodptr, v->interfacevftbllength[i]);
1517 MFREE (v->interfacevftbllength, s4, v->interfacetablelength);
1519 i = sizeof(vftbl) + sizeof(methodptr) * (v->vftbllength - 1) +
1520 sizeof(methodptr*) * (v->interfacetablelength -
1521 (v->interfacetablelength > 0));
1522 v = (vftbl*) (((methodptr*) v) - (v->interfacetablelength - 1) *
1523 (v->interfacetablelength > 1));
1527 FREE (c, classinfo);
1531 /************************* Funktion: class_findfield ***************************
1533 sucht in einer 'classinfo'-Struktur nach einem Feld mit gew"unschtem
1536 *******************************************************************************/
1538 fieldinfo *class_findfield (classinfo *c, unicode *name, unicode *desc)
1541 for (i = 0; i < c->fieldscount; i++) {
1542 if ((c->fields[i].name == name) && (c->fields[i].descriptor == desc))
1543 return &(c->fields[i]);
1545 panic ("Can not find field given in CONSTANT_Fieldref");
1550 /************************* Funktion: class_findmethod **************************
1552 sucht in einer 'classinfo'-Struktur nach einer Methode mit gew"unschtem
1554 Wenn als Typ NULL angegeben wird, dann ist der Typ egal.
1556 *******************************************************************************/
1558 methodinfo *class_findmethod (classinfo *c, unicode *name, unicode *desc)
1561 for (i = 0; i < c->methodscount; i++) {
1562 if ((c->methods[i].name == name) && ((desc == NULL) ||
1563 (c->methods[i].descriptor == desc)))
1564 return &(c->methods[i]);
1570 /************************* Funktion: class_resolvemethod ***********************
1572 sucht eine Klasse und alle Superklassen ab, um eine Methode zu finden.
1574 *******************************************************************************/
1577 methodinfo *class_resolvemethod (classinfo *c, unicode *name, unicode *desc)
1580 methodinfo *m = class_findmethod (c, name, desc);
1589 /************************* Funktion: class_issubclass **************************
1591 "uberpr"uft, ob eine Klasse von einer anderen Klasse abgeleitet ist.
1593 *******************************************************************************/
1595 bool class_issubclass (classinfo *sub, classinfo *super)
1598 if (!sub) return false;
1599 if (sub==super) return true;
1606 /****************** Initialisierungsfunktion f"ur eine Klasse ******************
1608 In Java kann jede Klasse ein statische Initialisierungsfunktion haben.
1609 Diese Funktion mu"s aufgerufen werden, BEVOR irgendwelche Methoden der
1610 Klasse aufgerufen werden, oder auf statische Variablen zugegriffen
1613 *******************************************************************************/
1616 extern int blockInts;
1619 void class_init (classinfo *c)
1622 java_objectheader *exceptionptr;
1626 if (!makeinitializations) return;
1627 if (c->initialized) return;
1628 c -> initialized = true;
1630 if (c->super) class_init (c->super);
1631 for (i=0; i < c->interfacescount; i++) class_init(c->interfaces[i]);
1633 m = class_findmethod (c,
1634 unicode_new_char ("<clinit>"),
1635 unicode_new_char ("()V"));
1638 sprintf (logtext, "Class ");
1639 unicode_sprint (logtext+strlen(logtext), c->name);
1640 sprintf (logtext+strlen(logtext), " has no initializer");
1646 if (! (m->flags & ACC_STATIC)) panic ("Class initializer is not static!");
1649 sprintf (logtext, "Starting initializer for class: ");
1650 unicode_sprint (logtext+strlen(logtext), c->name);
1659 exceptionptr = asm_calljavamethod (m, NULL,NULL,NULL,NULL);
1662 assert(blockInts == 0);
1667 printf ("#### Initializer has thrown: ");
1668 unicode_display (exceptionptr->vftbl->class->name);
1674 sprintf (logtext, "Finished initializer for class: ");
1675 unicode_sprint (logtext+strlen(logtext), c->name);
1684 /********* Funktion: class_showconstantpool (nur f"ur Debug-Zwecke) *********/
1686 void class_showconstantpool (classinfo *c)
1691 printf ("---- dump of constant pool ----\n");
1693 for (i=0; i<c->cpcount; i++) {
1694 printf ("#%d: ", (int) i);
1696 e = c -> cpinfos [i];
1699 switch (c -> cptags [i]) {
1700 case CONSTANT_Class:
1701 printf ("Classreference -> ");
1702 unicode_display ( ((classinfo*)e) -> name );
1705 case CONSTANT_Fieldref:
1706 printf ("Fieldref -> "); goto displayFMI;
1707 case CONSTANT_Methodref:
1708 printf ("Methodref -> "); goto displayFMI;
1709 case CONSTANT_InterfaceMethodref:
1710 printf ("InterfaceMethod -> "); goto displayFMI;
1713 constant_FMIref *fmi = e;
1714 unicode_display ( fmi->class->name );
1716 unicode_display ( fmi->name);
1718 unicode_display ( fmi->descriptor );
1722 case CONSTANT_String:
1723 printf ("String -> ");
1724 unicode_display (e);
1726 case CONSTANT_Integer:
1727 printf ("Integer -> %d", (int) ( ((constant_integer*)e) -> value) );
1729 case CONSTANT_Float:
1730 printf ("Float -> %f", ((constant_float*)e) -> value);
1732 case CONSTANT_Double:
1733 printf ("Double -> %f", ((constant_double*)e) -> value);
1737 u8 v = ((constant_long*)e) -> value;
1739 printf ("Long -> %ld", (long int) v);
1741 printf ("Long -> HI: %ld, LO: %ld\n",
1742 (long int) v.high, (long int) v.low);
1746 case CONSTANT_NameAndType:
1747 { constant_nameandtype *cnt = e;
1748 printf ("NameAndType: ");
1749 unicode_display (cnt->name);
1751 unicode_display (cnt->descriptor);
1755 printf ("Utf8 -> ");
1756 unicode_display (e);
1758 case CONSTANT_Arraydescriptor: {
1759 printf ("Arraydescriptor: ");
1760 displayarraydescriptor (e);
1764 panic ("Invalid type of ConstantPool-Entry");
1776 /********** Funktion: class_showmethods (nur f"ur Debug-Zwecke) *************/
1778 void class_showmethods (classinfo *c)
1782 printf ("--------- Fields and Methods ----------------\n");
1783 printf ("Flags: "); printflags (c->flags); printf ("\n");
1785 printf ("This: "); unicode_display (c->name); printf ("\n");
1787 printf ("Super: "); unicode_display (c->super->name); printf ("\n");
1789 printf ("Index: %d\n", c->index);
1791 printf ("interfaces:\n");
1792 for (i=0; i < c-> interfacescount; i++) {
1794 unicode_display (c -> interfaces[i] -> name);
1795 printf (" (%d)\n", c->interfaces[i] -> index);
1798 printf ("fields:\n");
1799 for (i=0; i < c -> fieldscount; i++) {
1800 field_display (&(c -> fields[i]));
1803 printf ("methods:\n");
1804 for (i=0; i < c -> methodscount; i++) {
1805 methodinfo *m = &(c->methods[i]);
1806 if ( !(m->flags & ACC_STATIC))
1807 printf ("vftblindex: %d ", m->vftblindex);
1809 method_display ( m );
1813 printf ("Virtual function table:\n");
1814 for (i=0; i<c->vftbl->vftbllength; i++) {
1815 printf ("entry: %d, %ld\n", i, (long int) (c->vftbl->table[i]) );
1822 /******************************************************************************/
1823 /******************* Funktionen fuer den Class-loader generell ****************/
1824 /******************************************************************************/
1827 /********************* Funktion: loader_load ***********************************
1829 l"adt und linkt die ge"unschte Klasse und alle davon
1830 referenzierten Klassen und Interfaces
1831 Return: Einen Zeiger auf diese Klasse
1833 *******************************************************************************/
1835 classinfo *loader_load (unicode *topname)
1839 long int starttime=0,stoptime=0;
1841 intsDisable(); /* schani */
1843 if (getloadingtime) starttime = getcputime();
1845 top = class_get (topname);
1847 while ( (c = list_first(&unloadedclasses)) ) {
1851 while ( (c = list_first(&unlinkedclasses)) ) {
1855 if (getloadingtime) {
1856 stoptime = getcputime();
1857 loadingtime += (stoptime-starttime);
1860 intsRestore(); /* schani */
1866 /******************* interne Funktion: loader_createarrayclass *****************
1868 Erzeugt (und linkt) eine Klasse f"ur die Arrays.
1870 *******************************************************************************/
1872 static classinfo *loader_createarrayclass ()
1875 c = class_get ( unicode_new_char ("The_Array_Class") );
1877 list_remove (&unloadedclasses, c);
1878 list_addlast (&unlinkedclasses, c);
1879 c -> super = class_java_lang_Object;
1887 /********************** Funktion: loader_init **********************************
1889 Initialisiert alle Listen und l"adt alle Klassen, die vom System
1890 und vom Compiler direkt ben"otigt werden.
1892 *******************************************************************************/
1898 list_init (&unloadedclasses, OFFSET(classinfo, listnode) );
1899 list_init (&unlinkedclasses, OFFSET(classinfo, listnode) );
1900 list_init (&linkedclasses, OFFSET(classinfo, listnode) );
1903 class_java_lang_Object =
1904 loader_load ( unicode_new_char ("java/lang/Object") );
1905 class_java_lang_String =
1906 loader_load ( unicode_new_char ("java/lang/String") );
1907 class_java_lang_ClassCastException =
1908 loader_load ( unicode_new_char ("java/lang/ClassCastException") );
1909 class_java_lang_NullPointerException =
1910 loader_load ( unicode_new_char ("java/lang/NullPointerException") );
1911 class_java_lang_ArrayIndexOutOfBoundsException = loader_load (
1912 unicode_new_char ("java/lang/ArrayIndexOutOfBoundsException") );
1913 class_java_lang_NegativeArraySizeException = loader_load (
1914 unicode_new_char ("java/lang/NegativeArraySizeException") );
1915 class_java_lang_OutOfMemoryError = loader_load (
1916 unicode_new_char ("java/lang/OutOfMemoryError") );
1917 class_java_lang_ArrayStoreException =
1918 loader_load ( unicode_new_char ("java/lang/ArrayStoreException") );
1919 class_java_lang_ArithmeticException =
1920 loader_load ( unicode_new_char ("java/lang/ArithmeticException") );
1921 class_java_lang_ThreadDeath = /* schani */
1922 loader_load ( unicode_new_char ("java/lang/ThreadDeath") );
1924 class_array = loader_createarrayclass ();
1927 proto_java_lang_ClassCastException =
1928 builtin_new(class_java_lang_ClassCastException);
1929 heap_addreference ( (void**) &proto_java_lang_ClassCastException);
1931 proto_java_lang_NullPointerException =
1932 builtin_new(class_java_lang_NullPointerException);
1933 heap_addreference ( (void**) &proto_java_lang_NullPointerException);
1935 proto_java_lang_ArrayIndexOutOfBoundsException =
1936 builtin_new(class_java_lang_ArrayIndexOutOfBoundsException);
1937 heap_addreference ( (void**) &proto_java_lang_ArrayIndexOutOfBoundsException);
1939 proto_java_lang_NegativeArraySizeException =
1940 builtin_new(class_java_lang_NegativeArraySizeException);
1941 heap_addreference ( (void**) &proto_java_lang_NegativeArraySizeException);
1943 proto_java_lang_OutOfMemoryError =
1944 builtin_new(class_java_lang_OutOfMemoryError);
1945 heap_addreference ( (void**) &proto_java_lang_OutOfMemoryError);
1947 proto_java_lang_ArithmeticException =
1948 builtin_new(class_java_lang_ArithmeticException);
1949 heap_addreference ( (void**) &proto_java_lang_ArithmeticException);
1951 proto_java_lang_ArrayStoreException =
1952 builtin_new(class_java_lang_ArrayStoreException);
1953 heap_addreference ( (void**) &proto_java_lang_ArrayStoreException);
1955 proto_java_lang_ThreadDeath = /* schani */
1956 builtin_new(class_java_lang_ThreadDeath);
1957 heap_addreference ( (void**) &proto_java_lang_ThreadDeath);
1963 /********************* Funktion: loader_initclasses ****************************
1965 initialisiert alle geladenen aber noch nicht initialisierten Klassen
1967 *******************************************************************************/
1969 void loader_initclasses ()
1973 intsDisable(); /* schani */
1975 if (makeinitializations) {
1976 c = list_first (&linkedclasses);
1979 c = list_next (&linkedclasses, c);
1983 intsRestore(); /* schani */
1986 static s4 classvalue = 0;
1988 static void loader_compute_class_values (classinfo *c)
1992 c->vftbl->baseval = ++classvalue;
1994 while (subs != NULL) {
1995 loader_compute_class_values(subs);
1996 subs = subs->nextsub;
1998 c->vftbl->diffval = classvalue - c->vftbl->baseval;
2002 for (i = 0; i < c->index; i++)
2004 printf("%3d %3d ", (int) c->vftbl->baseval, c->vftbl->diffval);
2005 unicode_display(c->name);
2012 void loader_compute_subclasses ()
2016 intsDisable(); /* schani */
2018 c = list_first (&linkedclasses);
2020 if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
2021 c->nextsub = c->super->sub;
2024 c = list_next (&linkedclasses, c);
2027 loader_compute_class_values(class_java_lang_Object);
2029 intsRestore(); /* schani */
2034 /******************** Funktion: loader_close ***********************************
2036 gibt alle Resourcen wieder frei
2038 *******************************************************************************/
2040 void loader_close ()
2044 while ( (c=list_first(&unloadedclasses)) ) {
2045 list_remove (&unloadedclasses,c);
2048 while ( (c=list_first(&unlinkedclasses)) ) {
2049 list_remove (&unlinkedclasses,c);
2052 while ( (c=list_first(&linkedclasses)) ) {
2053 list_remove (&linkedclasses,c);
2060 * These are local overrides for various environment variables in Emacs.
2061 * Please do not remove this and leave it at the end of the file, where
2062 * Emacs will automagically detect them.
2063 * ---------------------------------------------------------------------
2066 * indent-tabs-mode: t