Browse Source

+ create the data section and the first entry of the import section

Nikolay Nikolov 3 years ago
parent
commit
e8c3f5d6b0
1 changed files with 78 additions and 0 deletions
  1. 78 0
      compiler/ogwasm.pas

+ 78 - 0
compiler/ogwasm.pas

@@ -45,6 +45,7 @@ interface
       TWasmObjSection = class(TObjSection)
       TWasmObjSection = class(TObjSection)
       public
       public
         SegIdx: Integer;
         SegIdx: Integer;
+        SegOfs: qword;
         function IsCode: Boolean;
         function IsCode: Boolean;
         function IsData: Boolean;
         function IsData: Boolean;
       end;
       end;
@@ -68,7 +69,11 @@ interface
         FWasmSections: array [TWasmSectionID] of tdynamicarray;
         FWasmSections: array [TWasmSectionID] of tdynamicarray;
         procedure WriteUleb(d: tdynamicarray; v: uint64);
         procedure WriteUleb(d: tdynamicarray; v: uint64);
         procedure WriteUleb(w: TObjectWriter; v: uint64);
         procedure WriteUleb(w: TObjectWriter; v: uint64);
+        procedure WriteSleb(d: tdynamicarray; v: int64);
+        procedure WriteByte(d: tdynamicarray; b: byte);
+        procedure WriteName(d: tdynamicarray; const s: string);
         procedure WriteWasmSection(wsid: TWasmSectionID);
         procedure WriteWasmSection(wsid: TWasmSectionID);
+        procedure CopyDynamicArray(src, dest: tdynamicarray; size: QWord);
       protected
       protected
         function writeData(Data:TObjData):boolean;override;
         function writeData(Data:TObjData):boolean;override;
       public
       public
@@ -294,6 +299,33 @@ implementation
         until v=0;
         until v=0;
       end;
       end;
 
 
+    procedure TWasmObjOutput.WriteSleb(d: tdynamicarray; v: int64);
+      var
+        b: byte;
+        Done: Boolean=false;
+      begin
+        repeat
+          b:=byte(v) and 127;
+          v:=SarInt64(v,7);
+          if ((v=0) and ((b and 64)=0)) or ((v=-1) and ((b and 64)<>0)) then
+            Done:=true
+          else
+            b:=b or 128;
+          d.write(b,1);
+        until Done;
+      end;
+
+    procedure TWasmObjOutput.WriteByte(d: tdynamicarray; b: byte);
+      begin
+        d.write(b,1);
+      end;
+
+    procedure TWasmObjOutput.WriteName(d: tdynamicarray; const s: string);
+      begin
+        WriteUleb(d,Length(s));
+        d.writestr(s);
+      end;
+
     procedure TWasmObjOutput.WriteWasmSection(wsid: TWasmSectionID);
     procedure TWasmObjOutput.WriteWasmSection(wsid: TWasmSectionID);
       var
       var
         b: byte;
         b: byte;
@@ -304,11 +336,30 @@ implementation
         Writer.writearray(FWasmSections[wsid]);
         Writer.writearray(FWasmSections[wsid]);
       end;
       end;
 
 
+    procedure TWasmObjOutput.CopyDynamicArray(src, dest: tdynamicarray; size: QWord);
+      var
+        buf: array [0..4095] of byte;
+        bs: Integer;
+      begin
+        while size>0 do
+          begin
+            if size<SizeOf(buf) then
+              bs:=Integer(size)
+            else
+              bs:=SizeOf(buf);
+            src.read(buf,bs);
+            dest.write(buf,bs);
+            dec(size,bs);
+          end;
+      end;
+
     function TWasmObjOutput.writeData(Data:TObjData):boolean;
     function TWasmObjOutput.writeData(Data:TObjData):boolean;
       var
       var
         i: Integer;
         i: Integer;
         objsec: TWasmObjSection;
         objsec: TWasmObjSection;
         segment_count: Integer = 0;
         segment_count: Integer = 0;
+        cur_seg_ofs: qword = 0;
+        imports_count: Integer = 1;
       begin
       begin
         for i:=0 to Data.ObjSectionList.Count-1 do
         for i:=0 to Data.ObjSectionList.Count-1 do
           begin
           begin
@@ -318,16 +369,43 @@ implementation
             else
             else
               begin
               begin
                 objsec.SegIdx:=segment_count;
                 objsec.SegIdx:=segment_count;
+                objsec.SegOfs:=cur_seg_ofs;
                 Inc(segment_count);
                 Inc(segment_count);
+                Inc(cur_seg_ofs,objsec.Size);
+              end;
+          end;
+
+        WriteUleb(FWasmSections[wsiData],segment_count);
+        for i:=0 to Data.ObjSectionList.Count-1 do
+          begin
+            objsec:=TWasmObjSection(Data.ObjSectionList[i]);
+            if objsec.IsData then
+              begin
+                WriteByte(FWasmSections[wsiData],0);
+                WriteByte(FWasmSections[wsiData],$41);
+                WriteSleb(FWasmSections[wsiData],objsec.SegOfs);
+                WriteByte(FWasmSections[wsiData],$0b);
+                WriteUleb(FWasmSections[wsiData],objsec.Size);
+                objsec.Data.seek(0);
+                CopyDynamicArray(objsec.Data,FWasmSections[wsiData],objsec.Size);
               end;
               end;
           end;
           end;
 
 
         WriteUleb(FWasmSections[wsiDataCount],segment_count);
         WriteUleb(FWasmSections[wsiDataCount],segment_count);
 
 
+        WriteUleb(FWasmSections[wsiImport],imports_count);
+        WriteName(FWasmSections[wsiImport],'env');
+        WriteName(FWasmSections[wsiImport],'__linear_memory');
+        WriteByte(FWasmSections[wsiImport],$02);
+        WriteByte(FWasmSections[wsiImport],$00);
+        WriteUleb(FWasmSections[wsiImport],1);
+
         Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic));
         Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic));
         Writer.write(WasmVersion,SizeOf(WasmVersion));
         Writer.write(WasmVersion,SizeOf(WasmVersion));
 
 
+        WriteWasmSection(wsiImport);
         WriteWasmSection(wsiDataCount);
         WriteWasmSection(wsiDataCount);
+        WriteWasmSection(wsiData);
 
 
         Writeln('ObjSectionList:');
         Writeln('ObjSectionList:');
         for i:=0 to Data.ObjSectionList.Count-1 do
         for i:=0 to Data.ObjSectionList.Count-1 do