[pypy-svn] r59949 - in pypy/branch/oo-jit/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Sun Nov 16 19:41:19 CET 2008


Author: arigo
Date: Sun Nov 16 19:41:18 2008
New Revision: 59949

Modified:
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
ll2ctypes: passing void argument, done better.


Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/branch/oo-jit/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/ll2ctypes.py	Sun Nov 16 19:41:18 2008
@@ -169,7 +169,8 @@
 def build_new_ctypes_type(T, delayed_builders):
     if isinstance(T, lltype.Ptr):
         if isinstance(T.TO, lltype.FuncType):
-            argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS]
+            argtypes = [get_ctypes_type(ARG) for ARG in T.TO.ARGS
+                                             if ARG is not lltype.Void]
             if T.TO.RESULT is lltype.Void:
                 restype = None
             else:
@@ -441,8 +442,13 @@
                 raise NotImplementedError("ctypes wrapper for ll function "
                                           "without a _callable")
             else:
+                v1list = [i for i in range(len(T.TO.ARGS))
+                            if T.TO.ARGS[i] is lltype.Void]
                 ctypes_func_type = get_ctypes_type(T)
                 def callback(*cargs):
+                    cargs = list(cargs)
+                    for v1 in v1list:
+                        cargs.insert(v1, None)
                     assert len(cargs) == len(T.TO.ARGS)
                     llargs = [ctypes2lltype(ARG, carg)
                               for ARG, carg in zip(T.TO.ARGS, cargs)]
@@ -494,14 +500,6 @@
 
     return llobj
 
-_void_const_cache = {}
-
-def register_void_value(value):
-    res = len(_void_const_cache) + 1
-    # we start at one to avoid nasty bugs passing unregistered 0es around
-    _void_const_cache[res] = value
-    return res
-
 def ctypes2lltype(T, cobj):
     """Convert the ctypes object 'cobj' to its lltype equivalent.
     'T' is the expected lltype type.
@@ -543,10 +541,7 @@
             cobj = cobj.value
         llobj = r_singlefloat(cobj)
     elif T is lltype.Void:
-        if cobj is None:
-            llobj = cobj
-        else:
-            return _void_const_cache[cobj]
+        llobj = cobj
     else:
         from pypy.rpython.lltypesystem import rffi
         try:
@@ -644,7 +639,8 @@
             funcname, place))
 
     # get_ctypes_type() can raise NotImplementedError too
-    cfunc.argtypes = [get_ctypes_type(T) for T in FUNCTYPE.ARGS]
+    cfunc.argtypes = [get_ctypes_type(T) for T in FUNCTYPE.ARGS
+                                         if T is not lltype.Void]
     if FUNCTYPE.RESULT is lltype.Void:
         cfunc.restype = None
     else:
@@ -674,10 +670,18 @@
     for i in range(len(FUNCTYPE.ARGS)):
         if isinstance(FUNCTYPE.ARGS[i], lltype.ContainerType):
             container_arguments.append(i)
+    void_arguments = []
+    for i in range(len(FUNCTYPE.ARGS)):
+        if FUNCTYPE.ARGS[i] == lltype.Void:
+            void_arguments.append(i)
     def invoke_via_ctypes(*argvalues):
-        cargs = [lltype2ctypes(value) for value in argvalues]
-        for i in container_arguments:
-            cargs[i] = cargs[i].contents
+        cargs = []
+        for i in range(len(FUNCTYPE.ARGS)):
+            if i not in void_arguments:
+                cvalue = lltype2ctypes(argvalues[i])
+                for i in container_arguments:
+                    cvalue = cvalue.contents
+                cargs.append(cvalue)
         _restore_c_errno()
         cres = cfunc(*cargs)
         _save_c_errno()

Modified: pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/branch/oo-jit/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Sun Nov 16 19:41:18 2008
@@ -6,7 +6,7 @@
 from pypy.rpython.lltypesystem.ll2ctypes import lltype2ctypes, ctypes2lltype
 from pypy.rpython.lltypesystem.ll2ctypes import standard_c_lib
 from pypy.rpython.lltypesystem.ll2ctypes import uninitialized2ctypes
-from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED, register_void_value
+from pypy.rpython.lltypesystem.ll2ctypes import ALLOCATED
 from pypy.rpython.annlowlevel import llhelper
 from pypy.rlib import rposix
 from pypy.translator.tool.cbuild import ExternalCompilationInfo
@@ -759,31 +759,31 @@
 
         assert f() == 6
 
-    def test_c_callback_with_void_arg(self):
-        class Stuff(object):
-            def __init__(self, x):
-                self.x = x
+##    def test_c_callback_with_void_arg(self):
+##        class Stuff(object):
+##            def __init__(self, x):
+##                self.x = x
+
+##        c_source = py.code.Source("""
+##        int eating_callback(int arg, int voidarg, int(*call)(int, int))
+##        {
+##            return call(arg, voidarg);
+##        }
+##        """)
 
-        c_source = py.code.Source("""
-        int eating_callback(int arg, int voidarg, int(*call)(int, int))
-        {
-            return call(arg, voidarg);
-        }
-        """)
+##        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
 
-        eci = ExternalCompilationInfo(separate_module_sources=[c_source])
+##        args = [rffi.INT, rffi.INT,
+##                rffi.CCallback([rffi.INT, lltype.Void], rffi.INT)]
 
-        args = [rffi.INT, rffi.INT,
-                rffi.CCallback([rffi.INT, lltype.Void], rffi.INT)]
-
-        def callback(x, stuff):
-            return x + stuff.x
+##        def callback(x, stuff):
+##            return x + stuff.x
         
-        eating_callback = rffi.llexternal('eating_callback', args, rffi.INT,
-                                          compilation_info=eci)
+##        eating_callback = rffi.llexternal('eating_callback', args, rffi.INT,
+##                                          compilation_info=eci)
 
-        v = register_void_value(Stuff(2))
-        assert eating_callback(3, v, callback) == 3+2
+##        v = register_void_value(Stuff(2))
+##        assert eating_callback(3, v, callback) == 3+2
 
     def test_qsort(self):
         TP = rffi.CArrayPtr(rffi.INT)
@@ -864,3 +864,15 @@
         assert a1[0] == 48
         lltype.free(a1, flavor='raw')
         assert not ALLOCATED     # detects memory leaks in the test
+
+    def test_c_callback_with_void_arg_2(self):
+        ftest = []
+        def f(x):
+            ftest.append(x)
+        F = lltype.FuncType([lltype.Void], lltype.Void)
+        fn = lltype.functionptr(F, 'askjh', _callable=f)
+        fn(None)
+        assert ftest == [None]
+        fn2 = lltype2ctypes(fn)
+        fn2()
+        assert ftest == [None, None]



More information about the Pypy-commit mailing list