Fiddling with anonymous methods.

Fiddling with anonymous methods.

This recently filed issue (https://bitbucket.org/sglienke/spring4d/issues/146) and my not yet confirmed guess made me think.

Why can't the compiler do the following for cases where no variable capturing is required (which is the case for standalone routines or even stateless anonymous methods - for instance methods it secretly captures Self so it can call the method on the correct instance):

The stuff within the region would need to be compiler generated.

program anonymous_method_routine;

{$APPTYPE CONSOLE}

uses
  SysUtils;

procedure MyHandler;
begin
  Writeln('foo');
end;

{$REGION 'VTable stuff'}

function NopAddref(inst: Pointer): Integer; stdcall;
begin
  Result := -1;
end;

function NopRelease(inst: Pointer): Integer; stdcall;
begin
  Result := -1;
end;

function NopQueryInterface(inst: Pointer; const IID: TGUID; out Obj): HResult; stdcall;
begin
  Result := E_NOINTERFACE;
end;

const
  MyHandler_Vtable: array[0..3] of Pointer =
  (
   @NopQueryInterface,
   @NopAddref,
   @NopRelease,
   @MyHandler
  );
  MyHandler_Instance: Pointer =@MyHandler_Vtable;

{$ENDREGION}

var
  p: TProc;
begin
  try
    p := MyHandler;
    // what the compiler actually generates
    // p := procedure begin MyHandler() end;

    p(); // <- step into it and look at the callstack

    // what the compiler actually should generate
    PPointer(@p)^:=@MyHandler_Instance;

    p(); // <- check the callstack - it does not contain any compiler generated stuff
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;
end.

Allen Bauer Marco Cantù  ping

Comments

Post a Comment