* big update for exception handling code generation: possible mem holes

fixed, break/continue/exit should work always now as expected
This commit is contained in:
florian 2000-02-10 23:44:42 +00:00
parent ec8222a642
commit 05e486a068
4 changed files with 402 additions and 108 deletions

View File

@ -40,6 +40,13 @@ interface
procedure secondon(var p : ptree); procedure secondon(var p : ptree);
procedure secondfail(var p : ptree); procedure secondfail(var p : ptree);
type
tenumflowcontrol = (fc_exit,fc_break,fc_continue);
tflowcontrol = set of tenumflowcontrol;
var
flowcontrol : tflowcontrol;
implementation implementation
uses uses
@ -102,6 +109,8 @@ implementation
aktcontinuelabel:=oldclabel; aktcontinuelabel:=oldclabel;
aktbreaklabel:=oldblabel; aktbreaklabel:=oldblabel;
{ a break/continue in a while/repeat block can't be seen outside }
flowcontrol:=flowcontrol-[fc_break,fc_continue];
end; end;
@ -363,6 +372,8 @@ implementation
aktcontinuelabel:=oldclabel; aktcontinuelabel:=oldclabel;
aktbreaklabel:=oldblabel; aktbreaklabel:=oldblabel;
{ a break/continue in a for block can't be seen outside }
flowcontrol:=flowcontrol-[fc_break,fc_continue];
end; end;
@ -379,6 +390,7 @@ implementation
label label
do_jmp; do_jmp;
begin begin
include(flowcontrol,fc_exit);
if assigned(p^.left) then if assigned(p^.left) then
if p^.left^.treetype=assignn then if p^.left^.treetype=assignn then
begin begin
@ -482,6 +494,7 @@ do_jmp:
procedure secondbreakn(var p : ptree); procedure secondbreakn(var p : ptree);
begin begin
include(flowcontrol,fc_break);
if aktbreaklabel<>nil then if aktbreaklabel<>nil then
emitjmp(C_None,aktbreaklabel) emitjmp(C_None,aktbreaklabel)
else else
@ -495,6 +508,7 @@ do_jmp:
procedure secondcontinuen(var p : ptree); procedure secondcontinuen(var p : ptree);
begin begin
include(flowcontrol,fc_continue);
if aktcontinuelabel<>nil then if aktcontinuelabel<>nil then
emitjmp(C_None,aktcontinuelabel) emitjmp(C_None,aktcontinuelabel)
else else
@ -585,6 +599,32 @@ do_jmp:
var var
endexceptlabel : pasmlabel; endexceptlabel : pasmlabel;
{ does the necessary things to clean up the object stack }
{ in the except block }
procedure cleanupobjectstack;
begin
emitcall('FPC_POPOBJECTSTACK');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_PUSH,S_L,R_EAX);
emitcall('FPC_DESTROYEXCEPTION');
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
maybe_loadesi;
end;
{ pops one element from the exception address stack }
{ and removes the flag }
procedure cleanupaddrstack;
begin
emitcall('FPC_POPADDRSTACK');
{ allocate eax }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_POP,S_L,R_EAX);
{ deallocate eax }
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
end;
procedure secondtryexcept(var p : ptree); procedure secondtryexcept(var p : ptree);
var var
@ -593,32 +633,50 @@ do_jmp:
exitexceptlabel, exitexceptlabel,
continueexceptlabel, continueexceptlabel,
breakexceptlabel, breakexceptlabel,
exittrylabel,
continuetrylabel,
breaktrylabel,
doobjectdestroy,
doobjectdestroyandreraise,
oldaktexitlabel, oldaktexitlabel,
oldaktexit2label, oldaktexit2label,
oldaktcontinuelabel, oldaktcontinuelabel,
oldaktbreaklabel : pasmlabel; oldaktbreaklabel : pasmlabel;
oldexceptblock : ptree; oldexceptblock : ptree;
oldflowcontrol,tryflowcontrol,
exceptflowcontrol : tflowcontrol;
begin begin
oldflowcontrol:=flowcontrol;
flowcontrol:=[];
{ this can be called recursivly } { this can be called recursivly }
oldendexceptlabel:=endexceptlabel; oldendexceptlabel:=endexceptlabel;
{ we modify EAX } { we modify EAX }
usedinproc:=usedinproc or ($80 shr byte(R_EAX)); usedinproc:=usedinproc or ($80 shr byte(R_EAX));
{ save the old labels for control flow statements }
oldaktexitlabel:=aktexitlabel; oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label; oldaktexit2label:=aktexit2label;
getlabel(exitexceptlabel);
aktexitlabel:=exitexceptlabel;
aktexit2label:=exitexceptlabel;
if assigned(aktbreaklabel) then if assigned(aktbreaklabel) then
begin begin
oldaktcontinuelabel:=aktcontinuelabel; oldaktcontinuelabel:=aktcontinuelabel;
oldaktbreaklabel:=aktbreaklabel; oldaktbreaklabel:=aktbreaklabel;
end;
{ get new labels for the control flow statements }
getlabel(exittrylabel);
getlabel(exitexceptlabel);
if assigned(aktbreaklabel) then
begin
getlabel(breaktrylabel);
getlabel(continuetrylabel);
getlabel(breakexceptlabel); getlabel(breakexceptlabel);
getlabel(continueexceptlabel); getlabel(continueexceptlabel);
aktcontinuelabel:=continueexceptlabel;
aktbreaklabel:=breakexceptlabel;
end; end;
getlabel(exceptlabel); getlabel(exceptlabel);
getlabel(doexceptlabel); getlabel(doexceptlabel);
getlabel(endexceptlabel); getlabel(endexceptlabel);
@ -635,23 +693,48 @@ do_jmp:
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_NE,exceptlabel); emitjmp(C_NE,exceptlabel);
{ try code } { try block }
{ set control flow labels for the try block }
aktexitlabel:=exittrylabel;
aktexit2label:=exittrylabel;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=continuetrylabel;
aktbreaklabel:=breaktrylabel;
end;
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
aktexceptblock:=p^.left; aktexceptblock:=p^.left;
flowcontrol:=[];
secondpass(p^.left); secondpass(p^.left);
tryflowcontrol:=flowcontrol;
aktexceptblock:=oldexceptblock; aktexceptblock:=oldexceptblock;
if codegenerror then if codegenerror then
exit; exit;
emitlab(exceptlabel); emitlab(exceptlabel);
emitcall('FPC_POPADDRSTACK'); emitcall('FPC_POPADDRSTACK');
{ allocate eax }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_POP,S_L,R_EAX); emit_reg(A_POP,S_L,R_EAX);
emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX); emit_reg_reg(A_TEST,S_L,R_EAX,R_EAX);
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_E,endexceptlabel); emitjmp(C_E,endexceptlabel);
emitlab(doexceptlabel); emitlab(doexceptlabel);
{ set control flow labels for the except block }
{ and the on statements }
aktexitlabel:=exitexceptlabel;
aktexit2label:=exitexceptlabel;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=continueexceptlabel;
aktbreaklabel:=breakexceptlabel;
end;
flowcontrol:=[];
{ on statements }
if assigned(p^.right) then if assigned(p^.right) then
begin begin
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
@ -661,7 +744,7 @@ do_jmp:
end; end;
emitlab(lastonlabel); emitlab(lastonlabel);
{ default handling } { default handling except handling }
if assigned(p^.t1) then if assigned(p^.t1) then
begin begin
{ FPC_CATCHES must be called with { FPC_CATCHES must be called with
@ -669,72 +752,154 @@ do_jmp:
} }
push_int (-1); push_int (-1);
emitcall('FPC_CATCHES'); emitcall('FPC_CATCHES');
if assigned(p^.t1) then
begin
maybe_loadesi; maybe_loadesi;
{ the destruction of the exception object must be also }
{ guarded by an exception frame }
getlabel(doobjectdestroy);
getlabel(doobjectdestroyandreraise);
exprasmlist^.concat(new(paicpu,op_const(A_PUSH,S_L,1)));
emitcall('FPC_PUSHEXCEPTADDR');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_PUSH,S_L,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitcall('FPC_SETJMP');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_PUSH,S_L,R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg_reg(A_TEST,S_L,R_EAX,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_NE,doobjectdestroyandreraise);
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
aktexceptblock:=p^.t1; aktexceptblock:=p^.t1;
{ here we don't have to reset flowcontrol }
{ the default and on flowcontrols are handled equal }
secondpass(p^.t1); secondpass(p^.t1);
exceptflowcontrol:=flowcontrol;
aktexceptblock:=oldexceptblock; aktexceptblock:=oldexceptblock;
end;
emitcall('FPC_POPOBJECTSTACK'); emitlab(doobjectdestroyandreraise);
maybe_loadesi; emitcall('FPC_POPADDRSTACK');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_POP,S_L,R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg_reg(A_TEST,S_L,R_EAX,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_E,doobjectdestroy);
emitcall('FPC_POPSECONDOBJECTSTACK');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_PUSH,S_L,R_EAX);
emitcall('FPC_DESTROYEXCEPTION');
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
{ we don't need to restore esi here because reraise never }
{ returns }
emitcall('FPC_RERAISE');
emitlab(doobjectdestroy);
cleanupobjectstack;
emitjmp(C_None,endexceptlabel);
end end
else else
begin
emitcall('FPC_RERAISE'); emitcall('FPC_RERAISE');
{ deallocate eax } exceptflowcontrol:=flowcontrol;
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); end;
if fc_exit in exceptflowcontrol then
begin
{ do some magic for exit in the try block } { do some magic for exit in the try block }
emitlab(exitexceptlabel); emitlab(exitexceptlabel);
emitcall('FPC_POPADDRSTACK'); { we must also destroy the address frame which guards }
{ allocate eax } { exception object }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); cleanupaddrstack;
emit_reg(A_POP,S_L,R_EAX); cleanupobjectstack;
emitjmp(C_None,oldaktexitlabel); emitjmp(C_None,oldaktexitlabel);
{ deallocate eax } end;
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
if assigned(aktbreaklabel) then if fc_break in exceptflowcontrol then
begin begin
emitlab(breakexceptlabel); emitlab(breakexceptlabel);
emitcall('FPC_POPADDRSTACK'); { we must also destroy the address frame which guards }
{ allocate eax } { exception object }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); cleanupaddrstack;
emit_reg(A_POP,S_L,R_EAX); cleanupobjectstack;
{ deallocate eax }
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_None,oldaktbreaklabel); emitjmp(C_None,oldaktbreaklabel);
end;
if fc_continue in exceptflowcontrol then
begin
emitlab(continueexceptlabel); emitlab(continueexceptlabel);
emitcall('FPC_POPADDRSTACK'); { we must also destroy the address frame which guards }
{ allocate eax } { exception object }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); cleanupaddrstack;
emit_reg(A_POP,S_L,R_EAX); cleanupobjectstack;
{ deallocate eax } emitjmp(C_None,oldaktcontinuelabel);
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); end;
if fc_exit in tryflowcontrol then
begin
{ do some magic for exit in the try block }
emitlab(exittrylabel);
cleanupaddrstack;
emitjmp(C_None,oldaktexitlabel);
end;
if fc_break in tryflowcontrol then
begin
emitlab(breaktrylabel);
cleanupaddrstack;
emitjmp(C_None,oldaktbreaklabel);
end;
if fc_continue in tryflowcontrol then
begin
emitlab(continuetrylabel);
cleanupaddrstack;
emitjmp(C_None,oldaktcontinuelabel); emitjmp(C_None,oldaktcontinuelabel);
end; end;
emitlab(endexceptlabel); emitlab(endexceptlabel);
endexceptlabel:=oldendexceptlabel; endexceptlabel:=oldendexceptlabel;
{ restore the control flow labels }
aktexitlabel:=oldaktexitlabel; aktexitlabel:=oldaktexitlabel;
aktexit2label:=oldaktexit2label; aktexit2label:=oldaktexit2label;
if assigned(aktbreaklabel) then if assigned(oldaktbreaklabel) then
begin begin
aktcontinuelabel:=oldaktcontinuelabel; aktcontinuelabel:=oldaktcontinuelabel;
aktbreaklabel:=oldaktbreaklabel; aktbreaklabel:=oldaktbreaklabel;
end; end;
{ return all used control flow statements }
flowcontrol:=oldflowcontrol+exceptflowcontrol+
tryflowcontrol;
end; end;
procedure secondon(var p : ptree); procedure secondon(var p : ptree);
var var
nextonlabel : pasmlabel; nextonlabel,
exitonlabel,
continueonlabel,
breakonlabel,
oldaktexitlabel,
oldaktexit2label,
oldaktcontinuelabel,
doobjectdestroyandreraise,
doobjectdestroy,
oldaktbreaklabel : pasmlabel;
ref : treference; ref : treference;
oldexceptblock : ptree; oldexceptblock : ptree;
oldflowcontrol : tflowcontrol;
begin begin
oldflowcontrol:=flowcontrol;
flowcontrol:=[];
getlabel(nextonlabel); getlabel(nextonlabel);
{ push the vmt } { push the vmt }
@ -757,8 +922,41 @@ do_jmp:
{ deallocate eax } { deallocate eax }
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
{ in the case that another exception is risen }
{ we've to destroy the old one }
getlabel(doobjectdestroyandreraise);
exprasmlist^.concat(new(paicpu,op_const(A_PUSH,S_L,1)));
emitcall('FPC_PUSHEXCEPTADDR');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_PUSH,S_L,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitcall('FPC_SETJMP');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_PUSH,S_L,R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg_reg(A_TEST,S_L,R_EAX,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_NE,doobjectdestroyandreraise);
if assigned(p^.right) then if assigned(p^.right) then
begin begin
oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label;
getlabel(exitonlabel);
aktexitlabel:=exitonlabel;
aktexit2label:=exitonlabel;
if assigned(aktbreaklabel) then
begin
oldaktcontinuelabel:=aktcontinuelabel;
oldaktbreaklabel:=aktbreaklabel;
getlabel(breakonlabel);
getlabel(continueonlabel);
aktcontinuelabel:=continueonlabel;
aktbreaklabel:=breakonlabel;
end;
{ esi is destroyed by FPC_CATCHES } { esi is destroyed by FPC_CATCHES }
maybe_loadesi; maybe_loadesi;
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
@ -766,17 +964,66 @@ do_jmp:
secondpass(p^.right); secondpass(p^.right);
aktexceptblock:=oldexceptblock; aktexceptblock:=oldexceptblock;
end; end;
getlabel(doobjectdestroy);
emitlab(doobjectdestroyandreraise);
emit_ref(A_PUSH,S_L,newreference(ref)); emitcall('FPC_POPADDRSTACK');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg(A_POP,S_L,R_EAX)));
exprasmlist^.concat(new(paicpu,
op_reg_reg(A_TEST,S_L,R_EAX,R_EAX)));
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitjmp(C_E,doobjectdestroy);
emitcall('FPC_POPSECONDOBJECTSTACK');
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_PUSH,S_L,R_EAX);
emitcall('FPC_DESTROYEXCEPTION'); emitcall('FPC_DESTROYEXCEPTION');
emitcall('FPC_POPOBJECTSTACK'); exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
maybe_loadesi; { we don't need to restore esi here because reraise never }
{ returns }
emitcall('FPC_RERAISE');
emitlab(doobjectdestroy);
cleanupobjectstack;
{ clear some stuff } { clear some stuff }
ungetiftemp(ref); ungetiftemp(ref);
emitjmp(C_None,endexceptlabel); emitjmp(C_None,endexceptlabel);
if assigned(p^.right) then
begin
{ special handling for control flow instructions }
if fc_exit in flowcontrol then
begin
{ the address and object pop does secondtryexcept }
emitlab(exitonlabel);
emitjmp(C_None,oldaktexitlabel);
end;
if fc_break in flowcontrol then
begin
{ the address and object pop does secondtryexcept }
emitlab(breakonlabel);
emitjmp(C_None,oldaktbreaklabel);
end;
if fc_continue in flowcontrol then
begin
{ the address and object pop does secondtryexcept }
emitlab(continueonlabel);
emitjmp(C_None,oldaktcontinuelabel);
end;
aktexitlabel:=oldaktexitlabel;
aktexit2label:=oldaktexit2label;
if assigned(oldaktbreaklabel) then
begin
aktcontinuelabel:=oldaktcontinuelabel;
aktbreaklabel:=oldaktbreaklabel;
end;
end;
emitlab(nextonlabel); emitlab(nextonlabel);
flowcontrol:=oldflowcontrol+flowcontrol;
{ next on node } { next on node }
if assigned(p^.left) then if assigned(p^.left) then
secondpass(p^.left); secondpass(p^.left);
@ -800,15 +1047,23 @@ do_jmp:
oldaktcontinuelabel, oldaktcontinuelabel,
oldaktbreaklabel : pasmlabel; oldaktbreaklabel : pasmlabel;
oldexceptblock : ptree; oldexceptblock : ptree;
oldflowcontrol,tryflowcontrol : tflowcontrol;
decconst : longint;
begin begin
{ check if child nodes do a break/continue/exit }
oldflowcontrol:=flowcontrol;
flowcontrol:=[];
{ we modify EAX } { we modify EAX }
usedinproc:=usedinproc or ($80 shr byte(R_EAX)); usedinproc:=usedinproc or ($80 shr byte(R_EAX));
getlabel(finallylabel); getlabel(finallylabel);
getlabel(endfinallylabel); getlabel(endfinallylabel);
getlabel(reraiselabel);
{ the finally block must catch break, continue and exit }
{ statements }
oldaktexitlabel:=aktexitlabel; oldaktexitlabel:=aktexitlabel;
oldaktexit2label:=aktexit2label; oldaktexit2label:=aktexit2label;
getlabel(reraiselabel);
getlabel(exitfinallylabel); getlabel(exitfinallylabel);
aktexitlabel:=exitfinallylabel; aktexitlabel:=exitfinallylabel;
aktexit2label:=exitfinallylabel; aktexit2label:=exitfinallylabel;
@ -840,6 +1095,7 @@ do_jmp:
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
aktexceptblock:=p^.left; aktexceptblock:=p^.left;
secondpass(p^.left); secondpass(p^.left);
tryflowcontrol:=flowcontrol;
if codegenerror then if codegenerror then
exit; exit;
aktexceptblock:=oldexceptblock; aktexceptblock:=oldexceptblock;
@ -850,7 +1106,10 @@ do_jmp:
{ finally code } { finally code }
oldexceptblock:=aktexceptblock; oldexceptblock:=aktexceptblock;
aktexceptblock:=p^.right; aktexceptblock:=p^.right;
flowcontrol:=[];
secondpass(p^.right); secondpass(p^.right);
if flowcontrol<>[] then
CGMessage(cg_e_control_flow_outside_finally);
aktexceptblock:=oldexceptblock; aktexceptblock:=oldexceptblock;
if codegenerror then if codegenerror then
exit; exit;
@ -861,28 +1120,43 @@ do_jmp:
emitjmp(C_E,endfinallylabel); emitjmp(C_E,endfinallylabel);
emit_reg(A_DEC,S_L,R_EAX); emit_reg(A_DEC,S_L,R_EAX);
emitjmp(C_Z,reraiselabel); emitjmp(C_Z,reraiselabel);
emit_reg(A_DEC,S_L,R_EAX); if fc_exit in tryflowcontrol then
emitjmp(C_Z,oldaktexitlabel);
if assigned(aktbreaklabel) then
begin begin
emit_reg(A_DEC,S_L,R_EAX); emit_reg(A_DEC,S_L,R_EAX);
emitjmp(C_Z,oldaktexitlabel);
decconst:=1;
end
else
decconst:=2;
if fc_break in tryflowcontrol then
begin
emit_const_reg(A_SUB,S_L,decconst,R_EAX);
emitjmp(C_Z,oldaktbreaklabel); emitjmp(C_Z,oldaktbreaklabel);
emit_reg(A_DEC,S_L,R_EAX); decconst:=1;
end
else
inc(decconst);
if fc_continue in tryflowcontrol then
begin
emit_const_reg(A_SUB,S_L,decconst,R_EAX);
emitjmp(C_Z,oldaktcontinuelabel); emitjmp(C_Z,oldaktcontinuelabel);
end; end;
{ deallocate eax } { deallocate eax }
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emitlab(reraiselabel); emitlab(reraiselabel);
emitcall('FPC_RERAISE'); emitcall('FPC_RERAISE');
{ do some magic for exit,break,continue in the try block } { do some magic for exit,break,continue in the try block }
if fc_exit in tryflowcontrol then
begin
emitlab(exitfinallylabel); emitlab(exitfinallylabel);
{ allocate eax } { allocate eax }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_POP,S_L,R_EAX); emit_reg(A_POP,S_L,R_EAX);
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_const(A_PUSH,S_L,2); emit_const(A_PUSH,S_L,2);
emitjmp(C_NONE,finallylabel); emitjmp(C_NONE,finallylabel);
if assigned(aktbreaklabel) then end;
if fc_break in tryflowcontrol then
begin begin
emitlab(breakfinallylabel); emitlab(breakfinallylabel);
{ allocate eax } { allocate eax }
@ -892,11 +1166,12 @@ do_jmp:
exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,dealloc(R_EAX)));
emit_const(A_PUSH,S_L,3); emit_const(A_PUSH,S_L,3);
emitjmp(C_NONE,finallylabel); emitjmp(C_NONE,finallylabel);
end;
if fc_continue in tryflowcontrol then
begin
emitlab(continuefinallylabel); emitlab(continuefinallylabel);
{ allocate eax }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_reg(A_POP,S_L,R_EAX); emit_reg(A_POP,S_L,R_EAX);
{ deallocate eax }
exprasmlist^.concat(new(pairegalloc,alloc(R_EAX))); exprasmlist^.concat(new(pairegalloc,alloc(R_EAX)));
emit_const(A_PUSH,S_L,4); emit_const(A_PUSH,S_L,4);
emitjmp(C_NONE,finallylabel); emitjmp(C_NONE,finallylabel);
@ -911,6 +1186,7 @@ do_jmp:
aktcontinuelabel:=oldaktcontinuelabel; aktcontinuelabel:=oldaktcontinuelabel;
aktbreaklabel:=oldaktbreaklabel; aktbreaklabel:=oldaktbreaklabel;
end; end;
flowcontrol:=oldflowcontrol+tryflowcontrol;
end; end;
@ -927,7 +1203,11 @@ do_jmp:
end. end.
{ {
$Log$ $Log$
Revision 1.68 2000-02-09 13:22:47 peter Revision 1.69 2000-02-10 23:44:42 florian
* big update for exception handling code generation: possible mem holes
fixed, break/continue/exit should work always now as expected
Revision 1.68 2000/02/09 13:22:47 peter
* log truncated * log truncated
Revision 1.67 2000/01/21 12:17:42 jonas Revision 1.67 2000/01/21 12:17:42 jonas
@ -1005,4 +1285,6 @@ end.
Revision 1.48 1999/09/07 07:56:37 peter Revision 1.48 1999/09/07 07:56:37 peter
* reload esi in except block to allow virtual methods * reload esi in except block to allow virtual methods
Revision 1.47 1999/08/25 11:59:42 jonas
* changed pai386, paippc and paiapha (same for tai*) to paicpu (taicpu)
} }

