Only check evalbreaker after calls and on backwards egdes. Makes sure that __exit__ or __aexit__ is called in with statments in case of interrupt.
This commit is contained in:
parent
869c0c99b9
commit
6afa580bb4
|
@ -0,0 +1,3 @@
|
|||
Only handle asynchronous exceptions and requests to drop the GIL when
|
||||
returning from a call or on the back edges of loops. Makes sure that
|
||||
:meth:`__exit__` is always called in with statements, even for interrupts.
|
|
@ -837,7 +837,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
TARGET_##op
|
||||
|
||||
#ifdef LLTRACE
|
||||
#define FAST_DISPATCH() \
|
||||
#define DISPATCH() \
|
||||
{ \
|
||||
if (!lltrace && !_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
|
||||
f->f_lasti = INSTR_OFFSET(); \
|
||||
|
@ -847,7 +847,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
goto fast_next_opcode; \
|
||||
}
|
||||
#else
|
||||
#define FAST_DISPATCH() \
|
||||
#define DISPATCH() \
|
||||
{ \
|
||||
if (!_Py_TracingPossible(ceval) && !PyDTrace_LINE_ENABLED()) { \
|
||||
f->f_lasti = INSTR_OFFSET(); \
|
||||
|
@ -858,20 +858,17 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
#endif
|
||||
|
||||
#define DISPATCH() \
|
||||
{ \
|
||||
if (!_Py_atomic_load_relaxed(eval_breaker)) { \
|
||||
FAST_DISPATCH(); \
|
||||
} \
|
||||
continue; \
|
||||
}
|
||||
|
||||
#else
|
||||
#define TARGET(op) op
|
||||
#define FAST_DISPATCH() goto fast_next_opcode
|
||||
#define DISPATCH() continue
|
||||
#define DISPATCH() goto fast_next_opcode
|
||||
|
||||
#endif
|
||||
|
||||
#define CHECK_EVAL_BREAKER() \
|
||||
if (_Py_atomic_load_relaxed(eval_breaker)) { \
|
||||
continue; \
|
||||
}
|
||||
|
||||
|
||||
/* Tuple access macros */
|
||||
|
||||
|
@ -1323,7 +1320,7 @@ main_loop:
|
|||
and that all operation that succeed call [FAST_]DISPATCH() ! */
|
||||
|
||||
case TARGET(NOP): {
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(LOAD_FAST): {
|
||||
|
@ -1336,7 +1333,7 @@ main_loop:
|
|||
}
|
||||
Py_INCREF(value);
|
||||
PUSH(value);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(LOAD_CONST): {
|
||||
|
@ -1344,20 +1341,20 @@ main_loop:
|
|||
PyObject *value = GETITEM(consts, oparg);
|
||||
Py_INCREF(value);
|
||||
PUSH(value);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(STORE_FAST): {
|
||||
PREDICTED(STORE_FAST);
|
||||
PyObject *value = POP();
|
||||
SETLOCAL(oparg, value);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(POP_TOP): {
|
||||
PyObject *value = POP();
|
||||
Py_DECREF(value);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(ROT_TWO): {
|
||||
|
@ -1365,7 +1362,7 @@ main_loop:
|
|||
PyObject *second = SECOND();
|
||||
SET_TOP(second);
|
||||
SET_SECOND(top);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(ROT_THREE): {
|
||||
|
@ -1375,7 +1372,7 @@ main_loop:
|
|||
SET_TOP(second);
|
||||
SET_SECOND(third);
|
||||
SET_THIRD(top);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(ROT_FOUR): {
|
||||
|
@ -1387,14 +1384,14 @@ main_loop:
|
|||
SET_SECOND(third);
|
||||
SET_THIRD(fourth);
|
||||
SET_FOURTH(top);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(DUP_TOP): {
|
||||
PyObject *top = TOP();
|
||||
Py_INCREF(top);
|
||||
PUSH(top);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(DUP_TOP_TWO): {
|
||||
|
@ -1405,7 +1402,7 @@ main_loop:
|
|||
STACK_GROW(2);
|
||||
SET_TOP(top);
|
||||
SET_SECOND(second);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(UNARY_POSITIVE): {
|
||||
|
@ -2147,7 +2144,7 @@ main_loop:
|
|||
UNWIND_EXCEPT_HANDLER(b);
|
||||
Py_DECREF(POP());
|
||||
JUMPBY(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
else {
|
||||
PyObject *val = POP();
|
||||
|
@ -2161,7 +2158,7 @@ main_loop:
|
|||
PyObject *value = PyExc_AssertionError;
|
||||
Py_INCREF(value);
|
||||
PUSH(value);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(LOAD_BUILD_CLASS): {
|
||||
|
@ -2880,7 +2877,7 @@ main_loop:
|
|||
Py_DECREF(right);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
PREDICT(POP_JUMP_IF_TRUE);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(CONTAINS_OP): {
|
||||
|
@ -2897,7 +2894,7 @@ main_loop:
|
|||
PUSH(b);
|
||||
PREDICT(POP_JUMP_IF_FALSE);
|
||||
PREDICT(POP_JUMP_IF_TRUE);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
#define CANNOT_CATCH_MSG "catching classes that do not inherit from "\
|
||||
|
@ -2994,7 +2991,7 @@ main_loop:
|
|||
|
||||
case TARGET(JUMP_FORWARD): {
|
||||
JUMPBY(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
case TARGET(POP_JUMP_IF_FALSE): {
|
||||
|
@ -3003,12 +3000,12 @@ main_loop:
|
|||
int err;
|
||||
if (cond == Py_True) {
|
||||
Py_DECREF(cond);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
if (cond == Py_False) {
|
||||
Py_DECREF(cond);
|
||||
JUMPTO(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
err = PyObject_IsTrue(cond);
|
||||
Py_DECREF(cond);
|
||||
|
@ -3027,12 +3024,12 @@ main_loop:
|
|||
int err;
|
||||
if (cond == Py_False) {
|
||||
Py_DECREF(cond);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
if (cond == Py_True) {
|
||||
Py_DECREF(cond);
|
||||
JUMPTO(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
err = PyObject_IsTrue(cond);
|
||||
Py_DECREF(cond);
|
||||
|
@ -3052,11 +3049,11 @@ main_loop:
|
|||
if (cond == Py_True) {
|
||||
STACK_SHRINK(1);
|
||||
Py_DECREF(cond);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
if (cond == Py_False) {
|
||||
JUMPTO(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
err = PyObject_IsTrue(cond);
|
||||
if (err > 0) {
|
||||
|
@ -3076,11 +3073,11 @@ main_loop:
|
|||
if (cond == Py_False) {
|
||||
STACK_SHRINK(1);
|
||||
Py_DECREF(cond);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
if (cond == Py_True) {
|
||||
JUMPTO(oparg);
|
||||
FAST_DISPATCH();
|
||||
DISPATCH();
|
||||
}
|
||||
err = PyObject_IsTrue(cond);
|
||||
if (err > 0) {
|
||||
|
@ -3098,18 +3095,8 @@ main_loop:
|
|||
case TARGET(JUMP_ABSOLUTE): {
|
||||
PREDICTED(JUMP_ABSOLUTE);
|
||||
JUMPTO(oparg);
|
||||
#if FAST_LOOPS
|
||||
/* Enabling this path speeds-up all while and for-loops by bypassing
|
||||
the per-loop checks for signals. By default, this should be turned-off
|
||||
because it prevents detection of a control-break in tight loops like
|
||||
"while 1: pass". Compile with this option turned-on when you need
|
||||
the speed-up and do not need break checking inside tight loops (ones
|
||||
that contain only instructions ending with FAST_DISPATCH).
|
||||
*/
|
||||
FAST_DISPATCH();
|
||||
#else
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
#endif
|
||||
}
|
||||
|
||||
case TARGET(GET_ITER): {
|
||||
|
@ -3363,6 +3350,7 @@ main_loop:
|
|||
PUSH(res);
|
||||
if (res == NULL)
|
||||
goto error;
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -3376,6 +3364,7 @@ main_loop:
|
|||
if (res == NULL) {
|
||||
goto error;
|
||||
}
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -3395,6 +3384,7 @@ main_loop:
|
|||
if (res == NULL) {
|
||||
goto error;
|
||||
}
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
@ -3441,6 +3431,7 @@ main_loop:
|
|||
if (result == NULL) {
|
||||
goto error;
|
||||
}
|
||||
CHECK_EVAL_BREAKER();
|
||||
DISPATCH();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue