mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-12 06:26:10 +02:00
+ Wasm internal linker, object reader: implemented parsing of the type section
This commit is contained in:
parent
2626b85984
commit
a08c937beb
@ -184,9 +184,12 @@ interface
|
|||||||
|
|
||||||
TWasmObjInput = class(TObjInput)
|
TWasmObjInput = class(TObjInput)
|
||||||
private
|
private
|
||||||
|
FFuncTypes: array of TWasmFuncType;
|
||||||
|
|
||||||
function ReadUleb(r: TObjectReader; out v: uint64): boolean;
|
function ReadUleb(r: TObjectReader; out v: uint64): boolean;
|
||||||
public
|
public
|
||||||
constructor create;override;
|
constructor create;override;
|
||||||
|
destructor Destroy;override;
|
||||||
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
class function CanReadObjData(AReader:TObjectreader):boolean;override;
|
||||||
function ReadObjData(AReader:TObjectreader;out ObjData:TObjData):boolean;override;
|
function ReadObjData(AReader:TObjectreader;out ObjData:TObjData):boolean;override;
|
||||||
end;
|
end;
|
||||||
@ -2131,6 +2134,18 @@ implementation
|
|||||||
cobjdata:=TWasmObjData;
|
cobjdata:=TWasmObjData;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
destructor TWasmObjInput.Destroy;
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
for i:=low(FFuncTypes) to high(FFuncTypes) do
|
||||||
|
begin
|
||||||
|
FFuncTypes[i].free;
|
||||||
|
FFuncTypes[i]:=nil;
|
||||||
|
end;
|
||||||
|
inherited Destroy;
|
||||||
|
end;
|
||||||
|
|
||||||
class function TWasmObjInput.CanReadObjData(AReader: TObjectreader): boolean;
|
class function TWasmObjInput.CanReadObjData(AReader: TObjectreader): boolean;
|
||||||
var
|
var
|
||||||
ModuleMagic: array [0..3] of Byte;
|
ModuleMagic: array [0..3] of Byte;
|
||||||
@ -2160,14 +2175,116 @@ implementation
|
|||||||
SectionSize: uint64;
|
SectionSize: uint64;
|
||||||
SectionStart: LongInt;
|
SectionStart: LongInt;
|
||||||
|
|
||||||
|
TypeSectionRead: Boolean = false;
|
||||||
|
|
||||||
function ReadCustomSection: Boolean;
|
function ReadCustomSection: Boolean;
|
||||||
begin
|
begin
|
||||||
Result:=False;
|
Result:=False;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadTypeSection: Boolean;
|
function ReadTypeSection: Boolean;
|
||||||
|
var
|
||||||
|
FuncTypesCount, ParamsCount, ResultsCount: uint64;
|
||||||
|
FuncTypeId, WasmTypeId: Byte;
|
||||||
|
i, j: Integer;
|
||||||
|
wbt: TWasmBasicType;
|
||||||
begin
|
begin
|
||||||
Result:=False;
|
Result:=False;
|
||||||
|
if TypeSectionRead then
|
||||||
|
begin
|
||||||
|
InputError('Type section is duplicated');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
TypeSectionRead:=True;
|
||||||
|
if not ReadUleb(AReader, FuncTypesCount) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading the func types count');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if AReader.Pos>(SectionStart+SectionSize) then
|
||||||
|
begin
|
||||||
|
InputError('The func types count stretches beyond the end of the type section');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if FuncTypesCount>high(uint32) then
|
||||||
|
begin
|
||||||
|
InputError('The func types count does not fit in an unsigned 32-bit int');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
SetLength(FFuncTypes,FuncTypesCount);
|
||||||
|
for i:=0 to FuncTypesCount - 1 do
|
||||||
|
begin
|
||||||
|
FFuncTypes[i]:=TWasmFuncType.Create([],[]);
|
||||||
|
if not AReader.read(FuncTypeId,1) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading the function type identifier');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if FuncTypeId<>$60 then
|
||||||
|
begin
|
||||||
|
InputError('Incorrect function type identifier (expected $60, got $' + HexStr(FuncTypeId,2) + ')');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if not ReadUleb(AReader, ParamsCount) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading the function parameters count');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if AReader.Pos>(SectionStart+SectionSize) then
|
||||||
|
begin
|
||||||
|
InputError('The function paramaters count stretches beyond the end of the type section');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if ParamsCount>high(uint32) then
|
||||||
|
begin
|
||||||
|
InputError('The function parameters count does not fit in an unsigned 32-bit int');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
for j:=0 to ParamsCount-1 do
|
||||||
|
begin
|
||||||
|
if not AReader.read(WasmTypeId,1) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading a function parameter basic type');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if not decode_wasm_basic_type(WasmTypeId,wbt) then
|
||||||
|
begin
|
||||||
|
InputError('Unknown function parameter basic type: $' + HexStr(WasmTypeId,2));
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
FFuncTypes[i].add_param(wbt);
|
||||||
|
end;
|
||||||
|
if not ReadUleb(AReader, ResultsCount) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading the function results count');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if AReader.Pos>(SectionStart+SectionSize) then
|
||||||
|
begin
|
||||||
|
InputError('The function results count stretches beyond the end of the type section');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if ResultsCount>high(uint32) then
|
||||||
|
begin
|
||||||
|
InputError('The function results count does not fit in an unsigned 32-bit int');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
for j:=0 to ResultsCount-1 do
|
||||||
|
begin
|
||||||
|
if not AReader.read(WasmTypeId,1) then
|
||||||
|
begin
|
||||||
|
InputError('Error reading a function result basic type');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
if not decode_wasm_basic_type(WasmTypeId,wbt) then
|
||||||
|
begin
|
||||||
|
InputError('Unknown function result basic type: $' + HexStr(WasmTypeId,2));
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
|
FFuncTypes[i].add_result(wbt);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
result:=AReader.Pos=(SectionStart+SectionSize);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function ReadImportSection: Boolean;
|
function ReadImportSection: Boolean;
|
||||||
@ -2233,7 +2350,11 @@ implementation
|
|||||||
Byte(wsiCustom):
|
Byte(wsiCustom):
|
||||||
Result := ReadCustomSection;
|
Result := ReadCustomSection;
|
||||||
Byte(wsiType):
|
Byte(wsiType):
|
||||||
Result := ReadTypeSection;
|
if not ReadTypeSection then
|
||||||
|
begin
|
||||||
|
InputError('Error reading the type section');
|
||||||
|
exit;
|
||||||
|
end;
|
||||||
Byte(wsiImport):
|
Byte(wsiImport):
|
||||||
Result := ReadImportSection;
|
Result := ReadImportSection;
|
||||||
Byte(wsiFunction):
|
Byte(wsiFunction):
|
||||||
|
Loading…
Reference in New Issue
Block a user