+ write the code section (still, without the actual function code, but with

the correct locals)
This commit is contained in:
Nikolay Nikolov 2021-09-25 17:40:58 +03:00
parent fcb646bc3b
commit 6d1df899e6

View File

@ -88,6 +88,7 @@ interface
TWasmObjOutput = class(tObjOutput)
private
FData: TWasmObjData;
FWasmSections: array [TWasmSectionID] of tdynamicarray;
procedure WriteUleb(d: tdynamicarray; v: uint64);
procedure WriteUleb(w: TObjectWriter; v: uint64);
@ -100,6 +101,8 @@ interface
procedure WriteWasmResultType(dest: tdynamicarray; wrt: TWasmResultType);
procedure WriteWasmBasicType(dest: tdynamicarray; wbt: TWasmBasicType);
function IsExternalFunction(sym: TObjSymbol): Boolean;
procedure WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData);
procedure WriteFunctionCode(dest: tdynamicarray; objsym: TObjSymbol);
protected
function writeData(Data:TObjData):boolean;override;
public
@ -512,6 +515,58 @@ implementation
result:=(sym.bind=AB_EXTERNAL) and (TWasmObjData(sym.ObjData).FObjSymbolsExtraDataList.Find(sym.Name)<>nil);
end;
procedure TWasmObjOutput.WriteFunctionLocals(dest: tdynamicarray; ed: TWasmObjSymbolExtraData);
var
i,
rle_entries,
cnt: Integer;
lasttype: TWasmBasicType;
begin
if Length(ed.Locals)=0 then
begin
WriteUleb(dest,0);
exit;
end;
rle_entries:=1;
for i:=low(ed.Locals)+1 to high(ed.Locals) do
if ed.Locals[i]<>ed.Locals[i-1] then
inc(rle_entries);
WriteUleb(dest,rle_entries);
lasttype:=ed.Locals[Low(ed.Locals)];
cnt:=1;
for i:=low(ed.Locals)+1 to high(ed.Locals) do
if ed.Locals[i]=ed.Locals[i-1] then
inc(cnt)
else
begin
WriteUleb(dest,cnt);
WriteWasmBasicType(dest,lasttype);
lasttype:=ed.Locals[i];
cnt:=1;
end;
WriteUleb(dest,cnt);
WriteWasmBasicType(dest,lasttype);
end;
procedure TWasmObjOutput.WriteFunctionCode(dest: tdynamicarray; objsym: TObjSymbol);
var
encoded_locals: tdynamicarray;
ObjSymExtraData: TWasmObjSymbolExtraData;
codelen: LongWord;
begin
ObjSymExtraData:=TWasmObjSymbolExtraData(FData.FObjSymbolsExtraDataList.Find(objsym.Name));
encoded_locals:=tdynamicarray.Create(64);
WriteFunctionLocals(encoded_locals,ObjSymExtraData);
codelen:=encoded_locals.size+1;
WriteUleb(dest,codelen);
encoded_locals.seek(0);
CopyDynamicArray(encoded_locals,dest,encoded_locals.size);
WriteByte(dest,$0B);
encoded_locals.Free;
end;
function TWasmObjOutput.writeData(Data:TObjData):boolean;
var
i: Integer;
@ -524,6 +579,7 @@ implementation
functions_count: Integer = 0;
objsym: TObjSymbol;
begin
FData:=TWasmObjData(Data);
for i:=0 to Data.ObjSymbolList.Count-1 do
begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]);
@ -617,11 +673,15 @@ implementation
WriteUleb(FWasmSections[wsiImport],1); { 1 }
WriteUleb(FWasmSections[wsiFunction],functions_count);
WriteUleb(FWasmSections[wsiCode],functions_count);
for i:=0 to Data.ObjSymbolList.Count-1 do
begin
objsym:=TObjSymbol(Data.ObjSymbolList[i]);
if objsym.typ=AT_FUNCTION then
WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(TWasmObjData(Data).FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx);
begin
WriteUleb(FWasmSections[wsiFunction],TWasmObjSymbolExtraData(TWasmObjData(Data).FObjSymbolsExtraDataList.Find(objsym.Name)).TypeIdx);
WriteFunctionCode(FWasmSections[wsiCode],objsym);
end;
end;
Writer.write(WasmModuleMagic,SizeOf(WasmModuleMagic));
@ -631,6 +691,7 @@ implementation
WriteWasmSection(wsiImport);
WriteWasmSection(wsiFunction);
WriteWasmSection(wsiDataCount);
WriteWasmSection(wsiCode);
WriteWasmSection(wsiData);
Writeln('ObjSymbolList:');