Commits

Armin Rigo committed 83d81b5

Extract from _cffi_backend.c the tests, and copy them into a test C library.

  • Participants
  • Parent commits 4c16965
  • Branches ffi-backend

Comments (0)

Files changed (2)

pypy/module/_cffi_backend/test/_test_lib.c

+#include <stdio.h>
+#include <stdarg.h>
+
+static char _testfunc0(char a, char b)
+{
+    return a + b;
+}
+static long _testfunc1(int a, long b)
+{
+    return (long)a + b;
+}
+static long long _testfunc2(long long a, long long b)
+{
+    return a + b;
+}
+static double _testfunc3(float a, double b)
+{
+    return a + b;
+}
+static float _testfunc4(float a, double b)
+{
+    return (float)(a + b);
+}
+static void _testfunc5(void)
+{
+}
+static int *_testfunc6(int *x)
+{
+    static int y;
+    y = *x - 1000;
+    return &y;
+}
+struct _testfunc7_s { unsigned char a1; short a2; };
+static short _testfunc7(struct _testfunc7_s inlined)
+{
+    return inlined.a1 + inlined.a2;
+}
+static int _testfunc9(int num, ...)
+{
+    va_list vargs;
+    int i, total = 0;
+    va_start(vargs, num);
+    for (i=0; i<num; i++) {
+        int value = va_arg(vargs, int);
+        if (value == 0)
+            value = -66666666;
+        total += value;
+    }
+    va_end(vargs);
+    return total;
+}
+
+static struct _testfunc7_s _testfunc10(int n)
+{
+    struct _testfunc7_s result;
+    result.a1 = n;
+    result.a2 = n * n;
+    return result;
+}
+
+struct _testfunc11_s { int a1, a2; };
+static struct _testfunc11_s _testfunc11(int n)
+{
+    struct _testfunc11_s result;
+    result.a1 = n;
+    result.a2 = n * n;
+    return result;
+}
+
+struct _testfunc12_s { double a1; };
+static struct _testfunc12_s _testfunc12(int n)
+{
+    struct _testfunc12_s result;
+    result.a1 = n;
+    return result;
+}
+
+struct _testfunc13_s { int a1, a2, a3; };
+static struct _testfunc13_s _testfunc13(int n)
+{
+    struct _testfunc13_s result;
+    result.a1 = n;
+    result.a2 = n * n;
+    result.a3 = n * n * n;
+    return result;
+}
+
+struct _testfunc14_s { float a1; };
+static struct _testfunc14_s _testfunc14(int n)
+{
+    struct _testfunc14_s result;
+    result.a1 = (float)n;
+    return result;
+}
+
+struct _testfunc15_s { float a1; int a2; };
+static struct _testfunc15_s _testfunc15(int n)
+{
+    struct _testfunc15_s result;
+    result.a1 = (float)n;
+    result.a2 = n * n;
+    return result;
+}
+
+struct _testfunc16_s { float a1, a2; };
+static struct _testfunc16_s _testfunc16(int n)
+{
+    struct _testfunc16_s result;
+    result.a1 = (float)n;
+    result.a2 = -(float)n;
+    return result;
+}
+
+struct _testfunc17_s { int a1; float a2; };
+static struct _testfunc17_s _testfunc17(int n)
+{
+    struct _testfunc17_s result;
+    result.a1 = n;
+    result.a2 = (float)n * (float)n;
+    return result;
+}
+
+void *gettestfunc(int num)
+{
+    void *f;
+    switch (num) {
+    case 0: f = &_testfunc0; break;
+    case 1: f = &_testfunc1; break;
+    case 2: f = &_testfunc2; break;
+    case 3: f = &_testfunc3; break;
+    case 4: f = &_testfunc4; break;
+    case 5: f = &_testfunc5; break;
+    case 6: f = &_testfunc6; break;
+    case 7: f = &_testfunc7; break;
+    case 8: f = stderr; break;
+    case 9: f = &_testfunc9; break;
+    case 10: f = &_testfunc10; break;
+    case 11: f = &_testfunc11; break;
+    case 12: f = &_testfunc12; break;
+    case 13: f = &_testfunc13; break;
+    case 14: f = &_testfunc14; break;
+    case 15: f = &_testfunc15; break;
+    case 16: f = &_testfunc16; break;
+    case 17: f = &_testfunc17; break;
+    default:
+        return NULL;
+    }
+    return f;
+}

pypy/module/_cffi_backend/test/test_c.py

 This file is OBSCURE.  Really.  The purpose is to avoid copying and changing
 'test_c.py' from cffi/c/.
 """
-import py, ctypes, operator
+import py, ctypes
 from pypy.tool.udir import udir
 from pypy.conftest import gettestobjspace
 from pypy.interpreter import gateway
 from pypy.module._cffi_backend.test import _backend_test_c
 from pypy.module._cffi_backend import Module
+from pypy.translator.platform import host
+from pypy.translator.tool.cbuild import ExternalCompilationInfo
 
 
 class AppTestC(object):
                 import _cffi_backend
                 return _cffi_backend.load_library(path)""")
 
-        def testfunc0(a, b):
-            return chr((ord(a) + ord(b)) & 0xFF)
+        test_lib_c = tmpdir.join('_test_lib.c')
+        src_test_lib_c = py.path.local(__file__).dirpath().join('_test_lib.c')
+        src_test_lib_c.copy(test_lib_c)
+        eci = ExternalCompilationInfo()
+        test_lib = host.compile([test_lib_c], eci, standalone=False)
 
-        testfunc6_static = ctypes.c_int(0)
-        def testfunc6(p_int):
-            testfunc6_static.value = p_int[0] - 1000
-            ptr = ctypes.pointer(testfunc6_static)
-            return ctypes.cast(ptr, ctypes.c_void_p).value
-
-        class _testfunc7_s(ctypes.Structure):
-            _fields_ = [('a1', ctypes.c_ubyte),
-                        ('a2', ctypes.c_short)]
-        def testfunc7(inlined):
-            return inlined.a1 + inlined.a2
-
-        def prepfunc(func, argtypes, restype):
-            c_func = ctypes.CFUNCTYPE(restype, *argtypes)(func)
-            keepalive_funcs.append(c_func)
-            return ctypes.cast(c_func, ctypes.c_void_p).value
+        cdll = ctypes.CDLL(str(test_lib))
+        cdll.gettestfunc.restype = ctypes.c_void_p
 
         def testfunc_for_test(space, w_num):
-            if not testfuncs_w:
-                testfuncs = [
-                    prepfunc(testfunc0,       # testfunc0
-                             (ctypes.c_char, ctypes.c_char), ctypes.c_char),
-                    prepfunc(operator.add,    # testfunc1
-                             (ctypes.c_int, ctypes.c_long), ctypes.c_long),
-                    prepfunc(operator.add,    # testfunc2
-                             (ctypes.c_longlong, ctypes.c_longlong),
-                             ctypes.c_longlong),
-                    prepfunc(operator.add,    # testfunc3
-                             (ctypes.c_float, ctypes.c_double),
-                             ctypes.c_double),
-                    prepfunc(operator.add,    # testfunc4
-                             (ctypes.c_float, ctypes.c_double),
-                             ctypes.c_float),
-                    prepfunc(lambda: None,    # testfunc5
-                             (), None),
-                    prepfunc(testfunc6,       # testfunc6
-                             (ctypes.POINTER(ctypes.c_int),),
-                             ctypes.c_void_p),
-                    prepfunc(testfunc7,       # testfunc7
-                             (_testfunc7_s,), ctypes.c_short),
-                    ]
-                testfuncs_w[:] = [space.wrap(addr) for addr in testfuncs]
-            return testfuncs_w[space.int_w(w_num)]
+            addr = cdll.gettestfunc(space.int_w(w_num))
+            return space.wrap(addr)
 
         w_func = space.wrap(gateway.interp2app(find_and_load_library_for_test))
         w_testfunc = space.wrap(gateway.interp2app(testfunc_for_test))