unit ObjAuto;

interface

uses TypInfo;

const
  paEAX = Word(0);
  paEDX = Word(1);
  paECX = Word(2);
  paStack = Word(3);

type
  TCallingConvention = (ccRegister, ccCdecl, ccPascal, ccStdCall, ccSafeCall);
  TParamFlags = set of (pfVar, pfConst, pfArray, pfAddress, pfReference, pfOut,
    pfResult);
  PPointer = ^Pointer;
  PWord = ^Word;
  PMethodInfoHeader = ^TMethodInfoHeader;
  TMethodInfoHeader = packed record
    Len: Word;
    Addr: Pointer;
    Name: ShortString;
  end;
  PReturnInfo = ^TReturnInfo;
  TReturnInfo = packed record
    Version: Byte; // Must be 1
    CallingConvention: TCallingConvention;
    ReturnType: ^PTypeInfo;
    ParamSize: Word;
  end;
  PParamInfo = ^TParamInfo;
  TParamInfo = packed record
    Flags: TParamFlags;
    ParamType: ^PTypeInfo;
    Access: Word;
    Name: ShortString;
  end;

function ObjectInvoke(Instance: TObject; MethodHeader: PMethodInfoHeader;
  const ParamIndexes: array of Integer; const Params: array of Variant): Variant;
function GetMethodInfo(Instance: TObject;
  const MethodName: ShortString): PMethodInfoHeader;

// These functions should be overloaded and in TypInfo
function GetPropValue(Instance: TObject; PropInfo: PPropInfo): Variant;
procedure SetPropValue(Instance: TObject; PropInfo: PPropInfo; const Value: Variant);

type
  IMethodHandler = interface
    ['{4E61C8CD-16CC-4830-B1E4-84F86FBC0D23}']
    function Execute(const Args: array of Variant): Variant;
    function InstanceToVariant(Instance: TObject): Variant;
  end;

function CreateMethodPointer(const MethodHandler: IMethodHandler; TypeData: PTypeData): TMethod;
procedure ReleaseMethodPointer(MethodPointer: TMethod);

implementation
