mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-20 18:09:27 +02:00
* Handle safecall exceptions entirely in tcgtryfinallynode pass2. This simplifies things and removes the need in hidden safe_result variable.
git-svn-id: trunk@19950 -
This commit is contained in:
parent
96cab58ab4
commit
f6761d7939
@ -81,6 +81,7 @@ interface
|
||||
end;
|
||||
|
||||
tcgtryfinallynode = class(ttryfinallynode)
|
||||
procedure handle_safecall_exception;
|
||||
procedure pass_generate_code;override;
|
||||
end;
|
||||
|
||||
@ -1437,6 +1438,28 @@ implementation
|
||||
SecondTryFinally
|
||||
*****************************************************************************}
|
||||
|
||||
procedure tcgtryfinallynode.handle_safecall_exception;
|
||||
var
|
||||
cgpara: tcgpara;
|
||||
selfsym: tparavarsym;
|
||||
begin
|
||||
{ call fpc_safecallhandler, passing self for methods of classes,
|
||||
nil otherwise. }
|
||||
cgpara.init;
|
||||
paramanager.getintparaloc(pocall_default,1,cgpara);
|
||||
if is_class(current_procinfo.procdef.struct) then
|
||||
begin
|
||||
selfsym:=tparavarsym(current_procinfo.procdef.parast.Find('self'));
|
||||
if (selfsym=nil) or (selfsym.typ<>paravarsym) then
|
||||
InternalError(2011123101);
|
||||
cg.a_load_loc_cgpara(current_asmdata.CurrAsmList,selfsym.localloc,cgpara);
|
||||
end
|
||||
else
|
||||
cg.a_load_const_cgpara(current_asmdata.CurrAsmList,OS_ADDR,0,cgpara);
|
||||
cgpara.done;
|
||||
cg.g_call(current_asmdata.CurrAsmList,'FPC_SAFECALLHANDLER');
|
||||
end;
|
||||
|
||||
procedure tcgtryfinallynode.pass_generate_code;
|
||||
var
|
||||
reraiselabel,
|
||||
@ -1451,7 +1474,6 @@ implementation
|
||||
oldflowcontrol,tryflowcontrol : tflowcontrol;
|
||||
decconst : longint;
|
||||
excepttemps : texceptiontemps;
|
||||
retsym: tlocalvarsym;
|
||||
begin
|
||||
location_reset(location,LOC_VOID,OS_NO);
|
||||
|
||||
@ -1541,15 +1563,7 @@ implementation
|
||||
{$if defined(x86) or defined(arm)}
|
||||
if (tf_safecall_exceptions in target_info.flags) and
|
||||
(current_procinfo.procdef.proccalloption=pocall_safecall) then
|
||||
begin
|
||||
{ find safe_result variable we created in the generate_except_block }
|
||||
retsym:=tlocalvarsym(current_procinfo.procdef.localst.Find('safe_result'));
|
||||
{ Set return value of safecall procedure to indicate exception. }
|
||||
{ Exception will be raised after procedure exit based on return value }
|
||||
cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
||||
cg.a_load_loc_reg(current_asmdata.CurrAsmList,OS_INT,retsym.localloc,NR_FUNCTION_RESULT_REG);
|
||||
cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
||||
end
|
||||
handle_safecall_exception
|
||||
else
|
||||
{$endif}
|
||||
cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RERAISE',false);
|
||||
|
@ -459,9 +459,6 @@ implementation
|
||||
function generate_except_block:tnode;
|
||||
var
|
||||
newstatement : tstatementnode;
|
||||
{ safecall handling }
|
||||
sym: tsym;
|
||||
argnode: tnode;
|
||||
begin
|
||||
generate_except_block:=internalstatements(newstatement);
|
||||
|
||||
@ -477,30 +474,6 @@ implementation
|
||||
(not paramanager.ret_in_param(current_procinfo.procdef.returndef, current_procinfo.procdef.proccalloption)) and
|
||||
(not is_class(current_procinfo.procdef.returndef)) then
|
||||
addstatement(newstatement,finalize_data_node(load_result_node));
|
||||
{$if defined(x86) or defined(arm)}
|
||||
{ safecall handling }
|
||||
if (tf_safecall_exceptions in target_info.flags) and
|
||||
(current_procinfo.procdef.proccalloption=pocall_safecall) then
|
||||
begin
|
||||
{ create a local hidden variable "safe_result" }
|
||||
{ it will be used in ncgflw unit }
|
||||
{ to set "real" result value for safecall routine }
|
||||
sym:=tlocalvarsym.create('$safe_result',vs_value,hresultdef,[]);
|
||||
include(sym.symoptions,sp_internal);
|
||||
current_procinfo.procdef.localst.insert(sym);
|
||||
{ if safecall is used for a class method we need to call }
|
||||
{ SafecallException virtual method }
|
||||
{ In other case we return E_UNEXPECTED error value }
|
||||
if is_class(current_procinfo.procdef.struct) then
|
||||
argnode:=load_self_node
|
||||
else
|
||||
argnode:=cnilnode.create;
|
||||
addstatement(newstatement,cassignmentnode.create(
|
||||
cloadnode.create(sym,sym.Owner),
|
||||
ccallnode.createinternres('fpc_safecallhandler',
|
||||
ccallparanode.create(argnode,nil),hresultdef)));
|
||||
end;
|
||||
{$endif}
|
||||
end;
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user