Browse Source

+ write the externals to the symbol table

Nikolay Nikolov 3 years ago
parent
commit
2d2906205b
1 changed files with 77 additions and 6 deletions
  1. 77 6
      compiler/ogwasm.pas

+ 77 - 6
compiler/ogwasm.pas

@@ -40,6 +40,13 @@ interface
 
     type
 
+      { TWasmObjSymbol }
+
+      TWasmObjSymbol = class(TObjSymbol)
+        ImportIndex: Integer;
+        constructor create(AList:TFPHashObjectList;const AName:string);
+      end;
+
       { TWasmObjRelocation }
 
       TWasmObjRelocation = class(TObjRelocation)
@@ -94,8 +101,11 @@ interface
       TWasmObjOutput = class(tObjOutput)
       private
         FData: TWasmObjData;
+        FWasmSymbolTable: tdynamicarray;
+        FWasmSymbolTableEntriesCount: Integer;
         FWasmSections: array [TWasmSectionID] of tdynamicarray;
         FWasmCustomSections: array [TWasmCustomSectionType] of tdynamicarray;
+        FWasmLinkingSubsections: array [low(TWasmLinkingSubsectionType)..high(TWasmLinkingSubsectionType)] of tdynamicarray;
         procedure WriteUleb(d: tdynamicarray; v: uint64);
         procedure WriteUleb(w: TObjectWriter; v: uint64);
         procedure WriteSleb(d: tdynamicarray; v: int64);
@@ -110,6 +120,8 @@ interface
         function IsExternalFunction(sym: TObjSymbol): Boolean;
         procedure WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData);
         procedure WriteFunctionCode(dest: tdynamicarray; objsym: TObjSymbol);
+        procedure WriteSymbolTable;
+        procedure WriteLinkingSubsection(wlst: TWasmLinkingSubsectionType);
       protected
         function writeData(Data:TObjData):boolean;override;
       public
@@ -128,6 +140,16 @@ implementation
     uses
       verbose;
 
+{****************************************************************************
+                               TWasmObjSymbol
+****************************************************************************}
+
+    constructor TWasmObjSymbol.create(AList: TFPHashObjectList; const AName: string);
+      begin
+        inherited create(AList,AName);
+        ImportIndex:=-1;
+      end;
+
 {****************************************************************************
                               TWasmObjSymbolExtraData
 ****************************************************************************}
@@ -309,6 +331,7 @@ implementation
       begin
         inherited;
         CObjSection:=TWasmObjSection;
+        CObjSymbol:=TWasmObjSymbol;
         FObjSymbolsExtraDataList:=TFPHashObjectList.Create;
       end;
 
@@ -620,6 +643,24 @@ implementation
         encoded_locals.Free;
       end;
 
+    procedure TWasmObjOutput.WriteSymbolTable;
+      begin
+        WriteUleb(FWasmLinkingSubsections[WASM_SYMBOL_TABLE],FWasmSymbolTableEntriesCount);
+        FWasmSymbolTable.seek(0);
+        CopyDynamicArray(FWasmSymbolTable,FWasmLinkingSubsections[WASM_SYMBOL_TABLE],FWasmSymbolTable.size);
+      end;
+
+    procedure TWasmObjOutput.WriteLinkingSubsection(wlst: TWasmLinkingSubsectionType);
+      begin
+        if FWasmLinkingSubsections[wlst].size>0 then
+          begin
+            WriteByte(FWasmCustomSections[wcstLinking],Ord(wlst));
+            WriteUleb(FWasmCustomSections[wcstLinking],FWasmLinkingSubsections[wlst].size);
+            FWasmLinkingSubsections[wlst].seek(0);
+            CopyDynamicArray(FWasmLinkingSubsections[wlst],FWasmCustomSections[wcstLinking],FWasmLinkingSubsections[wlst].size);
+          end;
+      end;
+
     function TWasmObjOutput.writeData(Data:TObjData):boolean;
       var
         i: Integer;
@@ -627,10 +668,10 @@ implementation
         segment_count: Integer = 0;
         cur_seg_ofs: qword = 0;
         types_count,
-        imports_count: Integer;
+        imports_count, NextImportFunctionIndex: Integer;
         import_functions_count: Integer = 0;
         functions_count: Integer = 0;
-        objsym: TObjSymbol;
+        objsym: TWasmObjSymbol;
         cust_sec: TWasmCustomSectionType;
       begin
         FData:=TWasmObjData(Data);
