mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 01:50:26 +02:00
* group emitting a label of a try-block and restoring the control flow flags
in a single routine, so that both happen at the same time (needed for LLVM where inside a try-block all calls need to be performed using "invoke" and refer to the current try-block/catching label) git-svn-id: trunk@35144 -
This commit is contained in:
parent
a1c0d1a1ff
commit
c0f4e4db34
@ -529,6 +529,12 @@ implementation
|
||||
reasonbuf : treference;
|
||||
end;
|
||||
|
||||
texceptionstate = record
|
||||
exceptionlabel: TAsmLabel;
|
||||
oldflowcontrol,
|
||||
newflowcontrol: tflowcontrol;
|
||||
end;
|
||||
|
||||
|
||||
procedure get_exception_temps(list:TAsmList;var t:texceptiontemps);
|
||||
begin
|
||||
@ -546,12 +552,16 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure new_exception(list:TAsmList;const t:texceptiontemps;exceptlabel:tasmlabel);
|
||||
procedure new_exception(list:TAsmList;const t:texceptiontemps; out exceptstate: texceptionstate);
|
||||
var
|
||||
paraloc1, paraloc2, paraloc3, pushexceptres, setjmpres: tcgpara;
|
||||
pd: tprocdef;
|
||||
tmpresloc: tlocation;
|
||||
begin
|
||||
current_asmdata.getjumplabel(exceptstate.exceptionlabel);
|
||||
exceptstate.oldflowcontrol:=flowcontrol;
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
|
||||
paraloc1.init;
|
||||
paraloc2.init;
|
||||
paraloc3.init;
|
||||
@ -606,11 +616,19 @@ implementation
|
||||
hlcg.g_exception_reason_save(list,setjmpres.def,ossinttype,tmpresloc.register,t.reasonbuf);
|
||||
{ if we get 0 here in the function result register, it means that we
|
||||
longjmp'd back here }
|
||||
hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,tmpresloc.register,exceptlabel);
|
||||
hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,tmpresloc.register,exceptstate.exceptionlabel);
|
||||
setjmpres.resetiftemp;
|
||||
end;
|
||||
|
||||
|
||||
procedure emit_except_label(list: TAsmList; var exceptionstate: texceptionstate);
|
||||
begin
|
||||
hlcg.a_label(list,exceptionstate.exceptionlabel);
|
||||
exceptionstate.newflowcontrol:=flowcontrol;
|
||||
flowcontrol:=exceptionstate.oldflowcontrol;
|
||||
end;
|
||||
|
||||
|
||||
procedure free_exception(list:TAsmList;const t:texceptiontemps;a:aint;endexceptlabel:tasmlabel;onlyfree:boolean);
|
||||
var
|
||||
reasonreg: tregister;
|
||||
@ -643,14 +661,14 @@ implementation
|
||||
|
||||
{ generates code to be executed when another exeception is raised while
|
||||
control is inside except block }
|
||||
procedure handle_nested_exception(list:TAsmList;const t:texceptiontemps;entrylabel:TAsmLabel);
|
||||
procedure handle_nested_exception(list:TAsmList;const t:texceptiontemps;var entrystate: texceptionstate);
|
||||
var
|
||||
exitlabel: tasmlabel;
|
||||
begin
|
||||
{ don't generate line info for internal cleanup }
|
||||
list.concat(tai_marker.create(mark_NoLineInfoStart));
|
||||
current_asmdata.getjumplabel(exitlabel);
|
||||
hlcg.a_label(list,entrylabel);
|
||||
emit_except_label(current_asmdata.CurrAsmList,entrystate);
|
||||
free_exception(list,t,0,exitlabel,false);
|
||||
{ we don't need to save/restore registers here because reraise never }
|
||||
{ returns }
|
||||
@ -671,26 +689,21 @@ implementation
|
||||
exittrylabel,
|
||||
continuetrylabel,
|
||||
breaktrylabel,
|
||||
doobjectdestroyandreraise,
|
||||
oldCurrExitLabel,
|
||||
oldContinueLabel,
|
||||
oldBreakLabel : tasmlabel;
|
||||
oldflowcontrol,tryflowcontrol,
|
||||
exceptflowcontrol : tflowcontrol;
|
||||
destroytemps,
|
||||
excepttemps : texceptiontemps;
|
||||
trystate,doobjectdestroyandreraisestate: texceptionstate;
|
||||
label
|
||||
errorexit;
|
||||
begin
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
exceptflowcontrol:=[];
|
||||
continuetrylabel:=nil;
|
||||
breaktrylabel:=nil;
|
||||
continueexceptlabel:=nil;
|
||||
breakexceptlabel:=nil;
|
||||
|
||||
oldflowcontrol:=flowcontrol;
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
{ this can be called recursivly }
|
||||
oldBreakLabel:=nil;
|
||||
oldContinueLabel:=nil;
|
||||
@ -715,12 +728,11 @@ implementation
|
||||
current_asmdata.getjumplabel(continueexceptlabel);
|
||||
end;
|
||||
|
||||
current_asmdata.getjumplabel(exceptlabel);
|
||||
current_asmdata.getjumplabel(endexceptlabel);
|
||||
current_asmdata.getjumplabel(lastonlabel);
|
||||
|
||||
get_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,exceptlabel);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,trystate);
|
||||
|
||||
{ try block }
|
||||
{ set control flow labels for the try block }
|
||||
@ -731,16 +743,14 @@ implementation
|
||||
current_procinfo.CurrBreakLabel:=breaktrylabel;
|
||||
end;
|
||||
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
secondpass(left);
|
||||
tryflowcontrol:=flowcontrol;
|
||||
if codegenerror then
|
||||
goto errorexit;
|
||||
|
||||
{ don't generate line info for internal cleanup }
|
||||
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
|
||||
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,exceptlabel);
|
||||
emit_except_label(current_asmdata.CurrAsmList,trystate);
|
||||
|
||||
free_exception(current_asmdata.CurrAsmList, excepttemps, 0, endexceptlabel, false);
|
||||
|
||||
@ -778,27 +788,30 @@ implementation
|
||||
|
||||
if not (has_no_code(t1)) then
|
||||
begin
|
||||
current_asmdata.getjumplabel(doobjectdestroyandreraise);
|
||||
|
||||
get_exception_temps(current_asmdata.CurrAsmList,destroytemps);
|
||||
new_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraise);
|
||||
new_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
|
||||
{ the flowcontrol from the default except-block must be merged
|
||||
with the flowcontrol flags potentially set by the
|
||||
on-statements handled above (secondpass(right)), as they are
|
||||
at the same program level }
|
||||
flowcontrol:=
|
||||
flowcontrol+
|
||||
doobjectdestroyandreraisestate.oldflowcontrol;
|
||||
|
||||
|
||||
{ except block needs line info }
|
||||
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
|
||||
|
||||
{ here we don't have to reset flowcontrol }
|
||||
{ the default and on flowcontrols are handled equal }
|
||||
secondpass(t1);
|
||||
exceptflowcontrol:=flowcontrol;
|
||||
|
||||
handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraise);
|
||||
handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraisestate);
|
||||
|
||||
unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
|
||||
end
|
||||
else
|
||||
begin
|
||||
exceptflowcontrol:=flowcontrol;
|
||||
doobjectdestroyandreraisestate.newflowcontrol:=flowcontrol;
|
||||
cleanupobjectstack;
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
|
||||
end;
|
||||
@ -806,10 +819,10 @@ implementation
|
||||
else
|
||||
begin
|
||||
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil);
|
||||
exceptflowcontrol:=flowcontrol;
|
||||
doobjectdestroyandreraisestate.newflowcontrol:=flowcontrol;
|
||||
end;
|
||||
|
||||
if fc_exit in exceptflowcontrol then
|
||||
if fc_exit in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
{ do some magic for exit in the try block }
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
|
||||
@ -821,7 +834,7 @@ implementation
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
|
||||
end;
|
||||
|
||||
if fc_break in exceptflowcontrol then
|
||||
if fc_break in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
|
||||
{ we must also destroy the address frame which guards }
|
||||
@ -832,7 +845,7 @@ implementation
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
|
||||
end;
|
||||
|
||||
if fc_continue in exceptflowcontrol then
|
||||
if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
|
||||
{ we must also destroy the address frame which guards }
|
||||
@ -843,7 +856,7 @@ implementation
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
|
||||
end;
|
||||
|
||||
if fc_exit in tryflowcontrol then
|
||||
if fc_exit in trystate.newflowcontrol then
|
||||
begin
|
||||
{ do some magic for exit in the try block }
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,exittrylabel);
|
||||
@ -852,7 +865,7 @@ implementation
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
|
||||
end;
|
||||
|
||||
if fc_break in tryflowcontrol then
|
||||
if fc_break in trystate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,breaktrylabel);
|
||||
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
|
||||
@ -860,7 +873,7 @@ implementation
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
|
||||
end;
|
||||
|
||||
if fc_continue in tryflowcontrol then
|
||||
if fc_continue in trystate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,continuetrylabel);
|
||||
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
|
||||
@ -886,8 +899,8 @@ implementation
|
||||
end;
|
||||
|
||||
{ return all used control flow statements }
|
||||
flowcontrol:=oldflowcontrol+(exceptflowcontrol +
|
||||
tryflowcontrol - [fc_inflowcontrol]);
|
||||
flowcontrol:=trystate.oldflowcontrol+(doobjectdestroyandreraisestate.newflowcontrol +
|
||||
trystate.newflowcontrol - [fc_inflowcontrol]);
|
||||
end;
|
||||
|
||||
|
||||
@ -899,9 +912,8 @@ implementation
|
||||
breakonlabel,
|
||||
oldCurrExitLabel,
|
||||
oldContinueLabel,
|
||||
doobjectdestroyandreraise,
|
||||
oldBreakLabel : tasmlabel;
|
||||
oldflowcontrol : tflowcontrol;
|
||||
doobjectdestroyandreraisestate: texceptionstate;
|
||||
excepttemps : texceptiontemps;
|
||||
href2: treference;
|
||||
paraloc1 : tcgpara;
|
||||
@ -919,8 +931,6 @@ implementation
|
||||
breakonlabel:=nil;
|
||||
exitonlabel:=nil;
|
||||
|
||||
oldflowcontrol:=flowcontrol;
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
current_asmdata.getjumplabel(nextonlabel);
|
||||
|
||||
otherunit:=findunitsymtable(excepttype.owner).moduleid<>findunitsymtable(current_procinfo.procdef.owner).moduleid;
|
||||
@ -959,12 +969,10 @@ implementation
|
||||
end;
|
||||
|
||||
{ in the case that another exception is risen
|
||||
we've to destroy the old one }
|
||||
current_asmdata.getjumplabel(doobjectdestroyandreraise);
|
||||
|
||||
{ call setjmp, and jump to finally label on non-zero result }
|
||||
we've to destroy the old one:
|
||||
call setjmp, and jump to finally label on non-zero result }
|
||||
get_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraise);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
|
||||
|
||||
oldBreakLabel:=nil;
|
||||
oldContinueLabel:=nil;
|
||||
@ -986,7 +994,7 @@ implementation
|
||||
secondpass(right);
|
||||
end;
|
||||
|
||||
handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraise);
|
||||
handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraisestate);
|
||||
|
||||
{ clear some stuff }
|
||||
if assigned(exceptvarsym) then
|
||||
@ -999,21 +1007,21 @@ implementation
|
||||
if assigned(right) then
|
||||
begin
|
||||
{ special handling for control flow instructions }
|
||||
if fc_exit in flowcontrol then
|
||||
if fc_exit in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
{ the address and object pop does secondtryexcept }
|
||||
cg.a_label(current_asmdata.CurrAsmList,exitonlabel);
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
|
||||
end;
|
||||
|
||||
if fc_break in flowcontrol then
|
||||
if fc_break in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
{ the address and object pop does secondtryexcept }
|
||||
cg.a_label(current_asmdata.CurrAsmList,breakonlabel);
|
||||
cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
|
||||
end;
|
||||
|
||||
if fc_continue in flowcontrol then
|
||||
if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
|
||||
begin
|
||||
{ the address and object pop does secondtryexcept }
|
||||
cg.a_label(current_asmdata.CurrAsmList,continueonlabel);
|
||||
@ -1030,7 +1038,7 @@ implementation
|
||||
|
||||
unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
cg.a_label(current_asmdata.CurrAsmList,nextonlabel);
|
||||
flowcontrol:=oldflowcontrol+(flowcontrol-[fc_inflowcontrol]);
|
||||
flowcontrol:=doobjectdestroyandreraisestate.oldflowcontrol+(doobjectdestroyandreraisestate.newflowcontrol-[fc_inflowcontrol]);
|
||||
paraloc1.done;
|
||||
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
|
||||
|
||||
@ -1071,7 +1079,6 @@ implementation
|
||||
|
||||
procedure tcgtryfinallynode.pass_generate_code;
|
||||
var
|
||||
finallylabel,
|
||||
endfinallylabel,
|
||||
exitfinallylabel,
|
||||
continuefinallylabel,
|
||||
@ -1079,28 +1086,28 @@ implementation
|
||||
oldCurrExitLabel,
|
||||
oldContinueLabel,
|
||||
oldBreakLabel : tasmlabel;
|
||||
oldflowcontrol,tryflowcontrol : tflowcontrol;
|
||||
finallyexceptionstate: texceptionstate;
|
||||
prefinallyflowcontrol : tflowcontrol;
|
||||
excepttemps : texceptiontemps;
|
||||
reasonreg : tregister;
|
||||
begin
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
tryflowcontrol:=[];
|
||||
oldBreakLabel:=nil;
|
||||
oldContinueLabel:=nil;
|
||||
continuefinallylabel:=nil;
|
||||
breakfinallylabel:=nil;
|
||||
|
||||
{ check if child nodes do a break/continue/exit }
|
||||
oldflowcontrol:=flowcontrol;
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
current_asmdata.getjumplabel(finallylabel);
|
||||
current_asmdata.getjumplabel(endfinallylabel);
|
||||
|
||||
{ call setjmp, and jump to finally label on non-zero result }
|
||||
get_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,finallyexceptionstate);
|
||||
|
||||
{ the finally block must catch break, continue and exit }
|
||||
{ statements }
|
||||
oldCurrExitLabel:=current_procinfo.CurrExitLabel;
|
||||
if implicitframe then
|
||||
exitfinallylabel:=finallylabel
|
||||
exitfinallylabel:=finallyexceptionstate.exceptionlabel
|
||||
else
|
||||
current_asmdata.getjumplabel(exitfinallylabel);
|
||||
current_procinfo.CurrExitLabel:=exitfinallylabel;
|
||||
@ -1110,8 +1117,8 @@ implementation
|
||||
oldBreakLabel:=current_procinfo.CurrBreakLabel;
|
||||
if implicitframe then
|
||||
begin
|
||||
breakfinallylabel:=finallylabel;
|
||||
continuefinallylabel:=finallylabel;
|
||||
breakfinallylabel:=finallyexceptionstate.exceptionlabel;
|
||||
continuefinallylabel:=finallyexceptionstate.exceptionlabel;
|
||||
end
|
||||
else
|
||||
begin
|
||||
@ -1122,15 +1129,10 @@ implementation
|
||||
current_procinfo.CurrBreakLabel:=breakfinallylabel;
|
||||
end;
|
||||
|
||||
{ call setjmp, and jump to finally label on non-zero result }
|
||||
get_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
new_exception(current_asmdata.CurrAsmList,excepttemps,finallylabel);
|
||||
|
||||
{ try code }
|
||||
if assigned(left) then
|
||||
begin
|
||||
secondpass(left);
|
||||
tryflowcontrol:=flowcontrol;
|
||||
if codegenerror then
|
||||
exit;
|
||||
end;
|
||||
@ -1138,19 +1140,22 @@ implementation
|
||||
{ don't generate line info for internal cleanup }
|
||||
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
|
||||
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,finallylabel);
|
||||
emit_except_label(current_asmdata.CurrAsmList,finallyexceptionstate);
|
||||
{ just free the frame information }
|
||||
free_exception(current_asmdata.CurrAsmList,excepttemps,1,finallylabel,true);
|
||||
free_exception(current_asmdata.CurrAsmList,excepttemps,1,finallyexceptionstate.exceptionlabel,true);
|
||||
|
||||
{ end cleanup }
|
||||
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoEnd));
|
||||
|
||||
{ finally code }
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
{ finally code (don't unconditionally set fc_inflowcontrol, since the
|
||||
finally code is unconditionally executed; we do have to filter out
|
||||
flags regarding break/contrinue/etc. because we have to give an
|
||||
error in case one of those is used in the finally-code }
|
||||
flowcontrol:=finallyexceptionstate.oldflowcontrol*[fc_inflowcontrol];
|
||||
secondpass(right);
|
||||
{ goto is allowed if it stays inside the finally block,
|
||||
this is checked using the exception block number }
|
||||
if (flowcontrol-[fc_gotolabel])<>[fc_inflowcontrol] then
|
||||
if (flowcontrol-[fc_gotolabel])<>(finallyexceptionstate.oldflowcontrol*[fc_inflowcontrol]) then
|
||||
CGMessage(cg_e_control_flow_outside_finally);
|
||||
if codegenerror then
|
||||
exit;
|
||||
@ -1164,7 +1169,8 @@ implementation
|
||||
if implicitframe then
|
||||
begin
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,0,reasonreg,endfinallylabel);
|
||||
{ finally code only needed to be executed on exception }
|
||||
{ finally code only needed to be executed on exception (-> in
|
||||
if-branch -> fc_inflowcontrol) }
|
||||
flowcontrol:=[fc_inflowcontrol];
|
||||
secondpass(t1);
|
||||
if flowcontrol<>[fc_inflowcontrol] then
|
||||
@ -1180,34 +1186,34 @@ implementation
|
||||
else
|
||||
begin
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,0,reasonreg,endfinallylabel);
|
||||
if fc_exit in tryflowcontrol then
|
||||
if fc_exit in finallyexceptionstate.newflowcontrol then
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,2,reasonreg,oldCurrExitLabel);
|
||||
if fc_break in tryflowcontrol then
|
||||
if fc_break in finallyexceptionstate.newflowcontrol then
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,3,reasonreg,oldBreakLabel);
|
||||
if fc_continue in tryflowcontrol then
|
||||
if fc_continue in finallyexceptionstate.newflowcontrol then
|
||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,4,reasonreg,oldContinueLabel);
|
||||
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil);
|
||||
{ do some magic for exit,break,continue in the try block }
|
||||
if fc_exit in tryflowcontrol then
|
||||
if fc_exit in finallyexceptionstate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,exitfinallylabel);
|
||||
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
|
||||
hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,osuinttype,2,excepttemps.reasonbuf);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallylabel);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallyexceptionstate.exceptionlabel);
|
||||
end;
|
||||
if fc_break in tryflowcontrol then
|
||||
if fc_break in finallyexceptionstate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,breakfinallylabel);
|
||||
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
|
||||
hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,osuinttype,3,excepttemps.reasonbuf);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallylabel);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallyexceptionstate.exceptionlabel);
|
||||
end;
|
||||
if fc_continue in tryflowcontrol then
|
||||
if fc_continue in finallyexceptionstate.newflowcontrol then
|
||||
begin
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,continuefinallylabel);
|
||||
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
|
||||
hlcg.g_exception_reason_save_const(current_asmdata.CurrAsmList,osuinttype,4,excepttemps.reasonbuf);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallylabel);
|
||||
hlcg.a_jmp_always(current_asmdata.CurrAsmList,finallyexceptionstate.exceptionlabel);
|
||||
end;
|
||||
end;
|
||||
unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
|
||||
@ -1222,7 +1228,7 @@ implementation
|
||||
current_procinfo.CurrContinueLabel:=oldContinueLabel;
|
||||
current_procinfo.CurrBreakLabel:=oldBreakLabel;
|
||||
end;
|
||||
flowcontrol:=oldflowcontrol+(tryflowcontrol-[fc_inflowcontrol]);
|
||||
flowcontrol:=finallyexceptionstate.oldflowcontrol+(finallyexceptionstate.newflowcontrol-[fc_inflowcontrol]);
|
||||
end;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user