132 lines · 2.1 KB · C
RawDownload
#include "java.h" /* * Maintain information about 'finally' blocks. */ typedef	struct	Finally	Finally; static	Finally	*finally;	/* linked list of finally block records */ struct Finally {	int	npc;		/* Java pc of finally entry (jsr target) */	int	xpc;		/* Java pc of finally exit (ret) */	int	n;		/* number of jsr slots in gototbl */	int	*gototbl;	/* goto jump table */	int	off;		/* mp offset to gototbl */	Finally	*next;}; /* * Get record for finally block whose entry point is pc. */ static Finally*getfinally(int pc){	Finally *f; 	for(f = finally; f; f = f->next) {		if(f->npc == pc)			return f;	}	return nil;} /* * Count jsr's to the finally block whose entry point is pc. */ voidfinallyentry(int pc){	Finally *f; 	f = getfinally(pc);	if(f == nil) {		f = Malloc(sizeof(Finally));		f->npc = pc;		f->xpc = 0;		f->n = 0;		f->next = finally;		finally = f;	}	f->n += 1;} /* * Allocate the gototbl's and pass them to mdata.c. */ voidfinallyalloc(void){	Finally *f; 	for(f = finally; f; f = f->next) {		f->gototbl = Mallocz(f->n*sizeof(int));		f->off = mpgoto(f->n, f->gototbl);	}} /* * Fix up operands of a Dis movw that implements Java jsr/jsr_w. */ voidjsrfixup(Addr *s, Addr *d, int dispc, int javapc){	Finally *f;	int i; 	f = getfinally(javapc);	for(i = 0; i < f->n; i++) {		if(f->gototbl[i] == 0) {			f->gototbl[i] = dispc;			break;		}	}	if(i == f->n)		fatal("jsrfixup: %d, %d\n", dispc, javapc);	s->u.ival = i;	d->u.offset = f->off + f->n*IBY2WD;} /* * Fix up operands of a Dis goto that implements Java ret. */ voidretfixup(Addr *s, Addr *d, int retpc){	Finally *fi, *f; 	f = nil;	for(fi = finally; fi; fi = fi->next) {		if(fi->xpc == 0 && fi->npc < retpc		&& (f == nil || f->npc < fi->npc)) {			f = fi;		}	}	if(f == nil)		fatal("retfixup: %d\n", retpc);	f->xpc = retpc;		/* claim this finally block for this 'ret' */	s->u.offset = f->off + f->n*IBY2WD;	d->u.offset = f->off;} /* * Free finally information after each method is translated. */ voidfinallyfree(void){	Finally *f, *f2; 	for(f = finally; f; f = f2) {		f2 = f->next;		free(f);	}	finally = nil;}