@@ -643,7 +684,7 @@ implementation
 
         for i:=0 to Data.ObjSymbolList.Count-1 do
           begin
-            objsym:=TObjSymbol(Data.ObjSymbolList[i]);
+            objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
             if IsExternalFunction(objsym) then
               Inc(import_functions_count);
             if objsym.typ=AT_FUNCTION then
@@ -714,11 +755,14 @@ implementation
         WriteByte(FWasmSections[wsiImport],$7F);  { i32 }
         WriteByte(FWasmSections[wsiImport],$01);  { var }
         { import[2]..import[imports_count-2] }
+        NextImportFunctionIndex:=0;
         for i:=0 to Data.ObjSymbolList.Count-1 do
           begin
-            objsym:=TObjSymbol(Data.ObjSymbolList[i]);
+            objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
             if IsExternalFunction(objsym) then
               begin
+                objsym.ImportIndex:=NextImportFunctionIndex;
+                Inc(NextImportFunctionIndex);
                 WriteName(FWasmSections[wsiImport],'env');
                 WriteName(FWasmSections[wsiImport],objsym.Name);
                 WriteByte(FWasmSections[wsiImport],$00);  { func }
@@ -737,7 +781,7 @@ implementation
         WriteUleb(FWasmSections[wsiCode],functions_count);
         for i:=0 to Data.ObjSymbolList.Count-1 do
           begin
-            objsym:=TObjSymbol(Data.ObjSymbolList[i]);
+            objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
             if objsym.typ=AT_FUNCTION then
               begin
                 WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx);
@@ -745,6 +789,24 @@ implementation
               end;
           end;
 
+        for i:=0 to Data.ObjSymbolList.Count-1 do
+          begin
+            objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
+            if IsExternalFunction(objsym) then
+              begin
+                Inc(FWasmSymbolTableEntriesCount);
+                WriteByte(FWasmSymbolTable,Ord(SYMTAB_FUNCTION));
+                WriteUleb(FWasmSymbolTable,WASM_SYM_UNDEFINED);
+                WriteUleb(FWasmSymbolTable,objsym.ImportIndex);
+              end
+            else if objsym.typ=AT_FUNCTION then
+              begin
+              end;
+          end;
+
+        WriteSymbolTable;
+        WriteLinkingSubsection(WASM_SYMBOL_TABLE);
+
         Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic));
         Writer.write(WasmVersion,SizeOf(WasmVersion));
 
@@ -759,7 +821,7 @@ implementation
         Writeln('ObjSymbolList:');
         for i:=0 to Data.ObjSymbolList.Count-1 do
           begin
-            objsym:=TObjSymbol(Data.ObjSymbolList[i]);
+            objsym:=TWasmObjSymbol(Data.ObjSymbolList[i]);
             Write(objsym.Name, ' bind=', objsym.Bind, ' typ=', objsym.typ, ' address=', objsym.address, ' objsection=');
             if assigned(objsym.objsection) then
               Write(objsym.objsection.Name)
@@ -782,6 +844,7 @@ implementation
       var
         i: TWasmSectionID;
         j: TWasmCustomSectionType;
+        k: TWasmLinkingSubsectionType;
       begin
         inherited;
         cobjdata:=TWasmObjData;
@@ -789,17 +852,25 @@ implementation
           FWasmSections[i] := tdynamicarray.create(SectionDataMaxGrow);
         for j in TWasmCustomSectionType do
           FWasmCustomSections[j] := tdynamicarray.create(SectionDataMaxGrow);
+        for k:=low(TWasmLinkingSubsectionType) to high(TWasmLinkingSubsectionType) do
+          FWasmLinkingSubsections[k] := tdynamicarray.create(SectionDataMaxGrow);
+        FWasmSymbolTable:=tdynamicarray.create(SectionDataMaxGrow);
+        FWasmSymbolTableEntriesCount:=0;
       end;
 
     destructor TWasmObjOutput.destroy;
       var
         i: TWasmSectionID;
         j: TWasmCustomSectionType;
+        k: TWasmLinkingSubsectionType;
       begin
         for i in TWasmSectionID do
           FWasmSections[i].Free;
         for j in TWasmCustomSectionType do
           FWasmCustomSections[j].Free;
+        for k:=low(TWasmLinkingSubsectionType) to high(TWasmLinkingSubsectionType) do
+          FWasmLinkingSubsections[k].Free;
+        FWasmSymbolTable.Free;
         inherited destroy;
       end;