[pypy-svn] r22859 - in pypy/dist/pypy/rpython/memory: . test

mwh at codespeak.net mwh at codespeak.net
Sun Jan 29 19:47:17 CET 2006


Author: mwh
Date: Sun Jan 29 19:47:15 2006
New Revision: 22859

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/rpython/memory/test/test_gctransform.py
Log:
some very nearly insane code to generate the graph of the deallocator
for an lltype.


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Sun Jan 29 19:47:15 2006
@@ -1,5 +1,6 @@
 from pypy.rpython.lltypesystem import lltype
-from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, c_last_exception
+from pypy.objspace.flow.model import SpaceOperation, Variable, Constant, \
+     c_last_exception, FunctionGraph, Block, Link, checkgraph
 from pypy.translator.unsimplify import insert_empty_block
 from pypy.rpython import rmodel
 import sets
@@ -168,3 +169,47 @@
         result.concretetype = lltype.Void
         return [SpaceOperation("gc_pop_alive_pyobj", [var], result)]
 
+    # ----------------------------------------------------------------
+
+    def _deallocator_body_for_type(self, v, TYPE, depth=1):
+        if isinstance(TYPE, lltype.Array):
+            
+            inner = list(self._deallocator_body_for_type('v_%i'%depth, TYPE.OF, depth+1))
+            if inner:
+                yield '    '*depth + 'i_%d = 0'%(depth,)
+                yield '    '*depth + 'l_%d = len(%s)'%(depth, v)
+                yield '    '*depth + 'while i_%d < l_%d:'%(depth, depth)
+                yield '    '*depth + '    v_%d = %s[i_%d]'%(depth, v, depth)
+                for line in inner:
+                    yield line
+                yield '    '*depth + '    i_%d += 1'%(depth,)
+        elif isinstance(TYPE, lltype.Struct):
+            for name in TYPE._names:
+                inner = list(self._deallocator_body_for_type(
+                    v + '_' + name, TYPE._flds[name], depth))
+                if inner:
+                    yield '    '*depth + v + '_' + name + ' = ' + v + '.' + name
+                    for line in inner:
+                        yield line
+        elif isinstance(TYPE, lltype.Ptr):
+            yield '    '*depth + 'pop_alive(%s)'%v
+
+    def deallocation_graph_for_type(self, translator, TYPE, var):
+        def compute_ll_ops(hop):
+            hop.llops.extend(self.pop_alive(hop.args_v[1]))
+            return hop.inputconst(hop.r_result.lowleveltype, hop.s_result.const)
+        def pop_alive(var):
+            pass
+        pop_alive.compute_ll_ops = compute_ll_ops
+        pop_alive.llresult = lltype.Void
+
+        body = '\n'.join(self._deallocator_body_for_type('v', TYPE))
+        if not body:
+            return
+        src = 'def deallocator(v):\n' + body
+        d = {'pop_alive':pop_alive}
+        exec src in d
+        this = d['deallocator']
+        g = translator.rtyper.annotate_helper(this, [lltype.Ptr(TYPE)])
+        translator.rtyper.specialize_more_blocks()
+        return g

Modified: pypy/dist/pypy/rpython/memory/test/test_gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/test/test_gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/test/test_gctransform.py	Sun Jan 29 19:47:15 2006
@@ -240,3 +240,40 @@
             return 0
         return 1
     t = rtype_and_transform(f, [], gctransform.GCTransformer)
+
+# ----------------------------------------------------------------------
+
+def make_deallocator(TYPE, view=False):
+    def f():
+        pass
+    t = TranslationContext()
+    t.buildannotator().build_types(f, [])
+    t.buildrtyper().specialize(t)
+    
+    transformer = gctransform.GCTransformer()
+    v = Variable()
+    v.concretetype = TYPE
+    graph = transformer.deallocation_graph_for_type(t, TYPE, v)
+    if view:
+        t.view()
+    return graph
+
+def dont_test_deallocator_simple():
+    S = lltype.GcStruct("S", ('x', lltype.Signed))
+    dgraph = make_deallocator(S)
+    assert dgraph is None
+
+def test_deallocator_less_simple():
+    TPtr = lltype.Ptr(lltype.GcStruct("T", ('a', lltype.Signed)))
+    S = lltype.GcStruct(
+        "S",
+        ('x', lltype.Signed),
+        ('y', TPtr),
+        ('z', TPtr),
+        )
+    dgraph = make_deallocator(S)
+
+def test_deallocator_less_simple2():
+    S = lltype.GcArray(lltype.Ptr(lltype.GcStruct("S", ('x', lltype.Signed))))
+    dgraph = make_deallocator(S)
+    



More information about the Pypy-commit mailing list