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.
This commit is contained in:
Thomas Heller 2006-03-22 12:59:53 +00:00
parent c61c049955
commit 59feb6f5cc
4 changed files with 52 additions and 45 deletions

View File

@ -105,6 +105,10 @@ bytes(cdata)
#include <ffi.h>
#ifdef MS_WIN32
#include <windows.h>
#include <malloc.h>
#ifndef IS_INTRESOURCE
#define IS_INTRESOURCE(x) (((size_t)(x) >> 16) == 0)
#endif
# ifdef _WIN32_WCE
/* Unlike desktop Windows, WinCE has both W and A variants of
GetProcAddress, but the default W version is not what we want */
@ -2402,7 +2406,7 @@ static PPROC FindAddress(void *handle, char *name, PyObject *type)
funcname -> _funcname@<n>
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) {
sprintf(mangled_name, "_%s@%d", name, i*4);
address = (PPROC)GetProcAddress(handle, mangled_name);
@ -2557,14 +2561,14 @@ CFuncPtr_FromDll(PyTypeObject *type, PyObject *args, PyObject *kwds)
#ifdef MS_WIN32
address = FindAddress(handle, name, (PyObject *)type);
if (!address) {
if ((size_t)name & ~0xFFFF)
if (!IS_INTRESOURCE(name))
PyErr_Format(PyExc_AttributeError,
"function '%s' not found",
name);
else
PyErr_Format(PyExc_AttributeError,
"function ordinal %d not found",
name);
(WORD)(size_t)name);
return NULL;
}
#else
@ -2651,7 +2655,7 @@ CFuncPtr_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
CFuncPtrObject *self;
PyObject *callable;
StgDictObject *dict;
THUNK thunk;
ffi_info *thunk;
if (PyTuple_GET_SIZE(args) == 0)
return GenericCData_new(type, args, kwds);
@ -3192,10 +3196,10 @@ CFuncPtr_clear(CFuncPtrObject *self)
Py_CLEAR(self->paramflags);
if (self->thunk) {
FreeCallback(self->thunk);
FreeClosure(self->thunk->pcl);
PyMem_Free(self->thunk);
self->thunk = NULL;
}
self->thunk = NULL;
return CData_clear((CDataObject *)self);
}

View File

@ -264,16 +264,6 @@ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print()
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,
void *resp,
void **args,
@ -289,15 +279,10 @@ static void closure_fcn(ffi_cif *cif,
args);
}
void FreeCallback(THUNK thunk)
{
FreeClosure(((ffi_info *)thunk)->pcl);
}
THUNK AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int is_cdecl)
ffi_info *AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int is_cdecl)
{
int result;
ffi_info *p;
@ -306,8 +291,10 @@ THUNK AllocFunctionCallback(PyObject *callable,
nArgs = PySequence_Size(converters);
p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * (nArgs + 1));
if (p == NULL)
return (THUNK)PyErr_NoMemory();
if (p == NULL) {
PyErr_NoMemory();
return NULL;
}
p->pcl = MallocClosure();
if (p->pcl == NULL) {
PyErr_NoMemory();
@ -356,11 +343,12 @@ THUNK AllocFunctionCallback(PyObject *callable,
p->converters = converters;
p->callable = callable;
return (THUNK)p;
return p;
error:
if (p) {
FreeCallback((THUNK)p);
if (p->pcl)
FreeClosure(p->pcl);
PyMem_Free(p);
}
return NULL;

View File

@ -64,14 +64,17 @@
#endif
#ifdef MS_WIN32
#define alloca _alloca
#include <malloc.h>
#endif
#include <ffi.h>
#include "ctypes.h"
#ifdef _DEBUG
#define DEBUG_EXCEPTIONS /* */
#if defined(_DEBUG) || defined(__MINGW32__)
/* Don't use structured exception handling on Windows if this is defined.
MingW, AFAIK, doesn't support it.
*/
#define DONT_USE_SEH
#endif
#ifdef MS_WIN32
@ -96,6 +99,7 @@ static TCHAR *FormatError(DWORD code)
return lpMsgBuf;
}
#ifndef DONT_USE_SEH
void SetException(DWORD code, EXCEPTION_RECORD *pr)
{
TCHAR *lpMsgBuf;
@ -254,6 +258,7 @@ static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
*record = *ptrs->ExceptionRecord;
return EXCEPTION_EXECUTE_HANDLER;
}
#endif
static PyObject *
check_hresult(PyObject *self, PyObject *args)
@ -612,8 +617,10 @@ static int _call_function_pointer(int flags,
int cc;
#ifdef MS_WIN32
int delta;
#ifndef DONT_USE_SEH
DWORD dwExceptionCode = 0;
EXCEPTION_RECORD record;
#endif
#endif
/* XXX check before here */
if (restype == NULL) {
@ -640,14 +647,14 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_UNBLOCK_THREADS
#ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS
#ifndef DONT_USE_SEH
__try {
#endif
delta =
#endif
ffi_call(&cif, (void *)pProc, resmem, avalues);
#ifdef MS_WIN32
#ifndef DEBUG_EXCEPTIONS
#ifndef DONT_USE_SEH
}
__except (HandleException(GetExceptionInformation(),
&dwExceptionCode, &record)) {
@ -658,10 +665,12 @@ static int _call_function_pointer(int flags,
if ((flags & FUNCFLAG_PYTHONAPI) == 0)
Py_BLOCK_THREADS
#ifdef MS_WIN32
#ifndef DONT_USE_SEH
if (dwExceptionCode) {
SetException(dwExceptionCode, &record);
return -1;
}
#endif
if (delta < 0) {
if (flags & FUNCFLAG_CDECL)
PyErr_Format(PyExc_ValueError,

View File

@ -21,8 +21,9 @@ typedef int Py_ssize_t;
#define PY_LONG_LONG LONG_LONG
#endif
typedef int (*THUNK)(void);
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
this buffer is too small, PyMem_Malloc will be called to create a larger one,
@ -62,6 +63,16 @@ struct tagCDataObject {
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 {
/* First part identical to tagCDataObject */
PyObject_HEAD
@ -76,7 +87,7 @@ typedef struct {
union value b_value;
/* end of tagCDataObject, additional fields follow */
THUNK thunk;
ffi_info *thunk;
PyObject *callable;
/* These two fields will override the ones in the type's stgdict if
@ -145,17 +156,12 @@ CreateArrayType(PyObject *itemtype, Py_ssize_t length);
extern void init_callbacks_in_module(PyObject *m);
extern THUNK AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int stdcall);
extern void FreeCallback(THUNK);
extern PyMethodDef module_methods[];
typedef PyObject *(* GETFUNC)(void *, unsigned size);
typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size);
extern ffi_info *AllocFunctionCallback(PyObject *callable,
PyObject *converters,
PyObject *restype,
int stdcall);
/* a table entry describing a predefined ctypes type */
struct fielddesc {
char code;