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,
     aasmbase,aasmtai,aasmdata,aasmcpu,
     assemble
     assemble
     ,cutils
     ,cutils
-    ,cpubase
+    ,cpubase, cgbase
     ,fmodule
     ,fmodule
     ,verbose, itcpuwasm
     ,verbose, itcpuwasm
     ,cfileutl;
     ,cfileutl;
@@ -288,7 +288,7 @@ implementation
       WriteProcResult(pd);
       WriteProcResult(pd);
 
 
       if not stub then begin
       if not stub then begin
-        WriteTempAlloc(tcpuprocdef(pd).exprasmlist);
+        //WriteTempAlloc(tcpuprocdef(pd).exprasmlist);
         WriteTree(tcpuprocdef(pd).exprasmlist);
         WriteTree(tcpuprocdef(pd).exprasmlist);
       end else begin
       end else begin
         if stubUnreachable then
         if stubUnreachable then
@@ -312,9 +312,18 @@ implementation
           begin
           begin
             prm := tcpuparavarsym(pd.paras[i]);
             prm := tcpuparavarsym(pd.paras[i]);
             writer.AsmWrite(#9'(param'#9);
             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;
             end;
             writer.AsmWrite(')');
             writer.AsmWrite(')');
             writer.AsmLn;
             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  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  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_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;
         function  push_size(varspez: tvarspez; def: tdef; calloption: tproccalloption): longint;override;
         {Returns a structure giving the information on the storage of the parameter
         {Returns a structure giving the information on the storage of the parameter
         (which must be an integer parameter)
         (which must be an integer parameter)
@@ -118,17 +117,6 @@ implementation
       end;
       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;
     function tcpuparamanager.push_size(varspez: tvarspez; def: tdef; calloption: tproccalloption): longint;
       begin
       begin
         { all aggregate types are emulated using indirect pointer types }
         { all aggregate types are emulated using indirect pointer types }
@@ -256,12 +244,11 @@ implementation
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
                 paradef:=ptruinttype;
                 paradef:=ptruinttype;
               end
               end
-            //todo: wasm should have the similar
-            {else if jvmimplicitpointertype(hp.vardef) then
+            else if wasmAlwayInMem(hp.vardef) then
               begin
               begin
                 paracgsize:=OS_ADDR;
                 paracgsize:=OS_ADDR;
                 paradef:=cpointerdef.getreusable_no_free(hp.vardef);
                 paradef:=cpointerdef.getreusable_no_free(hp.vardef);
-              end}
+              end
             else
             else
               begin
               begin
                 paracgsize:=def_cgsize(hp.vardef);
                 paracgsize:=def_cgsize(hp.vardef);
@@ -278,9 +265,8 @@ implementation
             paraloc:=hp.paraloc[side].add_location;
             paraloc:=hp.paraloc[side].add_location;
             { All parameters are passed on the evaluation stack, pushed from
             { All parameters are passed on the evaluation stack, pushed from
               left to right (including self, if applicable). At the callee side,
               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^.reference.offset:=paraofs;
             paraloc^.size:=paracgsize;
             paraloc^.size:=paracgsize;
             paraloc^.def:=paradef;
             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
       { 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
         that case, ref contains a pointer to the actual data and we simply
         return that pointer) }
         return that pointer) }
-      if not wasmimplicitpointertype(fromsize) then
+      if not wasmAlwayInMem(fromsize) then
         internalerror(2010120534);
         internalerror(2010120534);
 
 
       if assigned(ref.symbol) then begin
       if assigned(ref.symbol) then begin
@@ -1803,7 +1803,7 @@ implementation
         end
         end
       else
       else
         begin
         begin
-          if not wasmimplicitpointertype(def) then
+          if not wasmAlwayInMem(def) then
             begin
             begin
               { passed by reference in array of single element; l contains the
               { passed by reference in array of single element; l contains the
                 base address of the array }
                 base address of the array }
@@ -1969,7 +1969,7 @@ implementation
       opc:=loadstoreopc(size,false,false,finishandval);
       opc:=loadstoreopc(size,false,false,finishandval);
       list.concat(taicpu.op_reg(opc,reg));
       list.concat(taicpu.op_reg(opc,reg));
       { avoid problems with getting the size of an open array etc }
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
         size:=ptruinttype;
       decstack(list,1);
       decstack(list,1);
     end;
     end;
@@ -1986,7 +1986,7 @@ implementation
 
 
       list.concat(taicpu.op_ref(opc,ref));
       list.concat(taicpu.op_ref(opc,ref));
       { avoid problems with getting the size of an open array etc }
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
         size:=ptruinttype;
       decstack(list,1+extra_slots);
       decstack(list,1+extra_slots);
     end;
     end;
@@ -1999,7 +1999,7 @@ implementation
       opc:=loadstoreopc(size,true,false,finishandval);
       opc:=loadstoreopc(size,true,false,finishandval);
       list.concat(taicpu.op_reg(opc,reg));
       list.concat(taicpu.op_reg(opc,reg));
       { avoid problems with getting the size of an open array etc }
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
         size:=ptruinttype;
       incstack(list,1);
       incstack(list,1);
       if finishandval<>-1 then
       if finishandval<>-1 then
@@ -2019,7 +2019,7 @@ implementation
       list.concat(taicpu.op_ref(opc,ref));
       list.concat(taicpu.op_ref(opc,ref));
 
 
       { avoid problems with getting the size of an open array etc }
       { avoid problems with getting the size of an open array etc }
-      if wasmimplicitpointertype(size) then
+      if wasmAlwayInMem(size) then
         size:=ptruinttype;
         size:=ptruinttype;
       incstack(list,1-extra_slots);
       incstack(list,1-extra_slots);
       if finishandval<>-1 then
       if finishandval<>-1 then
@@ -2324,7 +2324,7 @@ implementation
             begin
             begin
               { nothing }
               { nothing }
             end
             end
-          else if wasmimplicitpointertype(vs.vardef) then
+          else if wasmAlwayInMem(vs.vardef) then
             allocate_implicit_struct_with_base_ref(list,vs,ref)
             allocate_implicit_struct_with_base_ref(list,vs,ref)
           { enums are class instances in Java, while they are ordinals in
           { enums are class instances in Java, while they are ordinals in
             Pascal. When they are initialized with enum(0), such as in
             Pascal. When they are initialized with enum(0), such as in
@@ -2377,7 +2377,7 @@ implementation
           sym:=tsym(obj.symtable.symlist[i]);
           sym:=tsym(obj.symtable.symlist[i]);
           if (sym.typ=fieldvarsym) and
           if (sym.typ=fieldvarsym) and
              not(sp_static in sym.symoptions) and
              not(sp_static in sym.symoptions) and
-             (wasmimplicitpointertype(tfieldvarsym(sym).vardef) or
+             (wasmAlwayInMem(tfieldvarsym(sym).vardef) or
               ((tfieldvarsym(sym).vardef.typ=enumdef) and
               ((tfieldvarsym(sym).vardef.typ=enumdef) and
                get_enum_init_val_ref(tfieldvarsym(sym).vardef,ref))) then
                get_enum_init_val_ref(tfieldvarsym(sym).vardef,ref))) then
             begin
             begin
@@ -2400,7 +2400,7 @@ implementation
     begin
     begin
       { replace special types with their equivalent class type }
       { replace special types with their equivalent class type }
       if (checkdef.typ=pointerdef) and
       if (checkdef.typ=pointerdef) and
-         wasmimplicitpointertype(tpointerdef(checkdef).pointeddef) then
+         wasmAlwayInMem(tpointerdef(checkdef).pointeddef) then
         checkdef:=tpointerdef(checkdef).pointeddef;
         checkdef:=tpointerdef(checkdef).pointeddef;
       if (checkdef=voidpointertype) or
       if (checkdef=voidpointertype) or
          (checkdef.typ=formaldef) then
          (checkdef.typ=formaldef) then

+ 7 - 16
compiler/wasm/wasmdef.pas

@@ -8,9 +8,9 @@ uses
   symtype, symdef, symconst, constexp
   symtype, symdef, symconst, constexp
   ,defutil;
   ,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;
     function get_para_push_size(def: tdef): tdef;
 
 
@@ -34,24 +34,15 @@ implementation
         end;
         end;
     end;
     end;
 
 
-  function wasmimplicitpointertype(def: tdef): boolean;
+  function wasmAlwayInMem(def: tdef): boolean;
     begin
     begin
       case def.typ of
       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,
         filedef,
         recorddef,
         recorddef,
-        setdef:
+        objectdef,
+        stringdef:
           result:=true;
           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
         else
           result:=false;
           result:=false;
       end;
       end;