[pypy-commit] pypy null_byte_after_str: Fix GC tests

arigo pypy.commits at gmail.com
Sat Jul 30 04:32:14 EDT 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: null_byte_after_str
Changeset: r85919:022d722589d2
Date: 2016-07-30 10:22 +0200
http://bitbucket.org/pypy/pypy/changeset/022d722589d2/

Log:	Fix GC tests

diff --git a/rpython/rtyper/lltypesystem/llmemory.py b/rpython/rtyper/lltypesystem/llmemory.py
--- a/rpython/rtyper/lltypesystem/llmemory.py
+++ b/rpython/rtyper/lltypesystem/llmemory.py
@@ -304,8 +304,15 @@
         return cast_ptr_to_adr(p)
 
     def raw_memcopy(self, srcadr, dstadr):
-        # should really copy the length field, but we can't
-        pass
+        # copy the length field, if we can
+        srclen = srcadr.ptr._obj.getlength()
+        dstlen = dstadr.ptr._obj.getlength()
+        if dstlen != srclen:
+            assert dstlen > srclen, "can't increase the length"
+            # a decrease in length occurs in the GC tests when copying a STR:
+            # the copy is initially allocated with really one extra char,
+            # the 'extra_item_after_alloc', and must be fixed.
+            dstadr.ptr._obj.shrinklength(srclen)
 
 
 class ArrayLengthOffset(AddressOffset):
@@ -1048,7 +1055,7 @@
                 _reccopy(subsrc, subdst)
             else:
                 # this is a hack XXX de-hack this
-                llvalue = source._obj.getitem(i, uninitialized_ok=True)
+                llvalue = source._obj.getitem(i, uninitialized_ok=2)
                 if not isinstance(llvalue, lltype._uninitialized):
                     dest._obj.setitem(i, llvalue)
     elif isinstance(T, lltype.Struct):
diff --git a/rpython/rtyper/lltypesystem/lltype.py b/rpython/rtyper/lltypesystem/lltype.py
--- a/rpython/rtyper/lltypesystem/lltype.py
+++ b/rpython/rtyper/lltypesystem/lltype.py
@@ -1926,14 +1926,29 @@
         return 0, stop
 
     def getitem(self, index, uninitialized_ok=False):
-        v = self.items[index]
+        try:
+            v = self.items[index]
+        except IndexError:
+            if (index == len(self.items) and uninitialized_ok == 2 and
+                self._TYPE._hints.get('extra_item_after_alloc')):
+                # special case: reading the extra final char returns
+                # an uninitialized, if 'uninitialized_ok==2'
+                return _uninitialized(self._TYPE.OF)
+            raise
         if isinstance(v, _uninitialized) and not uninitialized_ok:
             raise UninitializedMemoryAccess("%r[%s]"%(self, index))
         return v
 
     def setitem(self, index, value):
         assert typeOf(value) == self._TYPE.OF
-        self.items[index] = value
+        try:
+            self.items[index] = value
+        except IndexError:
+            if (index == len(self.items) and value == '\x00' and
+                self._TYPE._hints.get('extra_item_after_alloc')):
+                # special case: writing NULL to the extra final char
+                return
+            raise
 
 assert not '__dict__' in dir(_array)
 assert not '__dict__' in dir(_struct)


More information about the pypy-commit mailing list