Browse Source

[PATCH 62/83] update code generation for record types

From 887824559adec40e56b774233763d790397357e2 Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Thu, 3 Oct 2019 17:22:22 -0400

git-svn-id: branches/wasm@45939 -
nickysn 5 years ago
parent
commit
d68eecda92
4 changed files with 34 additions and 48 deletions
  1. 14 5
      compiler/wasm/agwat.pas
  2. 4 18
      compiler/wasm/cpupara.pas
  3. 9 9
      compiler/wasm/hlcgcpu.pas
  4. 7 16
      compiler/wasm/wasmdef.pas

+ 14 - 5
compiler/wasm/agwat.pas

@@ -35,7 +35,7 @@ interface
     aasmbase,aasmtai,aasmdata,aasmcpu,
     assemble
     ,cutils
-    ,cpubase
+    ,cpubase, cgbase
     ,fmodule
     ,verbose, itcpuwasm
     ,cfileutl;
@@ -288,7 +288,7 @@ implementation
       WriteProcResult(pd);
 
       if not stub then begin
-        WriteTempAlloc(tcpuprocdef(pd).exprasmlist);
+        //WriteTempAlloc(tcpuprocdef(pd).exprasmlist);
         WriteTree(tcpuprocdef(pd).exprasmlist);
       end else begin
         if stubUnreachable then
