/* vm/descriptor.h - checking and parsing of field / method descriptors
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Authors: Edwin Steiner
Changes:
- $Id: descriptor.h 2570 2005-06-06 15:32:16Z twisti $
+ $Id: descriptor.h 6012 2006-11-16 19:45:15Z twisti $
*/
/* forward typedefs ***********************************************************/
typedef struct descriptor_pool descriptor_pool;
+typedef struct typedesc typedesc;
+typedef struct paramdesc paramdesc;
+typedef struct methoddesc methoddesc;
#include "vm/class.h"
#include "vm/global.h"
+#include "vm/hashtable.h"
#include "vm/method.h"
#include "vm/references.h"
-#include "vm/tables.h"
-/* data structures ************************************************************/
+/* data structures ************************************************************/
/*----------------------------------------------------------------------------*/
/* Descriptor Pools */
/* So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR. */
/* For non-primitive types decltype is TYPE_ADR. */
-typedef struct paramdesc paramdesc;
-
struct paramdesc {
+#if defined(__MIPS__)
+ u1 type; /* TYPE_??? of the register allocated */
+#endif
bool inmemory; /* argument in register or on stack */
s4 regoff; /* register index or stack offset */
};
s4 argintreguse; /* number of used integer argument registers */
s4 argfltreguse; /* number of used float argument registers */
s4 memuse; /* number of stack slots used */
- paramdesc *params;
+ paramdesc *params; /* allocated parameter descriptions [3] */
typedesc returntype; /* parsed descriptor of the return type */
typedesc paramtypes[1]; /* parameter types, variable length! */
};
+/* [3]...If params is NULL, the parameter descriptions have not yet been */
+/* allocated. In this case ___the possible 'this' pointer of the method */
+/* is NOT counted in paramcount/paramslots and it is NOT included in */
+/* the paramtypes array___. */
+/* If params != NULL, the parameter descriptions have been */
+/* allocated, and the 'this' pointer of the method, if any, IS included.*/
+/* In case the method has no parameters at all, the special value */
+/* METHODDESC_NO_PARAMS is used (see below). */
-/* function prototypes ********************************************************/
-
-/* descriptor_debug_print_typedesc *********************************************
-
- Print the given typedesc to the given stream
-
- IN:
- file.............stream to print to
- d................the parsed descriptor
-
-*******************************************************************************/
-
-void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
-
-
-/* descriptor_debug_print_methoddesc *******************************************
-
- Print the given methoddesc to the given stream
-
- IN:
- file.............stream to print to
- d................the parsed descriptor
-
-*******************************************************************************/
-
-void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
-
-
-/* descriptor_pool_new *********************************************************
-
- Allocate a new descriptor_pool
+/* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field */
+/* indicating that the method is a static method without any parameters. */
+/* This special value must be != NULL and it may only be set if */
+/* md->paramcount == 0. */
- IN:
- referer..........class for which to create the pool
+#define METHODDESC_NOPARAMS ((paramdesc*)1)
- RETURN VALUE:
- a pointer to the new descriptor_pool
-
-*******************************************************************************/
+/* function prototypes ********************************************************/
descriptor_pool * descriptor_pool_new(classinfo *referer);
-
-/* descriptor_pool_add_class ***************************************************
-
- Add the given class reference to the pool
-
- IN:
- pool.............the descriptor_pool
- name.............the class reference to add
-
- RETURN VALUE:
- true.............reference has been added
- false............an exception has been thrown
-
-*******************************************************************************/
-
bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
-
-
-/* descriptor_pool_add *********************************************************
-
- Check the given descriptor and add it to the pool
-
- IN:
- pool.............the descriptor_pool
- desc.............the descriptor to add. Maybe a field or method desc.
-
- OUT:
- *paramslots......if non-NULL, set to the number of parameters.
- LONG and DOUBLE are counted twice
-
- RETURN VALUE:
- true.............descriptor has been added
- false............an exception has been thrown
-
-*******************************************************************************/
-
bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
-
-/* descriptor_pool_create_classrefs ********************************************
-
- Create a table containing all the classrefs which were added to the pool
-
- IN:
- pool.............the descriptor_pool
-
- OUT:
- *count...........if count is non-NULL, this is set to the number
- of classrefs in the table
-
- RETURN VALUE:
- a pointer to the constant_classref table
-
-*******************************************************************************/
+u2 descriptor_to_basic_type(utf *desc);
+u2 descriptor_typesize(typedesc *td);
constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
s4 *count);
-
-
-/* descriptor_pool_lookup_classref *********************************************
-
- Return the constant_classref for the given class name
-
- IN:
- pool.............the descriptor_pool
- classname........name of the class to look up
-
- RETURN VALUE:
- a pointer to the constant_classref, or
- NULL if an exception has been thrown
-
-*******************************************************************************/
-
constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
-
-/* descriptor_pool_alloc_parsed_descriptors ************************************
-
- Allocate space for the parsed descriptors
-
- IN:
- pool.............the descriptor_pool
-
- NOTE:
- This function must be called after all descriptors have been added
- with descriptor_pool_add.
-
-*******************************************************************************/
-
void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
-
-/* descriptor_pool_parse_field_descriptor **************************************
-
- Parse the given field descriptor
-
- IN:
- pool.............the descriptor_pool
- desc.............the field descriptor
-
- RETURN VALUE:
- a pointer to the parsed field descriptor, or
- NULL if an exception has been thrown
-
- NOTE:
- descriptor_pool_alloc_parsed_descriptors must be called (once) before this
- function is used.
-
-*******************************************************************************/
-
typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
-
-
-/* descriptor_pool_parse_method_descriptor *************************************
-
- Parse the given method descriptor
-
- IN:
- pool.............the descriptor_pool
- desc.............the method descriptor
- mflags...........the method flags
-
- RETURN VALUE:
- a pointer to the parsed method descriptor, or
- NULL if an exception has been thrown
-
- NOTE:
- descriptor_pool_alloc_parsed_descriptors must be called (once) before this
- function is used.
-
-*******************************************************************************/
-
-methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags);
-
+methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
+ constant_classref *thisclass);
bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
-/* descriptor_pool_get_parsed_descriptors **************************************
-
- Return a pointer to the block of parsed descriptors
-
- IN:
- pool.............the descriptor_pool
-
- OUT:
- *size............if size is non-NULL, this is set to the size of the
- parsed descriptor block (in u1)
-
- RETURN VALUE:
- a pointer to the block of parsed descriptors,
- NULL if there are no descriptors in the pool
-
- NOTE:
- descriptor_pool_alloc_parsed_descriptors must be called (once) before this
- function is used.
-
-*******************************************************************************/
-
void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
-
-
-/* descriptor_pool_get_sizes ***************************************************
-
- Get the sizes of the class reference table and the parsed descriptors
-
- IN:
- pool.............the descriptor_pool
-
- OUT:
- *classrefsize....set to size of the class reference table
- *descsize........set to size of the parsed descriptors
-
- NOTE:
- This function may only be called after both
- descriptor_pool_create_classrefs, and
- descriptor_pool_alloc_parsed_descriptors
- have been called.
-
-*******************************************************************************/
-
void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
u4 *descsize);
-
-/* descriptor_debug_print_typedesc *********************************************
-
- Print the given typedesc to the given stream
-
- IN:
- file.............stream to print to
- d................the parsed descriptor
-
-*******************************************************************************/
-
-void descriptor_debug_print_typedesc(FILE *file, typedesc *d);
-
-
-/* descriptor_debug_print_methoddesc *******************************************
-
- Print the given methoddesc to the given stream
-
- IN:
- file.............stream to print to
- d................the parsed descriptor
-
-*******************************************************************************/
-
-void descriptor_debug_print_methoddesc(FILE *file, methoddesc *d);
-
-
-/* descriptor_pool_debug_dump **************************************************
-
- Print the state of the descriptor_pool to the given stream
-
- IN:
- pool.............the descriptor_pool
- file.............stream to print to
-
-*******************************************************************************/
-
+#ifndef NDEBUG
+void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
+void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
+void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
+#endif /* !defined(NDEBUG) */
-
-/* macros for descriptor parsing **********************************************/
-
-/* XXX These should be moved to descriptor.c */
-
-/* SKIP_FIELDDESCRIPTOR:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * CAUTION: This macro does not check for an unexpected end of the
- * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
- */
-#define SKIP_FIELDDESCRIPTOR(utf_ptr) \
- do { while (*(utf_ptr)=='[') (utf_ptr)++; \
- if (*(utf_ptr)++=='L') \
- while(*(utf_ptr)++ != ';') /* skip */; } while(0)
-
-/* SKIP_FIELDDESCRIPTOR_SAFE:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * Input:
- * utf_ptr....points to first char of descriptor
- * end_ptr....points to first char after the end of the string
- * errorflag..must be initialized (to false) by the caller!
- * Output:
- * utf_ptr....points to first char after the descriptor
- * errorflag..set to true if the string ended unexpectedly
- */
-#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag) \
- do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++; \
- if ((utf_ptr) == (end_ptr)) \
- (errorflag) = true; \
- else \
- if (*(utf_ptr)++=='L') { \
- while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';') \
- /* skip */; \
- if ((utf_ptr)[-1] != ';') \
- (errorflag) = true; }} while(0)
-
+/* machine dependent descriptor function */
+void md_param_alloc(methoddesc *md);
#endif /* _DESCRIPTOR_H */