From 4c2e0b9ff0ce9c285f1aedeef6a7146c81a55d0b Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 27 Feb 2021 16:47:36 +0000 Subject: [PATCH] * for setjmp based exception handling, get the type of the exception reason from the setjmp result git-svn-id: trunk@48828 - --- compiler/cgexcept.pas | 14 ++++++++------ compiler/ncgflw.pas | 24 ++++++++++++------------ compiler/psub.pas | 4 +++- compiler/symdef.pas | 5 ++++- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/compiler/cgexcept.pas b/compiler/cgexcept.pas index c0d421c923..8cb4c55696 100644 --- a/compiler/cgexcept.pas +++ b/compiler/cgexcept.pas @@ -131,10 +131,12 @@ unit cgexcept; 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_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; @@ -207,7 +209,7 @@ unit cgexcept; location_reset(tmpresloc,LOC_REGISTER,def_cgsize(setjmpres.def)); tmpresloc.register:=hlcg.getintregister(list,setjmpres.def); 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 longjmp'd back here } hlcg.a_cmp_const_reg_label(list,setjmpres.def,OC_NE,0,tmpresloc.register,exceptstate.exceptionlabel); @@ -237,9 +239,9 @@ unit cgexcept; popaddrstack(list); if not onlyfree then begin - reasonreg:=hlcg.getintregister(list,osuinttype); - hlcg.g_exception_reason_load(list,osuinttype,osuinttype,t.reasonbuf,reasonreg); - hlcg.a_cmp_const_reg_label(list,osuinttype,OC_EQ,a,reasonreg,endexceptlabel); + reasonreg:=hlcg.getintregister(list,setjmpresulttype); + hlcg.g_exception_reason_load(list,setjmpresulttype,setjmpresulttype,t.reasonbuf,reasonreg); + hlcg.a_cmp_const_reg_label(list,setjmpresulttype,OC_EQ,a,reasonreg,endexceptlabel); end; end; diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index 601a74919a..902c81d952 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -542,7 +542,7 @@ implementation { we must also destroy the address frame which guards the exception object } 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 begin 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); begin hlcg.a_label(list,framelabel); - hlcg.g_exception_reason_discard(list,osuinttype,excepttemps.reasonbuf); - hlcg.g_exception_reason_save_const(list,osuinttype,reason,excepttemps.reasonbuf); + hlcg.g_exception_reason_discard(list,setjmpresulttype,excepttemps.reasonbuf); + hlcg.g_exception_reason_save_const(list,setjmpresulttype,reason,excepttemps.reasonbuf); hlcg.a_jmp_always(list,finallycodelabel); end; @@ -936,13 +936,13 @@ implementation procedure handle_breakcontinueexit(const finallycode: tasmlabel; doreraise: boolean); begin { 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 - 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 - 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 - 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 cexceptionstatehandler.handle_reraise(current_asmdata.CurrAsmList,excepttemps,finallyexceptionstate,tek_normalfinally) else @@ -1019,8 +1019,8 @@ implementation exit; if not implicitframe then current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart)); - reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,osuinttype); - hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,osuinttype,osuinttype,excepttemps.reasonbuf,reasonreg); + reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,setjmpresulttype); + hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,setjmpresulttype,setjmpresulttype,excepttemps.reasonbuf,reasonreg); handle_breakcontinueexit(finallyNoExceptionLabel,false); current_asmdata.CurrAsmList.concatList(tmplist); @@ -1058,11 +1058,11 @@ implementation if not assigned(third) then begin { the value should now be in the exception handler } - reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,osuinttype); - hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,osuinttype,osuinttype,excepttemps.reasonbuf,reasonreg); + reasonreg:=hlcg.getintregister(current_asmdata.CurrAsmList,setjmpresulttype); + hlcg.g_exception_reason_load(current_asmdata.CurrAsmList,setjmpresulttype,setjmpresulttype,excepttemps.reasonbuf,reasonreg); if implicitframe then 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 if-branch -> fc_inflowcontrol) } if current_procinfo.procdef.generate_safecall_wrapper then diff --git a/compiler/psub.pas b/compiler/psub.pas index 5d31dafcf1..4054d58dfb 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -460,13 +460,15 @@ implementation procedure add_label_init(p:TObject;arg:pointer); begin + if not assigned(setjmpresulttype) then + setjmpresulttype:=search_system_proc('fpc_setjmp').returndef; if tstoredsym(p).typ=labelsym then begin addstatement(tstatementnode(arg^), cifnode.create(caddnode.create(equaln, ccallnode.createintern('fpc_setjmp', 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) ); end; diff --git a/compiler/symdef.pas b/compiler/symdef.pas index 1772851900..1c857d4fc0 100644 --- a/compiler/symdef.pas +++ b/compiler/symdef.pas @@ -1213,7 +1213,10 @@ interface { several types to simulate more or less C++ objects for GDB } vmttype, 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 } class_tobject : tobjectdef;