* refactored jumping out of exception frames so it can be overridden by descendents

git-svn-id: branches/debug_eh@40406 -
This commit is contained in:
Jonas Maebe 2018-11-29 21:31:02 +00:00
parent ccb7231744
commit 01ddde2283

View File

@ -105,10 +105,19 @@ interface
tcgtryexceptnode = class(ttryexceptnode)
protected
type
tframetype = (ft_try,ft_except);
procedure emit_jump_out_of_try_except_frame(list: TasmList; frametype: tframetype; const exceptiontate: tcgexceptionstatehandler.texceptionstate; var excepttemps: tcgexceptionstatehandler.texceptiontemps; framelabel, outerlabel: tasmlabel); virtual;
public
procedure pass_generate_code;override;
end;
tcgtryfinallynode = class(ttryfinallynode)
protected
procedure emit_jump_out_of_try_finally_frame(list: TasmList; const reason: byte; const exceptionstate: tcgexceptionstatehandler.texceptionstate; var excepttemps: tcgexceptionstatehandler.texceptiontemps; framelabel: tasmlabel);
public
procedure handle_safecall_exception;
procedure pass_generate_code;override;
end;
@ -694,6 +703,19 @@ implementation
var
endexceptlabel : tasmlabel;
{ jump out of an try/except block }
procedure tcgtryexceptnode.emit_jump_out_of_try_except_frame(list: TasmList; frametype: tframetype; const exceptiontate: tcgexceptionstatehandler.texceptionstate; var excepttemps: tcgexceptionstatehandler.texceptiontemps; framelabel, outerlabel: tasmlabel);
begin
hlcg.a_label(list,framelabel);
{ we must also destroy the address frame which guards
the exception object }
hlcg.g_call_system_proc(list,'fpc_popaddrstack',[],nil);
hlcg.g_exception_reason_discard(list,osuinttype,excepttemps.reasonbuf);
if frametype=ft_except then
cexceptionstatehandler.cleanupobjectstack;
hlcg.a_jmp_always(list,outerlabel);
end;
procedure tcgtryexceptnode.pass_generate_code;
@ -841,63 +863,23 @@ implementation
end;
if fc_exit in doobjectdestroyandreraisestate.newflowcontrol then
begin
{ do some magic for exit in the try block }
hlcg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
{ we must also destroy the address frame which guards }
{ exception object }
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
cexceptionstatehandler.cleanupobjectstack;
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_except,doobjectdestroyandreraisestate,excepttemps,exitexceptlabel,oldCurrExitLabel);
if fc_break in doobjectdestroyandreraisestate.newflowcontrol then
begin
hlcg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
{ we must also destroy the address frame which guards }
{ exception object }
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
cexceptionstatehandler.cleanupobjectstack;
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_except,doobjectdestroyandreraisestate,excepttemps,breakexceptlabel,oldBreakLabel);
if fc_continue in doobjectdestroyandreraisestate.newflowcontrol then
begin
hlcg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
{ we must also destroy the address frame which guards }
{ exception object }
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
cexceptionstatehandler.cleanupobjectstack;
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_except,doobjectdestroyandreraisestate,excepttemps,continueexceptlabel,oldContinueLabel);
if fc_exit in trystate.newflowcontrol then
begin
{ do some magic for exit in the try block }
hlcg.a_label(current_asmdata.CurrAsmList,exittrylabel);
hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_popaddrstack',[],nil);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_try,trystate,excepttemps,exittrylabel,oldCurrExitLabel);
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);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_try,trystate,excepttemps,breaktrylabel,oldBreakLabel);
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);
hlcg.g_exception_reason_discard(current_asmdata.CurrAsmList,osuinttype,excepttemps.reasonbuf);
hlcg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
end;
emit_jump_out_of_try_except_frame(current_asmdata.CurrAsmList,ft_try,trystate,excepttemps,continuetrylabel,oldContinueLabel);
cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
hlcg.a_label(current_asmdata.CurrAsmList,endexceptlabel);
@ -1069,6 +1051,16 @@ implementation
SecondTryFinally
*****************************************************************************}
{ jump out of a finally block }
procedure tcgtryfinallynode.emit_jump_out_of_try_finally_frame(list: TasmList; const reason: byte; const exceptionstate: tcgexceptionstatehandler.texceptionstate; 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.a_jmp_always(list,exceptionstate.exceptionlabel);
end;
procedure tcgtryfinallynode.handle_safecall_exception;
var
cgpara: tcgpara;
@ -1207,26 +1199,11 @@ implementation
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 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,finallyexceptionstate.exceptionlabel);
end;
emit_jump_out_of_try_finally_frame(current_asmdata.CurrAsmList,2,finallyexceptionstate,excepttemps,exitfinallylabel);
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,finallyexceptionstate.exceptionlabel);
end;
emit_jump_out_of_try_finally_frame(current_asmdata.CurrAsmList,3,finallyexceptionstate,excepttemps,breakfinallylabel);
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,finallyexceptionstate.exceptionlabel);
end;
emit_jump_out_of_try_finally_frame(current_asmdata.CurrAsmList,4,finallyexceptionstate,excepttemps,continuefinallylabel);
end;
cexceptionstatehandler.unget_exception_temps(current_asmdata.CurrAsmList,excepttemps);
hlcg.a_label(current_asmdata.CurrAsmList,endfinallylabel);