Browse Source

+ WebAssembly external asm writer: workaround for the 'missing functype' error,
produced by LLVM-MC versions 13 and above

Nikolay Nikolov 11 months ago
parent
commit
5e327453a8

+ 1 - 10
compiler/aggas.pas

@@ -71,6 +71,7 @@ interface
         destructor destroy; override;
         destructor destroy; override;
 {$ifdef WASM}
 {$ifdef WASM}
         procedure WriteFuncType(functype: TWasmFuncType);
         procedure WriteFuncType(functype: TWasmFuncType);
+        procedure WriteFuncTypeDirective(hp:tai_functype);virtual;abstract;
 {$endif WASM}
 {$endif WASM}
        private
        private
         setcount: longint;
         setcount: longint;
@@ -815,16 +816,6 @@ implementation
         end;
         end;
 
 
 {$ifdef WASM}
 {$ifdef WASM}
-      procedure WriteFuncTypeDirective(hp:tai_functype);
-        begin
-          writer.AsmWrite(#9'.functype'#9);
-          writer.AsmWrite(hp.funcname);
-          writer.AsmWrite(' ');
-          WriteFuncType(hp.functype);
-          writer.AsmLn;
-        end;
-
-
       procedure WriteTagType(hp: tai_tagtype);
       procedure WriteTagType(hp: tai_tagtype);
         var
         var
           wasm_basic_typ: TWasmBasicType;
           wasm_basic_typ: TWasmBasicType;

+ 4 - 2
compiler/wasm32/aasmcpu.pas

@@ -348,7 +348,8 @@ uses
       tai_functype = class(tai)
       tai_functype = class(tai)
         funcname: string;
         funcname: string;
         functype: TWasmFuncType;
         functype: TWasmFuncType;
-        constructor create(const afuncname: string; afunctype: TWasmFuncType);
+        is_forward: Boolean;
+        constructor create(const afuncname: string; afunctype: TWasmFuncType; aisforward: Boolean);
         destructor destroy;override;
         destructor destroy;override;
       end;
       end;
 
 
@@ -1862,10 +1863,11 @@ uses
 
 
     { tai_functype }
     { tai_functype }
 
 
-    constructor tai_functype.create(const afuncname: string; afunctype: TWasmFuncType);
+    constructor tai_functype.create(const afuncname: string; afunctype: TWasmFuncType; aisforward: Boolean);
       begin
       begin
         inherited Create;
         inherited Create;
         typ:=ait_functype;
         typ:=ait_functype;
+        is_forward:=aisforward;
         funcname:=afuncname;
         funcname:=afuncname;
         functype:=afunctype;
         functype:=afunctype;
       end;
       end;

+ 14 - 0
compiler/wasm32/agllvmmc.pas

@@ -44,6 +44,7 @@ interface
       function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
       function sectionname(atype:TAsmSectiontype;const aname:string;aorder:TAsmSectionOrder):string;override;
     public
     public
       constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
       constructor CreateWithWriter(info: pasminfo; wr: TExternalAssemblerOutputFile; freewriter, smart: boolean); override;
+      procedure WriteFuncTypeDirective(hp:tai_functype);override;
     end;
     end;
 
 
     { TLLVMMachineCodePlaygroundAssemblerV10 }
     { TLLVMMachineCodePlaygroundAssemblerV10 }
@@ -160,6 +161,19 @@ implementation
     end;
     end;
 
 
 
 
+  procedure TLLVMMachineCodePlaygroundAssembler.WriteFuncTypeDirective(hp: tai_functype);
+    begin
+      if not hp.is_forward or (FLLVMMajorVersion>=13) then
+        begin
+          writer.AsmWrite(#9'.functype'#9);
+          writer.AsmWrite(hp.funcname);
+          writer.AsmWrite(' ');
+          WriteFuncType(hp.functype);
+          writer.AsmLn;
+        end;
+    end;
+
+
   { TWASM32InstrWriter }
   { TWASM32InstrWriter }
 
 
 
 

+ 4 - 4
compiler/wasm32/hlcgcpu.pas

@@ -148,7 +148,7 @@ uses
 
 
       { Wasm-specific routines }
       { Wasm-specific routines }
 
 
-      procedure g_procdef(list:TAsmList;pd: tprocdef);
+      procedure g_procdef(list:TAsmList;pd: tprocdef;is_forward: Boolean);
       procedure g_maybe_checkforexceptions(list:TasmList); override;
       procedure g_maybe_checkforexceptions(list:TasmList); override;
 
 
       procedure a_load_stack_reg(list : TAsmList;size: tdef;reg: tregister);
       procedure a_load_stack_reg(list : TAsmList;size: tdef;reg: tregister);
@@ -2058,7 +2058,7 @@ implementation
       pd: tcpuprocdef;
       pd: tcpuprocdef;
     begin
     begin
       pd:=tcpuprocdef(current_procinfo.procdef);
       pd:=tcpuprocdef(current_procinfo.procdef);
-      g_procdef(list,pd);
+      g_procdef(list,pd,false);
 
 
       if not nostackframe then
       if not nostackframe then
         begin
         begin
@@ -2457,10 +2457,10 @@ implementation
       internalerror(2012090206);
       internalerror(2012090206);
     end;
     end;
 
 
-  procedure thlcgwasm.g_procdef(list: TAsmList; pd: tprocdef);
+  procedure thlcgwasm.g_procdef(list: TAsmList; pd: tprocdef; is_forward: Boolean);
     begin
     begin
       if not pd.is_generic then
       if not pd.is_generic then
-        list.Concat(tai_functype.create(pd.mangledname,tcpuprocdef(pd).create_functype));
+        list.Concat(tai_functype.create(pd.mangledname,tcpuprocdef(pd).create_functype,is_forward));
     end;
     end;
 
 
   procedure thlcgwasm.g_maybe_checkforexceptions(list: TasmList);
   procedure thlcgwasm.g_maybe_checkforexceptions(list: TasmList);

+ 7 - 5
compiler/wasm32/nwasmutil.pas

@@ -87,7 +87,7 @@ implementation
 
 
       procedure WriteImportDll(list: TAsmList; proc: tprocdef);
       procedure WriteImportDll(list: TAsmList; proc: tprocdef);
         begin
         begin
-          thlcgwasm(hlcg).g_procdef(list,proc);
+          thlcgwasm(hlcg).g_procdef(list,proc,false);
           list.Concat(tai_import_module.create(proc.mangledname,proc.import_dll^));
           list.Concat(tai_import_module.create(proc.mangledname,proc.import_dll^));
           list.Concat(tai_import_name.create(proc.mangledname,proc.import_name^));
           list.Concat(tai_import_name.create(proc.mangledname,proc.import_name^));
         end;
         end;
@@ -113,9 +113,9 @@ implementation
           if ((u.moduleflags * [mf_init,mf_finalize])<>[]) and assigned(u.globalsymtable) then
           if ((u.moduleflags * [mf_init,mf_finalize])<>[]) and assigned(u.globalsymtable) then
             begin
             begin
               if mf_init in u.moduleflags then
               if mf_init in u.moduleflags then
-                list.Concat(tai_functype.create(make_mangledname('INIT$',u.globalsymtable,''),TWasmFuncType.Create([],[])));
+                list.Concat(tai_functype.create(make_mangledname('INIT$',u.globalsymtable,''),TWasmFuncType.Create([],[]),false));
               if mf_finalize in u.moduleflags then
               if mf_finalize in u.moduleflags then
-                list.Concat(tai_functype.create(make_mangledname('FINALIZE$',u.globalsymtable,''),TWasmFuncType.Create([],[])));
+                list.Concat(tai_functype.create(make_mangledname('FINALIZE$',u.globalsymtable,''),TWasmFuncType.Create([],[]),false));
             end;
             end;
           for i:=0 to u.deflist.Count-1 do
           for i:=0 to u.deflist.Count-1 do
             begin
             begin
@@ -126,7 +126,9 @@ implementation
                   if (po_external in proc.procoptions) and (po_has_importdll in proc.procoptions) then
                   if (po_external in proc.procoptions) and (po_has_importdll in proc.procoptions) then
                     WriteImportDll(list,proc)
                     WriteImportDll(list,proc)
                   else if not proc.owner.iscurrentunit or (po_external in proc.procoptions) then
                   else if not proc.owner.iscurrentunit or (po_external in proc.procoptions) then
-                    thlcgwasm(hlcg).g_procdef(list,proc);
+                    thlcgwasm(hlcg).g_procdef(list,proc,false)
+                  else
+                    thlcgwasm(hlcg).g_procdef(list,proc,true);
                 end;
                 end;
             end;
             end;
         end;
         end;
@@ -170,7 +172,7 @@ implementation
                 if po_has_importdll in proc.procoptions then
                 if po_has_importdll in proc.procoptions then
                   WriteImportDll(list,proc)
                   WriteImportDll(list,proc)
                 else
                 else
-                  thlcgwasm(hlcg).g_procdef(list,proc);
+                  thlcgwasm(hlcg).g_procdef(list,proc,false);
             end;
             end;
          end;
          end;
       create_hlcodegen;
       create_hlcodegen;