Commit f7bcf72f authored by scoder's avatar scoder Committed by GitHub

Merge pull request #2607 from scoder/gen_exc_py37_fix

Use exception stack in Py3.7
parents c6320307 94b121da
...@@ -4256,7 +4256,10 @@ class GeneratorBodyDefNode(DefNode): ...@@ -4256,7 +4256,10 @@ class GeneratorBodyDefNode(DefNode):
code.put_xgiveref(Naming.retval_cname) code.put_xgiveref(Naming.retval_cname)
else: else:
code.put_xdecref_clear(Naming.retval_cname, py_object_type) code.put_xdecref_clear(Naming.retval_cname, py_object_type)
# For Py3.7, clearing is already done below.
code.putln("#if !CYTHON_USE_EXC_INFO_STACK")
code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname) code.putln("__Pyx_Coroutine_ResetAndClearException(%s);" % Naming.generator_cname)
code.putln("#endif")
code.putln('%s->resume_label = -1;' % Naming.generator_cname) code.putln('%s->resume_label = -1;' % Naming.generator_cname)
# clean up as early as possible to help breaking any reference cycles # clean up as early as possible to help breaking any reference cycles
code.putln('__Pyx_Coroutine_clear((PyObject*)%s);' % Naming.generator_cname) code.putln('__Pyx_Coroutine_clear((PyObject*)%s);' % Naming.generator_cname)
...@@ -7408,7 +7411,9 @@ class ExceptClauseNode(Node): ...@@ -7408,7 +7411,9 @@ class ExceptClauseNode(Node):
if not self.body.is_terminator: if not self.body.is_terminator:
for var in exc_vars: for var in exc_vars:
code.put_decref_clear(var, py_object_type) # FIXME: XDECREF() is needed to allow re-raising (which clears the exc_vars),
# but I don't think it's the right solution.
code.put_xdecref_clear(var, py_object_type)
code.put_goto(end_label) code.put_goto(end_label)
for new_label, old_label in [(code.break_label, old_break_label), for new_label, old_label in [(code.break_label, old_break_label),
......
This diff is collapsed.
...@@ -307,6 +307,31 @@ bad: ...@@ -307,6 +307,31 @@ bad:
} }
#endif #endif
/////////////// GetTopmostException.proto ///////////////
#if CYTHON_USE_EXC_INFO_STACK
static _PyErr_StackItem * __Pyx_PyErr_GetTopmostException(PyThreadState *tstate);
#endif
/////////////// GetTopmostException ///////////////
#if CYTHON_USE_EXC_INFO_STACK
// Copied from errors.c in CPython.
static _PyErr_StackItem *
__Pyx_PyErr_GetTopmostException(PyThreadState *tstate)
{
_PyErr_StackItem *exc_info = tstate->exc_info;
while ((exc_info->exc_type == NULL || exc_info->exc_type == Py_None) &&
exc_info->previous_item != NULL)
{
exc_info = exc_info->previous_item;
}
return exc_info;
}
#endif
/////////////// GetException.proto /////////////// /////////////// GetException.proto ///////////////
//@substitute: naming //@substitute: naming
//@requires: PyThreadStateGet //@requires: PyThreadStateGet
...@@ -360,13 +385,16 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) ...@@ -360,13 +385,16 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb)
*value = local_value; *value = local_value;
*tb = local_tb; *tb = local_tb;
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
#if PY_VERSION_HEX >= 0x030700A3 #if CYTHON_USE_EXC_INFO_STACK
tmp_type = tstate->exc_state.exc_type; {
tmp_value = tstate->exc_state.exc_value; _PyErr_StackItem *exc_info = tstate->exc_info;
tmp_tb = tstate->exc_state.exc_traceback; tmp_type = exc_info->exc_type;
tstate->exc_state.exc_type = local_type; tmp_value = exc_info->exc_value;
tstate->exc_state.exc_value = local_value; tmp_tb = exc_info->exc_traceback;
tstate->exc_state.exc_traceback = local_tb; exc_info->exc_type = local_type;
exc_info->exc_value = local_value;
exc_info->exc_traceback = local_tb;
}
#else #else
tmp_type = tstate->exc_type; tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value; tmp_value = tstate->exc_value;
...@@ -398,16 +426,18 @@ bad: ...@@ -398,16 +426,18 @@ bad:
static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/ static CYTHON_INLINE void __Pyx_ReraiseException(void); /*proto*/
/////////////// ReRaiseException.proto /////////////// /////////////// ReRaiseException ///////////////
//@requires: GetTopmostException
static CYTHON_INLINE void __Pyx_ReraiseException(void) { static CYTHON_INLINE void __Pyx_ReraiseException(void) {
PyObject *type = NULL, *value = NULL, *tb = NULL; PyObject *type = NULL, *value = NULL, *tb = NULL;
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
PyThreadState *tstate = PyThreadState_GET(); PyThreadState *tstate = PyThreadState_GET();
#if PY_VERSION_HEX >= 0x030700A3 #if CYTHON_USE_EXC_INFO_STACK
type = tstate->exc_state.exc_type; _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
value = tstate->exc_state.exc_value; type = exc_info->exc_type;
tb = tstate->exc_state.exc_traceback; value = exc_info->exc_value;
tb = exc_info->exc_traceback;
#else #else
type = tstate->exc_type; type = tstate->exc_type;
value = tstate->exc_value; value = tstate->exc_value;
...@@ -453,13 +483,15 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject ...@@ -453,13 +483,15 @@ static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject
#endif #endif
/////////////// SaveResetException /////////////// /////////////// SaveResetException ///////////////
//@requires: GetTopmostException
#if CYTHON_FAST_THREAD_STATE #if CYTHON_FAST_THREAD_STATE
static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
#if PY_VERSION_HEX >= 0x030700A3 #if CYTHON_USE_EXC_INFO_STACK
*type = tstate->exc_state.exc_type; _PyErr_StackItem *exc_info = __Pyx_PyErr_GetTopmostException(tstate);
*value = tstate->exc_state.exc_value; *type = exc_info->exc_type;
*tb = tstate->exc_state.exc_traceback; *value = exc_info->exc_value;
*tb = exc_info->exc_traceback;
#else #else
*type = tstate->exc_type; *type = tstate->exc_type;
*value = tstate->exc_value; *value = tstate->exc_value;
...@@ -473,13 +505,14 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject * ...@@ -473,13 +505,14 @@ static CYTHON_INLINE void __Pyx__ExceptionSave(PyThreadState *tstate, PyObject *
static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) { static CYTHON_INLINE void __Pyx__ExceptionReset(PyThreadState *tstate, PyObject *type, PyObject *value, PyObject *tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb; PyObject *tmp_type, *tmp_value, *tmp_tb;
#if PY_VERSION_HEX >= 0x030700A3 #if CYTHON_USE_EXC_INFO_STACK
tmp_type = tstate->exc_state.exc_type; _PyErr_StackItem *exc_info = tstate->exc_info;
tmp_value = tstate->exc_state.exc_value; tmp_type = exc_info->exc_type;
tmp_tb = tstate->exc_state.exc_traceback; tmp_value = exc_info->exc_value;
tstate->exc_state.exc_type = type; tmp_tb = exc_info->exc_traceback;
tstate->exc_state.exc_value = value; exc_info->exc_type = type;
tstate->exc_state.exc_traceback = tb; exc_info->exc_value = value;
exc_info->exc_traceback = tb;
#else #else
tmp_type = tstate->exc_type; tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value; tmp_value = tstate->exc_value;
...@@ -511,14 +544,15 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value, ...@@ -511,14 +544,15 @@ static CYTHON_INLINE void __Pyx_ExceptionSwap(PyObject **type, PyObject **value,
static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) { static CYTHON_INLINE void __Pyx__ExceptionSwap(PyThreadState *tstate, PyObject **type, PyObject **value, PyObject **tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb; PyObject *tmp_type, *tmp_value, *tmp_tb;
#if PY_VERSION_HEX >= 0x030700A3 #if CYTHON_USE_EXC_INFO_STACK
tmp_type = tstate->exc_state.exc_type; _PyErr_StackItem *exc_info = tstate->exc_info;
tmp_value = tstate->exc_state.exc_value; tmp_type = exc_info->exc_type;
tmp_tb = tstate->exc_state.exc_traceback; tmp_value = exc_info->exc_value;
tmp_tb = exc_info->exc_traceback;
tstate->exc_state.exc_type = *type; exc_info->exc_type = *type;
tstate->exc_state.exc_value = *value; exc_info->exc_value = *value;
tstate->exc_state.exc_traceback = *tb; exc_info->exc_traceback = *tb;
#else #else
tmp_type = tstate->exc_type; tmp_type = tstate->exc_type;
tmp_value = tstate->exc_value; tmp_value = tstate->exc_value;
......
...@@ -81,6 +81,8 @@ ...@@ -81,6 +81,8 @@
#define CYTHON_USE_TP_FINALIZE 0 #define CYTHON_USE_TP_FINALIZE 0
#undef CYTHON_USE_DICT_VERSIONS #undef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS 0 #define CYTHON_USE_DICT_VERSIONS 0
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#elif defined(PYSTON_VERSION) #elif defined(PYSTON_VERSION)
#define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYPY 0
...@@ -122,6 +124,8 @@ ...@@ -122,6 +124,8 @@
#define CYTHON_USE_TP_FINALIZE 0 #define CYTHON_USE_TP_FINALIZE 0
#undef CYTHON_USE_DICT_VERSIONS #undef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS 0 #define CYTHON_USE_DICT_VERSIONS 0
#undef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK 0
#else #else
#define CYTHON_COMPILING_IN_PYPY 0 #define CYTHON_COMPILING_IN_PYPY 0
...@@ -186,6 +190,9 @@ ...@@ -186,6 +190,9 @@
#ifndef CYTHON_USE_DICT_VERSIONS #ifndef CYTHON_USE_DICT_VERSIONS
#define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1) #define CYTHON_USE_DICT_VERSIONS (PY_VERSION_HEX >= 0x030600B1)
#endif #endif
#ifndef CYTHON_USE_EXC_INFO_STACK
#define CYTHON_USE_EXC_INFO_STACK (PY_VERSION_HEX >= 0x030700A3)
#endif
#endif #endif
#if !defined(CYTHON_FAST_PYCCALL) #if !defined(CYTHON_FAST_PYCCALL)
......
...@@ -145,6 +145,7 @@ EXT_DEP_MODULES = { ...@@ -145,6 +145,7 @@ EXT_DEP_MODULES = {
'Coverage': 'Cython.Coverage', 'Coverage': 'Cython.Coverage',
'tag:ipython': 'IPython.testing.globalipapp', 'tag:ipython': 'IPython.testing.globalipapp',
'tag:jedi': 'jedi_BROKEN_AND_DISABLED', 'tag:jedi': 'jedi_BROKEN_AND_DISABLED',
'tag:test.support': 'test.support', # support module for CPython unit tests
} }
def patch_inspect_isfunction(): def patch_inspect_isfunction():
...@@ -433,6 +434,7 @@ VER_DEP_MODULES = { ...@@ -433,6 +434,7 @@ VER_DEP_MODULES = {
'run.py35_asyncio_async_def', 'run.py35_asyncio_async_def',
'run.mod__spec__', 'run.mod__spec__',
'run.pep526_variable_annotations', # typing module 'run.pep526_variable_annotations', # typing module
'run.test_exceptions', # copied from Py3.7+
]), ]),
} }
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment