ctypes-commit Mailing List for ctypes (Page 110)
Brought to you by:
theller
You can subscribe to this list here.
2004 |
Jan
|
Feb
|
Mar
|
Apr
(8) |
May
(90) |
Jun
(143) |
Jul
(106) |
Aug
(94) |
Sep
(84) |
Oct
(163) |
Nov
(60) |
Dec
(58) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2005 |
Jan
(128) |
Feb
(79) |
Mar
(227) |
Apr
(192) |
May
(179) |
Jun
(41) |
Jul
(53) |
Aug
(103) |
Sep
(28) |
Oct
(38) |
Nov
(81) |
Dec
(17) |
2006 |
Jan
(184) |
Feb
(111) |
Mar
(188) |
Apr
(67) |
May
(58) |
Jun
(123) |
Jul
(73) |
Aug
|
Sep
|
Oct
(1) |
Nov
|
Dec
|
From: Thomas H. <th...@us...> - 2004-05-14 19:01:31
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv6951 Modified Files: callproc.c Log Message: Actually *use* the PyCArgObject's pffi_type field for calling a function. Should eventually make tag2ffitype() obsolete. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** callproc.c 14 May 2004 18:50:01 -0000 1.69 --- callproc.c 14 May 2004 19:01:14 -0000 1.70 *************** *** 621,625 **** for (i = 0; i < argcount; ++i) { ! ffi_type * tp = tag2ffitype(parms[i]->tag); if (tp == NULL) return -1; --- 621,629 ---- for (i = 0; i < argcount; ++i) { ! ffi_type *tp = parms[i]->pffi_type; ! if (tp == NULL) { ! fprintf(stderr, "BUG (arg): NO TYPE FOR '%c'\n", parms[i]->tag); ! tp = tag2ffitype(parms[i]->tag); ! } if (tp == NULL) return -1; *************** *** 627,631 **** values[i] = &parms[i]->value; } ! rtype = tag2ffitype(res->tag); if (FFI_OK != ffi_prep_cif(&cif, FFI_DEFAULT_ABI, --- 631,639 ---- values[i] = &parms[i]->value; } ! rtype = res->pffi_type; ! if (rtype == NULL) { ! fprintf(stderr, "BUG (result): NO TYPE FOR '%c'\n", res->tag); ! rtype = tag2ffitype(res->tag); ! } if (FFI_OK != ffi_prep_cif(&cif, FFI_DEFAULT_ABI, *************** *** 922,925 **** --- 930,934 ---- if (PointerTypeObject_Check(restype)) { + result->pffi_type = &ffi_type_pointer; result->tag = 'P'; return; *************** *** 948,951 **** --- 957,961 ---- if (PyCallable_Check(restype)) { result->tag = 'i'; /* call with integer result */ + result->pffi_type = &ffi_type_sint; return; } *************** *** 953,956 **** --- 963,967 ---- if (restype == Py_None) { result->tag = 'v'; /* call with void result */ + result->pffi_type = &ffi_type_void; return; } *************** *** 958,961 **** --- 969,973 ---- /* XXX This should not occur... */ result->tag = 'i'; + result->pffi_type = &ffi_type_sint; } |
From: Thomas H. <th...@us...> - 2004-05-14 18:50:18
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv4193 Modified Files: callproc.c _ctypes.c Log Message: Set the PyCArgObject's pffi_type slot, and print a warning if it's NULL. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** callproc.c 14 May 2004 18:01:30 -0000 1.68 --- callproc.c 14 May 2004 18:50:01 -0000 1.69 *************** *** 268,271 **** --- 268,272 ---- if (p == NULL) return NULL; + p->pffi_type = NULL; p->tag = '\0'; p->obj = NULL; *************** *** 693,697 **** for (i = argcount-1; i >= 0; --i) { float f; ! switch(parms[i]->tag) { case 'c': --- 694,703 ---- for (i = argcount-1; i >= 0; --i) { float f; ! if (parms[i]->pffi_type == NULL) { ! fprintf(stderr, "NO FFI_TYPE %c\n", parms[i]->tag); ! #ifdef _DEBUG ! _asm int 3; ! #endif ! } switch(parms[i]->tag) { case 'c': Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.139 retrieving revision 1.140 diff -C2 -d -r1.139 -r1.140 *** _ctypes.c 14 May 2004 17:57:04 -0000 1.139 --- _ctypes.c 14 May 2004 18:50:03 -0000 1.140 *************** *** 940,943 **** --- 940,944 ---- parg = new_CArgObject(); + parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); *************** *** 992,995 **** --- 993,997 ---- parg = new_CArgObject(); + parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); *************** *** 1046,1049 **** --- 1048,1052 ---- parg = new_CArgObject(); + parg->pffi_type = &ffi_type_pointer; parg->tag = 'z'; parg->obj = fd->setfunc(&parg->value, value, 0); *************** *** 1059,1062 **** --- 1062,1066 ---- parg = new_CArgObject(); + parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; parg->obj = fd->setfunc(&parg->value, value, 0); *************** *** 1095,1098 **** --- 1099,1103 ---- if (parg == NULL) return NULL; + parg->pffi_type = &ffi_type_pointer; parg->tag = 'Z'; Py_INCREF(value); *************** *** 1274,1277 **** --- 1279,1283 ---- parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; parg->obj = fd->setfunc(&parg->value, value, 0); if (parg->obj == NULL) { *************** *** 2072,2075 **** --- 2078,2082 ---- parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; Py_INCREF(self); parg->obj = (PyObject *)self; *************** *** 2564,2567 **** --- 2571,2575 ---- parg->tag = 'V'; + //XXX parg->pffi_type = ?? parg->value.p = self->b_ptr; parg->size = self->b_size; *************** *** 2836,2839 **** --- 2844,2848 ---- return NULL; p->tag = 'P'; + p->pffi_type = &ffi_type_pointer; p->value.p = (char *)self->b_ptr; Py_INCREF(self); *************** *** 3000,3003 **** --- 3009,3013 ---- parg->tag = fmt[0]; + parg->pffi_type = fd->pffi_type; Py_INCREF(self); parg->obj = (PyObject *)self; *************** *** 3188,3191 **** --- 3198,3202 ---- parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; Py_INCREF(self); parg->obj = (PyObject *)self; *************** *** 3377,3380 **** --- 3388,3392 ---- parg->tag = 'P'; + parg->pffi_type = &ffi_type_pointer; Py_INCREF(obj); parg->obj = obj; |
From: Thomas H. <th...@us...> - 2004-05-14 18:01:42
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25862 Modified Files: callproc.c Log Message: Small fix. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** callproc.c 14 May 2004 17:57:04 -0000 1.67 --- callproc.c 14 May 2004 18:01:30 -0000 1.68 *************** *** 484,488 **** #ifdef HAVE_USABLE_WCHAR_T if (PyUnicode_Check(obj)) { ! parm->ffi_type = &ffi_type_pointer; parm->tag = 'P'; parm->value.p = PyUnicode_AS_UNICODE(obj); --- 484,488 ---- #ifdef HAVE_USABLE_WCHAR_T if (PyUnicode_Check(obj)) { ! parm->pffi_type = &ffi_type_pointer; parm->tag = 'P'; parm->value.p = PyUnicode_AS_UNICODE(obj); |
From: Thomas H. <th...@us...> - 2004-05-14 17:57:14
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24793 Modified Files: _ctypes.c callproc.c ctypes.h Log Message: StgDictObject's now have a ffi_type field. PyCArgObject's have a pointer to ffi_type field. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** ctypes.h 11 May 2004 19:30:19 -0000 1.42 --- ctypes.h 14 May 2004 17:57:04 -0000 1.43 *************** *** 135,139 **** SETFUNC setfunc; GETFUNC getfunc; ! ffi_type *tp; /* always statically allocated */ }; --- 135,139 ---- SETFUNC setfunc; GETFUNC getfunc; ! ffi_type *pffi_type; /* always statically allocated */ }; *************** *** 156,159 **** --- 156,160 ---- int align; /* alignment requirements */ int length; /* number of fields */ + ffi_type ffi_type; PyObject *proto; /* Only for Pointer/ArrayObject */ SETFUNC setfunc; /* Only for ArrayObject */ *************** *** 209,212 **** --- 210,214 ---- typedef struct { PyObject_HEAD + ffi_type *pffi_type; char tag; union { Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** callproc.c 14 May 2004 16:50:13 -0000 1.66 --- callproc.c 14 May 2004 17:57:04 -0000 1.67 *************** *** 438,441 **** --- 438,442 ---- /* check for None, integer, string or unicode and use directly if successful */ if (obj == Py_None) { + parm->pffi_type = &ffi_type_pointer; parm->tag = 'P'; parm->value.p = NULL; *************** *** 446,449 **** --- 447,451 ---- if (PyInt_Check(obj)) { + parm->pffi_type = &ffi_type_sint; parm->tag = 'i'; parm->value.i = PyInt_AS_LONG(obj); *************** *** 454,457 **** --- 456,460 ---- if (PyLong_Check(obj)) { + parm->pffi_type = &ffi_type_sint; parm->tag = 'i'; parm->value.i = (long)PyLong_AsUnsignedLong(obj); *************** *** 471,474 **** --- 474,478 ---- if (PyString_Check(obj)) { + parm->pffi_type = &ffi_type_pointer; parm->tag = 'P'; parm->value.p = PyString_AS_STRING(obj); *************** *** 480,483 **** --- 484,488 ---- #ifdef HAVE_USABLE_WCHAR_T if (PyUnicode_Check(obj)) { + parm->ffi_type = &ffi_type_pointer; parm->tag = 'P'; parm->value.p = PyUnicode_AS_UNICODE(obj); *************** *** 506,509 **** --- 511,515 ---- } if (PyInt_Check(arg)) { + parm->pffi_type = &ffi_type_sint; parm->tag = 'i'; parm->value.i = PyInt_AS_LONG(arg); *************** *** 879,882 **** --- 885,889 ---- if (restype == NULL) { + result->pffi_type = &ffi_type_sint; result->tag = 'i'; return; *************** *** 895,898 **** --- 902,906 ---- if (strchr("zcbBhHiIlLqQdfP", fmt[0])) { result->tag = fmt[0]; + result->pffi_type = &dict->ffi_type; return; } *************** *** 1055,1058 **** --- 1063,1067 ---- if (pargs[0] == NULL) return NULL; + pargs[0]->pffi_type = &ffi_type_pointer; pargs[0]->tag = 'P'; pargs[0]->value.p = pIunk; Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.138 retrieving revision 1.139 diff -C2 -d -r1.138 -r1.139 *** _ctypes.c 7 May 2004 19:56:24 -0000 1.138 --- _ctypes.c 14 May 2004 17:57:04 -0000 1.139 *************** *** 461,465 **** return NULL; stgdict->size = sizeof(void *); ! stgdict->align = getentry("P")->tp->alignment; stgdict->length = 2; --- 461,465 ---- return NULL; stgdict->size = sizeof(void *); ! stgdict->align = getentry("P")->pffi_type->alignment; stgdict->length = 2; *************** *** 1157,1163 **** fmt = getentry(PyString_AS_STRING(proto)); ! stgdict->align = fmt->tp->alignment; stgdict->length = 1; ! stgdict->size = fmt->tp->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; --- 1157,1164 ---- fmt = getentry(PyString_AS_STRING(proto)); ! stgdict->ffi_type = *fmt->pffi_type; ! stgdict->align = fmt->pffi_type->alignment; stgdict->length = 1; ! stgdict->size = fmt->pffi_type->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; *************** *** 1394,1398 **** PyObject *converters = NULL; ! stgdict->align = getentry("P")->tp->alignment; stgdict->length = 1; stgdict->size = sizeof(void *); --- 1395,1399 ---- PyObject *converters = NULL; ! stgdict->align = getentry("P")->pffi_type->alignment; stgdict->length = 1; stgdict->size = sizeof(void *); |
From: Thomas H. <th...@us...> - 2004-05-14 16:50:23
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8682/source Modified Files: callproc.c Log Message: Remove the hack about ffi_type_long. It was a misunderstanding on my side. Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** callproc.c 7 May 2004 19:56:24 -0000 1.65 --- callproc.c 14 May 2004 16:50:13 -0000 1.66 *************** *** 539,564 **** #ifndef MS_WIN32 - /* - There's a problem with current CVS versions of libffi (2003-01-21). - It redefines ffi_type_slong and ffi_type_ulong to - ffi_type_sint64 and ffi_type_uint64. - - Fortunately, ctypes' unittests catch this. - - printf("SIZEOF_LONG %d\n", SIZEOF_LONG); - - printf("ffi_type_slong %p\n", &ffi_type_slong); - printf("ffi_type_sint64 %p\n", &ffi_type_sint64); - printf("ffi_type_sint %p\n", &ffi_type_sint); - printf("ffi_type_sint32 %p\n", &ffi_type_sint32); - */ - #if (SIZEOF_LONG_LONG == 8 && SIZEOF_LONG == 4) - #undef ffi_type_ulong - #define ffi_type_ulong ffi_type_uint32 - #undef ffi_type_slong - #define ffi_type_slong ffi_type_sint32 - #endif - #define ffi_type_ulonglong ffi_type_uint64 - #define ffi_type_slonglong ffi_type_sint64 ffi_type *tag2ffitype(char tag) --- 539,542 ---- *************** *** 572,598 **** return &ffi_type_uint8; case 'h': ! return &ffi_type_sshort; case 'H': ! return &ffi_type_ushort; case 'i': ! return &ffi_type_sint; case 'I': ! return &ffi_type_uint; case 'l': ! return &ffi_type_slong; case 'L': ! return &ffi_type_ulong; case 'q': ! return &ffi_type_slonglong; case 'Q': ! return &ffi_type_ulonglong; case 'z': case 'Z': case 'P': ! return&ffi_type_pointer; case 'd': ! return&ffi_type_double; case 'f': ! return&ffi_type_float; case 'v': return &ffi_type_void; --- 550,576 ---- return &ffi_type_uint8; case 'h': ! return &ffi_type_sint16; case 'H': ! return &ffi_type_uint16; case 'i': ! return &ffi_type_sint32; case 'I': ! return &ffi_type_uint32; case 'l': ! return &ffi_type_sint32; case 'L': ! return &ffi_type_uint32; case 'q': ! return &ffi_type_sint64; case 'Q': ! return &ffi_type_uint64; case 'z': case 'Z': case 'P': ! return &ffi_type_pointer; case 'd': ! return &ffi_type_double; case 'f': ! return &ffi_type_float; case 'v': return &ffi_type_void; |
From: Thomas H. <th...@us...> - 2004-05-14 16:49:05
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8297/source Modified Files: callbacks.c Log Message: Pass libffi the correct argument types. Allow 'z' and 'c' formats as return types. Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** callbacks.c 14 May 2004 15:05:28 -0000 1.42 --- callbacks.c 14 May 2004 16:48:54 -0000 1.43 *************** *** 501,504 **** --- 501,506 ---- } + extern ffi_type *tag2ffitype(char tag); + THUNK AllocFunctionCallback(PyObject *callable, int nArgBytes, *************** *** 513,526 **** nArgs = PySequence_Size(converters); ! p = PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * nArgs); /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! p->atypes[i] = &ffi_type_sint; } /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! &ffi_type_sint, &p->atypes[0]); --- 515,532 ---- nArgs = PySequence_Size(converters); ! p = (ffi_info *)PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * nArgs); /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! PyObject *cnv = PySequence_GetItem(converters, i); ! PrepareResult(restype, &cResult); ! p->atypes[i] = tag2ffitype(cResult.tag); ! Py_DECREF(cnv); } + PrepareResult(restype, &cResult); /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! tag2ffitype(cResult.tag), &p->atypes[0]); *************** *** 528,532 **** result = ffi_prep_closure(&p->cl, &p->cif, closure_fcn, p); - PrepareResult(restype, &cResult); switch (cResult.tag) { /* "bBhHiIlLqQdfP" */ --- 534,537 ---- *************** *** 554,557 **** --- 559,568 ---- p->format = "f"; break; + case 'z': + p->format = "z"; + break; + case 'c': + p->format = "c"; + break; default: PyErr_Format(PyExc_TypeError, "invalid restype %c", cResult.tag); |
From: Thomas H. <th...@us...> - 2004-05-14 15:05:39
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18248 Modified Files: callbacks.c Log Message: Revert last checkin, it doesn't seem to really work. Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** callbacks.c 14 May 2004 14:19:33 -0000 1.41 --- callbacks.c 14 May 2004 15:05:28 -0000 1.42 *************** *** 501,526 **** } - static ffi_type *ffi_type_for_fmt(char fmt) - { - switch (fmt) { - /* "bBhHiIlLqQdfP" */ - case 'b': return &ffi_type_sint8; - case 'B': return &ffi_type_uint8; - case 'h': return &ffi_type_sint16; - case 'H': return &ffi_type_uint16; - case 'i': return &ffi_type_sint32; - case 'I': return &ffi_type_uint32; - case 'l': return &ffi_type_sint32; - case 'L': return &ffi_type_uint32; - case 'q': return &ffi_type_sint64; - case 'Q': return &ffi_type_uint64; - case 'f': return &ffi_type_float; - case 'd': return &ffi_type_double; - case 'D': return &ffi_type_longdouble; - case 'P': return &ffi_type_pointer; - } - return NULL; - } - THUNK AllocFunctionCallback(PyObject *callable, int nArgBytes, --- 501,504 ---- *************** *** 539,552 **** /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! PyObject *cnv = PySequence_GetItem(converters, i); ! PrepareResult(cnv, &cResult); ! p->atypes[i] = ffi_type_for_fmt(cResult.tag); ! Py_DECREF(cnv); } - PrepareResult(restype, &cResult); /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! ffi_type_for_fmt(cResult.tag), &p->atypes[0]); --- 517,526 ---- /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! p->atypes[i] = &ffi_type_sint; } /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! &ffi_type_sint, &p->atypes[0]); *************** *** 554,557 **** --- 528,532 ---- result = ffi_prep_closure(&p->cl, &p->cif, closure_fcn, p); + PrepareResult(restype, &cResult); switch (cResult.tag) { /* "bBhHiIlLqQdfP" */ |
From: Thomas H. <th...@us...> - 2004-05-14 14:19:43
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8463 Modified Files: callbacks.c Log Message: Implement a patch provided by Bob Ippolito. Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** callbacks.c 14 May 2004 14:09:08 -0000 1.40 --- callbacks.c 14 May 2004 14:19:33 -0000 1.41 *************** *** 501,504 **** --- 501,526 ---- } + static ffi_type *ffi_type_for_fmt(char fmt) + { + switch (fmt) { + /* "bBhHiIlLqQdfP" */ + case 'b': return &ffi_type_sint8; + case 'B': return &ffi_type_uint8; + case 'h': return &ffi_type_sint16; + case 'H': return &ffi_type_uint16; + case 'i': return &ffi_type_sint32; + case 'I': return &ffi_type_uint32; + case 'l': return &ffi_type_sint32; + case 'L': return &ffi_type_uint32; + case 'q': return &ffi_type_sint64; + case 'Q': return &ffi_type_uint64; + case 'f': return &ffi_type_float; + case 'd': return &ffi_type_double; + case 'D': return &ffi_type_longdouble; + case 'P': return &ffi_type_pointer; + } + return NULL; + } + THUNK AllocFunctionCallback(PyObject *callable, int nArgBytes, *************** *** 517,526 **** /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! p->atypes[i] = &ffi_type_sint; } /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! &ffi_type_sint, &p->atypes[0]); --- 539,552 ---- /* Check for NULL */ for (i = 0; i < nArgs; ++i) { ! PyObject *cnv = PySequence_GetItem(converters, i); ! PrepareResult(cnv, &cResult); ! p->atypes[i] = ffi_type_for_fmt(cResult.tag); ! Py_DECREF(cnv); } + PrepareResult(restype, &cResult); /* XXX Check for FFI_OK */ result = ffi_prep_cif(&p->cif, FFI_DEFAULT_ABI, nArgs, ! ffi_type_for_fmt(cResult.tag), &p->atypes[0]); *************** *** 528,532 **** result = ffi_prep_closure(&p->cl, &p->cif, closure_fcn, p); - PrepareResult(restype, &cResult); switch (cResult.tag) { /* "bBhHiIlLqQdfP" */ --- 554,557 ---- |
From: Thomas H. <th...@us...> - 2004-05-14 14:09:20
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv5346 Modified Files: callbacks.c Log Message: Replace malloc/free with PyMem_Malloc/PyMem_Free. Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** callbacks.c 7 May 2004 19:56:24 -0000 1.39 --- callbacks.c 14 May 2004 14:09:08 -0000 1.40 *************** *** 397,401 **** BYTE *pCallback, *pNargBytes, *pConverters, *pCalladdr, *pRouter; ! pCallback = malloc(ti.pEnd - ti.pStart); memcpy(pCallback, ti.pStart, ti.pEnd - ti.pStart); pNargBytes = pCallback +(ti.pEnd - ti.pStart) - 16; --- 397,401 ---- BYTE *pCallback, *pNargBytes, *pConverters, *pCalladdr, *pRouter; ! pCallback = PyMem_Malloc(ti.pEnd - ti.pStart); memcpy(pCallback, ti.pStart, ti.pEnd - ti.pStart); pNargBytes = pCallback +(ti.pEnd - ti.pStart) - 16; *************** *** 513,517 **** nArgs = PySequence_Size(converters); ! p = malloc(sizeof(ffi_info) + sizeof(ffi_type) * nArgs); /* Check for NULL */ --- 513,517 ---- nArgs = PySequence_Size(converters); ! p = PyMem_Malloc(sizeof(ffi_info) + sizeof(ffi_type) * nArgs); /* Check for NULL */ *************** *** 567,571 **** void FreeCallback(THUNK thunk) { ! free(thunk); } --- 567,571 ---- void FreeCallback(THUNK thunk) { ! PyMem_Free(thunk); } |
From: Thomas H. <th...@us...> - 2004-05-11 19:30:31
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17904 Modified Files: ctypes.h Log Message: Add some comments. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** ctypes.h 11 May 2004 19:22:19 -0000 1.41 --- ctypes.h 11 May 2004 19:30:19 -0000 1.42 *************** *** 37,40 **** --- 37,41 ---- typedef struct { + /* First part identical to tagCDataObject */ PyObject_HEAD char *b_ptr; /* pointer to memory block */ *************** *** 47,50 **** --- 48,52 ---- PyObject *b_objects; /* list of references we need to keep */ + /* end of tagCDataObject, additional fields follow */ THUNK thunk; *************** *** 128,131 **** --- 130,134 ---- typedef PyObject *(* SETFUNC)(void *, PyObject *value, unsigned size); + /* a table entry describing a predefined ctypes type */ struct fielddesc { char code; *************** *** 146,149 **** --- 149,154 ---- } CFieldObject; + /* A subclass of PyDictObject, used as the instance dictionary of ctypes + metatypes */ typedef struct { PyDictObject dict; /* a subclass of dict */ |
From: Thomas H. <th...@us...> - 2004-05-11 19:22:28
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16003 Modified Files: ctypes.h Log Message: Remove unneeded (so far) field. Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** ctypes.h 7 May 2004 19:56:24 -0000 1.40 --- ctypes.h 11 May 2004 19:22:19 -0000 1.41 *************** *** 154,158 **** SETFUNC setfunc; /* Only for ArrayObject */ GETFUNC getfunc; /* Only for ArrayObject */ - ffi_type *tp; /* Only for Simple */ /* Following fields only used by CFuncPtrType_Type instances */ --- 154,157 ---- |
From: Thomas H. <th...@us...> - 2004-05-07 20:08:48
|
Update of /cvsroot/ctypes/ctypes/build/lib.win32-2.4 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20855 Modified Files: _ctypes_test.pyd _ctypes.pyd Log Message: Recompiled the binaries. Index: _ctypes_test.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.4/_ctypes_test.pyd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvsVlBR3b and /tmp/cvsJIkvD3 differ Index: _ctypes.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.4/_ctypes.pyd,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 Binary files /tmp/cvsB5ChTf and /tmp/cvsYYjXB7 differ |
From: Thomas H. <th...@us...> - 2004-05-07 20:08:18
|
Update of /cvsroot/ctypes/ctypes/build/lib.win32-2.3 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv20820 Modified Files: _ctypes_test.pyd _ctypes.pyd Log Message: Recompiled the binaries. Index: _ctypes_test.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.3/_ctypes_test.pyd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvs5d1kdf and /tmp/cvs3KL9lN differ Index: _ctypes.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.3/_ctypes.pyd,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 Binary files /tmp/cvsE74Vhm and /tmp/cvsDRKEvU differ |
From: Thomas H. <th...@us...> - 2004-05-07 20:04:10
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19963 Modified Files: setup.py Log Message: Fix the indentation of a code block - the logic was wrong. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** setup.py 7 May 2004 19:56:13 -0000 1.42 --- setup.py 7 May 2004 20:04:00 -0000 1.43 *************** *** 40,43 **** --- 40,57 ---- ## "source/libffi_msvc/win32.c", ]) + extensions = [Extension("_ctypes", + define_macros=[("CAN_PASS_BY_VALUE", "1")], + export_symbols=["DllGetClassObject,PRIVATE", + "DllCanUnloadNow,PRIVATE", + "CopyComPointer"], + libraries=["ole32", "user32", "oleaut32"], + include_dirs=["source/libffi_msvc"], + **kw), + Extension("_ctypes_test", + libraries=["oleaut32"], + sources=["source/_ctypes_test.c"], + include_dirs=["source/libffi_msvc"], + ) + ] if kw.has_key("depends"): kw["depends"].extend(["source/libffi_msvc/ffi.h", *************** *** 45,62 **** "source/libffi_msvc/ffitarget.h", "source/libffi_msvc/ffi_common.h"]) - extensions = [Extension("_ctypes", - define_macros=[("CAN_PASS_BY_VALUE", "1")], - export_symbols=["DllGetClassObject,PRIVATE", - "DllCanUnloadNow,PRIVATE", - "CopyComPointer"], - libraries=["ole32", "user32", "oleaut32"], - include_dirs=["source/libffi_msvc"], - **kw), - Extension("_ctypes_test", - libraries=["oleaut32"], - sources=["source/_ctypes_test.c"], - include_dirs=["source/libffi_msvc"], - ) - ] else: include_dirs = [] --- 59,62 ---- |
From: Thomas H. <th...@us...> - 2004-05-07 19:56:36
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18289 Modified Files: stgdict.c ctypes.h cfield.c callproc.c callbacks.c _ctypes_test.c _ctypes.c Log Message: First step of libffi integration: Hack the libffi sources so that they can be compiled with MSVC, and use ffi_type in the struct fielddesc table instead of the size and align members. Index: stgdict.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/stgdict.c,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** stgdict.c 20 Apr 2004 20:14:30 -0000 1.9 --- stgdict.c 7 May 2004 19:56:24 -0000 1.10 *************** *** 1,3 **** --- 1,4 ---- #include "Python.h" + #include <ffi.h> #include "ctypes.h" Index: _ctypes.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes.c,v retrieving revision 1.137 retrieving revision 1.138 diff -C2 -d -r1.137 -r1.138 *** _ctypes.c 20 Apr 2004 20:14:57 -0000 1.137 --- _ctypes.c 7 May 2004 19:56:24 -0000 1.138 *************** *** 82,85 **** --- 82,87 ---- #include "Python.h" #include "structmember.h" + + #include <ffi.h> #include "ctypes.h" *************** *** 459,463 **** return NULL; stgdict->size = sizeof(void *); ! stgdict->align = getentry("P")->align; stgdict->length = 2; --- 461,465 ---- return NULL; stgdict->size = sizeof(void *); ! stgdict->align = getentry("P")->tp->alignment; stgdict->length = 2; *************** *** 1155,1161 **** fmt = getentry(PyString_AS_STRING(proto)); ! stgdict->align = fmt->align; stgdict->length = 1; ! stgdict->size = fmt->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; --- 1157,1163 ---- fmt = getentry(PyString_AS_STRING(proto)); ! stgdict->align = fmt->tp->alignment; stgdict->length = 1; ! stgdict->size = fmt->tp->size; stgdict->setfunc = fmt->setfunc; stgdict->getfunc = fmt->getfunc; *************** *** 1392,1396 **** PyObject *converters = NULL; ! stgdict->align = getentry("P")->align; stgdict->length = 1; stgdict->size = sizeof(void *); --- 1394,1398 ---- PyObject *converters = NULL; ! stgdict->align = getentry("P")->tp->alignment; stgdict->length = 1; stgdict->size = sizeof(void *); Index: ctypes.h =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/ctypes.h,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** ctypes.h 20 Apr 2004 20:14:41 -0000 1.39 --- ctypes.h 7 May 2004 19:56:24 -0000 1.40 *************** *** 129,137 **** struct fielddesc { ! char code; ! int size; ! int align; ! SETFUNC setfunc; ! GETFUNC getfunc; }; --- 129,136 ---- struct fielddesc { ! char code; ! SETFUNC setfunc; ! GETFUNC getfunc; ! ffi_type *tp; /* always statically allocated */ }; *************** *** 155,158 **** --- 154,158 ---- SETFUNC setfunc; /* Only for ArrayObject */ GETFUNC getfunc; /* Only for ArrayObject */ + ffi_type *tp; /* Only for Simple */ /* Following fields only used by CFuncPtrType_Type instances */ Index: callbacks.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callbacks.c,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** callbacks.c 7 May 2004 16:45:50 -0000 1.38 --- callbacks.c 7 May 2004 19:56:24 -0000 1.39 *************** *** 1,12 **** #include "Python.h" #include "ctypes.h" #ifdef MS_WIN32 #include <windows.h> ! #else ! #include <ffi.h> ! # ifndef __stdcall ! # define __stdcall /* */ ! # endif #endif --- 1,9 ---- #include "Python.h" + #include <ffi.h> #include "ctypes.h" #ifdef MS_WIN32 #include <windows.h> ! #define alloca _alloca #endif Index: callproc.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/callproc.c,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** callproc.c 7 May 2004 16:45:44 -0000 1.64 --- callproc.c 7 May 2004 19:56:24 -0000 1.65 *************** *** 72,78 **** #else #include <dlfcn.h> - #include <ffi.h> #endif #include "ctypes.h" --- 72,78 ---- #else #include <dlfcn.h> #endif + #include <ffi.h> #include "ctypes.h" Index: cfield.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/cfield.c,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** cfield.c 20 Apr 2004 20:14:42 -0000 1.29 --- cfield.c 7 May 2004 19:56:24 -0000 1.30 *************** *** 2,5 **** --- 2,6 ---- #include "structmember.h" + #include <ffi.h> #include "ctypes.h" #ifdef MS_WIN32 *************** *** 930,933 **** --- 931,987 ---- } + static struct fielddesc formattable[] = { + { 's', s_set, s_get, &ffi_type_pointer}, + #if 1 + /* XXX This one seems unused */ + /* See comment above S_get() */ + { 'S', S_set, S_get, &ffi_type_schar}, + #endif + { 'b', b_set, b_get, &ffi_type_schar}, + { 'B', B_set, B_get, &ffi_type_uchar}, + { 'c', c_set, c_get, &ffi_type_schar}, + { 'd', d_set, d_get, &ffi_type_double}, + { 'f', f_set, f_get, &ffi_type_float}, + { 'h', h_set, h_get, &ffi_type_sshort}, + { 'H', H_set, H_get, &ffi_type_ushort}, + { 'i', i_set, i_get, &ffi_type_sint}, + { 'I', I_set, I_get, &ffi_type_uint}, + /* XXX Hm, sizeof(int) == sizeof(long) doesn't hold on every platform */ + /* As soon as we can get rid of the type codes, this is no longer a problem */ + { 'l', l_set, l_get, &ffi_type_sint}, + { 'L', L_set, L_get, &ffi_type_uint}, + #ifdef HAVE_LONG_LONG + { 'q', q_set, q_get, &ffi_type_slong}, + { 'Q', Q_set, Q_get, &ffi_type_ulong}, + #endif + { 'P', P_set, P_get, &ffi_type_pointer}, + { 'z', z_set, z_get, &ffi_type_pointer}, + #ifdef HAVE_USABLE_WCHAR_T + /* Correct or not? */ + { 'u', u_set, u_get, &ffi_type_sshort}, + { 'U', U_set, U_get, &ffi_type_pointer}, + { 'Z', Z_set, Z_get, &ffi_type_pointer}, + #endif + #ifdef MS_WIN32 + { 'X', BSTR_set, BSTR_get, &ffi_type_pointer}, + #endif + { 0, NULL, NULL, NULL}, + }; + + struct fielddesc * + getentry(char *fmt) + { + struct fielddesc *table = formattable; + + for (; table->code; ++table) { + if (table->code == fmt[0]) + return table; + } + return NULL; + } + + /* The following stuff replaces libffi's types.c file, the idea is stolen from + Python's structmodule.c */ + typedef struct { char c; char x; } s_char; typedef struct { char c; short x; } s_short; *************** *** 961,1008 **** #endif ! static struct fielddesc formattable[] = { ! { 's', sizeof(char), CHAR_ALIGN, s_set, s_get}, ! #if 1 ! /* See comment above S_get() */ ! { 'S', sizeof(char), CHAR_ALIGN, S_set, S_get}, ! #endif ! { 'B', sizeof(char), CHAR_ALIGN, B_set, B_get}, ! { 'b', sizeof(char), CHAR_ALIGN, b_set, b_get}, ! { 'c', sizeof(char), CHAR_ALIGN, c_set, c_get}, ! { 'd', sizeof(double), DOUBLE_ALIGN, d_set, d_get}, ! { 'f', sizeof(float), FLOAT_ALIGN, f_set, f_get}, ! { 'h', sizeof(short), SHORT_ALIGN, h_set, h_get}, ! { 'H', sizeof(short), SHORT_ALIGN, H_set, H_get}, ! { 'i', sizeof(int), INT_ALIGN, i_set, i_get}, ! { 'I', sizeof(int), INT_ALIGN, I_set, I_get}, ! { 'l', sizeof(long), LONG_ALIGN, l_set, l_get}, ! { 'L', sizeof(long), LONG_ALIGN, L_set, L_get}, ! #ifdef HAVE_LONG_LONG ! { 'q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, q_set, q_get}, ! { 'Q', sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, Q_set, Q_get}, ! #endif ! { 'P', sizeof(void *), VOID_P_ALIGN, P_set, P_get}, ! { 'z', sizeof(char *), CHAR_P_ALIGN, z_set, z_get}, ! #ifdef HAVE_USABLE_WCHAR_T ! { 'u', sizeof(wchar_t), WCHAR_ALIGN, u_set, u_get}, ! { 'U', sizeof(char), WCHAR_ALIGN, U_set, U_get}, ! { 'Z', sizeof(wchar_t *), WCHAR_P_ALIGN, Z_set, Z_get}, ! #endif ! #ifdef MS_WIN32 ! { 'X', sizeof(wchar_t *), WCHAR_P_ALIGN, BSTR_set, BSTR_get}, ! #endif ! { 0, 0, 0, NULL, NULL}, ! }; ! struct fielddesc * ! getentry(char *fmt) ! { ! struct fielddesc *table = formattable; ! for (; table->code; ++table) { ! if (table->code == fmt[0]) ! return table; ! } ! return NULL; ! } --- 1015,1035 ---- #endif + /* XXX We should make sure that the bit numbers of the types are really correct! */ ! ffi_type ffi_type_uint64 = {sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, FFI_TYPE_UINT64, NULL}; ! ffi_type ffi_type_sint64 = {sizeof(PY_LONG_LONG), LONG_LONG_ALIGN, FFI_TYPE_SINT64, NULL}; ! ffi_type ffi_type_uint32 = {sizeof(int), INT_ALIGN, FFI_TYPE_UINT32, NULL}; ! ffi_type ffi_type_sint32 = {sizeof(int), INT_ALIGN, FFI_TYPE_SINT32, NULL}; ! ffi_type ffi_type_uint16 = {sizeof(short), SHORT_ALIGN, FFI_TYPE_UINT16, NULL}; ! ffi_type ffi_type_sint16 = {sizeof(short), SHORT_ALIGN, FFI_TYPE_SINT16, NULL}; ! ffi_type ffi_type_uint8 = {sizeof(char), CHAR_ALIGN, FFI_TYPE_UINT8, NULL}; ! ffi_type ffi_type_sint8 = {sizeof(char), CHAR_ALIGN, FFI_TYPE_SINT8, NULL}; ! ffi_type ffi_type_float = {sizeof(float), FLOAT_ALIGN, FFI_TYPE_FLOAT, NULL}; ! ffi_type ffi_type_double = {sizeof(double), DOUBLE_ALIGN, FFI_TYPE_DOUBLE, NULL}; ! ffi_type ffi_type_pointer = {sizeof(void*), VOID_P_ALIGN, FFI_TYPE_POINTER, NULL}; ! /* Size and alignment are fake here. They must not be 0. */ ! ffi_type ffi_type_void = {1, 1, FFI_TYPE_VOID, NULL}; ! /* ffi_type_longdouble is missing */ ! /*---------------- EOF ----------------*/ Index: _ctypes_test.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/_ctypes_test.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** _ctypes_test.c 20 Apr 2004 20:14:57 -0000 1.13 --- _ctypes_test.c 7 May 2004 19:56:24 -0000 1.14 *************** *** 1,3 **** --- 1,4 ---- #include <Python.h> + #include <ffi.h> #include "ctypes.h" |
From: Thomas H. <th...@us...> - 2004-05-07 19:56:23
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv18232 Modified Files: setup.py Log Message: First step of libffi integration: Hack the libffi sources so that they can be compiled with MSVC, and use ffi_type in the struct fielddesc table instead of the size and align members. Index: setup.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/setup.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** setup.py 4 May 2004 09:15:09 -0000 1.41 --- setup.py 7 May 2004 19:56:13 -0000 1.42 *************** *** 34,50 **** if os.name == "nt": ! extensions = [Extension("_ctypes", ! define_macros=[("CAN_PASS_BY_VALUE", "1")], ! export_symbols=["DllGetClassObject,PRIVATE", ! "DllCanUnloadNow,PRIVATE", ! "CopyComPointer"], ! libraries=["ole32", "user32", "oleaut32"], ! **kw), ! Extension("_ctypes_test", ! libraries=["oleaut32"], ! sources=["source/_ctypes_test.c"]) ! ] else: include_dirs = [] extra_link_args = [] if sys.platform == "darwin": --- 34,68 ---- if os.name == "nt": ! kw["sources"].extend([ ! ## "source/libffi_msvc/types.c", ! ## "source/libffi_msvc/ffi.c", ! ## "source/libffi_msvc/prep_cif.c", ! ## "source/libffi_msvc/win32.c", ! ]) ! if kw.has_key("depends"): ! kw["depends"].extend(["source/libffi_msvc/ffi.h", ! "source/libffi_msvc/fficonfig.h", ! "source/libffi_msvc/ffitarget.h", ! "source/libffi_msvc/ffi_common.h"]) ! extensions = [Extension("_ctypes", ! define_macros=[("CAN_PASS_BY_VALUE", "1")], ! export_symbols=["DllGetClassObject,PRIVATE", ! "DllCanUnloadNow,PRIVATE", ! "CopyComPointer"], ! libraries=["ole32", "user32", "oleaut32"], ! include_dirs=["source/libffi_msvc"], ! **kw), ! Extension("_ctypes_test", ! libraries=["oleaut32"], ! sources=["source/_ctypes_test.c"], ! include_dirs=["source/libffi_msvc"], ! ) ! ] else: include_dirs = [] + library_dirs = [] + if os.path.exists('source/libffi'): + include_dirs.append('source/libffi/include') + library_dirs.append('source/libffi/lib') extra_link_args = [] if sys.platform == "darwin": *************** *** 55,62 **** libraries=["ffi"], include_dirs=include_dirs, extra_link_args=extra_link_args, **kw), Extension("_ctypes_test", ! sources=["source/_ctypes_test.c"]) ] --- 73,83 ---- libraries=["ffi"], include_dirs=include_dirs, + library_dirs=library_dirs, extra_link_args=extra_link_args, **kw), Extension("_ctypes_test", ! sources=["source/_ctypes_test.c"], ! include_dirs=include_dirs, ! ) ] |
From: Thomas H. <th...@us...> - 2004-05-07 19:54:12
|
Update of /cvsroot/ctypes/ctypes/source/libffi_msvc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17779 Added Files: win32.c Log Message: Added hacked libffi sources. --- NEW FILE: win32.c --- /* ----------------------------------------------------------------------- win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. Copyright (c) 2001 John Beniton Copyright (c) 2002 Ranjit Mathew X86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ /* theller: almost verbatim translation from gas syntax to MSVC inline assembler code. */ /* theller: ffi_call_SYSV and ffi_call_STDCALL now return an integer - the difference of the stack pointer before and after the function call. If everything is ok, zero is returned. If stdcall functions are passed the wrong number of arguments, the difference will be nonzero. */ #include <ffi.h> #include <ffi_common.h> __declspec(naked) int ffi_call_SYSV(void (* prepfunc)(char *, extended_cif *), /* 8 */ extended_cif *ecif, /* 12 */ unsigned bytes, /* 16 */ unsigned flags, /* 20 */ unsigned *rvalue, /* 24 */ void (*fn)()) /* 28 */ { _asm { push ebp mov ebp, esp push esi // NEW: this register must be preserved across function calls // XXX SAVE ESP NOW! mov esi, esp // Make room for all of the new args. mov ecx, [ebp+16] sub esp, ecx mov eax, esp // Place all of the ffi_prep_args in position push [ebp + 12] // ecif push eax call [ebp + 8] // prepfunc // Return stack to previous state and call the function add esp, 8 // FIXME: Align the stack to a 128-bit boundary to avoid // potential performance hits. call [ebp + 28] // Remove the space we pushed for the args mov ecx, [ebp + 16] add esp, ecx // XXX ASSERT THAT ESP IS THE SAME NOW THAN BEFORE! sub esi, esp // Load %ecx with the return type code mov ecx, [ebp + 20] // If the return value pointer is NULL, assume no return value. cmp [ebp + 24], 0 jne sc_retint // Even if there is no space for the return value, we are // obliged to handle floating-point values. cmp ecx, FFI_TYPE_FLOAT jne sc_noretval // fstp %st(0) fstp st(0) jmp sc_epilogue sc_retint: cmp ecx, FFI_TYPE_INT jne sc_retfloat // # Load %ecx with the pointer to storage for the return value mov ecx, [ebp + 24] mov [ecx + 0], eax jmp sc_epilogue sc_retfloat: cmp ecx, FFI_TYPE_FLOAT jne sc_retdouble // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstps (%ecx) fstp DWORD PTR [ecx] jmp sc_epilogue sc_retdouble: cmp ecx, FFI_TYPE_DOUBLE jne sc_retlongdouble // movl 24(%ebp),%ecx mov ecx, [ebp+24] fstp QWORD PTR [ecx] jmp sc_epilogue jmp sc_retlongdouble // avoid warning about unused label sc_retlongdouble: cmp ecx, FFI_TYPE_LONGDOUBLE jne sc_retint64 // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstpt (%ecx) fstp QWORD PTR [ecx] /* XXX ??? */ jmp sc_epilogue sc_retint64: cmp ecx, FFI_TYPE_SINT64 jne sc_retstruct // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] mov [ecx+0], eax mov [ecx+4], edx sc_retstruct: // Nothing to do! sc_noretval: sc_epilogue: mov eax, esi pop esi // NEW restore: must be preserved across function calls mov esp, ebp pop ebp ret } } __declspec(naked) int ffi_call_STDCALL(void (* prepfunc)(char *, extended_cif *), /* 8 */ extended_cif *ecif, /* 12 */ unsigned bytes, /* 16 */ unsigned flags, /* 20 */ unsigned *rvalue, /* 24 */ void (*fn)()) /* 28 */ { _asm { push ebp mov ebp, esp push esi // NEW: this register must be preserved across function calls // XXX SAVE ESP NOW! mov esi, esp // Make room for all of the new args. mov ecx, [ebp+16] sub esp, ecx mov eax, esp // Place all of the ffi_prep_args in position push [ebp + 12] // ecif push eax call [ebp + 8] // prepfunc // Return stack to previous state and call the function add esp, 8 // FIXME: Align the stack to a 128-bit boundary to avoid // potential performance hits. call [ebp + 28] // stdcall functions pop arguments off the stack themselves // XXX IS ESP NOW THE SAME AS BEFORE? sub esi, esp // Load %ecx with the return type code mov ecx, [ebp + 20] // If the return value pointer is NULL, assume no return value. cmp [ebp + 24], 0 jne sc_retint // Even if there is no space for the return value, we are // obliged to handle floating-point values. cmp ecx, FFI_TYPE_FLOAT jne sc_noretval // fstp %st(0) fstp st(0) jmp sc_epilogue sc_retint: cmp ecx, FFI_TYPE_INT jne sc_retfloat // # Load %ecx with the pointer to storage for the return value mov ecx, [ebp + 24] mov [ecx + 0], eax jmp sc_epilogue sc_retfloat: cmp ecx, FFI_TYPE_FLOAT jne sc_retdouble // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstps (%ecx) fstp DWORD PTR [ecx] jmp sc_epilogue sc_retdouble: cmp ecx, FFI_TYPE_DOUBLE jne sc_retdouble // movl 24(%ebp),%ecx mov ecx, [ebp+24] fstp QWORD PTR [ecx] jmp sc_epilogue jmp sc_retlongdouble // avoid warning about unused label sc_retlongdouble: cmp ecx, FFI_TYPE_LONGDOUBLE jne sc_retint64 // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] // fstpt (%ecx) fstp QWORD PTR [ecx] /* XXX ??? */ jmp sc_epilogue sc_retint64: cmp ecx, FFI_TYPE_SINT64 jne sc_retstruct // Load %ecx with the pointer to storage for the return value mov ecx, [ebp+24] mov [ecx+0], eax mov [ecx+4], edx sc_retstruct: // Nothing to do! sc_noretval: sc_epilogue: mov eax, esi pop esi // NEW restore: must be preserved across function calls mov esp, ebp pop ebp ret } } |
Update of /cvsroot/ctypes/ctypes/source/libffi_msvc In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17540 Added Files: win32.S types.c prep_cif.c ffitarget.h fficonfig.h ffi_common.h ffi.h ffi.c README.ctypes README LICENSE Log Message: Added hacked libffi sources. --- NEW FILE: ffi_common.h --- /* ----------------------------------------------------------------------- ffi_common.h - Copyright (c) 1996 Red Hat, Inc. Common internal definitions and macros. Only necessary for building libffi. ----------------------------------------------------------------------- */ #ifndef FFI_COMMON_H #define FFI_COMMON_H #ifdef __cplusplus extern "C" { #endif #include <fficonfig.h> /* Do not move this. Some versions of AIX are very picky about where this is positioned. */ #ifdef __GNUC__ # define alloca __builtin_alloca #else # if HAVE_ALLOCA_H # include <alloca.h> # else # ifdef _AIX #pragma alloca # else # ifndef alloca /* predefined by HP cc +Olibcalls */ char *alloca (); # endif # endif # endif #endif /* Check for the existence of memcpy. */ #if STDC_HEADERS # include <string.h> #else # ifndef HAVE_MEMCPY # define memcpy(d, s, n) bcopy ((s), (d), (n)) # endif #endif #if defined(FFI_DEBUG) #include <stdio.h> #endif #ifdef FFI_DEBUG /*@exits@*/ void ffi_assert(/*@temp@*/ char *expr, /*@temp@*/ char *file, int line); void ffi_stop_here(void); void ffi_type_test(/*@temp@*/ /*@out@*/ ffi_type *a, /*@temp@*/ char *file, int line); #define FFI_ASSERT(x) ((x) ? (void)0 : ffi_assert(#x, __FILE__,__LINE__)) #define FFI_ASSERT_AT(x, f, l) ((x) ? 0 : ffi_assert(#x, (f), (l))) #define FFI_ASSERT_VALID_TYPE(x) ffi_type_test (x, __FILE__, __LINE__) #else #define FFI_ASSERT(x) #define FFI_ASSERT_AT(x, f, l) #define FFI_ASSERT_VALID_TYPE(x) #endif #define ALIGN(v, a) (((((size_t) (v))-1) | ((a)-1))+1) /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif); /* Extended cif, used in callback from assembly routine */ typedef struct { /*@dependent@*/ ffi_cif *cif; /*@dependent@*/ void *rvalue; /*@dependent@*/ void **avalue; } extended_cif; /* Terse sized type definitions. */ typedef unsigned int UINT8 __attribute__((__mode__(__QI__))); typedef signed int SINT8 __attribute__((__mode__(__QI__))); typedef unsigned int UINT16 __attribute__((__mode__(__HI__))); typedef signed int SINT16 __attribute__((__mode__(__HI__))); typedef unsigned int UINT32 __attribute__((__mode__(__SI__))); typedef signed int SINT32 __attribute__((__mode__(__SI__))); typedef unsigned int UINT64 __attribute__((__mode__(__DI__))); typedef signed int SINT64 __attribute__((__mode__(__DI__))); typedef float FLOAT32; #ifdef __cplusplus } #endif #endif --- NEW FILE: README.ctypes --- The purpose is to hack the libffi sources so that they can be compiled with MSVC, and to extend them so that they have the features I need for ctypes. I retrieved the libffi sources from the gcc cvs repository on 2004-01-27. Then I did 'configure' in a 'build' subdirectory on a x86 linux system, and copied the files I found useful. --- NEW FILE: LICENSE --- libffi - Copyright (c) 1996-2003 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. --- NEW FILE: win32.S --- /* ----------------------------------------------------------------------- win32.S - Copyright (c) 1996, 1998, 2001, 2002 Red Hat, Inc. Copyright (c) 2001 John Beniton Copyright (c) 2002 Ranjit Mathew X86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #define LIBFFI_ASM #include <fficonfig.h> #include <ffi.h> .text .globl ffi_prep_args # This assumes we are using gas. .balign 16 .globl _ffi_call_SYSV _ffi_call_SYSV: pushl %ebp movl %esp,%ebp # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp movl %esp,%eax # Place all of the ffi_prep_args in position pushl 12(%ebp) pushl %eax call *8(%ebp) # Return stack to previous state and call the function addl $8,%esp # FIXME: Align the stack to a 128-bit boundary to avoid # potential performance hits. call *28(%ebp) # Remove the space we pushed for the args movl 16(%ebp),%ecx addl %ecx,%esp # Load %ecx with the return type code movl 20(%ebp),%ecx # If the return value pointer is NULL, assume no return value. cmpl $0,24(%ebp) jne retint # Even if there is no space for the return value, we are # obliged to handle floating-point values. cmpl $FFI_TYPE_FLOAT,%ecx jne noretval fstp %st(0) jmp epilogue retint: cmpl $FFI_TYPE_INT,%ecx jne retfloat # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) jmp epilogue retfloat: cmpl $FFI_TYPE_FLOAT,%ecx jne retdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstps (%ecx) jmp epilogue retdouble: cmpl $FFI_TYPE_DOUBLE,%ecx jne retlongdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpl (%ecx) jmp epilogue retlongdouble: cmpl $FFI_TYPE_LONGDOUBLE,%ecx jne retint64 # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpt (%ecx) jmp epilogue retint64: cmpl $FFI_TYPE_SINT64,%ecx jne retstruct # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) retstruct: # Nothing to do! noretval: epilogue: movl %ebp,%esp popl %ebp ret .ffi_call_SYSV_end: # This assumes we are using gas. .balign 16 .globl _ffi_call_STDCALL _ffi_call_STDCALL: pushl %ebp movl %esp,%ebp # Make room for all of the new args. movl 16(%ebp),%ecx subl %ecx,%esp movl %esp,%eax # Place all of the ffi_prep_args in position pushl 12(%ebp) pushl %eax call *8(%ebp) # Return stack to previous state and call the function addl $8,%esp # FIXME: Align the stack to a 128-bit boundary to avoid # potential performance hits. call *28(%ebp) # stdcall functions pop arguments off the stack themselves # Load %ecx with the return type code movl 20(%ebp),%ecx # If the return value pointer is NULL, assume no return value. cmpl $0,24(%ebp) jne sc_retint # Even if there is no space for the return value, we are # obliged to handle floating-point values. cmpl $FFI_TYPE_FLOAT,%ecx jne sc_noretval fstp %st(0) jmp sc_epilogue sc_retint: cmpl $FFI_TYPE_INT,%ecx jne sc_retfloat # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) jmp sc_epilogue sc_retfloat: cmpl $FFI_TYPE_FLOAT,%ecx jne sc_retdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstps (%ecx) jmp sc_epilogue sc_retdouble: cmpl $FFI_TYPE_DOUBLE,%ecx jne sc_retlongdouble # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpl (%ecx) jmp sc_epilogue sc_retlongdouble: cmpl $FFI_TYPE_LONGDOUBLE,%ecx jne sc_retint64 # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx fstpt (%ecx) jmp sc_epilogue sc_retint64: cmpl $FFI_TYPE_SINT64,%ecx jne sc_retstruct # Load %ecx with the pointer to storage for the return value movl 24(%ebp),%ecx movl %eax,0(%ecx) movl %edx,4(%ecx) sc_retstruct: # Nothing to do! sc_noretval: sc_epilogue: movl %ebp,%esp popl %ebp ret .ffi_call_STDCALL_end: --- NEW FILE: prep_cif.c --- /* ----------------------------------------------------------------------- prep_cif.c - Copyright (c) 1996, 1998 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> /* Round up to FFI_SIZEOF_ARG. */ #define STACK_ARG_SIZE(x) ALIGN(x, FFI_SIZEOF_ARG) /* Perform machine independent initialization of aggregate type specifications. */ static ffi_status initialize_aggregate(/*@out@*/ ffi_type *arg) { ffi_type **ptr; FFI_ASSERT(arg != NULL); /*@-usedef@*/ FFI_ASSERT(arg->elements != NULL); FFI_ASSERT(arg->size == 0); FFI_ASSERT(arg->alignment == 0); ptr = &(arg->elements[0]); while ((*ptr) != NULL) { if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; /* Perform a sanity check on the argument type */ FFI_ASSERT_VALID_TYPE(*ptr); arg->size = ALIGN(arg->size, (*ptr)->alignment); arg->size += (*ptr)->size; arg->alignment = (arg->alignment > (*ptr)->alignment) ? arg->alignment : (*ptr)->alignment; ptr++; } /* Structure size includes tail padding. This is important for structures that fit in one register on ABIs like the PowerPC64 Linux ABI that right justify small structs in a register. It's also needed for nested structure layout, for example struct A { long a; char b; }; struct B { struct A x; char y; }; should find y at an offset of 2*sizeof(long) and result in a total size of 3*sizeof(long). */ arg->size = ALIGN (arg->size, arg->alignment); if (arg->size == 0) return FFI_BAD_TYPEDEF; else return FFI_OK; /*@=usedef@*/ } /* Perform machine independent ffi_cif preparation, then call machine dependent routine. */ ffi_status ffi_prep_cif(/*@out@*/ /*@partial@*/ ffi_cif *cif, ffi_abi abi, unsigned int nargs, /*@dependent@*/ /*@out@*/ /*@partial@*/ ffi_type *rtype, /*@dependent@*/ ffi_type **atypes) { unsigned bytes = 0; unsigned int i; ffi_type **ptr; FFI_ASSERT(cif != NULL); FFI_ASSERT((abi > FFI_FIRST_ABI) && (abi <= FFI_DEFAULT_ABI)); cif->abi = abi; cif->arg_types = atypes; cif->nargs = nargs; cif->rtype = rtype; cif->flags = 0; /* Initialize the return type if necessary */ /*@-usedef@*/ if ((cif->rtype->size == 0) && (initialize_aggregate(cif->rtype) != FFI_OK)) return FFI_BAD_TYPEDEF; /*@=usedef@*/ /* Perform a sanity check on the return type */ FFI_ASSERT_VALID_TYPE(cif->rtype); /* x86-64 and s390 stack space allocation is handled in prep_machdep. */ #if !defined M68K && !defined __x86_64__ && !defined S390 /* Make space for the return structure pointer */ if (cif->rtype->type == FFI_TYPE_STRUCT #ifdef SPARC && (cif->abi != FFI_V9 || cif->rtype->size > 32) #endif ) bytes = STACK_ARG_SIZE(sizeof(void*)); #endif for (ptr = cif->arg_types, i = cif->nargs; i > 0; i--, ptr++) { /* Initialize any uninitialized aggregate type definitions */ if (((*ptr)->size == 0) && (initialize_aggregate((*ptr)) != FFI_OK)) return FFI_BAD_TYPEDEF; /* Perform a sanity check on the argument type, do this check after the initialization. */ FFI_ASSERT_VALID_TYPE(*ptr); #if !defined __x86_64__ && !defined S390 #ifdef SPARC if (((*ptr)->type == FFI_TYPE_STRUCT && ((*ptr)->size > 16 || cif->abi != FFI_V9)) || ((*ptr)->type == FFI_TYPE_LONGDOUBLE && cif->abi != FFI_V9)) bytes += sizeof(void*); else #endif { /* Add any padding if necessary */ if (((*ptr)->alignment - 1) & bytes) bytes = ALIGN(bytes, (*ptr)->alignment); bytes += STACK_ARG_SIZE((*ptr)->size); } #endif } cif->bytes = bytes; /* Perform machine dependent cif processing */ return ffi_prep_cif_machdep(cif); } --- NEW FILE: fficonfig.h --- /* fficonfig.h. Originally created by configure, now hand_maintained for MSVC. */ /* fficonfig.h. Generated automatically by configure. */ /* fficonfig.h.in. Generated automatically from configure.in by autoheader. */ /* Defines for MSVC */ #define __attribute__(x) /* */ #define alloca _alloca /*----------------------------------------------------------------*/ /* Define if using alloca.c. */ /* #undef C_ALLOCA */ /* Define to one of _getb67, GETB67, getb67 for Cray-2 and Cray-YMP systems. This function is required for alloca.c support on those systems. */ /* #undef CRAY_STACKSEG_END */ /* Define if you have alloca, as a function or macro. */ #define HAVE_ALLOCA 1 /* Define if you have <alloca.h> and it should be used (not on Ultrix). */ /* #define HAVE_ALLOCA_H 1 */ /* If using the C implementation of alloca, define if you know the direction of stack growth for your system; otherwise it will be automatically deduced at run-time. STACK_DIRECTION > 0 => grows toward higher addresses STACK_DIRECTION < 0 => grows toward lower addresses STACK_DIRECTION = 0 => direction of growth unknown */ /* #undef STACK_DIRECTION */ /* Define if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Define if you have the memcpy function. */ #define HAVE_MEMCPY 1 /* Define if read-only mmap of a plain file works. */ //#define HAVE_MMAP_FILE 1 /* Define if mmap of /dev/zero works. */ //#define HAVE_MMAP_DEV_ZERO 1 /* Define if mmap with MAP_ANON(YMOUS) works. */ //#define HAVE_MMAP_ANON 1 /* The number of bytes in type double */ #define SIZEOF_DOUBLE 8 /* The number of bytes in type long double */ #define SIZEOF_LONG_DOUBLE 12 /* Define if you have the long double type and it is bigger than a double */ #define HAVE_LONG_DOUBLE 1 /* whether byteorder is bigendian */ /* #undef WORDS_BIGENDIAN */ /* Define if the host machine stores words of multi-word integers in big-endian order. */ /* #undef HOST_WORDS_BIG_ENDIAN */ /* 1234 = LIL_ENDIAN, 4321 = BIGENDIAN */ #define BYTEORDER 1234 /* Define if your assembler and linker support unaligned PC relative relocs. */ /* #undef HAVE_AS_SPARC_UA_PCREL */ /* Define if your assembler supports .register. */ /* #undef HAVE_AS_REGISTER_PSEUDO_OP */ /* Define if .eh_frame sections should be read-only. */ /* #undef HAVE_RO_EH_FRAME */ /* Define to the flags needed for the .section .eh_frame directive. */ /* #define EH_FRAME_FLAGS "aw" */ /* Define to the flags needed for the .section .eh_frame directive. */ /* #define EH_FRAME_FLAGS "aw" */ /* Define this if you want extra debugging. */ /* #undef FFI_DEBUG */ /* Define this is you do not want support for aggregate types. */ /* #undef FFI_NO_STRUCTS */ /* Define this is you do not want support for the raw API. */ /* #undef FFI_NO_RAW_API */ /* Define this if you are using Purify and want to suppress spurious messages. */ /* #undef USING_PURIFY */ --- NEW FILE: ffitarget.h --- /* -----------------------------------------------------------------*-C-*- ffitarget.h - Copyright (c) 1996-2003 Red Hat, Inc. Target configuration macros for x86 and x86-64. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef LIBFFI_TARGET_H #define LIBFFI_TARGET_H /* ---- System specific configurations ----------------------------------- */ #if defined (X86_64) && defined (__i386__) #undef X86_64 #define X86 #endif /* ---- Generic type definitions ----------------------------------------- */ #ifndef LIBFFI_ASM typedef unsigned long ffi_arg; typedef signed long ffi_sarg; typedef enum ffi_abi { FFI_FIRST_ABI = 0, /* ---- Intel x86 Win32 ---------- */ #if defined(X86_WIN32) || defined(_MSC_VER) FFI_SYSV, FFI_STDCALL, /* TODO: Add fastcall support for the sake of completeness */ FFI_DEFAULT_ABI = FFI_SYSV, #endif /* ---- Intel x86 and AMD x86-64 - */ #if !defined(X86_WIN32) && (defined(__i386__) || defined(__x86_64__)) FFI_SYSV, FFI_UNIX64, /* Unix variants all use the same ABI for x86-64 */ #ifdef __i386__ FFI_DEFAULT_ABI = FFI_SYSV, #else FFI_DEFAULT_ABI = FFI_UNIX64, #endif #endif FFI_LAST_ABI = FFI_DEFAULT_ABI + 1 } ffi_abi; #endif /* ---- Definitions for closures ----------------------------------------- */ #define FFI_CLOSURES 1 #ifdef X86_64 #define FFI_TRAMPOLINE_SIZE 24 #define FFI_NATIVE_RAW_API 0 #else #ifdef _MSC_VER # define FFI_TRAMPOLINE_SIZE 15 #else # define FFI_TRAMPOLINE_SIZE 10 #endif #define FFI_NATIVE_RAW_API 1 /* x86 has native raw api support */ #endif #endif --- NEW FILE: ffi.c --- /* ----------------------------------------------------------------------- ffi.c - Copyright (c) 1996, 1998, 1999, 2001 Red Hat, Inc. Copyright (c) 2002 Ranjit Mathew Copyright (c) 2002 Bo Thorsen Copyright (c) 2002 Roger Sayle x86 Foreign Function Interface Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #ifndef __x86_64__ #include <ffi.h> #include <ffi_common.h> #include <stdlib.h> /* ffi_prep_args is called by the assembly routine once stack space has been allocated for the function's arguments */ /*@-exportheader@*/ void ffi_prep_args(char *stack, extended_cif *ecif) /*@=exportheader@*/ { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; argp = stack; if (ecif->cif->rtype->type == FFI_TYPE_STRUCT) { *(void **) argp = ecif->rvalue; argp += 4; } p_argv = ecif->avalue; for (i = ecif->cif->nargs, p_arg = ecif->cif->arg_types; i != 0; i--, p_arg++) { size_t z; /* Align if necessary */ if ((sizeof(int) - 1) & (unsigned) argp) argp = (char *) ALIGN(argp, sizeof(int)); z = (*p_arg)->size; if (z < sizeof(int)) { z = sizeof(int); switch ((*p_arg)->type) { case FFI_TYPE_SINT8: *(signed int *) argp = (signed int)*(SINT8 *)(* p_argv); break; case FFI_TYPE_UINT8: *(unsigned int *) argp = (unsigned int)*(UINT8 *)(* p_argv); break; case FFI_TYPE_SINT16: *(signed int *) argp = (signed int)*(SINT16 *)(* p_argv); break; case FFI_TYPE_UINT16: *(unsigned int *) argp = (unsigned int)*(UINT16 *)(* p_argv); break; case FFI_TYPE_SINT32: *(signed int *) argp = (signed int)*(SINT32 *)(* p_argv); break; case FFI_TYPE_UINT32: *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); break; case FFI_TYPE_STRUCT: *(unsigned int *) argp = (unsigned int)*(UINT32 *)(* p_argv); break; default: FFI_ASSERT(0); } } else { memcpy(argp, *p_argv, z); } p_argv++; argp += z; } return; } /* Perform machine dependent cif processing */ ffi_status ffi_prep_cif_machdep(ffi_cif *cif) { /* Set the return type flag */ switch (cif->rtype->type) { case FFI_TYPE_VOID: case FFI_TYPE_STRUCT: case FFI_TYPE_SINT64: case FFI_TYPE_FLOAT: case FFI_TYPE_DOUBLE: case FFI_TYPE_LONGDOUBLE: cif->flags = (unsigned) cif->rtype->type; break; case FFI_TYPE_UINT64: cif->flags = FFI_TYPE_SINT64; break; default: cif->flags = FFI_TYPE_INT; break; } return FFI_OK; } /*@-declundef@*/ /*@-exportheader@*/ #ifdef _MSC_VER extern int #else extern void #endif ffi_call_SYSV(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ #if defined(X86_WIN32) || defined(_MSC_VER) /*@-declundef@*/ /*@-exportheader@*/ #ifdef _MSC_VER extern int #else extern void #endif ffi_call_STDCALL(void (*)(char *, extended_cif *), /*@out@*/ extended_cif *, unsigned, unsigned, /*@out@*/ unsigned *, void (*fn)()); /*@=declundef@*/ /*@=exportheader@*/ #endif /* X86_WIN32 || _MSC_VER*/ #ifdef _MSC_VER int #else void #endif ffi_call(/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, /*@dependent@*/ void **avalue) { extended_cif ecif; ecif.cif = cif; ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; switch (cif->abi) { case FFI_SYSV: /*@-usedef@*/ #ifdef _MSC_VER return #endif ffi_call_SYSV(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #if defined(X86_WIN32) || defined(_MSC_VER) case FFI_STDCALL: /*@-usedef@*/ #ifdef _MSC_VER return #endif ffi_call_STDCALL(ffi_prep_args, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #endif /* X86_WIN32 */ default: FFI_ASSERT(0); break; } return -1; /* theller: Hrm. */ } /** private members **/ static void ffi_prep_incoming_args_SYSV (char *stack, void **ret, void** args, ffi_cif* cif); #ifndef _MSC_VER static void ffi_closure_SYSV (ffi_closure *) __attribute__ ((regparm(1))); static void ffi_closure_raw_SYSV (ffi_raw_closure *) __attribute__ ((regparm(1))); #endif /* This function is jumped to by the trampoline */ #ifdef _MSC_VER static void __fastcall ffi_closure_SYSV (ffi_closure *closure, int *argp) #else static void ffi_closure_SYSV (closure) ffi_closure *closure; #endif { // this is our return value storage long double res; // our various things... ffi_cif *cif; void **arg_area; unsigned short rtype; void *resp = (void*)&res; #ifdef _MSC_VER void *args = &argp[1]; #else void *args = __builtin_dwarf_cfa (); #endif cif = closure->cif; arg_area = (void**) alloca (cif->nargs * sizeof (void*)); /* this call will initialize ARG_AREA, such that each * element in that array points to the corresponding * value on the stack; and if the function returns * a structure, it will re-set RESP to point to the * structure return address. */ ffi_prep_incoming_args_SYSV(args, (void**)&resp, arg_area, cif); (closure->fun) (cif, resp, arg_area, closure->user_data); rtype = cif->flags; #ifdef _MSC_VER /* now, do a generic return based on the value of rtype */ if (rtype == FFI_TYPE_INT) { _asm mov eax, resp ; _asm mov eax, [eax] ; } else if (rtype == FFI_TYPE_FLOAT) { _asm mov eax, resp ; _asm fld DWORD PTR [eax] ; // asm ("flds (%0)" : : "r" (resp) : "st" ); } else if (rtype == FFI_TYPE_DOUBLE) { _asm mov eax, resp ; _asm fld QWORD PTR [eax] ; // asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_LONGDOUBLE) { // asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_SINT64) { _asm mov edx, resp ; _asm mov eax, [edx] ; _asm mov edx, [edx + 4] ; // asm ("movl 0(%0),%%eax;" // "movl 4(%0),%%edx" // : : "r"(resp) // : "eax", "edx"); } #else /* now, do a generic return based on the value of rtype */ if (rtype == FFI_TYPE_INT) { asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); } else if (rtype == FFI_TYPE_FLOAT) { asm ("flds (%0)" : : "r" (resp) : "st" ); } else if (rtype == FFI_TYPE_DOUBLE) { asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_LONGDOUBLE) { asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_SINT64) { asm ("movl 0(%0),%%eax;" "movl 4(%0),%%edx" : : "r"(resp) : "eax", "edx"); } #endif } /*@-exportheader@*/ static void ffi_prep_incoming_args_SYSV(char *stack, void **rvalue, void **avalue, ffi_cif *cif) /*@=exportheader@*/ { register unsigned int i; register void **p_argv; register char *argp; register ffi_type **p_arg; argp = stack; if ( cif->rtype->type == FFI_TYPE_STRUCT ) { *rvalue = *(void **) argp; argp += 4; } p_argv = avalue; for (i = cif->nargs, p_arg = cif->arg_types; (i != 0); i--, p_arg++) { size_t z; /* Align if necessary */ if ((sizeof(int) - 1) & (unsigned) argp) { argp = (char *) ALIGN(argp, sizeof(int)); } z = (*p_arg)->size; /* because we're little endian, this is what it turns into. */ *p_argv = (void*) argp; p_argv++; argp += z; } return; } /* How to make a trampoline. Derived from gcc/config/i386/i386.c. */ /* MOV EDX, ESP is 0x8b 0xd4 */ #ifdef _MSC_VER #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ { unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - ((unsigned int) __tramp + 8 + 4); \ *(unsigned char*) &__tramp[0] = 0xb9; \ *(unsigned int*) &__tramp[1] = __ctx; /* mov ecx, __ctx */ \ *(unsigned char*) &__tramp[5] = 0x8b; \ *(unsigned char*) &__tramp[6] = 0xd4; \ *(unsigned char*) &__tramp[7] = 0xe8; \ *(unsigned int*) &__tramp[8] = __dis; /* call __fun */ \ *(unsigned char*) &__tramp[12] = 0xC2; /* ret BYTES */ \ *(unsigned short*) &__tramp[13] = BYTES; \ } #else #define FFI_INIT_TRAMPOLINE(TRAMP,FUN,CTX,BYTES) \ ({ unsigned char *__tramp = (unsigned char*)(TRAMP); \ unsigned int __fun = (unsigned int)(FUN); \ unsigned int __ctx = (unsigned int)(CTX); \ unsigned int __dis = __fun - ((unsigned int) __tramp + FFI_TRAMPOLINE_SIZE); \ *(unsigned char*) &__tramp[0] = 0xb8; \ *(unsigned int*) &__tramp[1] = __ctx; /* movl __ctx, %eax */ \ *(unsigned char *) &__tramp[5] = 0xe9; \ *(unsigned int*) &__tramp[6] = __dis; /* jmp __fun */ \ }) #endif /* the cif must already be prep'ed */ ffi_status ffi_prep_closure (ffi_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*,void*,void**,void*), void *user_data) { short bytes; FFI_ASSERT (cif->abi == FFI_SYSV); if (cif->abi == FFI_SYSV) bytes = 0; #ifdef _MSC_VER else if (cif->abi == FFI_STDCALL) bytes = cif->bytes; #endif else return FFI_BAD_ABI; FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_SYSV, (void*)closure, bytes); closure->cif = cif; closure->user_data = user_data; closure->fun = fun; return FFI_OK; } /* ------- Native raw API support -------------------------------- */ #if !FFI_NO_RAW_API static void ffi_closure_raw_SYSV (closure) ffi_raw_closure *closure; { // this is our return value storage long double res; // our various things... ffi_raw *raw_args; ffi_cif *cif; unsigned short rtype; void *resp = (void*)&res; /* get the cif */ cif = closure->cif; /* the SYSV/X86 abi matches the RAW API exactly, well.. almost */ #ifndef _MSC_VER raw_args = (ffi_raw*) __builtin_dwarf_cfa (); #endif (closure->fun) (cif, resp, raw_args, closure->user_data); rtype = cif->flags; /* now, do a generic return based on the value of rtype */ #ifndef _MSC_VER if (rtype == FFI_TYPE_INT) { asm ("movl (%0),%%eax" : : "r" (resp) : "eax"); } else if (rtype == FFI_TYPE_FLOAT) { asm ("flds (%0)" : : "r" (resp) : "st" ); } else if (rtype == FFI_TYPE_DOUBLE) { asm ("fldl (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_LONGDOUBLE) { asm ("fldt (%0)" : : "r" (resp) : "st", "st(1)" ); } else if (rtype == FFI_TYPE_SINT64) { asm ("movl 0(%0),%%eax; movl 4(%0),%%edx" : : "r"(resp) : "eax", "edx"); } #endif } ffi_status ffi_prep_raw_closure (ffi_raw_closure* closure, ffi_cif* cif, void (*fun)(ffi_cif*,void*,ffi_raw*,void*), void *user_data) { int i; FFI_ASSERT (cif->abi == FFI_SYSV); // we currently don't support certain kinds of arguments for raw // closures. This should be implemented by a separate assembly language // routine, since it would require argument processing, something we // don't do now for performance. for (i = cif->nargs-1; i >= 0; i--) { FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_STRUCT); FFI_ASSERT (cif->arg_types[i]->type != FFI_TYPE_LONGDOUBLE); } FFI_INIT_TRAMPOLINE (&closure->tramp[0], &ffi_closure_raw_SYSV, (void*)closure, 0); closure->cif = cif; closure->user_data = user_data; closure->fun = fun; return FFI_OK; } static void ffi_prep_args_raw(char *stack, extended_cif *ecif) { memcpy (stack, ecif->avalue, ecif->cif->bytes); } void ffi_raw_call(/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, /*@dependent@*/ ffi_raw *fake_avalue) { extended_cif ecif; void **avalue = (void **)fake_avalue; ecif.cif = cif; ecif.avalue = avalue; /* If the return value is a struct and we don't have a return */ /* value address then we need to make one */ if ((rvalue == NULL) && (cif->rtype->type == FFI_TYPE_STRUCT)) { /*@-sysunrecog@*/ ecif.rvalue = alloca(cif->rtype->size); /*@=sysunrecog@*/ } else ecif.rvalue = rvalue; switch (cif->abi) { case FFI_SYSV: /*@-usedef@*/ ffi_call_SYSV(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #ifdef X86_WIN32 case FFI_STDCALL: /*@-usedef@*/ ffi_call_STDCALL(ffi_prep_args_raw, &ecif, cif->bytes, cif->flags, ecif.rvalue, fn); /*@=usedef@*/ break; #endif /* X86_WIN32 */ default: FFI_ASSERT(0); break; } } #endif #endif /* __x86_64__ */ --- NEW FILE: README --- This directory contains the libffi package, which is not part of GCC but shipped with GCC as convenience. Status ====== libffi-2.00 has not been released yet! This is a development snapshot! libffi-1.20 was released on October 5, 1998. Check the libffi web page for updates: <URL:http://sources.redhat.com/libffi/>. What is libffi? =============== Compilers for high level languages generate code that follow certain conventions. These conventions are necessary, in part, for separate compilation to work. One such convention is the "calling convention". The "calling convention" is essentially a set of assumptions made by the compiler about where function arguments will be found on entry to a function. A "calling convention" also specifies where the return value for a function is found. Some programs may not know at the time of compilation what arguments are to be passed to a function. For instance, an interpreter may be told at run-time about the number and types of arguments used to call a given function. Libffi can be used in such programs to provide a bridge from the interpreter program to compiled code. The libffi library provides a portable, high level programming interface to various calling conventions. This allows a programmer to call any function specified by a call interface description at run time. Ffi stands for Foreign Function Interface. A foreign function interface is the popular name for the interface that allows code written in one language to call code written in another language. The libffi library really only provides the lowest, machine dependent layer of a fully featured foreign function interface. A layer must exist above libffi that handles type conversions for values passed between the two languages. Supported Platforms and Prerequisites ===================================== Libffi has been ported to: SunOS 4.1.3 & Solaris 2.x (SPARC-V8, SPARC-V9) Irix 5.3 & 6.2 (System V/o32 & n32) Intel x86 - Linux (System V ABI) Alpha - Linux and OSF/1 m68k - Linux (System V ABI) PowerPC - Linux (System V ABI, Darwin, AIX) ARM - Linux (System V ABI) Libffi has been tested with the egcs 1.0.2 gcc compiler. Chances are that other versions will work. Libffi has also been built and tested with the SGI compiler tools. On PowerPC, the tests failed (see the note below). You must use GNU make to build libffi. SGI's make will not work. Sun's probably won't either. If you port libffi to another platform, please let me know! I assume that some will be easy (x86 NetBSD), and others will be more difficult (HP). Installing libffi ================= [Note: before actually performing any of these installation steps, you may wish to read the "Platform Specific Notes" below.] First you must configure the distribution for your particular system. Go to the directory you wish to build libffi in and run the "configure" program found in the root directory of the libffi source distribution. You may want to tell configure where to install the libffi library and header files. To do that, use the --prefix configure switch. Libffi will install under /usr/local by default. If you want to enable extra run-time debugging checks use the the --enable-debug configure switch. This is useful when your program dies mysteriously while using libffi. Another useful configure switch is --enable-purify-safety. Using this will add some extra code which will suppress certain warnings when you are using Purify with libffi. Only use this switch when using Purify, as it will slow down the library. Configure has many other options. Use "configure --help" to see them all. Once configure has finished, type "make". Note that you must be using GNU make. SGI's make will not work. Sun's probably won't either. You can ftp GNU make from prep.ai.mit.edu:/pub/gnu. To ensure that libffi is working as advertised, type "make test". To install the library and header files, type "make install". Using libffi ============ The Basics ---------- Libffi assumes that you have a pointer to the function you wish to call and that you know the number and types of arguments to pass it, as well as the return type of the function. The first thing you must do is create an ffi_cif object that matches the signature of the function you wish to call. The cif in ffi_cif stands for Call InterFace. To prepare a call interface object, use the following function: ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi, unsigned int nargs, ffi_type *rtype, ffi_type **atypes); CIF is a pointer to the call interface object you wish to initialize. ABI is an enum that specifies the calling convention to use for the call. FFI_DEFAULT_ABI defaults to the system's native calling convention. Other ABI's may be used with care. They are system specific. NARGS is the number of arguments this function accepts. libffi does not yet support vararg functions. RTYPE is a pointer to an ffi_type structure that represents the return type of the function. Ffi_type objects describe the types of values. libffi provides ffi_type objects for many of the native C types: signed int, unsigned int, signed char, unsigned char, etc. There is also a pointer ffi_type object and a void ffi_type. Use &ffi_type_void for functions that don't return values. ATYPES is a vector of ffi_type pointers. ARGS must be NARGS long. If NARGS is 0, this is ignored. ffi_prep_cif will return a status code that you are responsible for checking. It will be one of the following: FFI_OK - All is good. FFI_BAD_TYPEDEF - One of the ffi_type objects that ffi_prep_cif came across is bad. Before making the call, the VALUES vector should be initialized with pointers to the appropriate argument values. To call the the function using the initialized ffi_cif, use the ffi_call function: void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues); CIF is a pointer to the ffi_cif initialized specifically for this function. FN is a pointer to the function you want to call. RVALUE is a pointer to a chunk of memory that is to hold the result of the function call. Currently, it must be at least one word in size (except for the n32 version under Irix 6.x, which must be a pointer to an 8 byte aligned value (a long long). It must also be at least word aligned (depending on the return type, and the system's alignment requirements). If RTYPE is &ffi_type_void, this is ignored. If RVALUE is NULL, the return value is discarded. AVALUES is a vector of void* that point to the memory locations holding the argument values for a call. If NARGS is 0, this is ignored. If you are expecting a return value from FN it will have been stored at RVALUE. An Example ---------- Here is a trivial example that calls puts() a few times. #include <stdio.h> #include <ffi.h> int main() { ffi_cif cif; ffi_type *args[1]; void *values[1]; char *s; int rc; /* Initialize the argument info vectors */ args[0] = &ffi_type_uint; values[0] = &s; /* Initialize the cif */ if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_uint, args) == FFI_OK) { s = "Hello World!"; ffi_call(&cif, puts, &rc, values); /* rc now holds the result of the call to puts */ /* values holds a pointer to the function's arg, so to call puts() again all we need to do is change the value of s */ s = "This is cool!"; ffi_call(&cif, puts, &rc, values); } return 0; } Aggregate Types --------------- Although libffi has no special support for unions or bit-fields, it is perfectly happy passing structures back and forth. You must first describe the structure to libffi by creating a new ffi_type object for it. Here is the definition of ffi_type: typedef struct _ffi_type { unsigned size; short alignment; short type; struct _ffi_type **elements; } ffi_type; All structures must have type set to FFI_TYPE_STRUCT. You may set size and alignment to 0. These will be calculated and reset to the appropriate values by ffi_prep_cif(). elements is a NULL terminated array of pointers to ffi_type objects that describe the type of the structure elements. These may, in turn, be structure elements. The following example initializes a ffi_type object representing the tm struct from Linux's time.h: struct tm { int tm_sec; int tm_min; int tm_hour; int tm_mday; int tm_mon; int tm_year; int tm_wday; int tm_yday; int tm_isdst; /* Those are for future use. */ long int __tm_gmtoff__; __const char *__tm_zone__; }; { ffi_type tm_type; ffi_type *tm_type_elements[12]; int i; tm_type.size = tm_type.alignment = 0; tm_type.elements = &tm_type_elements; for (i = 0; i < 9; i++) tm_type_elements[i] = &ffi_type_sint; tm_type_elements[9] = &ffi_type_slong; tm_type_elements[10] = &ffi_type_pointer; tm_type_elements[11] = NULL; /* tm_type can now be used to represent tm argument types and return types for ffi_prep_cif() */ } Platform Specific Notes ======================= Intel x86 --------- There are no known problems with the x86 port. Sun SPARC - SunOS 4.1.3 & Solaris 2.x ------------------------------------- You must use GNU Make to build libffi on Sun platforms. MIPS - Irix 5.3 & 6.x --------------------- Irix 6.2 and better supports three different calling conventions: o32, n32 and n64. Currently, libffi only supports both o32 and n32 under Irix 6.x, but only o32 under Irix 5.3. Libffi will automatically be configured for whichever calling convention it was built for. By default, the configure script will try to build libffi with the GNU development tools. To build libffi with the SGI development tools, set the environment variable CC to either "cc -32" or "cc -n32" before running configure under Irix 6.x (depending on whether you want an o32 or n32 library), or just "cc" for Irix 5.3. With the n32 calling convention, when returning structures smaller than 16 bytes, be sure to provide an RVALUE that is 8 byte aligned. Here's one way of forcing this: double struct_storage[2]; my_small_struct *s = (my_small_struct *) struct_storage; /* Use s for RVALUE */ If you don't do this you are liable to get spurious bus errors. "long long" values are not supported yet. You must use GNU Make to build libffi on SGI platforms. ARM - System V ABI ------------------ The ARM port was performed on a NetWinder running ARM Linux ELF (2.0.31) and gcc 2.8.1. PowerPC System V ABI -------------------- There are two `System V ABI's which libffi implements for PowerPC. They differ only in how small structures are returned from functions. In the FFI_SYSV version, structures that are 8 bytes or smaller are returned in registers. This is what GCC does when it is configured for solaris, and is what the System V ABI I have (dated September 1995) says. In the FFI_GCC_SYSV version, all structures are returned the same way: by passing a pointer as the first argument to the function. This is what GCC does when it is configured for linux or a generic sysv target. EGCS 1.0.1 (and probably other versions of EGCS/GCC) also has a inconsistency with the SysV ABI: When a procedure is called with many floating-point arguments, some of them get put on the stack. They are all supposed to be stored in double-precision format, even if they are only single-precision, but EGCS stores single-precision arguments as single-precision anyway. This causes one test to fail (the `many arguments' test). What's With The Crazy Comments? =============================== You might notice a number of cryptic comments in the code, delimited by /*@ and @*/. These are annotations read by the program LCLint, a tool for statically checking C programs. You can read all about it at <http://larch-www.lcs.mit.edu:8001/larch/lclint/index.html>. History ======= 1.20 Oct-5-98 Raffaele Sena produces ARM port. 1.19 Oct-5-98 Fixed x86 long double and long long return support. m68k bug fixes from Andreas Schwab. Patch for DU assembler compatibility for the Alpha from Richard Henderson. 1.18 Apr-17-98 Bug fixes and MIPS configuration changes. 1.17 Feb-24-98 Bug fixes and m68k port from Andreas Schwab. PowerPC port from Geoffrey Keating. Various bug x86, Sparc and MIPS bug fixes. 1.16 Feb-11-98 Richard Henderson produces Alpha port. 1.15 Dec-4-97 Fixed an n32 ABI bug. New libtool, auto* support. 1.14 May-13-97 libtool is now used to generate shared and static libraries. Fixed a minor portability problem reported by Russ McManus <mc...@eq...>. 1.13 Dec-2-96 Added --enable-purify-safety to keep Purify from complaining about certain low level code. Sparc fix for calling functions with < 6 args. Linux x86 a.out fix. 1.12 Nov-22-96 Added missing ffi_type_void, needed for supporting void return types. Fixed test case for non MIPS machines. Cygnus Support is now Cygnus Solutions. 1.11 Oct-30-96 Added notes about GNU make. 1.10 Oct-29-96 Added configuration fix for non GNU compilers. 1.09 Oct-29-96 Added --enable-debug configure switch. Clean-ups based on LCLint feedback. ffi_mips.h is always installed. Many configuration fixes. Fixed ffitest.c for sparc builds. 1.08 Oct-15-96 Fixed n32 problem. Many clean-ups. 1.07 Oct-14-96 Gordon Irlam rewrites v8.S again. Bug fixes. 1.06 Oct-14-96 Gordon Irlam improved the sparc port. 1.05 Oct-14-96 Interface changes based on feedback. 1.04 Oct-11-96 Sparc port complete (modulo struct passing bug). 1.03 Oct-10-96 Passing struct args, and returning struct values works for all architectures/calling conventions. Expanded tests. 1.02 Oct-9-96 Added SGI n32 support. Fixed bugs in both o32 and Linux support. Added "make test". 1.01 Oct-8-96 Fixed float passing bug in mips version. Restructured some of the code. Builds cleanly with SGI tools. 1.00 Oct-7-96 First release. No public announcement. Authors & Credits ================= libffi was written by Anthony Green <gr...@cy...>. Portions of libffi were derived from Gianni Mariani's free gencall library for Silicon Graphics machines. The closure mechanism was designed and implemented by Kresten Krab Thorup. The Sparc port was derived from code contributed by the fine folks at Visible Decisions Inc <http://www.vdi.com>. Further enhancements were made by Gordon Irlam at Cygnus Solutions <http://www.cygnus.com>. The Alpha port was written by Richard Henderson at Cygnus Solutions. Andreas Schwab ported libffi to m68k Linux and provided a number of bug fixes. Geoffrey Keating ported libffi to the PowerPC. Raffaele Sena ported libffi to the ARM. Jesper Skov and Andrew Haley both did more than their fair share of stepping through the code and tracking down bugs. Thanks also to Tom Tromey for bug fixes and configuration help. Thanks to Jim Blandy, who provided some useful feedback on the libffi interface. If you have a problem, or have found a bug, please send a note to gr...@cy.... --- NEW FILE: types.c --- /* ----------------------------------------------------------------------- types.c - Copyright (c) 1996, 1998 Red Hat, Inc. Predefined ffi_types needed by libffi. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ #include <ffi.h> #include <ffi_common.h> /* Type definitions */ #define FFI_INTEGRAL_TYPEDEF(n, s, a, t) ffi_type ffi_type_##n = { s, a, t, NULL } #define FFI_AGGREGATE_TYPEDEF(n, e) ffi_type ffi_type_##n = { 0, 0, FFI_TYPE_STRUCT, e } /* Size and alignment are fake here. They must not be 0. */ FFI_INTEGRAL_TYPEDEF(void, 1, 1, FFI_TYPE_VOID); FFI_INTEGRAL_TYPEDEF(uint8, 1, 1, FFI_TYPE_UINT8); FFI_INTEGRAL_TYPEDEF(sint8, 1, 1, FFI_TYPE_SINT8); FFI_INTEGRAL_TYPEDEF(uint16, 2, 2, FFI_TYPE_UINT16); FFI_INTEGRAL_TYPEDEF(sint16, 2, 2, FFI_TYPE_SINT16); FFI_INTEGRAL_TYPEDEF(uint32, 4, 4, FFI_TYPE_UINT32); FFI_INTEGRAL_TYPEDEF(sint32, 4, 4, FFI_TYPE_SINT32); FFI_INTEGRAL_TYPEDEF(float, 4, 4, FFI_TYPE_FLOAT); #if defined ALPHA || defined SPARC64 || defined X86_64 || defined S390X \ || defined IA64 FFI_INTEGRAL_TYPEDEF(pointer, 8, 8, FFI_TYPE_POINTER); #else FFI_INTEGRAL_TYPEDEF(pointer, 4, 4, FFI_TYPE_POINTER); #endif #if defined X86 || defined X86_WIN32 || defined ARM || defined M68K FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); #elif defined SH FFI_INTEGRAL_TYPEDEF(uint64, 8, 4, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 4, FFI_TYPE_SINT64); #else FFI_INTEGRAL_TYPEDEF(uint64, 8, 8, FFI_TYPE_UINT64); FFI_INTEGRAL_TYPEDEF(sint64, 8, 8, FFI_TYPE_SINT64); #endif #if defined X86 || defined X86_WIN32 || defined M68K FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 12, 4, FFI_TYPE_LONGDOUBLE); #elif defined ARM || defined SH || defined POWERPC_AIX || defined POWERPC_DARWIN FFI_INTEGRAL_TYPEDEF(double, 8, 4, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 8, 4, FFI_TYPE_LONGDOUBLE); #elif defined SPARC FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); #ifdef SPARC64 FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); #else FFI_INTEGRAL_TYPEDEF(longdouble, 16, 8, FFI_TYPE_LONGDOUBLE); #endif #elif defined X86_64 FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 16, 16, FFI_TYPE_LONGDOUBLE); #else FFI_INTEGRAL_TYPEDEF(double, 8, 8, FFI_TYPE_DOUBLE); FFI_INTEGRAL_TYPEDEF(longdouble, 8, 8, FFI_TYPE_LONGDOUBLE); #endif --- NEW FILE: ffi.h --- /* -----------------------------------------------------------------*-C-*- libffi 2.00-beta - Copyright (c) 1996-2003 Red Hat, Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ``Software''), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL CYGNUS SOLUTIONS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ----------------------------------------------------------------------- */ /* ------------------------------------------------------------------- The basic API is described in the README file. The raw API is designed to bypass some of the argument packing and unpacking on architectures for which it can be avoided. The closure API allows interpreted functions to be packaged up inside a C function pointer, so that they can be called as C functions, with no understanding on the client side that they are interpreted. It can also be used in other cases in which it is necessary to package up a user specified parameter and a function pointer as a single function pointer. The closure API must be implemented in order to get its functionality, e.g. for use by gij. Routines are provided to emulate the raw API if the underlying platform doesn't allow faster implementation. More details on the raw and cloure API can be found in: http://gcc.gnu.org/ml/java/1999-q3/msg00138.html and http://gcc.gnu.org/ml/java/1999-q3/msg00174.html -------------------------------------------------------------------- */ #ifndef LIBFFI_H #define LIBFFI_H #ifdef __cplusplus extern "C" { #endif /* Specify which architecture libffi is configured for. */ //XXX #define X86 /* ---- System configuration information --------------------------------- */ #include <ffitarget.h> #ifndef LIBFFI_ASM #include <stddef.h> #include <limits.h> /* LONG_LONG_MAX is not always defined (not if STRICT_ANSI, for example). But we can find it either under the correct ANSI name, or under GNU C's internal name. */ #ifdef LONG_LONG_MAX # define FFI_LONG_LONG_MAX LONG_LONG_MAX #else # ifdef LLONG_MAX # define FFI_LONG_LONG_MAX LLONG_MAX # else # ifdef __GNUC__ # define FFI_LONG_LONG_MAX __LONG_LONG_MAX__ # endif # ifdef _MSC_VER # define FFI_LONG_LONG_MAX _I64_MAX # endif # endif #endif #if SCHAR_MAX == 127 # define ffi_type_uchar ffi_type_uint8 # define ffi_type_schar ffi_type_sint8 #else #error "char size not supported" #endif #if SHRT_MAX == 32767 # define ffi_type_ushort ffi_type_uint16 # define ffi_type_sshort ffi_type_sint16 #elif SHRT_MAX == 2147483647 # define ffi_type_ushort ffi_type_uint32 # define ffi_type_sshort ffi_type_sint32 #else #error "short size not supported" #endif #if INT_MAX == 32767 # define ffi_type_uint ffi_type_uint16 # define ffi_type_sint ffi_type_sint16 #elif INT_MAX == 2147483647 # define ffi_type_uint ffi_type_uint32 # define ffi_type_sint ffi_type_sint32 #elif INT_MAX == 9223372036854775807 # define ffi_type_uint ffi_type_uint64 # define ffi_type_sint ffi_type_sint64 #else #error "int size not supported" #endif #define ffi_type_ulong ffi_type_uint64 #define ffi_type_slong ffi_type_sint64 #if LONG_MAX == 2147483647 # if FFI_LONG_LONG_MAX != 9223372036854775807 #error "no 64-bit data type supported" # endif #elif LONG_MAX != 9223372036854775807 #error "long size not supported" #endif /* The closure code assumes that this works on pointers, i.e. a size_t */ /* can hold a pointer. */ typedef struct _ffi_type { size_t size; unsigned short alignment; unsigned short type; /*@null@*/ struct _ffi_type **elements; } ffi_type; /* These are defined in types.c */ extern ffi_type ffi_type_void; extern ffi_type ffi_type_uint8; extern ffi_type ffi_type_sint8; extern ffi_type ffi_type_uint16; extern ffi_type ffi_type_sint16; extern ffi_type ffi_type_uint32; extern ffi_type ffi_type_sint32; extern ffi_type ffi_type_uint64; extern ffi_type ffi_type_sint64; extern ffi_type ffi_type_float; extern ffi_type ffi_type_double; extern ffi_type ffi_type_longdouble; extern ffi_type ffi_type_pointer; typedef enum { FFI_OK = 0, FFI_BAD_TYPEDEF, FFI_BAD_ABI } ffi_status; typedef unsigned FFI_TYPE; typedef struct { ffi_abi abi; unsigned nargs; /*@dependent@*/ ffi_type **arg_types; /*@dependent@*/ ffi_type *rtype; unsigned bytes; unsigned flags; #ifdef FFI_EXTRA_CIF_FIELDS FFI_EXTRA_CIF_FIELDS; #endif } ffi_cif; /* ---- Definitions for the raw API -------------------------------------- */ #ifndef FFI_SIZEOF_ARG # if LONG_MAX == 2147483647 # define FFI_SIZEOF_ARG 4 # elif LONG_MAX == 9223372036854775807 # define FFI_SIZEOF_ARG 8 # endif #endif typedef union { ffi_sarg sint; ffi_arg uint; float flt; char data[FFI_SIZEOF_ARG]; void* ptr; } ffi_raw; void ffi_raw_call (/*@dependent@*/ ffi_cif *cif, void (*fn)(), /*@out@*/ void *rvalue, /*@dependent@*/ ffi_raw *avalue); void ffi_ptrarray_to_raw (ffi_cif *cif, void **args, ffi_raw *raw); void ffi_raw_to_ptrarray (ffi_cif *cif, ffi_raw *raw, void **args); size_t ffi_raw_size (ffi_cif *cif); /* This is analogous to the raw API, except it uses Java parameter */ /* pa... [truncated message content] |
From: Thomas H. <th...@us...> - 2004-05-07 17:46:47
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24865 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** ChangeLog 7 May 2004 17:45:26 -0000 1.42 --- ChangeLog 7 May 2004 17:46:32 -0000 1.43 *************** *** 1,5 **** 2004-05-07 Thomas Heller <th...@py...> ! * (Message): Tag the HEAD with 2004_05_07_before_libffi * ctypes\source\callbacks.c: Callback functions can now return --- 1,5 ---- 2004-05-07 Thomas Heller <th...@py...> ! * (Message): Tag the HEAD with before_libffi_2004_05_07 * ctypes\source\callbacks.c: Callback functions can now return |
From: Thomas H. <th...@us...> - 2004-05-07 17:45:48
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24645 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** ChangeLog 7 May 2004 17:44:49 -0000 1.41 --- ChangeLog 7 May 2004 17:45:26 -0000 1.42 *************** *** 1,5 **** 2004-05-07 Thomas Heller <th...@py...> ! * (Message): Tag the HEAD with 2004_05_07_libffi * ctypes\source\callbacks.c: Callback functions can now return --- 1,5 ---- 2004-05-07 Thomas Heller <th...@py...> ! * (Message): Tag the HEAD with 2004_05_07_before_libffi * ctypes\source\callbacks.c: Callback functions can now return |
From: Thomas H. <th...@us...> - 2004-05-07 17:44:59
|
Update of /cvsroot/ctypes/ctypes In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24502 Modified Files: ChangeLog Log Message: Index: ChangeLog =================================================================== RCS file: /cvsroot/ctypes/ctypes/ChangeLog,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** ChangeLog 6 May 2004 20:04:23 -0000 1.40 --- ChangeLog 7 May 2004 17:44:49 -0000 1.41 *************** *** 1,2 **** --- 1,9 ---- + 2004-05-07 Thomas Heller <th...@py...> + + * (Message): Tag the HEAD with 2004_05_07_libffi + + * ctypes\source\callbacks.c: Callback functions can now return + c_char and c_char_p data types. + 2004-05-06 Thomas Heller <th...@py...> |
From: Thomas H. <th...@us...> - 2004-05-07 17:44:36
|
Update of /cvsroot/ctypes/ctypes/build/lib.win32-2.4 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24428 Modified Files: _ctypes.pyd Log Message: Recompiled. Index: _ctypes.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.4/_ctypes.pyd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvsL1PJoj and /tmp/cvsIY4MkY differ |
From: Thomas H. <th...@us...> - 2004-05-07 17:44:26
|
Update of /cvsroot/ctypes/ctypes/build/lib.win32-2.3 In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv24384 Modified Files: _ctypes.pyd Log Message: Recompiled. Index: _ctypes.pyd =================================================================== RCS file: /cvsroot/ctypes/ctypes/build/lib.win32-2.3/_ctypes.pyd,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvsgR4q0E and /tmp/cvsN5uXSb differ |
From: Thomas H. <th...@us...> - 2004-05-07 17:02:36
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv16195 Modified Files: test_callbacks.py Log Message: I just learned about the failUnlessAlmostEqual unittest method! Index: test_callbacks.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_callbacks.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_callbacks.py 7 May 2004 16:47:19 -0000 1.10 --- test_callbacks.py 7 May 2004 17:02:09 -0000 1.11 *************** *** 59,66 **** def test_float(self): ! # because of rounding errors double -> float -> double, ! # this test doesn't work with every float value ! self.failUnlessEqual(self.check_type(c_float, 2.5), 2.5) ! self.failUnlessEqual(self.check_type_1(c_float, 2.5), 2.5) def test_double(self): --- 59,68 ---- def test_float(self): ! # only almost equal: double -> float -> double ! import math ! self.failUnlessAlmostEqual(self.check_type(c_float, math.e), math.e, ! places=6) ! self.failUnlessAlmostEqual(self.check_type_1(c_float, math.e), math.e, ! places=6) def test_double(self): |
From: Thomas H. <th...@us...> - 2004-05-07 16:47:34
|
Update of /cvsroot/ctypes/ctypes/unittests In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv11763 Modified Files: test_callbacks.py Log Message: The start of a systematic test of callback functions argument and return types. As it turns out, the way this currently works (in C) is flawed - I hope I can switch to libffi soon. Index: test_callbacks.py =================================================================== RCS file: /cvsroot/ctypes/ctypes/unittests/test_callbacks.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_callbacks.py 4 May 2004 09:15:19 -0000 1.9 --- test_callbacks.py 7 May 2004 16:47:19 -0000 1.10 *************** *** 2,6 **** from ctypes import * ! class CallbacksTestCase(unittest.TestCase): def test_integrate(self): --- 2,81 ---- from ctypes import * ! class CallbacksBase(unittest.TestCase): ! def callback(self, *args): ! return args[-1] ! ! def check_type(self, typ, arg): ! PROTO = CFUNCTYPE(typ, typ) ! return PROTO(self.callback)(arg) ! ! def check_type_1(self, typ, arg): ! PROTO = CFUNCTYPE(typ, c_byte, typ) ! return PROTO(self.callback)(0, arg) ! ! ################ ! ! ! class IntegerCallbacks(CallbacksBase): ! def test_byte(self): ! self.failUnlessEqual(self.check_type(c_byte, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_byte, 42), 42) ! ! def test_ubyte(self): ! self.failUnlessEqual(self.check_type(c_ubyte, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_ubyte, 42), 42) ! ! def test_short(self): ! self.failUnlessEqual(self.check_type(c_short, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_short, 42), 42) ! ! def test_ushort(self): ! self.failUnlessEqual(self.check_type(c_ushort, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_ushort, 42), 42) ! ! def test_int(self): ! self.failUnlessEqual(self.check_type(c_int, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_int, 42), 42) ! ! def test_uint(self): ! self.failUnlessEqual(self.check_type(c_uint, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_uint, 42), 42) ! ! def test_long(self): ! self.failUnlessEqual(self.check_type(c_long, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_long, 42), 42) ! ! def test_ulong(self): ! self.failUnlessEqual(self.check_type(c_ulong, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_ulong, 42), 42) ! ! def test_longlong(self): ! self.failUnlessEqual(self.check_type(c_longlong, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_longlong, 42), 42) ! ! def test_ulonglong(self): ! self.failUnlessEqual(self.check_type(c_ulonglong, 42), 42) ! self.failUnlessEqual(self.check_type_1(c_ulonglong, 42), 42) ! ! def test_float(self): ! # because of rounding errors double -> float -> double, ! # this test doesn't work with every float value ! self.failUnlessEqual(self.check_type(c_float, 2.5), 2.5) ! self.failUnlessEqual(self.check_type_1(c_float, 2.5), 2.5) ! ! def test_double(self): ! self.failUnlessEqual(self.check_type(c_double, 3.14), 3.14) ! self.failUnlessEqual(self.check_type_1(c_double, 3.14), 3.14) ! ! class CharCallbacks(CallbacksBase): ! def test_char(self): ! self.failUnlessEqual(self.check_type(c_char, "x"), "x") ! self.failUnlessEqual(self.check_type_1(c_char, "x"), "x") ! ! def test_char_p(self): ! self.failUnlessEqual(self.check_type(c_char_p, "abc"), "abc") ! self.failUnlessEqual(self.check_type_1(c_char_p, "abc"), "abc") ! ! class SampleCallbacksTestCase(unittest.TestCase): def test_integrate(self): |