[pypy-svn] r45057 - in pypy/dist/pypy/rpython/lltypesystem: . test

arigo at codespeak.net arigo at codespeak.net
Sat Jul 14 11:40:37 CEST 2007


Author: arigo
Date: Sat Jul 14 11:40:36 2007
New Revision: 45057

Modified:
   pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
   pypy/dist/pypy/rpython/lltypesystem/lltype.py
   pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
Log:
(lac, arigo)
Make strchr() callable via rffi.


Modified: pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/ll2ctypes.py	Sat Jul 14 11:40:36 2007
@@ -2,6 +2,11 @@
 import ctypes
 import ctypes.util
 from pypy.rpython.lltypesystem import lltype
+from pypy.tool.uid import fixid
+
+
+def uaddressof(obj):
+    return fixid(ctypes.addressof(obj))
 
 
 _ctypes_cache = {
@@ -48,6 +53,9 @@
             cobj = lltype2ctypes(value)
             setattr(self, field_name, cobj)
 
+        def _eq(self, other):
+            return ctypes.addressof(self) == ctypes.addressof(other)
+
     CStruct.__name__ = 'ctypes_%s' % (S,)
     if max_n is not None:
         CStruct._normalized_ctype = get_ctypes_type(S)
@@ -75,13 +83,29 @@
             return bigarray
         _malloc = classmethod(_malloc)
 
-        def _getitem(self, index):
-            cobj = self.items[index]
+        def _indexable(self, index):
+            PtrType = ctypes.POINTER((index+1) * ctypes_item)
+            p = ctypes.cast(ctypes.pointer(self.items), PtrType)
+            return p.contents
+
+        def _getitem(self, index, boundscheck=True):
+            if boundscheck:
+                items = self.items
+            else:
+                items = self._indexable(index)
+            cobj = items[index]
             return ctypes2lltype(ITEM, cobj)
 
-        def _setitem(self, index, value):
+        def _setitem(self, index, value, boundscheck=True):
+            if boundscheck:
+                items = self.items
+            else:
+                items = self._indexable(index)
             cobj = lltype2ctypes(value)
-            self.items[index] = cobj
+            items[index] = cobj
+
+        def _eq(self, other):
+            return ctypes.addressof(self) == ctypes.addressof(other)
 
     CArray.__name__ = 'ctypes_%s*%d' % (A, max_n)
     if max_n > 0:
@@ -111,9 +135,14 @@
     container._ctypes_storage = cstruct
     for field_name in STRUCT._names:
         field_value = getattr(container, field_name)
-        delattr(container, field_name)
         if not isinstance(field_value, lltype._uninitialized):
             setattr(cstruct, field_name, lltype2ctypes(field_value))
+    remove_regular_struct_content(container)
+
+def remove_regular_struct_content(container):
+    STRUCT = container._TYPE
+    for field_name in STRUCT._names:
+        delattr(container, field_name)
 
 def convert_array(container):
     ARRAY = container._TYPE
@@ -122,9 +151,31 @@
     container._ctypes_storage = carray
     for i in range(container.getlength()):
         item_value = container.items[i]    # fish fish
-        container.items[i] = None
         if not isinstance(item_value, lltype._uninitialized):
             carray.items[i] = lltype2ctypes(item_value)
+    remove_regular_array_content(container)
+
+def remove_regular_array_content(container):
+    for i in range(container.getlength()):
+        container.items[i] = None
+
+class _array_of_unknown_length(lltype._parentable):
+    _kind = "array"
+
+    __slots__ = ()
+
+    def __repr__(self):
+        return '<C array at 0x%x>' % (uaddressof(self._ctypes_storage),)
+
+    def getbounds(self):
+        # we have no clue, so we allow whatever index
+        return 0, sys.maxint
+
+    def getitem(self, index, uninitialized_ok=False):
+        return self._ctypes_storage._getitem(index, boundscheck=False)
+
+    def setitem(self, index, value):
+        self._ctypes_storage._setitem(index, value, boundscheck=False)
 
 # ____________________________________________________________
 
@@ -160,6 +211,21 @@
     """
     if T is lltype.Char:
         llobj = chr(cobj)
+    elif isinstance(T, lltype.Ptr):
+        if isinstance(T.TO, lltype.Struct):
+            # XXX var-sized structs
+            container = lltype._struct(T.TO)
+            container._ctypes_storage = cobj.contents
+            remove_regular_struct_content(container)
+        elif isinstance(T.TO, lltype.Array):
+            if T.TO._hints.get('nolength', False):
+                container = _array_of_unknown_length(T.TO)
+                container._ctypes_storage = cobj.contents
+            else:
+                raise NotImplementedError("array with an explicit length")
+        else:
+            raise NotImplementedError(T)
+        llobj = lltype._ptr(T, container, solid=True)
     else:
         llobj = cobj
 

Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py	Sat Jul 14 11:40:36 2007
@@ -1248,6 +1248,18 @@
     def _setup_extra_args(self):
         pass
 
+    def __eq__(self, other):
+        if not isinstance(other, _parentable):
+            return False
+        if (self._ctypes_storage is not None and
+            other._ctypes_storage is not None):
+            return self._ctypes_storage._eq(other._ctypes_storage)
+        else:
+            return self is other
+
+    def __ne__(self, other):
+        return not (self == other)
+
 def _struct_variety(flds, cache={}):
     flds = list(flds)
     flds.sort()

Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	(original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_ll2ctypes.py	Sat Jul 14 11:40:36 2007
@@ -81,6 +81,10 @@
     res = strlen(s)
     rffi.free_charp(s)
     assert res == 3
+    s = rffi.str2charp("")
+    res = strlen(s)
+    rffi.free_charp(s)
+    assert res == 0
 
 def test_func_not_in_clib():
     foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed)
@@ -97,3 +101,74 @@
     foobar = rffi.llexternal('I_really_dont_exist', [], lltype.Signed,
                              libraries=['I_really_dont_exist_either'])
     py.test.raises(NotImplementedError, foobar)
+
+def test_cstruct_to_ll():
+    S = lltype.Struct('S', ('x', lltype.Signed), ('y', lltype.Signed))
+    s = lltype.malloc(S, flavor='raw')
+    s2 = lltype.malloc(S, flavor='raw')
+    s.x = 123
+    sc = lltype2ctypes(s)
+    t = ctypes2lltype(lltype.Ptr(S), sc)
+    assert lltype.typeOf(t) == lltype.Ptr(S)
+    assert s == t
+    assert not (s != t)
+    assert t == s
+    assert not (t != s)
+    assert t != lltype.nullptr(S)
+    assert not (t == lltype.nullptr(S))
+    assert lltype.nullptr(S) != t
+    assert not (lltype.nullptr(S) == t)
+    assert t != s2
+    assert not (t == s2)
+    assert s2 != t
+    assert not (s2 == t)
+    assert t.x == 123
+    t.x += 1
+    assert s.x == 124
+    s.x += 1
+    assert t.x == 125
+    lltype.free(s, flavor='raw')
+    lltype.free(s2, flavor='raw')
+
+def test_carray_to_ll():
+    A = lltype.Array(lltype.Signed, hints={'nolength': True})
+    a = lltype.malloc(A, 10, flavor='raw')
+    a2 = lltype.malloc(A, 10, flavor='raw')
+    a[0] = 100
+    a[1] = 101
+    a[2] = 110
+    ac = lltype2ctypes(a)
+    b = ctypes2lltype(lltype.Ptr(A), ac)
+    assert lltype.typeOf(b) == lltype.Ptr(A)
+    assert b == a
+    assert not (b != a)
+    assert a == b
+    assert not (a != b)
+    assert b != lltype.nullptr(A)
+    assert not (b == lltype.nullptr(A))
+    assert lltype.nullptr(A) != b
+    assert not (lltype.nullptr(A) == b)
+    assert b != a2
+    assert not (b == a2)
+    assert a2 != b
+    assert not (a2 == b)
+    assert b[2] == 110
+    b[2] *= 2
+    assert a[2] == 220
+    a[2] *= 3
+    assert b[2] == 660
+    lltype.free(a, flavor='raw')
+    lltype.free(a2, flavor='raw')
+
+def test_strchr():
+    # XXX int vs long issues
+    strchr = rffi.llexternal('strchr', [rffi.CCHARP, lltype.Signed],
+                             rffi.CCHARP,
+                             includes=['string.h'])
+    s = rffi.str2charp("hello world")
+    res = strchr(s, ord('r'))
+    assert res[0] == 'r'
+    assert res[1] == 'l'
+    assert res[2] == 'd'
+    assert res[3] == '\x00'
+    rffi.free_charp(s)



More information about the Pypy-commit mailing list