summaryrefslogtreecommitdiff
path: root/Objects/codeobject.c
diff options
context:
space:
mode:
authorBrandt Bucher <brandtbucher@microsoft.com>2023-01-10 02:56:53 -0800
committerGitHub <noreply@github.com>2023-01-10 10:56:53 +0000
commitf07daaf4f7a637f9f9324e7c8bf78e8a3faae7e0 (patch)
tree8ced087e09fdf3f372efb7abc3874264d2a235d5 /Objects/codeobject.c
parentb2f7b2ef0b5421e01efb8c7bee2ef95d3bab77eb (diff)
downloadcpython-git-f07daaf4f7a637f9f9324e7c8bf78e8a3faae7e0.tar.gz
GH-100117: Make `co_lines` more efficient (GH-100447)
Diffstat (limited to 'Objects/codeobject.c')
-rw-r--r--Objects/codeobject.c50
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) {