summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Rigo <arigo@tunes.org>2020-08-13 10:18:12 +0200
committerArmin Rigo <arigo@tunes.org>2020-08-13 10:18:12 +0200
commit6ad20043e06f22a64fe497cd96036f34d49f63bf (patch)
tree43c7742343ba9579ee744557695b615effbaadfa
parentccad9d0020f4d50cb7b2c8e9b60b102e6d61a92a (diff)
downloadcffi-int128.tar.gz
in-progressint128
-rw-r--r--c/_cffi_backend.c18
-rw-r--r--c/cffi1_module.c5
-rw-r--r--c/parse_c_type.c3
-rw-r--r--c/realize_c_type.c6
-rw-r--r--cffi/_cffi_include.h27
-rw-r--r--cffi/cffi_opcode.py6
-rw-r--r--cffi/parse_c_type.h4
-rw-r--r--cffi/recompiler.py5
-rw-r--r--testing/cffi1/test_verify1.py8
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