Browse Source

* pass managed function result addresses as a hidden first parameter instead
of in X8, as the ABI allows this deviation (see added comments) and it's
required for some internal RTL code to call interface methods via RTTI

git-svn-id: trunk@29953 -

Jonas Maebe 10 năm trước cách đây
mục cha
commit
42aca4db46
1 tập tin đã thay đổi với 21 bổ sung2 xóa
  1. 21 2
      compiler/aarch64/cpupara.pas

+ 21 - 2
compiler/aarch64/cpupara.pas

@@ -291,8 +291,27 @@ unit cpupara;
           begin
             hp:=tparavarsym(paras[i]);
             { hidden function result parameter is passed in X8 (doesn't have to
-              be valid on return) }
-            if vo_is_funcret in hp.varoptions then
+              be valid on return) according to the ABI
+
+              -- don't follow the ABI for managed types, because
+               a) they are passed in registers as parameters, so we should also
+                  return them in a register to be ABI-compliant (which we can't
+                  because the entire compiler is built around the idea that
+                  they are returned by reference, for ref-counting performance
+                  and Delphi-compatibility reasons)
+               b) there are hacks in the system unit that expect that you can
+                  call
+                    function f: com_interface;
+                  as
+                    procedure p(out o: obj);
+                  That can only work in case we do not use x8 to return them
+                  from the function, but the regular first parameter register.
+
+              As the ABI says this behaviour is ok for C++ classes with a
+              non-trivial copy constructor or destructor, it seems reasonable
+              for us to do this for managed types as well.}
+            if (vo_is_funcret in hp.varoptions) and
+               not is_managed_type(hp.vardef) then
               begin
                 hp.paraloc[side].reset;
                 hp.paraloc[side].size:=OS_ADDR;