Author: Armin Rigo <[email protected]>
Branch: 
Changeset: r92574:ace97c304a30
Date: 2017-10-02 12:33 +0200
http://bitbucket.org/pypy/pypy/changeset/ace97c304a30/

Log:    (antocuni, arigo)

        More.

diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py 
b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -817,7 +817,7 @@
             if isinstance(T.TO, lltype.FuncType):
                 if hasattr(llobj._obj0, '_real_integer_addr'):
                     ctypes_func_type = get_ctypes_type(T)
-                    return ctypes.cast(llobj._obj0._real_integer_addr,
+                    return ctypes.cast(llobj._obj0._real_integer_addr(),
                                        ctypes_func_type)
                 # XXX a temporary workaround for comparison of lltype.FuncType
                 key = llobj._obj.__dict__.copy()
@@ -1044,7 +1044,7 @@
                     _callable = get_ctypes_trampoline(T.TO, cobj)
                     return lltype.functionptr(T.TO, name,
                                               _callable=_callable,
-                                              _real_integer_addr=cobjkey)
+                                          _real_integer_addr=lambda: cobjkey)
             elif isinstance(T.TO, lltype.OpaqueType):
                 if T == llmemory.GCREF:
                     container = _llgcopaque(cobj)
@@ -1302,6 +1302,10 @@
         # perform the call
         return self.trampoline(*argvalues)
 
+    def get_real_address(self):
+        cfunc = get_ctypes_callable(self.funcptr, self.calling_conv)
+        return ctypes.cast(cfunc, ctypes.c_void_p).value
+
 def get_ctypes_trampoline(FUNCTYPE, cfunc):
     RESULT = FUNCTYPE.RESULT
     container_arguments = []
diff --git a/rpython/rtyper/lltypesystem/rffi.py 
b/rpython/rtyper/lltypesystem/rffi.py
--- a/rpython/rtyper/lltypesystem/rffi.py
+++ b/rpython/rtyper/lltypesystem/rffi.py
@@ -145,6 +145,9 @@
         # Also, _nowrapper functions cannot release the GIL, by default.
         invoke_around_handlers = not sandboxsafe and not _nowrapper
 
+    if _nowrapper and isinstance(_callable, ll2ctypes.LL2CtypesCallable):
+        kwds['_real_integer_addr'] = _callable.get_real_address
+
     if random_effects_on_gcobjs not in (False, True):
         random_effects_on_gcobjs = (
             invoke_around_handlers or   # because it can release the GIL
diff --git a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py 
b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/test/test_ll2ctypes.py
@@ -1449,6 +1449,25 @@
         assert lltype.typeOf(f) == PtrF
         assert rffi.cast(lltype.Signed, f) == 42
 
+    def test_keep_value_across_rffi_llexternal(self):
+        c_source = py.code.Source(r"""
+            void ff1(void) { }
+            void *get_ff1(void) { return &ff1; }
+        """)
+        eci = ExternalCompilationInfo(
+            separate_module_sources=[c_source],
+            post_include_bits = [
+                "RPY_EXTERN void ff1(void); RPY_EXTERN void *get_ff1(void);"])
+        PtrFF1 = lltype.Ptr(lltype.FuncType([], lltype.Void))
+        f1 = rffi.llexternal('ff1', [], lltype.Void, compilation_info=eci,
+                             _nowrapper=True)
+        assert lltype.typeOf(f1) == PtrFF1
+        getff1 = rffi.llexternal('get_ff1', [], PtrFF1, compilation_info=eci,
+                                 _nowrapper=True)
+        f2 = getff1()
+        assert rffi.cast(lltype.Signed, f2) == rffi.cast(lltype.Signed, f1)
+        #assert f2 == f1  -- fails, would be nice but oh well
+
 
 class TestPlatform(object):
     def test_lib_on_libpaths(self):
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to