views:

113

answers:

1

I'm using an old script engine that's no longer supported by its creators, and having some trouble with memory leaks. It uses a function written in ASM to call from scripts into Delphi functions, and returns the result as an integer then passes that integer as an untyped parameter to another procedure that translates it into the correct type.

This works fine for most things, but when the return type of the Delphi function was Variant, it leaks memory because the variant is never getting disposed of. Does anyone know how I can take an untyped parameter containing a variant and ensure that it will be disposed of properly? This will probably involve some inline assembly.

procedure ConvertVariant(var input; var output: variant);
begin
  output := variant(input);
  asm
    //what do I put here? Input is still held in EAX at this point.
  end;
end;

EDIT: Responding to Rob Kennedy's question in comments:

AnsiString conversion works like this:

procedure VarFromString2(var s : AnsiString; var v : Variant);
begin
  v := s;
  s := '';
end;

procedure StringToVar(var p; var v : Variant);
begin
  asm
    call VarFromString2
  end;
end;

That works fine and doesn't produce memory leaks. When I try to do the same thing with a variant as the input parameter, and assign the original Null on the second procedure, the memory leaks still happen.

The variants mostly contain strings--the script in question is used to generate XML--and they got there by assigning a Delphi string to a variant in the Delphi function that this script is calling. (Changing the return type of the function wouldn't work in this case.)

+3  A: 

Have you tried the same trick as with the string, except that with a Variant, you should put UnAssigned instead of Null to free it, like you did s := ''; for the string.

And by the way, one of the only reasons I can think of that requires to explicitly free the strings, Variants, etc... is when using some ThreadVar.

François
...or if the code's doing low-level things that interfere with the compiler's ability to automatically generate cleanup code.
Mason Wheeler
I tried that, and I'm still seeing memory use increasing every time I run. That's the only indication I have to test this by, since variants aren't allocated by FastMM and don't show up in the memory leak report. But it's down considerably, which means that this is helping and there's something else leaking too. :(
Mason Wheeler