[pypy-svn] r51441 - in pypy/dist/pypy/rpython/lltypesystem: . test
arigo at codespeak.net
arigo at codespeak.net
Wed Feb 13 17:05:32 CET 2008
Author: arigo
Date: Wed Feb 13 17:05:30 2008
New Revision: 51441
Modified:
pypy/dist/pypy/rpython/lltypesystem/llmemory.py
pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
Log:
It was possible already to take the fakeaddress just past the end
of an array of primitives; this allows the same for arrays of
structures. Needed to llinterp the GCs handling dictionaries.
Modified: pypy/dist/pypy/rpython/lltypesystem/llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/llmemory.py Wed Feb 13 17:05:30 2008
@@ -60,7 +60,18 @@
if isinstance(index, str):
assert index.startswith('item') # itemN => N
index = int(index[4:])
- return parent.getitem(index + self.repeat)._as_ptr()
+ index += self.repeat
+ if index == parent.getlength():
+ # for references exactly to the end of the array
+ try:
+ endmarker = _end_markers[parent]
+ except KeyError:
+ endmarker = _endmarker_struct(A, parent=parent,
+ parentindex=index)
+ _end_markers[parent] = endmarker
+ return endmarker._as_ptr()
+ else:
+ return parent.getitem(index)._as_ptr()
elif (isinstance(A, lltype.FixedSizeArray) and
array_item_type_match(A.OF, self.TYPE)):
# for array of primitives or pointers
@@ -99,6 +110,24 @@
srcadr += ItemOffset(self.TYPE)
dstadr += ItemOffset(self.TYPE)
+_end_markers = weakref.WeakKeyDictionary() # <array of STRUCT> -> _endmarker
+class _endmarker_struct(lltype._struct):
+ __slots__ = ()
+ def __new__(self, *args, **kwds):
+ return object.__new__(self)
+ def __init__(self, *args, **kwds):
+ lltype._struct.__init__(self, *args, **kwds)
+ self._storage = False
+ def __getattr__(self, name):
+ raise AttributeError("cannot access fields in the endmarker "
+ "structure at the end of the array")
+ def __setattr__(self, name, value):
+ if name.startswith('_'):
+ object.__setattr__(self, name, value) # '_xxx' attributes
+ elif self._storage is False:
+ raise AttributeError("cannot access fields in the endmarker "
+ "structure at the end of the array")
+
class FieldOffset(AddressOffset):
Modified: pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py
==============================================================================
--- pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py (original)
+++ pypy/dist/pypy/rpython/lltypesystem/test/test_llmemory.py Wed Feb 13 17:05:30 2008
@@ -39,7 +39,35 @@
assert b.signed[0] == 123
b.signed[0] = 14
assert x[3] == 14
-
+
+def test_array_endaddress():
+ A = lltype.GcArray(lltype.Signed)
+ x = lltype.malloc(A, 5)
+ x[4] = 321
+ a = fakeaddress(x)
+ b = a + ArrayItemsOffset(A)
+ b += ItemOffset(lltype.Signed)*5
+ assert b == a + ArrayItemsOffset(A) + ItemOffset(lltype.Signed)*5
+ py.test.raises(IndexError, "b.signed[0]")
+ b -= ItemOffset(lltype.Signed)
+ assert b.signed[0] == 321
+
+def test_structarray_endaddress():
+ S = lltype.Struct('S', ('foo', lltype.Signed))
+ A = lltype.GcArray(S)
+ x = lltype.malloc(A, 5)
+ x[4].foo = 321
+ a = fakeaddress(x)
+ b = a + ArrayItemsOffset(A)
+ b += ItemOffset(S)*5
+ assert b == a + ArrayItemsOffset(A) + ItemOffset(S)*5
+ p = cast_adr_to_ptr(b, lltype.Ptr(S))
+ py.test.raises(AttributeError, "p.foo")
+ py.test.raises(AttributeError, "p.foo = 55")
+ b -= ItemOffset(S)
+ p = cast_adr_to_ptr(b, lltype.Ptr(S))
+ assert p.foo == 321
+
def test_dont_mix_offsets_and_ints():
o = AddressOffset()
py.test.raises(TypeError, "1 + o")
More information about the Pypy-commit
mailing list