From f6761d7939db1ae74bcfb0068b783018164a005b Mon Sep 17 00:00:00 2001 From: sergei Date: Mon, 2 Jan 2012 14:23:31 +0000 Subject: [PATCH] * Handle safecall exceptions entirely in tcgtryfinallynode pass2. This simplifies things and removes the need in hidden safe_result variable. git-svn-id: trunk@19950 - --- compiler/ncgflw.pas | 34 ++++++++++++++++++++++++---------- compiler/psub.pas | 27 --------------------------- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index 6c47165538..5a5bcf7855 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -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); diff --git a/compiler/psub.pas b/compiler/psub.pas index ff24e105d9..57bc4cefa8 100644 --- a/compiler/psub.pas +++ b/compiler/psub.pas @@ -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;