Commit 01fabbd9 authored by Robert Bradshaw's avatar Robert Bradshaw Committed by GitHub

Merge pull request #1773 from scoder/faster_traceback_handling

use faster __Pyx_PyObject_GetAttrStr() implementation and avoid stati…
parents a2db27bb 1f122aca
...@@ -2214,7 +2214,7 @@ class CCodeWriter(object): ...@@ -2214,7 +2214,7 @@ class CCodeWriter(object):
def put_finish_refcount_context(self): def put_finish_refcount_context(self):
self.putln("__Pyx_RefNannyFinishContext();") self.putln("__Pyx_RefNannyFinishContext();")
def put_add_traceback(self, qualified_name): def put_add_traceback(self, qualified_name, include_cline=True):
""" """
Build a Python traceback for propagating exceptions. Build a Python traceback for propagating exceptions.
...@@ -2222,7 +2222,7 @@ class CCodeWriter(object): ...@@ -2222,7 +2222,7 @@ class CCodeWriter(object):
""" """
format_tuple = ( format_tuple = (
qualified_name, qualified_name,
Naming.clineno_cname, Naming.clineno_cname if include_cline else 0,
Naming.lineno_cname, Naming.lineno_cname,
Naming.filename_cname, Naming.filename_cname,
) )
......
...@@ -2251,9 +2251,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): ...@@ -2251,9 +2251,10 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.put_label(code.error_label) code.put_label(code.error_label)
for cname, type in code.funcstate.all_managed_temps(): for cname, type in code.funcstate.all_managed_temps():
code.put_xdecref(cname, type) code.put_xdecref(cname, type)
# module state might not be ready for traceback generation with C-line handling yet
code.putln('if (%s) {' % env.module_cname) code.putln('if (%s) {' % env.module_cname)
code.putln('if (%s) {' % env.module_dict_cname) code.putln('if (%s) {' % env.module_dict_cname)
code.put_add_traceback("init %s" % env.qualified_name) code.put_add_traceback("init %s" % env.qualified_name, include_cline=False)
code.globalstate.use_utility_code(Nodes.traceback_utility_code) code.globalstate.use_utility_code(Nodes.traceback_utility_code)
# Module reference and module dict are in global variables which might still be needed # Module reference and module dict are in global variables which might still be needed
# for cleanup, atexit code, etc., so leaking is better than crashing. # for cleanup, atexit code, etc., so leaking is better than crashing.
......
...@@ -529,6 +529,36 @@ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno, ...@@ -529,6 +529,36 @@ static void __Pyx_WriteUnraisable(const char *name, CYTHON_UNUSED int clineno,
#endif #endif
} }
/////////////// CLineInTraceback.proto ///////////////
static int __Pyx_CLineForTraceback(int c_line);
/////////////// CLineInTraceback ///////////////
//@requires: ObjectHandling.c::PyObjectGetAttrStr
//@substitute: naming
static int __Pyx_CLineForTraceback(int c_line) {
#ifdef CYTHON_CLINE_IN_TRACEBACK /* 0 or 1 to disable/enable C line display in tracebacks at C compile time */
return ((CYTHON_CLINE_IN_TRACEBACK)) ? c_line : 0;
#else
PyObject *ptype, *pvalue, *ptraceback;
PyObject *use_cline;
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
use_cline = __Pyx_PyObject_GetAttrStr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"));
if (!use_cline) {
c_line = 0;
PyObject_SetAttr(${cython_runtime_cname}, PYIDENT("cline_in_traceback"), Py_False);
}
else if (PyObject_Not(use_cline) != 0) {
c_line = 0;
}
Py_XDECREF(use_cline);
PyErr_Restore(ptype, pvalue, ptraceback);
return c_line;
#endif
}
/////////////// AddTraceback.proto /////////////// /////////////// AddTraceback.proto ///////////////
static void __Pyx_AddTraceback(const char *funcname, int c_line, static void __Pyx_AddTraceback(const char *funcname, int c_line,
...@@ -536,6 +566,7 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, ...@@ -536,6 +566,7 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
/////////////// AddTraceback /////////////// /////////////// AddTraceback ///////////////
//@requires: ModuleSetupCode.c::CodeObjectCache //@requires: ModuleSetupCode.c::CodeObjectCache
//@requires: CLineInTraceback
//@substitute: naming //@substitute: naming
#include "compile.h" #include "compile.h"
...@@ -600,29 +631,9 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, ...@@ -600,29 +631,9 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
int py_line, const char *filename) { int py_line, const char *filename) {
PyCodeObject *py_code = 0; PyCodeObject *py_code = 0;
PyFrameObject *py_frame = 0; PyFrameObject *py_frame = 0;
PyObject *use_cline = 0;
PyObject *ptype, *pvalue, *ptraceback;
static PyObject* cline_in_traceback = NULL;
if (cline_in_traceback == NULL) {
#if PY_MAJOR_VERSION < 3
cline_in_traceback = PyString_FromString("cline_in_traceback");
#else
cline_in_traceback = PyUnicode_FromString("cline_in_traceback");
#endif
}
if (c_line) { if (c_line) {
PyErr_Fetch(&ptype, &pvalue, &ptraceback); c_line = __Pyx_CLineForTraceback(c_line);
use_cline = PyObject_GetAttr(${cython_runtime_cname}, cline_in_traceback);
if (use_cline == NULL) {
c_line = 0;
PyObject_SetAttr(${cython_runtime_cname}, cline_in_traceback, Py_False);
}
else if (PyObject_Not(use_cline) != 0) {
c_line = 0;
}
PyErr_Restore(ptype, pvalue, ptraceback);
} }
// Negate to avoid collisions between py and c lines. // Negate to avoid collisions between py and c lines.
...@@ -645,5 +656,4 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line, ...@@ -645,5 +656,4 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
bad: bad:
Py_XDECREF(py_code); Py_XDECREF(py_code);
Py_XDECREF(py_frame); Py_XDECREF(py_frame);
Py_XDECREF(use_cline);
} }
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