Skip to content

Commit f135b64

Browse files
committed
Switch from goto to do/while
1 parent 64155ab commit f135b64

File tree

1 file changed

+69
-73
lines changed

1 file changed

+69
-73
lines changed

Objects/genobject.c

Lines changed: 69 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ _PyGen_Finalize(PyObject *self)
153153
static void
154154
gen_clear_frame(PyGenObject *gen)
155155
{
156+
assert(gen->gi_frame_state == FRAME_CLEARED);
156157
_PyInterpreterFrame *frame = &gen->gi_iframe;
157158
frame->previous = NULL;
158159
_PyFrame_ClearExceptCode(frame);
@@ -285,48 +286,45 @@ gen_send_ex(PyGenObject *gen, PyObject *arg, PyObject **presult)
285286
{
286287
*presult = NULL;
287288
int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state);
288-
retry:
289-
if (frame_state == FRAME_CREATED && arg && arg != Py_None) {
290-
const char *msg = "can't send non-None value to a "
291-
"just-started generator";
292-
if (PyCoro_CheckExact(gen)) {
293-
msg = NON_INIT_CORO_MSG;
294-
}
295-
else if (PyAsyncGen_CheckExact(gen)) {
296-
msg = "can't send non-None value to a "
297-
"just-started async generator";
289+
do {
290+
if (frame_state == FRAME_CREATED && arg && arg != Py_None) {
291+
const char *msg = "can't send non-None value to a "
292+
"just-started generator";
293+
if (PyCoro_CheckExact(gen)) {
294+
msg = NON_INIT_CORO_MSG;
295+
}
296+
else if (PyAsyncGen_CheckExact(gen)) {
297+
msg = "can't send non-None value to a "
298+
"just-started async generator";
299+
}
300+
PyErr_SetString(PyExc_TypeError, msg);
301+
return PYGEN_ERROR;
298302
}
299-
PyErr_SetString(PyExc_TypeError, msg);
300-
return PYGEN_ERROR;
301-
}
302-
if (frame_state == FRAME_EXECUTING) {
303-
gen_raise_already_executing_error(gen);
304-
return PYGEN_ERROR;
305-
}
306-
if (FRAME_STATE_FINISHED(frame_state)) {
307-
if (PyCoro_CheckExact(gen)) {
308-
/* `gen` is an exhausted coroutine: raise an error,
309-
except when called from gen_close(), which should
310-
always be a silent method. */
311-
PyErr_SetString(
312-
PyExc_RuntimeError,
313-
"cannot reuse already awaited coroutine");
303+
if (frame_state == FRAME_EXECUTING) {
304+
gen_raise_already_executing_error(gen);
305+
return PYGEN_ERROR;
314306
}
315-
else if (arg) {
316-
/* `gen` is an exhausted generator:
317-
only return value if called from send(). */
318-
*presult = Py_NewRef(Py_None);
319-
return PYGEN_RETURN;
307+
if (FRAME_STATE_FINISHED(frame_state)) {
308+
if (PyCoro_CheckExact(gen)) {
309+
/* `gen` is an exhausted coroutine: raise an error,
310+
except when called from gen_close(), which should
311+
always be a silent method. */
312+
PyErr_SetString(
313+
PyExc_RuntimeError,
314+
"cannot reuse already awaited coroutine");
315+
}
316+
else if (arg) {
317+
/* `gen` is an exhausted generator:
318+
only return value if called from send(). */
319+
*presult = Py_NewRef(Py_None);
320+
return PYGEN_RETURN;
321+
}
322+
return PYGEN_ERROR;
320323
}
321-
return PYGEN_ERROR;
322-
}
323324

324-
assert((frame_state == FRAME_CREATED) ||
325-
FRAME_STATE_SUSPENDED(frame_state));
326-
327-
if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)) {
328-
goto retry;
329-
}
325+
assert((frame_state == FRAME_CREATED) ||
326+
FRAME_STATE_SUSPENDED(frame_state));
327+
} while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING));
330328

331329
return gen_send_ex2(gen, arg, presult, 0);
332330
}
@@ -422,29 +420,27 @@ gen_close(PyObject *self, PyObject *args)
422420
PyGenObject *gen = _PyGen_CAST(self);
423421

424422
int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state);
425-
retry:
426-
if (frame_state == FRAME_CREATED) {
427-
if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_COMPLETED)) {
428-
goto retry;
423+
do {
424+
if (frame_state == FRAME_CREATED) {
425+
if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_COMPLETED)) {
426+
continue;
427+
}
428+
Py_RETURN_NONE;
429429
}
430-
Py_RETURN_NONE;
431-
}
432430

433-
if (FRAME_STATE_FINISHED(frame_state)) {
434-
Py_RETURN_NONE;
435-
}
431+
if (FRAME_STATE_FINISHED(frame_state)) {
432+
Py_RETURN_NONE;
433+
}
436434

437-
if (frame_state == FRAME_EXECUTING) {
438-
gen_raise_already_executing_error(gen);
439-
return NULL;
440-
}
435+
if (frame_state == FRAME_EXECUTING) {
436+
gen_raise_already_executing_error(gen);
437+
return NULL;
438+
}
441439

442-
assert(frame_state == FRAME_SUSPENDED_YIELD_FROM ||
443-
frame_state == FRAME_SUSPENDED);
440+
assert(frame_state == FRAME_SUSPENDED_YIELD_FROM ||
441+
frame_state == FRAME_SUSPENDED);
444442

445-
if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)) {
446-
goto retry;
447-
}
443+
} while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING));
448444

449445
int err = 0;
450446
_PyInterpreterFrame *frame = &gen->gi_iframe;
@@ -584,27 +580,27 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
584580
PyObject *typ, PyObject *val, PyObject *tb)
585581
{
586582
int8_t frame_state = FT_ATOMIC_LOAD_INT8_RELAXED(gen->gi_frame_state);
587-
retry:
588-
if (frame_state == FRAME_EXECUTING) {
589-
gen_raise_already_executing_error(gen);
590-
return NULL;
591-
}
583+
do {
584+
if (frame_state == FRAME_EXECUTING) {
585+
gen_raise_already_executing_error(gen);
586+
return NULL;
587+
}
592588

593-
if (FRAME_STATE_FINISHED(frame_state)) {
594-
if (PyCoro_CheckExact(gen)) {
595-
/* `gen` is an exhausted coroutine: raise an error */
596-
PyErr_SetString(
597-
PyExc_RuntimeError,
598-
"cannot reuse already awaited coroutine");
589+
if (FRAME_STATE_FINISHED(frame_state)) {
590+
if (PyCoro_CheckExact(gen)) {
591+
/* `gen` is an exhausted coroutine: raise an error */
592+
PyErr_SetString(
593+
PyExc_RuntimeError,
594+
"cannot reuse already awaited coroutine");
595+
return NULL;
596+
}
597+
gen_set_exception(typ, val, tb);
599598
return NULL;
600599
}
601-
gen_set_exception(typ, val, tb);
602-
return NULL;
603-
}
604600

605-
if (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING)) {
606-
goto retry;
607-
}
601+
assert((frame_state == FRAME_CREATED) ||
602+
FRAME_STATE_SUSPENDED(frame_state));
603+
} while (!_Py_GEN_TRY_SET_FRAME_STATE(gen, frame_state, FRAME_EXECUTING));
608604

609605
if (frame_state == FRAME_SUSPENDED_YIELD_FROM) {
610606
_PyInterpreterFrame *frame = &gen->gi_iframe;

0 commit comments

Comments
 (0)