瀏覽代碼

* Handle safecall exceptions entirely in tcgtryfinallynode pass2. This simplifies things and removes the need in hidden safe_result variable.

git-svn-id: trunk@19950 -
sergei 13 年之前
父節點
當前提交
f6761d7939
共有 2 個文件被更改,包括 24 次插入37 次删除
  1. 24 10
      compiler/ncgflw.pas
  2. 0 27
      compiler/psub.pas

+ 24 - 10
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);

+ 0 - 27
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;