* Moved md_param_alloc prototype to decriptor.h
[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 2796 2005-06-23 09:42:34Z twisti $
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 typedef struct paramdesc paramdesc;
43
44 #include "vm/class.h"
45 #include "vm/global.h"
46 #include "vm/method.h"
47 #include "vm/references.h"
48 #include "vm/tables.h"
49
50
51 /* data structures ************************************************************/ 
52
53 /*----------------------------------------------------------------------------*/
54 /* Descriptor Pools                                                           */
55 /*                                                                            */
56 /* A descriptor_pool is a temporary data structure used during loading of     */
57 /* a class. The descriptor_pool is used to allocate the table of              */
58 /* constant_classrefs the class uses, and for parsing the field and method    */
59 /* descriptors which occurr within the class. The inner workings of           */
60 /* descriptor_pool are not important for outside code.                        */
61 /*                                                                            */
62 /* You use a descriptor_pool as follows:                                      */
63 /*                                                                            */
64 /* 1. create one with descriptor_pool_new                                     */
65 /* 2. add all explicit class references with descriptor_pool_add_class        */
66 /* 3. add all field/method descriptors with descriptor_pool_add               */
67 /* 4. call descriptor_pool_create_classrefs                                   */
68 /*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
69 /* 5. call descriptor_pool_alloc_parsed_descriptors                           */
70 /* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
71 /*    for each method descriptor call descriptor_pool_parse_method_descriptor */
72 /* 7. call descriptor_pool_get_parsed_descriptors                             */
73 /*                                                                            */
74 /* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
75 /*            memory which can be thrown away when the steps above have been  */
76 /*            done.                                                           */
77 /*----------------------------------------------------------------------------*/
78
79 struct descriptor_pool {
80         classinfo         *referer;
81         u4                 fieldcount;
82         u4                 methodcount;
83         u4                 paramcount;
84         u4                 descriptorsize;
85         u1                *descriptors;
86         u1                *descriptors_next;
87         hashtable          descriptorhash;
88         constant_classref *classrefs;
89         hashtable          classrefhash;
90         u1                *descriptor_kind;       /* useful for debugging */
91         u1                *descriptor_kind_next;  /* useful for debugging */
92 };
93
94
95 /* data structures for parsed field/method descriptors ************************/
96
97 struct typedesc {
98         constant_classref *classref;   /* class reference for TYPE_ADR types      */
99         u1                 type;       /* TYPE_??? constant [1]                   */
100         u1                 decltype;   /* (PRIMITIVE)TYPE_??? constant [2]        */
101         u1                 arraydim;   /* array dimension (0 if no array)         */
102 };
103
104 /* [1]...the type field contains the basic type used within the VM. So ints,  */
105 /*       shorts, chars, bytes, booleans all have TYPE_INT.                    */
106 /* [2]...the decltype field contains the declared type.                       */
107 /*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
108 /*       For non-primitive types decltype is TYPE_ADR.                        */
109
110 struct paramdesc {
111         bool inmemory;              /* argument in register or on stack           */
112         s4   regoff;                /* register index or stack offset             */
113 };
114
115 struct methoddesc {
116         s2         paramcount;      /* number of parameters                       */
117         s2         paramslots;      /* like above but LONG,DOUBLE count twice     */
118         s4         argintreguse;    /* number of used integer argument registers  */
119         s4         argfltreguse;    /* number of used float argument registers    */
120         s4         memuse;          /* number of stack slots used                 */
121         paramdesc *params;          /* allocated parameter descriptions [3]       */
122         typedesc   returntype;      /* parsed descriptor of the return type       */
123         typedesc   paramtypes[1];   /* parameter types, variable length!          */
124 };
125
126 /* [3]...If params is NULL, the parameter descriptions have not yet been      */
127 /*       allocated. In this case ___the possible 'this' pointer of the method */
128 /*       is NOT counted in paramcount/paramslots and it is NOT included in    */
129 /*       the paramtypes array___.                                             */
130 /*       If params != NULL, the parameter descriptions have been              */
131 /*       allocated, and the 'this' pointer of the method, if any, IS included.*/
132 /*       In case the method has no parameters at all, the special value       */
133 /*       METHODDESC_NO_PARAMS is used (see below).                            */
134
135 /* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field    */
136 /* indicating that the method is a static method without any parameters.      */
137 /* This special value must be != NULL and it may only be set if               */
138 /* md->paramcount == 0.                                                       */
139
140 #define METHODDESC_NOPARAMS  ((paramdesc*)1)
141
142 /* function prototypes ********************************************************/
143
144 /* descriptor_debug_print_typedesc *********************************************
145  
146    Print the given typedesc to the given stream
147
148    IN:
149            file.............stream to print to
150            d................the parsed descriptor
151
152 *******************************************************************************/
153
154 void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
155
156
157 /* descriptor_debug_print_methoddesc *******************************************
158  
159    Print the given methoddesc to the given stream
160
161    IN:
162            file.............stream to print to
163            d................the parsed descriptor
164
165 *******************************************************************************/
166
167 void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
168
169
170 /* descriptor_debug_print_paramdesc ********************************************
171  
172    Print the given paramdesc to the given stream
173
174    IN:
175            file.............stream to print to
176            d................the parameter descriptor
177
178 *******************************************************************************/
179
180 void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
181
182 /* descriptor_pool_new *********************************************************
183  
184    Allocate a new descriptor_pool
185
186    IN:
187        referer..........class for which to create the pool
188
189    RETURN VALUE:
190        a pointer to the new descriptor_pool
191
192 *******************************************************************************/
193
194 descriptor_pool * descriptor_pool_new(classinfo *referer);
195
196
197 /* descriptor_pool_add_class ***************************************************
198  
199    Add the given class reference to the pool
200
201    IN:
202        pool.............the descriptor_pool
203            name.............the class reference to add
204
205    RETURN VALUE:
206        true.............reference has been added
207            false............an exception has been thrown
208
209 *******************************************************************************/
210
211 bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
212
213
214 /* descriptor_pool_add *********************************************************
215  
216    Check the given descriptor and add it to the pool
217
218    IN:
219        pool.............the descriptor_pool
220            desc.............the descriptor to add. Maybe a field or method desc.
221
222    OUT:
223        *paramslots......if non-NULL, set to the number of parameters.
224                             LONG and DOUBLE are counted twice
225
226    RETURN VALUE:
227        true.............descriptor has been added
228            false............an exception has been thrown
229
230 *******************************************************************************/
231
232 bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
233
234
235 /* descriptor_pool_create_classrefs ********************************************
236  
237    Create a table containing all the classrefs which were added to the pool
238
239    IN:
240        pool.............the descriptor_pool
241
242    OUT:
243        *count...........if count is non-NULL, this is set to the number
244                             of classrefs in the table
245
246    RETURN VALUE:
247        a pointer to the constant_classref table
248
249 *******************************************************************************/
250
251 constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
252                                                                                                          s4 *count);
253
254
255 /* descriptor_pool_lookup_classref *********************************************
256  
257    Return the constant_classref for the given class name
258
259    IN:
260        pool.............the descriptor_pool
261            classname........name of the class to look up
262
263    RETURN VALUE:
264        a pointer to the constant_classref, or
265            NULL if an exception has been thrown
266
267 *******************************************************************************/
268
269 constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
270
271
272 /* descriptor_pool_alloc_parsed_descriptors ************************************
273  
274    Allocate space for the parsed descriptors
275
276    IN:
277        pool.............the descriptor_pool
278
279    NOTE:
280        This function must be called after all descriptors have been added
281            with descriptor_pool_add.
282
283 *******************************************************************************/
284
285 void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
286
287
288 /* descriptor_pool_parse_field_descriptor **************************************
289  
290    Parse the given field descriptor
291
292    IN:
293        pool.............the descriptor_pool
294            desc.............the field descriptor
295
296    RETURN VALUE:
297        a pointer to the parsed field descriptor, or
298            NULL if an exception has been thrown
299
300    NOTE:
301        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
302            function is used.
303
304 *******************************************************************************/
305
306 typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
307
308
309 /* descriptor_pool_parse_method_descriptor *************************************
310  
311    Parse the given method descriptor
312
313    IN:
314        pool.............the descriptor_pool
315        desc.............the method descriptor
316        mflags...........the method flags
317            thisclass........classref to the class containing the method.
318                                                 This is ignored if mflags contains ACC_STATIC.
319                                                 The classref is stored for inserting the 'this' argument.
320
321    RETURN VALUE:
322        a pointer to the parsed method descriptor, or
323            NULL if an exception has been thrown
324
325    NOTE:
326        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
327            function is used.
328
329 *******************************************************************************/
330
331 methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
332                                                                                                         constant_classref *thisclass);
333
334 /* descriptor_params_from_paramtypes *******************************************
335  
336    Create the paramdescs for a method descriptor. This function is called
337    when we know whether the method is static or not. This function may only
338    be called once for each methoddesc, and only if md->params == NULL.
339
340    IN:
341        md...............the parsed method descriptor
342                             md->params MUST be NULL.
343            mflags...........the ACC_* access flags of the method. Only the
344                             ACC_STATIC bit is checked.
345                                                 The value ACC_UNDEF is NOT allowed.
346
347    RETURN VALUE:
348        true.............the paramdescs were created successfully
349            false............an exception has been thrown
350
351    POSTCONDITION:
352        md->parms != NULL
353
354 *******************************************************************************/
355
356 bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
357
358 /* descriptor_pool_get_parsed_descriptors **************************************
359  
360    Return a pointer to the block of parsed descriptors
361
362    IN:
363        pool.............the descriptor_pool
364
365    OUT:
366            *size............if size is non-NULL, this is set to the size of the
367                             parsed descriptor block (in u1)
368
369    RETURN VALUE:
370        a pointer to the block of parsed descriptors,
371            NULL if there are no descriptors in the pool
372
373    NOTE:
374        descriptor_pool_alloc_parsed_descriptors must be called (once) before this
375            function is used.
376
377 *******************************************************************************/
378
379 void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
380
381
382 /* descriptor_pool_get_sizes ***************************************************
383  
384    Get the sizes of the class reference table and the parsed descriptors
385
386    IN:
387        pool.............the descriptor_pool
388
389    OUT:
390        *classrefsize....set to size of the class reference table
391            *descsize........set to size of the parsed descriptors
392
393    NOTE:
394        This function may only be called after both
395                descriptor_pool_create_classrefs, and
396                    descriptor_pool_alloc_parsed_descriptors
397            have been called.
398
399 *******************************************************************************/
400
401 void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
402                                                            u4 *descsize);
403
404
405 /* descriptor_debug_print_typedesc *********************************************
406  
407    Print the given typedesc to the given stream
408
409    IN:
410            file.............stream to print to
411            d................the parsed descriptor
412
413 *******************************************************************************/
414
415 void descriptor_debug_print_typedesc(FILE *file, typedesc *d);
416
417
418 /* descriptor_debug_print_methoddesc *******************************************
419  
420    Print the given methoddesc to the given stream
421
422    IN:
423            file.............stream to print to
424            d................the parsed descriptor
425
426 *******************************************************************************/
427
428 void descriptor_debug_print_methoddesc(FILE *file, methoddesc *d);
429
430
431 /* descriptor_pool_debug_dump **************************************************
432  
433    Print the state of the descriptor_pool to the given stream
434
435    IN:
436        pool.............the descriptor_pool
437            file.............stream to print to
438
439 *******************************************************************************/
440
441 void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
442
443
444 /* machine dependent descriptor function */
445 void md_param_alloc(methoddesc *md);
446
447 #endif /* _DESCRIPTOR_H */
448
449
450 /*
451  * These are local overrides for various environment variables in Emacs.
452  * Please do not remove this and leave it at the end of the file, where
453  * Emacs will automagically detect them.
454  * ---------------------------------------------------------------------
455  * Local variables:
456  * mode: c
457  * indent-tabs-mode: t
458  * c-basic-offset: 4
459  * tab-width: 4
460  * End:
461  * vim:noexpandtab:sw=4:ts=4:
462  */