[pypy-svn] r23380 - in pypy/dist/pypy: rpython/memory translator/c/test

cfbolz at codespeak.net cfbolz at codespeak.net
Wed Feb 15 22:23:16 CET 2006


Author: cfbolz
Date: Wed Feb 15 22:23:15 2006
New Revision: 23380

Modified:
   pypy/dist/pypy/rpython/memory/gctransform.py
   pypy/dist/pypy/translator/c/test/test_newgc.py
Log:
(arigo, cfbolz):

the setfield and setarrayitem in refcounting was doing stuff in the wrong
order, leading to a crash in obscure cases. test + fix


Modified: pypy/dist/pypy/rpython/memory/gctransform.py
==============================================================================
--- pypy/dist/pypy/rpython/memory/gctransform.py	(original)
+++ pypy/dist/pypy/rpython/memory/gctransform.py	Wed Feb 15 22:23:15 2006
@@ -349,9 +349,9 @@
         getoldvalop = SpaceOperation("getfield",
                                      [op.args[0], op.args[1]], oldval)
         result = [getoldvalop]
-        result.extend(self.pop_alive(oldval))
         result.extend(self.push_alive(op.args[2]))
         result.append(op)
+        result.extend(self.pop_alive(oldval))
         return result
 
     def replace_setarrayitem(self, op):
@@ -361,9 +361,9 @@
         getoldvalop = SpaceOperation("getarrayitem",
                                      [op.args[0], op.args[1]], oldval)
         result = [getoldvalop]
-        result.extend(self.pop_alive(oldval))
         result.extend(self.push_alive(op.args[2]))
         result.append(op)
+        result.extend(self.pop_alive(oldval))
         return result
 
     def get_rtti(self, TYPE):

Modified: pypy/dist/pypy/translator/c/test/test_newgc.py
==============================================================================
--- pypy/dist/pypy/translator/c/test/test_newgc.py	(original)
+++ pypy/dist/pypy/translator/c/test/test_newgc.py	Wed Feb 15 22:23:15 2006
@@ -164,3 +164,23 @@
     fn = compile_func(func, [])
     # does not crash
     fn()
+
+def test_wrong_order_setitem():
+    import os
+    class A(object):
+        pass
+    a = A()
+    a.b = None
+    class B(object):
+        def __del__(self):
+            a.freed += 1
+            a.b = None
+    def f(n):
+        a.freed = 0
+        a.b = B()
+        if n:
+            a.b = None
+        return a.freed
+    fn = compile_func(f, [int])
+    res = fn(1)
+    assert res == 1



More information about the Pypy-commit mailing list