Browse Source

+ wasm resource writer: write the linking custom section

Nikolay Nikolov 1 year ago
parent
commit
866f3ffa2a
1 changed files with 31 additions and 0 deletions
  1. 31 0
      packages/fcl-res/src/wasmwriter.pp

+ 31 - 0
packages/fcl-res/src/wasmwriter.pp

@@ -45,12 +45,15 @@ type
     fDataCurOfs : longword;
     fDataCurOfs : longword;
     FWasmSections: array [TWasmSectionID] of TMemoryStream;
     FWasmSections: array [TWasmSectionID] of TMemoryStream;
     FDataSegments: array [TWasmResourceDataSegment] of TMemoryStream;
     FDataSegments: array [TWasmResourceDataSegment] of TMemoryStream;
+    FWasmCustomSections: array [TWasmCustomSectionType] of TMemoryStream;
     function NextAligned(aBound, aValue : longword) : longword;
     function NextAligned(aBound, aValue : longword) : longword;
     procedure PrescanResourceTree;
     procedure PrescanResourceTree;
     function PrescanNode(aNode : TResourceTreeNode; aNodeSize : longword) : longword;
     function PrescanNode(aNode : TResourceTreeNode; aNodeSize : longword) : longword;
     procedure WriteResHeader(aResources : TResources);
     procedure WriteResHeader(aResources : TResources);
     procedure WriteWasmSection(aStream: TStream; wsid: TWasmSectionID);
     procedure WriteWasmSection(aStream: TStream; wsid: TWasmSectionID);
     procedure WriteWasmSectionIfNotEmpty(aStream: TStream; wsid: TWasmSectionID);
     procedure WriteWasmSectionIfNotEmpty(aStream: TStream; wsid: TWasmSectionID);
+    procedure WriteWasmCustomSection(aStream: TStream; wcst: TWasmCustomSectionType);
+    procedure WriteCustomSectionNames;
     procedure WriteImportSection;
     procedure WriteImportSection;
     procedure WriteDataSegments;
     procedure WriteDataSegments;
   protected
   protected
@@ -198,6 +201,23 @@ begin
     WriteWasmSection(aStream,wsid);
     WriteWasmSection(aStream,wsid);
 end;
 end;
 
 
+procedure TWasmResourceWriter.WriteWasmCustomSection(aStream: TStream;
+  wcst: TWasmCustomSectionType);
+begin
+  aStream.WriteByte(0);
+  WriteUleb(aStream,FWasmCustomSections[wcst].size);
+  aStream.CopyFrom(FWasmCustomSections[wcst],0);
+end;
+
+procedure TWasmResourceWriter.WriteCustomSectionNames;
+var
+  cust_sec: TWasmCustomSectionType;
+begin
+  { each custom sections starts with its name }
+  for cust_sec in TWasmCustomSectionType do
+    WriteName(FWasmCustomSections[cust_sec],WasmCustomSectionName[cust_sec]);
+end;
+
 procedure TWasmResourceWriter.WriteImportSection;
 procedure TWasmResourceWriter.WriteImportSection;
 const
 const
   ImportsCount = 1;
   ImportsCount = 1;
@@ -248,6 +268,10 @@ end;
 
 
 procedure TWasmResourceWriter.Write(aResources: TResources; aStream: TStream);
 procedure TWasmResourceWriter.Write(aResources: TResources; aStream: TStream);
 begin
 begin
+  WriteCustomSectionNames;
+
+  WriteUleb(FWasmCustomSections[wcstLinking],2);  { linking metadata version }
+
   fRoot:=TRootResTreeNode(GetTree(aResources));
   fRoot:=TRootResTreeNode(GetTree(aResources));
   PrescanResourceTree;
   PrescanResourceTree;
   WriteResHeader(aResources);
   WriteResHeader(aResources);
@@ -260,12 +284,14 @@ begin
   WriteWasmSection(aStream,wsiImport);
   WriteWasmSection(aStream,wsiImport);
   WriteWasmSection(aStream,wsiDataCount);
   WriteWasmSection(aStream,wsiDataCount);
   WriteWasmSection(aStream,wsiData);
   WriteWasmSection(aStream,wsiData);
+  WriteWasmCustomSection(aStream,wcstLinking);
 end;
 end;
 
 
 constructor TWasmResourceWriter.Create;
 constructor TWasmResourceWriter.Create;
 var
 var
   i: TWasmSectionID;
   i: TWasmSectionID;
   j: TWasmResourceDataSegment;
   j: TWasmResourceDataSegment;
+  k: TWasmCustomSectionType;
 begin
 begin
   fExtensions:='.o .or';
   fExtensions:='.o .or';
   fDescription:='WebAssembly resource writer';
   fDescription:='WebAssembly resource writer';
@@ -281,13 +307,18 @@ begin
     FWasmSections[i] := TMemoryStream.Create;
     FWasmSections[i] := TMemoryStream.Create;
   for j in TWasmResourceDataSegment do
   for j in TWasmResourceDataSegment do
     FDataSegments[j] := TMemoryStream.Create;
     FDataSegments[j] := TMemoryStream.Create;
+  for k in TWasmCustomSectionType do
+    FWasmCustomSections[k] := TMemoryStream.Create;
 end;
 end;
 
 
 destructor TWasmResourceWriter.Destroy;
 destructor TWasmResourceWriter.Destroy;
 var
 var
   i: TWasmSectionID;
   i: TWasmSectionID;
   j: TWasmResourceDataSegment;
   j: TWasmResourceDataSegment;
+  k: TWasmCustomSectionType;
 begin
 begin
+  for k in TWasmCustomSectionType do
+    FreeAndNil(FWasmCustomSections[k]);
   for j in TWasmResourceDataSegment do
   for j in TWasmResourceDataSegment do
     FreeAndNil(FDataSegments[j]);
     FreeAndNil(FDataSegments[j]);
   for i in TWasmSectionID do
   for i in TWasmSectionID do