All pastes #19209 Raw Edit

Anonymous

public text v1 · immutable
#19209 ·published 2005-08-03 18:13 UTC
rendered paste body
  // example
  newcall := vmbrtm_new;
  vmbrtm_setcallconv(newcall, vmb_callconv_cdecl);
  vmbrtm_setaddress(newcall, @mytest_cdecl);
  vmbrtm_pushparam32(newcall, 13);
  vmbrtm_pushparam32(newcall, 5);
  vmbrtm_callproc(newcall);
  vmbrtm_del(newcall);


/////////////// library code, quite new, not formatted yet

unit vmbRuntimeCall;

interface

uses
  vmbstack;

const
  vmb_callconv_stdcall        = 0;
  vmb_callconv_register       = 1;
  vmb_callconv_cdecl          = 2;

const
  vmbrtm_maxparams            = 8;

type
  pvmbruntimecall = ^tvmbruntimecall;
  tvmbruntimecall = record
    procaddress   : pointer;
    nparam        : integer;
    param         : array[0..7] of integer;
    callconv      : integer;
  end;


  function vmbrtm_new : pvmbruntimecall;
  procedure vmbrtm_del(rtc : pvmbruntimecall);

  procedure vmbrtm_clear(rtc : pvmbruntimecall);

  procedure vmbrtm_setaddress(rtc : pvmbruntimecall; addr : pointer);
  procedure vmbrtm_setcallconv(rtc : pvmbruntimecall; callconv : integer);

  procedure vmbrtm_callproc(rtc : pvmbruntimecall); overload;
  procedure vmbrtm_callproc(rtc : pvmbruntimecall; addr : pointer; callconv : integer); overload;

  procedure vmbrtm_pushparam32(rtc : pvmbruntimecall; val : integer);
  procedure vmbrtm_pushparam64(rtc : pvmbruntimecall; val : int64);


implementation

type
  // proc def helpers
  tvmbruntimeproc_stdcall0 = procedure(); stdcall;
  tvmbruntimeproc_stdcall1 = procedure(a : integer); stdcall;
  tvmbruntimeproc_stdcall2 = procedure(a, b : integer); stdcall;
  tvmbruntimeproc_stdcall3 = procedure(a, b, c : integer); stdcall;
  tvmbruntimeproc_stdcall4 = procedure(a, b, c, d : integer); stdcall;
  tvmbruntimeproc_stdcall5 = procedure(a, b, c, d, e : integer); stdcall;
  tvmbruntimeproc_stdcall6 = procedure(a, b, c, d, e, f : integer); stdcall;
  tvmbruntimeproc_stdcall7 = procedure(a, b, c, d, e, f, g : integer); stdcall;
  tvmbruntimeproc_stdcall8 = procedure(a, b, c, d, e, f, g, h : integer); stdcall;

  tvmbruntimeproc_register0 = procedure(); register;
  tvmbruntimeproc_register1 = procedure(a : integer); register;
  tvmbruntimeproc_register2 = procedure(a, b : integer); register;
  tvmbruntimeproc_register3 = procedure(a, b, c : integer); register;
  tvmbruntimeproc_register4 = procedure(a, b, c, d : integer); register;
  tvmbruntimeproc_register5 = procedure(a, b, c, d, e : integer); register;
  tvmbruntimeproc_register6 = procedure(a, b, c, d, e, f : integer); register;
  tvmbruntimeproc_register7 = procedure(a, b, c, d, e, f, g : integer); register;
  tvmbruntimeproc_register8 = procedure(a, b, c, d, e, f, g, h : integer); register;

  tvmbruntimeproc_cdecl0 = procedure(); cdecl;
  tvmbruntimeproc_cdecl1 = procedure(a : integer); cdecl;
  tvmbruntimeproc_cdecl2 = procedure(a, b : integer); cdecl;
  tvmbruntimeproc_cdecl3 = procedure(a, b, c : integer); cdecl;
  tvmbruntimeproc_cdecl4 = procedure(a, b, c, d : integer); cdecl;
  tvmbruntimeproc_cdecl5 = procedure(a, b, c, d, e : integer); cdecl;
  tvmbruntimeproc_cdecl6 = procedure(a, b, c, d, e, f : integer); cdecl;
  tvmbruntimeproc_cdecl7 = procedure(a, b, c, d, e, f, g : integer); cdecl;
  tvmbruntimeproc_cdecl8 = procedure(a, b, c, d, e, f, g, h : integer); cdecl;




// create & destroy calling object

function vmbrtm_new : pvmbruntimecall;
begin
  new(result);
  vmbrtm_clear(result);
end;

procedure vmbrtm_del(rtc : pvmbruntimecall);
begin
  dispose(rtc);
end;



// clear properties and set paramcount to 0

procedure vmbrtm_clear(rtc : pvmbruntimecall);
begin
  rtc.procaddress := nil;
  rtc.nparam := 0;
  rtc.callconv := vmb_callconv_stdcall;
end;



// set properties

procedure vmbrtm_setcallconv(rtc : pvmbruntimecall; callconv : integer);
begin
  rtc.callconv := callconv;
end;

procedure vmbrtm_setaddress(rtc : pvmbruntimecall; addr : pointer);
begin
  rtc.procaddress := addr;
end;



// call proc

procedure vmbrtm_callproc(rtc : pvmbruntimecall);
begin
  vmbrtm_callproc(rtc, rtc.procaddress, rtc.callconv);
end;

procedure vmbrtm_callproc(rtc : pvmbruntimecall; addr : pointer; callconv : integer);
begin
  case callconv of
    vmb_callconv_stdcall :
      case rtc.nparam of
        0 : tvmbruntimeproc_stdcall0(addr)();
        1 : tvmbruntimeproc_stdcall1(addr)(rtc.param[0]);
        2 : tvmbruntimeproc_stdcall2(addr)(rtc.param[0], rtc.param[1]);
        3 : tvmbruntimeproc_stdcall3(addr)(rtc.param[0], rtc.param[1], rtc.param[2]);
        4 : tvmbruntimeproc_stdcall4(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3]);
        5 : tvmbruntimeproc_stdcall5(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4]);
        6 : tvmbruntimeproc_stdcall6(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5]);
        7 : tvmbruntimeproc_stdcall7(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6]);
        8 : tvmbruntimeproc_stdcall8(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6], rtc.param[7]);
      end;
    vmb_callconv_register :
      case rtc.nparam of
        0 : tvmbruntimeproc_register0(addr)();
        1 : tvmbruntimeproc_register1(addr)(rtc.param[0]);
        2 : tvmbruntimeproc_register2(addr)(rtc.param[0], rtc.param[1]);
        3 : tvmbruntimeproc_register3(addr)(rtc.param[0], rtc.param[1], rtc.param[2]);
        4 : tvmbruntimeproc_register4(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3]);
        5 : tvmbruntimeproc_register5(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4]);
        6 : tvmbruntimeproc_register6(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5]);
        7 : tvmbruntimeproc_register7(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6]);
        8 : tvmbruntimeproc_register8(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6], rtc.param[7]);
      end;
    vmb_callconv_cdecl :
      case rtc.nparam of
        0 : tvmbruntimeproc_cdecl0(addr)();
        1 : tvmbruntimeproc_cdecl1(addr)(rtc.param[0]);
        2 : tvmbruntimeproc_cdecl2(addr)(rtc.param[0], rtc.param[1]);
        3 : tvmbruntimeproc_cdecl3(addr)(rtc.param[0], rtc.param[1], rtc.param[2]);
        4 : tvmbruntimeproc_cdecl4(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3]);
        5 : tvmbruntimeproc_cdecl5(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4]);
        6 : tvmbruntimeproc_cdecl6(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5]);
        7 : tvmbruntimeproc_cdecl7(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6]);
        8 : tvmbruntimeproc_cdecl8(addr)(rtc.param[0], rtc.param[1], rtc.param[2], rtc.param[3], rtc.param[4], rtc.param[5], rtc.param[6], rtc.param[7]);
      end;
  end;
end;