[pypy-svn] r32120 - in pypy/branch/more-gckinds/pypy/rpython: . lltypesystem test

mwh at codespeak.net mwh at codespeak.net
Sun Sep 10 15:01:47 CEST 2006


Author: mwh
Date: Sun Sep 10 15:01:46 2006
New Revision: 32120

Modified:
   pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py
   pypy/branch/more-gckinds/pypy/rpython/rptr.py
   pypy/branch/more-gckinds/pypy/rpython/test/test_rptr.py
Log:
make a test that involves a non-trivial-at-runtime interior pointer pass.
some refactoring will be needed.


Modified: pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/lltypesystem/lltype.py	Sun Sep 10 15:01:46 2006
@@ -619,6 +619,11 @@
         o = self.TO._container_example()
         return _ptr(self, o, solid=True)
 
+    def _interior_ptr_type_with_index(self):
+        R = GcStruct("Interior", ('ptr', self), ('index', Signed),
+                     hints={'interior_ptr_type':True})
+        return R
+
 class InteriorPtr(LowLevelType):
     def __init__(self, PARENTTYPE, TO, offsets):
         self.PARENTTYPE = PARENTTYPE

Modified: pypy/branch/more-gckinds/pypy/rpython/rptr.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/rptr.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/rptr.py	Sun Sep 10 15:01:46 2006
@@ -22,7 +22,10 @@
 
 class __extend__(annmodel.SomeInteriorPtr):
     def rtyper_makerepr(self, rtyper):
-        return InteriorPtrRepr(self.ll_ptrtype)
+        for offset in self.ll_ptrtype.offsets:
+            if isinstance(offset, int):
+                return InteriorPtrRepr(self.ll_ptrtype)
+        return FieldOnlyInteriorPtrRepr(self.ll_ptrtype)
 
 class PtrRepr(Repr):
 
@@ -100,7 +103,18 @@
         ARRAY = r_ptr.lowleveltype.TO
         ITEM_TYPE = ARRAY.OF
         if isinstance(ITEM_TYPE, ContainerType):
-            newopname = 'getarraysubstruct'
+            if ARRAY._gckind == 'gc' and ITEM_TYPE._gckind == 'raw':
+                v_array, v_index = hop.inputargs(r_ptr, Signed)
+                INTERIOR_PTR_TYPE = Ptr(ARRAY)._interior_ptr_type_with_index()
+                v_interior_ptr = hop.genop('malloc', [flowmodel.Constant(INTERIOR_PTR_TYPE, Void)],
+                                           resulttype = Ptr(INTERIOR_PTR_TYPE))
+                hop.genop('setfield',
+                          [v_interior_ptr, flowmodel.Constant('ptr', Void), v_array])
+                hop.genop('setfield',
+                          [v_interior_ptr, flowmodel.Constant('index', Void), v_index])
+                return v_interior_ptr
+            else:
+                newopname = 'getarraysubstruct'
         else:
             newopname = 'getarrayitem'
         vlist = hop.inputargs(r_ptr, Signed)
@@ -188,14 +202,13 @@
             return v
         return NotImplemented
 
-class InteriorPtrRepr(Repr):
+class FieldOnlyInteriorPtrRepr(Repr):
     def __init__(self, ptrtype):
         assert isinstance(ptrtype, InteriorPtr)
-        assert len(ptrtype.offsets) == 1
-        offset, = ptrtype.offsets
-        assert isinstance(offset, str)
+        for offset in ptrtype.offsets:
+            assert isinstance(offset, str)
         self.lowleveltype = Ptr(ptrtype.PARENTTYPE)
-        self.v_offsets = [flowmodel.Constant(offset, Void)]
+        self.v_offsets = [flowmodel.Constant(offset, Void) for offset in ptrtype.offsets]
         self.resulttype = Ptr(ptrtype.TO)
 
     def rtype_getattr(self, hop):
@@ -203,7 +216,7 @@
         vlist.append(hop.inputarg(Void, 1))        
         return hop.genop('getinteriorfield', vlist,
                          resulttype=hop.r_result.lowleveltype)
-        
+
     def rtype_setattr(self, hop):
         vlist = [hop.inputarg(hop.args_r[0], 0)] + self.v_offsets
         vlist.append(hop.inputarg(Void, 1))
@@ -211,3 +224,36 @@
         
         return hop.genop('setinteriorfield', vlist,
                          resulttype=hop.r_result.lowleveltype)
+
+class InteriorPtrRepr(Repr):
+    def __init__(self, ptrtype):
+        assert isinstance(ptrtype, InteriorPtr)
+        assert len(ptrtype.offsets) == 1, "for now"
+        numitemoffsets = 0
+        for offset in ptrtype.offsets:
+            if isinstance(offset, int):
+                numitemoffsets += 1
+        assert numitemoffsets == 1
+        self.parentptrtype = Ptr(ptrtype.PARENTTYPE)
+        self.lowleveltype = Ptr(self.parentptrtype._interior_ptr_type_with_index())
+        self.resulttype = Ptr(ptrtype.TO)
+        assert not isinstance(self.resulttype, ContainerType)
+
+    def rtype_getattr(self, hop):
+        v_interior_ptr, v_fieldname = hop.inputargs(self, Void)
+        v_ptr = hop.genop('getfield', [v_interior_ptr, flowmodel.Constant('ptr', Void)],
+                          resulttype=self.parentptrtype)
+        v_offset = hop.genop('getfield', [v_interior_ptr, flowmodel.Constant('index', Void)],
+                             resulttype=Signed)
+        return hop.genop('getinteriorfield', [v_ptr, v_offset, v_fieldname],
+                         resulttype=hop.r_result.lowleveltype)
+
+    def rtype_setattr(self, hop):
+        v_interior_ptr, v_fieldname, v_value = hop.inputargs(self, Void, hop.args_r[2])
+        v_ptr = hop.genop('getfield', [v_interior_ptr, flowmodel.Constant('ptr', Void)],
+                          resulttype=self.parentptrtype)
+        v_offset = hop.genop('getfield', [v_interior_ptr, flowmodel.Constant('index', Void)],
+                             resulttype=Signed)
+        return hop.genop('setinteriorfield', [v_ptr, v_offset, v_fieldname, v_value],
+                         resulttype=hop.r_result.lowleveltype)
+

Modified: pypy/branch/more-gckinds/pypy/rpython/test/test_rptr.py
==============================================================================
--- pypy/branch/more-gckinds/pypy/rpython/test/test_rptr.py	(original)
+++ pypy/branch/more-gckinds/pypy/rpython/test/test_rptr.py	Sun Sep 10 15:01:46 2006
@@ -217,3 +217,15 @@
         return t.s.x
     res = interpret(f, [])
     assert res == 1
+
+def test_interior_ptr_with_offset():
+    S = Struct("S", ('x', Signed))
+    T = GcArray(S)
+    def g(s):
+        s.x = 1
+    def f():
+        t = malloc(T, 1)
+        g(t[0])
+        return t[0].x
+    res = interpret(f, [])
+    assert res == 1



More information about the Pypy-commit mailing list