[pypy-svn] r25613 - in pypy/dist/pypy/rpython/lltypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Sun Apr 9 12:25:07 CEST 2006
Author: arigo
Date: Sun Apr 9 12:25:06 2006
New Revision: 25613
Modified:
pypy/dist/pypy/rpython/lltypesystem/lltype.py
pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
Log:
(arre, arigo)
Conversion from Array to Array(nolength=True), as well as
from FixedSizeArray to Array(nolength=True).
Modified: pypy/dist/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/lltype.py Sun Apr 9 12:25:06 2006
@@ -612,6 +612,24 @@
raise TypeError, "can only cast pointers to other pointers"
return ptr._cast_to(PTRTYPE)
+def cast_array_pointer(PTRTYPE, ptr):
+ CURTYPE = typeOf(ptr)
+ if not isinstance(CURTYPE, Ptr) or not isinstance(PTRTYPE, Ptr):
+ raise TypeError, "can only cast pointers to other pointers"
+ if (not isinstance(PTRTYPE.TO, Array) or
+ not PTRTYPE.TO._hints.get('nolength', False)):
+ raise TypeError, "can only convert to nolength Arrays"
+ if isinstance(CURTYPE.TO, Array):
+ if CURTYPE.TO._hints.get('nolength', False):
+ raise TypeError, "cannot convert from a nolength Array"
+ elif isinstance(CURTYPE.TO, FixedSizeArray):
+ pass
+ else:
+ raise TypeError, "can only convert from an array"
+ if CURTYPE.TO.OF != PTRTYPE.TO.OF:
+ raise TypeError, "pointers to arrays of different item types"
+ return ptr._cast_array_to(PTRTYPE)
+
def _expose(val, solid=False):
"""XXX A nice docstring here"""
T = typeOf(val)
@@ -692,7 +710,8 @@
def _setobj(self, pointing_to, solid=False):
if pointing_to is None:
obj0 = None
- elif solid or isinstance(self._T, (GC_CONTAINER, FuncType)):
+ elif (solid or isinstance(self._T, (GC_CONTAINER, FuncType))
+ or isinstance(pointing_to, _nolengtharray)):
obj0 = pointing_to
else:
self._set_weak(True)
@@ -761,20 +780,15 @@
field_name))
def __getitem__(self, i): # ! can only return basic or ptr !
- if isinstance(self._T, Array):
- if not (0 <= i < len(self._obj.items)):
+ if isinstance(self._T, (Array, FixedSizeArray)):
+ if not (0 <= i < self._obj.getlength()):
raise IndexError("array index out of bounds")
- o = self._obj.items[i]
- return _expose(o, self._solid)
- if isinstance(self._T, FixedSizeArray):
- if not (0 <= i < self._T.length):
- raise IndexError("fixed-size array index out of bounds")
- o = getattr(self._obj, 'item%d' % i)
+ o = self._obj.getitem(i)
return _expose(o, self._solid)
raise TypeError("%r instance is not an array" % (self._T,))
def __setitem__(self, i, val):
- if isinstance(self._T, Array):
+ if isinstance(self._T, (Array, FixedSizeArray)):
T1 = self._T.OF
if isinstance(T1, ContainerType):
raise TypeError("cannot directly assign to container array items")
@@ -783,34 +797,18 @@
raise TypeError("%r items:\n"
"expect %r\n"
" got %r" % (self._T, T1, T2))
- if not (0 <= i < len(self._obj.items)):
+ if not (0 <= i < self._obj.getlength()):
raise IndexError("array index out of bounds")
- self._obj.items[i] = val
- return
- if isinstance(self._T, FixedSizeArray):
- T1 = self._T.OF
- if isinstance(T1, ContainerType):
- raise TypeError("cannot directly assign to container array items")
- T2 = typeOf(val)
- if T2 != T1:
- raise TypeError("%r items:\n"
- "expect %r\n"
- " got %r" % (self._T, T1, T2))
- if not (0 <= i < self._T.length):
- raise IndexError("fixed-size array index out of bounds")
- setattr(self._obj, 'item%d' % i, val)
+ self._obj.setitem(i, val)
return
raise TypeError("%r instance is not an array" % (self._T,))
def __len__(self):
- if isinstance(self._T, Array):
+ if isinstance(self._T, (Array, FixedSizeArray)):
if self._T._hints.get('nolength', False):
raise TypeError("%r instance has no length attribute" %
(self._T,))
-
- return len(self._obj.items)
- if isinstance(self._T, FixedSizeArray):
- return self._T.length
+ return self._obj.getlength()
raise TypeError("%r instance is not an array" % (self._T,))
def __repr__(self):
@@ -862,7 +860,10 @@
if PARENTTYPE != PTRTYPE.TO:
raise TypeError("widening %r inside %r instead of %r" % (CURTYPE, PARENTTYPE, PTRTYPE.TO))
return _ptr(PTRTYPE, struc, solid=self._solid)
-
+
+ def _cast_array_to(self, PTRTYPE):
+ return _ptr(PTRTYPE, _nolengtharray(PTRTYPE.TO, self._obj))
+
def _cast_to_int(self):
obj = self._obj
while obj._parentstructure():
@@ -977,6 +978,18 @@
__setstate__ = setstate_with_slots
+ def getlength(self): # for FixedSizeArray kind of structs
+ assert isinstance(self._TYPE, FixedSizeArray)
+ return self._TYPE.length
+
+ def getitem(self, index): # for FixedSizeArray kind of structs
+ assert isinstance(self._TYPE, FixedSizeArray)
+ return getattr(self, 'item%d' % index)
+
+ def setitem(self, index, value): # for FixedSizeArray kind of structs
+ assert isinstance(self._TYPE, FixedSizeArray)
+ setattr(self, 'item%d' % index, value)
+
class _array(_parentable):
_kind = "array"
@@ -1010,6 +1023,41 @@
return 'array [ %s ]' % (', '.join([self._str_item(item)
for item in self.items]),)
+ def getlength(self):
+ return len(self.items)
+
+ def getitem(self, index):
+ return self.items[index]
+
+ def setitem(self, index, value):
+ self.items[index] = value
+
+class _nolengtharray(object):
+ _kind = "array"
+
+ __slots__ = ('_TYPE', 'wr_parentarray')
+
+ def __init__(self, TYPE, parentarray):
+ self._TYPE = TYPE
+ self.wr_parentarray = pickleable_weakref(parentarray)
+
+ def getparentarray(self):
+ parentarray = self.wr_parentarray()
+ if parentarray is None:
+ raise RuntimeError("accessing already garbage collected %r"
+ % (self._T,))
+ return parentarray
+
+ def getlength(self):
+ # for debugging only
+ return self.getparentarray().getlength()
+
+ def getitem(self, index):
+ return self.getparentarray().getitem(index)
+
+ def setitem(self, index, value):
+ return self.getparentarray().setitem(index, value)
+
assert not '__dict__' in dir(_array)
assert not '__dict__' in dir(_struct)
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_lltype.py Sun Apr 9 12:25:06 2006
@@ -519,6 +519,50 @@
a = malloc(A, 10)
py.test.raises(TypeError, len, a)
+def test_cast_length_to_no_length():
+ A = Array(Char, hints={'nolength': True})
+ S = GcStruct("str", ("hash", Signed),
+ ("chars", Array(Char)))
+ s = malloc(S, 5)
+ s.chars[0] = 'h'
+ s.chars[1] = 'e'
+ s.chars[2] = 'l'
+ s.chars[3] = 'l'
+ s.chars[4] = 'o'
+ a = cast_array_pointer(Ptr(A), s.chars)
+ assert a[0] == 'h'
+ assert a[1] == 'e'
+ assert a[2] == 'l'
+ assert a[3] == 'l'
+ assert a[4] == 'o'
+ py.test.raises(TypeError, len, a)
+ a[1] = 'E'
+ assert s.chars[1] == 'E'
+ s.chars[2] = 'L'
+ assert a[2] == 'L'
+
+def test_cast_fixed_to_no_length():
+ A = Array(Char, hints={'nolength': True})
+ S = GcStruct("str", ("hash", Signed),
+ ("chars", FixedSizeArray(Char, 5)))
+ s = malloc(S)
+ s.chars[0] = 'h'
+ s.chars[1] = 'e'
+ s.chars[2] = 'l'
+ s.chars[3] = 'l'
+ s.chars[4] = 'o'
+ a = cast_array_pointer(Ptr(A), s.chars)
+ assert a[0] == 'h'
+ assert a[1] == 'e'
+ assert a[2] == 'l'
+ assert a[3] == 'l'
+ assert a[4] == 'o'
+ py.test.raises(TypeError, len, a)
+ a[1] = 'E'
+ assert s.chars[1] == 'E'
+ s.chars[2] = 'L'
+ assert a[2] == 'L'
+
def test_dissect_ll_instance():
assert list(dissect_ll_instance(1)) == [(Signed, 1)]
GcS = GcStruct("S", ('x', Signed))
More information about the Pypy-commit
mailing list