浏览代码

+ tcgexitnode,tcgbreaknode,tcgcontinuenode: added possibility to generate specialized code for leaving unwind-protected regions.

git-svn-id: trunk@19636 -
sergei 13 年之前
父节点
当前提交
8c9ad67682
共有 3 个文件被更改,包括 23 次插入5 次删除
  1. 8 0
      compiler/cgobj.pas
  2. 12 4
      compiler/ncgflw.pas
  3. 3 1
      compiler/pass_2.pas

+ 8 - 0
compiler/cgobj.pas

@@ -525,6 +525,9 @@ unit cgobj;
           procedure g_maybe_got_init(list: TAsmList); virtual;
           procedure g_maybe_got_init(list: TAsmList); virtual;
           { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
           { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
           procedure g_call(list: TAsmList; const s: string);
           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
         protected
           procedure get_subsetref_load_info(const sref: tsubsetreference; out loadsize: tcgsize; out extra_load: boolean);
           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;
           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);
         deallocallcpuregisters(list);
       end;
       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);
     procedure tcg.a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister; shuffle: pmmshuffle);
       begin
       begin
         internalerror(200807231);
         internalerror(200807231);

+ 12 - 4
compiler/ncgflw.pas

@@ -839,8 +839,10 @@ implementation
          include(flowcontrol,fc_exit);
          include(flowcontrol,fc_exit);
          if assigned(left) then
          if assigned(left) then
            secondpass(left);
            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;
        end;
 
 
 
 
@@ -858,7 +860,10 @@ implementation
 {$ifdef OLDREGVARS}
 {$ifdef OLDREGVARS}
              load_all_regvars(current_asmdata.CurrAsmList);
              load_all_regvars(current_asmdata.CurrAsmList);
 {$endif OLDREGVARS}
 {$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
            end
          else
          else
            CGMessage(cg_e_break_not_allowed);
            CGMessage(cg_e_break_not_allowed);
@@ -879,7 +884,10 @@ implementation
 {$ifdef OLDREGVARS}
 {$ifdef OLDREGVARS}
              load_all_regvars(current_asmdata.CurrAsmList);
              load_all_regvars(current_asmdata.CurrAsmList);
 {$endif OLDREGVARS}
 {$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
            end
          else
          else
            CGMessage(cg_e_continue_not_allowed);
            CGMessage(cg_e_continue_not_allowed);

+ 3 - 1
compiler/pass_2.pas

@@ -35,6 +35,8 @@ uses
          fc_continue,
          fc_continue,
          fc_inflowcontrol,
          fc_inflowcontrol,
          fc_gotolabel,
          fc_gotolabel,
+         { in try block of try..finally }
+         fc_unwind,
          { the left side of an expression is already handled, so we are
          { the left side of an expression is already handled, so we are
            not allowed to do ssl }
            not allowed to do ssl }
          fc_lefthandled);
          fc_lefthandled);
@@ -199,7 +201,7 @@ implementation
             if (not codegenerror) then
             if (not codegenerror) then
              begin
              begin
                if (p.location.loc<>p.expectloc) then
                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
                if (p.location.loc=LOC_INVALID) then
                  Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
                  Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
              end;
              end;