[pypy-svn] r26577 - in pypy/dist/pypy/rpython: lltypesystem rctypes rctypes/test

arigo at codespeak.net arigo at codespeak.net
Sat Apr 29 16:11:28 CEST 2006


Author: arigo
Date: Sat Apr 29 16:11:26 2006
New Revision: 26577

Modified:
   pypy/dist/pypy/rpython/lltypesystem/llmemory.py
   pypy/dist/pypy/rpython/rctypes/rchar_p.py
   pypy/dist/pypy/rpython/rctypes/rvoid_p.py
   pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
   pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
   pypy/dist/pypy/rpython/rctypes/test/test_rvoid_p.py
Log:
Some more conversions to c_char_p and c_void_p.


Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py	Sat Apr 29 16:11:26 2006
@@ -267,6 +267,13 @@
 class _char_fakeaccessor(_fakeaccessor):
     TYPE = lltype.Char
 
+    def convert(self, value):
+        # hack to try to interpret the items of an array of bytes as chars
+        if lltype.typeOf(value) == lltype.Signed:
+            value = chr(value)
+        assert lltype.typeOf(value) == lltype.Char
+        return value
+
 class _address_fakeaccessor(_fakeaccessor):
     TYPE = Address
 

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	Sat Apr 29 16:11:26 2006
@@ -7,7 +7,7 @@
 from pypy.rpython.rctypes.rstringbuf import StringBufRepr
 from pypy.annotation.pairtype import pairtype
 
-from ctypes import c_char, c_char_p
+from ctypes import c_char, c_char_p, cast
 
 
 class CCharPRepr(CTypesValueRepr):
@@ -34,6 +34,13 @@
     def setstring(self, llops, v_box, v_str):
         llops.gendirectcall(ll_setstring, v_box, v_str)
 
+    def convert_const(self, value):
+        if not isinstance(value, (str, c_char_p)):
+            # maybe an array of characters? cast to a c_char_p
+            assert type(value)._type_ == c_char
+            value = cast(value, c_char_p)
+        return super(CCharPRepr, self).convert_const(value)
+
     def initialize_const(self, p, string):
         if isinstance(string, c_char_p):
             string = string.value

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 16:11:26 2006
@@ -1,27 +1,22 @@
 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.rstr import AbstractStringRepr
+from pypy.rpython.lltypesystem.rstr import string_repr
 from pypy.rpython.rctypes.rchar_p import CCharPRepr
-from pypy.rpython.lltypesystem import llmemory
+from pypy.rpython.lltypesystem import lltype, llmemory
 from pypy.rpython.rctypes.rpointer import PointerRepr
+from pypy.rpython.rctypes.rarray import ArrayRepr
 
 class CVoidPRepr(CTypesValueRepr):
-    pass  # No operations supported on c_void_p instances so far
+    def convert_const(self, value):
+        if isinstance(value, self.ctype):
+            return super(CVoidPRepr, self).convert_const(value)
+        raise NotImplementedError("XXX constant pointer passed to void* arg")
 
