Skip to content

Commit ea0ecaa

Browse files
committed
Deduplicate the THROW code
1 parent 9e1f521 commit ea0ecaa

File tree

1 file changed

+29
-55
lines changed

1 file changed

+29
-55
lines changed

Python/ceval.c

+29-55
Original file line numberDiff line numberDiff line change
@@ -1124,35 +1124,6 @@ match_class(PyThreadState *tstate, PyObject *subject, PyObject *type,
11241124
return NULL;
11251125
}
11261126

1127-
static PyObject *
1128-
throw(PyThreadState *tstate, PyObject *exc_value, PyObject *receiver)
1129-
{
1130-
PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
1131-
PyObject *exc_traceback = PyException_GetTraceback(exc_value);
1132-
PyErr_NormalizeException(&exc_type, &exc_value, &exc_traceback);
1133-
PyObject *throw;
1134-
int found = _PyObject_LookupAttr(receiver, &_Py_ID(throw), &throw);
1135-
if (found < 0) {
1136-
if (PyErr_GivenExceptionMatches(exc_value, PyExc_GeneratorExit))
1137-
{
1138-
PyErr_Clear();
1139-
_PyErr_Restore(tstate, exc_type, exc_value, exc_traceback);
1140-
}
1141-
return NULL;
1142-
}
1143-
if (found == 0) {
1144-
_PyErr_Restore(tstate, exc_type, exc_value, exc_traceback);
1145-
return NULL;
1146-
}
1147-
PyObject *retval = PyObject_CallFunctionObjArgs(throw, exc_type, exc_value,
1148-
exc_traceback, NULL);
1149-
Py_DECREF(throw);
1150-
Py_DECREF(exc_type);
1151-
Py_DECREF(exc_value);
1152-
Py_XDECREF(exc_traceback);
1153-
return retval;
1154-
}
1155-
11561127

11571128
static int do_raise(PyThreadState *tstate, PyObject *exc, PyObject *cause);
11581129
static int exception_group_match(
@@ -2685,13 +2656,36 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
26852656
}
26862657

26872658
TARGET(THROW_FORWARD) {
2659+
PREDICTED(THROW_FORWARD);
26882660
assert(frame->is_entry);
26892661
assert(throwflag);
26902662
PyObject *exc_value = POP();
2663+
PyObject *exc_type = Py_NewRef(Py_TYPE(exc_value));
2664+
PyObject *exc_traceback = PyException_GetTraceback(exc_value);
2665+
PyErr_NormalizeException(&exc_type, &exc_value, &exc_traceback);
26912666
PyObject *last_send = POP();
26922667
Py_DECREF(last_send);
2693-
PyObject *receiver = TOP();
2694-
PyObject *retval = throw(tstate, exc_value, receiver);
2668+
PyObject *yieldfrom = TOP();
2669+
PyObject *throw;
2670+
int found = _PyObject_LookupAttr(yieldfrom, &_Py_ID(throw), &throw);
2671+
if (found < 0) {
2672+
if (PyErr_GivenExceptionMatches(exc_value, PyExc_GeneratorExit))
2673+
{
2674+
PyErr_Clear();
2675+
_PyErr_Restore(tstate, exc_type, exc_value, exc_traceback);
2676+
}
2677+
goto error;
2678+
}
2679+
if (found == 0) {
2680+
_PyErr_Restore(tstate, exc_type, exc_value, exc_traceback);
2681+
goto error;
2682+
}
2683+
PyObject *retval = PyObject_CallFunctionObjArgs(
2684+
throw, exc_type, exc_value, exc_traceback, NULL);
2685+
Py_DECREF(throw);
2686+
Py_DECREF(exc_type);
2687+
Py_DECREF(exc_value);
2688+
Py_XDECREF(exc_traceback);
26952689
if (retval) {
26962690
PUSH(retval);
26972691
DISPATCH();
@@ -2705,35 +2699,15 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
27052699
if (_PyGen_FetchStopIterationValue(&TOP())) {
27062700
goto error;
27072701
}
2708-
Py_DECREF(receiver);
2702+
Py_DECREF(yieldfrom);
27092703
JUMPBY(oparg);
27102704
DISPATCH();
27112705
}
27122706

27132707
TARGET(THROW_BACKWARD) {
2714-
assert(frame->is_entry);
2715-
assert(throwflag);
2716-
PyObject *exc_value = POP();
2717-
PyObject *last_send = POP();
2718-
Py_DECREF(last_send);
2719-
PyObject *receiver = TOP();
2720-
PyObject *retval = throw(tstate, exc_value, receiver);
2721-
if (retval) {
2722-
PUSH(retval);
2723-
DISPATCH();
2724-
}
2725-
if (tstate->c_tracefunc &&
2726-
_PyErr_ExceptionMatches(tstate, PyExc_StopIteration))
2727-
{
2728-
call_exc_trace(tstate->c_tracefunc, tstate->c_traceobj, tstate,
2729-
frame);
2730-
}
2731-
if (_PyGen_FetchStopIterationValue(&TOP())) {
2732-
goto error;
2733-
}
2734-
Py_DECREF(receiver);
2735-
JUMPBY(-oparg);
2736-
DISPATCH();
2708+
// No interrupts!
2709+
oparg = -oparg;
2710+
JUMP_TO_INSTRUCTION(THROW_FORWARD);
27372711
}
27382712

27392713
TARGET(ASYNC_GEN_WRAP) {

0 commit comments

Comments
 (0)