Initial revision
[cacao.git] / comp / tools.c
1 /***************************** comp/tools.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: Reinhard Grafl      EMAIL: cacao@complang.tuwien.ac.at
11
12         Last Change: 1996/11/14
13
14 *******************************************************************************/
15
16
17 /***************** Funktion: compiler_addinitclass ****************************
18
19         zum Eintragen einer Klasse in die Liste der noch zu initialisierenden 
20         Klassen
21         
22 ******************************************************************************/
23                                 
24 void compiler_addinitclass (classinfo *c)
25 {
26         classinfo *cl;
27
28         if (c->initialized) return;
29         
30         cl = chain_first(uninitializedclasses);
31         if (cl == c)
32                 return;
33         
34         if (cl == class)
35                 cl = chain_next(uninitializedclasses);
36         for (;;) {
37                 if (cl == c)
38                         return;
39                 if (cl == NULL) {
40                         if (runverbose) {
41                                 sprintf(logtext, "compiler_addinitclass: ");
42                                 unicode_sprint(logtext+strlen(logtext), c->name);
43                                 dolog();
44                                 }
45                         chain_addlast(uninitializedclasses, c);
46                         return;
47                         }
48                 if (c < cl) {
49                         if (runverbose) {
50                                 sprintf(logtext, "compiler_addinitclass: ");
51                                 unicode_sprint(logtext+strlen(logtext), c->name);
52                                 dolog();
53                                 }
54                         chain_addbefore(uninitializedclasses, c);
55                         return;
56                         }
57                 cl = chain_next(uninitializedclasses);
58                 }
59 }
60                                 
61
62
63 /***************** Hilfsfunktionen zum Decodieren des Bytecodes ***************
64
65         lesen ein Datum des gew"unschten Typs aus dem Bytecode an der
66         angegebenen Stelle
67
68 ******************************************************************************/
69
70 static u1 code_get_u1 (u4 pos)
71 {
72         return jcode[pos];
73 }
74
75 static s1 code_get_s1 (u4 pos)
76 {
77         return code_get_u1 (pos);
78 }
79
80 static u2 code_get_u2 (u4 pos)
81 {
82         return ( ((u2) jcode[pos]) << 8 ) + jcode[pos+1];
83 }
84
85 static s2 code_get_s2 (u4 pos)
86 {
87         return code_get_u2 (pos);
88 }
89
90 static u4 code_get_u4 (u4 pos)
91 {
92         return    ( ((u4) jcode[pos])   << 24 ) 
93                 + ( ((u4) jcode[pos+1]) << 16 )
94                 + ( ((u4) jcode[pos+2]) << 8 )
95                 + ( jcode[pos+3] );
96 }
97
98 static s4 code_get_s4 (u4 pos)
99 {
100         return code_get_u4 (pos);
101 }
102
103
104
105 /******************** Funktion: descriptor2types *****************************
106
107         Decodiert einen Methoddescriptor.
108         Beim Aufruf dieser Funktion MUSS (!!!) der Descriptor ein
109         gueltiges Format haben (wird eh vorher vom loader ueberprueft).
110         
111         Die Funktion erzeugt ein Array von integers (u2), in das die 
112         Parametertypen eingetragen werden, und liefert einen Zeiger auf
113         das Array in einem Referenzparameter ('paramtypes') zur"uck.
114         Die L"ange dieses Arrays und der Methodenr"uckgabewert werden ebenfalls
115         in Referenzparametern zur"uckgeliefert.
116         
117         Der Parameter 'isstatic' gibt an (wenn true), dass kein zus"atzlicher
118         erster Eintrag f"ur den this-Zeiger in das Array eingetragen
119         werden soll (sonst wird er n"amlich automatisch erzeugt, mit dem
120         Typ TYPE_ADDRESS).
121         
122 ******************************************************************************/         
123
124 static void descriptor2types (unicode *desc, bool isstatic,
125                  s4 *paramnum, u1 **paramtypes, s4 *returntype)
126 {
127         u2 *text = desc->text;
128         s4 pos;
129         u1 *types;
130         s4 tnum;
131         
132         tnum = (isstatic) ? 0 : 1; 
133         pos=1;
134         while (text[pos] != ')') {
135            repeatcounting:      
136                 
137                 switch (text[pos]) {
138                 case '[':  pos++;
139                            goto repeatcounting;
140                 case 'L':  while (text[pos]!=';') pos++;
141                        break;
142             }
143                 pos++;
144                 tnum++;
145                 }
146         
147         types = DMNEW (u1, tnum);
148         
149         if (isstatic) tnum=0;
150         else {
151                 types[0] = TYPE_ADDRESS;
152                 tnum = 1;
153                 }
154         pos=1;
155         while (text[pos] != ')') {
156                 switch (text[pos]) {
157                 case 'B':
158                 case 'C':
159                 case 'I':
160                 case 'S':
161                 case 'Z':  types[tnum++] = TYPE_INT;
162                            break;
163                 case 'J':  types[tnum++] = TYPE_LONG;
164                            break;
165                 case 'F':  types[tnum++] = TYPE_FLOAT;
166                            break;
167                 case 'D':  types[tnum++] = TYPE_DOUBLE;
168                            break;
169                 case 'L':  types[tnum++] = TYPE_ADDRESS;
170                            while (text[pos] != ';') pos++;
171                            break;
172                 case '[':  types[tnum++] = TYPE_ADDRESS;
173                            while (text[pos] == '[') pos++;
174                            if (text[pos] == 'L') while (text[pos] != ';') pos++;
175                            break;
176                 default:   panic ("Ill formed methodtype-descriptor");
177                 }
178                 pos++;
179                 }
180                 
181         pos++;  /* ueberlesen von ')' */
182
183         switch (text[pos]) {
184                 case 'B':
185                 case 'C':
186                 case 'I':
187                 case 'S':
188                 case 'Z':  *returntype = TYPE_INT;
189                            break;
190                 case 'J':  *returntype = TYPE_LONG;
191                            break;
192                 case 'F':  *returntype = TYPE_FLOAT;
193                            break;
194                 case 'D':  *returntype = TYPE_DOUBLE;
195                            break;
196                 case '[':
197                 case 'L':  *returntype = TYPE_ADDRESS;
198                            break;
199                 case 'V':  *returntype = TYPE_VOID;
200                            break;
201         
202                 default:   panic ("Ill formed methodtype-descriptor");
203                 }
204
205         *paramnum = tnum;
206         *paramtypes = types;
207 }
208