/* Class.h
   Internal representation of a classfile. 
   Only a subset of the classfile contents is kept.
*/

/* Handy class file types */
typedef uint8	u1;
typedef uint16	u2;
typedef uint32	u4;

/* Constant pool tag definitions. */
#define	CONSTANT_Class			7
#define	CONSTANT_Fieldref		9
#define	CONSTANT_Methodref		10
#define	CONSTANT_InterfaceMethodref	11
#define	CONSTANT_String			8
#define	CONSTANT_Integer		3
#define	CONSTANT_Float			4
#define	CONSTANT_Long			5
#define	CONSTANT_Double			6
#define	CONSTANT_NameAndType		12
#define	CONSTANT_Utf8			1

/* Constant pool entries */
typedef struct {
  u1 tag;
  union {
    struct {
      u2 name_index;
    } class;
    struct {
      u2 class_index;
      u2 name_and_type_index;
    } fieldref;
    struct {
      u2 class_index;
      u2 name_and_type_index;
    } methodref;
    struct {
      u2 string_index;
    } string;
    struct {
      u4 bytes;
    } integer;
    struct {
      u2 name_index;
      u2 descriptor_index;
    } name_and_type;
    struct {
      u2 length;
      u1 *bytes; /* null terminated, terminator not in length */
    } utf8;
  } u;
} Constant;

/* Methods */
typedef struct {
  u2 name_index;
  u2 descriptor_index;
  u2 max_stack;
  u2 max_locals;
  u4 code_length;
  u1 *code;
  u4 *scode;  /* ultimately holds compiled code, if in jit system */
} Method;

/* Classes */
typedef struct {
  u2 class_index;
  u2 constants_count;  
  Constant *constants; /* NB: indexed from 1 to constants_count-1 */
  u2 methods_count;
  Method *methods; 
} Class;

/* Constant Pool Access functions.  
   These should always be used in preference to poking around
   directly in the pool.
 */

u1 get_constant_tag(Class *cl, u2 index);
char *get_utf8(Class *class,u2 index);
char *get_class(Class *class,u2 index);
char *get_string(Class *class,u2 index);
u4 get_integer(Class *class,u2 index);
char *get_name(Class *class,u2 index);
char *get_type(Class *class,u2 index);
char *get_field_class(Class *class,u2 index);
char *get_field_name(Class *class,u2 index);
char *get_field_type(Class *class,u2 index);
char *get_method_class(Class *class,u2 index);
char *get_method_name(Class *class,u2 index);
char *get_method_type(Class *class,u2 index);

/* Find a method in the method table. */
Method *find_method(Class *class,char *method_name, char *method_type);

/* Return the number of arguments to a method. */
int count_args(char *method_type);
int count_results(char *method_type);

/* Reading */
Class *read_class(FILE *cf);
