bpo-38644: Add _PyObject_VectorcallTstate() (GH-17052)

* Add _PyObject_VectorcallTstate() function: similar to
  _PyObject_Vectorcall(), but with tstate parameter
* Add tstate parameter to _PyObject_MakeTpCall()
This commit is contained in:
Victor Stinner 2019-11-08 10:05:17 +01:00 committed by GitHub
parent befa032d88
commit 7e43373317
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 94 additions and 50 deletions

View file

@ -3,6 +3,7 @@
#include "pycore_context.h"
#include "pycore_hamt.h"
#include "pycore_object.h"
#include "pycore_pyerrors.h"
#include "pycore_pystate.h"
#include "structmember.h"
@ -101,21 +102,18 @@ PyContext_CopyCurrent(void)
}
int
PyContext_Enter(PyObject *octx)
static int
_PyContext_Enter(PyThreadState *ts, PyObject *octx)
{
ENSURE_Context(octx, -1)
PyContext *ctx = (PyContext *)octx;
if (ctx->ctx_entered) {
PyErr_Format(PyExc_RuntimeError,
"cannot enter context: %R is already entered", ctx);
_PyErr_Format(ts, PyExc_RuntimeError,
"cannot enter context: %R is already entered", ctx);
return -1;
}
PyThreadState *ts = _PyThreadState_GET();
assert(ts != NULL);
ctx->ctx_prev = (PyContext *)ts->context; /* borrow */
ctx->ctx_entered = 1;
@ -128,7 +126,16 @@ PyContext_Enter(PyObject *octx)
int
PyContext_Exit(PyObject *octx)
PyContext_Enter(PyObject *octx)
{
PyThreadState *ts = _PyThreadState_GET();
assert(ts != NULL);
return _PyContext_Enter(ts, octx);
}
static int
_PyContext_Exit(PyThreadState *ts, PyObject *octx)
{
ENSURE_Context(octx, -1)
PyContext *ctx = (PyContext *)octx;
@ -139,9 +146,6 @@ PyContext_Exit(PyObject *octx)
return -1;
}
PyThreadState *ts = _PyThreadState_GET();
assert(ts != NULL);
if (ts->context != (PyObject *)ctx) {
/* Can only happen if someone misuses the C API */
PyErr_SetString(PyExc_RuntimeError,
@ -159,6 +163,14 @@ PyContext_Exit(PyObject *octx)
return 0;
}
int
PyContext_Exit(PyObject *octx)
{
PyThreadState *ts = _PyThreadState_GET();
assert(ts != NULL);
return _PyContext_Exit(ts, octx);
}
PyObject *
PyContextVar_New(const char *name, PyObject *def)
@ -621,20 +633,22 @@ static PyObject *
context_run(PyContext *self, PyObject *const *args,
Py_ssize_t nargs, PyObject *kwnames)
{
PyThreadState *ts = _PyThreadState_GET();
if (nargs < 1) {
PyErr_SetString(PyExc_TypeError,
"run() missing 1 required positional argument");
_PyErr_SetString(ts, PyExc_TypeError,
"run() missing 1 required positional argument");
return NULL;
}
if (PyContext_Enter((PyObject *)self)) {
if (_PyContext_Enter(ts, (PyObject *)self)) {
return NULL;
}
PyObject *call_result = _PyObject_Vectorcall(
args[0], args + 1, nargs - 1, kwnames);
PyObject *call_result = _PyObject_VectorcallTstate(
ts, args[0], args + 1, nargs - 1, kwnames);
if (PyContext_Exit((PyObject *)self)) {
if (_PyContext_Exit(ts, (PyObject *)self)) {
return NULL;
}