mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-07 10:20:29 +00:00
cleanup _PyMethodDef_RawFastCallDict
refer python/cpython@0a2e46835d refer python/cpython@98ccba8344 refer python/cpython@c89ef828cf refer python/cpython@250e4b0063
This commit is contained in:
parent
9220b67b3e
commit
7fb46fb510
2 changed files with 39 additions and 97 deletions
11
third_party/python/Objects/abstract.c
vendored
11
third_party/python/Objects/abstract.c
vendored
|
@ -2255,7 +2255,7 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
|
|
||||||
/* PyObject_Call() must not be called with an exception set,
|
/* PyObject_Call() must not be called with an exception set,
|
||||||
because it may clear it (directly or indirectly) and so the
|
because it can clear it (directly or indirectly) and so the
|
||||||
caller loses its exception */
|
caller loses its exception */
|
||||||
assert(!PyErr_Occurred());
|
assert(!PyErr_Occurred());
|
||||||
assert(PyTuple_Check(args));
|
assert(PyTuple_Check(args));
|
||||||
|
@ -2332,7 +2332,7 @@ _PyObject_FastCallDict(PyObject *callable, PyObject **args, Py_ssize_t nargs,
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
|
||||||
/* _PyObject_FastCallDict() must not be called with an exception set,
|
/* _PyObject_FastCallDict() must not be called with an exception set,
|
||||||
because it may clear it (directly or indirectly) and so the
|
because it can clear it (directly or indirectly) and so the
|
||||||
caller loses its exception */
|
caller loses its exception */
|
||||||
assert(!PyErr_Occurred());
|
assert(!PyErr_Occurred());
|
||||||
|
|
||||||
|
@ -2505,6 +2505,11 @@ PyObject *
|
||||||
_PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t nargs,
|
_PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t nargs,
|
||||||
PyObject *kwnames)
|
PyObject *kwnames)
|
||||||
{
|
{
|
||||||
|
/* _PyObject_FastCallKeywords() must not be called with an exception set,
|
||||||
|
because it can clear it (directly or indirectly) and so the
|
||||||
|
caller loses its exception */
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
|
|
||||||
assert(nargs >= 0);
|
assert(nargs >= 0);
|
||||||
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
|
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
|
||||||
|
|
||||||
|
@ -2562,6 +2567,8 @@ _PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t narg
|
||||||
Py_DECREF(argtuple);
|
Py_DECREF(argtuple);
|
||||||
Py_XDECREF(kwdict);
|
Py_XDECREF(kwdict);
|
||||||
|
|
||||||
|
result = _Py_CheckFunctionResult(callable, result, NULL);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_LeaveRecursiveCall();
|
Py_LeaveRecursiveCall();
|
||||||
return result;
|
return result;
|
||||||
|
|
125
third_party/python/Objects/methodobject.c
vendored
125
third_party/python/Objects/methodobject.c
vendored
|
@ -91,77 +91,12 @@ PyCFunction_GetFlags(PyObject *op)
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwds)
|
PyCFunction_Call(PyObject *func, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
PyCFunctionObject* f = (PyCFunctionObject*)func;
|
return _PyCFunction_FastCallDict(func,
|
||||||
PyCFunction meth = PyCFunction_GET_FUNCTION(func);
|
&PyTuple_GET_ITEM(args, 0),
|
||||||
PyObject *self = PyCFunction_GET_SELF(func);
|
PyTuple_GET_SIZE(args),
|
||||||
PyObject *arg, *res;
|
kwargs);
|
||||||
Py_ssize_t size;
|
|
||||||
int flags;
|
|
||||||
|
|
||||||
assert(kwds == NULL || PyDict_Check(kwds));
|
|
||||||
/* PyCFunction_Call() must not be called with an exception set,
|
|
||||||
because it can clear it (directly or indirectly) and so the
|
|
||||||
caller loses its exception */
|
|
||||||
assert(!PyErr_Occurred());
|
|
||||||
|
|
||||||
flags = PyCFunction_GET_FLAGS(func) & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
|
|
||||||
|
|
||||||
if (flags == (METH_VARARGS | METH_KEYWORDS)) {
|
|
||||||
res = (*(PyCFunctionWithKeywords)meth)(self, args, kwds);
|
|
||||||
}
|
|
||||||
else if (flags == METH_FASTCALL) {
|
|
||||||
PyObject **stack = &PyTuple_GET_ITEM(args, 0);
|
|
||||||
Py_ssize_t nargs = PyTuple_GET_SIZE(args);
|
|
||||||
res = _PyCFunction_FastCallDict(func, stack, nargs, kwds);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (kwds != NULL && PyDict_GET_SIZE(kwds) != 0) {
|
|
||||||
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
|
|
||||||
f->m_ml->ml_name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flags) {
|
|
||||||
case METH_VARARGS:
|
|
||||||
res = (*meth)(self, args);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METH_NOARGS:
|
|
||||||
size = PyTuple_GET_SIZE(args);
|
|
||||||
if (size != 0) {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
|
||||||
"%.200s() takes no arguments (%zd given)",
|
|
||||||
f->m_ml->ml_name, size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = (*meth)(self, NULL);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case METH_O:
|
|
||||||
size = PyTuple_GET_SIZE(args);
|
|
||||||
if (size != 1) {
|
|
||||||
PyErr_Format(PyExc_TypeError,
|
|
||||||
"%.200s() takes exactly one argument (%zd given)",
|
|
||||||
f->m_ml->ml_name, size);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
arg = PyTuple_GET_ITEM(args, 0);
|
|
||||||
res = (*meth)(self, arg);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
PyErr_SetString(PyExc_SystemError,
|
|
||||||
"Bad call flags in PyCFunction_Call. "
|
|
||||||
"METH_OLDARGS is no longer supported!");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return _Py_CheckFunctionResult(func, res, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *
|
PyObject *
|
||||||
|
@ -171,31 +106,33 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg
|
||||||
PyCFunction meth;
|
PyCFunction meth;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
int flags;
|
int flags;
|
||||||
|
PyObject *argstuple;
|
||||||
|
|
||||||
|
/* _PyMethodDef_RawFastCallDict() must not be called with an exception set,
|
||||||
|
because it can clear it (directly or indirectly) and so the
|
||||||
|
caller loses its exception */
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
|
|
||||||
assert(method != NULL);
|
assert(method != NULL);
|
||||||
assert(nargs >= 0);
|
assert(nargs >= 0);
|
||||||
assert(nargs == 0 || args != NULL);
|
assert(nargs == 0 || args != NULL);
|
||||||
assert(kwargs == NULL || PyDict_Check(kwargs));
|
assert(kwargs == NULL || PyDict_Check(kwargs));
|
||||||
|
|
||||||
/* _PyCFunction_FastCallDict() must not be called with an exception set,
|
|
||||||
because it may clear it (directly or indirectly) and so the
|
|
||||||
caller loses its exception */
|
|
||||||
assert(!PyErr_Occurred());
|
|
||||||
|
|
||||||
meth = method->ml_meth;
|
meth = method->ml_meth;
|
||||||
flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
|
flags = method->ml_flags & ~(METH_CLASS | METH_STATIC | METH_COEXIST);
|
||||||
|
|
||||||
switch (flags)
|
switch (flags)
|
||||||
{
|
{
|
||||||
case METH_NOARGS:
|
case METH_NOARGS:
|
||||||
if (nargs != 0) {
|
if (nargs != 0) {
|
||||||
goto no_keyword_error;
|
PyErr_Format(PyExc_TypeError,
|
||||||
}
|
"%.200s() takes no arguments (%zd given)",
|
||||||
|
method->ml_name, nargs);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
|
if (kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
|
||||||
PyErr_Format(PyExc_TypeError, "%.200s() takes no keyword arguments",
|
goto no_keyword_error;
|
||||||
method->ml_name);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (*meth) (self, NULL);
|
result = (*meth) (self, NULL);
|
||||||
|
@ -217,30 +154,27 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case METH_VARARGS:
|
case METH_VARARGS:
|
||||||
case METH_VARARGS | METH_KEYWORDS:
|
|
||||||
{
|
|
||||||
/* Slow-path: create a temporary tuple for positional arguments */
|
|
||||||
PyObject *tuple;
|
|
||||||
|
|
||||||
if (!(flags & METH_KEYWORDS)
|
if (!(flags & METH_KEYWORDS)
|
||||||
&& kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
|
&& kwargs != NULL && PyDict_GET_SIZE(kwargs) != 0) {
|
||||||
goto no_keyword_error;
|
goto no_keyword_error;
|
||||||
}
|
}
|
||||||
|
/* fall through next case */
|
||||||
|
|
||||||
tuple = _PyStack_AsTuple(args, nargs);
|
case METH_VARARGS | METH_KEYWORDS:
|
||||||
if (tuple == NULL) {
|
/* Slow-path: create a temporary tuple for positional arguments */
|
||||||
|
argstuple = _PyStack_AsTuple(args, nargs);
|
||||||
|
if (argstuple == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags & METH_KEYWORDS) {
|
if (flags & METH_KEYWORDS) {
|
||||||
result = (*(PyCFunctionWithKeywords)meth) (self, tuple, kwargs);
|
result = (*(PyCFunctionWithKeywords)meth) (self, argstuple, kwargs);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result = (*meth) (self, tuple);
|
result = (*meth) (self, argstuple);
|
||||||
}
|
}
|
||||||
Py_DECREF(tuple);
|
Py_DECREF(argstuple);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case METH_FASTCALL:
|
case METH_FASTCALL:
|
||||||
{
|
{
|
||||||
|
@ -262,7 +196,7 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg
|
||||||
|
|
||||||
default:
|
default:
|
||||||
PyErr_SetString(PyExc_SystemError,
|
PyErr_SetString(PyExc_SystemError,
|
||||||
"Bad call flags in PyCFunction_Call. "
|
"Bad call flags in _PyMethodDef_RawFastCallDict. "
|
||||||
"METH_OLDARGS is no longer supported!");
|
"METH_OLDARGS is no longer supported!");
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -271,8 +205,9 @@ _PyMethodDef_RawFastCallDict(PyMethodDef *method, PyObject *self, PyObject **arg
|
||||||
|
|
||||||
no_keyword_error:
|
no_keyword_error:
|
||||||
PyErr_Format(PyExc_TypeError,
|
PyErr_Format(PyExc_TypeError,
|
||||||
"%.200s() takes no arguments (%zd given)",
|
"%.200s() takes no keyword arguments",
|
||||||
method->ml_name, nargs);
|
method->ml_name, nargs);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue