* for setjmp based exception handling, get the type of the exception reason from the setjmp result

git-svn-id: trunk@48828 -
This commit is contained in:
florian 2021-02-27 16:47:36 +00:00
parent 58171b4308
commit 4c2e0b9ff0
4 changed files with 27 additions and 20 deletions

View File

@ -131,10 +131,12 @@ unit cgexcept;
class procedure tcgexceptionstatehandler.get_exception_temps(list:TAsmList;var t:texceptiontemps); class procedure tcgexceptionstatehandler.get_exception_temps(list:TAsmList;var t:texceptiontemps);
begin begin
if not assigned(setjmpresulttype) then
setjmpresulttype:=search_system_proc('fpc_setjmp').returndef;
tg.gethltemp(list,rec_exceptaddr,rec_exceptaddr.size,tt_persistent,t.envbuf); tg.gethltemp(list,rec_exceptaddr,rec_exceptaddr.size,tt_persistent,t.envbuf);
tg.gethltemp(list,rec_jmp_buf,rec_jmp_buf.size,tt_persistent,t.jmpbuf); tg.gethltemp(list,rec_jmp_buf,rec_jmp_buf.size,tt_persistent,t.jmpbuf);
tg.gethltemp(list,ossinttype,ossinttype.size,tt_persistent,t.reasonbuf); tg.gethltemp(list,setjmpresulttype,setjmpresulttype.size,tt_persistent,t.reasonbuf);
end; end;
@ -207,7 +209,7 @@ unit cgexcept;
location_reset(tmpresloc,LOC_REGISTER,def_cgsize(setjmpres.def)); location_reset(tmpresloc,LOC_REGISTER,def_cgsize(setjmpres.def));
tmpresloc.register:=hlcg.getintregister(list,setjmpres.def); tmpresloc.register:=hlcg.getintregister(list,setjmpres.def);
hlcg.gen_load_cgpara_loc(list,setjmpres.def,setjmpres,tmpresloc,true); hlcg.gen_load_cgpara_loc(list,setjmpres.def,setjmpres,tmpresloc,true);
hlcg.g_exception_reason_save(list,setjmpres.def,ossinttype,tmpresloc.register,t.reasonbuf); hlcg.g_exception_reason_save(list,setjmpres.def,setjmpresulttype,tmpresloc.register,t.reasonbuf);
{ if we get 1 here in the function result register, it means that we { if we get 1 here in the function result register, it means that we
longjmp'd back here } longjmp'd back here }
hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,tmpresloc.register,exceptstate.exceptionlabel); hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,tmpresloc.register,exceptstate.exceptionlabel);
@ -237,9 +239,9 @@ unit cgexcept;
popaddrstack(list); popaddrstack(list);
if not onlyfree then if not onlyfree then
begin begin
reasonreg:=hlcg.getintregister(list,osuinttype); reasonreg:=hlcg.getintregister(list,setjmpresulttype);
hlcg.g_exception_reason_load(list,osuinttype,osuinttype,t.reasonbuf,reasonreg); hlcg.g_exception_reason_load(list,setjmpresulttype,setjmpresulttype,t.reasonbuf,reasonreg);
hlcg.a_cmp_const_reg_label(list,osuinttype,OC_EQ,a,reasonreg,endexceptlabel); hlcg.a_cmp_const_reg_label(list,setjmpresulttype,OC_EQ,a,reasonreg,endexceptlabel);
end; end;
end; end;

View File

@ -542,7 +542,7 @@ implementation
{ we must also destroy the address frame which guards { we must also destroy the address frame which guards
the exception object } the exception object }
cexceptionstatehandler.popaddrstack(list); cexceptionstatehandler.popaddrstack(list);
hlcg.g_exception_reason_discard(list,osuinttype,excepttemps.reasonbuf); hlcg.g_exception_reason_discard(list,setjmpresulttype,excepttemps.reasonbuf);
if frametype=ft_except then if frametype=ft_except then
begin begin
cexceptionstatehandler.cleanupobjectstack(list); cexceptionstatehandler.cleanupobjectstack(list);
@ -875,8 +875,8 @@ implementation
procedure tcgtryfinallynode.emit_jump_out_of_try_finally_frame(list: TasmList; const reason: byte; const finallycodelabel: tasmlabel; var excepttemps: tcgexceptionstatehandler.texceptiontemps; framelabel: tasmlabel); procedure tcgtryfinallynode.emit_jump_out_of_try_finally_frame(list: TasmList; const reason: byte; const finallycodelabel: tasmlabel; var excepttemps: tcgexceptionstatehandler.texceptiontemps; framelabel: tasmlabel);
begin begin
hlcg.a_label(list,framelabel); hlcg.a_label(list,framelabel);
hlcg.g_exception_reason_discard(list,osuinttype,excepttemps.reasonbuf); hlcg.g_exception_reason_discard(list,setjmpresulttype,excepttemps.reasonbuf);
hlcg.g_exception_reason_save_const(list,osuinttype,reason,excepttemps.reasonbuf); hlcg.g_exception_reason_save_const(list,setjmpresulttype,reason,excepttemps.reasonbuf);
hlcg.a_jmp_always(list,finallycodelabel); hlcg.a_jmp_always(list,finallycodelabel);
end; end;
@ -936,13 +936,13 @@ implementation
procedure handle_breakcontinueexit(const finallycode: tasmlabel; doreraise: boolean); procedure handle_breakcontinueexit(const finallycode: tasmlabel; doreraise: boolean);
begin begin
{ no exception happened, but maybe break/continue/exit } { no exception happened, but maybe break/continue/exit }
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,0,reasonreg,endfinallylabel); hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,setjmpresulttype,OC_EQ,0,reasonreg,endfinallylabel);
if fc_exit in finallyexceptionstate.newflowcontrol then if fc_exit in finallyexceptionstate.newflowcontrol then
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,2,reasonreg,oldCurrExitLabel); hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,setjmpresulttype,OC_EQ,2,reasonreg,oldCurrExitLabel);
if fc_break in finallyexceptionstate.newflowcontrol then if fc_break in finallyexceptionstate.newflowcontrol then
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,3,reasonreg,oldBreakLabel); hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,setjmpresulttype,OC_EQ,3,reasonreg,oldBreakLabel);
if fc_continue in finallyexceptionstate.newflowcontrol then if fc_continue in finallyexceptionstate.newflowcontrol then
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,4,reasonreg,oldContinueLabel); hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,setjmpresulttype,OC_EQ,4,reasonreg,oldContinueLabel);
if doreraise then if doreraise then
cexceptionstatehandler.handle_reraise(current_asmdata.CurrAsmList,excepttemps,finallyexceptionstate,tek_normalfinally) cexceptionstatehandler.handle_reraise(current_asmdata.CurrAsmList,excepttemps,finallyexceptionstate,tek_normalfinally)
else else
@ -1019,8 +1019,8 @@ implementation
exit; exit;
if not implicitframe then if not implicitframe then
current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart)); current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,osuinttype); reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,setjmpresulttype);
hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,osuinttype,osuinttype,excepttemps.reasonbuf,reasonreg); hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,setjmpresulttype,setjmpresulttype,excepttemps.reasonbuf,reasonreg);
handle_breakcontinueexit(finallyNoExceptionLabel,false); handle_breakcontinueexit(finallyNoExceptionLabel,false);
current_asmdata.CurrAsmList.concatList(tmplist); current_asmdata.CurrAsmList.concatList(tmplist);
@ -1058,11 +1058,11 @@ implementation
if not assigned(third) then if not assigned(third) then
begin begin
{ the value should now be in the exception handler } { the value should now be in the exception handler }
reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,osuinttype); reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,setjmpresulttype);
hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,osuinttype,osuinttype,excepttemps.reasonbuf,reasonreg); hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,setjmpresulttype,setjmpresulttype,excepttemps.reasonbuf,reasonreg);
if implicitframe then if implicitframe then
begin begin
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,osuinttype,OC_EQ,0,reasonreg,endfinallylabel); hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,setjmpresulttype,OC_EQ,0,reasonreg,endfinallylabel);
{ finally code only needed to be executed on exception (-> in { finally code only needed to be executed on exception (-> in
if-branch -> fc_inflowcontrol) } if-branch -> fc_inflowcontrol) }
if current_procinfo.procdef.generate_safecall_wrapper then if current_procinfo.procdef.generate_safecall_wrapper then

View File

@ -460,13 +460,15 @@ implementation
procedure add_label_init(p:TObject;arg:pointer); procedure add_label_init(p:TObject;arg:pointer);
begin begin
if not assigned(setjmpresulttype) then
setjmpresulttype:=search_system_proc('fpc_setjmp').returndef;
if tstoredsym(p).typ=labelsym then if tstoredsym(p).typ=labelsym then
begin begin
addstatement(tstatementnode(arg^), addstatement(tstatementnode(arg^),
cifnode.create(caddnode.create(equaln, cifnode.create(caddnode.create(equaln,
ccallnode.createintern('fpc_setjmp', ccallnode.createintern('fpc_setjmp',
ccallparanode.create(cloadnode.create(tlabelsym(p).jumpbuf,tlabelsym(p).jumpbuf.owner),nil)), ccallparanode.create(cloadnode.create(tlabelsym(p).jumpbuf,tlabelsym(p).jumpbuf.owner),nil)),
cordconstnode.create(1,sinttype,true)) cordconstnode.create(1,setjmpresulttype,true))
,cgotonode.create(tlabelsym(p)),nil) ,cgotonode.create(tlabelsym(p)),nil)
); );
end; end;

View File

@ -1213,7 +1213,10 @@ interface
{ several types to simulate more or less C++ objects for GDB } { several types to simulate more or less C++ objects for GDB }
vmttype, vmttype,
vmtarraytype, vmtarraytype,
pvmttype : tdef; { type of classrefs, used for stabs } { type of classrefs, used for stabs }
pvmttype,
{ return type of the setjmp function }
setjmpresulttype : tdef;
{ pointer to the anchestor of all classes } { pointer to the anchestor of all classes }
class_tobject : tobjectdef; class_tobject : tobjectdef;