+ perform WebAssembly validation, if the compiler is compiled with the

DEBUG_WASM_VALIDATION defined
This commit is contained in:
Nikolay Nikolov 2024-02-26 12:05:51 +02:00
parent 1bb452d1c7
commit f2d739b93a
2 changed files with 58 additions and 4 deletions

View File

@ -108,8 +108,10 @@ uses
FValueStack: TWasmValueStack;
FCtrlStack: TWasmControlStack;
FGetLocalType: TGetLocalTypeProc;
FFuncType: TWasmFuncType;
FEndFunctionReached: Boolean;
public
constructor Create(AGetLocalType: TGetLocalTypeProc);
constructor Create(AGetLocalType: TGetLocalTypeProc; AFuncType: TWasmFuncType);
destructor Destroy; override;
procedure PushVal(vt: TWasmBasicType);
@ -500,11 +502,14 @@ uses
{ TWasmValidationStacks }
constructor TWasmValidationStacks.Create(AGetLocalType: TGetLocalTypeProc);
constructor TWasmValidationStacks.Create(AGetLocalType: TGetLocalTypeProc; AFuncType: TWasmFuncType);
begin
FEndFunctionReached:=False;
FGetLocalType:=AGetLocalType;
FValueStack:=TWasmValueStack.Create;
FCtrlStack:=TWasmControlStack.Create;
FFuncType:=AFuncType;
PushCtrl(a_block,[],[]);
end;
destructor TWasmValidationStacks.Destroy;
@ -534,7 +539,7 @@ uses
function TWasmValidationStacks.PopVal(expect: TWasmBasicType): TWasmBasicType;
begin
Result:=wbt_Unknown;
Result:=PopVal;
Result:=PopVal();
if (Result<>expect) and (Result<>wbt_Unknown) and (expect<>wbt_Unknown) then
internalerror(2024013105);
end;
@ -643,6 +648,8 @@ uses
frame: TWasmControlFrame;
n: TCGInt;
begin
if FEndFunctionReached then
internalerror(2024022602);
case a.opcode of
a_nop:
;
@ -1110,6 +1117,13 @@ uses
PopVals(label_types(FCtrlStack[n]));
PushVals(label_types(FCtrlStack[n]));
end;
a_return:
begin
PopVals(FFuncType.results);
Unreachable;
end;
a_end_function:
FEndFunctionReached:=True;
else
internalerror(2024030502);
end;

View File

@ -36,6 +36,9 @@ interface
tcpuprocinfo=class(tcgprocinfo)
private
FFuncType: TWasmFuncType;
FLocals: array of TWasmBasicType;
FParametersCount: Integer;
FFirstFreeLocal: Integer;
FAllocatedLocals: array of TWasmBasicType;
FGotoTargets: TFPHashObjectList;
@ -47,6 +50,7 @@ interface
{ used for allocating locals during the postprocess_code stage (i.e. after register allocation) }
function AllocWasmLocal(wbt: TWasmBasicType): Integer;
function GetLocalType(localidx: Integer): TWasmBasicType;
public
{ label to the nearest local exception handler }
CurrRaiseLabel : tasmlabel;
@ -423,6 +427,16 @@ implementation
SetLength(FAllocatedLocals,Length(FAllocatedLocals)+1);
FAllocatedLocals[High(FAllocatedLocals)]:=wbt;
result:=High(FAllocatedLocals)+FFirstFreeLocal;
SetLength(FLocals,Length(FLocals)+1);
FLocals[High(FLocals)]:=wbt;
end;
function tcpuprocinfo.GetLocalType(localidx: Integer): TWasmBasicType;
begin
if (localidx<Low(FLocals)) or (localidx>High(FLocals)) then
internalerror(2024022601);
result:=FLocals[localidx];
end;
constructor tcpuprocinfo.create(aparent: tprocinfo);
@ -889,9 +903,14 @@ implementation
local:=nil;
first:=true;
l:=ttgwasm(tg).localvars.first;
FFirstFreeLocal:=Length(findfirst_tai_functype(aktproccode).functype.params);
FFuncType:=findfirst_tai_functype(aktproccode).functype;
FLocals:=Copy(FFuncType.params);
FParametersCount:=Length(FLocals);
FFirstFreeLocal:=FParametersCount;
while Assigned(l) do
begin
SetLength(FLocals,Length(FLocals)+1);
FLocals[High(FLocals)]:=l.typ;
local:=tai_local.create(l.typ);
local.first:=first;
first:=false;
@ -944,6 +963,23 @@ implementation
end;
end;
procedure validate_code;
var
vs: TWasmValidationStacks;
hp: tai;
begin
vs:=TWasmValidationStacks.Create(@GetLocalType,FFuncType);
hp:=tai(aktproccode.first);
while assigned(hp) do
begin
if hp.typ=ait_instruction then
vs.Validate(taicpu(hp));
hp:=tai(hp.next);
end;
vs.Free;
end;
var
localslist: TAsmList;
labels_resolved, has_goto: Boolean;
@ -967,6 +1003,10 @@ implementation
insert_localslist(aktproccode,localslist);
localslist.Free;
{$ifdef DEBUG_WASM_VALIDATION}
validate_code;
{$endif DEBUG_WASM_VALIDATION}
inherited postprocess_code;
end;