1 /* vm/descriptor.h - checking and parsing of field / method descriptors
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
8 This file is part of CACAO.
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.
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.
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
25 Contact: cacao@complang.tuwien.ac.at
27 Authors: Edwin Steiner
31 $Id: descriptor.h 2181 2005-04-01 16:53:33Z edwin $
39 /* forward typedefs ***********************************************************/
41 typedef struct descriptor_pool descriptor_pool;
43 #include "vm/global.h"
44 #include "vm/references.h"
45 #include "vm/tables.h"
47 /* data structures ************************************************************/
49 /*----------------------------------------------------------------------------*/
50 /* Descriptor Pools */
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. */
58 /* You use a descriptor_pool as follows: */
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 */
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 */
73 /*----------------------------------------------------------------------------*/
75 struct descriptor_pool {
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 */
91 /* data structures for parsed field/method descriptors ************************/
94 constant_classref *classref; /* class reference for TYPE_ADR types */
95 u1 type; /* TYPE_??? constant */
96 u1 arraydim; /* array dimension (0 if no array) */
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! */
107 /* function prototypes ********************************************************/
109 /* descriptor_debug_print_typedesc *********************************************
111 Print the given typedesc to the given stream
114 file.............stream to print to
115 d................the parsed descriptor
117 *******************************************************************************/
119 void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
121 /* descriptor_debug_print_methoddesc *******************************************
123 Print the given methoddesc to the given stream
126 file.............stream to print to
127 d................the parsed descriptor
129 *******************************************************************************/
131 void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
133 /* descriptor_pool_new *********************************************************
135 Allocate a new descriptor_pool
138 referer..........class for which to create the pool
141 a pointer to the new descriptor_pool
143 *******************************************************************************/
145 descriptor_pool * descriptor_pool_new(classinfo *referer);
147 /* descriptor_pool_add_class ***************************************************
149 Add the given class reference to the pool
152 pool.............the descriptor_pool
153 name.............the class reference to add
156 true.............reference has been added
157 false............an exception has been thrown
159 *******************************************************************************/
161 bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
163 /* descriptor_pool_add *********************************************************
165 Check the given descriptor and add it to the pool
168 pool.............the descriptor_pool
169 desc.............the descriptor to add. Maybe a field or method desc.
172 true.............descriptor has been added
173 false............an exception has been thrown
175 *******************************************************************************/
177 bool descriptor_pool_add(descriptor_pool *pool,utf *desc);
179 /* descriptor_pool_create_classrefs ********************************************
181 Create a table containing all the classrefs which were added to the pool
184 pool.............the descriptor_pool
187 *count...........if count is non-NULL, this is set to the number
188 of classrefs in the table
191 a pointer to the constant_classref table
193 *******************************************************************************/
195 constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
198 /* descriptor_pool_lookup_classref *********************************************
200 Return the constant_classref for the given class name
203 pool.............the descriptor_pool
204 classname........name of the class to look up
207 a pointer to the constant_classref, or
208 NULL if an exception has been thrown
210 *******************************************************************************/
212 constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
214 /* descriptor_pool_alloc_parsed_descriptors ************************************
216 Allocate space for the parsed descriptors
219 pool.............the descriptor_pool
222 This function must be called after all descriptors have been added
223 with descriptor_pool_add.
225 *******************************************************************************/
227 void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
229 /* descriptor_pool_parse_field_descriptor **************************************
231 Parse the given field descriptor
234 pool.............the descriptor_pool
235 desc.............the field descriptor
238 a pointer to the parsed field descriptor, or
239 NULL if an exception has been thrown
242 descriptor_pool_alloc_parsed_descriptors must be called (once) before this
245 *******************************************************************************/
247 typedesc * descriptor_pool_parse_field_descriptor(descriptor_pool *pool,utf *desc);
249 /* descriptor_pool_parse_method_descriptor *************************************
251 Parse the given method descriptor
254 pool.............the descriptor_pool
255 desc.............the method descriptor
258 a pointer to the parsed method descriptor, or
259 NULL if an exception has been thrown
262 descriptor_pool_alloc_parsed_descriptors must be called (once) before this
265 *******************************************************************************/
267 methoddesc * descriptor_pool_parse_method_descriptor(descriptor_pool *pool,utf *desc);
269 /* descriptor_pool_get_parsed_descriptors **************************************
271 Return a pointer to the block of parsed descriptors
274 pool.............the descriptor_pool
277 *size............if size is non-NULL, this is set to the size of the
278 parsed descriptor block (in u1)
281 a pointer to the block of parsed descriptors,
282 NULL if there are no descriptors in the pool
285 descriptor_pool_alloc_parsed_descriptors must be called (once) before this
288 *******************************************************************************/
290 void * descriptor_pool_get_parsed_descriptors(descriptor_pool *pool,
293 /* descriptor_pool_get_sizes ***************************************************
295 Get the sizes of the class reference table and the parsed descriptors
298 pool.............the descriptor_pool
301 *classrefsize....set to size of the class reference table
302 *descsize........set to size of the parsed descriptors
305 This function may only be called after both
306 descriptor_pool_create_classrefs, and
307 descriptor_pool_alloc_parsed_descriptors
310 *******************************************************************************/
312 void descriptor_pool_get_sizes(descriptor_pool *pool,
313 u4 *classrefsize,u4 *descsize);
315 /* descriptor_debug_print_typedesc *********************************************
317 Print the given typedesc to the given stream
320 file.............stream to print to
321 d................the parsed descriptor
323 *******************************************************************************/
325 void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
327 /* descriptor_debug_print_methoddesc *******************************************
329 Print the given methoddesc to the given stream
332 file.............stream to print to
333 d................the parsed descriptor
335 *******************************************************************************/
337 void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
339 /* descriptor_pool_debug_dump **************************************************
341 Print the state of the descriptor_pool to the given stream
344 pool.............the descriptor_pool
345 file.............stream to print to
347 *******************************************************************************/
349 void descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file);
351 /* macros for descriptor parsing **********************************************/
353 /* XXX These should be moved to descriptor.c */
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.
360 * CAUTION: This macro does not check for an unexpected end of the
361 * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
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)
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.
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!
378 * utf_ptr....points to first char after the descriptor
379 * errorflag..set to true if the string ended unexpectedly
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; \
386 if (*(utf_ptr)++=='L') { \
387 while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';') \
389 if ((utf_ptr)[-1] != ';') \
390 (errorflag) = true; }} while(0)
393 #endif /* _DESCRIPTOR_H */
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 * ---------------------------------------------------------------------
403 * indent-tabs-mode: t
407 * vim:noexpandtab:sw=4:ts=4: