Это не столько решение, сколько способ найти решение, если кто-то захочет поработать над ним.
Было бы дорого хранить местоположение каждого экземпляра оператора.В качестве компромисса,
Недавняя работа, которую я выполнял при разборе во время выполнения, уменьшает необходимость добавлять дополнительные места в дереве.
Для этого примера с Devel :: Trepan :: Deparse вот что вы получите:
(trepanpl): disasm
Package Main
------------
#4: my $choice = 0;
COP (0x195a0b0) dbstate
BINOP (0x195a110) sassign
=> SVOP (0x195a158) const IV (0x1953f68) 0
OP (0x195a198) padsv [1]
#6: while ($choice == 0){
COP (0x1b5b070) dbstate
BINOP (0x1b5b0d0) leaveloop
LOOP (0x1b5b118) enterloop
UNOP (0x1b5b178) null
LOGOP (0x1b5b1b8) and
BINOP (0x195a850) eq <<< This is where the error is
OP (0x195a000) padsv [1]
SVOP (0x195a898) const IV (0x1953fb0) 0
LISTOP (0x195a6e8) lineseq
#9: $choice = '5,6,7';
COP (0x2459530) dbstate
BINOP (0x2459590) sassign
SVOP (0x24595d8) const PV (0x2da5ae0) "5,6,7"
OP (0x21e8618) padsv [1]
...
(trepanpl): deparse 0x195a850
binary operator ==, eq
while ($choice == 0) {
------------
А если вы добавите другие смещения, вы получите другие варианты.Например,
(trepanpl): deparse 0x195a000
not my, padsv
while ($choice == 0) {
-------
(trepanpl): deparse 0x21e8618
not my, padsv
$choice = '5,6,7';
-------
Обратите внимание, что вы получаете не только текст строки, но и место, где в строке возникла проблема.Если бы код был
while ($choice == 0 && $i_feel_pretty == 3)
, то отмена указала бы, в каком из двух условий возникла проблема, даже если они оба находятся в одной строке.
Итак, нужно получить адрес OP при появлении предупреждения или ошибки, а затем вызвать B :: DeparseTree , чтобы сообщить о местоположении и контексте.
В настоящее времяPerl предоставляет $SIG{__WARN__}
и $SIG{__DIE__}
, но значение PL_op недоступно во время вызова обработчика, даже если обработчик является подпрограммой XS.PL_op
сохраняется, затем устанавливается на поддельное OP_ENTERSUB
a для вызова обработчика.
Однако есть надежда, что решение этой проблемы может быть выполнено быстрее, чем исправление этой ошибки, существовавшей в течение 16 лет.лет, и я сомневаюсь, что это будет решено в ближайшее время.См. perl # 133239 .
Наконец, я скажу, что прямо сейчас B :: DeparseTree не возвращается к 5.16 и код вообще нуждается в большей любвичем я могу дать это сам.