From 8c9ad676829b3af3a3d4b943b08a0ba9c637eda9 Mon Sep 17 00:00:00 2001 From: sergei Date: Mon, 14 Nov 2011 22:47:37 +0000 Subject: [PATCH] + tcgexitnode,tcgbreaknode,tcgcontinuenode: added possibility to generate specialized code for leaving unwind-protected regions. git-svn-id: trunk@19636 - --- compiler/cgobj.pas | 8 ++++++++ compiler/ncgflw.pas | 16 ++++++++++++---- compiler/pass_2.pas | 4 +++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index 0daa199573..e16562b909 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -525,6 +525,9 @@ unit cgobj; procedure g_maybe_got_init(list: TAsmList); virtual; { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence } procedure g_call(list: TAsmList; const s: string); + { Generate code to exit an unwind-protected region. The default implementation + produces a simple jump to destination label. } + procedure g_local_unwind(list: TAsmList; l: TAsmLabel);virtual; protected procedure get_subsetref_load_info(const sref: tsubsetreference; out loadsize: tcgsize; out extra_load: boolean); procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); virtual; @@ -4278,6 +4281,11 @@ implementation deallocallcpuregisters(list); end; + procedure tcg.g_local_unwind(list: TAsmList; l: TAsmLabel); + begin + a_jmp_always(list,l); + end; + procedure tcg.a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister; shuffle: pmmshuffle); begin internalerror(200807231); diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index cc5a386ad9..6c47165538 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -839,8 +839,10 @@ implementation include(flowcontrol,fc_exit); if assigned(left) then secondpass(left); - - cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel); + if (fc_unwind in flowcontrol) then + cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel) + else + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel); end; @@ -858,7 +860,10 @@ implementation {$ifdef OLDREGVARS} load_all_regvars(current_asmdata.CurrAsmList); {$endif OLDREGVARS} - cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel) + if (fc_unwind in flowcontrol) then + cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel) + else + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel) end else CGMessage(cg_e_break_not_allowed); @@ -879,7 +884,10 @@ implementation {$ifdef OLDREGVARS} load_all_regvars(current_asmdata.CurrAsmList); {$endif OLDREGVARS} - cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel) + if (fc_unwind in flowcontrol) then + cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel) + else + cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel) end else CGMessage(cg_e_continue_not_allowed); diff --git a/compiler/pass_2.pas b/compiler/pass_2.pas index a20cb7d744..2aa9879912 100644 --- a/compiler/pass_2.pas +++ b/compiler/pass_2.pas @@ -35,6 +35,8 @@ uses fc_continue, fc_inflowcontrol, fc_gotolabel, + { in try block of try..finally } + fc_unwind, { the left side of an expression is already handled, so we are not allowed to do ssl } fc_lefthandled); @@ -199,7 +201,7 @@ implementation if (not codegenerror) then begin if (p.location.loc<>p.expectloc) then - Comment(V_Warning,'Location not equal to expectloc: '+nodetype2str[p.nodetype]); + Comment(V_Warning,'Location ('+tcgloc2str[p.location.loc]+') not equal to expectloc ('+tcgloc2str[p.expectloc]+'): '+nodetype2str[p.nodetype]); if (p.location.loc=LOC_INVALID) then Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]); end;