diff options
| author | Armin Rigo <arigo@tunes.org> | 2020-08-13 10:18:12 +0200 |
|---|---|---|
| committer | Armin Rigo <arigo@tunes.org> | 2020-08-13 10:18:12 +0200 |
| commit | 6ad20043e06f22a64fe497cd96036f34d49f63bf (patch) | |
| tree | 43c7742343ba9579ee744557695b615effbaadfa | |
| parent | ccad9d0020f4d50cb7b2c8e9b60b102e6d61a92a (diff) | |
| download | cffi-int128.tar.gz | |
in-progressint128
| -rw-r--r-- | c/_cffi_backend.c | 18 | ||||
| -rw-r--r-- | c/cffi1_module.c | 5 | ||||
| -rw-r--r-- | c/parse_c_type.c | 3 | ||||
| -rw-r--r-- | c/realize_c_type.c | 6 | ||||
| -rw-r--r-- | cffi/_cffi_include.h | 27 | ||||
| -rw-r--r-- | cffi/cffi_opcode.py | 6 | ||||
| -rw-r--r-- | cffi/parse_c_type.h | 4 | ||||
| -rw-r--r-- | cffi/recompiler.py | 5 | ||||
| -rw-r--r-- | testing/cffi1/test_verify1.py | 8 |
9 files changed, 61 insertions, 21 deletions
diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c index c7c48f8..0739927 100644 --- a/c/_cffi_backend.c +++ b/c/_cffi_backend.c @@ -60,6 +60,15 @@ # endif #endif +#ifdef __SIZEOF_INT128__ +# define HAVE_TYPE_INT128 +typedef __int128 largest_int_t; +typedef unsigned __int128 largest_uint_t; +#else +typedef long long largest_int_t; +typedef unsigned long long largest_uint_t; +#endif + /* Define the following macro ONLY if you trust libffi's version of * ffi_closure_alloc() more than the code in malloc_closure.h. @@ -254,15 +263,6 @@ static PyTypeObject CDataGCP_Type; #define CDataOwn_Check(ob) (Py_TYPE(ob) == &CDataOwning_Type || \ Py_TYPE(ob) == &CDataOwningGC_Type) -#ifdef __SIZEOF_INT128__ -# define HAVE_TYPE_INT128 -typedef __int128 largest_int_t; -typedef unsigned __int128 largest_uint_t; -#else -typedef long long largest_int_t; -typedef unsigned long long largest_uint_t; -#endif - typedef union { unsigned char m_char; unsigned short m_short; diff --git a/c/cffi1_module.c b/c/cffi1_module.c index 06a84fe..80e6988 100644 --- a/c/cffi1_module.c +++ b/c/cffi1_module.c @@ -4,7 +4,8 @@ #define CFFI_VERSION_MIN 0x2601 #define CFFI_VERSION_CHAR16CHAR32 0x2801 -#define CFFI_VERSION_MAX 0x28FF +#define CFFI_VERSION_INT128 0x2901 +#define CFFI_VERSION_MAX 0x29FF typedef struct FFIObject_s FFIObject; typedef struct LibObject_s LibObject; @@ -171,6 +172,8 @@ static PyObject *b_init_cffi_1_0_external_module(PyObject *self, PyObject *arg) num_exports = 26; if (version >= CFFI_VERSION_CHAR16CHAR32) num_exports = 28; + if (version >= CFFI_VERSION_INT128) + num_exports = 30; memcpy(exports, (char *)cffi_exports, num_exports * sizeof(void *)); /* make the module object */ diff --git a/c/parse_c_type.c b/c/parse_c_type.c index 698ef64..ffce219 100644 --- a/c/parse_c_type.c +++ b/c/parse_c_type.c @@ -43,6 +43,8 @@ enum token_e { TOK_CDECL, TOK_STDCALL, + + TOK_INT128, }; typedef struct { @@ -160,6 +162,7 @@ static void next_token(token_t *tok) if (tok->size == 7 && !memcmp(p,"__cdecl",7)) tok->kind = TOK_CDECL; if (tok->size == 9 && !memcmp(p,"__stdcall",9))tok->kind = TOK_STDCALL; if (tok->size == 8 && !memcmp(p,"_Complex",8)) tok->kind = TOK__COMPLEX; + if (tok->size == 8 && !memcmp(p,"__int128",8)) tok->kind = TOK_INT128; break; case 'c': if (tok->size == 4 && !memcmp(p, "char", 4)) tok->kind = TOK_CHAR; diff --git a/c/realize_c_type.c b/c/realize_c_type.c index 82629b7..1bb9f75 100644 --- a/c/realize_c_type.c +++ b/c/realize_c_type.c @@ -155,10 +155,14 @@ static PyObject *build_primitive_type(int num) "double _Complex", "char16_t", "char32_t", + "__int128", + "unsigned __int128", }; PyObject *x; - assert(sizeof(primitive_name) == sizeof(*primitive_name) * _CFFI__NUM_PRIM); + if (sizeof(primitive_name) != sizeof(*primitive_name) * _CFFI__NUM_PRIM) + Py_FatalError("realize_c_type.c: fix primitive_name[]"); + if (num == _CFFI_PRIM_VOID) { x = new_void_type(); } diff --git a/cffi/_cffi_include.h b/cffi/_cffi_include.h index 3129150..4b39b29 100644 --- a/cffi/_cffi_include.h +++ b/cffi/_cffi_include.h @@ -79,6 +79,15 @@ extern "C" { # endif #endif +#ifdef __SIZEOF_INT128__ +# define HAVE_TYPE_INT128 +typedef __int128 _cffi_largest_int_t; +typedef unsigned __int128 _cffi_largest_uint_t; +#else +typedef long long _cffi_largest_int_t; +typedef unsigned long long _cffi_largest_uint_t; +#endif + #ifdef __GNUC__ # define _CFFI_UNUSED_FN __attribute__((unused)) #else @@ -116,10 +125,14 @@ extern "C" { PyInt_FromLong((long)x) : \ sizeof(type) == sizeof(long) ? \ PyLong_FromUnsignedLong((unsigned long)x) : \ - PyLong_FromUnsignedLongLong((unsigned long long)x)) : \ - (sizeof(type) <= sizeof(long) ? \ + sizeof(type) <= sizeof(long long) ? \ + PyLong_FromUnsignedLongLong((unsigned long long)x) : \ + _cffi_PyLong_FromUnsignedLargestInt(x)) : \ + ( sizeof(type) <= sizeof(long) ? \ PyInt_FromLong((long)x) : \ - PyLong_FromLongLong((long long)x))) + sizeof(type) <= sizeof(long long) ? \ + PyLong_FromLongLong((long long)x) : \ + _cffi_PyLong_FromLargestInt(x) )) #define _cffi_to_c_int(o, type) \ ((type)( \ @@ -131,6 +144,8 @@ extern "C" { : (type)_cffi_to_c_i32(o)) : \ sizeof(type) == 8 ? (((type)-1) > 0 ? (type)_cffi_to_c_u64(o) \ : (type)_cffi_to_c_i64(o)) : \ + sizeof(type) == 16 ? (((type)-1) > 0 ? (type)_cffi_to_c_u128(o) \ + : (type)_cffi_to_c_i128(o)) : \ (Py_FatalError("unsupported size for type " #type), (type)0))) #define _cffi_to_c_i8 \ @@ -189,7 +204,11 @@ extern "C" { ((int(*)(PyObject *))_cffi_exports[26]) #define _cffi_from_c_wchar3216_t \ ((PyObject *(*)(int))_cffi_exports[27]) -#define _CFFI_NUM_EXPORTS 28 +#define _cffi_to_c_i128 \ + ((_cffi_largest_int_t(*)(PyObject *))_cffi_exports[28]) +#define _cffi_to_c_u128 \ + ((_cffi_largest_uint_t(*)(PyObject *))_cffi_exports[29]) +#define _CFFI_NUM_EXPORTS 30 struct _cffi_ctypedescr; diff --git a/cffi/cffi_opcode.py b/cffi/cffi_opcode.py index a0df98d..db85d99 100644 --- a/cffi/cffi_opcode.py +++ b/cffi/cffi_opcode.py @@ -109,8 +109,10 @@ PRIM_FLOATCOMPLEX = 48 PRIM_DOUBLECOMPLEX = 49 PRIM_CHAR16 = 50 PRIM_CHAR32 = 51 +PRIM_INT128 = 52 +PRIM_UINT128 = 53 -_NUM_PRIM = 52 +_NUM_PRIM = 54 _UNKNOWN_PRIM = -1 _UNKNOWN_FLOAT_PRIM = -2 _UNKNOWN_LONG_DOUBLE = -3 @@ -169,6 +171,8 @@ PRIMITIVE_TO_INDEX = { 'uint_fast64_t': PRIM_UINT_FAST64, 'intmax_t': PRIM_INTMAX, 'uintmax_t': PRIM_UINTMAX, + '__int128': PRIM_INT128, + 'unsigned __int128': PRIM_UINT128, } F_UNION = 0x01 diff --git a/cffi/parse_c_type.h b/cffi/parse_c_type.h index 84e4ef8..e2428ca 100644 --- a/cffi/parse_c_type.h +++ b/cffi/parse_c_type.h @@ -83,8 +83,10 @@ typedef void *_cffi_opcode_t; #define _CFFI_PRIM_DOUBLECOMPLEX 49 #define _CFFI_PRIM_CHAR16 50 #define _CFFI_PRIM_CHAR32 51 +#define _CFFI_PRIM_INT128 52 +#define _CFFI_PRIM_UINT128 53 -#define _CFFI__NUM_PRIM 52 +#define _CFFI__NUM_PRIM 54 #define _CFFI__UNKNOWN_PRIM (-1) #define _CFFI__UNKNOWN_FLOAT_PRIM (-2) #define _CFFI__UNKNOWN_LONG_DOUBLE (-3) diff --git a/cffi/recompiler.py b/cffi/recompiler.py index 1309572..9843321 100644 --- a/cffi/recompiler.py +++ b/cffi/recompiler.py @@ -6,6 +6,7 @@ from .cffi_opcode import * VERSION_BASE = 0x2601 VERSION_EMBEDDED = 0x2701 VERSION_CHAR16CHAR32 = 0x2801 +VERSION_INT128 = 0x2901 class GlobalExpr: @@ -519,6 +520,8 @@ class Recompiler: extraarg = '' if isinstance(tp, model.BasePrimitiveType) and not tp.is_complex_type(): if tp.is_integer_type() and tp.name != '_Bool': + if tp.name.endswith('__int128'): + self.needs_version(VERSION_INT128) converter = '_cffi_to_c_int' extraarg = ', %s' % tp.name elif isinstance(tp, model.UnknownFloatType): @@ -584,6 +587,8 @@ class Recompiler: def _convert_expr_from_c(self, tp, var, context): if isinstance(tp, model.BasePrimitiveType): if tp.is_integer_type() and tp.name != '_Bool': + if tp.name.endswith('__int128'): + self.needs_version(VERSION_INT128) return '_cffi_from_c_int(%s, %s)' % (var, tp.name) elif isinstance(tp, model.UnknownFloatType): return '_cffi_from_c_double(%s)' % (var,) diff --git a/testing/cffi1/test_verify1.py b/testing/cffi1/test_verify1.py index f2321b0..5c72d77 100644 --- a/testing/cffi1/test_verify1.py +++ b/testing/cffi1/test_verify1.py @@ -2360,11 +2360,11 @@ def test_ffi_new_with_cycles(): def test_int128(): ffi = FFI() - ffi.cdef("""__int128 f(__int128 x, __int128 y);""") + ffi.cdef("""__int128 f128(__int128 x, __int128 y);""") lib = ffi.verify(""" - static __int128 f(__int128 x, __int128 y) { return x - y; } + static __int128 f128(__int128 x, __int128 y) { return x - y; } """) x = 0x0123456789abcdef0123456789abcdef y = 0x102030405060708090a0b0c0d0e0f000 - assert lib.f(x, y) == x - y - assert lib.f(y, x) == y - x + assert lib.f128(x, y) == x - y + assert lib.f128(y, x) == y - x |
