From: <th...@us...> - 2009-07-15 20:05:58
|
Revision: 6539 http://jython.svn.sourceforge.net/jython/?rev=6539&view=rev Author: thobes Date: 2009-07-15 20:05:51 +0000 (Wed, 15 Jul 2009) Log Message: ----------- Changed the ContextManager interface to get the exception as one argument, this reduces the need fo object (re-) creation. This also reduces the overhead even more for the optimized context managers, since parts of the code that was previously generated in the compiled Python code is now part of the library in ContextGuard. Also fixed a bug in the code for turning generator functions into optimized context managers. Modified Paths: -------------- trunk/jython/src/org/python/compiler/CodeCompiler.java trunk/jython/src/org/python/core/ContextGuard.java trunk/jython/src/org/python/core/ContextManager.java trunk/jython/src/org/python/modules/_threading/Condition.java trunk/jython/src/org/python/modules/_threading/Lock.java Modified: trunk/jython/src/org/python/compiler/CodeCompiler.java =================================================================== --- trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-15 02:34:53 UTC (rev 6538) +++ trunk/jython/src/org/python/compiler/CodeCompiler.java 2009-07-15 20:05:51 UTC (rev 6539) @@ -2278,7 +2278,7 @@ final Method contextGuard_getManager = Method.getMethod("org.python.core.ContextManager getManager (org.python.core.PyObject)"); final Method __enter__ = Method.getMethod("org.python.core.PyObject __enter__ (org.python.core.ThreadState)"); - final Method __exit__ = Method.getMethod("boolean __exit__ (org.python.core.ThreadState,org.python.core.PyObject,org.python.core.PyObject,org.python.core.PyObject)"); + final Method __exit__ = Method.getMethod("boolean __exit__ (org.python.core.ThreadState,org.python.core.PyException)"); // mgr = (EXPR) visit(node.getInternalContext_expr()); @@ -2313,9 +2313,7 @@ public void finalBody(CodeCompiler compiler) throws Exception { compiler.code.aload(mgr_tmp); loadThreadState(); - compiler.getNone(); - compiler.code.dup(); - compiler.code.dup(); + compiler.code.aconst_null(); compiler.code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor()); compiler.code.pop(); } @@ -2355,25 +2353,15 @@ loadFrame(); code.invokestatic("org/python/core/Py", "setException", "(" + $throwable + $pyFrame + ")" + $pyExc); - code.pop(); + code.aload(mgr_tmp); + code.swap(); loadThreadState(); - code.getfield("org/python/core/ThreadState", "exception", $pyExc); - int ts_tmp = storeTop(); + code.swap(); + code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor()); // # The exceptional case is handled here // exc = False # implicit // if not exit(*sys.exc_info()): - code.aload(mgr_tmp); - loadThreadState(); - code.aload(ts_tmp); - code.getfield("org/python/core/PyException", "type", $pyObj); - code.aload(ts_tmp); - code.getfield("org/python/core/PyException", "value", $pyObj); - code.aload(ts_tmp); - code.freeLocal(ts_tmp); - code.getfield("org/python/core/PyException", "traceback", "Lorg/python/core/PyTraceback;"); - code.checkcast("org/python/core/PyObject"); - code.invokeinterface(Type.getType(ContextManager.class).getInternalName(), __exit__.getName(), __exit__.getDescriptor()); code.ifne(label_end); // raise // # The exception is swallowed if exit() returns true Modified: trunk/jython/src/org/python/core/ContextGuard.java =================================================================== --- trunk/jython/src/org/python/core/ContextGuard.java 2009-07-15 02:34:53 UTC (rev 6538) +++ trunk/jython/src/org/python/core/ContextGuard.java 2009-07-15 20:05:51 UTC (rev 6539) @@ -17,9 +17,18 @@ return __enter__method.__call__(ts); } - public boolean __exit__(ThreadState ts, PyObject type, PyObject value, - PyObject traceback) { - return __exit__method.__call__(ts, type, value, traceback).__nonzero__(); + public boolean __exit__(ThreadState ts, PyException exception) { + final PyObject type, value, traceback; + if (exception != null) { + type = exception.type; + value = exception.value; + traceback = exception.traceback; + } else { + type = value = traceback = Py.None; + } + return __exit__method.__call__(ts, type, + value == null ? Py.None : value, + traceback == null ? Py.None : traceback).__nonzero__(); } public static ContextManager getManager(PyObject manager) { @@ -43,7 +52,7 @@ * finally: * print "done" */ - + public static PyObject makeManager(PyObject object) { if (object instanceof PyFunction) { PyFunction function = (PyFunction) object; @@ -125,19 +134,18 @@ return res; } - public boolean __exit__(ThreadState ts, PyObject type, PyObject value, - PyObject traceback) { - PyException ex = null; - if (type != null && type != Py.None) { - ex = Py.makeException(type, value, traceback); - frame.setGeneratorInput(ex); + public boolean __exit__(ThreadState ts, PyException exception) { + if (exception != null) { + frame.setGeneratorInput(exception); } - PyObject res = null; + final PyObject res; try { res = body(ts); } catch(PyException e) { - if (e == ex) { + if (e.equals(exception)) { return false; + } else { + throw e; } } if (frame.f_lasti != -1) { Modified: trunk/jython/src/org/python/core/ContextManager.java =================================================================== --- trunk/jython/src/org/python/core/ContextManager.java 2009-07-15 02:34:53 UTC (rev 6538) +++ trunk/jython/src/org/python/core/ContextManager.java 2009-07-15 20:05:51 UTC (rev 6539) @@ -7,5 +7,5 @@ public interface ContextManager { public PyObject __enter__(ThreadState ts); - public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback); + public boolean __exit__(ThreadState ts, PyException exception); } Modified: trunk/jython/src/org/python/modules/_threading/Condition.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/Condition.java 2009-07-15 02:34:53 UTC (rev 6538) +++ trunk/jython/src/org/python/modules/_threading/Condition.java 2009-07-15 20:05:51 UTC (rev 6539) @@ -2,6 +2,7 @@ import org.python.core.ContextManager; import org.python.core.Py; +import org.python.core.PyException; import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyType; @@ -65,7 +66,7 @@ _lock.release(); } - public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback) { + public boolean __exit__(ThreadState ts, PyException exception) { _lock.release(); return false; } Modified: trunk/jython/src/org/python/modules/_threading/Lock.java =================================================================== --- trunk/jython/src/org/python/modules/_threading/Lock.java 2009-07-15 02:34:53 UTC (rev 6538) +++ trunk/jython/src/org/python/modules/_threading/Lock.java 2009-07-15 20:05:51 UTC (rev 6539) @@ -3,6 +3,7 @@ import java.util.concurrent.locks.ReentrantLock; import org.python.core.ContextManager; import org.python.core.Py; +import org.python.core.PyException; import org.python.core.PyNewWrapper; import org.python.core.PyObject; import org.python.core.PyType; @@ -76,7 +77,7 @@ return false; } - public boolean __exit__(ThreadState ts, PyObject type, PyObject value, PyObject traceback) { + public boolean __exit__(ThreadState ts, PyException exception) { _lock.unlock(); return false; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |