Beispiel #1
0
def test_cancollect_external():
    fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=False)
    def g():
        fext1()
    t = rtype(g, [])
    gg = graphof(t, g)
    assert not CollectAnalyzer(t).analyze_direct_call(gg)

    fext2 = rffi.llexternal('fext2', [], lltype.Void, threadsafe=True)
    def g():
        fext2()
    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)

    S = lltype.GcStruct('S', ('x', lltype.Signed))
    FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, threadsafe=False)
    def h(x):
        lltype.malloc(S, zero=True)
    def g():
        fext3(h)
    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)
Beispiel #2
0
def external(name, args, result):
    unsafe = rffi.llexternal(name, args, result,
                             compilation_info=CConfig._compilation_info_)
    safe = rffi.llexternal(name, args, result,
                           compilation_info=CConfig._compilation_info_,
                           sandboxsafe=True, threadsafe=False)
    return unsafe, safe
Beispiel #3
0
def test_cancollect_external():
    fext1 = rffi.llexternal('fext1', [], lltype.Void, threadsafe=False)

    def g():
        fext1()

    t = rtype(g, [])
    gg = graphof(t, g)
    assert not CollectAnalyzer(t).analyze_direct_call(gg)

    fext2 = rffi.llexternal('fext2', [], lltype.Void, threadsafe=True)

    def g():
        fext2()

    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)

    S = lltype.GcStruct('S', ('x', lltype.Signed))
    FUNC = lltype.Ptr(lltype.FuncType([lltype.Signed], lltype.Void))
    fext3 = rffi.llexternal('fext3', [FUNC], lltype.Void, threadsafe=False)

    def h(x):
        lltype.malloc(S, zero=True)

    def g():
        fext3(h)

    t = rtype(g, [])
    gg = graphof(t, g)
    assert CollectAnalyzer(t).analyze_direct_call(gg)
Beispiel #4
0
 def test_different_signatures(self):
     fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
                                 rffi.INT)
     fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP],
                                 rffi.INT)
     fcntl_int(12345, 1, 0)
     fcntl_str(12345, 3, "xxx")
     fcntl_int(12345, 1, 0)
Beispiel #5
0
 def test_different_signatures(self):
     fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
                                 rffi.INT)
     fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP],
                                 rffi.INT)
     fcntl_int(12345, 1, 0)
     fcntl_str(12345, 3, "xxx")
     fcntl_int(12345, 1, 0)
Beispiel #6
0
def setup_init_functions(eci):
    init_buffer = rffi.llexternal('init_bufferobject', [], lltype.Void, compilation_info=eci)
    init_pycobject = rffi.llexternal('init_pycobject', [], lltype.Void, compilation_info=eci)
    init_capsule = rffi.llexternal('init_capsule', [], lltype.Void, compilation_info=eci)
    INIT_FUNCTIONS.extend([
        lambda space: init_buffer(),
        lambda space: init_pycobject(),
        lambda space: init_capsule(),
    ])
Beispiel #7
0
 def test_different_signatures(self):
     if sys.platform=='win32':
         py.test.skip("No fcntl on win32")
     fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
                                 rffi.INT)
     fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP],
                                 rffi.INT)
     fcntl_int(12345, 1, 0)
     fcntl_str(12345, 3, "xxx")
     fcntl_int(12345, 1, 0)
Beispiel #8
0
 def test_different_signatures(self):
     if sys.platform == 'win32':
         py.test.skip("No fcntl on win32")
     fcntl_int = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.INT],
                                 rffi.INT)
     fcntl_str = rffi.llexternal('fcntl', [rffi.INT, rffi.INT, rffi.CCHARP],
                                 rffi.INT)
     fcntl_int(12345, 1, 0)
     fcntl_str(12345, 3, "xxx")
     fcntl_int(12345, 1, 0)
Beispiel #9
0
def external(name, args, result):
    unsafe = rffi.llexternal(name,
                             args,
                             result,
                             compilation_info=CConfig._compilation_info_)
    safe = rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=CConfig._compilation_info_,
                           sandboxsafe=True,
                           threadsafe=False)
    return unsafe, safe
Beispiel #10
0
 def test_llexternal_macro(self):
     eci = ExternalCompilationInfo(
         post_include_bits = ["#define fn(x) (42 + x)"],
     )
     fn1 = rffi.llexternal('fn', [rffi.INT], rffi.INT, 
                           compilation_info=eci, macro=True)
     fn2 = rffi.llexternal('fn2', [rffi.DOUBLE], rffi.DOUBLE, 
                           compilation_info=eci, macro='fn')
     res = fn1(10)
     assert res == 52
     res = fn2(10.5)
     assert res == 52.5
Beispiel #11
0
    def test_opaque_obj_2(self):
        FILEP = rffi.COpaquePtr('FILE')
        fopen = rffi.llexternal('fopen', [rffi.CCHARP, rffi.CCHARP], FILEP)
        fclose = rffi.llexternal('fclose', [FILEP], rffi.INT)
        tmppath = udir.join('test_ll2ctypes.test_opaque_obj_2')
        ll_file = fopen(str(tmppath), "w")
        assert ll_file
        fclose(ll_file)
        assert tmppath.check(file=1)
        assert not ALLOCATED     # detects memory leaks in the test

        assert rffi.cast(FILEP, -1) == rffi.cast(FILEP, -1)
