Browse Source

[PATCH 60/83] adding static linking

From fec5de9f0ad5c701407c765bea2af1da2403438a Mon Sep 17 00:00:00 2001
From: Dmitry Boyarintsev <[email protected]>
Date: Fri, 27 Sep 2019 16:45:45 -0400

git-svn-id: branches/wasm@45937 -
nickysn 5 years ago
parent
commit
d633176293
3 changed files with 106 additions and 15 deletions
  1. 3 3
      compiler/systems/i_wasm.pas
  2. 70 2
      compiler/systems/t_wasm.pas
  3. 33 10
      compiler/wasm/agwat.pas

+ 3 - 3
compiler/systems/i_wasm.pas

@@ -58,12 +58,12 @@ unit i_wasm;
             unitext      : '.ppu';
             unitlibext   : '.ppl';
             asmext       : '.wat';
-            objext       : '.wasm';
+            objext       : '.o';
             resext       : '';
-            resobjext    : '.wasm';
+            resobjext    : '.o';
             sharedlibext : ''; // keep it empty! The sharedlibext drives the export module name
                                // if this is populated, then the name should be cleared when generating import
-            staticlibext : '.wasm';
+            staticlibext : '.a';
             staticlibprefix : '';
             sharedlibprefix : '';
             sharedClibext : '.wasm';

+ 70 - 2
compiler/systems/t_wasm.pas

@@ -7,7 +7,9 @@ interface
 uses
   systems,
 
-  globtype,
+  globtype, globals,
+  aasmbase,
+  cfileutl, cutils, cclasses,
 
   import, export, aasmdata, aasmcpu,
   fmodule, ogbase,
@@ -36,8 +38,13 @@ type
 
   { tlinkerjvm }
 
+  { tlinkerwasm }
+
   tlinkerwasm=class(texternallinker)
+  public
     constructor Create;override;
+    procedure SetDefaultInfo;override;
+
     //function  MakeExecutable:boolean;override;
     function  MakeSharedLibrary:boolean;override;
   end;
@@ -58,10 +65,71 @@ begin
   inherited Create;
 end;
 
+procedure tlinkerwasm.SetDefaultInfo;
+begin
+  Info.DllCmd[1] := 'wasm-ld $SONAME $GCSECTIONS -o $EXE';
+  Info.DllCmd[2] := 'wasmtool --exportrename $INPUT $EXE';
+end;
+
 function tlinkerwasm.MakeSharedLibrary: boolean;
+var
+  GCSectionsStr  : ansistring;
+  binstr, cmdstr : Tcmdstr;
+  InitStr,
+  FiniStr,
+  SoNameStr      : string[80];
+  mapstr,ltostr  : TCmdStr;
+  success        : Boolean;
+
+  tmp : TCmdStrListItem;
+  tempFileName : ansistring;
 begin
-  Result := true;
+  //Result := true;
   //Result:=inherited MakeSharedLibrary;
+  if (cs_link_smart in current_settings.globalswitches) and
+     create_smartlink_sections then
+   GCSectionsStr:='--gc-sections'
+  else
+    GCSectionsStr:='';
+
+  SoNameStr:='';
+  SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
+  Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
+
+  tmp := TCmdStrListItem(ObjectFiles.First);
+  while Assigned(tmp) do begin
+    cmdstr := tmp.Str+ ' ' + cmdstr;
+    tmp := TCmdStrListItem(tmp.Next);
+  end;
+
+  if HasExports then
+    cmdstr := cmdstr + ' --export-dynamic'; //' --export-dynamic';
+
+  cmdstr := cmdstr + ' --no-entry --allow-undefined';
+
+  if success and (cs_link_strip in current_settings.globalswitches) then
+   begin
+     { only remove non global symbols and debugging info for a library }
+     cmdstr := cmdstr + ' --strip-all';
+   end;
+
+  //Replace(cmdstr,'$OPT',Info.ExtraOptions);
+  //Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
+  //Replace(cmdstr,'$INIT',InitStr);
+  //Replace(cmdstr,'$FINI',FiniStr);
+  Replace(cmdstr,'$SONAME',SoNameStr);
+  //Replace(cmdstr,'$MAP',mapstr);
+  //Replace(cmdstr,'$LTO',ltostr);
+  Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
+  writeln(utilsprefix+binstr,' ',cmdstr);
+  success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
+
+  SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
+  Replace(cmdstr,'$INPUT',current_module.objfilename );
+  Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
+  DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);
+
+  MakeSharedLibrary:=success;
 end;
 
 { texportlibwasm }

