oleaut32: Use a saner calling convention for the marshaller asm thunks.
This commit is contained in:
parent
76969a8651
commit
2915e47979
@ -409,15 +409,15 @@ static HRESULT num_of_funcs(ITypeInfo *tinfo, unsigned int *num,
|
|||||||
#include "pshpack1.h"
|
#include "pshpack1.h"
|
||||||
|
|
||||||
typedef struct _TMAsmProxy {
|
typedef struct _TMAsmProxy {
|
||||||
BYTE popleax;
|
DWORD lealeax;
|
||||||
|
BYTE pushleax;
|
||||||
BYTE pushlval;
|
BYTE pushlval;
|
||||||
DWORD nr;
|
DWORD nr;
|
||||||
BYTE pushleax;
|
|
||||||
BYTE lcall;
|
BYTE lcall;
|
||||||
DWORD xcall;
|
DWORD xcall;
|
||||||
BYTE lret;
|
BYTE lret;
|
||||||
WORD bytestopop;
|
WORD bytestopop;
|
||||||
BYTE nop;
|
WORD nop;
|
||||||
} TMAsmProxy;
|
} TMAsmProxy;
|
||||||
|
|
||||||
#include "poppack.h"
|
#include "poppack.h"
|
||||||
@ -1330,10 +1330,10 @@ static inline BOOL is_out_elem(const ELEMDESC *elem)
|
|||||||
return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags);
|
return (elem->u.paramdesc.wParamFlags & PARAMFLAG_FOUT || !elem->u.paramdesc.wParamFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DWORD
|
static DWORD WINAPI xCall(int method, void **args)
|
||||||
xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|
||||||
{
|
{
|
||||||
DWORD *args = ((DWORD*)&tpinfo)+1, *xargs;
|
TMProxyImpl *tpinfo = args[0];
|
||||||
|
DWORD *xargs;
|
||||||
const FUNCDESC *fdesc;
|
const FUNCDESC *fdesc;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
int i, relaydeb = TRACE_ON(olerelay);
|
int i, relaydeb = TRACE_ON(olerelay);
|
||||||
@ -1393,7 +1393,7 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||||||
if (nrofnames > sizeof(names)/sizeof(names[0]))
|
if (nrofnames > sizeof(names)/sizeof(names[0]))
|
||||||
ERR("Need more names!\n");
|
ERR("Need more names!\n");
|
||||||
|
|
||||||
xargs = args;
|
xargs = (DWORD *)(args + 1);
|
||||||
for (i=0;i<fdesc->cParams;i++) {
|
for (i=0;i<fdesc->cParams;i++) {
|
||||||
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
|
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
|
||||||
if (relaydeb) {
|
if (relaydeb) {
|
||||||
@ -1460,7 +1460,7 @@ xCall(LPVOID retptr, int method, TMProxyImpl *tpinfo /*, args */)
|
|||||||
buf.curoff = 0;
|
buf.curoff = 0;
|
||||||
|
|
||||||
/* generic deserializer using typelib description */
|
/* generic deserializer using typelib description */
|
||||||
xargs = args;
|
xargs = (DWORD *)(args + 1);
|
||||||
status = S_OK;
|
status = S_OK;
|
||||||
for (i=0;i<fdesc->cParams;i++) {
|
for (i=0;i<fdesc->cParams;i++) {
|
||||||
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
|
ELEMDESC *elem = fdesc->lprgelemdescParam+i;
|
||||||
@ -1719,8 +1719,8 @@ static inline HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
|
|||||||
static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
|
static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
/* nrofargs without This */
|
/* nrofargs including This */
|
||||||
int nrofargs;
|
int nrofargs = 1;
|
||||||
ITypeInfo *tinfo2;
|
ITypeInfo *tinfo2;
|
||||||
TMAsmProxy *xasm = proxy->asmstubs + num;
|
TMAsmProxy *xasm = proxy->asmstubs + num;
|
||||||
HRESULT hres;
|
HRESULT hres;
|
||||||
@ -1733,7 +1733,6 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
|
|||||||
}
|
}
|
||||||
ITypeInfo_Release(tinfo2);
|
ITypeInfo_Release(tinfo2);
|
||||||
/* some args take more than 4 byte on the stack */
|
/* some args take more than 4 byte on the stack */
|
||||||
nrofargs = 0;
|
|
||||||
for (j=0;j<fdesc->cParams;j++)
|
for (j=0;j<fdesc->cParams;j++)
|
||||||
nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo);
|
nrofargs += _argsize(&fdesc->lprgelemdescParam[j].tdesc, proxy->tinfo);
|
||||||
|
|
||||||
@ -1742,25 +1741,21 @@ static HRESULT init_proxy_entry_point(TMProxyImpl *proxy, unsigned int num)
|
|||||||
ERR("calling convention is not stdcall????\n");
|
ERR("calling convention is not stdcall????\n");
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
/* popl %eax - return ptr
|
/* leal 4(%esp),%eax
|
||||||
* pushl <nr>
|
|
||||||
* pushl %eax
|
* pushl %eax
|
||||||
|
* pushl <nr>
|
||||||
* call xCall
|
* call xCall
|
||||||
* lret <nr> (+4)
|
* lret <nr>
|
||||||
*
|
|
||||||
*
|
|
||||||
* arg3 arg2 arg1 <method> <returnptr>
|
|
||||||
*/
|
*/
|
||||||
xasm->popleax = 0x58;
|
xasm->lealeax = 0x0424448d;
|
||||||
|
xasm->pushleax = 0x50;
|
||||||
xasm->pushlval = 0x68;
|
xasm->pushlval = 0x68;
|
||||||
xasm->nr = num;
|
xasm->nr = num;
|
||||||
xasm->pushleax = 0x50;
|
xasm->lcall = 0xe8;
|
||||||
xasm->lcall = 0xe8; /* relative jump */
|
xasm->xcall = (char *)xCall - (char *)&xasm->lret;
|
||||||
xasm->xcall = (DWORD)xCall;
|
|
||||||
xasm->xcall -= (DWORD)&(xasm->lret);
|
|
||||||
xasm->lret = 0xc2;
|
xasm->lret = 0xc2;
|
||||||
xasm->bytestopop = (nrofargs+2)*4; /* pop args, This, iMethod */
|
xasm->bytestopop = nrofargs * 4;
|
||||||
xasm->nop = 0x90;
|
xasm->nop = 0x9090;
|
||||||
proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
|
proxy->lpvtbl[fdesc->oVft / sizeof(void *)] = xasm;
|
||||||
#else
|
#else
|
||||||
FIXME("not implemented on non i386\n");
|
FIXME("not implemented on non i386\n");
|
||||||
@ -1800,8 +1795,6 @@ PSFacBuf_CreateProxy(
|
|||||||
proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
|
proxy = CoTaskMemAlloc(sizeof(TMProxyImpl));
|
||||||
if (!proxy) return E_OUTOFMEMORY;
|
if (!proxy) return E_OUTOFMEMORY;
|
||||||
|
|
||||||
assert(sizeof(TMAsmProxy) == 16);
|
|
||||||
|
|
||||||
proxy->dispatch = NULL;
|
proxy->dispatch = NULL;
|
||||||
proxy->dispatch_proxy = NULL;
|
proxy->dispatch_proxy = NULL;
|
||||||
proxy->outerunknown = pUnkOuter;
|
proxy->outerunknown = pUnkOuter;
|
||||||
@ -1863,40 +1856,23 @@ PSFacBuf_CreateProxy(
|
|||||||
proxy->lpvtbl[i] = ProxyIUnknown_Release;
|
proxy->lpvtbl[i] = ProxyIUnknown_Release;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
if(!defer_to_dispatch)
|
if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
|
||||||
{
|
|
||||||
hres = init_proxy_entry_point(proxy, i);
|
|
||||||
if(FAILED(hres)) return hres;
|
|
||||||
}
|
|
||||||
else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
|
else proxy->lpvtbl[3] = ProxyIDispatch_GetTypeInfoCount;
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if(!defer_to_dispatch)
|
if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
|
||||||
{
|
|
||||||
hres = init_proxy_entry_point(proxy, i);
|
|
||||||
if(FAILED(hres)) return hres;
|
|
||||||
}
|
|
||||||
else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
|
else proxy->lpvtbl[4] = ProxyIDispatch_GetTypeInfo;
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if(!defer_to_dispatch)
|
if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
|
||||||
{
|
|
||||||
hres = init_proxy_entry_point(proxy, i);
|
|
||||||
if(FAILED(hres)) return hres;
|
|
||||||
}
|
|
||||||
else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
|
else proxy->lpvtbl[5] = ProxyIDispatch_GetIDsOfNames;
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6:
|
||||||
if(!defer_to_dispatch)
|
if(!defer_to_dispatch) hres = init_proxy_entry_point(proxy, i);
|
||||||
{
|
|
||||||
hres = init_proxy_entry_point(proxy, i);
|
|
||||||
if(FAILED(hres)) return hres;
|
|
||||||
}
|
|
||||||
else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
|
else proxy->lpvtbl[6] = ProxyIDispatch_Invoke;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
hres = init_proxy_entry_point(proxy, i);
|
hres = init_proxy_entry_point(proxy, i);
|
||||||
if(FAILED(hres)) return hres;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user