[pypy-svn] r25344 - in pypy/branch/explicit-exceptions: rpython/memory translator/c translator/c/test

mwh at codespeak.net mwh at codespeak.net
Wed Apr 5 11:40:24 CEST 2006


Author: mwh
Date: Wed Apr  5 11:40:22 2006
New Revision: 25344

Modified:
   pypy/branch/explicit-exceptions/rpython/memory/gctransform.py
   pypy/branch/explicit-exceptions/translator/c/funcgen.py
   pypy/branch/explicit-exceptions/translator/c/test/test_genc.py
Log:
(hpk, mwh, pedronis)
fix the "PyObjPtr mess" on the explicit exceptions branch
- don't special case PyObject* in genc at all
- special case the few PyObject*-returning operations that need to be followed
  with an incref in gctransform
- a new entry in the 'most insane test of the year' contest


Modified: pypy/branch/explicit-exceptions/rpython/memory/gctransform.py
==============================================================================
--- pypy/branch/explicit-exceptions/rpython/memory/gctransform.py	(original)
+++ pypy/branch/explicit-exceptions/rpython/memory/gctransform.py	Wed Apr  5 11:40:22 2006
@@ -110,7 +110,12 @@
             origname = op.opname
             op = ops[index]
             if var_needsgc(op.result):
-                if op.opname not in ('direct_call', 'indirect_call') and not var_ispyobj(op.result):
+                if var_ispyobj(op.result):
+                    assert op.opname != 'cast_pointer', 'casting to a PyObject*??'
+                    if op.opname in ('getfield', 'getarrayitem', 'same_as'):
+                        lst = list(self.push_alive(op.result))
+                        newops.extend(lst)
+                elif op.opname not in ('direct_call', 'indirect_call'):
                     lst = list(self.push_alive(op.result))
                     newops.extend(lst)
                 livevars.append(op.result)

Modified: pypy/branch/explicit-exceptions/translator/c/funcgen.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/funcgen.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/funcgen.py	Wed Apr  5 11:40:22 2006
@@ -11,9 +11,6 @@
 PyObjPtr = Ptr(PyObject)
 LOCALVAR = 'l_%s'
 
-# I'm not absolutely sure, so just in case:
-NEED_OLD_EXTRA_REFS = True  # oupps seems to be
-
 class FunctionCodeGenerator(object):
     """
     Collects information about a function which we have to generate
@@ -364,9 +361,6 @@
         T = self.lltypemap(op.result)
         newvalue = self.expr(op.result, special_case_void=False)
         result = ['%s = %s;' % (newvalue, sourceexpr)]
-        # need to adjust the refcount of the result only for PyObjects
-        if NEED_OLD_EXTRA_REFS and T == PyObjPtr:
-            result.append('Py_XINCREF(%s);' % newvalue)
         result = '\n'.join(result)
         if T is Void:
             result = '/* %s */' % result
@@ -506,9 +500,7 @@
         result.append('%s = (%s)%s;' % (self.expr(op.result),
                                         cdecl(typename, ''),
                                         self.expr(op.args[0])))
-
-        if NEED_OLD_EXTRA_REFS and TYPE == PyObjPtr:
-            result.append('Py_XINCREF(%s);'%(LOCAL_VAR % op.result.name))
+        assert TYPE != PyObjPtr
         return '\t'.join(result)
 
     OP_CAST_PTR_TO_ADR = OP_CAST_POINTER
@@ -527,8 +519,6 @@
         if TYPE is not Void:
             result.append('%s = %s;' % (self.expr(op.result),
                                         self.expr(op.args[0])))
-            if NEED_OLD_EXTRA_REFS and TYPE == PyObjPtr:
-                result.append('Py_XINCREF(%s);'%(LOCAL_VAR % op.result.name))
         return '\t'.join(result)
 
     def OP_HINT(self, op):

Modified: pypy/branch/explicit-exceptions/translator/c/test/test_genc.py
==============================================================================
--- pypy/branch/explicit-exceptions/translator/c/test/test_genc.py	(original)
+++ pypy/branch/explicit-exceptions/translator/c/test/test_genc.py	Wed Apr  5 11:40:22 2006
@@ -298,3 +298,35 @@
 
     f1 = compile(f, [])
     assert f1() == 1
+
+# this test shows if we have a problem with refcounting PyObject
+def test_refcount_pyobj():
+    def prob_with_pyobj(b):
+        return 3, b
+
+    f = compile(prob_with_pyobj, [object])
+    from sys import getrefcount as g
+    obj = None
+    before = g(obj)
+    f(obj)
+    after = g(obj)
+    assert before == after
+
+def test_refcount_pyobj_setfield():
+    import weakref, gc
+    class S(object):
+        def __init__(self):
+            self.p = None
+    def foo(wref, objfact):
+        s = S()
+        b = objfact()
+        s.p = b
+        wr = wref(b)
+        s.p = None
+        return wr
+    f = compile(foo, [object, object], backendopt=False)
+    class C(object):
+        pass
+    wref = f(weakref.ref, C)
+    gc.collect()
+    assert not wref()



More information about the Pypy-commit mailing list