#include "lib9.h"#include "bio.h"#include "isa.h" enum { /* Java constant pool tags */ CON_Utf8 = 1, /* CON_Unicode = 2, */ /* obsolete */ CON_Integer = 3, CON_Float = 4, CON_Long = 5, CON_Double = 6, CON_Class = 7, CON_String = 8, CON_Fieldref = 9, CON_Methodref = 10, CON_InterfaceMref = 11, CON_NameAndType = 12, /* Java access flags */ ACC_PUBLIC = 0x0001, ACC_PRIVATE = 0x0002, ACC_PROTECTED = 0x0004, ACC_STATIC = 0x0008, ACC_FINAL = 0x0010, ACC_SUPER = 0x0020, ACC_SYNCHRONIZED = 0x0020, /* sic */ ACC_VOLATILE = 0x0040, ACC_TRANSIENT = 0x0080, ACC_NATIVE = 0x0100, ACC_INTERFACE = 0x0200, ACC_ABSTRACT = 0x0400, _MUSTCOMPILE = MUSTCOMPILE<<16, _DONTCOMPILE = DONTCOMPILE<<16, /* basic block flags */ BB_LDR = 1 << 0, /* set for all leaders */ BB_ENTRY = 1 << 1, /* method entry point */ BB_FINALLY = 1 << 2, /* finally block entry point */ BB_HANDLER = 1 << 3, /* EH entry point */ BB_REACHABLE = 1 << 4, /* reachable basic block */ /* basic block states */ BB_PRESIM = 1 << 0, /* not simulated yet */ BB_ACTIVE = 1 << 1, /* simulating or being unified */ BB_POSTSIM = 1 << 2, /* simulated */ BB_POSTUNIFY = 1 << 3, /* unified */ /* Dis operand classification */ Anone = 0, Aimm, Amp, Ampind, Afp, Afpind, Aend, /* Dis n(fp) types */ DIS_X = 0, /* not yet typed */ DIS_W, /* 'B', 'Z', 'C', 'S', 'I' */ DIS_L, /* 'F', 'J', 'D' */ DIS_P, /* 'L', '[' */ /* inferno/vm/Array */ ARY_DATA = IBY2WD, /* Array data (Dis array) */ ARY_NDIM = 2*IBY2WD, /* number of dimensions */ ARY_ADT = 3*IBY2WD, /* 'ref Class' of element type */ ARY_ETYPE = 4*IBY2WD, /* primitive element type code */ /* java/lang/String */ STR_DISSTR = IBY2WD, /* offset to Dis string in a String */ /* miscellaneous */ REFSYSEX = 24, /* 24(fp) is a 'ref Sys->Exception' */ EXOBJ = 28, /* 28(fp) is exception object */ THISOFF = 32, /* 32(fp) is "this" pointer */ REGSIZE = 32, /* 32(fp) is first usable frame cell */ Hashsize = 31, ALLOCINCR = 16}; typedef struct Attr Attr;typedef struct Field Field;typedef struct Method Method;typedef union Const Const;typedef struct Class Class;typedef struct Jinst Jinst;typedef struct StkSnap StkSnap;typedef struct BB BB;typedef struct BBList BBList;typedef struct Code Code;typedef struct PCode PCode;typedef struct Handler Handler; typedef struct Addr Addr;typedef struct Inst Inst; union Const { double tdouble; /* CONSTANT_[Float|Double]_info */ vlong tvlong; /* CONSTANT_Long_info */ int tint; /* CONSTANT_Integer_info */ ushort string_index; /* CONSTANT_String_info */ struct { /* CONSTANT_Class_info */ ushort name_index; } ci; /* CONSTANT_[Fieldref|Methodref|InterfaceMethodref]_info */ struct { ushort class_index; ushort name_type_index; } fmiref; struct { /* CONSTANT_NameAndType */ ushort name_index; ushort sig_index; } nat; struct { /* CONSTANT_Utf8_info */ ushort ln; char *utf8; } utf8;}; struct Attr { /* attribute_info */ ushort name; uint ln; uchar *info;}; struct Field { /* field_info */ ushort access_flags; ushort name_index; ushort sig_index; ushort attr_count; Attr *attr_info; /* ConstantValue attributes */}; struct Method { /* method_info */ ushort access_flags; ushort name_index; ushort sig_index; ushort attr_count; Attr *attr_info; /* Code, Exceptions attributes */}; struct Class { /* ClassFile */ /* uint magic; */ /* 0xcafebabe */ ushort min; ushort maj; ushort cp_count; Const *cps; char *cts; ushort access_flags; ushort this_class; ushort super_class; ushort interfaces_count; ushort *interfaces; ushort fields_count; Field *fields; ushort methods_count; Method *methods; ushort source_file;}; struct Addr { /* Dis operand */ uchar mode; /* Anone, Aimm, Amp, etc. */ union { int ival; /* immediate, $ival */ int offset; /* single indirect, offset(fp) */ struct { /* double indirect, si(fi(fp)) */ ushort fi; ushort si; } b; } u;}; struct Jinst { /* Java instruction */ uchar op; /* op code */ uchar jtype; /* Java type of dst ('I', '[', etc.) */ int pc; /* pc offset */ int line; /* source line number */ int size; /* size of this instruction */ Inst *dis; /* Dis code for this instruction */ BB *bb; /* the instruction's basic block */ int nsrc; /* 0 or more source operands */ int *src; Addr dst; /* usual destination operand */ Addr movsrc; /* source operand if mov generated for load */ union { int i; /* AT, X1, X2, B2, B4, V1, V2 */ struct { /* iinc */ uint ix; int icon; } x1c; struct { /* invokeinterface */ uint ix; uint narg; uint zero; } x2c0; struct { /* multianewarray */ uint ix; uint dim; } x2d; struct { /* tableswitch */ int dflt; int lb; int hb; int *tbl; } t1; struct { /* lookupswitch */ int dflt; int np; int *tbl; } t2; struct { /* wide */ uchar op; uint ix; int icon; } w; } u;}; struct Handler { /* exception_table entry */ ushort start_pc; ushort end_pc; ushort handler_pc; ushort catch_type;}; struct Code { /* one Java method */ int max_stack; int max_locals; int code_length; Jinst *j; int nex; Handler **ex;}; struct PCode { Code *code; char *name; char *sig;}; struct StkSnap { /* snapshot of simulated Java VM stack */ uchar jtype; int npc; int *pc;}; struct BB { /* basic block */ int id; /* unique identifier */ Jinst *js; /* first instruction in basic block */ Jinst *je; /* last instruction in basic block */ BBList *succ; /* successors */ BBList *pred; /* predecessors */ uchar *dom; /* bit-vector of dominators */ uchar flags; /* basic block leader flags */ uchar state; /* BB_PRESIM, etc. */ int entrysz; /* size of saved entry stack */ StkSnap *entrystk; /* snapshot of entry stack */ int exitsz; /* size of saved exit stack */ StkSnap *exitstk; /* snapshot of exit stack */}; struct BBList { BB *bb; BBList *next;}; struct Inst { /* Dis instruction */ uchar op; /* op code */ Addr s; /* source */ Addr m; /* middle */ Addr d; /* destination */ int pc; /* 0-based instruction offset */ Jinst *j; Inst *next;}; /* asm.c */extern int Aconv(va_list*, Fconv*);extern int Iconv(va_list*, Fconv*);extern void asminst(void);extern void sblinst(Biobuf*);extern Inst *clinitclone; /* bb.c */extern void flowgraph(void);extern void bbfree(void);extern void bbinit(void);extern void bbput(BB*);extern BB *bbget(void);extern void crefseed(void);extern void crefenter(char*, BB*);extern int crefstate(char*, BB*, int);extern void creffree(void); /* desc.c */extern int descid(int, int, uchar*);extern void mpdescid(int, int, uchar*);extern void asmdesc(void);extern void disndesc(void);extern void disdesc(void); /* dis.c */extern void discon(int);extern void disword(int);extern void disdata(int, int);extern void disflush(int, int, int);extern void disbyte(int, int);extern void disint(int, int);extern void dislong(int, vlong);extern void disreal(int, double);extern void disstring(int, char*);extern void disarray(int, int, int);extern void disapop(void);extern void disout(void);extern Inst *ihead;extern Inst *itail; /* entry.c */extern void setentry(int, int);extern void asmentry(void);extern void disentry(void); /* finally.c */extern void finallyentry(int);extern void finallyalloc(void);extern void jsrfixup(Addr*, Addr*, int, int);extern void retfixup(Addr*, Addr*, int);extern void finallyfree(void); /* frame.c */extern void openframe(char*, int);extern int closeframe(void);extern int localix(uchar, int);extern void reservereg(StkSnap*, int);extern int getreg(uchar);extern void acqreg(Addr*);extern void relreg(Addr*);extern void clearreg(void);extern void disstackext(void); /* javadas.c */extern int Jconv(va_list*, Fconv*);extern Code *javadas(Attr*); /* javatbl.c */extern int isload(Jinst*);extern int isstore(Jinst*); /* links.c */extern void xtrnlink(int, int, char*, char*);extern void addfcpatch(Inst*, Inst*, char*, char*);extern void dofcpatch(void);extern void asmlinks(void);extern void disnlinks(void);extern void dislinks(void);extern void sbllinks(Biobuf*); /* loader.c */extern void ClassLoader(char*);extern void dumpcpool(void);extern char *CLASSNAME(int);extern char *STRING(int);extern Class *class;extern PCode *pcode;extern char *THISCLASS;extern char *SUPERCLASS; /* main.c */extern int compileflag;extern int gensbl;extern int verbose;extern Biobuf *bout;extern char *ofile; /* mdata.c */extern int mpint(int);extern int mplong(vlong);extern int mpreal(double);extern int mpstring(char*);extern int mpcase(int, int*);extern void mpdesc(void);extern int mpgoto(int, int*);extern void asmarray(int, int, int, int);extern void asmint(int, int);extern void asmstring(int, char*);extern void asmvar(void);extern void disnvar(void);extern void disvar(void); /* module.c */extern void asmmod(void);extern void dismod(void); /* patch.c */extern void patchop(Inst*);extern void patchcase(Inst*, int, int*);extern void patchmethod(int);extern void patchfree(void); /* sbl.c */extern void sblout(char*); /* simjvm.c */extern void simjvm(char*); /* unify.c */extern void unify(void); /* util.c */extern void uSet(uchar*);extern void uN(int);extern uchar u1(void);extern ushort u2(void);extern uint u4(void);extern void getattr(Attr*);extern int CVattrindex(Field*);extern char *uPtr(void);extern int align(int, int);extern void pstring(char*);extern void fatal(char*, ...);extern void verifycpindex(Jinst*, int, int);extern void verifyerror(Jinst*);extern void verifyerrormess(char*);extern char *nextjavatype(char*);extern uchar j2dtype(uchar);extern void addrimm(Addr*, int);extern int notimmable(int);extern void addrsind(Addr*, uchar, int);extern void addrdind(Addr*, uchar, uint, uint);extern void dstreg(Addr*, uchar);extern void setbit(uchar*, int);extern int hashval(char*);extern void *Malloc(uint);extern void *Mallocz(uint);extern void *Realloc(void*, uint);extern int cellsize[]; /* xlate.c */extern void xlate(void);extern Code *code;#pragma varargck type "A" Addr*
#include "lib9.h"
#include "bio.h"
#include "isa.h"
enum {
/* Java constant pool tags */
CON_Utf8 = 1,
/* CON_Unicode = 2, */ /* obsolete */
CON_Integer = 3,
CON_Float = 4,
CON_Long = 5,
CON_Double = 6,
CON_Class = 7,
CON_String = 8,
CON_Fieldref = 9,
CON_Methodref = 10,
CON_InterfaceMref = 11,
CON_NameAndType = 12,
/* Java access flags */
ACC_PUBLIC = 0x0001,
ACC_PRIVATE = 0x0002,
ACC_PROTECTED = 0x0004,
ACC_STATIC = 0x0008,
ACC_FINAL = 0x0010,
ACC_SUPER = 0x0020,
ACC_SYNCHRONIZED = 0x0020, /* sic */
ACC_VOLATILE = 0x0040,
ACC_TRANSIENT = 0x0080,
ACC_NATIVE = 0x0100,
ACC_INTERFACE = 0x0200,
ACC_ABSTRACT = 0x0400,
_MUSTCOMPILE = MUSTCOMPILE<<16,
_DONTCOMPILE = DONTCOMPILE<<16,
/* basic block flags */
BB_LDR = 1 << 0, /* set for all leaders */
BB_ENTRY = 1 << 1, /* method entry point */
BB_FINALLY = 1 << 2, /* finally block entry point */
BB_HANDLER = 1 << 3, /* EH entry point */
BB_REACHABLE = 1 << 4, /* reachable basic block */
/* basic block states */
BB_PRESIM = 1 << 0, /* not simulated yet */
BB_ACTIVE = 1 << 1, /* simulating or being unified */
BB_POSTSIM = 1 << 2, /* simulated */
BB_POSTUNIFY = 1 << 3, /* unified */
/* Dis operand classification */
Anone = 0,
Aimm,
Amp,
Ampind,
Afp,
Afpind,
Aend,
/* Dis n(fp) types */
DIS_X = 0, /* not yet typed */
DIS_W, /* 'B', 'Z', 'C', 'S', 'I' */
DIS_L, /* 'F', 'J', 'D' */
DIS_P, /* 'L', '[' */
/* inferno/vm/Array */
ARY_DATA = IBY2WD, /* Array data (Dis array) */
ARY_NDIM = 2*IBY2WD, /* number of dimensions */
ARY_ADT = 3*IBY2WD, /* 'ref Class' of element type */
ARY_ETYPE = 4*IBY2WD, /* primitive element type code */
/* java/lang/String */
STR_DISSTR = IBY2WD, /* offset to Dis string in a String */
/* miscellaneous */
REFSYSEX = 24, /* 24(fp) is a 'ref Sys->Exception' */
EXOBJ = 28, /* 28(fp) is exception object */
THISOFF = 32, /* 32(fp) is "this" pointer */
REGSIZE = 32, /* 32(fp) is first usable frame cell */
Hashsize = 31,
ALLOCINCR = 16
};
typedef struct Attr Attr;
typedef struct Field Field;
typedef struct Method Method;
typedef union Const Const;
typedef struct Class Class;
typedef struct Jinst Jinst;
typedef struct StkSnap StkSnap;
typedef struct BB BB;
typedef struct BBList BBList;
typedef struct Code Code;
typedef struct PCode PCode;
typedef struct Handler Handler;
typedef struct Addr Addr;
typedef struct Inst Inst;
union Const {
double tdouble; /* CONSTANT_[Float|Double]_info */
vlong tvlong; /* CONSTANT_Long_info */
int tint; /* CONSTANT_Integer_info */
ushort string_index; /* CONSTANT_String_info */
struct { /* CONSTANT_Class_info */
ushort name_index;
} ci;
/* CONSTANT_[Fieldref|Methodref|InterfaceMethodref]_info */
struct {
ushort class_index;
ushort name_type_index;
} fmiref;
struct { /* CONSTANT_NameAndType */
ushort name_index;
ushort sig_index;
} nat;
struct { /* CONSTANT_Utf8_info */
ushort ln;
char *utf8;
} utf8;
};
struct Attr { /* attribute_info */
ushort name;
uint ln;
uchar *info;
};
struct Field { /* field_info */
ushort access_flags;
ushort name_index;
ushort sig_index;
ushort attr_count;
Attr *attr_info; /* ConstantValue attributes */
};
struct Method { /* method_info */
ushort access_flags;
ushort name_index;
ushort sig_index;
ushort attr_count;
Attr *attr_info; /* Code, Exceptions attributes */
};
struct Class { /* ClassFile */
/* uint magic; */ /* 0xcafebabe */
ushort min;
ushort maj;
ushort cp_count;
Const *cps;
char *cts;
ushort access_flags;
ushort this_class;
ushort super_class;
ushort interfaces_count;
ushort *interfaces;
ushort fields_count;
Field *fields;
ushort methods_count;
Method *methods;
ushort source_file;
};
struct Addr { /* Dis operand */
uchar mode; /* Anone, Aimm, Amp, etc. */
union {
int ival; /* immediate, $ival */
int offset; /* single indirect, offset(fp) */
struct { /* double indirect, si(fi(fp)) */
ushort fi;
ushort si;
} b;
} u;
};
struct Jinst { /* Java instruction */
uchar op; /* op code */
uchar jtype; /* Java type of dst ('I', '[', etc.) */
int pc; /* pc offset */
int line; /* source line number */
int size; /* size of this instruction */
Inst *dis; /* Dis code for this instruction */
BB *bb; /* the instruction's basic block */
int nsrc; /* 0 or more source operands */
int *src;
Addr dst; /* usual destination operand */
Addr movsrc; /* source operand if mov generated for load */
union {
int i; /* AT, X1, X2, B2, B4, V1, V2 */
struct { /* iinc */
uint ix;
int icon;
} x1c;
struct { /* invokeinterface */
uint ix;
uint narg;
uint zero;
} x2c0;
struct { /* multianewarray */
uint ix;
uint dim;
} x2d;
struct { /* tableswitch */
int dflt;
int lb;
int hb;
int *tbl;
} t1;
struct { /* lookupswitch */
int dflt;
int np;
int *tbl;
} t2;
struct { /* wide */
uchar op;
uint ix;
int icon;
} w;
} u;
};
struct Handler { /* exception_table entry */
ushort start_pc;
ushort end_pc;
ushort handler_pc;
ushort catch_type;
};
struct Code { /* one Java method */
int max_stack;
int max_locals;
int code_length;
Jinst *j;
int nex;
Handler **ex;
};
struct PCode {
Code *code;
char *name;
char *sig;
};
struct StkSnap { /* snapshot of simulated Java VM stack */
uchar jtype;
int npc;
int *pc;
};
struct BB { /* basic block */
int id; /* unique identifier */
Jinst *js; /* first instruction in basic block */
Jinst *je; /* last instruction in basic block */
BBList *succ; /* successors */
BBList *pred; /* predecessors */
uchar *dom; /* bit-vector of dominators */
uchar flags; /* basic block leader flags */
uchar state; /* BB_PRESIM, etc. */
int entrysz; /* size of saved entry stack */
StkSnap *entrystk; /* snapshot of entry stack */
int exitsz; /* size of saved exit stack */
StkSnap *exitstk; /* snapshot of exit stack */
};
struct BBList {
BB *bb;
BBList *next;
};
struct Inst { /* Dis instruction */
uchar op; /* op code */
Addr s; /* source */
Addr m; /* middle */
Addr d; /* destination */
int pc; /* 0-based instruction offset */
Jinst *j;
Inst *next;
};
/* asm.c */
extern int Aconv(va_list*, Fconv*);
extern int Iconv(va_list*, Fconv*);
extern void asminst(void);
extern void sblinst(Biobuf*);
extern Inst *clinitclone;
/* bb.c */
extern void flowgraph(void);
extern void bbfree(void);
extern void bbinit(void);
extern void bbput(BB*);
extern BB *bbget(void);
extern void crefseed(void);
extern void crefenter(char*, BB*);
extern int crefstate(char*, BB*, int);
extern void creffree(void);
/* desc.c */
extern int descid(int, int, uchar*);
extern void mpdescid(int, int, uchar*);
extern void asmdesc(void);
extern void disndesc(void);
extern void disdesc(void);
/* dis.c */
extern void discon(int);
extern void disword(int);
extern void disdata(int, int);
extern void disflush(int, int, int);
extern void disbyte(int, int);
extern void disint(int, int);
extern void dislong(int, vlong);
extern void disreal(int, double);
extern void disstring(int, char*);
extern void disarray(int, int, int);
extern void disapop(void);
extern void disout(void);
extern Inst *ihead;
extern Inst *itail;
/* entry.c */
extern void setentry(int, int);
extern void asmentry(void);
extern void disentry(void);
/* finally.c */
extern void finallyentry(int);
extern void finallyalloc(void);
extern void jsrfixup(Addr*, Addr*, int, int);
extern void retfixup(Addr*, Addr*, int);
extern void finallyfree(void);
/* frame.c */
extern void openframe(char*, int);
extern int closeframe(void);
extern int localix(uchar, int);
extern void reservereg(StkSnap*, int);
extern int getreg(uchar);
extern void acqreg(Addr*);
extern void relreg(Addr*);
extern void clearreg(void);
extern void disstackext(void);
/* javadas.c */
extern int Jconv(va_list*, Fconv*);
extern Code *javadas(Attr*);
/* javatbl.c */
extern int isload(Jinst*);
extern int isstore(Jinst*);
/* links.c */
extern void xtrnlink(int, int, char*, char*);
extern void addfcpatch(Inst*, Inst*, char*, char*);
extern void dofcpatch(void);
extern void asmlinks(void);
extern void disnlinks(void);
extern void dislinks(void);
extern void sbllinks(Biobuf*);
/* loader.c */
extern void ClassLoader(char*);
extern void dumpcpool(void);
extern char *CLASSNAME(int);
extern char *STRING(int);
extern Class *class;
extern PCode *pcode;
extern char *THISCLASS;
extern char *SUPERCLASS;
/* main.c */
extern int compileflag;
extern int gensbl;
extern int verbose;
extern Biobuf *bout;
extern char *ofile;
/* mdata.c */
extern int mpint(int);
extern int mplong(vlong);
extern int mpreal(double);
extern int mpstring(char*);
extern int mpcase(int, int*);
extern void mpdesc(void);
extern int mpgoto(int, int*);
extern void asmarray(int, int, int, int);
extern void asmint(int, int);
extern void asmstring(int, char*);
extern void asmvar(void);
extern void disnvar(void);
extern void disvar(void);
/* module.c */
extern void asmmod(void);
extern void dismod(void);
/* patch.c */
extern void patchop(Inst*);
extern void patchcase(Inst*, int, int*);
extern void patchmethod(int);
extern void patchfree(void);
/* sbl.c */
extern void sblout(char*);
/* simjvm.c */
extern void simjvm(char*);
/* unify.c */
extern void unify(void);
/* util.c */
extern void uSet(uchar*);
extern void uN(int);
extern uchar u1(void);
extern ushort u2(void);
extern uint u4(void);
extern void getattr(Attr*);
extern int CVattrindex(Field*);
extern char *uPtr(void);
extern int align(int, int);
extern void pstring(char*);
extern void fatal(char*, ...);
extern void verifycpindex(Jinst*, int, int);
extern void verifyerror(Jinst*);
extern void verifyerrormess(char*);
extern char *nextjavatype(char*);
extern uchar j2dtype(uchar);
extern void addrimm(Addr*, int);
extern int notimmable(int);
extern void addrsind(Addr*, uchar, int);
extern void addrdind(Addr*, uchar, uint, uint);
extern void dstreg(Addr*, uchar);
extern void setbit(uchar*, int);
extern int hashval(char*);
extern void *Malloc(uint);
extern void *Mallocz(uint);
extern void *Realloc(void*, uint);
extern int cellsize[];
/* xlate.c */
extern void xlate(void);
extern Code *code;
#pragma varargck type "A" Addr*