#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;}
#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.
*/
void
finallyentry(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.
*/
void
finallyalloc(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.
*/
void
jsrfixup(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.
*/
void
retfixup(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.
*/
void
finallyfree(void)
{
Finally *f, *f2;
for(f = finally; f; f = f2) {
f2 = f->next;
free(f);
}
finally = nil;
}