исключить неправильные номера строк в предупреждениях
Этот код
1. use warnings;
2. my $undef;
3.
4. if ($undef == 3) {
5. } elsif ($undef == 0) {
6. }
используется для получения этого вывода:
Use of uninitialized value in numeric eq (==) at wrong.pl line 4.
Use of uninitialized value in numeric eq (==) at wrong.pl line 4.
, где строка второго предупреждения была ошибочно сообщена - это должна быть строка 5. Рафаэль исправил это - проблема возникла из-за того, что между выполнением оператора if и elsif
не было nextstate OP, поэтому PL_curcop
по-прежнему сообщает что текущая исполняемая строка - это строка 4. Решение заключалось в том, чтобы вводить операторы nextstate для каждого elsif
, хотя оказалось, что OP-оператор nextstate должен был быть операцией с нулевым состоянием, а не живым OP-оператором nextstate, иначе другие номера строк стали доложены. (Jenga!)
Проблема носит более общий характер, чем elsif
(хотя случай elsif
является наиболее распространенным и наиболее запутанным). В идеале этот код
1. use warnings;
2. my $undef;
3.
4. my $a = $undef + 1;
5. my $b
6. = $undef
7. + 1;
выдаст этот вывод
Use of uninitialized value $undef in addition (+) at wrong.pl line 4.
Use of uninitialized value $undef in addition (+) at wrong.pl line 7.
(а не строки 4 и 5), но для этого требуется, чтобы каждый OP содержал (как минимум) информацию о номере строки.
Что может сработать, так это иметь дополнительный номер строки в памяти непосредственно перед структурой BASEOP, с битом флага в операторе, чтобы сказать, присутствует ли он. Первоначально во время компиляции каждый OP будет иметь свой номер строки. Затем добавьте поздний проход в оптимизатор (возможно, в сочетании с переупаковкой optree), который просматривает две операции на каждом краю графика пути выполнения. Если номер строки изменяется, помечает целевой пункт с этой информацией. Как только все пути прослежены, замените каждую операцию с флагом на операцию nextstate-light (которая просто обновляет PL_curcop
), которая, в свою очередь, передает управление истинной операции. Все операции будут заменены вариантами, в которых не хранится номер строки. (Что, по логике, почему это будет лучше всего работать в сочетании с переупаковкой optree, поскольку это уже копирует / перераспределяет все OP)
(хотя я должен отметить, что мы не уверены, что делать это для общего случая стоит)