summaryrefslogtreecommitdiff
path: root/Objects/abstract.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/abstract.c')
-rw-r--r--Objects/abstract.c448
1 files changed, 223 insertions, 225 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c
index d838856d45..8447fdbc24 100644
--- a/Objects/abstract.c
+++ b/Objects/abstract.c
@@ -103,7 +103,7 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue)
}
return defaultvalue;
}
- result = PyObject_CallFunctionObjArgs(hint, NULL);
+ result = _PyObject_CallNoArg(hint);
Py_DECREF(hint);
if (result == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError)) {
@@ -252,14 +252,6 @@ PyObject_DelItemString(PyObject *o, const char *key)
cause issues later on. Don't use these functions in new code.
*/
int
-PyObject_AsCharBuffer(PyObject *obj,
- const char **buffer,
- Py_ssize_t *buffer_len)
-{
- return PyObject_AsReadBuffer(obj, (const void **)buffer, buffer_len);
-}
-
-int
PyObject_CheckReadBuffer(PyObject *obj)
{
PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
@@ -276,9 +268,8 @@ PyObject_CheckReadBuffer(PyObject *obj)
return 1;
}
-int PyObject_AsReadBuffer(PyObject *obj,
- const void **buffer,
- Py_ssize_t *buffer_len)
+static int
+as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len)
{
Py_buffer view;
@@ -295,6 +286,21 @@ int PyObject_AsReadBuffer(PyObject *obj,
return 0;
}
+int
+PyObject_AsCharBuffer(PyObject *obj,
+ const char **buffer,
+ Py_ssize_t *buffer_len)
+{
+ return as_read_buffer(obj, (const void **)buffer, buffer_len);
+}
+
+int PyObject_AsReadBuffer(PyObject *obj,
+ const void **buffer,
+ Py_ssize_t *buffer_len)
+{
+ return as_read_buffer(obj, buffer, buffer_len);
+}
+
int PyObject_AsWriteBuffer(PyObject *obj,
void **buffer,
Py_ssize_t *buffer_len)
@@ -2167,24 +2173,24 @@ PyMapping_Values(PyObject *o)
/* XXX PyCallable_Check() is in object.c */
PyObject *
-PyObject_CallObject(PyObject *o, PyObject *a)
+PyObject_CallObject(PyObject *callable, PyObject *args)
{
- return PyEval_CallObjectWithKeywords(o, a, NULL);
+ return PyEval_CallObjectWithKeywords(callable, args, NULL);
}
PyObject*
-_Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where)
+_Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where)
{
int err_occurred = (PyErr_Occurred() != NULL);
- assert((func != NULL) ^ (where != NULL));
+ assert((callable != NULL) ^ (where != NULL));
if (result == NULL) {
if (!err_occurred) {
- if (func)
+ if (callable)
PyErr_Format(PyExc_SystemError,
"%R returned NULL without setting an error",
- func);
+ callable);
else
PyErr_Format(PyExc_SystemError,
"%s returned NULL without setting an error",
@@ -2200,10 +2206,10 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where)
if (err_occurred) {
Py_DECREF(result);
- if (func) {
+ if (callable) {
_PyErr_FormatFromCause(PyExc_SystemError,
"%R returned a result with an error set",
- func);
+ callable);
}
else {
_PyErr_FormatFromCause(PyExc_SystemError,
@@ -2221,7 +2227,7 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where)
}
PyObject *
-PyObject_Call(PyObject *func, PyObject *args, PyObject *kwargs)
+PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)
{
ternaryfunc call;
PyObject *result;
@@ -2233,21 +2239,21 @@ PyObject_Call(PyObject *func, PyObject *args, PyObject *kwargs)
assert(PyTuple_Check(args));
assert(kwargs == NULL || PyDict_Check(kwargs));
- call = func->ob_type->tp_call;
+ call = callable->ob_type->tp_call;
if (call == NULL) {
PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
- func->ob_type->tp_name);
+ callable->ob_type->tp_name);
return NULL;
}
if (Py_EnterRecursiveCall(" while calling a Python object"))
return NULL;
- result = (*call)(func, args, kwargs);
+ result = (*call)(callable, args, kwargs);
Py_LeaveRecursiveCall();
- return _Py_CheckFunctionResult(func, result, NULL);
+ return _Py_CheckFunctionResult(callable, result, NULL);
}
PyObject*
@@ -2271,7 +2277,7 @@ _PyStack_AsTuple(PyObject **stack, Py_ssize_t nargs)
}
PyObject *
-_PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
+_PyObject_FastCallDict(PyObject *callable, PyObject **args, Py_ssize_t nargs,
PyObject *kwargs)
{
ternaryfunc call;
@@ -2282,7 +2288,7 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
caller loses its exception */
assert(!PyErr_Occurred());
- assert(func != NULL);
+ assert(callable != NULL);
assert(nargs >= 0);
assert(nargs == 0 || args != NULL);
assert(kwargs == NULL || PyDict_Check(kwargs));
@@ -2291,20 +2297,20 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
return NULL;
}
- if (PyFunction_Check(func)) {
- result = _PyFunction_FastCallDict(func, args, nargs, kwargs);
+ if (PyFunction_Check(callable)) {
+ result = _PyFunction_FastCallDict(callable, args, nargs, kwargs);
}
- else if (PyCFunction_Check(func)) {
- result = _PyCFunction_FastCallDict(func, args, nargs, kwargs);
+ else if (PyCFunction_Check(callable)) {
+ result = _PyCFunction_FastCallDict(callable, args, nargs, kwargs);
}
else {
PyObject *tuple;
/* Slow-path: build a temporary tuple */
- call = func->ob_type->tp_call;
+ call = callable->ob_type->tp_call;
if (call == NULL) {
PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
- func->ob_type->tp_name);
+ callable->ob_type->tp_name);
goto exit;
}
@@ -2313,10 +2319,10 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
goto exit;
}
- result = (*call)(func, tuple, kwargs);
+ result = (*call)(callable, tuple, kwargs);
Py_DECREF(tuple);
- result = _Py_CheckFunctionResult(func, result, NULL);
+ result = _Py_CheckFunctionResult(callable, result, NULL);
}
exit:
@@ -2325,9 +2331,10 @@ exit:
return result;
}
-/* Positional arguments are obj followed by args. */
+/* Positional arguments are obj followed by args:
+ call callable(obj, *args, **kwargs) */
PyObject *
-_PyObject_Call_Prepend(PyObject *func,
+_PyObject_Call_Prepend(PyObject *callable,
PyObject *obj, PyObject *args, PyObject *kwargs)
{
PyObject *small_stack[8];
@@ -2355,7 +2362,7 @@ _PyObject_Call_Prepend(PyObject *func,
&PyTuple_GET_ITEM(args, 0),
argcount * sizeof(PyObject *));
- result = _PyObject_FastCallDict(func,
+ result = _PyObject_FastCallDict(callable,
stack, argcount + 1,
kwargs);
if (stack != small_stack) {
@@ -2446,56 +2453,121 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
}
PyObject *
-_PyObject_FastCallKeywords(PyObject *func, PyObject **stack, Py_ssize_t nargs,
+_PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t nargs,
PyObject *kwnames)
{
- PyObject *kwdict, *result;
- Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
-
assert(nargs >= 0);
assert(kwnames == NULL || PyTuple_CheckExact(kwnames));
- assert((nargs == 0 && nkwargs == 0) || stack != NULL);
+
/* kwnames must only contains str strings, no subclass, and all keys must
- be unique: these are implemented in Python/ceval.c and
+ be unique: these checks are implemented in Python/ceval.c and
_PyArg_ParseStack(). */
- if (PyFunction_Check(func)) {
- return _PyFunction_FastCallKeywords(func, stack, nargs, kwnames);
+ if (PyFunction_Check(callable)) {
+ return _PyFunction_FastCallKeywords(callable, stack, nargs, kwnames);
}
-
- if (PyCFunction_Check(func)) {
- return _PyCFunction_FastCallKeywords(func, stack, nargs, kwnames);
+ if (PyCFunction_Check(callable)) {
+ return _PyCFunction_FastCallKeywords(callable, stack, nargs, kwnames);
}
+ else {
+ /* Slow-path: build a temporary tuple for positional arguments and a
+ temporary dictionary for keyword arguments (if any) */
+
+ ternaryfunc call;
+ PyObject *argtuple;
+ PyObject *kwdict, *result;
+ Py_ssize_t nkwargs;
- if (nkwargs > 0) {
- kwdict = _PyStack_AsDict(stack + nargs, kwnames);
- if (kwdict == NULL) {
+ result = NULL;
+ nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames);
+ assert((nargs == 0 && nkwargs == 0) || stack != NULL);
+
+ if (Py_EnterRecursiveCall(" while calling a Python object")) {
return NULL;
}
- }
- else {
- kwdict = NULL;
- }
- result = _PyObject_FastCallDict(func, stack, nargs, kwdict);
- Py_XDECREF(kwdict);
- return result;
+ call = callable->ob_type->tp_call;
+ if (call == NULL) {
+ PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
+ callable->ob_type->tp_name);
+ goto exit;
+ }
+
+ argtuple = _PyStack_AsTuple(stack, nargs);
+ if (argtuple == NULL) {
+ goto exit;
+ }
+
+ if (nkwargs > 0) {
+ kwdict = _PyStack_AsDict(stack + nargs, kwnames);
+ if (kwdict == NULL) {
+ Py_DECREF(argtuple);
+ goto exit;
+ }
+ }
+ else {
+ kwdict = NULL;
+ }
+
+ result = (*call)(callable, argtuple, kwdict);
+ Py_DECREF(argtuple);
+ Py_XDECREF(kwdict);
+
+ exit:
+ Py_LeaveRecursiveCall();
+ return result;
+ }
}
-static PyObject*
-call_function_tail(PyObject *callable, PyObject *args)
+static PyObject *
+_PyObject_CallFunctionVa(PyObject *callable, const char *format,
+ va_list va, int is_size_t)
{
+ PyObject* small_stack[5];
+ /*const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack);*/
+ const Py_ssize_t small_stack_len = 0;
+ PyObject **stack;
+ Py_ssize_t nargs, i;
PyObject *result;
- assert(args != NULL);
+ if (callable == NULL) {
+ return null_error();
+ }
+
+ if (!format || !*format) {
+ return _PyObject_CallNoArg(callable);
+ }
- if (!PyTuple_Check(args)) {
- result = _PyObject_CallArg1(callable, args);
+ if (is_size_t) {
+ stack = _Py_VaBuildStack(small_stack, small_stack_len, format, va, &nargs);
}
else {
- result = PyObject_Call(callable, args, NULL);
+ stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, format, va, &nargs);
+ }
+ if (stack == NULL) {
+ return NULL;
+ }
+
+ if (nargs == 1 && PyTuple_Check(stack[0])) {
+ /* Special cases for backward compatibility:
+ - PyObject_CallFunction(func, "O", tuple) calls func(*tuple)
+ - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls
+ func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */
+ PyObject *args = stack[0];
+ result = _PyObject_FastCall(callable,
+ &PyTuple_GET_ITEM(args, 0),
+ PyTuple_GET_SIZE(args));
+ }
+ else {
+ result = _PyObject_FastCall(callable, stack, nargs);
}
+ for (i = 0; i < nargs; ++i) {
+ Py_DECREF(stack[i]);
+ }
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
return result;
}
@@ -2503,25 +2575,12 @@ PyObject *
PyObject_CallFunction(PyObject *callable, const char *format, ...)
{
va_list va;
- PyObject *args, *result;
-
- if (callable == NULL) {
- return null_error();
- }
-
- if (!format || !*format) {
- return _PyObject_CallNoArg(callable);
- }
+ PyObject *result;
va_start(va, format);
- args = Py_VaBuildValue(format, va);
+ result = _PyObject_CallFunctionVa(callable, format, va, 0);
va_end(va);
- if (args == NULL) {
- return NULL;
- }
- result = call_function_tail(callable, args);
- Py_DECREF(args);
return result;
}
@@ -2529,289 +2588,227 @@ PyObject *
_PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...)
{
va_list va;
- PyObject *args, *result;
-
- if (callable == NULL) {
- return null_error();
- }
-
- if (!format || !*format) {
- return _PyObject_CallNoArg(callable);
- }
+ PyObject *result;
va_start(va, format);
- args = _Py_VaBuildValue_SizeT(format, va);
+ result = _PyObject_CallFunctionVa(callable, format, va, 1);
va_end(va);
- if (args == NULL) {
- return NULL;
- }
- result = call_function_tail(callable, args);
- Py_DECREF(args);
return result;
}
static PyObject*
-callmethod(PyObject* func, const char *format, va_list va, int is_size_t)
+callmethod(PyObject* callable, const char *format, va_list va, int is_size_t)
{
- PyObject *args, *result;
-
- assert(func != NULL);
+ assert(callable != NULL);
- if (!PyCallable_Check(func)) {
- type_error("attribute of type '%.200s' is not callable", func);
+ if (!PyCallable_Check(callable)) {
+ type_error("attribute of type '%.200s' is not callable", callable);
return NULL;
}
- if (!format || !*format) {
- return _PyObject_CallNoArg(func);
- }
-
- if (is_size_t) {
- args = _Py_VaBuildValue_SizeT(format, va);
- }
- else {
- args = Py_VaBuildValue(format, va);
- }
- if (args == NULL) {
- return NULL;
- }
-
- result = call_function_tail(func, args);
- Py_DECREF(args);
- return result;
+ return _PyObject_CallFunctionVa(callable, format, va, is_size_t);
}
PyObject *
-PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
+PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...)
{
va_list va;
- PyObject *func = NULL;
- PyObject *retval = NULL;
+ PyObject *callable, *retval;
- if (o == NULL || name == NULL) {
+ if (obj == NULL || name == NULL) {
return null_error();
}
- func = PyObject_GetAttrString(o, name);
- if (func == NULL)
+ callable = PyObject_GetAttrString(obj, name);
+ if (callable == NULL)
return NULL;
va_start(va, format);
- retval = callmethod(func, format, va, 0);
+ retval = callmethod(callable, format, va, 0);
va_end(va);
- Py_DECREF(func);
+
+ Py_DECREF(callable);
return retval;
}
PyObject *
-_PyObject_CallMethodId(PyObject *o, _Py_Identifier *name,
+_PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name,
const char *format, ...)
{
va_list va;
- PyObject *func = NULL;
- PyObject *retval = NULL;
+ PyObject *callable, *retval;
- if (o == NULL || name == NULL) {
+ if (obj == NULL || name == NULL) {
return null_error();
}
- func = _PyObject_GetAttrId(o, name);
- if (func == NULL)
+ callable = _PyObject_GetAttrId(obj, name);
+ if (callable == NULL)
return NULL;
va_start(va, format);
- retval = callmethod(func, format, va, 0);
+ retval = callmethod(callable, format, va, 0);
va_end(va);
- Py_DECREF(func);
+
+ Py_DECREF(callable);
return retval;
}
PyObject *
-_PyObject_CallMethod_SizeT(PyObject *o, const char *name,
+_PyObject_CallMethod_SizeT(PyObject *obj, const char *name,
const char *format, ...)
{
va_list va;
- PyObject *func = NULL;
- PyObject *retval;
+ PyObject *callable, *retval;
- if (o == NULL || name == NULL) {
+ if (obj == NULL || name == NULL) {
return null_error();
}
- func = PyObject_GetAttrString(o, name);
- if (func == NULL)
+ callable = PyObject_GetAttrString(obj, name);
+ if (callable == NULL)
return NULL;
+
va_start(va, format);
- retval = callmethod(func, format, va, 1);
+ retval = callmethod(callable, format, va, 1);
va_end(va);
- Py_DECREF(func);
+
+ Py_DECREF(callable);
return retval;
}
PyObject *
-_PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name,
+_PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name,
const char *format, ...)
{
va_list va;
- PyObject *func = NULL;
- PyObject *retval;
+ PyObject *callable, *retval;
- if (o == NULL || name == NULL) {
+ if (obj == NULL || name == NULL) {
return null_error();
}
- func = _PyObject_GetAttrId(o, name);
- if (func == NULL) {
+ callable = _PyObject_GetAttrId(obj, name);
+ if (callable == NULL) {
return NULL;
}
+
va_start(va, format);
- retval = callmethod(func, format, va, 1);
+ retval = callmethod(callable, format, va, 1);
va_end(va);
- Py_DECREF(func);
+
+ Py_DECREF(callable);
return retval;
}
-static PyObject **
-objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size,
- va_list va, Py_ssize_t *p_nargs)
+PyObject *
+_PyObject_VaCallFunctionObjArgs(PyObject *callable, va_list vargs)
{
- Py_ssize_t i, n;
- va_list countva;
+ PyObject *small_stack[5];
PyObject **stack;
+ Py_ssize_t nargs;
+ PyObject *result;
+ Py_ssize_t i;
+ va_list countva;
- /* Count the number of arguments */
- va_copy(countva, va);
+ if (callable == NULL) {
+ return null_error();
+ }
- n = 0;
+ /* Count the number of arguments */
+ va_copy(countva, vargs);
+ nargs = 0;
while (1) {
PyObject *arg = va_arg(countva, PyObject *);
if (arg == NULL) {
break;
}
- n++;
+ nargs++;
}
- *p_nargs = n;
+ va_end(countva);
/* Copy arguments */
- if (n <= small_stack_size) {
+ if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
stack = small_stack;
}
else {
- stack = PyMem_Malloc(n * sizeof(stack[0]));
+ stack = PyMem_Malloc(nargs * sizeof(stack[0]));
if (stack == NULL) {
- va_end(countva);
PyErr_NoMemory();
return NULL;
}
}
- for (i = 0; i < n; ++i) {
- stack[i] = va_arg(va, PyObject *);
+ for (i = 0; i < nargs; ++i) {
+ stack[i] = va_arg(vargs, PyObject *);
}
- va_end(countva);
- return stack;
+
+ /* Call the function */
+ result = _PyObject_FastCall(callable, stack, nargs);
+
+ if (stack != small_stack) {
+ PyMem_Free(stack);
+ }
+ return result;
}
PyObject *
PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
{
- PyObject *small_stack[5];
- PyObject **stack;
- Py_ssize_t nargs;
- PyObject *result;
va_list vargs;
+ PyObject *result;
if (callable == NULL || name == NULL) {
return null_error();
}
callable = PyObject_GetAttr(callable, name);
- if (callable == NULL)
+ if (callable == NULL) {
return NULL;
+ }
- /* count the args */
va_start(vargs, name);
- stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
- vargs, &nargs);
+ result = _PyObject_VaCallFunctionObjArgs(callable, vargs);
va_end(vargs);
- if (stack == NULL) {
- Py_DECREF(callable);
- return NULL;
- }
- result = _PyObject_FastCall(callable, stack, nargs);
Py_DECREF(callable);
- if (stack != small_stack) {
- PyMem_Free(stack);
- }
-
return result;
}
PyObject *
-_PyObject_CallMethodIdObjArgs(PyObject *callable,
- struct _Py_Identifier *name, ...)
+_PyObject_CallMethodIdObjArgs(PyObject *obj,
+ struct _Py_Identifier *name, ...)
{
- PyObject *small_stack[5];
- PyObject **stack;
- Py_ssize_t nargs;
- PyObject *result;
va_list vargs;
+ PyObject *callable, *result;
- if (callable == NULL || name == NULL) {
+ if (obj == NULL || name == NULL) {
return null_error();
}
- callable = _PyObject_GetAttrId(callable, name);
- if (callable == NULL)
+ callable = _PyObject_GetAttrId(obj, name);
+ if (callable == NULL) {
return NULL;
+ }
- /* count the args */
va_start(vargs, name);
- stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
- vargs, &nargs);
+ result = _PyObject_VaCallFunctionObjArgs(callable, vargs);
va_end(vargs);
- if (stack == NULL) {
- Py_DECREF(callable);
- return NULL;
- }
- result = _PyObject_FastCall(callable, stack, nargs);
Py_DECREF(callable);
- if (stack != small_stack) {
- PyMem_Free(stack);
- }
-
return result;
}
PyObject *
PyObject_CallFunctionObjArgs(PyObject *callable, ...)
{
- PyObject *small_stack[5];
- PyObject **stack;
- Py_ssize_t nargs;
- PyObject *result;
va_list vargs;
+ PyObject *result;
- if (callable == NULL) {
- return null_error();
- }
-
- /* count the args */
va_start(vargs, callable);
- stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
- vargs, &nargs);
+ result = _PyObject_VaCallFunctionObjArgs(callable, vargs);
va_end(vargs);
- if (stack == NULL) {
- return NULL;
- }
-
- result = _PyObject_FastCall(callable, stack, nargs);
- if (stack != small_stack) {
- PyMem_Free(stack);
- }
return result;
}
@@ -3111,7 +3108,8 @@ PyObject *
PyObject_GetIter(PyObject *o)
{
PyTypeObject *t = o->ob_type;
- getiterfunc f = NULL;
+ getiterfunc f;
+
f = t->tp_iter;
if (f == NULL) {
if (PySequence_Check(o))