View File

@ -3471,7 +3471,7 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
{ do we need to handle exceptions because of ansi/widestrings ? } { do we need to handle exceptions because of ansi/widestrings ? }
if (procinfo^.flags and pi_needs_implicit_finally)<>0 then if (procinfo^.flags and pi_needs_implicit_finally)<>0 then
begin begin
{ the excpetion helper routines modify all registers } { the exception helper routines modify all registers }
aktprocsym^.definition^.usedregisters:=$ff; aktprocsym^.definition^.usedregisters:=$ff;
getlabel(noreraiselabel); getlabel(noreraiselabel);
@ -3740,7 +3740,11 @@ procedure mov_reg_to_dest(p : ptree; s : topsize; reg : tregister);
end. end.
{ {
$Log$ $Log$
Revision 1.80 2000-02-09 17:36:10 jonas Revision 1.81 2000-02-10 23:44:43 florian
* big update for exception handling code generation: possible mem holes
fixed, break/continue/exit should work always now as expected
Revision 1.80 2000/02/09 17:36:10 jonas
* added missing regalloc for ecx in range check code * added missing regalloc for ecx in range check code
Revision 1.79 2000/02/09 13:22:50 peter Revision 1.79 2000/02/09 13:22:50 peter

View File

@ -550,8 +550,8 @@ implementation
label label
nextreg; nextreg;
begin begin
{!!!!!!!! temptoremove:=nil; }
cleartempgen; cleartempgen;
flowcontrol:=[];
{ when size optimization only count occurrence } { when size optimization only count occurrence }
if cs_littlesize in aktglobalswitches then if cs_littlesize in aktglobalswitches then
t_times:=1 t_times:=1
@ -608,7 +608,6 @@ implementation
end; end;
end; end;
*) *)
{ $ifdef dummy}
if (p^.registers32<4) then if (p^.registers32<4) then
begin begin
for i:=1 to maxvarregs do for i:=1 to maxvarregs do
@ -725,7 +724,6 @@ implementation
end; end;
end; end;
end; end;
{ $endif dummy}
if ((p^.registersfpu+1)<maxfpuvarregs) then if ((p^.registersfpu+1)<maxfpuvarregs) then
begin begin
for i:=1 to maxfpuvarregs do for i:=1 to maxfpuvarregs do
@ -834,7 +832,11 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.56 2000-02-09 13:22:55 peter Revision 1.57 2000-02-10 23:44:43 florian
* big update for exception handling code generation: possible mem holes
fixed, break/continue/exit should work always now as expected
Revision 1.56 2000/02/09 13:22:55 peter
* log truncated * log truncated
Revision 1.55 2000/02/05 15:57:58 florian Revision 1.55 2000/02/05 15:57:58 florian

View File

@ -121,6 +121,9 @@ uses
{$endif} {$endif}
{$ifdef go32v2} {$ifdef go32v2}
catch, catch,
{$ifdef nocatch}
lineinfo,
{$endif nocatch}
{$endif} {$endif}
{$endif FPC} {$endif FPC}
globals,compiler globals,compiler
@ -273,7 +276,11 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.54 2000-02-09 13:22:59 peter Revision 1.55 2000-02-10 23:44:43 florian
* big update for exception handling code generation: possible mem holes
fixed, break/continue/exit should work always now as expected
Revision 1.54 2000/02/09 13:22:59 peter
* log truncated * log truncated
Revision 1.53 2000/01/07 01:14:30 peter Revision 1.53 2000/01/07 01:14:30 peter
@ -306,5 +313,4 @@ end.
Revision 1.45 1999/08/04 00:23:18 florian Revision 1.45 1999/08/04 00:23:18 florian
* renamed i386asm and i386base to cpuasm and cpubase * renamed i386asm and i386base to cpuasm and cpubase
} }