Răsfoiți Sursa

* handle explicit reraise for llvm specifically, as it needs to unwind to
the parent exception frame (-> pop current exception label, invoke/call
reraise, push current exception label again)

git-svn-id: branches/debug_eh@40417 -

Jonas Maebe 6 ani în urmă
părinte
comite
7ffd5fc90b
2 a modificat fișierele cu 58 adăugiri și 11 ștergeri
  1. 5 3
      compiler/llvm/llvmpi.pas
  2. 53 8
      compiler/llvm/nllvmflw.pas

+ 5 - 3
compiler/llvm/llvmpi.pas

@@ -39,8 +39,9 @@ interface
         constructor create(aparent: tprocinfo); override;
         destructor destroy; override;
         procedure pushexceptlabel(lab: TAsmLabel);
-        procedure popexceptlabel(lab: TAsmLabel);
-        function CurrExceptLabel: TAsmLabel; inline;
+        { returns true if there no more exception labels on the stack }
+        function popexceptlabel(lab: TAsmLabel): boolean;
+        function CurrExceptLabel: TAsmLabel;
       end;
 
 implementation
@@ -71,11 +72,12 @@ implementation
       end;
 
 
-    procedure tllvmprocinfo.popexceptlabel(lab: TAsmLabel);
+    function tllvmprocinfo.popexceptlabel(lab: TAsmLabel): boolean;
       begin
         if CurrExceptLabel<>lab then
           internalerror(2016121302);
         fexceptlabelstack.count:=fexceptlabelstack.count-1;
+        result:=fexceptlabelstack.count=0;
       end;
 
 

+ 53 - 8
compiler/llvm/nllvmflw.pas

@@ -26,8 +26,9 @@ unit nllvmflw;
 interface
 
     uses
+      globtype,
       aasmbase,aasmdata,
-      nflw, ncgflw, ncgnstfl;
+      node, nflw, ncgflw, ncgnstfl;
 
     type
       tllvmlabelnode = class(tcglabelnode)
@@ -39,20 +40,26 @@ interface
         class procedure emit_except_label(list: TAsmList; var exceptionstate: texceptionstate); override;
       end;
 
+    tllvmraisenode = class(tcgraisenode)
+      function pass_1: tnode; override;
+      procedure pass_generate_code; override;
+    end;
+
 
 implementation
 
+    uses
+      systems,globals,verbose,
+      symconst,symtable,symsym,llvmdef,defutil,
+      pass_2,cgutils,hlcgobj,parabase,paramgr,tgobj,
+      llvmbase,aasmtai,aasmllvm,
+      procinfo,llvmpi;
+
+
 {*****************************************************************************
                              SecondLabel
 *****************************************************************************}
 
-    uses
-      systems,
-      symconst,symdef,llvmdef,
-      cgbase,cgutils,hlcgobj,
-      llvmbase,aasmllvm,
-      procinfo,llvmpi;
-
     function tllvmlabelnode.getasmlabel: tasmlabel;
       begin
         { don't allocate global labels even if the label is accessed from
@@ -133,9 +140,47 @@ implementation
       end;
 
 
+{*****************************************************************************
+                     tllvmexceptionstatehandler
+*****************************************************************************}
+
+    function tllvmraisenode.pass_1: tnode;
+      begin
+        if assigned(left) then
+          result:=inherited
+        else
+          begin
+            expectloc:=LOC_VOID;
+            result:=nil;
+          end;
+      end;
+
+
+    procedure tllvmraisenode.pass_generate_code;
+      var
+        currexceptlabel: tasmlabel;
+      begin
+        location_reset(location,LOC_VOID,OS_NO);
+        currexceptlabel:=nil;
+        { a reraise must raise the exception to the parent exception frame }
+        if fc_catching_exceptions in flowcontrol then
+          begin
+            currexceptlabel:=tllvmprocinfo(current_procinfo).CurrExceptLabel;
+            if tllvmprocinfo(current_procinfo).popexceptlabel(currexceptlabel) then
+              exclude(flowcontrol,fc_catching_exceptions);
+          end;
+        hlcg.g_call_system_proc(current_asmdata.CurrAsmList,'fpc_reraise',[],nil).resetiftemp;
+        if assigned(currexceptlabel) then
+          begin
+            tllvmprocinfo(current_procinfo).pushexceptlabel(currexceptlabel);
+            include(flowcontrol,fc_catching_exceptions);
+          end;
+      end;
+
 
 begin
   clabelnode:=tllvmlabelnode;
   cexceptionstatehandler:=tllvmexceptionstatehandler;
+  craisenode:=tllvmraisenode;
 end.