513 lines · 8.0 KB · C
RawDownload
#include "java.h"#include "reloc.h" /* * Manage module Data Section. */ enum {	MP_INT,	MP_LONG,	MP_REAL,	MP_STRING,	MP_CASE,	MP_GOTO}; typedef struct Hentry	Hentry;typedef	struct Datum	Datum; struct Datum {	uchar	kind;			/* MP_INT, etc. */	int	offset;			/* byte offset in Data Section */	union {		struct {			union {				vlong	ival;	/* MP_INT, MP_LONG */				double	rval;	/* MP_REAL */			} u;			Datum *next;		} v;		char *s;		/* MP_STRING */		struct {		/* MP_CASE */			int	n;	/* number of cases in jmptbl */			int	*jmptbl;/* 3 words per case, plus default */		} c;		struct {		/* MP_GOTO (for finally blocks) */			int	n;	/* number of entries in gototbl */			int	*gototbl;		} g;	} u;	Datum *next;}; struct Hentry{	Datum	*md;	Hentry	*next;}; static	Hentry	*htable[Hashsize];static	int	mpoff; static	Datum	*mplist	= nil;static	Datum	*mptail	= nil;static	Datum	*llist	= nil;static	Datum	*rlist	= nil; /* * Allocate a Datum structure. */ static Datum*newDatum(uchar kind){	Datum *md; 	md = Malloc(sizeof(Datum));	md->kind = kind;	md->next = nil;	md->u.v.next = nil;	return md;} /* * Append a module datum to mplist. */ static voidappend(Datum *md){	if(mplist == nil)		mplist = md;	else		mptail->next = md;	mptail = md;} /* * Add a 'byte', int 'word', or 'long'. */ static intmpintegral(uchar kind, vlong ival){	Datum *md;	int size; 	md = newDatum(kind);	md->u.v.u.ival = ival;	switch(kind) {	case MP_INT:		size = IBY2WD;		mpoff = align(mpoff, IBY2WD);		break;	case MP_LONG:		size = IBY2LG;		mpoff = align(mpoff, IBY2LG);		md->u.v.next = llist;		llist = md;		break;	default:		SET(size);	/* not reached */	}	md->offset = mpoff;	mpoff += size;	append(md);	return md->offset;} /* * Add a 'word' (int). */ intmpint(int ival){	return mpintegral(MP_INT, ival);} /* * Add a 'long'. */ intmplong(vlong lval){	Datum *md; 	for(md = llist; md; md = md->u.v.next) {		if(lval == md->u.v.u.ival)			return md->offset;	}	return mpintegral(MP_LONG, lval);} /* * Add a 'real'. */ /* from math/dtoa.c */#ifdef __LITTLE_ENDIAN#define word0(x) ((unsigned long*)&x)[1]#else#define word0(x) ((unsigned long*)&x)[0]#endif#define Sign_bit 0x80000000 intmpreal(double rval){	Datum *md; 	for(md = rlist; md; md = md->u.v.next) {		/* distinguish 0.0 from -0.0 */		if(rval == md->u.v.u.rval &&		(word0(rval) & Sign_bit) == (word0(md->u.v.u.rval) & Sign_bit))			return md->offset;	}	md = newDatum(MP_REAL);	md->u.v.u.rval = rval;	md->u.v.next = rlist;	rlist = md;	mpoff = align(mpoff, IBY2FT);	md->offset = mpoff;	mpoff += IBY2FT;	append(md);	return md->offset;} /* * Add a 'case' jump table. */ intmpcase(int sz, int *jt){	Datum *md; 	md = newDatum(MP_CASE);	mpoff = align(mpoff, IBY2WD);	md->offset = mpoff;	mpoff += (sz*3+2)*IBY2WD;	md->u.c.n = sz;	md->u.c.jmptbl = jt;	append(md);	return md->offset;} /* * Add a 'goto' jump table; used for implementing finally blocks. */ intmpgoto(int n, int *gototbl){	Datum *md; 	md = newDatum(MP_GOTO);	mpoff = align(mpoff, IBY2WD);	md->offset = mpoff;	mpoff += (n+2)*IBY2WD;	md->u.g.n = n;	md->u.g.gototbl = gototbl;	append(md);	return md->offset+IBY2WD;} /* * Hash table lookup function. */ static Hentry*htlook(char *s){	Hentry *he; 	for(he = htable[hashval(s)]; he; he = he->next)		if(strcmp(s, he->md->u.s) == 0)			return he;	return nil;} /* * Hash table enter function. */ static Hentry*htenter(Datum *md){	uint h;	Hentry *he; 	h = hashval(md->u.s);	he = Malloc(sizeof(Hentry));	he->md = md;	he->next = htable[h];	htable[h] = he;	return he;} /* * Add a 'string'. */ intmpstring(char *s){	Hentry *he;	Datum *md; 	if(he = htlook(s))		return he->md->offset;	md = newDatum(MP_STRING);	md->u.s = s;	mpoff = align(mpoff, IBY2WD);	md->offset = mpoff;	mpoff += IBY2WD;	append(md);	htenter(md);	return md->offset;} /* * Calculate the type descriptor for the Module Data section. */ voidmpdesc(void){	Datum *md;	int ltsize, rtsize, ln, mdsize;	uchar *map; 	ltsize = LTrelocsize();		/* link-time reloc data */	mpoff = align(mpoff, IBY2WD);	rtsize = RTrelocsize();		/* run-time reloc data */	mdsize = ltsize + mpoff + rtsize;	ln = mdsize / (8*IBY2WD) + (mdsize % (8*IBY2WD) != 0);	map = Mallocz(ln);	LTrelocdesc(map);	for(md = mplist; md; md = md->next) {		if(md->kind == MP_STRING)			setbit(map, ltsize + md->offset);	}	RTrelocdesc(map, ltsize + mpoff);	RTfixoff(ltsize + mpoff);	mpdescid(mdsize, ln, map);} static voidasmprefix(int off, char *s){	Bprint(bout, "\t%s\t@mp+%d,", s, off);} /* * Begin an array initializer. */ voidasmarray(int off, int tid, int nelt, int reloff){	asmprefix(off, "array");	Bprint(bout, "$%d,%d\n", tid, nelt);	asmprefix(off, "indir");	Bprint(bout, "%d\n", reloff);} voidasmint(int off, int val){	asmprefix(off, "word");	Bprint(bout, "%d\n", val);} static voidasmlong(int off, vlong val){	asmprefix(off, "long");	Bprint(bout, "%lld\n", val);} static voidasmreal(int off, double val){	asmprefix(off, "real");	Bprint(bout, "%g\n", val);} voidasmstring(int off, char *s){	asmprefix(off, "string");	Bputc(bout, '"');	pstring(s);	Bprint(bout, "\"\n");} static voidasmcase(int off, Datum *md){	int i; 	asmprefix(off, "word");	Bprint(bout, "%d", md->u.c.n);	for(i = 0; i < md->u.c.n; i++) {		Bprint(bout, ",%d", md->u.c.jmptbl[i*3]);		Bprint(bout, ",%d", md->u.c.jmptbl[i*3+1]);		Bprint(bout, ",%d", md->u.c.jmptbl[i*3+2]);	}	Bprint(bout, ",%d\n", md->u.c.jmptbl[md->u.c.n*3]);} static voidasmgoto(int off, Datum *md){	int i; 	asmprefix(off, "word");	Bprint(bout, "%d", md->u.g.n);	for(i = 0; i < md->u.g.n; i++)		Bprint(bout, ",%d", md->u.g.gototbl[i]);	Bputc(bout, '\n');} /* * Write Module Data to .s file. */ voidasmvar(void){	Datum *md;	int ltsize, rtsize, off; 	ltsize = LTrelocsize();	rtsize = RTrelocsize();	Bprint(bout, "\tvar\t@mp,%d\n", ltsize + mpoff + rtsize);	off = asmthisCreloc(0);	asmint(off, mpoff + rtsize);	off += IBY2WD;	asmDreloc(off);	off += IBY2WD;	off = asmCreloc(off);	off = align(off, 32);	if(off != ltsize)		fatal("asmvar: off %d, ltsize %d\n", off, ltsize); 	for(md = mplist; md; md = md->next) {		off = ltsize + md->offset;		switch(md->kind) {		case MP_INT:			asmint(off, md->u.v.u.ival);			break;		case MP_LONG:			asmlong(off, md->u.v.u.ival);			break;		case MP_REAL:			asmreal(off, md->u.v.u.rval);			break;		case MP_STRING:			asmstring(off, md->u.s);			break;		case MP_CASE:			asmcase(off, md);			break;		case MP_GOTO:			asmgoto(off, md);			break;		}	}	asmRTClass(ltsize + mpoff);} /* * Put Module Data size into .dis Header. */ voiddisnvar(void){	discon(LTrelocsize() + mpoff + RTrelocsize());} static voiddiscase(int off, Datum *md){	int i; 	disint(off, md->u.c.n);	off += IBY2WD;	for(i = 0; i < md->u.c.n; i++) {		disint(off, md->u.c.jmptbl[i*3]);		off += IBY2WD;		disint(off, md->u.c.jmptbl[i*3+1]);		off += IBY2WD;		disint(off, md->u.c.jmptbl[i*3+2]);		off += IBY2WD;	}	disint(off, md->u.c.jmptbl[md->u.c.n*3]);} static voiddisgoto(int off, Datum *md){	int i; 	disint(off, md->u.g.n);	for(i = 0; i < md->u.g.n; i++) {		off += IBY2WD;		disint(off, md->u.g.gototbl[i]);	}} /* * Write Module Data to .dis file. */ voiddisvar(void){	Datum *md;	int ltsize, rtsize, off; 	ltsize = LTrelocsize();	rtsize = RTrelocsize();	off = disthisCreloc(0);	disint(off, mpoff + rtsize);	off += IBY2WD;	disDreloc(off);	off += IBY2WD;	off = disCreloc(off);	off = align(off, 32);	if(off != ltsize)		fatal("disvar: off %d, ltsize %d\n", off, ltsize); 	for(md = mplist; md; md = md->next) {		off = ltsize + md->offset;		switch(md->kind) {		case MP_INT:			disint(off, md->u.v.u.ival);			break;		case MP_LONG:			dislong(off, md->u.v.u.ival);			break;		case MP_REAL:			disreal(off, md->u.v.u.rval);			break;		case MP_STRING:			disstring(off, md->u.s);

Lines 1–500 of 513.