Some years ago I've ported an old unix application to Delphi 5. For linked lists iterations it used local procedures passed by address to a global 'iterator' function.
Below is a simplified example:
type TPerformProc = procedure;
procedure Perform(proc:TPerformProc);
begin
proc;
end;
procedure Test;
var loc_var:integer;
procedure loc_proc;
begin
loc_var:=loc_var+10;
end;
begin
loc_var:=0;
writeln('loc var: ',loc_var);
Perform(addr(loc_proc));
writeln('loc var: ',loc_var);
writeln('-----');
end;
The example procedure crashes in Delphi, but it worked on unix just fine.
With some help, I've been able to get it working like this:
type TPerformProc = procedure;
var loc_bp:integer;
procedure Perform(proc:TPerformProc);
begin
asm
push loc_bp
end;
proc;
asm
pop eax
end;
end;
procedure Test;
var loc_var:integer;
procedure loc_proc;
begin
loc_var:=loc_var+10;
end;
begin
loc_var:=0;
writeln('loc var: ',loc_var);
asm
mov loc_bp,ebp
end;
Perform(addr(loc_proc));
writeln('loc var: ',loc_var);
writeln('-----');
end;
To solve the problem, I store a reference to the stack frame of the local procedure and then I call the local procedure.
It's clear to me, that the solution above is not a proper fix, but rather a hack and I understand that a new Delphi version might handle the local procedures in a different way and break the hack. Fortunately enough, this part of Delphi stayed the same and the code works OK even with latest Delhi.
However, I want to compile the application as 64-bit one and the hack is no longer working. So far I was not able to find a similar solution, but for 64-bit. Is here someone who can help here ?
Thank you.