mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-07 05:08:06 +02:00
+ perform WebAssembly validation, if the compiler is compiled with the
DEBUG_WASM_VALIDATION defined
This commit is contained in:
parent
1bb452d1c7
commit
f2d739b93a
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user