summaryrefslogtreecommitdiffstats
path: root/Python/ceval.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/ceval.c')
-rw-r--r--Python/ceval.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/Python/ceval.c b/Python/ceval.c
index c371f28..e2f38ac 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -97,6 +97,7 @@ static PyObject *load_args(PyObject ***, int);
#define CALL_FLAG_KW 2
#ifdef LLTRACE
+static int lltrace;
static int prtrace(PyObject *, char *);
#endif
static int call_trace(Py_tracefunc, PyObject *, PyFrameObject *,
@@ -540,9 +541,6 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throw)
unsigned char *first_instr;
PyObject *names;
PyObject *consts;
-#ifdef LLTRACE
- int lltrace;
-#endif
#if defined(Py_DEBUG) || defined(LLTRACE)
/* Make it easier to find out where we are with a debugger */
char *filename;
@@ -661,10 +659,12 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throw)
#define STACKADJ(n) { (void)(BASIC_STACKADJ(n), \
lltrace && prtrace(TOP(), "stackadj")); \
assert(STACK_LEVEL() <= f->f_stacksize); }
+#define EXT_POP(STACK_POINTER) (lltrace && prtrace(*(STACK_POINTER), "ext_pop"), *--(STACK_POINTER))
#else
#define PUSH(v) BASIC_PUSH(v)
#define POP() BASIC_POP()
#define STACKADJ(n) BASIC_STACKADJ(n)
+#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
#endif
/* Local variable macros */
@@ -2172,6 +2172,43 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throw)
STACK_LEVEL());
continue;
+ 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 or WHY_CONTINUE), retval
+ - SECOND = WHY_*; no retval below it
+ - (SECOND, THIRD, FOURTH) = exc_info()
+ In the last case, we must call
+ TOP(SECOND, THIRD, FOURTH)
+ otherwise we must call
+ TOP(None, None, None)
+ but we must preserve the stack entries below TOP.
+ The code here just sets the stack up for the call;
+ separate CALL_FUNCTION(3) and POP_TOP opcodes are
+ emitted by the compiler.
+ */
+
+ x = TOP();
+ u = SECOND();
+ if (PyInt_Check(u) || u == Py_None) {
+ u = v = w = Py_None;
+ }
+ else {
+ v = THIRD();
+ w = FOURTH();
+ }
+ Py_INCREF(u);
+ Py_INCREF(v);
+ Py_INCREF(w);
+ PUSH(u);
+ PUSH(v);
+ PUSH(w);
+ break;
+ }
+
case CALL_FUNCTION:
{
PyObject **sp;
@@ -2511,9 +2548,9 @@ fast_yield:
return retval;
}
-/* this is gonna seem *real weird*, but if you put some other code between
+/* This is gonna seem *real weird*, but if you put some other code between
PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
- the test in the if statement in Misc/gdbinit:pystack* */
+ the test in the if statements in Misc/gdbinit (pystack and pystackv). */
PyObject *
PyEval_EvalCodeEx(PyCodeObject *co, PyObject *globals, PyObject *locals,
@@ -3473,8 +3510,6 @@ PyEval_GetFuncDesc(PyObject *func)
}
}
-#define EXT_POP(STACK_POINTER) (*--(STACK_POINTER))
-
static void
err_args(PyObject *func, int flags, int nargs)
{