[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