+ 33 - 10
compiler/wasm/agwat.pas

@@ -57,7 +57,7 @@ interface
        procedure WriteOutGlobalInt32(const aname: string; val: integer; isconst: boolean = true);
 
        procedure WriteInstruction(hp: tai);
-       procedure WriteProcDef(pd: tprocdef; stub: Boolean = false);
+       procedure WriteProcDef(pd: tprocdef; stub: Boolean = false; stubUnreachable: Boolean = true);
        procedure WriteProcParams(pd: tprocdef);
        procedure WriteProcResult(pd: tprocdef);
        procedure WriteSymtableProcdefs(st: TSymtable);
@@ -260,7 +260,7 @@ implementation
       writer.AsmLn;
     end;
 
-    procedure TWabtTextAssembler.WriteProcDef(pd: tprocdef; stub: Boolean );
+    procedure TWabtTextAssembler.WriteProcDef(pd: tprocdef; stub: Boolean; stubUnreachable: Boolean);
     var
       i : integer;
     begin
@@ -288,6 +288,9 @@ implementation
       if not stub then begin
         WriteTempAlloc(tcpuprocdef(pd).exprasmlist);
         WriteTree(tcpuprocdef(pd).exprasmlist);
+      end else begin
+        if stubUnreachable then
+          writer.AsmWriteLn(#9#9'unreachable');
       end;
       writer.AsmWriteln(#9')');
       writer.AsmLn;
@@ -597,9 +600,9 @@ implementation
         WriteSymtableProcdefs(current_module.globalsymtable);
         WriteSymtableProcdefs(current_module.localsymtable);
 
-        if current_module.islibrary then
-          WriteExports(current_asmdata.asmlists[al_exports])
-        else
+        if current_module.islibrary then begin
+          WriteExports(current_asmdata.asmlists[al_exports]);
+        end else
           WriteUnitExports(current_module.globalsymtable);
 
         //WriteSymtableStructDefs(current_module.globalsymtable);
@@ -763,12 +766,32 @@ implementation
     begin
       if not Assigned(p) then Exit;
       hp:=tai(p.First);
+      if not Assigned(hp) then Exit;
+
+      // writting out table, so wat2wasm can create reallocation symbols
+      writer.AsmWrite(#9'(table 0 funcref)');
+      writer.AsmWriteLn(#9'(elem 0 (i32.const 0) ');
+      while Assigned(hp) do begin
+        case hp.typ of
+          ait_importexport:
+          begin
+            x:=tai_impexp(hp);
+            writer.AsmWrite(#9#9);
+            writer.AsmWriteLn(GetWasmName(x.intname));
+          end;
+        end;
+        hp := tai_impexp(hp.Next);
+      end;
+      writer.AsmWriteLn(#9') ');
+
+      // writing export sections
+      hp:=tai(p.First);
       while Assigned(hp) do begin
         case hp.typ of
           ait_importexport:
           begin
             x:=tai_impexp(hp);
-            writer.AsmWrite('(export "');
+            writer.AsmWrite(#9#9'(export "');
             writer.AsmWrite(x.extname);
             writer.AsmWrite('" (');
             case x.symstype of
@@ -856,11 +879,11 @@ implementation
             else
               proc := nil;
             if proc<>nil then begin
-              writer.AsmWrite(#9'(import "_fpc_use" "');
+              {writer.AsmWrite(#9'(import "_fpc_use" "');
               writer.AsmWrite(proc.mangledname);
-              writer.AsmWrite('" ');
+              writer.AsmWrite('" ');}
               WriteProcDef(proc, true);
-              writer.AsmWrite(')');
+              //writer.AsmWrite(')');
             end;
           end;
         end;
@@ -954,7 +977,7 @@ implementation
          id     : as_wasm_wabt;
          idtxt  : 'Wabt';
          asmbin : 'wat2wasm';
-         asmcmd : '$EXTRAOPT $ASM';
+         asmcmd : '-r --no-canonicalize-leb128s -o $OBJ $EXTRAOPT $ASM';
          supported_targets : [system_wasm_wasm32];
          flags : [];
          labelprefix : 'L';