/*
 * $Id: class_file.h,v 1.3 2000/09/05 15:08:56 m-hirano Exp $
 * $RWC_Release: Omni-1.6 $
 * $RWC_Copyright:
 *  Omni Compiler Software Version 1.5-1.6
 *  Copyright (C) 2002 PC Cluster Consortium
 *  
 *  This software is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License version
 *  2.1 published by the Free Software Foundation.
 *  
 *  Omni Compiler Software Version 1.0-1.4
 *  Copyright (C) 1999, 2000, 2001.
 *   Tsukuba Research Center, Real World Computing Partnership, Japan.
 *  
 *  Please check the Copyright and License information in the files named
 *  COPYRIGHT and LICENSE under the top  directory of the Omni Compiler
 *  Software release kit.
 *  
 *  
 *  $
 */

#define TRUE 1
#define FALSE 0

#include "jvm-opcode.h"
#define MAX_OPCODE 256

struct opcode_info {
    int opcode;
    char *name;
    char *opd_type;
};

extern struct opcode_info *opcode_infos[];
extern struct opcode_info opcode_info_table[];

#define MAX_STR_LEN 1024

#define MAGIC 0xCAFEBABE

enum cp_tag {
 CONSTANT_utf8 = 1,
 CONSTANT_Integer = 3,
 CONSTANT_Float = 4,
 CONSTANT_Long = 5,
 CONSTANT_Double = 6,
 CONSTANT_Class = 7,
 CONSTANT_String = 8,
 CONSTANT_Fieldref = 9,
 CONSTANT_Methodref = 10,
 CONSTANT_InterfaceMethodref = 11,
 CONSTANT_NameAndType = 12
};

typedef struct _cp_info {
    enum cp_tag tag;
    union {
	int i;		/* Integer */
	int f;		/* Float */
	double d;	/* Double */
	struct {	
#if (WORDS_BIGENDIAN == 0)
	    int low,high;
#else
	    int high,low;
#endif
	} L;		/* Long */
	struct {
	    short len;
	    char *str;
	} utf8;		/* utf8 */
	struct {
	    int name_index;
	    struct _class_file *cfp;
	} class;	/* Class */
	struct {	
	    int string_index;
	    char *str;
	    int id;
	} string;	/* String */
	struct {
	    int class_index;
	    int name_index;
	    struct _field_info *fp;
	} field;	/* Field */
	struct {
	    int class_index;
	    int name_index;
	    struct _method_info *mp;
	} method;	/* Method & InterfaceMethod */
	struct {
	    int name_index;
	    int desc_index;
	} name;		/* Name and Type */
    } info;
} cp_info;

enum attr_kind {
    ATTR_NONE = 0,
    ATTR_CODE,
    ATTR_EXCEPTIONS,
    ATTR_SYNTHETIC,
    ATTR_LINE_NO,
    ATTR_LOCAL_VAR,
    ATTR_SOURCE_FILE,
    ATTR_INNER_CLASS,
    ATTR_CONST_VAL
};

typedef struct _attr_info {
    enum attr_kind kind;
    void *p;
    int index;	/* for ATTR_CONST_VAL */
} attr_info;

typedef struct _exception_info {
    int start_pc;
    int end_pc;
    int handler_pc;
    int catch_type;
} exception_info;

typedef struct _code_attr {
    int max_stack;
    int max_locals;
    int code_len;
    char *code;
    int exception_table_len;
    exception_info *exception_table;
    int attr_count;
    attr_info *attrs;

    /* internal */
    int id; 	/* code id */
} code_attr;

typedef struct _exception_attr {
    int n_exceptions;
    int *exception_index_table;
} exception_attr;

typedef struct _field_info {
    int access_flag;
    int name_index;
    int desc_index;
    int attr_count;
    attr_info *attrs;

    /* Internal */
    char is_static;
    char is_object;
    int disp;
} field_info;

#define FIELD_ACC_STATIC 0x8
#define IS_STATIC_FIELD(fp) ((fp)->access_flag & FIELD_ACC_STATIC)

typedef struct _method_info {
    int access_flag;
    int name_index;
    int desc_index;
    int attr_count;
    attr_info *attrs;

    /* internal info */
    int disp;
    int id;		/* method id, unique number */
    int n_args;
    char *cname;	/* for system_class */
} method_info;

#define ACC_INTERFACE 0x200
#define IS_INTERFACE_CLASS(cfp) ((cfp)->access_flag & ACC_INTERFACE)

typedef struct _class_file {
    int magic;
    short major_version;
    short minor_version;
    int cp_count;
    cp_info *cp_info_table;
    int access_flag;
    int this_class;
    int super_class;
    int interface_count;
    int *interfaces;
    int field_count;
    field_info *fields;
    int method_count;
    method_info *methods;
    int attr_count;
    attr_info *attrs;

    /* internal info */
    struct _class_file *link;	/* class file link */
    char *this_class_name;	/* Key */
    struct _class_file *super;	/* super class */
    struct _class_file *next;	/* reference order link */
    char is_system;
    char is_linked;
    char is_interface;
    int id;

    int n_static,i_static;	/* static field */
    int n_var,i_var;
    int n_method;
} class_file;

typedef enum jexc_data_type {
    UNDEF = 0,	/* undefined */
    BYTE,
    SHORT,
    INT,
    LONG,
    FLOAT,
    DOUBLE,
    OBJECT,
    BASIC_TYPE_END
} DATA_TYPE;

class_file *read_class_file(char *file_name);
void print_cp_info(FILE *fp,cp_info *cp);
void print_field_info(FILE *fp,field_info *ip,class_file *cfp);
void print_method_info(FILE *fp,method_info *mp,class_file *cfp);
void print_code_attr(FILE *fp,code_attr *cp, class_file *cfp);

char *get_cp_str(class_file *cfp,int index);
char *get_class_name(class_file *cfp,int index);
class_file *get_class(class_file *cfp,int index);

char *get_field_class_name(class_file *cfp,int index);
class_file *get_field_class(class_file *cfp,int index);
field_info *get_field(class_file *cfp,int index);
char *get_field_name(class_file *cfp,int index);
char *get_field_desc(class_file *cfp,int index);

method_info *get_method(class_file *cfp,int index);
char *get_method_class_name(class_file *cfp,int index);
class_file *get_method_class(class_file *cfp,int index);
char *get_method_name(class_file *cfp,int index);
char *get_method_desc(class_file *cfp,int index);

char *get_NameAndType_desc(class_file *cfp,int index);
char *get_NameAndType_name(class_file *cfp,int index);

int get_desc_n_args(char *desc);
DATA_TYPE get_desc_data_type(char *name);

char *attr_name(enum attr_kind k);
char *intern(char *name);


