Update of /cvsroot/pywin32/pywin32/com/win32com/src
In directory sfp-cvsdas-2.v30.ch3.sourceforge.com:/tmp/cvs-serv30327/com/win32com/src
Modified Files:
univgw.cpp
Log Message:
Get vtable interfaces working on 64bit windows (Nikolay Igotti)
Index: univgw.cpp
===================================================================
RCS file: /cvsroot/pywin32/pywin32/com/win32com/src/univgw.cpp,v
retrieving revision 1.13
retrieving revision 1.14
diff -C2 -d -r1.13 -r1.14
*** univgw.cpp 4 Feb 2009 02:34:24 -0000 1.13
--- univgw.cpp 27 Aug 2010 07:32:02 -0000 1.14
***************
*** 169,173 ****
! static pfnGWMethod make_method(DWORD index, UINT argsize)
{
unsigned char * code;
--- 169,173 ----
! static pfnGWMethod make_method(DWORD index, UINT argsize, UINT argc)
{
unsigned char * code;
***************
*** 234,239 ****
return NULL;
}
! #else // _M_IX86
/* The MAINWIN toolkit allows us to build this on Linux!!! */
# pragma message("XXXXXXXXX - win32com.universal wont work on this platform - need make_method")
--- 234,278 ----
return NULL;
}
+ #elif _M_X64
+ static const unsigned char wrapper[] = {
+ 0x48, 0x89, 0x54, 0x24, 0x10, /* mov [rsp + 16], rdx */
+ 0x4c, 0x89, 0x44, 0x24, 0x18, /* mov [rsp + 24], r8 */
+ 0x4c, 0x89, 0x4c, 0x24, 0x20, /* mov [rsp + 32], r9 */
! 0x48, 0x89, 0xca, /* mov rdx, rcx */
! 0x4c, 0x8d, 0x44, 0x24, 0x10, /* lea r8, [rsp + 16] */
! 0x48, 0x83, 0xec, 0x28, /* sub rsp, 40 - we have to keep stack 16-byte aligned */
! 0x48, 0xc7, 0xc1, 0x00, 0x00, 0x00, 0x00, /* mov rcx, imm32 */
! 0x48, 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* mov rax, imm64, target address */
! 0xff, 0xd0, /* call rax */
! 0x48, 0x83, 0xc4, 0x28, /* add rsp, 40 */
! 0xc3 /* ret */
! };
!
! code = (unsigned char *)VirtualAlloc(NULL, sizeof(wrapper), MEM_COMMIT, PAGE_READWRITE);
! if (code==NULL) {
! PyErr_NoMemory();
! return NULL; // caller sets memory error
! }
! memcpy(code, &wrapper[0], sizeof(wrapper));
!
! for (int i=0; i < 3; i++)
! {
! if (i < argc)
! continue;
! for (int j = 0; j < 5; j++)
! code[i*5+j] = 0x90;
! }
!
! *(int*)(code+30) = index;
! *(void**)(code+36) = &univgw_dispatch;
!
! DWORD oldprotect;
! if (!VirtualProtect(code, sizeof(wrapper), PAGE_EXECUTE, &oldprotect)) {
! VirtualFree(code, 0, MEM_RELEASE);
! PyErr_SetString(PyExc_RuntimeError, "failed to set memory attributes to executable");
! return NULL;
! }
! #else // other arches
/* The MAINWIN toolkit allows us to build this on Linux!!! */
# pragma message("XXXXXXXXX - win32com.universal wont work on this platform - need make_method")
***************
*** 369,372 ****
--- 408,415 ----
return NULL;
}
+ PyObject * methodsArgc = PyObject_CallMethod(obDef, "vtbl_argcounts", NULL);
+ if ( methodsArgc == NULL )
+ return NULL;
+
int numReservedVtables = 3; // the methods list should not specify IUnknown methods
***************
*** 418,421 ****
--- 461,468 ----
goto error;
+ PyObject * obArgCount = PySequence_GetItem(methodsArgc, i);
+ if ( obArgCount == NULL )
+ goto error;
+
int argSize = PyInt_AsLong(obArgSize);
Py_DECREF(obArgSize);
***************
*** 423,429 ****
goto error;
// dynamically construct a function with the provided argument
// size; reserve additional space for the _this argument.
! pfnGWMethod meth = make_method(i, argSize + sizeof(gw_object *));
if ( meth == NULL )
goto error;
--- 470,480 ----
goto error;
+ int argCount = PyInt_AsLong(obArgCount);
+ Py_DECREF(obArgCount);
+ if ( argCount == -1 && PyErr_Occurred() )
+ goto error;
// dynamically construct a function with the provided argument
// size; reserve additional space for the _this argument.
! pfnGWMethod meth = make_method(i, argSize + sizeof(void*), argCount + 1);
if ( meth == NULL )
goto error;
***************
*** 432,435 ****
--- 483,488 ----
}
Py_DECREF(methods);
+ Py_DECREF(methodsArgc);
+
DWORD oldprotect;
if (!VirtualProtect(vtbl, size, PAGE_EXECUTE, &oldprotect)) {
|