I found that Delphi 5 generates the wrong build code in certain cases. I canโt understand in what cases at all. The following example shows an access violation because a very strange optimization is taking place. For a byte in a record or array, Delphi generates a push dword [...], pop ebx, mov .., bl, which works correctly if there is data after this byte (we need at least three to correctly press dword), but not works if data is not available. I emulated strict boundaries here using win32 Virtual * functions
In particular, an error occurs when the last byte of a block is accessed inside the FeedBytesToClass procedure. And if I try to change something like using a data array instead of an object property to delete the actionFlag variable, Delphi will generate the correct assembly instructions.
const
BlockSize = 4096;
type
TSomeClass = class
private
fBytes: PByteArray;
public
property Bytes: PByteArray read fBytes;
constructor Create;
destructor Destroy;override;
end;
constructor TSomeClass.Create;
begin
inherited Create;
GetMem(fBytes, BlockSize);
end;
destructor TSomeClass.Destroy;
begin
FreeMem(fBytes);
inherited;
end;
procedure FeedBytesToClass(SrcDataBytes: PByteArray; Count: integer);
var
j: integer;
Ofs: integer;
actionFlag: boolean;
AClass: TSomeClass;
begin
AClass:=TSomeClass.Create;
try
actionFlag:=true;
for j:=0 to Count-1 do
begin
Ofs:=j;
if actionFlag then
begin
AClass.Bytes[Ofs]:=SrcDataBytes[j];
end;
end;
finally
AClass.Free;
end;
end;
procedure TForm31.Button1Click(Sender: TObject);
var
SrcDataBytes: PByteArray;
begin
SrcDataBytes:=VirtualAlloc(Nil, BlockSize, MEM_COMMIT, PAGE_READWRITE);
try
if VirtualLock(SrcDataBytes, BlockSize) then
try
FeedBytesToClass(SrcDataBytes, BlockSize);
finally
VirtualUnLock(SrcDataBytes, BlockSize);
end;
finally
VirtualFree(SrcDataBytes, MEM_DECOMMIT, BlockSize);
end;
end;
Initially, an error occurred when I used access to the RGB data of bitmart bits, but the code there is too complicated, so I narrowed it down to this fragment.
So, the question is what is so specific here, what does Delphi produce push, pop, mov optim. I need to know this to avoid such side effects in general.
source
share