extended type system to use symbolic references
[cacao.git] / src / vm / descriptor.h
1 /* vm/descriptor.h - checking and parsing of field / method descriptors
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Edwin Steiner
28
29    Changes:
30
31    $Id: descriptor.h 2181 2005-04-01 16:53:33Z edwin $
32
33 */
34
35
36 #ifndef _DESCRIPTOR_H
37 #define _DESCRIPTOR_H
38
39 /* forward typedefs ***********************************************************/
40
41 typedef struct descriptor_pool descriptor_pool;
42
43 #include "vm/global.h"
44 #include "vm/references.h"
45 #include "vm/tables.h"
46
47 /* data structures ************************************************************/ 
48
49 /*----------------------------------------------------------------------------*/
50 /* Descriptor Pools                                                           */
51 /*                                                                            */
52 /* A descriptor_pool is a temporary data structure used during loading of     */
53 /* a class. The descriptor_pool is used to allocate the table of              */
54 /* constant_classrefs the class uses, and for parsing the field and method    */
55 /* descriptors which occurr within the class. The inner workings of           */
56 /* descriptor_pool are not important for outside code.                        */
57 /*                                                                            */
58 /* You use a descriptor_pool as follows:                                      */
59 /*                                                                            */
60 /* 1. create one with descriptor_pool_new                                     */
61 /* 2. add all explicit class references with descriptor_pool_add_class        */
62 /* 3. add all field/method descriptors with descriptor_pool_add               */
63 /* 4. call descriptor_pool_create_classrefs                                   */
64 /*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
65 /* 5. call descriptor_pool_alloc_parsed_descriptors                           */
66 /* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
67 /*    for each method descriptor call descriptor_pool_parse_method_descriptor */
68 /* 7. call descriptor_pool_get_parsed_descriptors                             */
69 /*                                                                            */
70 /* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
71 /*            memory which can be thrown away when the steps above have been  */
72 /*            done.                                                           */
73 /*----------------------------------------------------------------------------*/
74
75 struct descriptor_pool {
76         classinfo         *referer;
77         u4                 fieldcount;
78         u4                 methodcount;
79         u4                 paramcount;
80         u4                 descriptorsize;
81         u1                *descriptors;
82         u1                *descriptors_next;
83         hashtable          descriptorhash;
84         constant_classref *classrefs;
85         hashtable          classrefhash;
86         u1                *descriptor_kind;       /* useful for debugging */
87         u1                *descriptor_kind_next;  /* useful for debugging */
88 };
89
90
91 /* data structures for parsed field/method descriptors ************************/
92
93 struct typedesc {
94         constant_classref *classref;   /* class reference for TYPE_ADR types      */
95         u1                 type;       /* TYPE_??? constant                       */
96         u1                 arraydim;   /* array dimension (0 if no array)         */
97 };
98
99 struct methoddesc {
100         s2                 paramcount; /* number of parameters                    */
101         s2                 paramslots; /* like above but LONG,DOUBLE count twice  */
102         typedesc           returntype; /* parsed descriptor of the return type    */
103         typedesc           paramtypes[1]; /* parameter types, variable length!    */
104 };
105
106
107 /* function prototypes ********************************************************/
108
109 /* descriptor_debug_print_typedesc *********************************************
110  
111    Print the given typedesc to the given stream
112
113    IN:
114            file.............stream to print to
115            d................the parsed descriptor
116
117 *******************************************************************************/
118
119 void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
120
121 /* descriptor_debug_print_methoddesc *******************************************
122  
123    Print the given methoddesc to the given stream
124
125    IN:
126            file.............stream to print to
127            d................the parsed descriptor
128
129 *******************************************************************************/
130
131 void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
132
133 /* descriptor_pool_new *********************************************************
134  
135    Allocate a new descriptor_pool
136
137    IN:
138        referer..........class for which to create the pool
139
140    RETURN VALUE:
141        a pointer to the new descriptor_pool
142
143 *******************************************************************************/
144
145 descriptor_pool * descriptor_pool_new(classinfo *referer);
146
147 /* descriptor_pool_add_class ***************************************************
148  
149    Add the given class reference to the pool
150
151    IN:
152        pool.............the descriptor_pool
153            name.............the class reference to add
154
155    RETURN VALUE:
156        true.............reference has been added
157            false............an exception has been thrown
158
159 *******************************************************************************/
160
161 bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
162
163 /* descriptor_pool_add *********************************************************
164  
165    Check the given descriptor and add it to the pool
166
167    IN:
168        pool.............the descriptor_pool
169            desc.............the descriptor to add. Maybe a field or method desc.
170
171    RETURN VALUE:
172        true.............descriptor has been added
173            false............an exception has been thrown
174
175 *******************************************************************************/
176
177 bool descriptor_pool_add(descriptor_pool *pool,utf *desc);
178
179 /* descriptor_pool_create_classrefs ********************************************
180  
181    Create a table containing all the classrefs which were added to the pool
182
183    IN:
184        pool.............the descriptor_pool
185
186    OUT:
187        *count...........if count is non-NULL, this is set to the number
188                             of classrefs in the table
189
190    RETURN VALUE:
191        a pointer to the constant_classref table
192
193 *******************************************************************************/
194
195 constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
196                                                                                                          s4 *count);
197
198 /* descriptor_pool_lookup_classref *********************************************
199  
200    Return the constant_classref for the given class name
201
202    IN:
203        pool.............the descriptor_pool
204            classname........name of the class to look up
205
206    RETURN VALUE:
207        a pointer to the constant_classref, or
208            NULL if an exception has been thrown
209
210 *******************************************************************************/
211
212 constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
213
214 /* descriptor_pool_alloc_parsed_descriptors ************************************
215  
216    Allocate space for the parsed descriptors
217
218    IN:
219        pool.............the descriptor_pool
220
221    NOTE:
222        This function must be called after all descriptors have been added
223            with descriptor_pool_add.
224
225 *******************************************************************************/
226
227 void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
228
229 /* descriptor_pool_parse_field_descriptor **************************************
230  
231    Parse the given field descriptor
232
233    IN:
234        pool.............the descriptor_pool
235            desc.............the field descriptor
236
237    RETURN VALUE:
238        a pointer to the parsed field descriptor, or
239            NULL if an exception has been thrown
240
241    NOTE:
242        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
243            function is used.
244
245 *******************************************************************************/
246
247 typedesc * descriptor_pool_parse_field_descriptor(descriptor_pool *pool,utf *desc);
248
249 /* descriptor_pool_parse_method_descriptor *************************************
250  
251    Parse the given method descriptor
252
253    IN:
254        pool.............the descriptor_pool
255            desc.............the method descriptor
256
257    RETURN VALUE:
258        a pointer to the parsed method descriptor, or
259            NULL if an exception has been thrown
260
261    NOTE:
262        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
263            function is used.
264
265 *******************************************************************************/
266
267 methoddesc * descriptor_pool_parse_method_descriptor(descriptor_pool *pool,utf *desc);
268
269 /* descriptor_pool_get_parsed_descriptors **************************************
270  
271    Return a pointer to the block of parsed descriptors
272
273    IN:
274        pool.............the descriptor_pool
275
276    OUT:
277            *size............if size is non-NULL, this is set to the size of the
278                             parsed descriptor block (in u1)
279
280    RETURN VALUE:
281        a pointer to the block of parsed descriptors,
282            NULL if there are no descriptors in the pool
283
284    NOTE:
285        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
286            function is used.
287
288 *******************************************************************************/
289
290 void * descriptor_pool_get_parsed_descriptors(descriptor_pool *pool,
291                                                                                           s4 *size);
292
293 /* descriptor_pool_get_sizes ***************************************************
294  
295    Get the sizes of the class reference table and the parsed descriptors
296
297    IN:
298        pool.............the descriptor_pool
299
300    OUT:
301        *classrefsize....set to size of the class reference table
302            *descsize........set to size of the parsed descriptors
303
304    NOTE:
305        This function may only be called after both
306                descriptor_pool_create_classrefs, and
307                    descriptor_pool_alloc_parsed_descriptors
308            have been called.
309
310 *******************************************************************************/
311
312 void descriptor_pool_get_sizes(descriptor_pool *pool,
313                                                            u4 *classrefsize,u4 *descsize);
314
315 /* descriptor_debug_print_typedesc *********************************************
316  
317    Print the given typedesc to the given stream
318
319    IN:
320            file.............stream to print to
321            d................the parsed descriptor
322
323 *******************************************************************************/
324
325 void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
326
327 /* descriptor_debug_print_methoddesc *******************************************
328  
329    Print the given methoddesc to the given stream
330
331    IN:
332            file.............stream to print to
333            d................the parsed descriptor
334
335 *******************************************************************************/
336
337 void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
338
339 /* descriptor_pool_debug_dump **************************************************
340  
341    Print the state of the descriptor_pool to the given stream
342
343    IN:
344        pool.............the descriptor_pool
345            file.............stream to print to
346
347 *******************************************************************************/
348
349 void descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file);
350
351 /* macros for descriptor parsing **********************************************/
352
353 /* XXX These should be moved to descriptor.c */
354
355 /* SKIP_FIELDDESCRIPTOR:
356  * utf_ptr must point to the first character of a field descriptor.
357  * After the macro call utf_ptr points to the first character after
358  * the field descriptor.
359  *
360  * CAUTION: This macro does not check for an unexpected end of the
361  * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
362  */
363 #define SKIP_FIELDDESCRIPTOR(utf_ptr)                                                   \
364         do { while (*(utf_ptr)=='[') (utf_ptr)++;                                       \
365                 if (*(utf_ptr)++=='L')                                                                  \
366                         while(*(utf_ptr)++ != ';') /* skip */; } while(0)
367
368 /* SKIP_FIELDDESCRIPTOR_SAFE:
369  * utf_ptr must point to the first character of a field descriptor.
370  * After the macro call utf_ptr points to the first character after
371  * the field descriptor.
372  *
373  * Input:
374  *     utf_ptr....points to first char of descriptor
375  *     end_ptr....points to first char after the end of the string
376  *     errorflag..must be initialized (to false) by the caller!
377  * Output:
378  *     utf_ptr....points to first char after the descriptor
379  *     errorflag..set to true if the string ended unexpectedly
380  */
381 #define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                    \
382         do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;     \
383                 if ((utf_ptr) == (end_ptr))                                                                             \
384                         (errorflag) = true;                                                                                     \
385                 else                                                                                                                    \
386                         if (*(utf_ptr)++=='L') {                                                                        \
387                                 while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';')    \
388                                         /* skip */;                                                                                     \
389                                 if ((utf_ptr)[-1] != ';')                                                               \
390                                         (errorflag) = true; }} while(0)
391
392
393 #endif /* _DESCRIPTOR_H */
394
395
396 /*
397  * These are local overrides for various environment variables in Emacs.
398  * Please do not remove this and leave it at the end of the file, where
399  * Emacs will automagically detect them.
400  * ---------------------------------------------------------------------
401  * Local variables:
402  * mode: c
403  * indent-tabs-mode: t
404  * c-basic-offset: 4
405  * tab-width: 4
406  * End:
407  * vim:noexpandtab:sw=4:ts=4:
408  */