@@ -312,9 +312,18 @@ implementation
           begin
             prm := tcpuparavarsym(pd.paras[i]);
             writer.AsmWrite(#9'(param'#9);
-            case prm.getsize of
-              1..4: writer.AsmWrite('i32');
-              8: writer.AsmWrite('i64');
+            case prm.paraloc[calleeside].Size of
+              OS_8..OS_32, OS_S8..OS_S32:
+                writer.AsmWrite('i32');
+              OS_64, OS_S64:
+                writer.AsmWrite('i64');
+              OS_F32:
+                writer.AsmWrite('f32');
+              OS_F64:
+                writer.AsmWrite('f64');
+            else
+              // unsupported calleeside parameter type
+              Internalerror(2019093001);
             end;
             writer.AsmWrite(')');
             writer.AsmLn;

+ 4 - 18
compiler/wasm/cpupara.pas

@@ -39,7 +39,6 @@ interface
         function  push_high_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
         function  keep_para_array_range(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean; override;
         function  push_addr_param(varspez:tvarspez;def : tdef;calloption : tproccalloption) : boolean;override;
-        function  push_copyout_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean; override;
         function  push_size(varspez: tvarspez; def: tdef; calloption: tproccalloption): longint;override;
         {Returns a structure giving the information on the storage of the parameter
         (which must be an integer parameter)
@@ -118,17 +117,6 @@ implementation
       end;
 
 
-    function tcpuparamanager.push_copyout_param(varspez: tvarspez; def: tdef; calloption: tproccalloption): boolean;
-      begin
-        { in principle also for vs_constref, but since we can't have real
-          references, that won't make a difference }
-        {result:=
-          (varspez in [vs_var,vs_out,vs_constref]) and
-          not jvmimplicitpointertype(def);}
-        Result := false;
-      end;
-
-
     function tcpuparamanager.push_size(varspez: tvarspez; def: tdef; calloption: tproccalloption): longint;
       begin
         { all aggregate types are emulated using indirect pointer types }
@@ -256,12 +244,11 @@ implementation
                 paracgsize:=OS_ADDR;
                 paradef:=ptruinttype;
               end
-            //todo: wasm should have the similar
-            {else if jvmimplicitpointertype(hp.vardef) then
+            else if wasmAlwayInMem(hp.vardef) then
               begin
                 paracgsize:=OS_ADDR;
                 paradef:=cpointerdef.getreusable_no_free(hp.vardef);
-              end}
+              end
             else
               begin
                 paracgsize:=def_cgsize(hp.vardef);
@@ -278,9 +265,8 @@ implementation
             paraloc:=hp.paraloc[side].add_location;
             { All parameters are passed on the evaluation stack, pushed from
               left to right (including self, if applicable). At the callee side,
-              they're available as local variables 0..n-1 (with 64 bit values
-              taking up two slots) }
-            paraloc^.loc:=LOC_REFERENCE;;
+              they're available as local variables 0..n-1  }
+            paraloc^.loc:=LOC_REFERENCE;
             paraloc^.reference.offset:=paraofs;
             paraloc^.size:=paracgsize;
             paraloc^.def:=paradef;

+ 9 - 9
compiler/wasm/hlcgcpu.pas

@@ -1135,7 +1135,7 @@ implementation
       { only allowed for types that are not implicit pointers in Pascal (in
         that case, ref contains a pointer to the actual data and we simply
         return that pointer) }
-      if not wasmimplicitpointertype(fromsize) then
+      if not wasmAlwayInMem(fromsize) then
         internalerror(2010120534);
 
       if assigned(ref.symbol) then begin
@@ -1803,7 +1803,7 @@ implementation
         end
       else
         begin
-          if not wasmimplicitpointertype(def) then
+          if not wasmAlwayInMem(def) then
             begin
               { passed by reference in array of single element; l contains the
                 base address of the array }
@@ -1969,7 +1969,7 @@ implementation
       opc:=loadstoreopc(size,false,false,finishandval);
       list.concat(taicpu.op_reg(opc,reg));
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
       decstack(list,1);
     end;
@@ -1986,7 +1986,7 @@ implementation
 
       list.concat(taicpu.op_ref(opc,ref));
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
       decstack(list,1+extra_slots);
     end;
@@ -1999,7 +1999,7 @@ implementation
       opc:=loadstoreopc(size,true,false,finishandval);
       list.concat(taicpu.op_reg(opc,reg));
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
       incstack(list,1);
       if finishandval<>-1 then
@@ -2019,7 +2019,7 @@ implementation
       list.concat(taicpu.op_ref(opc,ref));
 
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
       incstack(list,1-extra_slots);
       if finishandval<>-1 then
@@ -2324,7 +2324,7 @@ implementation
             begin
               { nothing }
             end
-          else if wasmimplicitpointertype(vs.vardef) then
+          else if wasmAlwayInMem(vs.vardef) then
             allocate_implicit_struct_with_base_ref(list,vs,ref)
           { enums are class instances in Java, while they are ordinals in
             Pascal. When they are initialized with enum(0), such as in
@@ -2377,7 +2377,7 @@ implementation
           sym:=tsym(obj.symtable.symlist[i]);
           if (sym.typ=fieldvarsym) and
              not(sp_static in sym.symoptions) and
-             (wasmimplicitpointertype(tfieldvarsym(sym).vardef) or
+             (wasmAlwayInMem(tfieldvarsym(sym).vardef) or
               ((tfieldvarsym(sym).vardef.typ=enumdef) and
                get_enum_init_val_ref(tfieldvarsym(sym).vardef,ref))) then
             begin
@@ -2400,7 +2400,7 @@ implementation
     begin
       { replace special types with their equivalent class type }
       if (checkdef.typ=pointerdef) and
-         wasmimplicitpointertype(tpointerdef(checkdef).pointeddef) then
+         wasmAlwayInMem(tpointerdef(checkdef).pointeddef) then
         checkdef:=tpointerdef(checkdef).pointeddef;
       if (checkdef=voidpointertype) or
          (checkdef.typ=formaldef) then

+ 7 - 16
compiler/wasm/wasmdef.pas

@@ -8,9 +8,9 @@ uses
   symtype, symdef, symconst, constexp
   ,defutil;
 
-    { returns whether a def is emulated using an implicit pointer type on the
-      WebAssembly target (e.g., records, regular arrays, ...) }
-    function wasmimplicitpointertype(def: tdef): boolean;
+    { returns whether a def always resides in memory,
+      rather than in wasm local variables...) }
+    function wasmAlwayInMem(def: tdef): boolean;
 
     function get_para_push_size(def: tdef): tdef;
 
@@ -34,24 +34,15 @@ implementation
         end;
     end;
 
-  function wasmimplicitpointertype(def: tdef): boolean;
+  function wasmAlwayInMem(def: tdef): boolean;
     begin
       case def.typ of
-        arraydef:
-          result:=(tarraydef(def).highrange>=tarraydef(def).lowrange) or
-              is_open_array(def) or
-              is_array_of_const(def) or
-              is_array_constructor(def);
+        arraydef,
         filedef,
         recorddef,
-        setdef:
+        objectdef,
+        stringdef:
           result:=true;
-        objectdef:
-          result:=is_object(def);
-        stringdef :
-          result:=tstringdef(def).stringtype in [st_shortstring,st_longstring];
-        procvardef:
-          result:=not tprocvardef(def).is_addressonly;
         else
           result:=false;
       end;