diff --git a/third_party/python/Include/abstract.h b/third_party/python/Include/abstract.h index 69a3c6934..b62568ea4 100644 --- a/third_party/python/Include/abstract.h +++ b/third_party/python/Include/abstract.h @@ -24,8 +24,7 @@ int _PyStack_UnpackDict( Py_ssize_t nargs, PyObject *kwargs, PyObject ***p_stack, - PyObject **p_kwnames, - PyObject *func); + PyObject **p_kwnames); PyObject *_PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, PyObject *kwargs); diff --git a/third_party/python/Include/methodobject.h b/third_party/python/Include/methodobject.h index 3e74490ee..42062832a 100644 --- a/third_party/python/Include/methodobject.h +++ b/third_party/python/Include/methodobject.h @@ -93,6 +93,12 @@ typedef struct { PyObject *m_module; /* The __module__ attribute, can be anything */ PyObject *m_weakreflist; /* List of weak references */ } PyCFunctionObject; +PyObject * _PyMethodDef_RawFastCallDict( + PyMethodDef *method, + PyObject *self, + PyObject **args, + Py_ssize_t nargs, + PyObject *kwargs); #endif int PyCFunction_ClearFreeList(void); diff --git a/third_party/python/Modules/socketmodule.c b/third_party/python/Modules/socketmodule.c index 08e500003..81bef83d5 100644 --- a/third_party/python/Modules/socketmodule.c +++ b/third_party/python/Modules/socketmodule.c @@ -3867,11 +3867,15 @@ sock_sendto(PySocketSockObject *s, PyObject *args) arglen = PyTuple_Size(args); switch (arglen) { case 2: - PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro); + if (!PyArg_ParseTuple(args, "y*O:sendto", &pbuf, &addro)) { + return NULL; + } break; case 3: - PyArg_ParseTuple(args, "y*iO:sendto", - &pbuf, &flags, &addro); + if (!PyArg_ParseTuple(args, "y*iO:sendto", + &pbuf, &flags, &addro)) { + return NULL; + } break; default: PyErr_Format(PyExc_TypeError, @@ -3879,8 +3883,6 @@ sock_sendto(PySocketSockObject *s, PyObject *args) arglen); return NULL; } - if (PyErr_Occurred()) - return NULL; if (!IS_SELECTABLE(s)) { PyBuffer_Release(&pbuf); diff --git a/third_party/python/Objects/abstract.c b/third_party/python/Objects/abstract.c index 50056de4c..a14a1f4ea 100644 --- a/third_party/python/Objects/abstract.c +++ b/third_party/python/Objects/abstract.c @@ -2446,7 +2446,7 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames) int _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, - PyObject ***p_stack, PyObject **p_kwnames, PyObject *func) + PyObject ***p_stack, PyObject **p_kwnames) { PyObject **stack, **kwstack; Py_ssize_t nkwargs; diff --git a/third_party/python/Objects/descrobject.c b/third_party/python/Objects/descrobject.c index be1be6949..be831695e 100644 --- a/third_party/python/Objects/descrobject.c +++ b/third_party/python/Objects/descrobject.c @@ -228,15 +228,15 @@ getset_set(PyGetSetDescrObject *descr, PyObject *obj, PyObject *value) } static PyObject * -methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) +methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwargs) { - Py_ssize_t argc; - PyObject *self, *func, *result, **stack; + Py_ssize_t nargs; + PyObject *self, *result; /* Make sure that the first argument is acceptable as 'self' */ assert(PyTuple_Check(args)); - argc = PyTuple_GET_SIZE(args); - if (argc < 1) { + nargs = PyTuple_GET_SIZE(args); + if (nargs < 1) { PyErr_Format(PyExc_TypeError, "descriptor '%V' of '%.100s' " "object needs an argument", @@ -257,12 +257,10 @@ methoddescr_call(PyMethodDescrObject *descr, PyObject *args, PyObject *kwds) return NULL; } - func = PyCFunction_NewEx(descr->d_method, self, NULL); - if (func == NULL) - return NULL; - stack = &PyTuple_GET_ITEM(args, 1); - result = _PyObject_FastCallDict(func, stack, argc - 1, kwds); - Py_DECREF(func); + result = _PyMethodDef_RawFastCallDict(descr->d_method, self, + &PyTuple_GET_ITEM(args, 1), nargs - 1, + kwargs); + result = _Py_CheckFunctionResult((PyObject *)descr, result, NULL); return result; } diff --git a/third_party/python/Objects/methodobject.c b/third_party/python/Objects/methodobject.c index 661a8a200..f43be865a 100644 --- a/third_party/python/Objects/methodobject.c +++ b/third_party/python/Objects/methodobject.c @@ -165,17 +165,14 @@ PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds) } PyObject * -_PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, - PyObject *kwargs) +_PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **args, + Py_ssize_t nargs, PyObject *kwargs) { - PyCFunctionObject *func; PyCFunction meth; - PyObject *self; PyObject *result; int flags; - assert(func_obj != NULL); - assert(PyCFunction_Check(func_obj)); + assert(method != NULL); assert(nargs >= 0); assert(nargs == 0 || args != NULL); assert(kwargs == NULL || PyDict_Check(kwargs)); @@ -185,10 +182,8 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, caller loses its exception */ assert(!PyErr_Occurred()); - func = (PyCFunctionObject*)func_obj; - meth = PyCFunction_GET_FUNCTION(func); - self = PyCFunction_GET_SELF(func); - flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST); + meth = method->ml_meth; + flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST); switch (flags) { @@ -199,7 +194,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) { PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments", - func->m_ml->ml_name); + method->ml_name); return NULL; } @@ -210,7 +205,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, if (nargs != 1) { PyErr_Format(PyExc_TypeError, "%.200s() takes exactly one argument (%zd given)", - func->m_ml->ml_name, nargs); + method->ml_name, nargs); return NULL; } @@ -253,8 +248,7 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, PyObject *kwnames; _PyCFunctionFast fastmeth = (_PyCFunctionFast)meth; - if (_PyStack_UnpackDict(args, nargs, kwargs, - &stack, &kwnames, func_obj) < 0) { + if (_PyStack_UnpackDict(args, nargs, kwargs, &stack, &kwnames) < 0) { return NULL; } @@ -273,17 +267,33 @@ _PyCFunction_FastCallDict(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, return NULL; } - result = _Py_CheckFunctionResult(func_obj, result, NULL); - return result; no_keyword_error: PyErr_Format(PyExc_TypeError, "%.200s() takes no arguments (%zd given)", - func->m_ml->ml_name, nargs); + method->ml_name, nargs); return NULL; } +PyObject * +_PyCFunction_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, + PyObject *kwargs) +{ + PyObject *result; + + assert(func != NULL); + assert(PyCFunction_Check(func)); + + result = _PyMethodDef_RawFastCallDict(((PyCFunctionObject*)func)->m_ml, + PyCFunction_GET_SELF(func), + args, nargs, kwargs); + result = _Py_CheckFunctionResult(func, result, NULL); + return result; +} + + + PyObject * _PyCFunction_FastCallKeywords(PyObject *func_obj, PyObject **args, Py_ssize_t nargs, PyObject *kwnames)