Charles.Forsyth20060303a828770d19 years agoHistory
638 lines · 11.5 KB · C
RawDownload
#include "limbo.h" static	void	disbig(long, Long);static	void	disbyte(long, int);static	void	disbytes(long, void*, int);static	void	disdatum(long, Node*);static	void	disflush(int, long, long);static	void	disint(long, long);static	void	disreal(long, Real);static	void	disstring(long, Sym*); static	uchar	*cache;static	int	ncached;static	int	ndatum;static	int	startoff;static	int	lastoff;static	int	lastkind;static	int	lencache; voiddiscon(long val){	if(val >= -64 && val <= 63) {		Bputc(bout, val & ~0x80);		return;	}	if(val >= -8192 && val <= 8191) {		Bputc(bout, ((val>>8) & ~0xC0) | 0x80);		Bputc(bout, val);		return;	}	if(val < 0 && ((val >> 29) & 0x7) != 7	|| val > 0 && (val >> 29) != 0)		fatal("overflow in constant 0x%lux\n", val);	Bputc(bout, (val>>24) | 0xC0);	Bputc(bout, val>>16);	Bputc(bout, val>>8);	Bputc(bout, val);} voiddisword(long w){	Bputc(bout, w >> 24);	Bputc(bout, w >> 16);	Bputc(bout, w >> 8);	Bputc(bout, w);} voiddisdata(int kind, long n){	if(n < DMAX && n != 0)		Bputc(bout, DBYTE(kind, n));	else{		Bputc(bout, DBYTE(kind, 0));		discon(n);	}} #define	NAMELEN	64 voiddismod(Decl *m){	char name[8*NAMELEN];	ulong fileoff; 	fileoff = Boffset(bout);	strncpy(name, m->sym->name, NAMELEN);	name[NAMELEN-1] = '\0';	Bwrite(bout, name, strlen(name)+1);	for(m = m->ty->tof->ids; m != nil; m = m->next){		switch(m->store){		case Dglobal:			discon(-1);			discon(-1);			disword(sign(m));			Bprint(bout, ".mp");			Bputc(bout, '\0');			break;		case Dfn:if(debug['v']) print("Dfn: %s %d %p\n", m->sym->name, m->refs, m);			discon(m->pc->pc);			discon(m->desc->id);			disword(sign(m));			if(m->dot->ty->kind == Tadt)				Bprint(bout, "%s.", m->dot->sym->name);			Bprint(bout, "%s", m->sym->name);			Bputc(bout, '\0');			break;		default:			fatal("unknown kind %K in dismod", m);			break;		}	}	if(debug['s'])		print("%ld linkage bytes start %ld\n", Boffset(bout) - fileoff, fileoff);} voiddispath(void){	char name[8*NAMELEN], *sp; 	sp = srcpath(name, 8*NAMELEN);	Bwrite(bout, sp, strlen(sp)+1);} voiddisentry(Decl *e){	if(e == nil){		discon(-1);		discon(-1);		return;	}	discon(e->pc->pc);	discon(e->desc->id);} voiddisdesc(Desc *d){	ulong fileoff; 	fileoff = Boffset(bout);	for(; d != nil; d = d->next){		discon(d->id);		discon(d->size);		discon(d->nmap);		Bwrite(bout, d->map, d->nmap);	}	if(debug['s'])		print("%ld type descriptor bytes start %ld\n", Boffset(bout) - fileoff, fileoff);} voiddisvar(long size, Decl *d){	ulong fileoff; 	fileoff = Boffset(bout);	USED(size); 	lastkind = -1;	ncached = 0;	ndatum = 0; 	for(; d != nil; d = d->next)		if(d->store == Dglobal && d->init != nil)			disdatum(d->offset, d->init); 	disflush(-1, -1, 0); 	Bputc(bout, 0); 	if(debug['s'])		print("%ld data bytes start %ld\n", Boffset(bout) - fileoff, fileoff);} voiddisldt(long size, Decl *ds){	int m;	Decl *d, *id;	Sym *s;	Node *n; 	if(0){		discon(size);		disvar(size, ds);		return;	} 	m = 0;	for(d = ds; d != nil; d = d->next)		if(d->store == Dglobal && d->init != nil)			m++;	discon(m);	for(d = ds; d != nil; d = d->next){		if(d->store == Dglobal && d->init != nil){			n = d->init;			if(n->ty->kind != Tiface)				nerror(n, "disldt: not Tiface");			discon(n->val);			for(id = n->decl->ty->ids; id != nil; id = id->next){				disword(sign(id));				if(id->dot->ty->kind == Tadt){					s = id->dot->sym;					Bprint(bout, "%s", s->name);					Bputc(bout, '.');				}				s = id->sym;				Bprint(bout, "%s", s->name);				Bputc(bout, 0);			}		}	}	discon(0);} static voiddisdatum(long offset, Node *n){	Node *elem, *wild;	Case *c;	Label *lab;	Decl *id;	Sym *s;	long e, last, esz;	int i; 	switch(n->ty->kind){	case Tbyte:		disbyte(offset, n->val);		break;	case Tint:	case Tfix:		disint(offset, n->val);		break;	case Tbig:		disbig(offset, n->val);		break;	case Tstring:		disstring(offset, n->decl->sym);		break;	case Treal:		disreal(offset, n->rval);		break;	case Tadt:	case Tadtpick:	case Ttuple:		id = n->ty->ids;		for(n = n->left; n != nil; n = n->right){			disdatum(offset + id->offset, n->left);			id = id->next;		}		break;	case Tany:		break;	case Tcase:		c = n->ty->cse;		disint(offset, c->nlab);		offset += IBY2WD;		for(i = 0; i < c->nlab; i++){			lab = &c->labs[i];			disint(offset, lab->start->val);			offset += IBY2WD;			disint(offset, lab->stop->val+1);			offset += IBY2WD;			disint(offset, lab->inst->pc);			offset += IBY2WD;		}		disint(offset, c->iwild ? c->iwild->pc : -1);		break;	case Tcasel:		c = n->ty->cse;		disint(offset, c->nlab);		offset += 2*IBY2WD;		for(i = 0; i < c->nlab; i++){			lab = &c->labs[i];			disbig(offset, lab->start->val);			offset += IBY2LG;			disbig(offset, lab->stop->val+1);			offset += IBY2LG;			disint(offset, lab->inst->pc);			offset += 2*IBY2WD;		}		disint(offset, c->iwild ? c->iwild->pc : -1);		break;	case Tcasec:		c = n->ty->cse;		disint(offset, c->nlab);		offset += IBY2WD;		for(i = 0; i < c->nlab; i++){			lab = &c->labs[i];			disstring(offset, lab->start->decl->sym);			offset += IBY2WD;			if(lab->stop != lab->start)				disstring(offset, lab->stop->decl->sym);			offset += IBY2WD;			disint(offset, lab->inst->pc);			offset += IBY2WD;		}		disint(offset, c->iwild ? c->iwild->pc : -1);		break;	case Tgoto:		c = n->ty->cse;		disint(offset, n->ty->size/IBY2WD-1);		offset += IBY2WD;		for(i = 0; i < c->nlab; i++){			disint(offset, c->labs[i].inst->pc);			offset += IBY2WD;		}		if(c->iwild != nil)			disint(offset, c->iwild->pc);		break;	case Tarray:		disflush(-1, -1, 0);		disdata(DEFA, 1);		/* 1 is ignored */		discon(offset);		disword(n->ty->tof->decl->desc->id);		disword(n->left->val); 		if(n->right == nil)			break; 		disdata(DIND, 1);		/* 1 is ignored */		discon(offset);		disword(0); 		c = n->right->ty->cse;		wild = nil;		if(c->wild != nil)			wild = c->wild->right;		last = 0;		esz = n->ty->tof->size;		for(i = 0; i < c->nlab; i++){			e = c->labs[i].start->val;			if(wild != nil){				for(; last < e; last++)					disdatum(esz * last, wild);			}			last = e;			e = c->labs[i].stop->val;			elem = c->labs[i].node->right;			for(; last <= e; last++)				disdatum(esz * last, elem);		}		if(wild != nil)			for(e = n->left->val; last < e; last++)				disdatum(esz * last, wild); 		disflush(-1, -1, 0);		disdata(DAPOP, 1);		/* 1 is ignored */		discon(0); 		break;	case Tiface:		disint(offset, n->val);		offset += IBY2WD;		for(id = n->decl->ty->ids; id != nil; id = id->next){			offset = align(offset, IBY2WD);			disint(offset, sign(id));			offset += IBY2WD; 			if(id->dot->ty->kind == Tadt){				s = id->dot->sym;				disbytes(offset, s->name, s->len);				offset += s->len;				disbyte(offset, '.');				offset++;			}			s = id->sym;			disbytes(offset, s->name, s->len);			offset += s->len;			disbyte(offset, 0);			offset++;		}		break;	default:		nerror(n, "can't dis global %n", n);		break;	}} voiddisexc(Except *es){	int i, n;	Decl *d;	Except *e;	Case *c;	Label *lab; 	n = 0;	for(e = es; e != nil; e = e->next)		if(e->p1->reach || e->p2->reach)			n++;	discon(n);	for(e = es; e != nil; e = e->next){		if(!e->p1->reach && !e->p2->reach)			continue;		c = e->c;		discon(e->d->offset);		discon(getpc(e->p1));		discon(getpc(e->p2));		if(e->desc)			discon(e->desc->id);		else			discon(-1);		discon(c->nlab|(e->ne<<16));		for(i = 0; i < c->nlab; i++){			lab = &c->labs[i];			d = lab->start->decl;			if(lab->start->ty->kind == Texception)				d = d->init->decl;			Bprint(bout, "%s", d->sym->name);			Bputc(bout, '\0');			discon(lab->inst->pc);		}		if(c->iwild == nil)			discon(-1);		else			discon(c->iwild->pc);	}	discon(0);} static voiddisbyte(long off, int v){	disflush(DEFB, off, 1);	cache[ncached++] = v;	ndatum++;} static voiddisbytes(long off, void *v, int n){	disflush(DEFB, off, n);	memmove(&cache[ncached], v, n);	ncached += n;	ndatum += n;} static voiddisint(long off, long v){	disflush(DEFW, off, IBY2WD);	cache[ncached++] = v >> 24;	cache[ncached++] = v >> 16;	cache[ncached++] = v >> 8;	cache[ncached++] = v;	ndatum++;} static voiddisbig(long off, Long v){	ulong iv; 	disflush(DEFL, off, IBY2LG);	iv = v >> 32;	cache[ncached++] = iv >> 24;	cache[ncached++] = iv >> 16;	cache[ncached++] = iv >> 8;	cache[ncached++] = iv;	iv = v;	cache[ncached++] = iv >> 24;	cache[ncached++] = iv >> 16;	cache[ncached++] = iv >> 8;	cache[ncached++] = iv;	ndatum++;} static voiddisreal(long off, Real v){	ulong bv[2];	ulong iv; 	disflush(DEFF, off, IBY2LG);	dtocanon(v, bv);	iv = bv[0];	cache[ncached++] = iv >> 24;	cache[ncached++] = iv >> 16;	cache[ncached++] = iv >> 8;	cache[ncached++] = iv;	iv = bv[1];	cache[ncached++] = iv >> 24;	cache[ncached++] = iv >> 16;	cache[ncached++] = iv >> 8;	cache[ncached++] = iv;	ndatum++;} static voiddisstring(long offset, Sym *sym){	disflush(-1, -1, 0);	disdata(DEFS, sym->len);	discon(offset);	Bwrite(bout, sym->name, sym->len);} static voiddisflush(int kind, long off, long size){	if(kind != lastkind || off != lastoff){		if(lastkind != -1 && ncached){			disdata(lastkind, ndatum);			discon(startoff);			Bwrite(bout, cache, ncached);		}		startoff = off;		lastkind = kind;		ncached = 0;		ndatum = 0;

Lines 1–500 of 638.