Browse Source

* WebAssembly: refactored tai_local, so that it is a single directive,
containing multiple locals, instead of creating multiple tai_local directives,
each containing a single local. No functional changes.

Nikolay Nikolov 10 months ago
parent
commit
b9ca30165c

+ 18 - 9
compiler/aggas.pas

@@ -839,6 +839,23 @@ implementation
             end;
             end;
           writer.AsmLn;
           writer.AsmLn;
         end;
         end;
+
+      procedure WriteWasmLocalDirective(hp: tai_local);
+        var
+          t: TWasmBasicType;
+          first: boolean=true;
+        begin
+          writer.AsmWrite(#9'.local'#9);
+          for t in tai_local(hp).locals do
+            begin
+              if first then
+                first:=false
+              else
+                writer.AsmWrite(', ');
+              writer.AsmWrite(gas_wasm_basic_type_str[t]);
+            end;
+          writer.AsmLn;
+        end;
 {$endif WASM}
 {$endif WASM}
 
 
     var
     var
@@ -1638,15 +1655,7 @@ implementation
 
 
 {$ifdef WASM}
 {$ifdef WASM}
            ait_local:
            ait_local:
-             begin
-               if tai_local(hp).first then
-                 writer.AsmWrite(#9'.local'#9)
-               else
-                 writer.AsmWrite(', ');
-               writer.AsmWrite(gas_wasm_basic_type_str[tai_local(hp).bastyp]);
-               if tai_local(hp).last then
-                 writer.AsmLn;
-             end;
+             WriteWasmLocalDirective(tai_local(hp));
            ait_globaltype:
            ait_globaltype:
              begin
              begin
                writer.AsmWrite(#9'.globaltype'#9);
                writer.AsmWrite(#9'.globaltype'#9);

+ 3 - 1
compiler/ogwasm.pas

@@ -1206,9 +1206,11 @@ implementation
     procedure TWasmObjData.DeclareLocal(al: tai_local);
     procedure TWasmObjData.DeclareLocal(al: tai_local);
       var
       var
         ObjSymExtraData: TWasmObjSymbolExtraData;
         ObjSymExtraData: TWasmObjSymbolExtraData;
+        t: TWasmBasicType;
       begin
       begin
         ObjSymExtraData:=TWasmObjSymbolExtraData(FObjSymbolsExtraDataList.Find(FLastFuncName));
         ObjSymExtraData:=TWasmObjSymbolExtraData(FObjSymbolsExtraDataList.Find(FLastFuncName));
-        ObjSymExtraData.AddLocal(al.bastyp);
+        for t in al.locals do
+          ObjSymExtraData.AddLocal(t);
       end;
       end;
 
 
     procedure TWasmObjData.symbolpairdefine(akind: TSymbolPairKind; const asym, avalue: string);
     procedure TWasmObjData.symbolpairdefine(akind: TSymbolPairKind; const asym, avalue: string);

+ 17 - 6
compiler/wasm32/aasmcpu.pas

@@ -325,10 +325,10 @@ uses
       { tai_local }
       { tai_local }
 
 
       tai_local = class(tai)
       tai_local = class(tai)
-        bastyp: TWasmBasicType;
-        first: boolean;
-        last: boolean;
-        constructor create(abasictype: TWasmBasicType);
+        locals: TWasmLocalsDynArray;
+        constructor create(alocals: TWasmLocalsDynArray);
+        procedure AddLocal(abasictype: TWasmBasicType);
+        procedure AddLocals(alocals: TWasmLocalsDynArray);
       end;
       end;
 
 
       { tai_globaltype }
       { tai_globaltype }
@@ -1892,13 +1892,24 @@ uses
 
 
     { tai_local }
     { tai_local }
 
 
-    constructor tai_local.create(abasictype: TWasmBasicType);
+    constructor tai_local.create(alocals: TWasmLocalsDynArray);
       begin
       begin
         inherited Create;
         inherited Create;
-        bastyp := abasictype;
+        locals := Copy(alocals);
         typ := ait_local;
         typ := ait_local;
       end;
       end;
 
 
+    procedure tai_local.AddLocal(abasictype: TWasmBasicType);
+      begin
+        SetLength(locals,Length(locals)+1);
+        locals[high(locals)]:=abasictype;
+      end;
+
+    procedure tai_local.AddLocals(alocals: TWasmLocalsDynArray);
+      begin
+        locals:=Concat(locals,alocals);
+      end;
+
     { timpexp_ai }
     { timpexp_ai }
 
 
       constructor tai_export_name.create(const aextname, aintname: ansistring;
       constructor tai_export_name.create(const aextname, aintname: ansistring;

+ 8 - 4
compiler/wasm32/agwasa.pas

@@ -401,6 +401,7 @@ implementation
         i,pos    : longint;
         i,pos    : longint;
         InlineLevel : longint;
         InlineLevel : longint;
         do_line  : boolean;
         do_line  : boolean;
+        t: TWasmBasicType;
       const
       const
         WasmBasicTypeStr : array [TWasmBasicType] of string = ('unknown','i32','i64','f32','f64','funcref','externref','v128');
         WasmBasicTypeStr : array [TWasmBasicType] of string = ('unknown','i32','i64','f32','f64','funcref','externref','v128');
 
 
@@ -621,10 +622,13 @@ implementation
 
 
              ait_local :
              ait_local :
                begin
                begin
-                 writer.AsmWrite(#9#9'(local ');
-                 writer.AsmWrite( WasmBasicTypeStr[ tai_local(hp).bastyp ] );
-                 writer.AsmWrite(')');
-                 writer.AsmLn;
+                 for t in tai_local(hp).locals do
+                   begin
+                     writer.AsmWrite(#9#9'(local ');
+                     writer.AsmWrite( WasmBasicTypeStr[ t ] );
+                     writer.AsmWrite(')');
+                     writer.AsmLn;
+                   end;
                end;
                end;
 
 
              else
              else

+ 1 - 0
compiler/wasm32/cpubase.pas

@@ -140,6 +140,7 @@ uses
         wbt_v128
         wbt_v128
       );
       );
       TWasmResultType = array of TWasmBasicType;
       TWasmResultType = array of TWasmBasicType;
+      TWasmLocalsDynArray = array of TWasmBasicType;
 
 
       { TWasmFuncType }
       { TWasmFuncType }
 
 

+ 7 - 15
compiler/wasm32/cpupi.pas

@@ -897,12 +897,11 @@ implementation
         function prepare_locals: TAsmList;
         function prepare_locals: TAsmList;
           var
           var
             local: tai_local;
             local: tai_local;
-            first: Boolean;
             l : TWasmLocal;
             l : TWasmLocal;
           begin
           begin
             result:=TAsmList.create;
             result:=TAsmList.create;
-            local:=nil;
-            first:=true;
+            local:=tai_local.create([]);
+            result.Concat(local);
             l:=ttgwasm(tg).localvars.first;
             l:=ttgwasm(tg).localvars.first;
             FFuncType:=findfirst_tai_functype(aktproccode).functype;
             FFuncType:=findfirst_tai_functype(aktproccode).functype;
             FLocals:=Copy(FFuncType.params);
             FLocals:=Copy(FFuncType.params);
@@ -912,30 +911,23 @@ implementation
               begin
               begin
                 SetLength(FLocals,Length(FLocals)+1);
                 SetLength(FLocals,Length(FLocals)+1);
                 FLocals[High(FLocals)]:=l.typ;
                 FLocals[High(FLocals)]:=l.typ;
-                local:=tai_local.create(l.typ);
-                local.first:=first;
-                first:=false;
-                result.Concat(local);
+                local.AddLocal(l.typ);
                 l:=l.nextseq;
                 l:=l.nextseq;
                 Inc(FFirstFreeLocal);
                 Inc(FFirstFreeLocal);
               end;
               end;
           end;
           end;
 
 
         procedure add_extra_allocated_locals(localslist: TAsmList);
         procedure add_extra_allocated_locals(localslist: TAsmList);
-          var
-            t: TWasmBasicType;
           begin
           begin
-            for t in FAllocatedLocals do
-              localslist.Concat(tai_local.create(t));
+            if tai(localslist.First).typ<>ait_local then
+              internalerror(2024081501);
+            tai_local(localslist.First).AddLocals(FAllocatedLocals);
           end;
           end;
 
 
         procedure insert_localslist(destlist,localslist: TAsmList);
         procedure insert_localslist(destlist,localslist: TAsmList);
           begin
           begin
             if assigned(localslist) then
             if assigned(localslist) then
-              begin
-                tai_local(localslist.Last).last:=true;
-                destlist.insertListAfter(findfirst_tai_functype(destlist),localslist);
-              end;
+              destlist.insertListAfter(findfirst_tai_functype(destlist),localslist);
           end;
           end;
 
 
         procedure check_goto_br_instructions(list: TAsmList; out HasGotoBrInstructions: boolean);
         procedure check_goto_br_instructions(list: TAsmList; out HasGotoBrInstructions: boolean);