bpo-42739: Don't use sentinels to mark end of line table. (GH-25657)

* Add length parameter to PyLineTable_InitAddressRange and doen't use sentinel values at end of table. Makes the line number table more robust.

* Update PyCodeAddressRange to match PEP 626.
This commit is contained in:
Mark Shannon 2021-04-29 13:12:51 +01:00 committed by GitHub
parent 53dd6c99b3
commit c76da79b37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 4968 additions and 4986 deletions

View file

@ -456,15 +456,15 @@ code_getlnotab(PyCodeObject *code, void *closure)
}
_PyCode_InitAddressRange(code, &bounds);
while (PyLineTable_NextAddressRange(&bounds)) {
if (bounds.ar_computed_line != line) {
if (bounds.opaque.computed_line != line) {
int bdelta = bounds.ar_start - code_offset;
int ldelta = bounds.ar_computed_line - line;
int ldelta = bounds.opaque.computed_line - line;
if (!emit_delta(&bytes, bdelta, ldelta, &table_offset)) {
Py_DECREF(bytes);
return NULL;
}
code_offset = bounds.ar_start;
line = bounds.ar_computed_line;
line = bounds.opaque.computed_line;
}
}
_PyBytes_Resize(&bytes, table_offset);
@ -1120,20 +1120,20 @@ code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
static void
retreat(PyCodeAddressRange *bounds)
{
int ldelta = ((signed char *)bounds->lo_next)[-1];
int ldelta = ((signed char *)bounds->opaque.lo_next)[-1];
if (ldelta == -128) {
ldelta = 0;
}
bounds->ar_computed_line -= ldelta;
bounds->lo_next -= 2;
bounds->opaque.computed_line -= ldelta;
bounds->opaque.lo_next -= 2;
bounds->ar_end = bounds->ar_start;
bounds->ar_start -= ((unsigned char *)bounds->lo_next)[-2];
ldelta = ((signed char *)bounds->lo_next)[-1];
bounds->ar_start -= ((unsigned char *)bounds->opaque.lo_next)[-2];
ldelta = ((signed char *)bounds->opaque.lo_next)[-1];
if (ldelta == -128) {
bounds->ar_line = -1;
}
else {
bounds->ar_line = bounds->ar_computed_line;
bounds->ar_line = bounds->opaque.computed_line;
}
}
@ -1141,23 +1141,22 @@ static void
advance(PyCodeAddressRange *bounds)
{
bounds->ar_start = bounds->ar_end;
int delta = ((unsigned char *)bounds->lo_next)[0];
assert (delta < 255);
int delta = ((unsigned char *)bounds->opaque.lo_next)[0];
bounds->ar_end += delta;
int ldelta = ((signed char *)bounds->lo_next)[1];
bounds->lo_next += 2;
int ldelta = ((signed char *)bounds->opaque.lo_next)[1];
bounds->opaque.lo_next += 2;
if (ldelta == -128) {
bounds->ar_line = -1;
}
else {
bounds->ar_computed_line += ldelta;
bounds->ar_line = bounds->ar_computed_line;
bounds->opaque.computed_line += ldelta;
bounds->ar_line = bounds->opaque.computed_line;
}
}
static inline int
at_end(PyCodeAddressRange *bounds) {
return ((unsigned char *)bounds->lo_next)[0] == 255;
return bounds->opaque.lo_next >= bounds->opaque.limit;
}
int
@ -1256,12 +1255,13 @@ PyCode_Addr2Line(PyCodeObject *co, int addrq)
}
void
PyLineTable_InitAddressRange(char *linetable, int firstlineno, PyCodeAddressRange *range)
PyLineTable_InitAddressRange(char *linetable, Py_ssize_t length, int firstlineno, PyCodeAddressRange *range)
{
range->lo_next = linetable;
range->opaque.lo_next = linetable;
range->opaque.limit = range->opaque.lo_next + length;
range->ar_start = -1;
range->ar_end = 0;
range->ar_computed_line = firstlineno;
range->opaque.computed_line = firstlineno;
range->ar_line = -1;
}
@ -1269,7 +1269,8 @@ int
_PyCode_InitAddressRange(PyCodeObject* co, PyCodeAddressRange *bounds)
{
char *linetable = PyBytes_AS_STRING(co->co_linetable);
PyLineTable_InitAddressRange(linetable, co->co_firstlineno, bounds);
Py_ssize_t length = PyBytes_GET_SIZE(co->co_linetable);
PyLineTable_InitAddressRange(linetable, length, co->co_firstlineno, bounds);
return bounds->ar_line;
}