Search code examples
delphianonymous-methodsdelphi-10-seattle

What kind of metadata is generated by anonymous methods? And is there a way to remove it?


I'm using the tool MapFileStats to inspect generated map files from delphi. I found that anonymous methods generate some kind of metadata, which doesn't seem to be related with RTTI. What kind of metadata is it? It would be nice to remove it because in our production environment it sums up to a very large size.

Example code:

program RttiDemo;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])}
{$WEAKLINKRTTI OFF}   

var
  AProc: TProc;

begin
  try

    AProc := procedure()
      begin
        // ...
      end;

  except
    on E: Exception do
      WriteLn(E.ClassName, ': ', E.Message);
  end;

end.

Screenshot from MapFileStats:

Screenshot displaying MailFileStats

Another example:

program RttiDemo;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

{$RTTI EXPLICIT METHODS([]) FIELDS([]) PROPERTIES([])}
{$WEAKLINKRTTI OFF}

type

  TDemo = class
    procedure Demo();
  end;

procedure TDemo.Demo;
var
  AProc: TProc;
begin
  AProc := procedure()
    var
      i: Integer;
    begin
      i := 5;
      WriteLn(i);
    end;

  AProc();
end;

var
  Demo: TDemo;

begin
  Demo := TDemo.Create();
  try
    Demo.Demo;
  finally
    FreeAndNil(Demo);
  end;
end.

Screenshot:

another MapFileStats screenshot


Solution

  • An anonymous function is backed by a class that implements the interfaces needed for the anonymous function to work. The meta data reported here represents the information needed for that class. I do not believe that you can remove it from your executable.

    The following will emit the name of the class of the object that implements the anonymous method:

    Writeln((IInterface(Pointer(@AProc)^) as TObject).ClassName);
    

    When added to your second program, the output is:

    TDemo.Demo$0$ActRec
    

    This is the same name as you highlighted in the question.