Beispiel #12
0
def setup_init_functions(eci):
    init_buffer = rffi.llexternal('init_bufferobject', [], lltype.Void, compilation_info=eci)
    init_pycobject = rffi.llexternal('init_pycobject', [], lltype.Void, compilation_info=eci)
    init_capsule = rffi.llexternal('init_capsule', [], lltype.Void, compilation_info=eci)
    INIT_FUNCTIONS.extend([
        lambda space: init_buffer(),
        lambda space: init_pycobject(),
        lambda space: init_capsule(),
    ])
    from pypy.module.posix.interp_posix import add_fork_hook
    reinit_tls = rffi.llexternal('PyThread_ReInitTLS', [], lltype.Void,
                                 compilation_info=eci)    
    add_fork_hook('child', reinit_tls)
Beispiel #13
0
def setup_init_functions(eci):
    init_buffer = rffi.llexternal('init_bufferobject', [],
                                  lltype.Void,
                                  compilation_info=eci)
    init_pycobject = rffi.llexternal('init_pycobject', [],
                                     lltype.Void,
                                     compilation_info=eci)
    init_capsule = rffi.llexternal('init_capsule', [],
                                   lltype.Void,
                                   compilation_info=eci)
    INIT_FUNCTIONS.extend([
        lambda space: init_buffer(),
        lambda space: init_pycobject(),
        lambda space: init_capsule(),
    ])
Beispiel #14
0
def test_func_not_in_clib():
    foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed)
    py.test.raises(NotImplementedError, foobar)

    foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                             libraries=['m'])    # math library
    py.test.raises(NotImplementedError, foobar)

    foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                             libraries=['m', 'z'])  # math and zlib libraries
    py.test.raises(NotImplementedError, foobar)

    foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                             libraries=['I_really_dont_exist_either'])
    py.test.raises(NotImplementedError, foobar)
Beispiel #15
0
    def test_qsort(self):
        CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT)
        qsort = rffi.llexternal(
            'qsort',
            [rffi.VOIDP, rffi.SIZE_T, rffi.SIZE_T,
             lltype.Ptr(CMPFUNC)], lltype.Void)

        lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10]
        A = lltype.Array(lltype.Signed, hints={'nolength': True})
        a = lltype.malloc(A, 10, flavor='raw')
        for i in range(10):
            a[i] = lst[i]

        SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))

        def my_compar(p1, p2):
            p1 = rffi.cast(SIGNEDPTR, p1)
            p2 = rffi.cast(SIGNEDPTR, p2)
            print 'my_compar:', p1[0], p2[0]
            return rffi.cast(rffi.INT, cmp(p1[0], p2[0]))

        qsort(rffi.cast(rffi.VOIDP, a), rffi.cast(rffi.SIZE_T, 10),
              rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)),
              llhelper(lltype.Ptr(CMPFUNC), my_compar))

        for i in range(10):
            print a[i],
        print
        lst.sort()
        for i in range(10):
            assert a[i] == lst[i]
        lltype.free(a, flavor='raw')
        assert not ALLOCATED  # detects memory leaks in the test
Beispiel #16
0
 def test_llexternal_source(self):
     eci = ExternalCompilationInfo(
         separate_module_sources = ["int fn() { return 42; }"]
     )
     fn = rffi.llexternal('fn', [], rffi.INT, compilation_info=eci)
     res = fn()
     assert res == 42
Beispiel #17
0
    def define_callback_simple(cls):
        c_source = py.code.Source("""
        int mystuff(int(*cb)(int, int))
        {
            return cb(40, 2) + cb(3, 4);
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        S = lltype.GcStruct('S', ('x', lltype.Signed))
        CALLBACK = lltype.FuncType([lltype.Signed, lltype.Signed],
                                   lltype.Signed)
        z = rffi.llexternal('mystuff', [lltype.Ptr(CALLBACK)], lltype.Signed,
                            compilation_info=eci)

        def mycallback(a, b):
            gc.collect()
            return a + b

        def f():
            p = lltype.malloc(S)
            p.x = 100
            result = z(mycallback)
            return result * p.x

        return f
Beispiel #18
0
 def install_dll(self, eci):
     """NOT_RPYTHON
     Called when the dll has been compiled"""
     if sys.platform == 'win32':
         self.get_pythonapi_handle = rffi.llexternal(
             'pypy_get_pythonapi_handle', [], DLLHANDLE,
             compilation_info=eci)
Beispiel #19
0
    def test_pass_around_t_object(self):
        from pypy.rpython.annlowlevel import base_ptr_lltype
        T = base_ptr_lltype()

        class X(object):
            _TYPE = T
            x = 10

        def callback(x):
            return x.x

        c_source = py.code.Source("""
        long eating_callback(void *arg, long(*call)(void*))
        {
            return call(arg);
        }
        """)

        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [T, rffi.CCallback([T], rffi.LONG)]
        eating_callback = rffi.llexternal('eating_callback',
                                          args,
                                          rffi.LONG,
                                          compilation_info=eci)

        res = eating_callback(X(), callback)
        assert res == 10
Beispiel #20
0
def external(name, args, result, eci=CConfig._compilation_info_):
    if _WIN and rffi.sizeof(rffi.TIME_T) == 8:
        # Recent Microsoft compilers use 64bit time_t and
        # the corresponding functions are named differently
        if rffi.TIME_T in args or rffi.TIME_TP in args or result in (rffi.TIME_T, rffi.TIME_TP):
            name = "_" + name + "64"
    return rffi.llexternal(name, args, result, compilation_info=eci, calling_conv=calling_conv, threadsafe=False)
    def test_pass_around_t_object(self):
        from pypy.rpython.annlowlevel import base_ptr_lltype
        T = base_ptr_lltype()
        
        class X(object):
            _TYPE = T
            x = 10

        def callback(x):
            return x.x

        c_source = py.code.Source("""
        int eating_callback(void *arg, int(*call)(int))
        {
            return call(arg);
        }
        """)

        eci = ExternalCompilationInfo(separate_module_sources=[c_source],
                                      export_symbols=['eating_callback'])

        args = [T, rffi.CCallback([T], rffi.INT)]
        eating_callback = rffi.llexternal('eating_callback', args, rffi.INT,
                                          compilation_info=eci)

        res = eating_callback(X(), callback)
        assert res == 10
Beispiel #22
0
    def test_llexternal_with_callback(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype

        class Abc:
            pass
        abc = Abc()

        FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
        z = llexternal('z', [lltype.Ptr(FUNC)], lltype.Signed)
        def g(n):
            abc.foobar = n
            return n + 1
        def f(x):
            return z(g)
        t, wa = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[0])
        assert len(result) == 1
        (struct, T, name), = result
        assert struct == "struct"
        assert name.endswith("foobar")
Beispiel #23
0
def llexternal(name, args, result, **kwds):
    return rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=eci,
                           _nowrapper=True,
                           **kwds)
Beispiel #24
0
    def test_llexternal(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype
        z = llexternal('z', [lltype.Signed], lltype.Signed)

        def f(x):
            return z(x)

        t, ra = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(fgraph.startblock.operations[0])
        assert not result

        z = lltype.functionptr(lltype.FuncType([lltype.Signed], lltype.Signed),
                               'foobar')

        def g(x):
            return z(x)

        t, ra = self.translate(g, [int])
        ggraph = graphof(t, g)

        assert ggraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(ggraph.startblock.operations[0])
        assert result
Beispiel #25
0
    def test_qsort(self):
        CMPFUNC = lltype.FuncType([rffi.VOIDP, rffi.VOIDP], rffi.INT)
        qsort = rffi.llexternal('qsort', [rffi.VOIDP,
                                          rffi.SIZE_T,
                                          rffi.SIZE_T,
                                          lltype.Ptr(CMPFUNC)],
                                lltype.Void)

        lst = [23, 43, 24, 324, 242, 34, 78, 5, 3, 10]
        A = lltype.Array(lltype.Signed, hints={'nolength': True})
        a = lltype.malloc(A, 10, flavor='raw')
        for i in range(10):
            a[i] = lst[i]

        SIGNEDPTR = lltype.Ptr(lltype.FixedSizeArray(lltype.Signed, 1))

        def my_compar(p1, p2):
            p1 = rffi.cast(SIGNEDPTR, p1)
            p2 = rffi.cast(SIGNEDPTR, p2)
            print 'my_compar:', p1[0], p2[0]
            return rffi.cast(rffi.INT, cmp(p1[0], p2[0]))

        qsort(rffi.cast(rffi.VOIDP, a),
              rffi.cast(rffi.SIZE_T, 10),
              rffi.cast(rffi.SIZE_T, llmemory.sizeof(lltype.Signed)),
              llhelper(lltype.Ptr(CMPFUNC), my_compar))

        for i in range(10):
            print a[i],
        print
        lst.sort()
        for i in range(10):
            assert a[i] == lst[i]
        lltype.free(a, flavor='raw')
        assert not ALLOCATED     # detects memory leaks in the test
Beispiel #26
0
def external(name, args, result, **kwds):
    return rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=eci,
                           sandboxsafe=True,
                           **kwds)
Beispiel #27
0
    def test_llexternal_with_callback(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype

        class Abc:
            pass
        abc = Abc()

        FUNC = lltype.FuncType([lltype.Signed], lltype.Signed)
        z = llexternal('z', [lltype.Ptr(FUNC)], lltype.Signed)
        def g(n):
            abc.foobar = n
            return n + 1
        def f(x):
            return z(g)
        t, wa = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = wa.analyze(fgraph.startblock.operations[0])
        assert len(result) == 1
        (struct, T, name), = result
        assert struct == "struct"
        assert name.endswith("foobar")
Beispiel #28
0
def setup_va_functions(eci):
    for name, TP in VA_TP_LIST.iteritems():
        name_no_star = process_va_name(name)
        func = rffi.llexternal('pypy_va_get_%s' % name_no_star, [VA_LIST_P],
                               TP,
                               compilation_info=eci)
        globals()['va_get_%s' % name_no_star] = func
Beispiel #29
0
def winexternal(name, args, result, **kwds):
    return rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=eci,
                           calling_conv='win',
                           **kwds)
Beispiel #30
0
    def configure_boehm_once(cls):
        """ Configure boehm only once, since we don't cache failures
        """
        if hasattr(cls, 'malloc_fn_ptr'):
            return cls.malloc_fn_ptr
        from pypy.rpython.tool import rffi_platform
        compilation_info = rffi_platform.configure_boehm()

        # Versions 6.x of libgc needs to use GC_local_malloc().
        # Versions 7.x of libgc removed this function; GC_malloc() has
        # the same behavior if libgc was compiled with
        # THREAD_LOCAL_ALLOC.
        class CConfig:
            _compilation_info_ = compilation_info
            HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc")
        config = rffi_platform.configure(CConfig)
        if config['HAS_LOCAL_MALLOC']:
            GC_MALLOC = "GC_local_malloc"
        else:
            GC_MALLOC = "GC_malloc"
        malloc_fn_ptr = rffi.llexternal(GC_MALLOC,
                                        [lltype.Signed], # size_t, but good enough
                                        llmemory.GCREF,
                                        compilation_info=compilation_info,
                                        sandboxsafe=True,
                                        _nowrapper=True)
        cls.malloc_fn_ptr = malloc_fn_ptr
        cls.compilation_info = compilation_info
        return malloc_fn_ptr
Beispiel #31
0
    def test_gcc_options(self):
        # check that the env var CC is correctly interpreted, even if
        # it contains the compiler name followed by some options.
        if sys.platform == 'win32':
            py.test.skip("only for gcc")

        from pypy.rpython.lltypesystem import lltype, rffi
        dir = udir.ensure('test_gcc_options', dir=1)
        dir.join('someextraheader.h').write('#define someextrafunc() 42\n')
        eci = ExternalCompilationInfo(includes=['someextraheader.h'])
        someextrafunc = rffi.llexternal('someextrafunc', [], lltype.Signed,
                                        compilation_info=eci)

        def entry_point(argv):
            return someextrafunc()

        old_cc = os.environ.get('CC')
        try:
            os.environ['CC'] = 'gcc -I%s' % dir
            t, cbuilder = self.compile(entry_point)
        finally:
            if old_cc is None:
                del os.environ['CC']
            else:
                os.environ['CC'] = old_cc
Beispiel #32
0
    def test_gcc_options(self):
        # check that the env var CC is correctly interpreted, even if
        # it contains the compiler name followed by some options.
        if sys.platform == 'win32':
            py.test.skip("only for gcc")

        from pypy.rpython.lltypesystem import lltype, rffi
        dir = udir.ensure('test_gcc_options', dir=1)
        dir.join('someextraheader.h').write('#define someextrafunc() 42\n')
        eci = ExternalCompilationInfo(includes=['someextraheader.h'])
        someextrafunc = rffi.llexternal('someextrafunc', [], lltype.Signed,
                                        compilation_info=eci)

        def entry_point(argv):
            return someextrafunc()

        old_cc = os.environ.get('CC')
        try:
            os.environ['CC'] = 'gcc -I%s' % dir
            t, cbuilder = self.compile(entry_point)
        finally:
            if old_cc is None:
                del os.environ['CC']
            else:
                os.environ['CC'] = old_cc
Beispiel #33
0
def winexternal(name, args, result, **kwargs):
    return rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=CConfig._compilation_info_,
                           calling_conv='win',
                           **kwargs)
Beispiel #34
0
def llexternal(name, ARGS, RESULT, **kwargs):
    return rffi.llexternal(name,
                           ARGS,
                           RESULT,
                           compilation_info=eci,
                           sandboxsafe=True,
                           **kwargs)
Beispiel #35
0
    def define_callback_simple(cls):
        c_source = py.code.Source("""
        int mystuff(int(*cb)(int, int))
        {
            return cb(40, 2) + cb(3, 4);
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        S = lltype.GcStruct('S', ('x', lltype.Signed))
        CALLBACK = lltype.FuncType([lltype.Signed, lltype.Signed],
                                   lltype.Signed)
        z = rffi.llexternal('mystuff', [lltype.Ptr(CALLBACK)],
                            lltype.Signed,
                            compilation_info=eci)

        def mycallback(a, b):
            gc.collect()
            return a + b

        def f():
            p = lltype.malloc(S)
            p.x = 100
            result = z(mycallback)
            return result * p.x

        return f
Beispiel #36
0
    def test_llexternal(self):
        from pypy.rpython.lltypesystem.rffi import llexternal
        from pypy.rpython.lltypesystem import lltype
        z = llexternal('z', [lltype.Signed], lltype.Signed)
        def f(x):
            return z(x)
        t, ra = self.translate(f, [int])
        fgraph = graphof(t, f)
        backend_optimizations(t)
        assert fgraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(fgraph.startblock.operations[0])
        assert not result

        z = lltype.functionptr(lltype.FuncType([lltype.Signed], lltype.Signed),
                               'foobar')
        def g(x):
            return z(x)
        t, ra = self.translate(g, [int])
        ggraph = graphof(t, g)

        assert ggraph.startblock.operations[0].opname == 'direct_call'

        result = ra.can_raise(ggraph.startblock.operations[0])
        assert result
Beispiel #37
0
def external(name, args, result):
    return rffi.llexternal(name,
                           args,
                           result,
                           compilation_info=CConfig._compilation_info_,
                           calling_conv=calling_conv,
                           threadsafe=False)
Beispiel #38
0
    def define_callback_simple(cls):
        import gc
        from pypy.rpython.lltypesystem import lltype, rffi
        from pypy.rpython.annlowlevel import llhelper
        from pypy.translator.tool.cbuild import ExternalCompilationInfo

        c_source = py.code.Source("""
        int mystuff(int(*cb)(int, int))
        {
            return cb(40, 2) + cb(3, 4);
        }
        """)
        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
        S = lltype.GcStruct('S', ('x', lltype.Signed))
        CALLBACK = lltype.FuncType([lltype.Signed, lltype.Signed],
                                   lltype.Signed)
        z = rffi.llexternal('mystuff', [lltype.Ptr(CALLBACK)], lltype.Signed,
                            compilation_info=eci)

        def mycallback(a, b):
            gc.collect()
            return a + b

        def f():
            p = lltype.malloc(S)
            p.x = 100
            result = z(mycallback)
            return result * p.x

        return f
Beispiel #39
0
def register_stat_variant(name):
    if sys.platform.startswith('win'):
        _functions = {
            'stat': '_stati64',
            'fstat': '_fstati64',
            'lstat': '_stati64'
        }  # no lstat on Windows
        c_func_name = _functions[name]
    elif sys.platform.startswith('linux'):
        # because we always use _FILE_OFFSET_BITS 64 - this helps things work that are not a c compiler
        _functions = {'stat': 'stat64', 'fstat': 'fstat64', 'lstat': 'lstat64'}
        c_func_name = _functions[name]
    else:
        c_func_name = name

    arg_is_path = (name != 'fstat')
    if arg_is_path:
        ARG1 = rffi.CCHARP
    else:
        ARG1 = rffi.INT
    os_mystat = rffi.llexternal(c_func_name, [ARG1, STAT_STRUCT],
                                rffi.INT,
                                compilation_info=compilation_info)

    def os_mystat_llimpl(arg):
        stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw')
        try:
            if arg_is_path:
                arg = rffi.str2charp(arg)
            error = rffi.cast(rffi.LONG, os_mystat(arg, stresult))
            if arg_is_path:
                rffi.free_charp(arg)
            if error != 0:
                raise OSError(rposix.get_errno(), "os_?stat failed")
            return build_stat_result(stresult)
        finally:
            lltype.free(stresult, flavor='raw')

    def fakeimpl(arg):
        st = getattr(os, name)(arg)
        fields = [TYPE for fieldname, TYPE in LL_STAT_FIELDS]
        TP = TUPLE_TYPE(fields)
        ll_tup = lltype.malloc(TP.TO)
        for i, (fieldname, TYPE) in enumerate(LL_STAT_FIELDS):
            val = getattr(st, fieldname)
            rffi.setintfield(ll_tup, 'item%d' % i, int(val))
        return ll_tup

    if arg_is_path:
        s_arg = str
    else:
        s_arg = int
    register_external(getattr(os, name), [s_arg],
                      s_StatResult,
                      "ll_os.ll_os_%s" % (name, ),
                      llimpl=func_with_new_name(os_mystat_llimpl,
                                                'os_%s_llimpl' % (name, )),
                      llfakeimpl=func_with_new_name(fakeimpl,
                                                    'os_%s_fake' % (name, )))
Beispiel #40
0
 def test_llexternal_source(self):
     eci = ExternalCompilationInfo(
         separate_module_sources=["int fn() { return 42; }"],
         export_symbols=['fn'],
     )
     fn = rffi.llexternal('fn', [], rffi.INT, compilation_info=eci)
     res = fn()
     assert res == 42
Beispiel #41
0
 def install_dll(self, eci):
     """NOT_RPYTHON
     Called when the dll has been compiled"""
     if sys.platform == 'win32':
         self.get_pythonapi_handle = rffi.llexternal(
             'pypy_get_pythonapi_handle', [],
             DLLHANDLE,
             compilation_info=eci)
Beispiel #42
0
def llexternal(name, args, res, _callable=None):
    return rffi.llexternal(name,
                           args,
                           res,
                           compilation_info=compilation_info,
                           sandboxsafe=True,
                           _nowrapper=True,
                           _callable=_callable)
Beispiel #43
0
 def __init__(self, rtyper, stats=None, translate_support_code=False,
              annmixlevel=None, gcdescr=None):
     self.rtyper = rtyper
     self.translate_support_code = translate_support_code
     self.compiled_functions = []
     self.fail_ops = []
     self.in_out_args = []
     if translate_support_code:
         get_size = llmemory.sizeof
     else:
         get_size = rffi.sizeof
     self._arraydescrs = [
         ArrayDescr(get_size(llmemory.GCREF), self.SIZE_GCPTR),    # 0
         ArrayDescr(get_size(lltype.Signed),  self.SIZE_INT),      # 1
         ArrayDescr(get_size(lltype.Char),    self.SIZE_CHAR),     # 2
         ArrayDescr(get_size(lltype.UniChar), self.SIZE_UNICHAR),  # 3
         ]
     self._descr_caches = {}
     self.fielddescr_vtable = self.fielddescrof(rclass.OBJECT, 'typeptr')
     if sys.maxint == 2147483647:
         self.size_of_int = 4
     else:
         self.size_of_int = 8
     if runicode.MAXUNICODE > 0xffff:
         self.size_of_unicode = 4
     else:
         self.size_of_unicode = 2
     self.gcarray_gcref   = lltype.GcArray(llmemory.GCREF)
     self.gcarray_signed  = lltype.GcArray(lltype.Signed)
     self.gcarray_char    = lltype.GcArray(lltype.Char)
     self.gcarray_unichar = lltype.GcArray(lltype.UniChar)
     basesize, _, ofs_length = symbolic.get_array_token(
         self.gcarray_signed, self.translate_support_code)
     self.array_index_array = basesize
     self.array_index_length = ofs_length
     basesize, _, ofs_length = symbolic.get_array_token(
         rstr.STR, self.translate_support_code)
     self.string_index_array = basesize
     self.string_index_length = ofs_length
     basesize, _, ofs_length = symbolic.get_array_token(
         rstr.UNICODE, self.translate_support_code)
     self.unicode_index_array = basesize
     self.unicode_index_length = ofs_length
     self.vtable_descr = self.fielddescrof(rclass.OBJECT, 'typeptr')
     self._ovf_error_instance = self._get_prebuilt_error(OverflowError)
     self._zer_error_instance = self._get_prebuilt_error(ZeroDivisionError)
     #
     # temporary (Boehm only)
     from pypy.translator.tool.cbuild import ExternalCompilationInfo
     compilation_info = ExternalCompilationInfo(libraries=['gc'])
     self.malloc_fn_ptr = rffi.llexternal("GC_malloc",
                                          [rffi.SIZE_T],
                                          llmemory.GCREF,
                                          compilation_info=compilation_info,
                                          sandboxsafe=True,
                                          _nowrapper=True)
     assert rffi.sizeof(rffi.SIZE_T) == self.size_of_int
Beispiel #44
0
 def proc_func(self, func):
     name = func.__name__
     arg_tps = [self.proc_tp(arg) for arg in func.argtypes]
     ll_item = rffi.llexternal(
         name, arg_tps,
         self.proc_tp(func.restype), 
         compilation_info=self.CConfig._compilation_info_)
     self.ns[name] = ll_item
     return ll_item
Beispiel #45
0
 def test_rand(self):
     eci = ExternalCompilationInfo(includes=['stdlib.h'])
     rand = rffi.llexternal('rand', [], rffi.INT,
                            compilation_info=eci)
     srand = rffi.llexternal('srand', [rffi.UINT], lltype.Void,
                             compilation_info=eci)
     srand(rffi.r_uint(123))
     res1 = rand()
     res2 = rand()
     res3 = rand()
     srand(rffi.r_uint(123))
     res1b = rand()
     res2b = rand()
     res3b = rand()
     assert res1 == res1b
     assert res2 == res2b
     assert res3 == res3b
     assert not ALLOCATED     # detects memory leaks in the test
Beispiel #46
0
 def test_rand(self):
     eci = ExternalCompilationInfo(includes=['stdlib.h'])
     rand = rffi.llexternal('rand', [], rffi.INT, compilation_info=eci)
     srand = rffi.llexternal('srand', [rffi.UINT],
                             lltype.Void,
                             compilation_info=eci)
     srand(rffi.r_uint(123))
     res1 = rand()
     res2 = rand()
     res3 = rand()
     srand(rffi.r_uint(123))
     res1b = rand()
     res2b = rand()
     res3b = rand()
     assert res1 == res1b
     assert res2 == res2b
     assert res3 == res3b
     assert not ALLOCATED  # detects memory leaks in the test
Beispiel #47
0
def register_stat_variant(name):
    if sys.platform.startswith('win'):
        _functions = {'stat':  '_stati64',
                      'fstat': '_fstati64',
                      'lstat': '_stati64'}    # no lstat on Windows
        c_func_name = _functions[name]
    elif sys.platform.startswith('linux'):
        # because we always use _FILE_OFFSET_BITS 64 - this helps things work that are not a c compiler 
        _functions = {'stat':  'stat64',
                      'fstat': 'fstat64',
                      'lstat': 'lstat64'}
        c_func_name = _functions[name]
    else:
        c_func_name = name

    arg_is_path = (name != 'fstat')
    if arg_is_path:
        ARG1 = rffi.CCHARP
    else:
        ARG1 = rffi.INT
    os_mystat = rffi.llexternal(c_func_name, [ARG1, STAT_STRUCT], rffi.INT,
                                compilation_info=compilation_info)

    def os_mystat_llimpl(arg):
        stresult = lltype.malloc(STAT_STRUCT.TO, flavor='raw')
        try:
            if arg_is_path:
                arg = rffi.str2charp(arg)
            error = rffi.cast(rffi.LONG, os_mystat(arg, stresult))
            if arg_is_path:
                rffi.free_charp(arg)
            if error != 0:
                raise OSError(rposix.get_errno(), "os_?stat failed")
            return build_stat_result(stresult)
        finally:
            lltype.free(stresult, flavor='raw')

    def fakeimpl(arg):
        st = getattr(os, name)(arg)
        fields = [TYPE for fieldname, TYPE in LL_STAT_FIELDS]
        TP = TUPLE_TYPE(fields)
        ll_tup = lltype.malloc(TP.TO)
        for i, (fieldname, TYPE) in enumerate(LL_STAT_FIELDS):
            val = getattr(st, fieldname)
            rffi.setintfield(ll_tup, 'item%d' % i, int(val))
        return ll_tup

    if arg_is_path:
        s_arg = str
    else:
        s_arg = int
    register_external(getattr(os, name), [s_arg], s_StatResult,
                      "ll_os.ll_os_%s" % (name,),
                      llimpl=func_with_new_name(os_mystat_llimpl,
                                                'os_%s_llimpl' % (name,)),
                      llfakeimpl=func_with_new_name(fakeimpl,
                                                    'os_%s_fake' % (name,)))
Beispiel #48
0
    def llexternal(self, *args, **kwds):
        kwds = kwds.copy()
        from pypy.rpython.lltypesystem import rffi

        if 'compilation_info' in kwds:
            kwds['compilation_info'] = self.compilation_info.merge(
                kwds['compilation_info'])
        else:
            kwds['compilation_info'] = self.compilation_info
        return rffi.llexternal(*args, **kwds)
Beispiel #49
0
    def llexternal(self, *args, **kwds):
        kwds = kwds.copy()
        from pypy.rpython.lltypesystem import rffi

        if 'compilation_info' in kwds:
            kwds['compilation_info'] = self.compilation_info.merge(
                kwds['compilation_info'])
        else:
            kwds['compilation_info'] = self.compilation_info
        return rffi.llexternal(*args, **kwds)
Beispiel #50
0
def external(name, args, result, calling_conv="c", **kwds):
    return rffi.llexternal(
        name,
        args,
        result,
        compilation_info=CConfig._compilation_info_,
        calling_conv=calling_conv,
        sandboxsafe=True,
        **kwds
    )
Beispiel #51
0
    def test_func_not_in_clib(self):
        eci = ExternalCompilationInfo(libraries=['m'])
        foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed)
        py.test.raises(NotImplementedError, foobar)

        foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                                 compilation_info=eci)    # math library
        py.test.raises(NotImplementedError, foobar)

        eci = ExternalCompilationInfo(libraries=['m', 'z'])
        foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                                 compilation_info=eci)  # math and zlib
        py.test.raises(NotImplementedError, foobar)

        eci = ExternalCompilationInfo(libraries=['I_really_dont_exist_either'])
        foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                                 compilation_info=eci)
        py.test.raises(NotImplementedError, foobar)
        assert not ALLOCATED     # detects memory leaks in the test
Beispiel #52
0
 def proc_func(self, func):
     name = func.__name__
     arg_tps = [self.proc_tp(arg) for arg in func.argtypes]
     ll_item = rffi.llexternal(
         name,
         arg_tps,
         self.proc_tp(func.restype),
         compilation_info=self.CConfig._compilation_info_)
     self.ns[name] = ll_item
     return ll_item
Beispiel #53
0
def setup_init_functions(eci):
    init_buffer = rffi.llexternal('init_bufferobject', [],
                                  lltype.Void,
                                  compilation_info=eci)
    init_pycobject = rffi.llexternal('init_pycobject', [],
                                     lltype.Void,
                                     compilation_info=eci)
    init_capsule = rffi.llexternal('init_capsule', [],
                                   lltype.Void,
                                   compilation_info=eci)
    INIT_FUNCTIONS.extend([
        lambda space: init_buffer(),
        lambda space: init_pycobject(),
        lambda space: init_capsule(),
    ])
    from pypy.module.posix.interp_posix import add_fork_hook
    reinit_tls = rffi.llexternal('PyThread_ReInitTLS', [],
                                 lltype.Void,
                                 compilation_info=eci)
    add_fork_hook('child', reinit_tls)
Beispiel #54
0
def external(name, args, result, eci=CConfig._compilation_info_):
    if _WIN and rffi.sizeof(rffi.TIME_T) == 8:
        # Recent Microsoft compilers use 64bit time_t and
        # the corresponding functions are named differently
        if (rffi.TIME_T in args or rffi.TIME_TP in args
            or result in (rffi.TIME_T, rffi.TIME_TP)):
            name = '_' + name + '64'
    return rffi.llexternal(name, args, result,
                           compilation_info=eci,
                           calling_conv=calling_conv,
                           threadsafe=False)
Beispiel #55
0
def test_strlen():
    strlen = rffi.llexternal('strlen', [rffi.CCHARP], lltype.Signed,
                             includes=['string.h'])
    s = rffi.str2charp("xxx")
    res = strlen(s)
    rffi.free_charp(s)
    assert res == 3
    s = rffi.str2charp("")
    res = strlen(s)
    rffi.free_charp(s)
    assert res == 0
Beispiel #56
0
    def __init__(self, translator, inline=False):
        super(BoehmGCTransformer, self).__init__(translator, inline=inline)
        self.finalizer_funcptrs = {}

        atomic_mh = mallocHelpers()
        atomic_mh.allocate = lambda size: llop.boehm_malloc_atomic(llmemory.Address, size)
        ll_malloc_fixedsize_atomic = atomic_mh._ll_malloc_fixedsize

        mh = mallocHelpers()
        mh.allocate = lambda size: llop.boehm_malloc(llmemory.Address, size)
        c_realloc = rffi.llexternal('GC_REALLOC', [rffi.VOIDP, rffi.INT],
                                    rffi.VOIDP, sandboxsafe=True)
        def _realloc(ptr, size):
            return llmemory.cast_ptr_to_adr(c_realloc(rffi.cast(rffi.VOIDP, ptr), size))
        mh.realloc = _realloc
        ll_malloc_fixedsize = mh._ll_malloc_fixedsize

        # XXX, do we need/want an atomic version of this function?
        ll_malloc_varsize_no_length = mh.ll_malloc_varsize_no_length
        ll_malloc_varsize = mh.ll_malloc_varsize

        ll_realloc = mh.ll_realloc

        HDRPTR = lltype.Ptr(self.HDR)

        def ll_identityhash(addr):
            obj = llmemory.cast_adr_to_ptr(addr, HDRPTR)
            h = obj.hash
            if h == 0:
                obj.hash = h = ~llmemory.cast_adr_to_int(addr)
            return h

        if self.translator:
            self.malloc_fixedsize_ptr = self.inittime_helper(
                ll_malloc_fixedsize, [lltype.Signed], llmemory.Address)
            self.malloc_fixedsize_atomic_ptr = self.inittime_helper(
                ll_malloc_fixedsize_atomic, [lltype.Signed], llmemory.Address)
            self.malloc_varsize_no_length_ptr = self.inittime_helper(
                ll_malloc_varsize_no_length, [lltype.Signed]*3, llmemory.Address, inline=False)
            self.malloc_varsize_ptr = self.inittime_helper(
                ll_malloc_varsize, [lltype.Signed]*4, llmemory.Address, inline=False)
            self.weakref_create_ptr = self.inittime_helper(
                ll_weakref_create, [llmemory.Address], llmemory.WeakRefPtr,
                inline=False)
            self.weakref_deref_ptr = self.inittime_helper(
                ll_weakref_deref, [llmemory.WeakRefPtr], llmemory.Address)
            self.realloc_ptr = self.inittime_helper(
                ll_realloc, [llmemory.Address] + [lltype.Signed] * 4,
                llmemory.Address)
            self.identityhash_ptr = self.inittime_helper(
                ll_identityhash, [llmemory.Address], lltype.Signed,
                inline=False)
            self.mixlevelannotator.finish()   # for now
            self.mixlevelannotator.backend_optimize()
