[pypy-commit] pypy default: (arigo, cfbolz): don't use __slots__ as storage for fixed sized arrays

cfbolz pypy.commits at gmail.com
Sun Feb 21 09:15:06 EST 2016


Author: Carl Friedrich Bolz <cfbolz at gmx.de>
Branch: 
Changeset: r82365:4a97212b2ecf
Date: 2016-02-21 15:07 +0100
http://bitbucket.org/pypy/pypy/changeset/4a97212b2ecf/

Log:	(arigo, cfbolz): don't use __slots__ as storage for fixed sized
	arrays

diff --git a/rpython/rtyper/lltypesystem/ll2ctypes.py b/rpython/rtyper/lltypesystem/ll2ctypes.py
--- a/rpython/rtyper/lltypesystem/ll2ctypes.py
+++ b/rpython/rtyper/lltypesystem/ll2ctypes.py
@@ -463,6 +463,9 @@
 
 def remove_regular_struct_content(container):
     STRUCT = container._TYPE
+    if isinstance(STRUCT, lltype.FixedSizeArray):
+        del container._items
+        return
     for field_name in STRUCT._names:
         FIELDTYPE = getattr(STRUCT, field_name)
         if not isinstance(FIELDTYPE, lltype.ContainerType):
@@ -642,6 +645,12 @@
             cobj = lltype2ctypes(value)
             setattr(self._storage.contents, field_name, cobj)
 
+    def getitem(self, index, uninitialized_ok=False):
+        return getattr(self, "item%s" % index)
+
+    def setitem(self, index, value):
+        setattr(self, "item%s" % index, value)
+
 class _array_mixin(_parentable_mixin):
     """Mixin added to _array containers when they become ctypes-based."""
     __slots__ = ()
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
@@ -1761,7 +1761,10 @@
 
     def __new__(self, TYPE, n=None, initialization=None, parent=None,
                 parentindex=None):
-        my_variety = _struct_variety(TYPE._names)
+        if isinstance(TYPE, FixedSizeArray):
+            my_variety = _fixedsizearray
+        else:
+            my_variety = _struct_variety(TYPE._names)
         return object.__new__(my_variety)
 
     def __init__(self, TYPE, n=None, initialization=None, parent=None,
@@ -1814,23 +1817,48 @@
             raise UninitializedMemoryAccess("%r.%s"%(self, field_name))
         return r
 
-    # for FixedSizeArray kind of structs:
+
+class _fixedsizearray(_struct):
+    def __init__(self, TYPE, n=None, initialization=None, parent=None,
+                 parentindex=None):
+        _parentable.__init__(self, TYPE)
+        if n is not None:
+            raise TypeError("%r is not variable-sized" % (TYPE,))
+        typ = TYPE.OF
+        storage = []
+        for i, fld in enumerate(TYPE._names):
+            value = typ._allocate(initialization=initialization,
+                                  parent=self, parentindex=fld)
+            storage.append(value)
+        self._items = storage
+        if parent is not None:
+            self._setparentstructure(parent, parentindex)
 
     def getlength(self):
-        assert isinstance(self._TYPE, FixedSizeArray)
         return self._TYPE.length
 
     def getbounds(self):
         return 0, self.getlength()
 
     def getitem(self, index, uninitialized_ok=False):
-        assert isinstance(self._TYPE, FixedSizeArray)
-        return self._getattr('item%d' % index, uninitialized_ok)
+        assert 0 <= index < self.getlength()
+        return self._items[index]
 
     def setitem(self, index, value):
-        assert isinstance(self._TYPE, FixedSizeArray)
-        setattr(self, 'item%d' % index, value)
+        assert 0 <= index < self.getlength()
+        self._items[index] = value
 
+    def __getattr__(self, name):
+        # obscure
+        if name.startswith("item"):
+            return self.getitem(int(name[len('item'):]))
+        return _struct.__getattr__(self, name)
+
+    def __setattr__(self, name, value):
+        if name.startswith("item"):
+            self.setitem(int(name[len('item'):]), value)
+            return
+        _struct.__setattr__(self, name, value)
 
 class _array(_parentable):
     _kind = "array"


More information about the pypy-commit mailing list