From: <zy...@us...> - 2010-04-26 14:27:44
|
Revision: 7047 http://jython.svn.sourceforge.net/jython/?rev=7047&view=rev Author: zyasoft Date: 2010-04-26 14:27:38 +0000 (Mon, 26 Apr 2010) Log Message: ----------- Fixed weakref leak in calling functions with kwargs by nulling out after call (in compiler). Fixes #1586. Bumped bytecode magic Modified Paths: -------------- trunk/jython/Lib/test/test_weakref_jy.py trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/core/imp.java trunk/jython/src/org/python/modules/thread/PyLocal.java Modified: trunk/jython/Lib/test/test_weakref_jy.py =================================================================== --- trunk/jython/Lib/test/test_weakref_jy.py 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/Lib/test/test_weakref_jy.py 2010-04-26 14:27:38 UTC (rev 7047) @@ -5,6 +5,7 @@ import unittest import weakref from test import test_support +from test_weakref import extra_collect class ReferencesTestCase(unittest.TestCase): @@ -38,8 +39,45 @@ self.assertEqual(len(hash_called), 2) +class ArgsTestCase(unittest.TestCase): + + # XXX consider adding other tests for dict, list, etc + + def test_python_fn_kwargs(self): + + weakrefs = [] + sentinel = [] + + def watch(obj, kwarg=True): + self.assertEqual(kwarg, True) + # log the death of the reference by appending to the sentinel + ref = weakref.ref(obj, sentinel.append) + weakrefs.append(ref) + + self.assert_(not sentinel) + + thunk1 = lambda: None + watch(thunk1) + self.assert_(not sentinel) + + del thunk1 + extra_collect() + self.assert_(sentinel) + + del sentinel[:] + + thunk2 = lambda: None + watch(thunk2, kwarg=True) # <--- only difference: called with a kwarg + self.assert_(not sentinel) + + del thunk2 + extra_collect() + self.assert_(sentinel) + + + def test_main(): - test_support.run_unittest(ReferencesTestCase) + test_support.run_unittest(ReferencesTestCase, ArgsTestCase) if __name__ == '__main__': Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -1804,15 +1804,14 @@ code.aload(argArray); code.aload(strArray); - code.freeLocal(argArray); code.freeLocal(strArray); code.dup2_x2(); code.pop2(); stackConsume(3); // target + starargs + kwargs - code.invokevirtual(p(PyObject.class), "_callextra", sig(PyObject.class, PyObject[].class, String[].class, PyObject.class, PyObject.class)); + freeArray(argArray); } else if (keys.size() > 0) { loadThreadState(); stackProduce(p(ThreadState.class)); @@ -1820,11 +1819,11 @@ int strArray = makeStrings(code, keys); code.aload(argArray); code.aload(strArray); - code.freeLocal(argArray); code.freeLocal(strArray); stackConsume(2); // target + ts code.invokevirtual(p(PyObject.class), "__call__", sig(PyObject.class, ThreadState.class, PyObject[].class, String[].class)); + freeArray(argArray); } else { loadThreadState(); stackProduce(p(ThreadState.class)); Modified: trunk/jython/src/org/python/core/imp.java =================================================================== --- trunk/jython/src/org/python/core/imp.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/core/imp.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -21,7 +21,7 @@ private static final String UNKNOWN_SOURCEFILE = "<unknown>"; - private static final int APIVersion = 28; + private static final int APIVersion = 29; public static final int NO_MTIME = -1; Modified: trunk/jython/src/org/python/modules/thread/PyLocal.java =================================================================== --- trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-25 18:33:34 UTC (rev 7046) +++ trunk/jython/src/org/python/modules/thread/PyLocal.java 2010-04-26 14:27:38 UTC (rev 7047) @@ -59,7 +59,9 @@ if (where[0] == TYPE && args.length > 0) { throw Py.TypeError("Initialization arguments are not supported"); } - this.args = args; + // caller zeros out `args` + this.args = new PyObject[args.length]; + System.arraycopy(args, 0, this.args, 0, args.length); this.keywords = keywords; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |