[pypy-svn] r26546 - in pypy/dist/pypy/rpython/rctypes: . test

ac at codespeak.net ac at codespeak.net
Sat Apr 29 04:46:23 CEST 2006


Author: ac
Date: Sat Apr 29 04:46:22 2006
New Revision: 26546

Modified:
   pypy/dist/pypy/rpython/rctypes/rvoid_p.py
   pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
Log:
(aleale, arre)
Support calling a function taking a c_void_p with a stringbuffer.



Modified: pypy/dist/pypy/rpython/rctypes/rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rvoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rvoid_p.py	Sat Apr 29 04:46:22 2006
@@ -1,5 +1,30 @@
-from pypy.rpython.rctypes.rmodel import CTypesValueRepr
-
+from pypy.rpython.rctypes.rmodel import CTypesValueRepr, C_ZERO
+from pypy.rpython.rctypes.rstringbuf import StringBufRepr
+from pypy.annotation.pairtype import pairtype
+from pypy.rpython.rctypes.rchar_p import CCharPRepr
+from pypy.rpython.lltypesystem import llmemory
 
 class CVoidPRepr(CTypesValueRepr):
     pass  # No operations supported on c_void_p instances so far
+
+class __extend__(pairtype(StringBufRepr, CVoidPRepr)):
+    def convert_from_to((r_from, r_to), v, llops):
+        # warning: no keepalives, only for short-lived conversions like
+        # in argument passing
+        r_temp = r_to.r_memoryowner
+        v_owned_box = r_temp.allocate_instance(llops)
+        v_c_array = r_from.get_c_data_of_item(llops, v, C_ZERO)
+        v_adr = llops.genop('cast_ptr_to_adr', [v_c_array],
+                            resulttype = llmemory.Address)
+        r_temp.setvalue(llops, v_owned_box, v_adr)
+        return llops.convertvar(v_owned_box, r_temp, r_to)
+        # XXX some code duplication above
+
+class __extend__(pairtype(CCharPRepr, CVoidPRepr)):
+    def convert_from_to((r_from, r_to), v, llops):
+        v_ptr = r_from.getvalue(llops, v)
+        v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
+                            resulttype = llmemory.Address)
+                            
+        return r_to.return_value(llops, v_adr)
+

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rfunc.py	Sat Apr 29 04:46:22 2006
@@ -11,10 +11,11 @@
 from pypy.translator.c.test.test_genc import compile
 from pypy import conftest
 from pypy.rpython.lltypesystem.rstr import string_repr
-from pypy.rpython.lltypesystem import lltype
+from pypy.rpython.lltypesystem import lltype, llmemory
 
 from ctypes import cdll, pythonapi, PyDLL, _FUNCFLAG_PYTHONAPI
-from ctypes import c_int, c_long, c_char_p, c_char, create_string_buffer
+from ctypes import c_int, c_long, c_char_p, c_void_p, c_char
+from ctypes import create_string_buffer, cast
 from ctypes import POINTER, py_object, byref, Structure
 from pypy.rpython.rctypes.tool import util      # ctypes.util from 0.9.9.6
 
@@ -63,6 +64,18 @@
 ##PyIntIntCallback = CALLBACK_FUNCTYPE(c_int, c_int, callconv=PyDLL)
 ##pycallback = PyIntIntCallback(mycallback)
 
+def ll_memcpy(dst, src, length):
+    C_ARRAY = lltype.Ptr(lltype.FixedSizeArray(lltype.Char, 1))
+    c_src = llmemory.cast_adr_to_ptr(src, C_ARRAY)
+    c_dst = llmemory.cast_adr_to_ptr(dst, C_ARRAY)
+    for i in range(length):
+        c_dst[i] = c_src[i]
+    return dst
+
+memcpy = mylib.memcpy
+memcpy.argtypes = [c_void_p, c_void_p, c_long]
+memcpy.restype = c_void_p
+memcpy.llinterp_friendly_version = ll_memcpy
 
 def test_labs(n=6):
     assert labs(n) == abs(n)
@@ -159,6 +172,18 @@
         a.build_types(ep, [])
         if conftest.option.view:
             a.translator.view()
+    def test_annotate_call_void_p_arg_with_stringbuf(self):
+        string = 'abc xyz'
+        def f(x):
+            buf = create_string_buffer(len(string) + 1)
+            res = memcpy(buf, string, len(string))
+            return buf.value
+        a = RPythonAnnotator()
+        s = a.build_types(f, [int])
+        if conftest.option.view:
+            a.translator.view()
+        assert s.knowntype == str
+        
 
 ##    def test_annotate_callback(self):
 ##        def fn(n):
@@ -232,6 +257,17 @@
         res = interpret(fn, [11])
         assert res == 42
 
+    def test_specialize_call_void_p_arg_with_stringbuf(self):
+        string = 'abc xyz'
+        def f():
+            buf = create_string_buffer(len(string) + 1)
+            res = memcpy(buf, c_char_p(string), len(string))
+            return buf.value
+        assert f() == string
+        res = interpret(f, [])
+        assert ''.join(res.chars) == string
+        
+
 class Test_compile:
     def test_compile_labs(self):
         fn = compile(test_labs, [int])
@@ -300,3 +336,14 @@
         s1 = time.ctime(N)
         s2 = fn(N)
         assert s1.strip() == s2.strip()
+
+    def test_compile_call_void_p_arg_with_stringbuf(self):
+        string = 'abc xyz'
+        def f():
+            buf = create_string_buffer(len(string) + 1)
+            res = memcpy(buf, c_char_p(string), len(string))
+            return buf.value
+        assert f() == string
+        fn = compile(f, [])
+        assert fn() == string
+        



More information about the Pypy-commit mailing list