// 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;