mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-12 22:49:34 +02:00
+ 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:
parent
0a383d8c0f
commit
5adec3ca98
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user