## Maintain information about 'finally' blocks.# Finally: adt { npc: int; # Java pc of finally entry (jsr target) xpc: int; # Java pc of finally exit (ret) n: int; # number of jsr slots in gototbl gototbl: array of int; # goto jump table off: int; # mp offset to gototbl next: cyclic ref Finally;}; finally: ref Finally; # linked list of finally block records ## Get record for finally block whose entry point is pc.# getfinally(pc: int): ref Finally{ f: ref Finally; for(f = finally; f != nil; f = f.next) { if(f.npc == pc) return f; } return nil;} ## Count jsr's to the finally block whose entry point is pc.# finallyentry(pc: int){ f: ref Finally; f = getfinally(pc); if(f == nil) { f = ref Finally(pc, 0, 0, nil, 0, finally); finally = f; } f.n += 1;} ## Allocate the gototbl's and pass them to mdata.c.# finallyalloc(){ f: ref Finally; for(f = finally; f != nil; f = f.next) { f.gototbl = array [f.n] of { * => 0 }; f.off = mpgoto(f.n, f.gototbl); }} ## Fix up operands of a Dis movw that implements Java jsr/jsr_w.# jsrfixup(s: ref Addr, d: ref Addr, dispc: int, javapc: int){ f: ref Finally; i: int; 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: " + string dispc + ", " + string javapc); s.ival = i; d.offset = f.off + f.n*IBY2WD;} ## Fix up operands of a Dis goto that implements Java ret.# retfixup(s: ref Addr, d: ref Addr, retpc: int){ fi, f: ref Finally; f = nil; for(fi = finally; fi != nil; fi = fi.next) { if(fi.xpc == 0 && fi.npc < retpc && (f == nil || f.npc < fi.npc)) { f = fi; } } if(f == nil) fatal("retfixup: " + string retpc); f.xpc = retpc; # claim this finally block for this 'ret' s.offset = f.off + f.n*IBY2WD; d.offset = f.off;} ## Free finally information after each method is translated.# finallyfree(){ finally = nil;}
#
# Maintain information about 'finally' blocks.
#
Finally: adt {
npc: int; # Java pc of finally entry (jsr target)
xpc: int; # Java pc of finally exit (ret)
n: int; # number of jsr slots in gototbl
gototbl: array of int; # goto jump table
off: int; # mp offset to gototbl
next: cyclic ref Finally;
};
finally: ref Finally; # linked list of finally block records
#
# Get record for finally block whose entry point is pc.
#
getfinally(pc: int): ref Finally
{
f: ref Finally;
for(f = finally; f != nil; f = f.next) {
if(f.npc == pc)
return f;
}
return nil;
}
#
# Count jsr's to the finally block whose entry point is pc.
#
finallyentry(pc: int)
{
f: ref Finally;
f = getfinally(pc);
if(f == nil) {
f = ref Finally(pc, 0, 0, nil, 0, finally);
finally = f;
}
f.n += 1;
}
#
# Allocate the gototbl's and pass them to mdata.c.
#
finallyalloc()
{
f: ref Finally;
for(f = finally; f != nil; f = f.next) {
f.gototbl = array [f.n] of { * => 0 };
f.off = mpgoto(f.n, f.gototbl);
}
}
#
# Fix up operands of a Dis movw that implements Java jsr/jsr_w.
#
jsrfixup(s: ref Addr, d: ref Addr, dispc: int, javapc: int)
{
f: ref Finally;
i: int;
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: " + string dispc + ", " + string javapc);
s.ival = i;
d.offset = f.off + f.n*IBY2WD;
}
#
# Fix up operands of a Dis goto that implements Java ret.
#
retfixup(s: ref Addr, d: ref Addr, retpc: int)
{
fi, f: ref Finally;
f = nil;
for(fi = finally; fi != nil; fi = fi.next) {
if(fi.xpc == 0 && fi.npc < retpc
&& (f == nil || f.npc < fi.npc)) {
f = fi;
}
}
if(f == nil)
fatal("retfixup: " + string retpc);
f.xpc = retpc; # claim this finally block for this 'ret'
s.offset = f.off + f.n*IBY2WD;
d.offset = f.off;
}
#
# Free finally information after each method is translated.
#
finallyfree()
{
finally = nil;
}