diff options
author | Brandt Bucher <brandtbucher@microsoft.com> | 2023-01-10 02:56:53 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-01-10 10:56:53 +0000 |
commit | f07daaf4f7a637f9f9324e7c8bf78e8a3faae7e0 (patch) | |
tree | 8ced087e09fdf3f372efb7abc3874264d2a235d5 /Objects/codeobject.c | |
parent | b2f7b2ef0b5421e01efb8c7bee2ef95d3bab77eb (diff) | |
download | cpython-git-f07daaf4f7a637f9f9324e7c8bf78e8a3faae7e0.tar.gz |
GH-100117: Make `co_lines` more efficient (GH-100447)
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r-- | Objects/codeobject.c | 50 |
1 files changed, 18 insertions, 32 deletions
diff --git a/Objects/codeobject.c b/Objects/codeobject.c index 6facfef4c9..ab31b6582c 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -1184,37 +1184,31 @@ lineiter_dealloc(lineiterator *li) } static PyObject * +_source_offset_converter(int *value) { + if (*value == -1) { + Py_RETURN_NONE; + } + return PyLong_FromLong(*value); +} + +static PyObject * lineiter_next(lineiterator *li) { PyCodeAddressRange *bounds = &li->li_line; if (!_PyLineTable_NextAddressRange(bounds)) { return NULL; } - PyObject *start = NULL; - PyObject *end = NULL; - PyObject *line = NULL; - PyObject *result = PyTuple_New(3); - start = PyLong_FromLong(bounds->ar_start); - end = PyLong_FromLong(bounds->ar_end); - if (bounds->ar_line < 0) { - line = Py_NewRef(Py_None); - } - else { - line = PyLong_FromLong(bounds->ar_line); - } - if (result == NULL || start == NULL || end == NULL || line == NULL) { - goto error; + int start = bounds->ar_start; + int line = bounds->ar_line; + // Merge overlapping entries: + while (_PyLineTable_NextAddressRange(bounds)) { + if (bounds->ar_line != line) { + _PyLineTable_PreviousAddressRange(bounds); + break; + } } - PyTuple_SET_ITEM(result, 0, start); - PyTuple_SET_ITEM(result, 1, end); - PyTuple_SET_ITEM(result, 2, line); - return result; -error: - Py_XDECREF(start); - Py_XDECREF(end); - Py_XDECREF(line); - Py_XDECREF(result); - return result; + return Py_BuildValue("iiO&", start, bounds->ar_end, + _source_offset_converter, &line); } PyTypeObject _PyLineIterator = { @@ -1291,14 +1285,6 @@ positionsiter_dealloc(positionsiterator* pi) } static PyObject* -_source_offset_converter(int* value) { - if (*value == -1) { - Py_RETURN_NONE; - } - return PyLong_FromLong(*value); -} - -static PyObject* positionsiter_next(positionsiterator* pi) { if (pi->pi_offset >= pi->pi_range.ar_end) { |