mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-11-22 02:19:37 +01:00
* 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:
parent
ccb7231744
commit
01ddde2283
@ -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);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user