Commit 59feb6f5 authored by Thomas Heller's avatar Thomas Heller

Include <malloc.h> on windows, to avoid warnings when compiling with mingw.

Don't use SEH when compiling wth mingw.
Use IS_INTRESOURCE to determine function name from function ordinal.

Rewrite the code that allocates and frees callback functions, hopefully
this avoids the coverty warnings: Remove the THUNK typedef, and move the
definition of struct ffi_info into the header file.
parent c61c0499
...@@ -105,6 +105,10 @@ bytes(cdata) ...@@ -105,6 +105,10 @@ bytes(cdata)
#include <ffi.h> #include <ffi.h>
#ifdef MS_WIN32 #ifdef MS_WIN32
#include <windows.h> #include <windows.h>
#include <malloc.h>
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
#endif
# ifdef _WIN32_WCE # ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of /* Unlike desktop Windows, WinCE has both W and A variants of
GetProcAddress, but the default W version is not what we want */ GetProcAddress, but the default W version is not what we want */
...@@ -2402,7 +2406,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type) ...@@ -2402,7 +2406,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type)
funcname -> _funcname@<n> funcname -> _funcname@<n>
where n is 0, 4, 8, 12, ..., 128 where n is 0, 4, 8, 12, ..., 128
*/ */
mangled_name = _alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */ mangled_name = alloca(strlen(name) + 1 + 1 + 1 + 3); /* \0 _ @ %d */
for (i = 0; i < 32; ++i) { for (i = 0; i < 32; ++i) {
sprintf(mangled_name, "_%s@%d", name, i*4); sprintf(mangled_name, "_%s@%d", name, i*4);
address = (PPROC)GetProcAddress(handle, mangled_name); address = (PPROC)GetProcAddress(handle, mangled_name);
...@@ -2557,14 +2561,14 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2557,14 +2561,14 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
#ifdef MS_WIN32 #ifdef MS_WIN32
address = FindAddress(handle, name, (PyObject *)type); address = FindAddress(handle, name, (PyObject *)type);
if (!address) { if (!address) {
if ((size_t)name & ~0xFFFF) if (!IS_INTRESOURCE(name))
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"function '%s' not found", "function '%s' not found",
name); name);
else else
PyErr_Format(PyExc_AttributeError, PyErr_Format(PyExc_AttributeError,
"function ordinal %d not found", "function ordinal %d not found",
name); (WORD)(size_t)name);
return NULL; return NULL;
} }
#else #else
...@@ -2651,7 +2655,7 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -2651,7 +2655,7 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
CFuncPtrObject *self; CFuncPtrObject *self;
PyObject *callable; PyObject *callable;
StgDictObject *dict; StgDictObject *dict;
THUNK thunk; ffi_info *thunk;
if (PyTuple_GET_SIZE(args) == 0) if (PyTuple_GET_SIZE(args) == 0)
return GenericCData_new(type, args, kwds); return GenericCData_new(type, args, kwds);
...@@ -3192,10 +3196,10 @@ CFuncPtr_clear(CFuncPtrObject *self) ...@@ -3192,10 +3196,10 @@ CFuncPtr_clear(CFuncPtrObject *self)
Py_CLEAR(self->paramflags); Py_CLEAR(self->paramflags);
if (self->thunk) { if (self->thunk) {
FreeCallback(self->thunk); FreeClosure(self->thunk->pcl);
PyMem_Free(self->thunk); PyMem_Free(self->thunk);
}
self->thunk = NULL; self->thunk = NULL;
}
return CData_clear((CDataObject *)self); return CData_clear((CDataObject *)self);
} }
......
...@@ -264,16 +264,6 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print() ...@@ -264,16 +264,6 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
PyGILState_Release(state); PyGILState_Release(state);
} }
typedef struct {
ffi_closure *pcl; /* the C callable */
ffi_cif cif;
PyObject *converters;
PyObject *callable;
SETFUNC setfunc;
ffi_type *restype;
ffi_type *atypes[0];
} ffi_info;
static void closure_fcn(ffi_cif *cif, static void closure_fcn(ffi_cif *cif,
void *resp, void *resp,
void **args, void **args,
...@@ -289,12 +279,7 @@ static void closure_fcn(ffi_cif *cif, ...@@ -289,12 +279,7 @@ static void closure_fcn(ffi_cif *cif,
args); args);
} }
void FreeCallback(THUNK thunk) ffi_info *AllocFunctionCallback(PyObject *callable,
{
FreeClosure(((ffi_info *)thunk)->pcl);
}
THUNK AllocFunctionCallback(PyObject *callable,
PyObject *converters, PyObject *converters,
PyObject *restype, PyObject *restype,
int is_cdecl) int is_cdecl)
...@@ -306,8 +291,10 @@ THUNK AllocFunctionCallback(PyObject *callable, ...@@ -306,8 +291,10 @@ THUNK AllocFunctionCallback(PyObject *callable,
nArgs = PySequence_Size(converters); nArgs = PySequence_Size(converters);
p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1)); p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
if (p == NULL) if (p == NULL) {
return (THUNK)PyErr_NoMemory(); PyErr_NoMemory();
return NULL;
}
p->pcl = MallocClosure(); p->pcl = MallocClosure();
if (p->pcl == NULL) { if (p->pcl == NULL) {
PyErr_NoMemory(); PyErr_NoMemory();
...@@ -356,11 +343,12 @@ THUNK AllocFunctionCallback(PyObject *callable, ...@@ -356,11 +343,12 @@ THUNK AllocFunctionCallback(PyObject *callable,
p->converters = converters; p->converters = converters;
p->callable = callable; p->callable = callable;
return (THUNK)p; return p;
error: error:
if (p) { if (p) {
FreeCallback((THUNK)p); if (p->pcl)
FreeClosure(p->pcl);
PyMem_Free(p); PyMem_Free(p);
} }
return NULL; return NULL;
......
...@@ -64,14 +64,17 @@ ...@@ -64,14 +64,17 @@
#endif #endif
#ifdef MS_WIN32 #ifdef MS_WIN32
#define alloca _alloca #include <malloc.h>
#endif #endif
#include <ffi.h> #include <ffi.h>
#include "ctypes.h" #include "ctypes.h"
#ifdef _DEBUG #if defined(_DEBUG) || defined(__MINGW32__)
#define DEBUG_EXCEPTIONS /* */ /* Don't use structured exception handling on Windows if this is defined.
MingW, AFAIK, doesn't support it.
*/
#define DONT_USE_SEH
#endif #endif
#ifdef MS_WIN32 #ifdef MS_WIN32
...@@ -96,6 +99,7 @@ static TCHAR *FormatError(DWORD code) ...@@ -96,6 +99,7 @@ static TCHAR *FormatError(DWORD code)
return lpMsgBuf; return lpMsgBuf;
} }
#ifndef DONT_USE_SEH
void SetException(DWORD code, EXCEPTION_RECORD *pr) void SetException(DWORD code, EXCEPTION_RECORD *pr)
{ {
TCHAR *lpMsgBuf; TCHAR *lpMsgBuf;
...@@ -254,6 +258,7 @@ static DWORD HandleException(EXCEPTION_POINTERS *ptrs, ...@@ -254,6 +258,7 @@ static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
*record = *ptrs->ExceptionRecord; *record = *ptrs->ExceptionRecord;
return EXCEPTION_EXECUTE_HANDLER; return EXCEPTION_EXECUTE_HANDLER;
} }
#endif
static PyObject * static PyObject *
check_hresult(PyObject *self, PyObject *args) check_hresult(PyObject *self, PyObject *args)
...@@ -612,8 +617,10 @@ static int _call_function_pointer(int flags, ...@@ -612,8 +617,10 @@ static int _call_function_pointer(int flags,
int cc; int cc;
#ifdef MS_WIN32 #ifdef MS_WIN32
int delta; int delta;
#ifndef DONT_USE_SEH
DWORD dwExceptionCode = 0; DWORD dwExceptionCode = 0;
EXCEPTION_RECORD record; EXCEPTION_RECORD record;
#endif
#endif #endif
/* XXX check before here */ /* XXX check before here */
if (restype == NULL) { if (restype == NULL) {
...@@ -640,14 +647,14 @@ static int _call_function_pointer(int flags, ...@@ -640,14 +647,14 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0) if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_UNBLOCK_THREADS Py_UNBLOCK_THREADS
#ifdef MS_WIN32 #ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS #ifndef DONT_USE_SEH
__try { __try {
#endif #endif
delta = delta =
#endif #endif
ffi_call(&cif, (void *)pProc, resmem, avalues); ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32 #ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS #ifndef DONT_USE_SEH
} }
__except (HandleException(GetExceptionInformation(), __except (HandleException(GetExceptionInformation(),
&dwExceptionCode, &record)) { &dwExceptionCode, &record)) {
...@@ -658,10 +665,12 @@ static int _call_function_pointer(int flags, ...@@ -658,10 +665,12 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0) if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS Py_BLOCK_THREADS
#ifdef MS_WIN32 #ifdef MS_WIN32
#ifndef DONT_USE_SEH
if (dwExceptionCode) { if (dwExceptionCode) {
SetException(dwExceptionCode, &record); SetException(dwExceptionCode, &record);
return -1; return -1;
} }
#endif
if (delta < 0) { if (delta < 0) {
if (flags & FUNCFLAG_CDECL) if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError, PyErr_Format(PyExc_ValueError,
......
...@@ -21,8 +21,9 @@ typedef int Py_ssize_t; ...@@ -21,8 +21,9 @@ typedef int Py_ssize_t;
#define PY_LONG_LONG LONG_LONG #define PY_LONG_LONG LONG_LONG
#endif #endif
typedef int (*THUNK)(void);
typedef struct tagCDataObject CDataObject; typedef struct tagCDataObject CDataObject;
typedef PyObject *(* GETFUNC)(void *, unsigned size);
typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
/* A default buffer in CDataObject, which can be used for small C types. If /* A default buffer in CDataObject, which can be used for small C types. If
this buffer is too small, PyMem_Malloc will be called to create a larger one, this buffer is too small, PyMem_Malloc will be called to create a larger one,
...@@ -62,6 +63,16 @@ struct tagCDataObject { ...@@ -62,6 +63,16 @@ struct tagCDataObject {
union value b_value; union value b_value;
}; };
typedef struct {
ffi_closure *pcl; /* the C callable */
ffi_cif cif;
PyObject *converters;
PyObject *callable;
SETFUNC setfunc;
ffi_type *restype;
ffi_type *atypes[0];
} ffi_info;
typedef struct { typedef struct {
/* First part identical to tagCDataObject */ /* First part identical to tagCDataObject */
PyObject_HEAD PyObject_HEAD
...@@ -76,7 +87,7 @@ typedef struct { ...@@ -76,7 +87,7 @@ typedef struct {
union value b_value; union value b_value;
/* end of tagCDataObject, additional fields follow */ /* end of tagCDataObject, additional fields follow */
THUNK thunk; ffi_info *thunk;
PyObject *callable; PyObject *callable;
/* These two fields will override the ones in the type's stgdict if /* These two fields will override the ones in the type's stgdict if
...@@ -145,17 +156,12 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length); ...@@ -145,17 +156,12 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length);
extern void init_callbacks_in_module(PyObject *m); extern void init_callbacks_in_module(PyObject *m);
extern THUNK AllocFunctionCallback(PyObject *callable, extern PyMethodDef module_methods[];
extern ffi_info *AllocFunctionCallback(PyObject *callable,
PyObject *converters, PyObject *converters,
PyObject *restype, PyObject *restype,
int stdcall); int stdcall);
extern void FreeCallback(THUNK);
extern PyMethodDef module_methods[];
typedef PyObject *(* GETFUNC)(void *, unsigned size);
typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
/* a table entry describing a predefined ctypes type */ /* a table entry describing a predefined ctypes type */
struct fielddesc { struct fielddesc {
char code; char code;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment