Esempio n. 1
0
    def test_cdll_life_time(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(py.code.Source('''
        long fun(long i) {
            return i + 42;
        }
        '''))
        eci = ExternalCompilationInfo(export_symbols=['fun'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)
        slong = cast_type_to_ffitype(rffi.LONG)
        fun = lib.getrawpointer('fun', [slong], slong)
        del lib     # already delete here

        buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw')
        buffer[0] = 200
        buffer[1] = -1
        fun.call([rffi.cast(rffi.VOIDP, buffer)],
                 rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
        assert buffer[1] == 242

        lltype.free(buffer, flavor='raw')
        del fun

        assert not ALLOCATED
Esempio n. 2
0
    def test_cdll_life_time(self):
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        long fun(long i) {
            return i + 42;
        }
        '''))
        eci = ExternalCompilationInfo(export_symbols=['fun'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)
        slong = cast_type_to_ffitype(rffi.LONG)
        fun = lib.getrawpointer('fun', [slong], slong)
        del lib  # already delete here

        buffer = lltype.malloc(rffi.LONGP.TO, 2, flavor='raw')
        buffer[0] = 200
        buffer[1] = -1
        fun.call([rffi.cast(rffi.VOIDP, buffer)],
                 rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 1)))
        assert buffer[1] == 242

        lltype.free(buffer, flavor='raw')
        del fun

        assert not ALLOCATED
Esempio n. 3
0
    def test_struct_by_val(self):
        import platform
        if platform.machine() == 'x86_64':
            py.test.skip("Segfaults on x86_64 because small structures "
                         "may be passed in registers and "
                         "c_elements must not be null")
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        long sum_x_y_p(struct x_y *p) {
            return p->x + p->y;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['sum_x_y'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        slong = cast_type_to_ffitype(rffi.LONG)
        size = slong.c_size * 2
        alignment = slong.c_alignment
        tp = make_struct_ffitype(size, alignment)

        sum_x_y = lib.getrawpointer('sum_x_y', [tp], slong)

        buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw')
        buffer[0] = 200
        buffer[1] = 220
        buffer[2] = 666
        sum_x_y.call([rffi.cast(rffi.VOIDP, buffer)],
                     rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 2)))
        assert buffer[2] == 420

        lltype.free(buffer, flavor='raw')
        del sum_x_y
        lltype.free(tp, flavor='raw')
        del lib

        assert not ALLOCATED
Esempio n. 4
0
    def test_struct_by_val(self):
        import platform
        if platform.machine() == 'x86_64':
            py.test.skip("Segfaults on x86_64 because small structures "
                         "may be passed in registers and "
                         "c_elements must not be null")
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct x_y {
            long x;
            long y;
        };

        long sum_x_y(struct x_y s) {
            return s.x + s.y;
        }

        long sum_x_y_p(struct x_y *p) {
            return p->x + p->y;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['sum_x_y'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        slong = cast_type_to_ffitype(rffi.LONG)
        size = slong.c_size*2
        alignment = slong.c_alignment
        tp = make_struct_ffitype(size, alignment)

        sum_x_y = lib.getrawpointer('sum_x_y', [tp], slong)

        buffer = lltype.malloc(rffi.LONGP.TO, 3, flavor='raw')
        buffer[0] = 200
        buffer[1] = 220
        buffer[2] = 666
        sum_x_y.call([rffi.cast(rffi.VOIDP, buffer)],
                     rffi.cast(rffi.VOIDP, rffi.ptradd(buffer, 2)))
        assert buffer[2] == 420

        lltype.free(buffer, flavor='raw')
        del sum_x_y
        lltype.free(tp, flavor='raw')
        del lib

        assert not ALLOCATED
Esempio n. 5
0
    def test_ret_struct_val(self):
        import platform
        if platform.machine() == 'x86_64':
            py.test.skip("Segfaults on x86_64 because small structures "
                         "may be passed in registers and "
                         "c_elements must not be null")
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['give', 'perturb'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        size = ffi_type_sshort.c_size*2
        alignment = ffi_type_sshort.c_alignment
        tp = make_struct_ffitype(size, alignment)

        give  = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort],
                                  tp)
        inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')
        inbuffer[0] = rffi.cast(rffi.SHORT, 40)
        inbuffer[1] = rffi.cast(rffi.SHORT, 72)

        outbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')

        give.call([rffi.cast(rffi.VOIDP, inbuffer),
                   rffi.cast(rffi.VOIDP, rffi.ptradd(inbuffer, 1))],
                   rffi.cast(rffi.VOIDP, outbuffer))

        assert outbuffer[0] == 40
        assert outbuffer[1] == 72

        perturb  = lib.getrawpointer('perturb', [tp], tp)

        inbuffer[0] = rffi.cast(rffi.SHORT, 7)
        inbuffer[1] = rffi.cast(rffi.SHORT, 11)

        perturb.call([rffi.cast(rffi.VOIDP, inbuffer)],
                     rffi.cast(rffi.VOIDP, outbuffer))

        assert inbuffer[0] == 7
        assert inbuffer[1] == 11

        assert outbuffer[0] == 14
        assert outbuffer[1] == 33

        lltype.free(outbuffer, flavor='raw')
        lltype.free(inbuffer, flavor='raw')
        del give
        del perturb
        lltype.free(tp, flavor='raw')
        del lib

        assert not ALLOCATED
Esempio n. 6
0
    def test_ret_struct_val(self):
        import platform
        if platform.machine() == 'x86_64':
            py.test.skip("Segfaults on x86_64 because small structures "
                         "may be passed in registers and "
                         "c_elements must not be null")
        from pypy.translator.tool.cbuild import ExternalCompilationInfo
        from pypy.translator.platform import platform
        from pypy.tool.udir import udir

        c_file = udir.ensure("test_libffi", dir=1).join("xlib.c")
        c_file.write(
            py.code.Source('''
        #include <stdlib.h>
        #include <stdio.h>

        struct s2h {
            short x;
            short y;
        };

        struct s2h give(short x, short y) {
            struct s2h out;
            out.x = x;
            out.y = y;
            return out;
        }

        struct s2h perturb(struct s2h inp) {
            inp.x *= 2;
            inp.y *= 3;
            return inp;
        }
        
        '''))
        eci = ExternalCompilationInfo(export_symbols=['give', 'perturb'])
        lib_name = str(platform.compile([c_file], eci, 'x', standalone=False))

        lib = CDLL(lib_name)

        size = ffi_type_sshort.c_size * 2
        alignment = ffi_type_sshort.c_alignment
        tp = make_struct_ffitype(size, alignment)

        give = lib.getrawpointer('give', [ffi_type_sshort, ffi_type_sshort],
                                 tp)
        inbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')
        inbuffer[0] = rffi.cast(rffi.SHORT, 40)
        inbuffer[1] = rffi.cast(rffi.SHORT, 72)

        outbuffer = lltype.malloc(rffi.SHORTP.TO, 2, flavor='raw')

        give.call([
            rffi.cast(rffi.VOIDP, inbuffer),
            rffi.cast(rffi.VOIDP, rffi.ptradd(inbuffer, 1))
        ], rffi.cast(rffi.VOIDP, outbuffer))

        assert outbuffer[0] == 40
        assert outbuffer[1] == 72

        perturb = lib.getrawpointer('perturb', [tp], tp)

        inbuffer[0] = rffi.cast(rffi.SHORT, 7)
        inbuffer[1] = rffi.cast(rffi.SHORT, 11)

        perturb.call([rffi.cast(rffi.VOIDP, inbuffer)],
                     rffi.cast(rffi.VOIDP, outbuffer))

        assert inbuffer[0] == 7
        assert inbuffer[1] == 11

        assert outbuffer[0] == 14
        assert outbuffer[1] == 33

        lltype.free(outbuffer, flavor='raw')
        lltype.free(inbuffer, flavor='raw')
        del give
        del perturb
        lltype.free(tp, flavor='raw')
        del lib

        assert not ALLOCATED