Skip to content

Commit 304197b

Browse files
bpo-46944: use FASTCALL calling convention in generator.throw (GH-31723)
1 parent 4f74ffc commit 304197b

File tree

2 files changed

+24
-14
lines changed

2 files changed

+24
-14
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speed up throwing exception in generator with :const:`METH_FASTCALL` calling convention. Patch by Kumar Aditya.

Objects/genobject.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -561,16 +561,23 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
561561

562562

563563
static PyObject *
564-
gen_throw(PyGenObject *gen, PyObject *args)
564+
gen_throw(PyGenObject *gen, PyObject *const *args, Py_ssize_t nargs)
565565
{
566566
PyObject *typ;
567567
PyObject *tb = NULL;
568568
PyObject *val = NULL;
569569

570-
if (!PyArg_UnpackTuple(args, "throw", 1, 3, &typ, &val, &tb)) {
570+
if (!_PyArg_CheckPositional("throw", nargs, 1, 3)) {
571571
return NULL;
572572
}
573-
573+
typ = args[0];
574+
if (nargs == 3) {
575+
val = args[1];
576+
tb = args[2];
577+
}
578+
else if (nargs == 2) {
579+
val = args[1];
580+
}
574581
return _gen_throw(gen, 1, typ, val, tb);
575582
}
576583

@@ -813,7 +820,7 @@ PyDoc_STRVAR(sizeof__doc__,
813820

814821
static PyMethodDef gen_methods[] = {
815822
{"send",(PyCFunction)gen_send, METH_O, send_doc},
816-
{"throw",(PyCFunction)gen_throw, METH_VARARGS, throw_doc},
823+
{"throw",(PyCFunction)(void(*)(void))gen_throw, METH_FASTCALL, throw_doc},
817824
{"close",(PyCFunction)gen_close, METH_NOARGS, close_doc},
818825
{"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
819826
{NULL, NULL} /* Sentinel */
@@ -1159,7 +1166,7 @@ PyDoc_STRVAR(coro_close_doc,
11591166

11601167
static PyMethodDef coro_methods[] = {
11611168
{"send",(PyCFunction)gen_send, METH_O, coro_send_doc},
1162-
{"throw",(PyCFunction)gen_throw, METH_VARARGS, coro_throw_doc},
1169+
{"throw",(PyCFunction)(void(*)(void))gen_throw, METH_FASTCALL, coro_throw_doc},
11631170
{"close",(PyCFunction)gen_close, METH_NOARGS, coro_close_doc},
11641171
{"__sizeof__", (PyCFunction)gen_sizeof, METH_NOARGS, sizeof__doc__},
11651172
{NULL, NULL} /* Sentinel */
@@ -1246,9 +1253,9 @@ coro_wrapper_send(PyCoroWrapper *cw, PyObject *arg)
12461253
}
12471254

12481255
static PyObject *
1249-
coro_wrapper_throw(PyCoroWrapper *cw, PyObject *args)
1256+
coro_wrapper_throw(PyCoroWrapper *cw, PyObject *const *args, Py_ssize_t nargs)
12501257
{
1251-
return gen_throw((PyGenObject *)cw->cw_coroutine, args);
1258+
return gen_throw((PyGenObject *)cw->cw_coroutine, args, nargs);
12521259
}
12531260

12541261
static PyObject *
@@ -1266,7 +1273,8 @@ coro_wrapper_traverse(PyCoroWrapper *cw, visitproc visit, void *arg)
12661273

12671274
static PyMethodDef coro_wrapper_methods[] = {
12681275
{"send",(PyCFunction)coro_wrapper_send, METH_O, coro_send_doc},
1269-
{"throw",(PyCFunction)coro_wrapper_throw, METH_VARARGS, coro_throw_doc},
1276+
{"throw",(PyCFunction)(void(*)(void))coro_wrapper_throw,
1277+
METH_FASTCALL, coro_throw_doc},
12701278
{"close",(PyCFunction)coro_wrapper_close, METH_NOARGS, coro_close_doc},
12711279
{NULL, NULL} /* Sentinel */
12721280
};
@@ -1789,7 +1797,7 @@ async_gen_asend_iternext(PyAsyncGenASend *o)
17891797

17901798

17911799
static PyObject *
1792-
async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args)
1800+
async_gen_asend_throw(PyAsyncGenASend *o, PyObject *const *args, Py_ssize_t nargs)
17931801
{
17941802
PyObject *result;
17951803

@@ -1800,7 +1808,7 @@ async_gen_asend_throw(PyAsyncGenASend *o, PyObject *args)
18001808
return NULL;
18011809
}
18021810

1803-
result = gen_throw((PyGenObject*)o->ags_gen, args);
1811+
result = gen_throw((PyGenObject*)o->ags_gen, args, nargs);
18041812
result = async_gen_unwrap_value(o->ags_gen, result);
18051813

18061814
if (result == NULL) {
@@ -1821,7 +1829,7 @@ async_gen_asend_close(PyAsyncGenASend *o, PyObject *args)
18211829

18221830
static PyMethodDef async_gen_asend_methods[] = {
18231831
{"send", (PyCFunction)async_gen_asend_send, METH_O, send_doc},
1824-
{"throw", (PyCFunction)async_gen_asend_throw, METH_VARARGS, throw_doc},
1832+
{"throw", (PyCFunction)(void(*)(void))async_gen_asend_throw, METH_FASTCALL, throw_doc},
18251833
{"close", (PyCFunction)async_gen_asend_close, METH_NOARGS, close_doc},
18261834
{NULL, NULL} /* Sentinel */
18271835
};
@@ -2183,7 +2191,7 @@ async_gen_athrow_send(PyAsyncGenAThrow *o, PyObject *arg)
21832191

21842192

21852193
static PyObject *
2186-
async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
2194+
async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *const *args, Py_ssize_t nargs)
21872195
{
21882196
PyObject *retval;
21892197

@@ -2194,7 +2202,7 @@ async_gen_athrow_throw(PyAsyncGenAThrow *o, PyObject *args)
21942202
return NULL;
21952203
}
21962204

2197-
retval = gen_throw((PyGenObject*)o->agt_gen, args);
2205+
retval = gen_throw((PyGenObject*)o->agt_gen, args, nargs);
21982206
if (o->agt_args) {
21992207
return async_gen_unwrap_value(o->agt_gen, retval);
22002208
} else {
@@ -2239,7 +2247,8 @@ async_gen_athrow_close(PyAsyncGenAThrow *o, PyObject *args)
22392247

22402248
static PyMethodDef async_gen_athrow_methods[] = {
22412249
{"send", (PyCFunction)async_gen_athrow_send, METH_O, send_doc},
2242-
{"throw", (PyCFunction)async_gen_athrow_throw, METH_VARARGS, throw_doc},
2250+
{"throw", (PyCFunction)(void(*)(void))async_gen_athrow_throw,
2251+
METH_FASTCALL, throw_doc},
22432252
{"close", (PyCFunction)async_gen_athrow_close, METH_NOARGS, close_doc},
22442253
{NULL, NULL} /* Sentinel */
22452254
};

0 commit comments

Comments
 (0)