Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a530a95

Browse files
authored
bpo-44878: Remove loop from interpreter. All dispatching is done by gotos. (GH-27727)
1 parent f08e6d1 commit a530a95

2 files changed

Lines changed: 19 additions & 14 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Remove the loop from the bytecode interpreter. All instructions end with a
2+
DISPATCH macro, so the loop is now redundant.

Python/ceval.c

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,7 +1280,7 @@ eval_frame_handle_pending(PyThreadState *tstate)
12801280

12811281
#define CHECK_EVAL_BREAKER() \
12821282
if (_Py_atomic_load_relaxed(eval_breaker)) { \
1283-
continue; \
1283+
goto check_eval_breaker; \
12841284
}
12851285

12861286

@@ -1584,7 +1584,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
15841584
assert(!_PyErr_Occurred(tstate));
15851585
#endif
15861586

1587-
for (;;) {
1587+
check_eval_breaker:
1588+
{
15881589
assert(STACK_LEVEL() >= 0); /* else underflow */
15891590
assert(STACK_LEVEL() <= co->co_stacksize); /* else overflow */
15901591
assert(!_PyErr_Occurred(tstate));
@@ -4292,6 +4293,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
42924293
CHECK_EVAL_BREAKER();
42934294
DISPATCH();
42944295
}
4296+
42954297
TARGET(CALL_METHOD_KW): {
42964298
/* Designed to work in tandem with LOAD_METHOD. Same as CALL_METHOD
42974299
but pops TOS to get a tuple of keyword names. */
@@ -4315,6 +4317,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, InterpreterFrame *frame, int thr
43154317
CHECK_EVAL_BREAKER();
43164318
DISPATCH();
43174319
}
4320+
43184321
TARGET(CALL_FUNCTION): {
43194322
PREDICTED(CALL_FUNCTION);
43204323
PyObject **sp, *res;
@@ -4621,7 +4624,17 @@ MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR)
46214624
int level, handler, lasti;
46224625
if (get_exception_handler(co, offset, &level, &handler, &lasti) == 0) {
46234626
// No handlers, so exit.
4624-
break;
4627+
assert(retval == NULL);
4628+
assert(_PyErr_Occurred(tstate));
4629+
4630+
/* Pop remaining stack entries. */
4631+
while (!EMPTY()) {
4632+
PyObject *o = POP();
4633+
Py_XDECREF(o);
4634+
}
4635+
frame->stackdepth = 0;
4636+
frame->f_state = FRAME_RAISED;
4637+
goto exiting;
46254638
}
46264639

46274640
assert(STACK_LEVEL() >= level);
@@ -4661,18 +4674,8 @@ MISS_WITH_OPARG_COUNTER(BINARY_SUBSCR)
46614674
NEXTOPARG();
46624675
PRE_DISPATCH_GOTO();
46634676
DISPATCH_GOTO();
4664-
} /* main loop */
4665-
4666-
assert(retval == NULL);
4667-
assert(_PyErr_Occurred(tstate));
4668-
4669-
/* Pop remaining stack entries. */
4670-
while (!EMPTY()) {
4671-
PyObject *o = POP();
4672-
Py_XDECREF(o);
46734677
}
4674-
frame->stackdepth = 0;
4675-
frame->f_state = FRAME_RAISED;
4678+
46764679
exiting:
46774680
if (cframe.use_tracing) {
46784681
if (tstate->c_tracefunc) {

0 commit comments

Comments
 (0)