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;