mirror of https://github.com/python/cpython
Use static inline function Py_EnterRecursiveCall() (#91988)
Currently, calling Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() may use a function call or a static inline function call, depending if the internal pycore_ceval.h header file is included or not. Use a different name for the static inline function to ensure that the static inline function is always used in Python internals for best performance. Similar approach than PyThreadState_GET() (function call) and _PyThreadState_GET() (static inline function). * Rename _Py_EnterRecursiveCall() to _Py_EnterRecursiveCallTstate() * Rename _Py_LeaveRecursiveCall() to _Py_LeaveRecursiveCallTstate() * pycore_ceval.h: Rename Py_EnterRecursiveCall() to _Py_EnterRecursiveCall() and Py_LeaveRecursiveCall() and _Py_LeaveRecursiveCall()
This commit is contained in:
parent
14243369b5
commit
d716a0dfe2
|
@ -91,7 +91,7 @@ extern void _PyEval_DeactivateOpCache(void);
|
||||||
|
|
||||||
#ifdef USE_STACKCHECK
|
#ifdef USE_STACKCHECK
|
||||||
/* With USE_STACKCHECK macro defined, trigger stack checks in
|
/* With USE_STACKCHECK macro defined, trigger stack checks in
|
||||||
_Py_CheckRecursiveCall() on every 64th call to Py_EnterRecursiveCall. */
|
_Py_CheckRecursiveCall() on every 64th call to _Py_EnterRecursiveCall. */
|
||||||
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
static inline int _Py_MakeRecCheck(PyThreadState *tstate) {
|
||||||
return (tstate->recursion_remaining-- <= 0
|
return (tstate->recursion_remaining-- <= 0
|
||||||
|| (tstate->recursion_remaining & 63) == 0);
|
|| (tstate->recursion_remaining & 63) == 0);
|
||||||
|
@ -106,29 +106,25 @@ PyAPI_FUNC(int) _Py_CheckRecursiveCall(
|
||||||
PyThreadState *tstate,
|
PyThreadState *tstate,
|
||||||
const char *where);
|
const char *where);
|
||||||
|
|
||||||
static inline int _Py_EnterRecursiveCall(PyThreadState *tstate,
|
static inline int _Py_EnterRecursiveCallTstate(PyThreadState *tstate,
|
||||||
const char *where) {
|
const char *where) {
|
||||||
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
|
return (_Py_MakeRecCheck(tstate) && _Py_CheckRecursiveCall(tstate, where));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int _Py_EnterRecursiveCall_inline(const char *where) {
|
static inline int _Py_EnterRecursiveCall(const char *where) {
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
return _Py_EnterRecursiveCall(tstate, where);
|
return _Py_EnterRecursiveCallTstate(tstate, where);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Py_EnterRecursiveCall(where) _Py_EnterRecursiveCall_inline(where)
|
static inline void _Py_LeaveRecursiveCallTstate(PyThreadState *tstate) {
|
||||||
|
|
||||||
static inline void _Py_LeaveRecursiveCall(PyThreadState *tstate) {
|
|
||||||
tstate->recursion_remaining++;
|
tstate->recursion_remaining++;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void _Py_LeaveRecursiveCall_inline(void) {
|
static inline void _Py_LeaveRecursiveCall(void) {
|
||||||
PyThreadState *tstate = _PyThreadState_GET();
|
PyThreadState *tstate = _PyThreadState_GET();
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Py_LeaveRecursiveCall() _Py_LeaveRecursiveCall_inline()
|
|
||||||
|
|
||||||
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
|
extern struct _PyInterpreterFrame* _PyEval_GetFrame(void);
|
||||||
|
|
||||||
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
|
extern PyObject* _Py_MakeCoro(PyFunctionObject *func);
|
||||||
|
|
|
@ -112,6 +112,7 @@ bytes(cdata)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
||||||
#include "structmember.h" // PyMemberDef
|
#include "structmember.h" // PyMemberDef
|
||||||
|
|
||||||
#include <ffi.h>
|
#include <ffi.h>
|
||||||
|
@ -2270,12 +2271,12 @@ PyCSimpleType_from_param(PyObject *type, PyObject *value)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (as_parameter) {
|
if (as_parameter) {
|
||||||
if (Py_EnterRecursiveCall("while processing _as_parameter_")) {
|
if (_Py_EnterRecursiveCall("while processing _as_parameter_")) {
|
||||||
Py_DECREF(as_parameter);
|
Py_DECREF(as_parameter);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
value = PyCSimpleType_from_param(type, as_parameter);
|
value = PyCSimpleType_from_param(type, as_parameter);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
Py_DECREF(as_parameter);
|
Py_DECREF(as_parameter);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define NEEDS_PY_IDENTIFIER
|
#define NEEDS_PY_IDENTIFIER
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
||||||
#include "structmember.h" // PyMemberDef
|
#include "structmember.h" // PyMemberDef
|
||||||
#include "pycore_accu.h"
|
#include "pycore_accu.h"
|
||||||
|
|
||||||
|
@ -1059,19 +1060,19 @@ scan_once_unicode(PyScannerObject *s, PyObject *pystr, Py_ssize_t idx, Py_ssize_
|
||||||
return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr);
|
return scanstring_unicode(pystr, idx + 1, s->strict, next_idx_ptr);
|
||||||
case '{':
|
case '{':
|
||||||
/* object */
|
/* object */
|
||||||
if (Py_EnterRecursiveCall(" while decoding a JSON object "
|
if (_Py_EnterRecursiveCall(" while decoding a JSON object "
|
||||||
"from a unicode string"))
|
"from a unicode string"))
|
||||||
return NULL;
|
return NULL;
|
||||||
res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
|
res = _parse_object_unicode(s, pystr, idx + 1, next_idx_ptr);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return res;
|
return res;
|
||||||
case '[':
|
case '[':
|
||||||
/* array */
|
/* array */
|
||||||
if (Py_EnterRecursiveCall(" while decoding a JSON array "
|
if (_Py_EnterRecursiveCall(" while decoding a JSON array "
|
||||||
"from a unicode string"))
|
"from a unicode string"))
|
||||||
return NULL;
|
return NULL;
|
||||||
res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
|
res = _parse_array_unicode(s, pystr, idx + 1, next_idx_ptr);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return res;
|
return res;
|
||||||
case 'n':
|
case 'n':
|
||||||
/* null */
|
/* null */
|
||||||
|
@ -1430,17 +1431,17 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
|
||||||
return _steal_accumulate(acc, encoded);
|
return _steal_accumulate(acc, encoded);
|
||||||
}
|
}
|
||||||
else if (PyList_Check(obj) || PyTuple_Check(obj)) {
|
else if (PyList_Check(obj) || PyTuple_Check(obj)) {
|
||||||
if (Py_EnterRecursiveCall(" while encoding a JSON object"))
|
if (_Py_EnterRecursiveCall(" while encoding a JSON object"))
|
||||||
return -1;
|
return -1;
|
||||||
rv = encoder_listencode_list(s, acc, obj, indent_level);
|
rv = encoder_listencode_list(s, acc, obj, indent_level);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
else if (PyDict_Check(obj)) {
|
else if (PyDict_Check(obj)) {
|
||||||
if (Py_EnterRecursiveCall(" while encoding a JSON object"))
|
if (_Py_EnterRecursiveCall(" while encoding a JSON object"))
|
||||||
return -1;
|
return -1;
|
||||||
rv = encoder_listencode_dict(s, acc, obj, indent_level);
|
rv = encoder_listencode_dict(s, acc, obj, indent_level);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -1468,13 +1469,13 @@ encoder_listencode_obj(PyEncoderObject *s, _PyAccu *acc,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Py_EnterRecursiveCall(" while encoding a JSON object")) {
|
if (_Py_EnterRecursiveCall(" while encoding a JSON object")) {
|
||||||
Py_DECREF(newobj);
|
Py_DECREF(newobj);
|
||||||
Py_XDECREF(ident);
|
Py_XDECREF(ident);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
rv = encoder_listencode_obj(s, acc, newobj, indent_level);
|
rv = encoder_listencode_obj(s, acc, newobj, indent_level);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
|
|
||||||
Py_DECREF(newobj);
|
Py_DECREF(newobj);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
||||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||||
#include "pycore_runtime.h" // _Py_ID()
|
#include "pycore_runtime.h" // _Py_ID()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
@ -3068,21 +3069,21 @@ save_list(PicklerObject *self, PyObject *obj)
|
||||||
if (len != 0) {
|
if (len != 0) {
|
||||||
/* Materialize the list elements. */
|
/* Materialize the list elements. */
|
||||||
if (PyList_CheckExact(obj) && self->proto > 0) {
|
if (PyList_CheckExact(obj) && self->proto > 0) {
|
||||||
if (Py_EnterRecursiveCall(" while pickling an object"))
|
if (_Py_EnterRecursiveCall(" while pickling an object"))
|
||||||
goto error;
|
goto error;
|
||||||
status = batch_list_exact(self, obj);
|
status = batch_list_exact(self, obj);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
} else {
|
} else {
|
||||||
PyObject *iter = PyObject_GetIter(obj);
|
PyObject *iter = PyObject_GetIter(obj);
|
||||||
if (iter == NULL)
|
if (iter == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (Py_EnterRecursiveCall(" while pickling an object")) {
|
if (_Py_EnterRecursiveCall(" while pickling an object")) {
|
||||||
Py_DECREF(iter);
|
Py_DECREF(iter);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
status = batch_list(self, iter);
|
status = batch_list(self, iter);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
Py_DECREF(iter);
|
Py_DECREF(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3327,10 +3328,10 @@ save_dict(PicklerObject *self, PyObject *obj)
|
||||||
if (PyDict_CheckExact(obj) && self->proto > 0) {
|
if (PyDict_CheckExact(obj) && self->proto > 0) {
|
||||||
/* We can take certain shortcuts if we know this is a dict and
|
/* We can take certain shortcuts if we know this is a dict and
|
||||||
not a dict subclass. */
|
not a dict subclass. */
|
||||||
if (Py_EnterRecursiveCall(" while pickling an object"))
|
if (_Py_EnterRecursiveCall(" while pickling an object"))
|
||||||
goto error;
|
goto error;
|
||||||
status = batch_dict_exact(self, obj);
|
status = batch_dict_exact(self, obj);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
} else {
|
} else {
|
||||||
items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items));
|
items = PyObject_CallMethodNoArgs(obj, &_Py_ID(items));
|
||||||
if (items == NULL)
|
if (items == NULL)
|
||||||
|
@ -3339,12 +3340,12 @@ save_dict(PicklerObject *self, PyObject *obj)
|
||||||
Py_DECREF(items);
|
Py_DECREF(items);
|
||||||
if (iter == NULL)
|
if (iter == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (Py_EnterRecursiveCall(" while pickling an object")) {
|
if (_Py_EnterRecursiveCall(" while pickling an object")) {
|
||||||
Py_DECREF(iter);
|
Py_DECREF(iter);
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
status = batch_dict(self, iter);
|
status = batch_dict(self, iter);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
Py_DECREF(iter);
|
Py_DECREF(iter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4300,9 +4301,9 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
|
||||||
return save_unicode(self, obj);
|
return save_unicode(self, obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We're only calling Py_EnterRecursiveCall here so that atomic
|
/* We're only calling _Py_EnterRecursiveCall here so that atomic
|
||||||
types above are pickled faster. */
|
types above are pickled faster. */
|
||||||
if (Py_EnterRecursiveCall(" while pickling an object")) {
|
if (_Py_EnterRecursiveCall(" while pickling an object")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4460,7 +4461,7 @@ save(PicklerObject *self, PyObject *obj, int pers_save)
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
|
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
Py_XDECREF(reduce_func);
|
Py_XDECREF(reduce_func);
|
||||||
Py_XDECREF(reduce_value);
|
Py_XDECREF(reduce_value);
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_abstract.h" // _PyIndex_Check()
|
#include "pycore_abstract.h" // _PyIndex_Check()
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||||
#include "pycore_object.h" // _Py_CheckSlotResult()
|
#include "pycore_object.h" // _Py_CheckSlotResult()
|
||||||
#include "pycore_pyerrors.h" // _PyErr_Occurred()
|
#include "pycore_pyerrors.h" // _PyErr_Occurred()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
@ -2546,7 +2546,7 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert(n >= 2);
|
assert(n >= 2);
|
||||||
if (Py_EnterRecursiveCall(" in __issubclass__")) {
|
if (_Py_EnterRecursiveCall(" in __issubclass__")) {
|
||||||
Py_DECREF(bases);
|
Py_DECREF(bases);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -2556,7 +2556,7 @@ abstract_issubclass(PyObject *derived, PyObject *cls)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
Py_DECREF(bases);
|
Py_DECREF(bases);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
@ -2633,7 +2633,7 @@ object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls
|
||||||
if (PyTuple_Check(cls)) {
|
if (PyTuple_Check(cls)) {
|
||||||
/* Not a general sequence -- that opens up the road to
|
/* Not a general sequence -- that opens up the road to
|
||||||
recursion and stack overflow. */
|
recursion and stack overflow. */
|
||||||
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Py_ssize_t n = PyTuple_GET_SIZE(cls);
|
Py_ssize_t n = PyTuple_GET_SIZE(cls);
|
||||||
|
@ -2646,19 +2646,19 @@ object_recursive_isinstance(PyThreadState *tstate, PyObject *inst, PyObject *cls
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__));
|
PyObject *checker = _PyObject_LookupSpecial(cls, &_Py_ID(__instancecheck__));
|
||||||
if (checker != NULL) {
|
if (checker != NULL) {
|
||||||
if (_Py_EnterRecursiveCall(tstate, " in __instancecheck__")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " in __instancecheck__")) {
|
||||||
Py_DECREF(checker);
|
Py_DECREF(checker);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *res = PyObject_CallOneArg(checker, inst);
|
PyObject *res = PyObject_CallOneArg(checker, inst);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
Py_DECREF(checker);
|
Py_DECREF(checker);
|
||||||
|
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
|
@ -2725,7 +2725,7 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
|
||||||
|
|
||||||
if (PyTuple_Check(cls)) {
|
if (PyTuple_Check(cls)) {
|
||||||
|
|
||||||
if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
Py_ssize_t n = PyTuple_GET_SIZE(cls);
|
Py_ssize_t n = PyTuple_GET_SIZE(cls);
|
||||||
|
@ -2737,19 +2737,19 @@ object_issubclass(PyThreadState *tstate, PyObject *derived, PyObject *cls)
|
||||||
/* either found it, or got an error */
|
/* either found it, or got an error */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
checker = _PyObject_LookupSpecial(cls, &_Py_ID(__subclasscheck__));
|
checker = _PyObject_LookupSpecial(cls, &_Py_ID(__subclasscheck__));
|
||||||
if (checker != NULL) {
|
if (checker != NULL) {
|
||||||
int ok = -1;
|
int ok = -1;
|
||||||
if (_Py_EnterRecursiveCall(tstate, " in __subclasscheck__")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " in __subclasscheck__")) {
|
||||||
Py_DECREF(checker);
|
Py_DECREF(checker);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
PyObject *res = PyObject_CallOneArg(checker, derived);
|
PyObject *res = PyObject_CallOneArg(checker, derived);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
Py_DECREF(checker);
|
Py_DECREF(checker);
|
||||||
if (res != NULL) {
|
if (res != NULL) {
|
||||||
ok = PyObject_IsTrue(res);
|
ok = PyObject_IsTrue(res);
|
||||||
|
|
|
@ -3489,7 +3489,7 @@ _PyBytesWriter_Alloc(_PyBytesWriter *writer, Py_ssize_t size)
|
||||||
Don't modify the _PyBytesWriter structure (use a shorter small buffer)
|
Don't modify the _PyBytesWriter structure (use a shorter small buffer)
|
||||||
in debug mode to also be able to detect stack overflow when running
|
in debug mode to also be able to detect stack overflow when running
|
||||||
tests in debug mode. The _PyBytesWriter is large (more than 512 bytes),
|
tests in debug mode. The _PyBytesWriter is large (more than 512 bytes),
|
||||||
if Py_EnterRecursiveCall() is not used in deep C callback, we may hit a
|
if _Py_EnterRecursiveCall() is not used in deep C callback, we may hit a
|
||||||
stack overflow. */
|
stack overflow. */
|
||||||
writer->allocated = Py_MIN(writer->allocated, 10);
|
writer->allocated = Py_MIN(writer->allocated, 10);
|
||||||
/* _PyBytesWriter_CheckConsistency() requires the last byte to be 0,
|
/* _PyBytesWriter_CheckConsistency() requires the last byte to be 0,
|
||||||
|
|
|
@ -209,11 +209,11 @@ _PyObject_MakeTpCall(PyThreadState *tstate, PyObject *callable,
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object") == 0)
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object") == 0)
|
||||||
{
|
{
|
||||||
result = _PyCFunctionWithKeywords_TrampolineCall(
|
result = _PyCFunctionWithKeywords_TrampolineCall(
|
||||||
(PyCFunctionWithKeywords)call, callable, argstuple, kwdict);
|
(PyCFunctionWithKeywords)call, callable, argstuple, kwdict);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Py_DECREF(argstuple);
|
Py_DECREF(argstuple);
|
||||||
|
@ -336,13 +336,13 @@ _PyObject_Call(PyThreadState *tstate, PyObject *callable,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = (*call)(callable, args, kwargs);
|
result = (*call)(callable, args, kwargs);
|
||||||
|
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
|
|
||||||
return _Py_CheckFunctionResult(tstate, callable, result, NULL);
|
return _Py_CheckFunctionResult(tstate, callable, result, NULL);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Descriptors -- a new, flexible way to describe attributes */
|
/* Descriptors -- a new, flexible way to describe attributes */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
#include "pycore_tuple.h" // _PyTuple_ITEMS()
|
||||||
|
@ -302,7 +302,7 @@ typedef void (*funcptr)(void);
|
||||||
static inline funcptr
|
static inline funcptr
|
||||||
method_enter_call(PyThreadState *tstate, PyObject *func)
|
method_enter_call(PyThreadState *tstate, PyObject *func)
|
||||||
{
|
{
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
|
return (funcptr)((PyMethodDescrObject *)func)->d_method->ml_meth;
|
||||||
|
@ -330,7 +330,7 @@ method_vectorcall_VARARGS(
|
||||||
PyObject *result = _PyCFunction_TrampolineCall(
|
PyObject *result = _PyCFunction_TrampolineCall(
|
||||||
meth, args[0], argstuple);
|
meth, args[0], argstuple);
|
||||||
Py_DECREF(argstuple);
|
Py_DECREF(argstuple);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ method_vectorcall_VARARGS_KEYWORDS(
|
||||||
}
|
}
|
||||||
result = _PyCFunctionWithKeywords_TrampolineCall(
|
result = _PyCFunctionWithKeywords_TrampolineCall(
|
||||||
meth, args[0], argstuple, kwdict);
|
meth, args[0], argstuple, kwdict);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
exit:
|
exit:
|
||||||
Py_DECREF(argstuple);
|
Py_DECREF(argstuple);
|
||||||
Py_XDECREF(kwdict);
|
Py_XDECREF(kwdict);
|
||||||
|
@ -386,7 +386,7 @@ method_vectorcall_FASTCALL_KEYWORDS_METHOD(
|
||||||
PyObject *result = meth(args[0],
|
PyObject *result = meth(args[0],
|
||||||
((PyMethodDescrObject *)func)->d_common.d_type,
|
((PyMethodDescrObject *)func)->d_common.d_type,
|
||||||
args+1, nargs-1, kwnames);
|
args+1, nargs-1, kwnames);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ method_vectorcall_FASTCALL(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = meth(args[0], args+1, nargs-1);
|
PyObject *result = meth(args[0], args+1, nargs-1);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ method_vectorcall_FASTCALL_KEYWORDS(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
|
PyObject *result = meth(args[0], args+1, nargs-1, kwnames);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +451,7 @@ method_vectorcall_NOARGS(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL);
|
PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], NULL);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,7 +479,7 @@ method_vectorcall_O(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]);
|
PyObject *result = _PyCFunction_TrampolineCall(meth, args[0], args[1]);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#define PY_SSIZE_T_CLEAN
|
#define PY_SSIZE_T_CLEAN
|
||||||
#include <Python.h>
|
#include <Python.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall
|
||||||
#include "pycore_exceptions.h" // struct _Py_exc_state
|
#include "pycore_exceptions.h" // struct _Py_exc_state
|
||||||
#include "pycore_initconfig.h"
|
#include "pycore_initconfig.h"
|
||||||
#include "pycore_object.h"
|
#include "pycore_object.h"
|
||||||
|
@ -1097,7 +1098,7 @@ exceptiongroup_split_recursive(PyObject *exc,
|
||||||
for (Py_ssize_t i = 0; i < num_excs; i++) {
|
for (Py_ssize_t i = 0; i < num_excs; i++) {
|
||||||
PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
|
PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
|
||||||
_exceptiongroup_split_result rec_result;
|
_exceptiongroup_split_result rec_result;
|
||||||
if (Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
|
if (_Py_EnterRecursiveCall(" in exceptiongroup_split_recursive")) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
if (exceptiongroup_split_recursive(
|
if (exceptiongroup_split_recursive(
|
||||||
|
@ -1105,10 +1106,10 @@ exceptiongroup_split_recursive(PyObject *exc,
|
||||||
construct_rest, &rec_result) < 0) {
|
construct_rest, &rec_result) < 0) {
|
||||||
assert(!rec_result.match);
|
assert(!rec_result.match);
|
||||||
assert(!rec_result.rest);
|
assert(!rec_result.rest);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
if (rec_result.match) {
|
if (rec_result.match) {
|
||||||
assert(PyList_CheckExact(match_list));
|
assert(PyList_CheckExact(match_list));
|
||||||
if (PyList_Append(match_list, rec_result.match) < 0) {
|
if (PyList_Append(match_list, rec_result.match) < 0) {
|
||||||
|
@ -1234,11 +1235,11 @@ collect_exception_group_leaves(PyObject *exc, PyObject *leaves)
|
||||||
/* recursive calls */
|
/* recursive calls */
|
||||||
for (Py_ssize_t i = 0; i < num_excs; i++) {
|
for (Py_ssize_t i = 0; i < num_excs; i++) {
|
||||||
PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
|
PyObject *e = PyTuple_GET_ITEM(eg->excs, i);
|
||||||
if (Py_EnterRecursiveCall(" in collect_exception_group_leaves")) {
|
if (_Py_EnterRecursiveCall(" in collect_exception_group_leaves")) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int res = collect_exception_group_leaves(e, leaves);
|
int res = collect_exception_group_leaves(e, leaves);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* Method object implementation */
|
/* Method object implementation */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||||
#include "pycore_object.h"
|
#include "pycore_object.h"
|
||||||
#include "pycore_pyerrors.h"
|
#include "pycore_pyerrors.h"
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
|
@ -403,7 +403,7 @@ typedef void (*funcptr)(void);
|
||||||
static inline funcptr
|
static inline funcptr
|
||||||
cfunction_enter_call(PyThreadState *tstate, PyObject *func)
|
cfunction_enter_call(PyThreadState *tstate, PyObject *func)
|
||||||
{
|
{
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return (funcptr)PyCFunction_GET_FUNCTION(func);
|
return (funcptr)PyCFunction_GET_FUNCTION(func);
|
||||||
|
@ -425,7 +425,7 @@ cfunction_vectorcall_FASTCALL(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
|
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -441,7 +441,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
|
PyObject *result = meth(PyCFunction_GET_SELF(func), args, nargs, kwnames);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ cfunction_vectorcall_FASTCALL_KEYWORDS_METHOD(
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
|
PyObject *result = meth(PyCFunction_GET_SELF(func), cls, args, nargs, kwnames);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -485,7 +485,7 @@ cfunction_vectorcall_NOARGS(
|
||||||
}
|
}
|
||||||
PyObject *result = _PyCFunction_TrampolineCall(
|
PyObject *result = _PyCFunction_TrampolineCall(
|
||||||
meth, PyCFunction_GET_SELF(func), NULL);
|
meth, PyCFunction_GET_SELF(func), NULL);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,7 +513,7 @@ cfunction_vectorcall_O(
|
||||||
}
|
}
|
||||||
PyObject *result = _PyCFunction_TrampolineCall(
|
PyObject *result = _PyCFunction_TrampolineCall(
|
||||||
meth, PyCFunction_GET_SELF(func), args[0]);
|
meth, PyCFunction_GET_SELF(func), args[0]);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
#include "pycore_call.h" // _PyObject_CallNoArgs()
|
||||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCall()
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||||
#include "pycore_context.h" // _PyContextTokenMissing_Type
|
#include "pycore_context.h" // _PyContextTokenMissing_Type
|
||||||
#include "pycore_dict.h" // _PyObject_MakeDictFromInstanceAttributes()
|
#include "pycore_dict.h" // _PyObject_MakeDictFromInstanceAttributes()
|
||||||
#include "pycore_floatobject.h" // _PyFloat_DebugMallocStats()
|
#include "pycore_floatobject.h" // _PyFloat_DebugMallocStats()
|
||||||
|
@ -427,12 +427,12 @@ PyObject_Repr(PyObject *v)
|
||||||
|
|
||||||
/* It is possible for a type to have a tp_repr representation that loops
|
/* It is possible for a type to have a tp_repr representation that loops
|
||||||
infinitely. */
|
infinitely. */
|
||||||
if (_Py_EnterRecursiveCall(tstate,
|
if (_Py_EnterRecursiveCallTstate(tstate,
|
||||||
" while getting the repr of an object")) {
|
" while getting the repr of an object")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
res = (*Py_TYPE(v)->tp_repr)(v);
|
res = (*Py_TYPE(v)->tp_repr)(v);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
|
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -487,11 +487,11 @@ PyObject_Str(PyObject *v)
|
||||||
|
|
||||||
/* It is possible for a type to have a tp_str representation that loops
|
/* It is possible for a type to have a tp_str representation that loops
|
||||||
infinitely. */
|
infinitely. */
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while getting the str of an object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while getting the str of an object")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
res = (*Py_TYPE(v)->tp_str)(v);
|
res = (*Py_TYPE(v)->tp_str)(v);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
|
|
||||||
if (res == NULL) {
|
if (res == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -724,11 +724,11 @@ PyObject_RichCompare(PyObject *v, PyObject *w, int op)
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (_Py_EnterRecursiveCall(tstate, " in comparison")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " in comparison")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyObject *res = do_richcompare(tstate, v, w, op);
|
PyObject *res = do_richcompare(tstate, v, w, op);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -490,11 +490,11 @@ class Obj2ModPrototypeVisitor(PickleVisitor):
|
||||||
class Obj2ModVisitor(PickleVisitor):
|
class Obj2ModVisitor(PickleVisitor):
|
||||||
@contextmanager
|
@contextmanager
|
||||||
def recursive_call(self, node, level):
|
def recursive_call(self, node, level):
|
||||||
self.emit('if (Py_EnterRecursiveCall(" while traversing \'%s\' node")) {' % node, level, reflow=False)
|
self.emit('if (_Py_EnterRecursiveCall(" while traversing \'%s\' node")) {' % node, level, reflow=False)
|
||||||
self.emit('goto failed;', level + 1)
|
self.emit('goto failed;', level + 1)
|
||||||
self.emit('}', level)
|
self.emit('}', level)
|
||||||
yield
|
yield
|
||||||
self.emit('Py_LeaveRecursiveCall();', level)
|
self.emit('_Py_LeaveRecursiveCall();', level)
|
||||||
|
|
||||||
def funcHeader(self, name):
|
def funcHeader(self, name):
|
||||||
ctype = get_c_type(name)
|
ctype = get_c_type(name)
|
||||||
|
@ -1483,6 +1483,7 @@ def generate_module_def(mod, metadata, f, internal_h):
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_ast.h"
|
#include "pycore_ast.h"
|
||||||
#include "pycore_ast_state.h" // struct ast_state
|
#include "pycore_ast_state.h" // struct ast_state
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall
|
||||||
#include "pycore_interp.h" // _PyInterpreterState.ast
|
#include "pycore_interp.h" // _PyInterpreterState.ast
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
#include "structmember.h"
|
#include "structmember.h"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -880,7 +880,7 @@ Py_SetRecursionLimit(int new_limit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The function _Py_EnterRecursiveCall() only calls _Py_CheckRecursiveCall()
|
/* The function _Py_EnterRecursiveCallTstate() only calls _Py_CheckRecursiveCall()
|
||||||
if the recursion_depth reaches recursion_limit. */
|
if the recursion_depth reaches recursion_limit. */
|
||||||
int
|
int
|
||||||
_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
|
_Py_CheckRecursiveCall(PyThreadState *tstate, const char *where)
|
||||||
|
@ -1736,7 +1736,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
||||||
|
|
||||||
/* support for generator.throw() */
|
/* support for generator.throw() */
|
||||||
if (throwflag) {
|
if (throwflag) {
|
||||||
if (_Py_EnterRecursiveCall(tstate, "")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, "")) {
|
||||||
tstate->recursion_remaining--;
|
tstate->recursion_remaining--;
|
||||||
goto exit_unwind;
|
goto exit_unwind;
|
||||||
}
|
}
|
||||||
|
@ -1776,7 +1776,7 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
|
||||||
|
|
||||||
|
|
||||||
start_frame:
|
start_frame:
|
||||||
if (_Py_EnterRecursiveCall(tstate, "")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, "")) {
|
||||||
tstate->recursion_remaining--;
|
tstate->recursion_remaining--;
|
||||||
goto exit_unwind;
|
goto exit_unwind;
|
||||||
}
|
}
|
||||||
|
@ -2492,7 +2492,7 @@ handle_eval_breaker:
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
TRACE_FUNCTION_EXIT();
|
TRACE_FUNCTION_EXIT();
|
||||||
DTRACE_FUNCTION_EXIT();
|
DTRACE_FUNCTION_EXIT();
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
if (!frame->is_entry) {
|
if (!frame->is_entry) {
|
||||||
frame = cframe.current_frame = pop_frame(tstate, frame);
|
frame = cframe.current_frame = pop_frame(tstate, frame);
|
||||||
_PyFrame_StackPush(frame, retval);
|
_PyFrame_StackPush(frame, retval);
|
||||||
|
@ -2704,7 +2704,7 @@ handle_eval_breaker:
|
||||||
_PyFrame_SetStackPointer(frame, stack_pointer);
|
_PyFrame_SetStackPointer(frame, stack_pointer);
|
||||||
TRACE_FUNCTION_EXIT();
|
TRACE_FUNCTION_EXIT();
|
||||||
DTRACE_FUNCTION_EXIT();
|
DTRACE_FUNCTION_EXIT();
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
/* Restore previous cframe and return. */
|
/* Restore previous cframe and return. */
|
||||||
tstate->cframe = cframe.previous;
|
tstate->cframe = cframe.previous;
|
||||||
tstate->cframe->use_tracing = cframe.use_tracing;
|
tstate->cframe->use_tracing = cframe.use_tracing;
|
||||||
|
@ -5066,12 +5066,12 @@ handle_eval_breaker:
|
||||||
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
|
PyCFunction cfunc = PyCFunction_GET_FUNCTION(callable);
|
||||||
// This is slower but CPython promises to check all non-vectorcall
|
// This is slower but CPython promises to check all non-vectorcall
|
||||||
// function calls.
|
// function calls.
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
PyObject *arg = TOP();
|
PyObject *arg = TOP();
|
||||||
PyObject *res = cfunc(PyCFunction_GET_SELF(callable), arg);
|
PyObject *res = cfunc(PyCFunction_GET_SELF(callable), arg);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
|
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
|
@ -5268,11 +5268,11 @@ handle_eval_breaker:
|
||||||
PyCFunction cfunc = meth->ml_meth;
|
PyCFunction cfunc = meth->ml_meth;
|
||||||
// This is slower but CPython promises to check all non-vectorcall
|
// This is slower but CPython promises to check all non-vectorcall
|
||||||
// function calls.
|
// function calls.
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
PyObject *res = cfunc(self, arg);
|
PyObject *res = cfunc(self, arg);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
Py_DECREF(self);
|
Py_DECREF(self);
|
||||||
Py_DECREF(arg);
|
Py_DECREF(arg);
|
||||||
|
@ -5340,11 +5340,11 @@ handle_eval_breaker:
|
||||||
PyCFunction cfunc = meth->ml_meth;
|
PyCFunction cfunc = meth->ml_meth;
|
||||||
// This is slower but CPython promises to check all non-vectorcall
|
// This is slower but CPython promises to check all non-vectorcall
|
||||||
// function calls.
|
// function calls.
|
||||||
if (_Py_EnterRecursiveCall(tstate, " while calling a Python object")) {
|
if (_Py_EnterRecursiveCallTstate(tstate, " while calling a Python object")) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
PyObject *res = cfunc(self, NULL);
|
PyObject *res = cfunc(self, NULL);
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
assert((res != NULL) ^ (_PyErr_Occurred(tstate) != NULL));
|
||||||
Py_DECREF(self);
|
Py_DECREF(self);
|
||||||
STACK_SHRINK(oparg + 1);
|
STACK_SHRINK(oparg + 1);
|
||||||
|
@ -5484,7 +5484,7 @@ handle_eval_breaker:
|
||||||
assert(frame->frame_obj == NULL);
|
assert(frame->frame_obj == NULL);
|
||||||
gen->gi_frame_state = FRAME_CREATED;
|
gen->gi_frame_state = FRAME_CREATED;
|
||||||
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
gen_frame->owner = FRAME_OWNED_BY_GENERATOR;
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
if (!frame->is_entry) {
|
if (!frame->is_entry) {
|
||||||
_PyInterpreterFrame *prev = frame->previous;
|
_PyInterpreterFrame *prev = frame->previous;
|
||||||
_PyThreadState_PopFrame(tstate, frame);
|
_PyThreadState_PopFrame(tstate, frame);
|
||||||
|
@ -5850,7 +5850,7 @@ exception_unwind:
|
||||||
|
|
||||||
exit_unwind:
|
exit_unwind:
|
||||||
assert(_PyErr_Occurred(tstate));
|
assert(_PyErr_Occurred(tstate));
|
||||||
_Py_LeaveRecursiveCall(tstate);
|
_Py_LeaveRecursiveCallTstate(tstate);
|
||||||
if (frame->is_entry) {
|
if (frame->is_entry) {
|
||||||
/* Restore previous cframe and exit */
|
/* Restore previous cframe and exit */
|
||||||
tstate->cframe = cframe.previous;
|
tstate->cframe = cframe.previous;
|
||||||
|
@ -7955,12 +7955,12 @@ maybe_dtrace_line(_PyInterpreterFrame *frame,
|
||||||
|
|
||||||
int Py_EnterRecursiveCall(const char *where)
|
int Py_EnterRecursiveCall(const char *where)
|
||||||
{
|
{
|
||||||
return _Py_EnterRecursiveCall_inline(where);
|
return _Py_EnterRecursiveCall(where);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef Py_LeaveRecursiveCall
|
#undef Py_LeaveRecursiveCall
|
||||||
|
|
||||||
void Py_LeaveRecursiveCall(void)
|
void Py_LeaveRecursiveCall(void)
|
||||||
{
|
{
|
||||||
_Py_LeaveRecursiveCall_inline();
|
_Py_LeaveRecursiveCall();
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
|
||||||
#include "pycore_ast.h" // PyAST_mod2obj
|
#include "pycore_ast.h" // PyAST_mod2obj
|
||||||
|
#include "pycore_ceval.h" // _Py_EnterRecursiveCall
|
||||||
#include "pycore_compile.h" // _PyAST_Compile()
|
#include "pycore_compile.h" // _PyAST_Compile()
|
||||||
#include "pycore_interp.h" // PyInterpreterState.importlib
|
#include "pycore_interp.h" // PyInterpreterState.importlib
|
||||||
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
|
#include "pycore_object.h" // _PyDebug_PrintTotalRefs()
|
||||||
|
@ -1268,13 +1269,13 @@ print_chained(struct exception_print_context* ctx, PyObject *value,
|
||||||
{
|
{
|
||||||
PyObject *f = ctx->file;
|
PyObject *f = ctx->file;
|
||||||
|
|
||||||
if (Py_EnterRecursiveCall(" in print_chained") < 0) {
|
if (_Py_EnterRecursiveCall(" in print_chained") < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
bool need_close = ctx->need_close;
|
bool need_close = ctx->need_close;
|
||||||
int res = print_exception_recursive(ctx, value);
|
int res = print_exception_recursive(ctx, value);
|
||||||
ctx->need_close = need_close;
|
ctx->need_close = need_close;
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1445,11 +1446,11 @@ print_exception_group(struct exception_print_context *ctx, PyObject *value)
|
||||||
PyObject *exc = PyTuple_GET_ITEM(excs, i);
|
PyObject *exc = PyTuple_GET_ITEM(excs, i);
|
||||||
|
|
||||||
if (!truncated) {
|
if (!truncated) {
|
||||||
if (Py_EnterRecursiveCall(" in print_exception_group") != 0) {
|
if (_Py_EnterRecursiveCall(" in print_exception_group") != 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
int res = print_exception_recursive(ctx, exc);
|
int res = print_exception_recursive(ctx, exc);
|
||||||
Py_LeaveRecursiveCall();
|
_Py_LeaveRecursiveCall();
|
||||||
if (res < 0) {
|
if (res < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue