|
@@ -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;
|
|
|
|
|
|
|