Beispiel #57
0
def new_unary_math_function(name):
    c_func = rffi.llexternal(name, [rffi.DOUBLE], rffi.DOUBLE,
                             compilation_info=eci, sandboxsafe=True)

    def ll_math(x):
        _error_reset()
        r = c_func(x)
        _check_error(r)
        return r

    return func_with_new_name(ll_math, 'll_math_' + name)
Beispiel #58
0
    def configure_boehm_once(cls):
        """ Configure boehm only once, since we don't cache failures
        """
        if hasattr(cls, 'malloc_fn_ptr'):
            return cls.malloc_fn_ptr
        from pypy.rpython.tool import rffi_platform
        compilation_info = rffi_platform.configure_boehm()

        # on some platform GC_init is required before any other
        # GC_* functions, call it here for the benefit of tests
        # XXX move this to tests
        init_fn_ptr = rffi.llexternal("GC_init", [],
                                      lltype.Void,
                                      compilation_info=compilation_info,
                                      sandboxsafe=True,
                                      _nowrapper=True)
        init_fn_ptr()

        # Versions 6.x of libgc needs to use GC_local_malloc().
        # Versions 7.x of libgc removed this function; GC_malloc() has
        # the same behavior if libgc was compiled with
        # THREAD_LOCAL_ALLOC.
        class CConfig:
            _compilation_info_ = compilation_info
            HAS_LOCAL_MALLOC = rffi_platform.Has("GC_local_malloc")

        config = rffi_platform.configure(CConfig)
        if config['HAS_LOCAL_MALLOC']:
            GC_MALLOC = "GC_local_malloc"
        else:
            GC_MALLOC = "GC_malloc"
        malloc_fn_ptr = rffi.llexternal(
            GC_MALLOC,
            [lltype.Signed],  # size_t, but good enough
            llmemory.GCREF,
            compilation_info=compilation_info,
            sandboxsafe=True,
            _nowrapper=True)
        cls.malloc_fn_ptr = malloc_fn_ptr
        return malloc_fn_ptr