Browse Source

+ Added a simple helper tcg.g_call, intended to replace allocallcpuregisters+a_call_name+deallocallcpuregisters sequence which is used all over the place.
* Refactored code generation for tcgonnonde and tcgtryexceptnode, simplifying both compiler and generated code. Merged compilerprocs called in sequence into larger ones (fpc_popobjectstack+fpc_destroyexception -> fpc_doneexception, fpc_popsecondobjectstack+fpc_destroyexception+fpc_reraise -> fpc_raise_nested).

git-svn-id: trunk@19506 -

sergei 14 years ago
parent
commit
a32fdc3ae6
4 changed files with 52 additions and 91 deletions
  1. 8 0
      compiler/cgobj.pas
  2. 27 90
      compiler/ncgflw.pas
  3. 2 0
      rtl/inc/compproc.inc
  4. 15 1
      rtl/inc/except.inc

+ 8 - 0
compiler/cgobj.pas

@@ -523,6 +523,8 @@ unit cgobj;
 
 
           { initialize the pic/got register }
           { initialize the pic/got register }
           procedure g_maybe_got_init(list: TAsmList); virtual;
           procedure g_maybe_got_init(list: TAsmList); virtual;
+          { allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
+          procedure g_call(list: TAsmList; const s: string);
         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;
@@ -4269,6 +4271,12 @@ implementation
       begin
       begin
       end;
       end;
 
 
+    procedure tcg.g_call(list: TAsmList;const s: string);
+      begin
+        allocallcpuregisters(list);
+        a_call_name(list,s,false);
+        deallocallcpuregisters(list);
+      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

+ 27 - 90
compiler/ncgflw.pas

@@ -1031,22 +1031,26 @@ implementation
     { does the necessary things to clean up the object stack }
     { does the necessary things to clean up the object stack }
     { in the except block                                    }
     { in the except block                                    }
     procedure cleanupobjectstack;
     procedure cleanupobjectstack;
+      begin
+         cg.g_call(current_asmdata.CurrAsmList,'FPC_DONEEXCEPTION');
+      end;
+
+    { generates code to be executed when another exeception is raised while
+      control is inside except block }
+    procedure handle_nested_exception(list:TAsmList;const t:texceptiontemps;entrylabel:TAsmLabel);
       var
       var
-        paraloc1 : tcgpara;
+         exitlabel: tasmlabel;
       begin
       begin
-         cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPOBJECTSTACK',false);
-         cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-         paraloc1.init;
-         paramanager.getintparaloc(pocall_default,1,paraloc1);
-         cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-         cg.a_load_reg_cgpara(current_asmdata.CurrAsmList,OS_ADDR,NR_FUNCTION_RESULT_REG,paraloc1);
-         paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-         cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_DESTROYEXCEPTION',false);
-         cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-         paraloc1.done;
+         { don't generate line info for internal cleanup }
+         list.concat(tai_marker.create(mark_NoLineInfoStart));
+         current_asmdata.getjumplabel(exitlabel);
+         cg.a_label(list,entrylabel);
+         free_exception(list,t,0,exitlabel,false);
+         { we don't need to save/restore registers here because reraise never }
+         { returns                                                            }
+         cg.a_call_name(list,'FPC_RAISE_NESTED',false);
+         cg.a_label(list,exitlabel);
+         cleanupobjectstack;
       end;
       end;
 
 
 
 
@@ -1061,7 +1065,6 @@ implementation
          exittrylabel,
          exittrylabel,
          continuetrylabel,
          continuetrylabel,
          breaktrylabel,
          breaktrylabel,
-         doobjectdestroy,
          doobjectdestroyandreraise,
          doobjectdestroyandreraise,
          oldCurrExitLabel,
          oldCurrExitLabel,
          oldContinueLabel,
          oldContinueLabel,
@@ -1070,7 +1073,6 @@ implementation
          exceptflowcontrol : tflowcontrol;
          exceptflowcontrol : tflowcontrol;
          destroytemps,
          destroytemps,
          excepttemps : texceptiontemps;
          excepttemps : texceptiontemps;
-         paraloc1 : tcgpara;
       label
       label
          errorexit;
          errorexit;
       begin
       begin
@@ -1168,7 +1170,6 @@ implementation
 
 
               if not (has_no_code(t1)) then
               if not (has_no_code(t1)) then
                begin
                begin
-                 current_asmdata.getjumplabel(doobjectdestroy);
                  current_asmdata.getjumplabel(doobjectdestroyandreraise);
                  current_asmdata.getjumplabel(doobjectdestroyandreraise);
 
 
                  get_exception_temps(current_asmdata.CurrAsmList,destroytemps);
                  get_exception_temps(current_asmdata.CurrAsmList,destroytemps);
@@ -1182,34 +1183,8 @@ implementation
                  secondpass(t1);
                  secondpass(t1);
                  exceptflowcontrol:=flowcontrol;
                  exceptflowcontrol:=flowcontrol;
 
 
-                 { don't generate line info for internal cleanup }
-                 current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
-
-                 cg.a_label(current_asmdata.CurrAsmList,doobjectdestroyandreraise);
-
-                 free_exception(current_asmdata.CurrAsmList,destroytemps,0,doobjectdestroy,false);
+                 handle_nested_exception(current_asmdata.CurrAsmList,destroytemps,doobjectdestroyandreraise);
 
 
-                 cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-                 cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPSECONDOBJECTSTACK',false);
-                 cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-
-                 paraloc1.init;
-                 paramanager.getintparaloc(pocall_default,1,paraloc1);
-                 cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-                 cg.a_load_reg_cgpara(current_asmdata.CurrAsmList, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
-                 paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-                 cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-                 cg.a_call_name(current_asmdata.CurrAsmList,'FPC_DESTROYEXCEPTION',false);
-                 cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-                 paraloc1.done;
-                 { we don't need to restore esi here because reraise never }
-                 { returns                                                 }
-                 cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RERAISE',false);
-
-                 cg.a_label(current_asmdata.CurrAsmList,doobjectdestroy);
-
-                 cleanupobjectstack;
                  unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
                  unget_exception_temps(current_asmdata.CurrAsmList,destroytemps);
                  cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
                  cg.a_jmp_always(current_asmdata.CurrAsmList,endexceptlabel);
                end
                end
@@ -1232,9 +1207,7 @@ implementation
               cg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
               cg.a_label(current_asmdata.CurrAsmList,exitexceptlabel);
               { we must also destroy the address frame which guards }
               { we must also destroy the address frame which guards }
               { exception object                                    }
               { exception object                                    }
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cleanupobjectstack;
               cleanupobjectstack;
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
@@ -1247,9 +1220,7 @@ implementation
               cg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
               cg.a_label(current_asmdata.CurrAsmList,breakexceptlabel);
               { we must also destroy the address frame which guards }
               { we must also destroy the address frame which guards }
               { exception object                                    }
               { exception object                                    }
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cleanupobjectstack;
               cleanupobjectstack;
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
@@ -1262,9 +1233,7 @@ implementation
               cg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
               cg.a_label(current_asmdata.CurrAsmList,continueexceptlabel);
               { we must also destroy the address frame which guards }
               { we must also destroy the address frame which guards }
               { exception object                                    }
               { exception object                                    }
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cleanupobjectstack;
               cleanupobjectstack;
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
@@ -1276,9 +1245,7 @@ implementation
            begin
            begin
               { do some magic for exit in the try block }
               { do some magic for exit in the try block }
               cg.a_label(current_asmdata.CurrAsmList,exittrylabel);
               cg.a_label(current_asmdata.CurrAsmList,exittrylabel);
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldCurrExitLabel);
               { from g_exception_reason_load  }
               { from g_exception_reason_load  }
@@ -1288,9 +1255,7 @@ implementation
          if fc_break in tryflowcontrol then
          if fc_break in tryflowcontrol then
            begin
            begin
               cg.a_label(current_asmdata.CurrAsmList,breaktrylabel);
               cg.a_label(current_asmdata.CurrAsmList,breaktrylabel);
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldBreakLabel);
               { from g_exception_reason_load  }
               { from g_exception_reason_load  }
@@ -1300,9 +1265,7 @@ implementation
          if fc_continue in tryflowcontrol then
          if fc_continue in tryflowcontrol then
            begin
            begin
               cg.a_label(current_asmdata.CurrAsmList,continuetrylabel);
               cg.a_label(current_asmdata.CurrAsmList,continuetrylabel);
-              cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-              cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK',false);
-              cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+              cg.g_call(current_asmdata.CurrAsmList,'FPC_POPADDRSTACK');
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.g_exception_reason_load(current_asmdata.CurrAsmList,excepttemps.reasonbuf);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
               cg.a_jmp_always(current_asmdata.CurrAsmList,oldContinueLabel);
               { from g_exception_reason_load  }
               { from g_exception_reason_load  }
@@ -1341,7 +1304,6 @@ implementation
          oldCurrExitLabel,
          oldCurrExitLabel,
          oldContinueLabel,
          oldContinueLabel,
          doobjectdestroyandreraise,
          doobjectdestroyandreraise,
-         doobjectdestroy,
          oldBreakLabel : tasmlabel;
          oldBreakLabel : tasmlabel;
          oldflowcontrol : tflowcontrol;
          oldflowcontrol : tflowcontrol;
          excepttemps : texceptiontemps;
          excepttemps : texceptiontemps;
@@ -1362,9 +1324,7 @@ implementation
          paramanager.getintparaloc(pocall_default,1,paraloc1);
          paramanager.getintparaloc(pocall_default,1,paraloc1);
          cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc1);
          cg.a_loadaddr_ref_cgpara(current_asmdata.CurrAsmList,href2,paraloc1);
          paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
          paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-         cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_CATCHES',false);
-         cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
+         cg.g_call(current_asmdata.CurrAsmList,'FPC_CATCHES');
 
 
          cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
          cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
          { is it this catch? No. go to next onlabel }
          { is it this catch? No. go to next onlabel }
@@ -1418,31 +1378,8 @@ implementation
               secondpass(right);
               secondpass(right);
            end;
            end;
 
 
-         { don't generate lineinfo for internal cleanup }
-         current_asmdata.CurrAsmList.concat(tai_marker.create(mark_NoLineInfoStart));
-
-         current_asmdata.getjumplabel(doobjectdestroy);
-         cg.a_label(current_asmdata.CurrAsmList,doobjectdestroyandreraise);
-
-         free_exception(current_asmdata.CurrAsmList,excepttemps,0,doobjectdestroy,false);
+         handle_nested_exception(current_asmdata.CurrAsmList,excepttemps,doobjectdestroyandreraise);
 
 
-         cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_POPSECONDOBJECTSTACK',false);
-         cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_reg_alloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-         paramanager.getintparaloc(pocall_default,1,paraloc1);
-         cg.a_reg_dealloc(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
-         cg.a_load_reg_cgpara(current_asmdata.CurrAsmList, OS_ADDR, NR_FUNCTION_RESULT_REG, paraloc1);
-         paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
-         cg.allocallcpuregisters(current_asmdata.CurrAsmList);
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_DESTROYEXCEPTION',false);
-         cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
-         { we don't need to store/restore registers here because reraise never
-           returns                                                             }
-         cg.a_call_name(current_asmdata.CurrAsmList,'FPC_RERAISE',false);
-
-         cg.a_label(current_asmdata.CurrAsmList,doobjectdestroy);
-         cleanupobjectstack;
          { clear some stuff }
          { clear some stuff }
          if assigned(exceptvarsym) then
          if assigned(exceptvarsym) then
            begin
            begin

+ 2 - 0
rtl/inc/compproc.inc

@@ -663,6 +663,8 @@ Function fpc_Catches(Objtype : TClass) : TObject; compilerproc;
 Procedure fpc_DestroyException(o : TObject); compilerproc;
 Procedure fpc_DestroyException(o : TObject); compilerproc;
 function fpc_GetExceptionAddr : Pointer; compilerproc;
 function fpc_GetExceptionAddr : Pointer; compilerproc;
 function fpc_safecallhandler(obj: TObject): HResult; compilerproc;
 function fpc_safecallhandler(obj: TObject): HResult; compilerproc;
+procedure fpc_doneexception; compilerproc;
+procedure fpc_raise_nested; compilerproc;
 {$endif FPC_HAS_FEATURE_EXCEPTIONS}
 {$endif FPC_HAS_FEATURE_EXCEPTIONS}
 
 
 
 

+ 15 - 1
rtl/inc/except.inc

@@ -259,7 +259,6 @@ begin
     end;
     end;
 end;
 end;
 
 
-function Internal_PopObjectStack: TObject; external name 'FPC_POPOBJECTSTACK';
 
 
 { this is for popping exception objects when a second exception is risen }
 { this is for popping exception objects when a second exception is risen }
 { in an except/on                                                        }
 { in an except/on                                                        }
@@ -308,6 +307,9 @@ begin
   longjmp(_ExceptAddrStack^.Buf^,FPC_Exception);
   longjmp(_ExceptAddrStack^.Buf^,FPC_Exception);
 end;
 end;
 
 
+function Internal_PopSecondObjectStack : TObject; external name 'FPC_POPSECONDOBJECTSTACK';
+function Internal_PopObjectStack: TObject; external name 'FPC_POPOBJECTSTACK';
+procedure Internal_Reraise; external name 'FPC_RERAISE';
 
 
 Function fpc_Catches(Objtype : TClass) : TObject;[Public, Alias : 'FPC_CATCHES']; compilerproc;
 Function fpc_Catches(Objtype : TClass) : TObject;[Public, Alias : 'FPC_CATCHES']; compilerproc;
 var
 var
@@ -366,6 +368,18 @@ begin
   ExceptAddrStack:=Nil;
   ExceptAddrStack:=Nil;
 end;
 end;
 
 
+
+procedure fpc_doneexception;[public,alias:'FPC_DONEEXCEPTION'] compilerproc;
+begin
+  Internal_PopObjectStack.Free;
+end;
+
+procedure fpc_raise_nested;[public,alias:'FPC_RAISE_NESTED']compilerproc;
+begin
+  Internal_PopSecondObjectStack.Free;
+  Internal_Reraise;
+end;
+
 function fpc_safecallhandler(obj: TObject): HResult; [public,alias:'FPC_SAFECALLHANDLER']; compilerproc;
 function fpc_safecallhandler(obj: TObject): HResult; [public,alias:'FPC_SAFECALLHANDLER']; compilerproc;
 var
 var
   raiselist: PExceptObject;
   raiselist: PExceptObject;