+ workaround for WebAssembly treating the stack parameter of the store and load

instructions as unsigned. This caused an 'out of bounds memory access' trap
  when accessing arrays with negative offset index, e.g. in test/cg/tvec.pp
This commit is contained in:
Nikolay Nikolov 2021-10-03 03:16:34 +03:00
parent 0a383d8c0f
commit 5adec3ca98

View File

@ -1072,12 +1072,26 @@ implementation
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
if assigned(ref.symbol) then
begin
list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if ref.offset<0 then
begin
list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_sub));
decstack(list,1);
end
else if ref.offset>0 then
begin
list.Concat(taicpu.op_const(a_i32_const,ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if dup then
begin
@ -1087,18 +1101,32 @@ implementation
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
if assigned(ref.symbol) then
begin
list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if ref.offset<0 then
begin
list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_sub));
decstack(list,1);
end
else if ref.offset>0 then
begin
list.Concat(taicpu.op_const(a_i32_const,ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
end;
ref.base:=NR_NO;
ref.index:=NR_NO;
if ref.offset<0 then
ref.offset:=0;
ref.offset:=0;
ref.symbol:=nil;
result:=1;
end
else if (ref.base<>NR_NO) then
@ -1107,26 +1135,54 @@ implementation
begin
{ regular field -> load self on the stack }
a_load_reg_stack(list,voidpointertype,ref.base);
if assigned(ref.symbol) then
begin
list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if ref.offset<0 then
begin
list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_sub));
decstack(list,1);
end
else if ref.offset>0 then
begin
list.Concat(taicpu.op_const(a_i32_const,ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if dup then
begin
a_load_reg_stack(list,voidpointertype,ref.base);
if assigned(ref.symbol) then
begin
list.Concat(taicpu.op_sym(a_i32_const,ref.symbol));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
if ref.offset<0 then
begin
list.Concat(taicpu.op_const(a_i32_const,-ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_sub));
decstack(list,1);
end
else if ref.offset>0 then
begin
list.Concat(taicpu.op_const(a_i32_const,ref.offset));
incstack(list,1);
list.Concat(taicpu.op_none(a_i32_add));
decstack(list,1);
end;
end;
if ref.offset<0 then
ref.offset:=0;
ref.offset:=0;
ref.symbol:=nil;
ref.base:=NR_NO;
result:=1;
end