diff options
author | Nick Coghlan <ncoghlan@gmail.com> | 2008-03-07 14:13:28 (GMT) |
---|---|---|
committer | Nick Coghlan <ncoghlan@gmail.com> | 2008-03-07 14:13:28 (GMT) |
commit | 7af53be66f8c074902e0e7e7c452a280538582bc (patch) | |
tree | c2d5933745c44a5099ceadb4f81bc7aa82dfe1c1 /Python/ceval.c | |
parent | e75f59a578a4538451c1d96610a6d183ba8f2e81 (diff) | |
download | cpython-7af53be66f8c074902e0e7e7c452a280538582bc.zip cpython-7af53be66f8c074902e0e7e7c452a280538582bc.tar.gz cpython-7af53be66f8c074902e0e7e7c452a280538582bc.tar.bz2 |
Speed up with statements by storing the __exit__ method on the stack instead of in a temp variable (bumps the magic number for pyc files)
Diffstat (limited to 'Python/ceval.c')
-rw-r--r-- | Python/ceval.c | 74 |
1 files changed, 50 insertions, 24 deletions
diff --git a/Python/ceval.c b/Python/ceval.c index f210c9f..4fc1709 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -2254,17 +2254,20 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) case WITH_CLEANUP: { - /* TOP is the context.__exit__ bound method. - Below that are 1-3 values indicating how/why - we entered the finally clause: - - SECOND = None - - (SECOND, THIRD) = (WHY_{RETURN,CONTINUE}), retval - - SECOND = WHY_*; no retval below it - - (SECOND, THIRD, FOURTH) = exc_info() + /* At the top of the stack are 1-3 values indicating + how/why we entered the finally clause: + - TOP = None + - (TOP, SECOND) = (WHY_{RETURN,CONTINUE}), retval + - TOP = WHY_*; no retval below it + - (TOP, SECOND, THIRD) = exc_info() + Below them is EXIT, the context.__exit__ bound method. In the last case, we must call - TOP(SECOND, THIRD, FOURTH) + EXIT(TOP, SECOND, THIRD) otherwise we must call - TOP(None, None, None) + EXIT(None, None, None) + + In all cases, we remove EXIT from the stack, leaving + the rest in the same order. In addition, if the stack represents an exception, *and* the function call returns a 'true' value, we @@ -2273,36 +2276,59 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) should still be resumed.) */ - x = TOP(); - u = SECOND(); - if (PyInt_Check(u) || u == Py_None) { + PyObject *exit_func; + + u = POP(); + if (u == Py_None) { + exit_func = TOP(); + SET_TOP(u); + v = w = Py_None; + } + else if (PyInt_Check(u)) { + switch(PyInt_AS_LONG(u)) { + case WHY_RETURN: + case WHY_CONTINUE: + /* Retval in TOP. */ + exit_func = SECOND(); + SET_SECOND(TOP()); + SET_TOP(u); + break; + default: + exit_func = TOP(); + SET_TOP(u); + break; + } u = v = w = Py_None; } else { - v = THIRD(); - w = FOURTH(); + v = TOP(); + w = SECOND(); + exit_func = THIRD(); + SET_TOP(u); + SET_SECOND(v); + SET_THIRD(w); } /* XXX Not the fastest way to call it... */ - x = PyObject_CallFunctionObjArgs(x, u, v, w, NULL); - if (x == NULL) + x = PyObject_CallFunctionObjArgs(exit_func, u, v, w, + NULL); + if (x == NULL) { + Py_DECREF(exit_func); break; /* Go to error exit */ + } if (u != Py_None && PyObject_IsTrue(x)) { /* There was an exception and a true return */ - Py_DECREF(x); - x = TOP(); /* Again */ - STACKADJ(-3); + STACKADJ(-2); Py_INCREF(Py_None); SET_TOP(Py_None); - Py_DECREF(x); Py_DECREF(u); Py_DECREF(v); Py_DECREF(w); } else { - /* Let END_FINALLY do its thing */ - Py_DECREF(x); - x = POP(); - Py_DECREF(x); + /* The stack was rearranged to remove EXIT + above. Let END_FINALLY do its thing */ } + Py_DECREF(x); + Py_DECREF(exit_func); PREDICT(END_FINALLY); break; } |