Browse Source

[PATCH 64/83] update push_addr_param

From 228ebfa78cdd147212f917be02bfa42b3b413487 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Tue, 15 Oct 2019 11:08:19 -0400

git-svn-id: branches/wasm@45941 -
nickysn 5 years ago
parent
commit
0df53929cc
1 changed files with 38 additions and 11 deletions
  1. 38 11
      compiler/wasm/cpupara.pas

+ 38 - 11
compiler/wasm/cpupara.pas

@@ -108,22 +108,49 @@ implementation
     { true if a parameter is too large to copy and only the address is pushed }
     function tcpuparamanager.push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;
       begin
-        {result:=
-          jvmimplicitpointertype(def) or
-          ((def.typ=formaldef) and
-           not(varspez in [vs_var,vs_out]));}
-        //todo:
-        result := false;
+        result:=false;
+        { var,out,constref always require address }
+        if varspez in [vs_var,vs_out,vs_constref] then
+          begin
+            result:=true;
+            exit;
+          end;
+        { Only vs_const, vs_value here }
+        case def.typ of
+          variantdef,
+          formaldef :
+            result:=true;
+          recorddef :
+            begin
+              { Delphi stdcall passes records on the stack for call by value }
+              result:=(varspez=vs_const) or (def.size=0);
+            end;
+          arraydef :
+            begin
+              result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
+                 is_open_array(def) or
+                 is_array_of_const(def) or
+                 is_array_constructor(def);
+            end;
+          objectdef :
+            result:=is_object(def);
+          stringdef :
+            result:= (tstringdef(def).stringtype in [st_shortstring,st_longstring]);
+          procvardef :
+            result:=not(calloption in cdecl_pocalls) and not tprocvardef(def).is_addressonly;
+          setdef :
+            result:=not is_smallset(def);
+          else
+            ;
+        end;
+
       end;
 
 
     function tcpuparamanager.push_size(varspez: tvarspez; def: tdef; calloption: tproccalloption): longint;
       begin
         { all aggregate types are emulated using indirect pointer types }
-        if def.typ in [arraydef,recorddef,setdef,stringdef] then
-          result:=4
-        else
-          result:=inherited;
+        result:=inherited;
       end;
 
 
@@ -244,7 +271,7 @@ implementation
                 paracgsize:=OS_ADDR;
                 paradef:=ptruinttype;
               end
-            else if wasmAlwayInMem(hp.vardef) then
+            else if push_addr_param(hp.varspez, hp.vardef,p.proccalloption) then
               begin
                 paracgsize:=OS_ADDR;
                 paradef:=cpointerdef.getreusable_no_free(hp.vardef);