/*
 *      Interactive disassembler (IDA).
 *      Version 3.05
 *      Copyright (c) 1990-95 by Ilfak Guilfanov.
 *      ALL RIGHTS RESERVED.
 *                              FIDO:   2:5020/209
 *                              E-mail: ig@estar.msk.su
 *
 */

#ifndef _JAVA_HPP
#define _JAVA_HPP

// #define REMOVE_UNICODE

#include "../idaidp.hpp"
#include <fpro.h>
#include "ins.hpp"

//----------------------------------------------------------------------
// Redefine temporary names
//
#define         wid        segpref
#define         xtrn_ip    auxpref

#define         swit       Op1.specflag2
#define         ref        specflag1
#define         _name      value_shorts.low
#define         _class     value_shorts.high
#define         _sign      addr_shorts.low
#define         _subnam    addr_shorts.high
#define         cp_ind     specval_shorts.low
#define         cp_type    specval_shorts.high
// _Ssize for MAP only (_Spage used in MAP)
#define         _Ssize     addr_shorts.low
#define         _Spage     addr_shorts.high

#define         o_cpool    o_idpspec0
#define         o_array    o_idpspec1
//----------------------------------------------------------------------
struct TXS
{
  char *str;
  char size;
};
#define TXS_DECLARE(p) { p, (char)sizeof(p) }
//----------------------------------------------------------------------

typedef struct {
                 uchar type;   // CONSTANT_type
                 uchar flag;
#define _REF            0x01   // has reference
#define HAS_FM_NAME     0x02   // Utf8 is valid FM Name
#define HAS_SIGNATURE   0x04   // Utf8 is valid Signature
#define HAS_PARAMSIGN   0x08   // Utf8 is valid Signature for Call
#define HAS_CLASS_NAME  0x10   // Utf8 is valid as Class Name (Not FM!)
#define SUB_FM_NAME     0x20
#define SUB_SIGNATURE   0x40
#define SUB_PARAMSIGN   0x80
#define SUB_SHIFT 4
#if (HAS_FM_NAME << SUB_SHIFT) != SUB_FM_NAME
#error
#endif
#if (HAS_SIGNATURE << SUB_SHIFT) != SUB_SIGNATURE
#error
#endif
#if (HAS_PARAMSIGN << SUB_SHIFT) != SUB_PARAMSIGN
#error
#endif
                ushort ref_ip;      // in xtrn-segment...
                union {
                        ulong value;          // low part of # value
                        struct {
                                ushort low;   // BegInd Utf8 (name)
                                ushort high;  // index to _Class
                              }value_shorts;  // univication
                      };
                union {
                        ulong value2;         // hi part of # value
                        struct {
                                ushort low;     //TypeName
                                ushort high;    //Signature
                               }addr_shorts;
                      };
               }ConstOpis;

typedef struct {
                ushort  name;           // index to name
                ushort  sign;           // index to signature
                ushort  access;         // access flag
                ushort  Number;         // Number of current Field or Method
                uchar   flag;           // for ERROR diagnostic
               }_FMid_;

typedef struct {
                _FMid_  id;             // for search procedure
                ulong   CodeSize;       // CODE size
                ea_t    startEA;        // EA of Code (checker & slb)
                ea_t    DataBase;       // EA of loc variable segment
                ushort  DataSize;       // max locals (DATA size)
                ushort  stacks;         // stack size
                uval_t  excNode;        // Node for exception table
                uval_t  thrNode;        // Node for throws
               }SegInfo;

typedef struct {
                ushort  maxCPindex;     // max valid index in ConstantPool
                ushort  MinVers;        //-> of file
                ushort  ThisClass;      // index of ThisClass
                ushort  ThisName;       // index of it's Name
                ushort  SuperClass;     // index of SuperClass
                ushort  SuperName;      // index of it's Name
                ushort  AccessFlag;     // access flags
                ushort  FieldCnt;       // Field Declaration Counter
                uval_t  ClassNode;      // Field (>0) & Method (<0) (0?)
                ushort  MethodCnt;      // Method's Segment fot this Class
                ushort  SourceName;     // Index of Utf8 Source File Name
                uval_t  impNode;        // Node for Interfaces
                ea_t    startEA;        // для SearchFM
                ulong   errload;        // loader error counter
                ea_t    xtrnEA;         // beg header segment
                uval_t  xtrnNode;       // node for xtrn Segment
                ushort  xtrnCnt;        // header size
                ushort  xtrnLQE;
               }ClassInfo;

typedef struct {
                _FMid_  id;             // for search procedure
                uval_t  valNode;      // init value's node
               }FieldInfo;

typedef struct {
                ushort  start_pc;
                ushort  end_pc;
                ushort  handler_pc;
                ushort  catchInd;
                ushort  catchName;
               }Exception;

//------------------------------------------------------------------------
extern ClassInfo curClass;
extern SegInfo   curSeg;
extern FieldInfo curField;
extern uchar     debugmode;
//------------------------------------------------------------------------
ConstOpis *LoadOpis(ushort index, uchar type = 0);
ea_t       SearchFM(ushort nam_ind, ushort sig_ind, short *deltaN);
void       destroyed(void);
void       not_compat(void);
void       myBase(const char *arg);
char      *DecompName(void);
segment_t *getMySeg(ea_t ea);
// !не менять последовательность!
enum fmt_t {
    fmt_string = 0,
    fmt_sign,
    fmt_retsign,
    fmt_retclass,
    fmt_paramstr,
    fmt_cast,
    fmt_signclass,
    fmt_fullname,
    fmt_name
   };
typedef ushort (*_OUTPRC_)(void);
int fmtString(ushort index, short size, fmt_t mode, _OUTPRC_);
typedef int (*_DMPPRC_)(char *ptr, ushort size);
int dmpString(ushort index, _DMPPRC_ dmpproc);
uchar loadDialog(bool manual);
//------------------------------------------------------------------------
#ifdef __debug__
#define deb_error(cond, text)   if(cond) error(text)
#else
#define deb_error(cond, text)
#endif
//------------------------------------------------------------------------
enum j_registers { Rvars=0, Roptop, Rframe, rVcs, rVds };
//------------------------------------------------------------------------
void  header(void);
void  footer(void);

void  segstart(ea_t ea);
void  segend(ea_t ea);

int   ana(void);
int   emu(void);
void  out(void);
bool  outop(op_t &op);

void  java_data(ea_t ea);

void  loader(FILE *fp, bool manualload);
long  gen_map_file(FILE *fp);
ea_t  get_ref_addr(ea_t ea, const char *str, int pos);

int   cmp_opnd(op_t &op1, op_t &op2);
bool  can_have_type(op_t &op);

//------------------------------------------------------------------------
inline int set_cmt_if_none(ea_t ea, const char *cmt, int repeatable)
{
  if ( !has_cmt(getFlags(ea)) )
    return set_cmt(ea, cmt, repeatable);
  return 0;
}

#define UAS_JASMIN   0x0001     // is jasmin assembler?

inline bool jasmin(void) { return (ash.uflag & UAS_JASMIN) != 0; }

#endif