-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)):
+class __extend__(pairtype(CCharPRepr, CVoidPRepr),
+                 pairtype(PointerRepr, 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],
@@ -29,11 +24,27 @@
                             
         return r_to.return_value(llops, v_adr)
 
-class __extend__(pairtype(PointerRepr, CVoidPRepr)):
+class __extend__(pairtype(StringBufRepr, CVoidPRepr),
+                 pairtype(ArrayRepr, CVoidPRepr)):
     def convert_from_to((r_from, r_to), v, llops):
-        v_ptr = r_from.getvalue(llops, v)
+        v_ptr = r_from.get_c_data_of_item(llops, v, C_ZERO)
         v_adr = llops.genop('cast_ptr_to_adr', [v_ptr],
                             resulttype = llmemory.Address)
                             
         return r_to.return_value(llops, v_adr)
 
+class __extend__(pairtype(AbstractStringRepr, CVoidPRepr)):
+    def convert_from_to((r_from, r_to), v, llops):
+        # warning: no keepalives, only for short-lived conversions like
+        # in argument passing
+        # r_from could be char_repr: first convert it to string_repr
+        v = llops.convertvar(v, r_from, string_repr)
+        v_adr = llops.gendirectcall(ll_string2addr, v)
+        return r_to.return_value(llops, v_adr)
+
+def ll_string2addr(s):
+    if s:
+        ptr = lltype.direct_arrayitems(s.chars)
+        return llmemory.cast_ptr_to_adr(ptr)
+    else:
+        return llmemory.NULL

Modified: pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_ctypes.py	Sat Apr 29 16:11:26 2006
@@ -174,26 +174,59 @@
     assert x.value == 42
 
 def test_pythonapi():
-    pythonapi.PyInt_AsLong.argtypes = [py_object]
-    pythonapi.PyInt_AsLong.restype = c_long
-    assert pythonapi.PyInt_AsLong(py_object(17L)) == 17
-    py.test.raises(TypeError, "pythonapi.PyInt_AsLong(py_object('hello'))")
+    PyInt_AsLong = pythonapi.PyInt_AsLong
+    saved = PyInt_AsLong.__dict__.copy()
+    try:
+        PyInt_AsLong.argtypes = [py_object]
+        PyInt_AsLong.restype = c_long
+        assert PyInt_AsLong(py_object(17L)) == 17
+        py.test.raises(TypeError, "PyInt_AsLong(py_object('hello'))")
+    finally:
+        PyInt_AsLong.__dict__ = saved
 
 def test_py_object_subclass():
-    # automatic unwrapping of the py_object result
-    pythonapi.PyInt_FromLong.argtypes = [c_long]
-    pythonapi.PyInt_FromLong.restype = py_object
-    assert isinstance(pythonapi.PyInt_FromLong(17), int)
-
-    # but not if we subclass it...
-    class W_Object(py_object):
-        pass
-    pythonapi.PyInt_FromLong.argtypes = [c_long]
-    pythonapi.PyInt_FromLong.restype = W_Object
-    assert isinstance(pythonapi.PyInt_FromLong(17), W_Object)
+    PyInt_FromLong = pythonapi.PyInt_FromLong
+    saved = PyInt_FromLong.__dict__.copy()
+    try:
+        # automatic unwrapping of the py_object result
+        PyInt_FromLong.argtypes = [c_long]
+        PyInt_FromLong.restype = py_object
+        assert isinstance(PyInt_FromLong(17), int)
+
+        # but not if we subclass it...
+        class W_Object(py_object):
+            pass
+        PyInt_FromLong.argtypes = [c_long]
+        PyInt_FromLong.restype = W_Object
+        assert isinstance(PyInt_FromLong(17), W_Object)
+    finally:
+        PyInt_FromLong.__dict__ = saved
 
 def test_sizeof():
     x = create_string_buffer(117)
     assert sizeof(x) == 117    # assumes that chars are one byte each
     x = (c_int * 42)()
     assert sizeof(x) == 42 * sizeof(c_int)
+
+def test_convert_pointers():
+    PyString_FromString = pythonapi.PyString_FromString
+    saved = PyString_FromString.__dict__.copy()
+    try:
+        PyString_FromString.restype = py_object
+
+        # automatic conversions to c_char_p
+        PyString_FromString.argtypes = [c_char_p]
+        assert PyString_FromString("hello") == "hello"
+        assert PyString_FromString(c_char_p("hello")) == "hello"
+        assert PyString_FromString((c_char * 6)(*"hello")) == "hello"
+        assert PyString_FromString(create_string_buffer("hello")) == "hello"
+
+        # automatic conversions to c_void_p
+        PyString_FromString.argtypes = [c_void_p]
+        assert PyString_FromString("hello") == "hello"
+        assert PyString_FromString(c_char_p("hello")) == "hello"
+        assert PyString_FromString((c_char * 6)(*"hello")) == "hello"
+        assert PyString_FromString((c_byte * 6)(104,101,108,108,111)) =="hello"
+        assert PyString_FromString(create_string_buffer("hello")) == "hello"
+    finally:
+        PyString_FromString.__dict__ = saved

Modified: pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py
==============================================================================
--- pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py	(original)
+++ pypy/dist/pypy/rpython/rctypes/test/test_rchar_p.py	Sat Apr 29 16:11:26 2006
@@ -13,6 +13,7 @@
 from pypy.rpython.test.test_llinterp import interpret
 
 from ctypes import c_char_p, pointer, Structure
+from ctypes import c_int, c_char, create_string_buffer, CFUNCTYPE
 
 class Test_annotation:
     def test_annotate_c_char_p(self):
@@ -111,6 +112,31 @@
             assert not c_char_p(None)
         interpret(func, [])
 
+    def test_convert_pointers(self):
+        from pypy.rpython.rctypes.rchar_p import ll_strlen
+        strlen = CFUNCTYPE(c_int, c_char_p)()   # not directly executable!
+        strlen.__name__ = 'strlen'
+        strlen.llinterp_friendly_version = ll_strlen
+        PTR = c_char_p("hello")
+        BUF = create_string_buffer(10)
+        BUF.value = "hello"
+
+        def func(n):
+            # constant arguments
+            assert strlen("hello") == 5
+            assert strlen(PTR) == 5
+            assert strlen(BUF) == 5
+            # variable arguments
+            s = chr(n) + 'bc'
+            assert strlen(s) == 3
+            assert strlen(c_char_p(s)) == 3
+            assert strlen((c_char * 6)('a', 'b')) == 2
+            buf = create_string_buffer(10)
+            buf.value = "hello"
+            assert strlen(buf) == 5
+
+        interpret(func, [65])
+
 class Test_compilation:
     def test_compile_c_char_p(self):
         def func():

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	Sat Apr 29 16:11:26 2006
@@ -12,6 +12,7 @@
 from pypy.rpython.test.test_llinterp import interpret
 
 from ctypes import c_void_p, c_int, cast, pointer, POINTER
+from ctypes import c_char, c_byte, c_char_p, create_string_buffer, CFUNCTYPE
 
 class Test_annotation:
     def test_annotate_c_void_p(self):
@@ -48,6 +49,38 @@
             assert not c_void_p()
         interpret(func, [])
 
+    def test_convert_pointers(self):
+        strlen = CFUNCTYPE(c_int, c_void_p)()
+        strlen.__name__ = 'strlen'
+        def ll_strlen_from_void_p(adr):
+            i = 0
+            while adr.char[i] != '\x00':
+                i += 1
+            return i
+        strlen.llinterp_friendly_version = ll_strlen_from_void_p
+        PTR = c_char_p("hello")
+        BUF = create_string_buffer(10)
+        BUF.value = "hello"
+        ARR = (c_byte * 10)(65, 66, 67)
+
+        def func(n):
+            # constant arguments XXX in-progress
+            ##   assert strlen("hello") == 5
+            ##   assert strlen(PTR) == 5
+            ##   assert strlen(BUF) == 5
+            ##   assert strlen(ARR) == 3
+            # variable arguments
+            s = chr(n) + 'bc'
+            assert strlen(s) == 3
+            assert strlen(c_char_p(s)) == 3
+            assert strlen((c_char * 6)('a', 'b')) == 2
+            assert strlen((c_byte * 6)(104,101,108,108,111)) == 5
+            buf = create_string_buffer(10)
+            buf.value = "hello"
+            assert strlen(buf) == 5
+
+        interpret(func, [65])
+
 class Test_compilation:
     def test_compile_c_char_p(self):
         def func():



More information about the Pypy-commit mailing list