From 4d231bcc77ac8ce7d11bda0804130dcdd678f710 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Thu, 14 Nov 2019 13:36:21 +0100 Subject: bpo-38644: Add _PyObject_Call() (GH-17089) * Add pycore_call.h internal header file. * Add _PyObject_Call(): PyObject_Call() with tstate * Add _PyObject_CallNoArgTstate(): _PyObject_CallNoArg() with tstate * Add _PyObject_FastCallDictTstate(): _PyObject_FastCallDict() with tstate * _PyObject_Call_Prepend() now takes tstate * Replace _PyObject_FastCall() calls with _PyObject_VectorcallTstate() calls --- Include/cpython/abstract.h | 17 ++- Include/internal/pycore_call.h | 39 +++++++ Makefile.pre.in | 1 + Objects/call.c | 222 +++++++++++++++++++++---------------- Objects/typeobject.c | 36 +++--- PCbuild/pythoncore.vcxproj | 1 + PCbuild/pythoncore.vcxproj.filters | 3 + Python/_warnings.c | 8 +- Python/bltinmodule.c | 15 +-- Python/ceval.c | 11 +- 10 files changed, 216 insertions(+), 137 deletions(-) create mode 100644 Include/internal/pycore_call.h diff --git a/Include/cpython/abstract.h b/Include/cpython/abstract.h index fef538e..2c4eae7 100644 --- a/Include/cpython/abstract.h +++ b/Include/cpython/abstract.h @@ -137,7 +137,8 @@ PyAPI_FUNC(PyObject *) PyVectorcall_Call(PyObject *callable, PyObject *tuple, Py static inline PyObject * _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) { - return _PyObject_Vectorcall(func, args, (size_t)nargs, NULL); + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL); } /* Call a callable without any arguments @@ -145,7 +146,8 @@ _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs) PyObject_CallNoArgs(). */ static inline PyObject * _PyObject_CallNoArg(PyObject *func) { - return _PyObject_Vectorcall(func, NULL, 0, NULL); + PyThreadState *tstate = PyThreadState_GET(); + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); } static inline PyObject * @@ -155,16 +157,11 @@ _PyObject_CallOneArg(PyObject *func, PyObject *arg) PyObject *_args[2]; PyObject **args = _args + 1; // For PY_VECTORCALL_ARGUMENTS_OFFSET args[0] = arg; - return _PyObject_Vectorcall(func, args, - 1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL); + PyThreadState *tstate = PyThreadState_GET(); + size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET; + return _PyObject_VectorcallTstate(tstate, func, args, nargsf, NULL); } -PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( - PyObject *callable, - PyObject *obj, - PyObject *args, - PyObject *kwargs); - PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod( PyObject *name, PyObject *const *args, size_t nargsf, PyObject *kwnames); diff --git a/Include/internal/pycore_call.h b/Include/internal/pycore_call.h new file mode 100644 index 0000000..f7d856a --- /dev/null +++ b/Include/internal/pycore_call.h @@ -0,0 +1,39 @@ +#ifndef Py_INTERNAL_CALL_H +#define Py_INTERNAL_CALL_H +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef Py_BUILD_CORE +# error "this header requires Py_BUILD_CORE define" +#endif + +PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend( + PyThreadState *tstate, + PyObject *callable, + PyObject *obj, + PyObject *args, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate( + PyThreadState *tstate, + PyObject *callable, + PyObject *const *args, + size_t nargsf, + PyObject *kwargs); + +PyAPI_FUNC(PyObject *) _PyObject_Call( + PyThreadState *tstate, + PyObject *callable, + PyObject *args, + PyObject *kwargs); + +static inline PyObject * +_PyObject_CallNoArgTstate(PyThreadState *tstate, PyObject *func) { + return _PyObject_VectorcallTstate(tstate, func, NULL, 0, NULL); +} + +#ifdef __cplusplus +} +#endif +#endif /* !Py_INTERNAL_CALL_H */ diff --git a/Makefile.pre.in b/Makefile.pre.in index 3c607d0..d08c78d 100644 --- a/Makefile.pre.in +++ b/Makefile.pre.in @@ -1076,6 +1076,7 @@ PYTHON_HEADERS= \ \ $(srcdir)/Include/internal/pycore_accu.h \ $(srcdir)/Include/internal/pycore_atomic.h \ + $(srcdir)/Include/internal/pycore_call.h \ $(srcdir)/Include/internal/pycore_ceval.h \ $(srcdir)/Include/internal/pycore_code.h \ $(srcdir)/Include/internal/pycore_condvar.h \ diff --git a/Objects/call.c b/Objects/call.c index 96174c4..ae08d18 100644 --- a/Objects/call.c +++ b/Objects/call.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_call.h" #include "pycore_ceval.h" /* _PyEval_EvalFrame() */ #include "pycore_object.h" #include "pycore_pyerrors.h" @@ -18,11 +19,12 @@ _PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs, static PyObject * -null_error(void) +null_error(PyThreadState *tstate) { - if (!PyErr_Occurred()) - PyErr_SetString(PyExc_SystemError, - "null argument to internal routine"); + if (!_PyErr_Occurred(tstate)) { + _PyErr_SetString(tstate, PyExc_SystemError, + "null argument to internal routine"); + } return NULL; } @@ -81,17 +83,18 @@ _Py_CheckFunctionResult(PyThreadState *tstate, PyObject *callable, PyObject * PyObject_CallNoArgs(PyObject *func) { - return _PyObject_CallNoArg(func); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_CallNoArgTstate(tstate, func); } PyObject * -_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, - size_t nargsf, PyObject *kwargs) +_PyObject_FastCallDictTstate(PyThreadState *tstate, PyObject *callable, + PyObject *const *args, size_t nargsf, + PyObject *kwargs) { assert(callable != NULL); - PyThreadState *tstate = _PyThreadState_GET(); /* _PyObject_FastCallDict() must not be called with an exception set, because it can clear it (directly or indirectly) and so the caller loses its exception */ @@ -130,10 +133,23 @@ _PyObject_FastCallDict(PyObject *callable, PyObject *const *args, PyObject * +_PyObject_FastCallDict(PyObject *callable, PyObject *const *args, + size_t nargsf, PyObject *kwargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_FastCallDictTstate(tstate, callable, args, nargsf, kwargs); +} + + +PyObject * _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, PyObject *const *args, Py_ssize_t nargs, PyObject *keywords) { + assert(nargs >= 0); + assert(nargs == 0 || args != NULL); + assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); + /* Slow path: build a temporary tuple for positional arguments and a * temporary dictionary for keyword arguments (if any) */ ternaryfunc call = Py_TYPE(callable)->tp_call; @@ -144,9 +160,6 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, return NULL; } - assert(nargs >= 0); - assert(nargs == 0 || args != NULL); - assert(keywords == NULL || PyTuple_Check(keywords) || PyDict_Check(keywords)); PyObject *argstuple = _PyTuple_FromArray(args, nargs); if (argstuple == NULL) { return NULL; @@ -182,8 +195,7 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable, Py_DECREF(kwdict); } - result = _Py_CheckFunctionResult(tstate, callable, result, NULL); - return result; + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } @@ -228,14 +240,15 @@ PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs) PyObject *result = func(callable, args, nargs | PY_VECTORCALL_ARGUMENTS_OFFSET, kwnames); _PyStack_UnpackDict_Free(args, nargs, kwnames); + return _Py_CheckFunctionResult(tstate, callable, result, NULL); } PyObject * -PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) +_PyObject_Call(PyThreadState *tstate, PyObject *callable, + PyObject *args, PyObject *kwargs) { - PyThreadState *tstate = _PyThreadState_GET(); ternaryfunc call; PyObject *result; @@ -270,11 +283,19 @@ PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) } } +PyObject * +PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) +{ + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_Call(tstate, callable, args, kwargs); +} + PyObject * PyCFunction_Call(PyObject *callable, PyObject *args, PyObject *kwargs) { - return PyObject_Call(callable, args, kwargs); + PyThreadState *tstate = _PyThreadState_GET(); + return _PyObject_Call(tstate, callable, args, kwargs); } @@ -385,30 +406,31 @@ PyObject * PyEval_CallObjectWithKeywords(PyObject *callable, PyObject *args, PyObject *kwargs) { + PyThreadState *tstate = _PyThreadState_GET(); #ifdef Py_DEBUG /* PyEval_CallObjectWithKeywords() must not be called with an exception set. It raises a new exception if parameters are invalid or if PyTuple_New() fails, and so the original exception is lost. */ - assert(!PyErr_Occurred()); + assert(!_PyErr_Occurred(tstate)); #endif if (args != NULL && !PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "argument list must be a tuple"); + _PyErr_SetString(tstate, PyExc_TypeError, + "argument list must be a tuple"); return NULL; } if (kwargs != NULL && !PyDict_Check(kwargs)) { - PyErr_SetString(PyExc_TypeError, - "keyword list must be a dictionary"); + _PyErr_SetString(tstate, PyExc_TypeError, + "keyword list must be a dictionary"); return NULL; } if (args == NULL) { - return _PyObject_FastCallDict(callable, NULL, 0, kwargs); + return _PyObject_FastCallDictTstate(tstate, callable, NULL, 0, kwargs); } else { - return PyObject_Call(callable, args, kwargs); + return _PyObject_Call(tstate, callable, args, kwargs); } } @@ -416,32 +438,31 @@ PyEval_CallObjectWithKeywords(PyObject *callable, PyObject * PyObject_CallObject(PyObject *callable, PyObject *args) { - assert(!PyErr_Occurred()); + PyThreadState *tstate = _PyThreadState_GET(); + assert(!_PyErr_Occurred(tstate)); if (args == NULL) { - return _PyObject_CallNoArg(callable); + return _PyObject_CallNoArgTstate(tstate, callable); } if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "argument list must be a tuple"); + _PyErr_SetString(tstate, PyExc_TypeError, + "argument list must be a tuple"); return NULL; } - return PyObject_Call(callable, args, NULL); + return _PyObject_Call(tstate, callable, args, NULL); } /* Call callable(obj, *args, **kwargs). */ PyObject * -_PyObject_Call_Prepend(PyObject *callable, +_PyObject_Call_Prepend(PyThreadState *tstate, PyObject *callable, PyObject *obj, PyObject *args, PyObject *kwargs) { + assert(PyTuple_Check(args)); + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; - Py_ssize_t argcount; - PyObject *result; - assert(PyTuple_Check(args)); - - argcount = PyTuple_GET_SIZE(args); + Py_ssize_t argcount = PyTuple_GET_SIZE(args); if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; } @@ -459,9 +480,9 @@ _PyObject_Call_Prepend(PyObject *callable, _PyTuple_ITEMS(args), argcount * sizeof(PyObject *)); - result = _PyObject_FastCallDict(callable, - stack, argcount + 1, - kwargs); + PyObject *result = _PyObject_FastCallDictTstate(tstate, callable, + stack, argcount + 1, + kwargs); if (stack != small_stack) { PyMem_Free(stack); } @@ -472,8 +493,8 @@ _PyObject_Call_Prepend(PyObject *callable, /* --- Call with a format string ---------------------------------- */ static PyObject * -_PyObject_CallFunctionVa(PyObject *callable, const char *format, - va_list va, int is_size_t) +_PyObject_CallFunctionVa(PyThreadState *tstate, PyObject *callable, + const char *format, va_list va, int is_size_t) { PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); @@ -482,11 +503,11 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format, PyObject *result; if (callable == NULL) { - return null_error(); + return null_error(tstate); } if (!format || !*format) { - return _PyObject_CallNoArg(callable); + return _PyObject_CallNoArgTstate(tstate, callable); } if (is_size_t) { @@ -507,12 +528,14 @@ _PyObject_CallFunctionVa(PyObject *callable, const char *format, - 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_ITEMS(args), - PyTuple_GET_SIZE(args)); + result = _PyObject_VectorcallTstate(tstate, callable, + _PyTuple_ITEMS(args), + PyTuple_GET_SIZE(args), + NULL); } else { - result = _PyObject_FastCall(callable, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, callable, + stack, nargs, NULL); } for (i = 0; i < nargs; ++i) { @@ -530,9 +553,10 @@ PyObject_CallFunction(PyObject *callable, const char *format, ...) { va_list va; PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); va_end(va); return result; @@ -547,9 +571,10 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...) { va_list va; PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 0); + result = _PyObject_CallFunctionVa(tstate, callable, format, va, 0); va_end(va); return result; @@ -559,11 +584,11 @@ PyEval_CallFunction(PyObject *callable, const char *format, ...) PyObject * _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) { - va_list va; - PyObject *result; + PyThreadState *tstate = _PyThreadState_GET(); + va_list va; va_start(va, format); - result = _PyObject_CallFunctionVa(callable, format, va, 1); + PyObject *result = _PyObject_CallFunctionVa(tstate, callable, format, va, 1); va_end(va); return result; @@ -571,37 +596,37 @@ _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) static PyObject* -callmethod(PyObject* callable, const char *format, va_list va, int is_size_t) +callmethod(PyThreadState *tstate, PyObject* callable, const char *format, va_list va, int is_size_t) { assert(callable != NULL); - if (!PyCallable_Check(callable)) { - PyErr_Format(PyExc_TypeError, - "attribute of type '%.200s' is not callable", - Py_TYPE(callable)->tp_name); + _PyErr_Format(tstate, PyExc_TypeError, + "attribute of type '%.200s' is not callable", + Py_TYPE(callable)->tp_name); return NULL; } - return _PyObject_CallFunctionVa(callable, format, va, is_size_t); + return _PyObject_CallFunctionVa(tstate, callable, format, va, is_size_t); } PyObject * PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -615,19 +640,19 @@ PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) PyObject * PyEval_CallMethod(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -639,19 +664,19 @@ PyObject * _PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = _PyObject_GetAttrId(obj, name); - if (callable == NULL) + PyObject *callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 0); + PyObject *retval = callmethod(tstate, callable, format, va, 0); va_end(va); Py_DECREF(callable); @@ -663,19 +688,19 @@ PyObject * _PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = PyObject_GetAttrString(obj, name); - if (callable == NULL) + PyObject *callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) { return NULL; + } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va, 1); va_end(va); Py_DECREF(callable); @@ -687,20 +712,19 @@ PyObject * _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, const char *format, ...) { - va_list va; - PyObject *callable, *retval; - + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } - callable = _PyObject_GetAttrId(obj, name); + PyObject *callable = _PyObject_GetAttrId(obj, name); if (callable == NULL) { return NULL; } + va_list va; va_start(va, format); - retval = callmethod(callable, format, va, 1); + PyObject *retval = callmethod(tstate, callable, format, va, 1); va_end(va); Py_DECREF(callable); @@ -711,7 +735,8 @@ _PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, /* --- Call with "..." arguments ---------------------------------- */ static PyObject * -object_vacall(PyObject *base, PyObject *callable, va_list vargs) +object_vacall(PyThreadState *tstate, PyObject *base, + PyObject *callable, va_list vargs) { PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; @@ -721,7 +746,7 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) va_list countva; if (callable == NULL) { - return null_error(); + return null_error(tstate); } /* Count the number of arguments */ @@ -758,7 +783,7 @@ object_vacall(PyObject *base, PyObject *callable, va_list vargs) } /* Call the function */ - result = _PyObject_FastCall(callable, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, callable, stack, nargs, NULL); if (stack != small_stack) { PyMem_Free(stack); @@ -804,8 +829,9 @@ _PyObject_VectorcallMethod(PyObject *name, PyObject *const *args, PyObject * PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) { + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } PyObject *callable = NULL; @@ -817,7 +843,7 @@ PyObject_CallMethodObjArgs(PyObject *obj, PyObject *name, ...) va_list vargs; va_start(vargs, name); - PyObject *result = object_vacall(obj, callable, vargs); + PyObject *result = object_vacall(tstate, obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -829,8 +855,9 @@ PyObject * _PyObject_CallMethodIdObjArgs(PyObject *obj, struct _Py_Identifier *name, ...) { + PyThreadState *tstate = _PyThreadState_GET(); if (obj == NULL || name == NULL) { - return null_error(); + return null_error(tstate); } PyObject *oname = _PyUnicode_FromId(name); /* borrowed */ @@ -847,7 +874,7 @@ _PyObject_CallMethodIdObjArgs(PyObject *obj, va_list vargs; va_start(vargs, name); - PyObject *result = object_vacall(obj, callable, vargs); + PyObject *result = object_vacall(tstate, obj, callable, vargs); va_end(vargs); Py_DECREF(callable); @@ -858,11 +885,12 @@ _PyObject_CallMethodIdObjArgs(PyObject *obj, PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...) { + PyThreadState *tstate = _PyThreadState_GET(); va_list vargs; PyObject *result; va_start(vargs, callable); - result = object_vacall(NULL, callable, vargs); + result = object_vacall(tstate, NULL, callable, vargs); va_end(vargs); return result; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 50a3c15..7203634 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1,6 +1,7 @@ /* Type object implementation */ #include "Python.h" +#include "pycore_call.h" #include "pycore_object.h" #include "pycore_pyerrors.h" #include "pycore_pystate.h" @@ -6554,19 +6555,21 @@ slot_tp_hash(PyObject *self) static PyObject * slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); _Py_IDENTIFIER(__call__); int unbound; - PyObject *meth = lookup_method(self, &PyId___call__, &unbound); - PyObject *res; - if (meth == NULL) + PyObject *meth = lookup_method(self, &PyId___call__, &unbound); + if (meth == NULL) { return NULL; + } + PyObject *res; if (unbound) { - res = _PyObject_Call_Prepend(meth, self, args, kwds); + res = _PyObject_Call_Prepend(tstate, meth, self, args, kwds); } else { - res = PyObject_Call(meth, args, kwds); + res = _PyObject_Call(tstate, meth, args, kwds); } Py_DECREF(meth); @@ -6688,17 +6691,16 @@ static PyObject * slot_tp_richcompare(PyObject *self, PyObject *other, int op) { PyThreadState *tstate = _PyThreadState_GET(); - int unbound; - PyObject *func, *res; - func = lookup_maybe_method(self, &name_op[op], &unbound); + int unbound; + PyObject *func = lookup_maybe_method(self, &name_op[op], &unbound); if (func == NULL) { PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } PyObject *stack[2] = {self, other}; - res = vectorcall_unbound(tstate, unbound, func, stack, 2); + PyObject *res = vectorcall_unbound(tstate, unbound, func, stack, 2); Py_DECREF(func); return res; } @@ -6793,18 +6795,21 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) static int slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); + _Py_IDENTIFIER(__init__); int unbound; PyObject *meth = lookup_method(self, &PyId___init__, &unbound); - PyObject *res; - - if (meth == NULL) + if (meth == NULL) { return -1; + } + + PyObject *res; if (unbound) { - res = _PyObject_Call_Prepend(meth, self, args, kwds); + res = _PyObject_Call_Prepend(tstate, meth, self, args, kwds); } else { - res = PyObject_Call(meth, args, kwds); + res = _PyObject_Call(tstate, meth, args, kwds); } Py_DECREF(meth); if (res == NULL) @@ -6823,6 +6828,7 @@ slot_tp_init(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { + PyThreadState *tstate = _PyThreadState_GET(); PyObject *func, *result; func = _PyObject_GetAttrId((PyObject *)type, &PyId___new__); @@ -6830,7 +6836,7 @@ slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } - result = _PyObject_Call_Prepend(func, (PyObject *)type, args, kwds); + result = _PyObject_Call_Prepend(tstate, func, (PyObject *)type, args, kwds); Py_DECREF(func); return result; } diff --git a/PCbuild/pythoncore.vcxproj b/PCbuild/pythoncore.vcxproj index b724740..f5be8aa 100644 --- a/PCbuild/pythoncore.vcxproj +++ b/PCbuild/pythoncore.vcxproj @@ -160,6 +160,7 @@ + diff --git a/PCbuild/pythoncore.vcxproj.filters b/PCbuild/pythoncore.vcxproj.filters index 8090813..ba1839f 100644 --- a/PCbuild/pythoncore.vcxproj.filters +++ b/PCbuild/pythoncore.vcxproj.filters @@ -183,6 +183,9 @@ Include + + Include + Include diff --git a/Python/_warnings.c b/Python/_warnings.c index dd2b072..b8585d2 100644 --- a/Python/_warnings.c +++ b/Python/_warnings.c @@ -1,4 +1,5 @@ #include "Python.h" +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "frameobject.h" #include "clinic/_warnings.c.h" @@ -27,10 +28,11 @@ static struct PyModuleDef warningsmodule; static WarningsState * _Warnings_GetState() { - PyThreadState *tstate = PyThreadState_GET(); + PyThreadState *tstate = _PyThreadState_GET(); if (tstate == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "_Warnings_GetState: could not identify current interpreter"); + _PyErr_SetString(tstate, PyExc_RuntimeError, + "_Warnings_GetState: could not identify " + "current interpreter"); return NULL; } return &tstate->interp->warnings; diff --git a/Python/bltinmodule.c b/Python/bltinmodule.c index d79e254..4470310 100644 --- a/Python/bltinmodule.c +++ b/Python/bltinmodule.c @@ -4,6 +4,7 @@ #include #include "ast.h" #undef Yield /* undefine macro conflicting with */ +#include "pycore_pyerrors.h" #include "pycore_pystate.h" #include "pycore_tupleobject.h" @@ -1254,23 +1255,23 @@ map_next(mapobject *lz) { PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; - Py_ssize_t niters, nargs, i; PyObject *result = NULL; + PyThreadState *tstate = _PyThreadState_GET(); - niters = PyTuple_GET_SIZE(lz->iters); + const Py_ssize_t niters = PyTuple_GET_SIZE(lz->iters); if (niters <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; } else { stack = PyMem_Malloc(niters * sizeof(stack[0])); if (stack == NULL) { - PyErr_NoMemory(); + _PyErr_NoMemory(tstate); return NULL; } } - nargs = 0; - for (i=0; i < niters; i++) { + Py_ssize_t nargs = 0; + for (Py_ssize_t i=0; i < niters; i++) { PyObject *it = PyTuple_GET_ITEM(lz->iters, i); PyObject *val = Py_TYPE(it)->tp_iternext(it); if (val == NULL) { @@ -1280,10 +1281,10 @@ map_next(mapobject *lz) nargs++; } - result = _PyObject_FastCall(lz->func, stack, nargs); + result = _PyObject_VectorcallTstate(tstate, lz->func, stack, nargs, NULL); exit: - for (i=0; i < nargs; i++) { + for (Py_ssize_t i=0; i < nargs; i++) { Py_DECREF(stack[i]); } if (stack != small_stack) { diff --git a/Python/ceval.c b/Python/ceval.c index 046cd69..11d25a5 100644 --- a/Python/ceval.c +++ b/Python/ceval.c @@ -10,6 +10,7 @@ #define PY_LOCAL_AGGRESSIVE #include "Python.h" +#include "pycore_call.h" #include "pycore_ceval.h" #include "pycore_code.h" #include "pycore_object.h" @@ -4306,7 +4307,6 @@ fail: /* Jump here from prelude on failure */ current Python frame (f), the associated C stack is still in use, so recursion_depth must be boosted for the duration. */ - assert(tstate != NULL); if (Py_REFCNT(f) > 1) { Py_DECREF(f); _PyObject_GC_TRACK(f); @@ -5024,10 +5024,11 @@ do_call_core(PyThreadState *tstate, PyObject *func, PyObject *callargs, PyObject return NULL; } - C_TRACE(result, _PyObject_FastCallDict(func, - &_PyTuple_ITEMS(callargs)[1], - nargs - 1, - kwdict)); + C_TRACE(result, _PyObject_FastCallDictTstate( + tstate, func, + &_PyTuple_ITEMS(callargs)[1], + nargs - 1, + kwdict)); Py_DECREF(func); return result; } -- cgit v0.12