Initial revision
[cacao.git] / ncomp / ntools.c
1 /***************************** ncomp/ntools.c **********************************
2
3         Copyright (c) 1997 A. Krall, R. Grafl, M. Gschwind, M. Probst
4
5         See file COPYRIGHT for information on usage and disclaimer of warranties
6
7         Ein paar zus"atzlich notwendige Funktionen, die sonst nirgends 
8         hinpassen.
9
10         Authors: Andreas  Krall      EMAIL: cacao@complang.tuwien.ac.at
11                  Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
12
13         Last Change: 1997/11/03
14
15 *******************************************************************************/
16
17
18 /***************** Funktion: compiler_addinitclass ****************************
19
20         zum Eintragen einer Klasse in die Liste der noch zu initialisierenden 
21         Klassen
22         
23 ******************************************************************************/
24                                 
25 static void compiler_addinitclass (classinfo *c)
26 {
27         classinfo *cl;
28
29         if (c->initialized) return;
30         
31         cl = chain_first(uninitializedclasses);
32         if (cl == c)
33                 return;
34         
35         if (cl == class)
36                 cl = chain_next(uninitializedclasses);
37         for (;;) {
38                 if (cl == c)
39                         return;
40                 if (cl == NULL) {
41                         if (runverbose) {
42                                 sprintf(logtext, "compiler_addinitclass: ");
43                                 unicode_sprint(logtext+strlen(logtext), c->name);
44                                 dolog();
45                                 }
46                         chain_addlast(uninitializedclasses, c);
47                         return;
48                         }
49                 if (c < cl) {
50                         if (runverbose) {
51                                 sprintf(logtext, "compiler_addinitclass: ");
52                                 unicode_sprint(logtext+strlen(logtext), c->name);
53                                 dolog();
54                                 }
55                         chain_addbefore(uninitializedclasses, c);
56                         return;
57                         }
58                 cl = chain_next(uninitializedclasses);
59                 }
60 }
61                                 
62
63
64 /***************** Hilfsfunktionen zum Decodieren des Bytecodes ***************
65
66         lesen ein Datum des gew"unschten Typs aus dem Bytecode an der
67         angegebenen Stelle
68
69 ******************************************************************************/
70
71 #define code_get_u1(pos)    jcode[pos]
72 #define code_get_s1(pos)    ((s1)jcode[pos])
73 #define code_get_u2(pos)    ((((u2)jcode[pos])<<8)+jcode[pos+1])
74 #define code_get_s2(pos)    ((s2)((((u2)jcode[pos])<<8)+jcode[pos+1]))
75 #define code_get_u4(pos)    ((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
76                              (((u4)jcode[pos+2])<<8)+jcode[pos+3])
77 #define code_get_s4(pos)    ((s4)((((u4)jcode[pos])<<24)+(((u4)jcode[pos+1])<<16)+\
78                              (((u4)jcode[pos+2])<<8)+jcode[pos+3]))
79
80
81 /******************** Funktion: descriptor2types *****************************
82
83         Decodiert einen Methoddescriptor.
84         Beim Aufruf dieser Funktion MUSS (!!!) der Descriptor ein
85         gueltiges Format haben (wird eh vorher vom loader ueberprueft).
86         
87         Die Funktion erzeugt ein Array von integers (u2), in das die 
88         Parametertypen eingetragen werden, und liefert einen Zeiger auf
89         das Array in einem Referenzparameter ('paramtypes') zur"uck.
90         Die L"ange dieses Arrays und der Methodenr"uckgabewert werden ebenfalls
91         in Referenzparametern zur"uckgeliefert.
92         
93         Der Parameter 'isstatic' gibt an (wenn true), dass kein zus"atzlicher
94         erster Eintrag f"ur den this-Zeiger in das Array eingetragen
95         werden soll (sonst wird er n"amlich automatisch erzeugt, mit dem
96         Typ TYPE_ADR).
97         
98 ******************************************************************************/         
99
100 static void descriptor2types (methodinfo *m)
101 {
102         u1 *types, *tptr;
103         int pcount, c;
104         u2 *cptr;
105
106         pcount = 0;
107         types = DMNEW (u1, m->descriptor->length);
108         
109         tptr = types;
110         if (!(m->flags & ACC_STATIC)) {
111                 *tptr++ = TYPE_ADR;
112                 pcount++;
113                 }
114
115         cptr = m->descriptor->text;
116         cptr++;
117         while ((c = *cptr++) != ')') {
118                 pcount++;
119                 switch (c) {
120                         case 'B':
121                         case 'C':
122                         case 'I':
123                         case 'S':
124                         case 'Z':  *tptr++ = TYPE_INT;
125                                    break;
126                         case 'J':  *tptr++ = TYPE_LNG;
127                                    break;
128                         case 'F':  *tptr++ = TYPE_FLT;
129                                    break;
130                         case 'D':  *tptr++ = TYPE_DBL;
131                                    break;
132                         case 'L':  *tptr++ = TYPE_ADR;
133                                    while (*cptr++ != ';');
134                                    break;
135                         case '[':  *tptr++ = TYPE_ADR;
136                                    while (c == '[')
137                                        c = *cptr++;
138                                    if (c == 'L')
139                                        while (*cptr++ != ';') /* skip */;
140                                    break;
141                         default:   panic ("Ill formed methodtype-descriptor");
142                         }
143                 }
144                 
145         switch (*cptr) {
146                 case 'B':
147                 case 'C':
148                 case 'I':
149                 case 'S':
150                 case 'Z':  m->returntype = TYPE_INT;
151                            break;
152                 case 'J':  m->returntype = TYPE_LNG;
153                            break;
154                 case 'F':  m->returntype = TYPE_FLT;
155                            break;
156                 case 'D':  m->returntype = TYPE_DBL;
157                            break;
158                 case '[':
159                 case 'L':  m->returntype = TYPE_ADR;
160                            break;
161                 case 'V':  m->returntype = TYPE_VOID;
162                            break;
163         
164                 default:   panic ("Ill formed methodtype-descriptor");
165                 }
166
167         m->paramcount = pcount;
168         m->paramtypes = types;
169 }
170