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

ac at codespeak.net ac at codespeak.net
Sun Nov 5 12:28:25 CET 2006


Author: ac
Date: Sun Nov  5 12:28:21 2006
New Revision: 34225

Modified:
   pypy/dist/pypy/rpython/rctypes/avoid_p.py
   pypy/dist/pypy/rpython/rctypes/rchar_p.py
   pypy/dist/pypy/rpython/rctypes/rmodel.py
   pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
Log:
Support ctypes.cast to and from c_char_p.

Modified: pypy/dist/pypy/rpython/rctypes/avoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/avoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/avoid_p.py	Sun Nov  5 12:28:21 2006
@@ -48,7 +48,8 @@
     _about_ = cast
 
     def checkptr(self, ctype):
-        assert (isinstance(ctype, PointerType) or ctype == c_void_p or
+        assert (isinstance(ctype, PointerType) or
+                ctype in (c_void_p, c_char_p) or
                 isinstance(ctype, CFuncPtrType)), (
             "cast(): can only cast between pointers so far, not %r" % (ctype,))
 
@@ -67,6 +68,7 @@
     def specialize_call(self, hop):
         from pypy.rpython.rctypes.rpointer import PointerRepr
         from pypy.rpython.rctypes.rvoid_p import CVoidPRepr
+        from pypy.rpython.rctypes.rchar_p import CCharPRepr
         from pypy.rpython.rctypes.rstringbuf import StringBufRepr
         from pypy.rpython.rctypes.rfunc import CFuncPtrRepr
         from pypy.rpython.lltypesystem import lltype, llmemory
@@ -76,7 +78,7 @@
             # to become a general non-constant SomeCTypesObject
             s_arg = hop.args_s[0].normalized()
             r_arg = hop.rtyper.getrepr(s_arg)
-        assert isinstance(r_arg, (PointerRepr, CVoidPRepr,
+        assert isinstance(r_arg, (PointerRepr, CVoidPRepr, CCharPRepr,
                                   StringBufRepr, CFuncPtrRepr))
         targetctype = hop.args_s[1].const
         v_box, c_targetctype = hop.inputargs(r_arg, lltype.Void)
@@ -97,4 +99,4 @@
             v_result = hop.genop('cast_adr_to_ptr', [v_adr],
                                  resulttype = hop.r_result.ll_type)
         hop.exception_cannot_occur()
-        return hop.r_result.return_value(hop.llops, v_result)
+        return hop.r_result.cast_return_value(hop.llops, v_result)

Modified: pypy/dist/pypy/rpython/rctypes/rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rchar_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rchar_p.py	Sun Nov  5 12:28:21 2006
@@ -24,6 +24,10 @@
         # field instead of the c_data pointer
         return llops.gendirectcall(ll_charp2str, v_value)
 
+    def cast_return_value(self, llops, v_value):
+        # This should not return a string but a char pointer
+        return CTypesValueRepr.return_value(self, llops, v_value)
+
     def get_content_keepalive_type(self):
         "An extra keepalive used for the RPython string."
         return string_repr.lowleveltype

Modified: pypy/dist/pypy/rpython/rctypes/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/rmodel.py	Sun Nov  5 12:28:21 2006
@@ -245,6 +245,10 @@
         r_temp.setvalue(llops, v_owned_box, v_value)
         return llops.convertvar(v_owned_box, r_temp, self)
 
+    def cast_return_value(self, llops, v_value):
+        # like return_value(), but used for the cast function
+        return self.return_value(llops, v_value)
+
     def rtype_is_true(self, hop):
         [v_box] = hop.inputargs(self)
         v_value = self.getvalue(hop.llops, v_box)

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py	Sun Nov  5 12:28:21 2006
@@ -12,7 +12,7 @@
 from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.test.test_llinterp import interpret
 
-from ctypes import c_void_p, c_int, c_long, cast, pointer, POINTER
+from ctypes import c_void_p, c_int, c_long, cast, pointer, POINTER, c_ubyte
 from ctypes import c_char, c_byte, c_char_p, create_string_buffer, CFUNCTYPE
 
 class Test_annotation:
@@ -53,6 +53,25 @@
         s = a.build_types(fn, [])
         assert s.knowntype == c_void_p
 
+    def test_annotate_c_char_p(self):
+        def fn():
+            x = c_int(12)
+            p1 = cast(pointer(x), c_char_p)
+            p2 = cast(p1, POINTER(c_int))
+            assert p2.contents.value == 12
+            return p1, p2
+
+        t = TranslationContext()
+        a = t.buildannotator()
+        s = a.build_types(fn, [])
+        assert s.items[0].knowntype == c_char_p
+        assert s.items[1].knowntype == POINTER(c_int)
+
+        if conftest.option.view:
+            t.view()
+
+   
+
 class Test_specialization:
     def test_specialize_c_void_p(self):
         def func():
@@ -65,6 +84,18 @@
         assert lltype.typeOf(res.item0.c_data[0]) == llmemory.Address
         assert res.item1 == 12
 
+    def test_specialize_c_char_p(self):
+        py.test.skip("LLinterp is grumpy about converting between pointers pointing to different types of data.")
+        def func():
+            x = c_int(12)
+            p1 = cast(pointer(x), c_char_p)
+            p2 = cast(p1, POINTER(c_int))
+            return p1, p2.contents.value
+
+        res = interpret(func, [])
+        assert lltype.typeOf(res.item0.c_data[0]) == llmemory.Address
+        assert res.item1 == 12
+
     def test_truth_value(self):
         def func():
             assert not c_void_p()
@@ -118,7 +149,7 @@
         assert lltype.typeOf(res) == lltype.Signed    # xxx
 
 class Test_compilation:
-    def test_compile_c_char_p(self):
+    def test_compile_c_void_p(self):
         def func():
             x = c_int(12)
             p1 = cast(pointer(x), c_void_p)
@@ -128,6 +159,16 @@
         fn = compile(func, [])
         assert fn() == 12
 
+    def test_compile_c_char_p(self):
+        def func():
+            x = c_ubyte(12)
+            p1 = cast(pointer(x), c_char_p)
+            p2 = cast(p1, POINTER(c_ubyte))
+            return p2.contents.value
+
+        fn = compile(func, [])
+        assert fn() == 12
+
     def test_compile_funcptr_as_void_p(self):
         from pypy.rpython.rctypes.test.test_rfunc import labs
         UNARYFN = CFUNCTYPE(c_long, c_long)



More information about the Pypy-commit mailing list